From 0549464579d1c85070232f79463b2e3fed468d80 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Fri, 18 Sep 2026 19:08:03 -0400 Subject: [PATCH 1/9] chore(typecheck): make tsc --noEmit pass Type-only fixes for the 32 errors tsc reported. One runtime fix rides along: RevenueIntroScreen spread the POSTHOG_SDKS and STRIPE_SDKS sets before calling array methods on them, which previously threw on those branches. Generated-By: PostHog Desktop Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589 --- e2e-harness/__tests__/e2e-flow-snapshot.test.ts | 3 ++- e2e-harness/__tests__/wizard-ci-driver.test.ts | 2 +- src/lib/__tests__/wizard-tools.test.ts | 7 ++++++- .../agent/runner/harness/pi/__tests__/tools.test.ts | 8 +++++--- src/lib/agent/runner/harness/pi/mcp.ts | 4 +++- .../orchestrator/__tests__/task-notice-timeout.test.ts | 2 +- src/lib/programs/__tests__/metrics-program.test.ts | 3 +-- .../programs/__tests__/warehouse-suggestion.test.ts | 8 ++++---- src/ui/tui/components/visualizer/CrateStack.tsx | 2 +- src/ui/tui/playground/demos/McpDemo.tsx | 10 +++++----- src/ui/tui/screens/MetricsIntroScreen.tsx | 2 +- src/ui/tui/screens/RevenueIntroScreen.tsx | 8 ++++---- src/utils/__tests__/ci-region.test.ts | 2 ++ src/utils/bounded-fs.ts | 2 +- src/wizard.ts | 2 +- 15 files changed, 38 insertions(+), 27 deletions(-) diff --git a/e2e-harness/__tests__/e2e-flow-snapshot.test.ts b/e2e-harness/__tests__/e2e-flow-snapshot.test.ts index 2a525cfb0..243d4f830 100644 --- a/e2e-harness/__tests__/e2e-flow-snapshot.test.ts +++ b/e2e-harness/__tests__/e2e-flow-snapshot.test.ts @@ -18,6 +18,7 @@ import { InkUI } from '@ui/tui/ink-ui'; import { setUI } from '@ui/index'; import { buildSession, RunPhase } from '@lib/wizard-session'; import { Integration } from '@lib/constants'; +import { HostResolution } from '@lib/host-resolution'; import { FRAMEWORK_REGISTRY } from '@lib/registry'; import { WizardReadiness } from '@lib/health-checks/readiness'; import { @@ -89,7 +90,7 @@ function traceFlow( store.setCredentials({ accessToken: 'phx_x', projectApiKey: 'phc_x', - host: 'https://us.posthog.com', + host: HostResolution.fromApiHost('https://us.posthog.com'), projectId: 1, }); } else if (screen === ScreenId.SelfDrivingGithub) { diff --git a/e2e-harness/__tests__/wizard-ci-driver.test.ts b/e2e-harness/__tests__/wizard-ci-driver.test.ts index 45d4af832..2edf4553e 100644 --- a/e2e-harness/__tests__/wizard-ci-driver.test.ts +++ b/e2e-harness/__tests__/wizard-ci-driver.test.ts @@ -251,7 +251,7 @@ describe('WizardCiDriver — source-maps project pick', () => { store.setCredentials({ accessToken: 'phx_x', projectApiKey: 'phc_x', - host: 'https://us.posthog.com', + host: HostResolution.fromApiHost('https://us.posthog.com'), projectId: 1, }); } diff --git a/src/lib/__tests__/wizard-tools.test.ts b/src/lib/__tests__/wizard-tools.test.ts index 771751234..5ddeff913 100644 --- a/src/lib/__tests__/wizard-tools.test.ts +++ b/src/lib/__tests__/wizard-tools.test.ts @@ -920,7 +920,12 @@ describe('resolveAskQuestionKinds', () => { it('reads a kind-less question as free text, which is what a credential is', () => { expect( resolveAskQuestionKinds([ - { id: 'password', prompt: 'Database password', sensitive: true }, + { id: 'password', prompt: 'Database password', sensitive: true } as { + kind?: undefined; + id: string; + prompt: string; + sensitive: boolean; + }, ]), ).toEqual([ { diff --git a/src/lib/agent/runner/harness/pi/__tests__/tools.test.ts b/src/lib/agent/runner/harness/pi/__tests__/tools.test.ts index 018e85adf..c3ef60dc1 100644 --- a/src/lib/agent/runner/harness/pi/__tests__/tools.test.ts +++ b/src/lib/agent/runner/harness/pi/__tests__/tools.test.ts @@ -66,6 +66,8 @@ const call = (tool: { execute: unknown }, args: unknown): Promise => args, ); +type ExecuteLoosely = (id: string, params: unknown) => Promise; + describe('pi wizard_ask — sensitive answers are vaulted', () => { it('returns {secretRef}, never the raw value', async () => { const { wizardAsk } = makeTools({ token: SECRET, tracker: 'linear' }); @@ -687,13 +689,13 @@ describe('audit ledger tools', () => { status: 'pending' as const, }); - await tool('audit_seed_checks').execute('1', { + await (tool('audit_seed_checks').execute as ExecuteLoosely)('1', { checks: [check('sdk-installed'), check('init-correct')], } as never); - await tool('audit_resolve_checks').execute('2', { + await (tool('audit_resolve_checks').execute as ExecuteLoosely)('2', { updates: [{ id: 'sdk-installed', status: 'pass' }], } as never); - await tool('audit_add_checks').execute('3', { + await (tool('audit_add_checks').execute as ExecuteLoosely)('3', { checks: [check('live-data-source-maps')], } as never); diff --git a/src/lib/agent/runner/harness/pi/mcp.ts b/src/lib/agent/runner/harness/pi/mcp.ts index 4e662178f..eeaa3607a 100644 --- a/src/lib/agent/runner/harness/pi/mcp.ts +++ b/src/lib/agent/runner/harness/pi/mcp.ts @@ -59,7 +59,9 @@ export async function setupPostHogMcp(opts: { // The adapter ships raw TypeScript; loading through jiti is its documented requirement. const jiti = createJiti(import.meta.url); - const mod = await jiti.import('pi-mcp-adapter'); + const mod = await jiti.import<{ + createMcpAdapter: (options: unknown) => PostHogMcpSetup['extensionFactory']; + }>('pi-mcp-adapter'); const extensionFactory = mod.createMcpAdapter({ config: { mcpServers: { diff --git a/src/lib/agent/runner/sequence/orchestrator/__tests__/task-notice-timeout.test.ts b/src/lib/agent/runner/sequence/orchestrator/__tests__/task-notice-timeout.test.ts index c7d35a034..c6acf1014 100644 --- a/src/lib/agent/runner/sequence/orchestrator/__tests__/task-notice-timeout.test.ts +++ b/src/lib/agent/runner/sequence/orchestrator/__tests__/task-notice-timeout.test.ts @@ -13,7 +13,7 @@ import type { TaskNotice } from '@lib/wizard-session'; // factory would otherwise read these before they exist. const { showTaskNotice, cancelTaskNotice, wizardCapture, captureException } = vi.hoisted(() => ({ - showTaskNotice: vi.fn<[TaskNotice], Promise>(), + showTaskNotice: vi.fn<(notice: TaskNotice) => Promise>(), cancelTaskNotice: vi.fn(), wizardCapture: vi.fn(), captureException: vi.fn(), diff --git a/src/lib/programs/__tests__/metrics-program.test.ts b/src/lib/programs/__tests__/metrics-program.test.ts index 27dbd8989..ae5936408 100644 --- a/src/lib/programs/__tests__/metrics-program.test.ts +++ b/src/lib/programs/__tests__/metrics-program.test.ts @@ -2,7 +2,6 @@ import { AGENT_SKILL_STEPS } from '@lib/programs/agent-skill/index'; import { getProgramConfig, Program } from '@lib/programs/program-registry'; import { metricsConfig } from '@lib/programs/metrics/index'; import type { ProgramRun } from '@lib/agent/agent-runner'; -import type { WizardSession } from '@lib/wizard-session'; import { metricsCommand } from '../../../commands/metrics'; @@ -38,7 +37,7 @@ describe('metrics program', () => { const run = staticRun(metricsConfig); expect(run.skillId).toBeUndefined(); - const prompt = run.customPrompt?.({} as WizardSession); + const prompt = run.customPrompt?.({} as never); expect(prompt).toContain('load_skill_menu'); expect(prompt).toContain('"metrics"'); // Every published variant the prompt teaches the agent to choose from. diff --git a/src/lib/programs/__tests__/warehouse-suggestion.test.ts b/src/lib/programs/__tests__/warehouse-suggestion.test.ts index de7a39b9c..0f6023f28 100644 --- a/src/lib/programs/__tests__/warehouse-suggestion.test.ts +++ b/src/lib/programs/__tests__/warehouse-suggestion.test.ts @@ -78,7 +78,7 @@ describe('outro suggestion', () => { const s = sessionWith([POSTGRES, STRIPE]); const runDef = await resolveRun(s); // eslint-disable-next-line @typescript-eslint/no-explicit-any - const outro = runDef.buildOutroData!(s, CREDENTIALS as any); + const outro = runDef.buildOutroData!(s, CREDENTIALS as any)!; const text = outro.nextSteps!.items.join('\n'); // The project segment and the kind are what land the user on the source's @@ -100,7 +100,7 @@ describe('outro suggestion', () => { const s = sessionWith(many); const runDef = await resolveRun(s); // eslint-disable-next-line @typescript-eslint/no-explicit-any - const outro = runDef.buildOutroData!(s, CREDENTIALS as any); + const outro = runDef.buildOutroData!(s, CREDENTIALS as any)!; const links = outro.nextSteps!.items.filter((i) => i.includes('new-source'), ); @@ -113,7 +113,7 @@ describe('outro suggestion', () => { const s = sessionWith([]); const runDef = await resolveRun(s); // eslint-disable-next-line @typescript-eslint/no-explicit-any - const outro = runDef.buildOutroData!(s, CREDENTIALS as any); + const outro = runDef.buildOutroData!(s, CREDENTIALS as any)!; expect(outro.nextSteps).toBeUndefined(); }); @@ -123,7 +123,7 @@ describe('outro suggestion', () => { const s = sessionWith(sources); const runDef = await resolveRun(s); // eslint-disable-next-line @typescript-eslint/no-explicit-any - const outro = runDef.buildOutroData!(s, CREDENTIALS as any); + const outro = runDef.buildOutroData!(s, CREDENTIALS as any)!; expect(outro.message).toBe('Successfully installed PostHog!'); expect(outro.changes).toContain('Added PostHog provider'); diff --git a/src/ui/tui/components/visualizer/CrateStack.tsx b/src/ui/tui/components/visualizer/CrateStack.tsx index d002faa95..781502a4c 100644 --- a/src/ui/tui/components/visualizer/CrateStack.tsx +++ b/src/ui/tui/components/visualizer/CrateStack.tsx @@ -109,7 +109,7 @@ export const CrateStack = ({ width, height }: VisualProps) => { return ( ({ name, - status: - i === 1 ? McpClientStatus.Unchanged : McpClientStatus.Changed, + status: i === 1 ? McpClientStatus.Unchanged : McpClientStatus.Changed, })); }, async installPlugins(clientNames) { diff --git a/src/ui/tui/screens/MetricsIntroScreen.tsx b/src/ui/tui/screens/MetricsIntroScreen.tsx index 87875559a..cdda2be1e 100644 --- a/src/ui/tui/screens/MetricsIntroScreen.tsx +++ b/src/ui/tui/screens/MetricsIntroScreen.tsx @@ -23,7 +23,7 @@ export const MetricsIntroScreen = ({ store }: MetricsIntroScreenProps) => { // kubernetes, other), so there's no pre-seeded skillId here. Fall back to // the group id for the "more info" lookup. const skillId = session.skillId ?? 'metrics'; - const { skillEntry, fetchFailed } = useSkillEntry(skillId, session.localMcp); + const { skillEntry, fetchFailed } = useSkillEntry(skillId); const body = showingMoreInfo ? ( diff --git a/src/ui/tui/screens/RevenueIntroScreen.tsx b/src/ui/tui/screens/RevenueIntroScreen.tsx index bdfd0df32..3d791dd3b 100644 --- a/src/ui/tui/screens/RevenueIntroScreen.tsx +++ b/src/ui/tui/screens/RevenueIntroScreen.tsx @@ -205,11 +205,11 @@ const DetectErrorBody = ({ error }: { error: RevenueDetectError }) => { Revenue analytics requires: - {' \u2022'} A PostHog SDK ({POSTHOG_SDKS.slice(0, 3).join(', ')}, - …) + {' \u2022'} A PostHog SDK ( + {[...POSTHOG_SDKS].slice(0, 3).join(', ')}, …) - {' \u2022'} A Stripe SDK ({STRIPE_SDKS.join(', ')}) + {' \u2022'} A Stripe SDK ({[...STRIPE_SDKS].join(', ')}) @@ -247,7 +247,7 @@ const DetectErrorBody = ({ error }: { error: RevenueDetectError }) => { Install one of: - {STRIPE_SDKS.map((sdk) => ( + {[...STRIPE_SDKS].map((sdk) => ( {' \u2022'} {sdk} diff --git a/src/utils/__tests__/ci-region.test.ts b/src/utils/__tests__/ci-region.test.ts index 2f7cf9acd..d174852a5 100644 --- a/src/utils/__tests__/ci-region.test.ts +++ b/src/utils/__tests__/ci-region.test.ts @@ -55,6 +55,7 @@ describe('getOrAskForProjectData CI region', () => { it('uses the provided region and never probes @me for it', async () => { const result = await getOrAskForProjectData({ + signup: false, ci: true, apiKey: 'phx_test', projectId: 123, @@ -76,6 +77,7 @@ describe('getOrAskForProjectData CI region', () => { mockedDetect.mockResolvedValue('us'); await getOrAskForProjectData({ + signup: false, ci: true, apiKey: 'phx_test', projectId: 123, diff --git a/src/utils/bounded-fs.ts b/src/utils/bounded-fs.ts index 23c091a0f..35e6dd55c 100644 --- a/src/utils/bounded-fs.ts +++ b/src/utils/bounded-fs.ts @@ -143,7 +143,7 @@ export async function boundedGlob( ignore: [...PROJECT_IGNORE_GLOBS, ...(options.extraIgnore ?? [])], suppressErrors: true, followSymbolicLinks: false, - }); + }) as NodeJS.ReadableStream & { destroy(): void }; const matches: string[] = []; return new Promise((resolve) => { diff --git a/src/wizard.ts b/src/wizard.ts index 5072275b2..621e14699 100644 --- a/src/wizard.ts +++ b/src/wizard.ts @@ -81,7 +81,7 @@ export class Wizard { private cli: Argv; private constructor() { - let cli = yargs(hideBin(process.argv)) + let cli: Argv = yargs(hideBin(process.argv)) .env('POSTHOG_WIZARD') .options(GLOBAL_OPTIONS); From e74871affcacd7e2ca2d8b441acc0de2c1fd6e1c Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Fri, 18 Sep 2026 19:08:03 -0400 Subject: [PATCH 2/9] chore(test): split vitest into per-surface projects Projects: store, agent, tui, cli, harness, architecture, keyed by today's directories. New scripts test: and test:arch, a surfaces workflow that runs each project alone plus a production and CI bundle audit, aliases and empty shape files for the future src/{store,agent,tui,cli} surfaces, and a chunk manifest script for dist/. Generated-By: PostHog Desktop Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589 --- .github/workflows/surfaces.yml | 86 +++++++++++++++++++++++++++++++ package.json | 7 +++ scripts/README.md | 1 + scripts/chunk-manifest.no-jest.ts | 40 ++++++++++++++ vitest.config.ts | 56 ++++++++++++++++---- 5 files changed, 179 insertions(+), 11 deletions(-) create mode 100644 .github/workflows/surfaces.yml create mode 100644 scripts/chunk-manifest.no-jest.ts diff --git a/.github/workflows/surfaces.yml b/.github/workflows/surfaces.yml new file mode 100644 index 000000000..aa04ae6e8 --- /dev/null +++ b/.github/workflows/surfaces.yml @@ -0,0 +1,86 @@ +name: 'Surfaces' +on: + push: + branches: + - main + pull_request: + +jobs: + architecture: + name: Architecture + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + - uses: pnpm/action-setup@eae0cfeb286e66ffb5155f1a79b90583a127a68b # v2.4.1 + with: + version: 10.34.5 + run_install: false + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version-file: 'package.json' + cache: 'pnpm' + - run: pnpm install --frozen-lockfile + - run: node scripts/generate-version.cjs + - run: pnpm typecheck + - run: pnpm lint + - run: pnpm test:arch + + surface: + name: ${{ matrix.project }} + runs-on: ubuntu-latest + timeout-minutes: 15 + strategy: + fail-fast: false + matrix: + project: [legacy, agent, tui, cli, harness] + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + - uses: pnpm/action-setup@eae0cfeb286e66ffb5155f1a79b90583a127a68b # v2.4.1 + with: + version: 10.34.5 + run_install: false + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version-file: 'package.json' + cache: 'pnpm' + - run: pnpm install --frozen-lockfile + - run: node scripts/generate-version.cjs + - run: pnpm test:${{ matrix.project }} --coverage + - uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # pin@v5.3.1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: false + flags: ${{ matrix.project }} + + bundle: + name: Bundle audit + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + - uses: pnpm/action-setup@eae0cfeb286e66ffb5155f1a79b90583a127a68b # v2.4.1 + with: + version: 10.34.5 + run_install: false + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version-file: 'package.json' + cache: 'pnpm' + - run: pnpm install --frozen-lockfile + - name: Production build and smoke test + run: pnpm build + - name: Production chunk manifest + run: + npx tsx scripts/chunk-manifest.no-jest.ts dist > + chunk-manifest.prod.json + - name: CI build and smoke test + run: pnpm build:ci + - name: CI chunk manifest + run: + npx tsx scripts/chunk-manifest.no-jest.ts dist > + chunk-manifest.ci.json + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: chunk-manifests-${{ github.sha }} + path: chunk-manifest.*.json diff --git a/package.json b/package.json index 617175ae8..554ca512b 100644 --- a/package.json +++ b/package.json @@ -132,6 +132,13 @@ "fix:prettier": "prettier --write \"{lib,src,test}/**/*.ts\"", "fix:eslint": "eslint . --cache --format stylish --fix", "test": "pnpm build && vitest run", + "test:legacy": "vitest run --project legacy", + "test:agent": "vitest run --project agent", + "test:tui": "vitest run --project tui", + "test:cli": "vitest run --project cli", + "test:harness": "vitest run --project harness", + "test:arch": "vitest run --project architecture", + "test:goldens:update": "vitest run --project tui --project legacy -u", "test:coverage": "pnpm build && vitest run --coverage", "test:e2e": "pnpm build && ./e2e-tests/run.sh", "test:e2e-record": "export RECORD_FIXTURES=true && pnpm build && ./e2e-tests/run.sh", diff --git a/scripts/README.md b/scripts/README.md index a136ce8f5..725eda866 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -17,6 +17,7 @@ real ink render) and is driven purely by store state manipulation; a PTY parent | **`tui-host.no-jest.ts`** | Real TUI host: `MODE=fixed` follows a profile; `MODE=serve` accepts socket commands. | `APP_DIR`, `PROJECT_ID`, key for a full run, `SNAP_CTRL`; run under a PTY, with `CONTROL_SOCK` in serve mode | | **`tui-snapshots.no-jest.ts`** | Runs the fixed host and saves colored `SNAP_OUT/NN-.ans` frames, including within-screen progress. | `SNAP_OUT`, `APP_DIR`, `PROJECT_ID`, `POSTHOG_KEY_FILE` or `POSTHOG_PERSONAL_API_KEY` | | **`wizard-ci-mcp.no-jest.ts`** | Stdio MCP server: `open_app`, `read_state`, `perform_action`, `render_screen`, `run_agent`. Screen output is plain text. | Spawns the host; `open_app` requires `appDir` and `projectId`, with optional `keyFile`, `apiKey`, `region` | +| **`chunk-manifest.no-jest.ts`** | Prints a structural manifest of `dist/`: per chunk, the source files it contains and the chunks it imports, hash suffixes stripped. Baselines live in `scripts/__fixtures__/chunk-manifest.{prod,ci}.json`. | A built `dist/` | | **`wizard-ci-explore.no-jest.ts`** | `pnpm wizard-ci-explore`: opens an app, confirms setup, reads state, prints one frame, and exits. It does not run the agent. | `APP_DIR`, `PROJECT_ID`; optional `POSTHOG_KEY_FILE` | > You usually don't call these directly — `pnpm wizard-ci-snapshots` (in diff --git a/scripts/chunk-manifest.no-jest.ts b/scripts/chunk-manifest.no-jest.ts new file mode 100644 index 000000000..623c2e064 --- /dev/null +++ b/scripts/chunk-manifest.no-jest.ts @@ -0,0 +1,40 @@ +/** + * Structural manifest of the built bundle: for every chunk in dist/, the + * source files it contains (from its sourcemap) and the chunks it imports. + * Hash suffixes are stripped so the output is stable across builds. + * + * tsx scripts/chunk-manifest.no-jest.ts [distDir] > manifest.json + */ +import fs from 'fs'; +import path from 'path'; + +const dist = path.resolve(process.argv[2] ?? 'dist'); +const root = path.resolve(dist, '..'); + +const stripHash = (file: string): string => + file.replace(/-[A-Za-z0-9_-]{8}\.js$/, '.js'); + +const importRe = /(?:from\s*|import\s*\(\s*)["']\.\/([^"']+\.js)["']/g; + +const manifest: Record = {}; + +for (const file of fs + .readdirSync(dist) + .filter((f) => f.endsWith('.js')) + .sort()) { + const code = fs.readFileSync(path.join(dist, file), 'utf8'); + const mapPath = path.join(dist, `${file}.map`); + const sources = fs.existsSync(mapPath) + ? ( + JSON.parse(fs.readFileSync(mapPath, 'utf8')) as { sources: string[] } + ).sources + .map((s) => path.relative(root, path.resolve(dist, s))) + .filter((s) => !s.includes('node_modules')) + .sort() + : []; + const imports = new Set(); + for (const m of code.matchAll(importRe)) imports.add(stripHash(m[1])); + manifest[stripHash(file)] = { sources, imports: [...imports].sort() }; +} + +process.stdout.write(JSON.stringify(manifest, null, 2) + '\n'); diff --git a/vitest.config.ts b/vitest.config.ts index 817d2577d..e95dbab94 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -29,6 +29,40 @@ function resolveTsForJs(): Plugin { }; } +// Per-surface Vitest projects keyed by today's directories. Each project runs +// alone with `vitest run --project `; `vitest run` runs them all. +const TESTS = '__tests__/**/*.{js,jsx,ts,tsx}'; +const AGENT_TESTS = [ + `src/lib/agent/**/${TESTS}`, + `src/lib/middleware/**/${TESTS}`, + 'src/lib/__tests__/agent-*.test.ts', + 'src/lib/__tests__/gateway-session.test.ts', + 'src/lib/__tests__/wizard-can-use-tool.test.ts', + 'src/lib/__tests__/yara-*.test.ts', +]; +const TUI_TESTS = [`src/ui/tui/**/${TESTS}`]; +const CLI_TESTS = [ + `src/commands/**/${TESTS}`, + `src/lib/runners/${TESTS}`, + 'src/__tests__/*cli*.test.ts', + 'src/__tests__/wizard.test.ts', + 'src/__tests__/headless-scope.test.ts', +]; +const HARNESS_TESTS = [`e2e-harness/${TESTS}`]; +const ARCH_TESTS = ['src/__tests__/architecture/**/*.{ts,tsx}']; +const EXCLUDE = [ + '**/node_modules/**', + '**/dist/**', + '**/e2e-tests/**', + '**/*.no-jest.*', + '**/*.d.ts', +]; + +const project = (name: string, include: string[], exclude: string[] = []) => ({ + extends: true as const, + test: { name, include, exclude: [...EXCLUDE, ...exclude] }, +}); + export default defineConfig({ plugins: [resolveTsForJs()], // The source targets the React 19 automatic JSX runtime (tsconfig @@ -63,17 +97,17 @@ export default defineConfig({ test: { globals: true, environment: 'node', - include: [ - '**/__tests__/**/*.{test,spec}.{js,jsx,ts,tsx}', - '**/__tests__/**/*.{js,jsx,ts,tsx}', - '**/*.{test,spec}.{js,jsx,ts,tsx}', - ], - exclude: [ - '**/node_modules/**', - '**/dist/**', - '**/e2e-tests/**', - '**/*.no-jest.*', - '**/*.d.ts', + projects: [ + project('agent', AGENT_TESTS), + project('tui', TUI_TESTS), + project('cli', CLI_TESTS), + project('harness', HARNESS_TESTS), + project('architecture', ARCH_TESTS), + project( + 'legacy', + [`src/**/${TESTS}`], + [...AGENT_TESTS, ...TUI_TESTS, ...CLI_TESTS, ...ARCH_TESTS], + ), ], coverage: { provider: 'v8', From 507443e36a699d26ec6c8a005a591f31e2bd0d29 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Fri, 18 Sep 2026 19:08:03 -0400 Subject: [PATCH 3/9] chore(test): capture behavior baselines before the surface split Goldens recorded from the current tree: a frame per screen and overlay at two sizes through the real ScreenContainer, keyboard versus control action session diffs, store invariants, flow traces and screen analytics per program, post auth gate ids, the MCP control state sequence, and prod and CI chunk manifests. The import boundaries test seeds the 72 current violations and fails on new ones or stale entries. Generated-By: PostHog Desktop Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589 --- .../__fixtures__/control-frame-auth.txt | 49 + .../__fixtures__/control-frame-intro.txt | 49 + .../__fixtures__/control-state-baseline.json | 107 ++ scripts/__fixtures__/chunk-manifest.ci.json | 880 +++++++++++++ scripts/__fixtures__/chunk-manifest.prod.json | 880 +++++++++++++ .../architecture/import-boundaries.test.ts | 413 ++++++ .../architecture/known-violations.json | 76 ++ .../__snapshots__/flow-traces.test.ts.snap | 1104 +++++++++++++++++ .../post-auth-gates.test.ts.snap | 28 + .../programs/__tests__/flow-traces.test.ts | 231 ++++ .../__tests__/post-auth-gates.test.ts | 26 + .../frames/agent-skill-intro-120x40.txt | 39 + .../frames/agent-skill-intro-60x15.txt | 9 + .../frames/ai-observability-intro-120x40.txt | 39 + .../frames/ai-observability-intro-60x15.txt | 9 + .../__snapshots__/frames/ai-opt-in-120x40.txt | 39 + .../__snapshots__/frames/ai-opt-in-60x15.txt | 9 + .../frames/audit-intro-120x40.txt | 39 + .../frames/audit-intro-60x15.txt | 9 + .../frames/audit-outro-120x40.txt | 17 + .../frames/audit-outro-60x15.txt | 9 + .../__snapshots__/frames/audit-run-120x40.txt | 39 + .../__snapshots__/frames/audit-run-60x15.txt | 9 + .../__snapshots__/frames/auth-120x40.txt | 39 + .../__snapshots__/frames/auth-60x15.txt | 9 + .../frames/auth-error-120x40.txt | 18 + .../__snapshots__/frames/auth-error-60x15.txt | 9 + .../frames/doctor-intro-120x40.txt | 39 + .../frames/doctor-intro-60x15.txt | 9 + .../frames/doctor-report-120x40.txt | 16 + .../frames/doctor-report-60x15.txt | 9 + .../frames/error-tracking-detect-120x40.txt | 9 + .../frames/error-tracking-detect-60x15.txt | 9 + .../frames/error-tracking-intro-120x40.txt | 39 + .../frames/error-tracking-intro-60x15.txt | 9 + .../__snapshots__/frames/exit-120x40.txt | 3 + .../__snapshots__/frames/exit-60x15.txt | 9 + .../frames/health-check-120x40.txt | 39 + .../frames/health-check-60x15.txt | 9 + .../__snapshots__/frames/intro-120x40.txt | 39 + .../__snapshots__/frames/intro-60x15.txt | 9 + .../frames/keep-skills-120x40.txt | 7 + .../frames/keep-skills-60x15.txt | 9 + .../frames/managed-settings-120x40.txt | 39 + .../frames/managed-settings-60x15.txt | 9 + .../frames/manual-auth-code-120x40.txt | 11 + .../frames/manual-auth-code-60x15.txt | 9 + .../__snapshots__/frames/mcp-120x40.txt | 15 + .../__snapshots__/frames/mcp-60x15.txt | 9 + .../__snapshots__/frames/mcp-add-120x40.txt | 15 + .../__snapshots__/frames/mcp-add-60x15.txt | 9 + .../frames/mcp-remove-120x40.txt | 11 + .../__snapshots__/frames/mcp-remove-60x15.txt | 9 + .../frames/mcp-suggested-prompts-120x40.txt | 39 + .../frames/mcp-suggested-prompts-60x15.txt | 9 + .../frames/metrics-intro-120x40.txt | 39 + .../frames/metrics-intro-60x15.txt | 9 + .../frames/migration-intro-120x40.txt | 39 + .../frames/migration-intro-60x15.txt | 9 + .../frames/mint-failure-120x40.txt | 39 + .../frames/mint-failure-60x15.txt | 9 + .../__snapshots__/frames/outro-120x40.txt | 20 + .../__snapshots__/frames/outro-60x15.txt | 9 + .../frames/port-conflict-120x40.txt | 39 + .../frames/port-conflict-60x15.txt | 9 + .../frames/revenue-intro-120x40.txt | 39 + .../frames/revenue-intro-60x15.txt | 9 + .../__snapshots__/frames/run-120x40.txt | 39 + .../__snapshots__/frames/run-60x15.txt | 9 + .../frames/self-driving-github-120x40.txt | 39 + .../frames/self-driving-github-60x15.txt | 9 + .../frames/self-driving-handoff-120x40.txt | 39 + .../frames/self-driving-handoff-60x15.txt | 9 + .../self-driving-integration-check-120x40.txt | 39 + .../self-driving-integration-check-60x15.txt | 9 + ...self-driving-integration-detect-120x40.txt | 9 + .../self-driving-integration-detect-60x15.txt | 9 + .../frames/self-driving-intro-120x40.txt | 39 + .../frames/self-driving-intro-60x15.txt | 9 + .../frames/session-timeout-120x40.txt | 11 + .../frames/session-timeout-60x15.txt | 9 + .../frames/settings-override-120x40.txt | 39 + .../frames/settings-override-60x15.txt | 9 + .../__snapshots__/frames/setup-120x40.txt | 10 + .../__snapshots__/frames/setup-60x15.txt | 9 + .../frames/slack-connect-120x40.txt | 39 + .../frames/slack-connect-60x15.txt | 9 + .../frames/source-maps-detect-120x40.txt | 9 + .../frames/source-maps-detect-60x15.txt | 9 + .../frames/source-maps-intro-120x40.txt | 39 + .../frames/source-maps-intro-60x15.txt | 9 + .../frames/source-maps-outro-120x40.txt | 24 + .../frames/source-maps-outro-60x15.txt | 9 + .../frames/task-notice-120x40.txt | 39 + .../frames/task-notice-60x15.txt | 9 + .../frames/warehouse-intro-120x40.txt | 39 + .../frames/warehouse-intro-60x15.txt | 9 + .../frames/wizard-ask-120x40.txt | 39 + .../__snapshots__/frames/wizard-ask-60x15.txt | 9 + .../keyboard-equivalence.test.tsx.snap | 241 ++++ src/ui/tui/__tests__/frames.test.tsx | 587 +++++++++ .../helpers/render-screen.no-jest.tsx | 60 + .../__tests__/keyboard-equivalence.test.tsx | 457 +++++++ src/ui/tui/__tests__/store-invariants.test.ts | 873 +++++++++++++ 104 files changed, 7754 insertions(+) create mode 100644 e2e-harness/__fixtures__/control-frame-auth.txt create mode 100644 e2e-harness/__fixtures__/control-frame-intro.txt create mode 100644 e2e-harness/__fixtures__/control-state-baseline.json create mode 100644 scripts/__fixtures__/chunk-manifest.ci.json create mode 100644 scripts/__fixtures__/chunk-manifest.prod.json create mode 100644 src/__tests__/architecture/import-boundaries.test.ts create mode 100644 src/__tests__/architecture/known-violations.json create mode 100644 src/lib/programs/__tests__/__snapshots__/flow-traces.test.ts.snap create mode 100644 src/lib/programs/__tests__/__snapshots__/post-auth-gates.test.ts.snap create mode 100644 src/lib/programs/__tests__/flow-traces.test.ts create mode 100644 src/lib/programs/__tests__/post-auth-gates.test.ts create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/agent-skill-intro-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/agent-skill-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/ai-observability-intro-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/ai-observability-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/ai-opt-in-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/ai-opt-in-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/audit-intro-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/audit-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/audit-outro-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/audit-outro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/audit-run-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/audit-run-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/auth-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/auth-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/auth-error-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/auth-error-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/doctor-intro-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/doctor-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/doctor-report-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/doctor-report-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/error-tracking-detect-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/error-tracking-detect-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/error-tracking-intro-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/error-tracking-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/exit-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/exit-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/health-check-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/health-check-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/intro-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/keep-skills-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/keep-skills-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/managed-settings-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/managed-settings-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/manual-auth-code-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/manual-auth-code-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/mcp-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/mcp-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/mcp-add-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/mcp-add-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/mcp-remove-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/mcp-remove-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/mcp-suggested-prompts-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/mcp-suggested-prompts-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/metrics-intro-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/metrics-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/migration-intro-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/migration-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/mint-failure-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/mint-failure-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/outro-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/outro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/port-conflict-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/port-conflict-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/run-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/run-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/self-driving-github-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/self-driving-github-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/self-driving-handoff-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/self-driving-handoff-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-check-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-check-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-detect-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-detect-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/self-driving-intro-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/self-driving-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/session-timeout-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/session-timeout-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/settings-override-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/settings-override-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/setup-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/setup-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/slack-connect-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/slack-connect-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/source-maps-detect-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/source-maps-detect-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/source-maps-intro-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/source-maps-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/source-maps-outro-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/source-maps-outro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/task-notice-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/task-notice-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/warehouse-intro-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/warehouse-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/wizard-ask-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/wizard-ask-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/keyboard-equivalence.test.tsx.snap create mode 100644 src/ui/tui/__tests__/frames.test.tsx create mode 100644 src/ui/tui/__tests__/helpers/render-screen.no-jest.tsx create mode 100644 src/ui/tui/__tests__/keyboard-equivalence.test.tsx create mode 100644 src/ui/tui/__tests__/store-invariants.test.ts diff --git a/e2e-harness/__fixtures__/control-frame-auth.txt b/e2e-harness/__fixtures__/control-frame-auth.txt new file mode 100644 index 000000000..644e86286 --- /dev/null +++ b/e2e-harness/__fixtures__/control-frame-auth.txt @@ -0,0 +1,49 @@ + PostHog Wizard v2.76.0 Feedback: wizard@posthog.com + + PostHog Setup Wizard + ✔ Framework: Node.js + + Privacy & data + • Source files are read by Claude for AI context + • .env* and secrets stay on your machine + • Press [I] for full privacy & usage info + + ⠴ Waiting for authentication... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + I privacy & data diff --git a/e2e-harness/__fixtures__/control-frame-intro.txt b/e2e-harness/__fixtures__/control-frame-intro.txt new file mode 100644 index 000000000..493bdcb50 --- /dev/null +++ b/e2e-harness/__fixtures__/control-frame-intro.txt @@ -0,0 +1,49 @@ + PostHog Wizard v2.76.0 Feedback: wizard@posthog.com + + + + + + + + + + + + + + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + Review what data is shared in "Privacy & data." + .env* values stay on your machine. + + Let's do two hours of work in eight minutes. + + Directory ✔ /wz-baseline-express-todo + Framework ✔ Node.js (detected) + + ▸ Continue + Change framework + More info + Privacy & data + Cancel + + + + + + + + + + + + + + + + ↑↓ navigate enter select diff --git a/e2e-harness/__fixtures__/control-state-baseline.json b/e2e-harness/__fixtures__/control-state-baseline.json new file mode 100644 index 000000000..9797a94c0 --- /dev/null +++ b/e2e-harness/__fixtures__/control-state-baseline.json @@ -0,0 +1,107 @@ +{ + "recordedFrom": "scripts/tui-host.no-jest.ts MODE=serve via scripts/wizard-ci-mcp.no-jest.ts, wizard 2.76.0", + "app": "wizard-workbench/apps/basic-integration/javascript-node/express-todo (throwaway copy, detection only, no key)", + "projectId": "228144", + "steps": [ + { + "call": "open_app", + "state": { + "currentScreen": "intro", + "hasOverlay": false, + "runPhase": "idle", + "session": { + "installDir": "", + "integration": "javascript_node", + "detectedFrameworkLabel": "Node.js", + "detectionComplete": true, + "setupConfirmed": false, + "integrate": null, + "hasCredentials": false, + "projectId": null, + "mcpComplete": false, + "slackStepDismissed": false, + "skillsComplete": false, + "outroDismissed": false, + "llmOptIn": false, + "discoveredFeatures": [] + }, + "tasks": [], + "statusMessages": [], + "eventPlan": [], + "pendingQuestion": null, + "taskNotice": null, + "setupQuestions": [], + "actions": [ + { "id": "confirm_setup", "description": "Confirm the intro and continue (sets setupConfirmed)." } + ], + "integration": "idle", + "integrationError": null + } + }, + { + "call": "perform_action", + "action": "confirm_setup", + "state": { + "currentScreen": "auth", + "hasOverlay": false, + "runPhase": "idle", + "session": { + "installDir": "", + "integration": "javascript_node", + "detectedFrameworkLabel": "Node.js", + "detectionComplete": true, + "setupConfirmed": true, + "integrate": null, + "hasCredentials": false, + "projectId": null, + "mcpComplete": false, + "slackStepDismissed": false, + "skillsComplete": false, + "outroDismissed": false, + "llmOptIn": false, + "discoveredFeatures": [] + }, + "tasks": [], + "statusMessages": [], + "eventPlan": [], + "pendingQuestion": null, + "taskNotice": null, + "setupQuestions": [], + "actions": [] + } + }, + { + "call": "read_state", + "state": { + "currentScreen": "auth", + "hasOverlay": false, + "runPhase": "idle", + "session": { + "installDir": "", + "integration": "javascript_node", + "detectedFrameworkLabel": "Node.js", + "detectionComplete": true, + "setupConfirmed": true, + "integrate": null, + "hasCredentials": false, + "projectId": null, + "mcpComplete": false, + "slackStepDismissed": false, + "skillsComplete": false, + "outroDismissed": false, + "llmOptIn": false, + "discoveredFeatures": [] + }, + "tasks": [], + "statusMessages": [], + "eventPlan": [], + "pendingQuestion": null, + "taskNotice": null, + "setupQuestions": [], + "actions": [], + "integration": "idle", + "integrationError": null + } + } + ] +} diff --git a/scripts/__fixtures__/chunk-manifest.ci.json b/scripts/__fixtures__/chunk-manifest.ci.json new file mode 100644 index 000000000..a8ecaa206 --- /dev/null +++ b/scripts/__fixtures__/chunk-manifest.ci.json @@ -0,0 +1,880 @@ +{ + "add-mcp-server-to-clients.js": { + "sources": [ + "src/steps/add-mcp-server-to-clients/MCPClient.ts", + "src/steps/add-mcp-server-to-clients/clients/claude-code.ts", + "src/steps/add-mcp-server-to-clients/clients/claude-web.ts", + "src/steps/add-mcp-server-to-clients/clients/codex.ts", + "src/steps/add-mcp-server-to-clients/clients/cursor.ts", + "src/steps/add-mcp-server-to-clients/clients/opencode.ts", + "src/steps/add-mcp-server-to-clients/clients/visual-studio-code.ts", + "src/steps/add-mcp-server-to-clients/clients/zed.ts", + "src/steps/add-mcp-server-to-clients/index.ts", + "src/steps/add-mcp-server-to-clients/plugin-client.ts" + ], + "imports": [ + "analytics.js", + "debug.js", + "defaults.js", + "rolldown-runtime.js", + "telemetry.js" + ] + }, + "agent-interface.js": { + "sources": [ + "src/lib/agent/agent-env-isolation.ts", + "src/lib/agent/agent-interface.ts", + "src/lib/agent/agent-phase.ts", + "src/lib/agent/bash-fence.ts", + "src/lib/agent/claude-settings.ts", + "src/lib/agent/commandments.ts", + "src/lib/agent/output-signals.ts", + "src/lib/agent/runner/harness/pi/gateway.ts", + "src/lib/agent/runner/harness/pi/runtime-notes.ts", + "src/lib/agent/runner/switchboard/commandments.ts", + "src/lib/agent/stored-login.ts", + "src/lib/agent/triage-provider.ts", + "src/lib/auth-session-state.ts", + "src/lib/fetch-retry.ts", + "src/lib/safe-tools.ts", + "src/lib/secret-vault.ts", + "src/lib/wizard-ask-bridge.ts", + "src/lib/wizard-tools/handoff.ts", + "src/lib/wizard-tools/mcp.ts", + "src/lib/wizard-tools/tools.ts", + "src/utils/custom-headers.ts", + "src/utils/env-scan.ts" + ], + "imports": [ + "analytics.js", + "bounded-fs.js", + "debug.js", + "errors.js", + "gateway-session.js", + "queue-tools.js", + "rolldown-runtime.js", + "wizard-abort.js", + "wizard-session.js", + "yara-hooks.js" + ] + }, + "agent-prompt-loader.js": { + "sources": ["src/lib/agent/agent-prompt-loader.ts"], + "imports": [ + "agent-interface.js", + "analytics.js", + "debug.js", + "queue-tools.js" + ] + }, + "agent-runner.js": { + "sources": [ + "src/lib/agent/agent-prompt.ts", + "src/lib/agent/agent-runner.ts", + "src/lib/agent/runner/harness/anthropic/index.ts", + "src/lib/agent/runner/index.ts", + "src/lib/agent/runner/sequence/linear.ts", + "src/lib/agent/runner/sequence/orchestrator/executor.ts", + "src/lib/agent/runner/sequence/orchestrator/orchestrator-runner.ts", + "src/lib/agent/runner/sequence/orchestrator/run-metrics.ts", + "src/lib/agent/runner/sequence/orchestrator/seeded-deps.ts", + "src/lib/agent/runner/shared/authenticate.ts", + "src/lib/agent/runner/shared/bootstrap.ts", + "src/lib/agent/runner/shared/errors.ts", + "src/lib/agent/runner/switchboard/flags/index.ts", + "src/lib/agent/runner/switchboard/flags/orchestrator.ts", + "src/lib/agent/runner/switchboard/flags/schemes.ts", + "src/lib/agent/runner/switchboard/flags/self-driving.ts", + "src/lib/agent/runner/switchboard/harness.ts", + "src/lib/agent/runner/switchboard/index.ts", + "src/lib/agent/runner/switchboard/sequence.ts", + "src/lib/agent/token-pricing.ts", + "src/lib/detection/agentic.ts", + "src/lib/detection/context.ts", + "src/lib/detection/features.ts", + "src/lib/detection/framework.ts", + "src/lib/middleware/benchmark.ts", + "src/lib/middleware/benchmarks/cache-tracker.ts", + "src/lib/middleware/benchmarks/compaction-tracker.ts", + "src/lib/middleware/benchmarks/context-size-tracker.ts", + "src/lib/middleware/benchmarks/cost-tracker.ts", + "src/lib/middleware/benchmarks/duration-tracker.ts", + "src/lib/middleware/benchmarks/index.ts", + "src/lib/middleware/benchmarks/json-writer.ts", + "src/lib/middleware/benchmarks/summary.ts", + "src/lib/middleware/benchmarks/token-tracker.ts", + "src/lib/middleware/benchmarks/turn-counter.ts", + "src/lib/middleware/config.ts", + "src/lib/middleware/phase-detector.ts", + "src/lib/middleware/pipeline.ts", + "src/lib/programs/audit/ledger-watcher.ts", + "src/lib/programs/posthog-integration/detect.ts", + "src/lib/programs/shared/package-scanning.ts", + "src/lib/programs/warehouse-source/detect.ts", + "src/lib/warehouse-sources/detect.ts", + "src/lib/warehouse-sources/registry.ts", + "src/utils/terminal-bell.ts" + ], + "imports": [ + "agent-interface.js", + "agent-prompt-loader.js", + "analytics.js", + "bounded-fs.js", + "debug.js", + "environment.js", + "errors.js", + "file-watcher.js", + "gateway-session.js", + "package-manager.js", + "pi.js", + "queue-tools.js", + "registry.js", + "rolldown-runtime.js", + "setup-utils.js", + "wizard-abort.js", + "wizard-session.js", + "yara-hooks.js" + ] + }, + "analytics.js": { + "sources": ["src/utils/analytics.ts", "src/utils/ci-flag-overrides.ts"], + "imports": ["debug.js", "wizard-session.js"] + }, + "api.js": { + "sources": ["src/lib/api.ts"], + "imports": ["analytics.js", "debug.js", "rolldown-runtime.js"] + }, + "bin.js": { + "sources": [ + "bin.ts", + "src/commands/ai-observability.ts", + "src/commands/audit.ts", + "src/commands/basic-integration/index.ts", + "src/commands/basic-integration/skill.ts", + "src/commands/cli/add.ts", + "src/commands/cli/index.ts", + "src/commands/command.ts", + "src/commands/doctor.ts", + "src/commands/error-tracking.ts", + "src/commands/factories/family-command-factory.ts", + "src/commands/factories/family-picker.tsx", + "src/commands/factories/native-command-factory.ts", + "src/commands/factories/shared.ts", + "src/commands/mcp-analytics.ts", + "src/commands/mcp/add.ts", + "src/commands/mcp/index.ts", + "src/commands/mcp/remove.ts", + "src/commands/mcp/tui-availability.ts", + "src/commands/mcp/tutorial.ts", + "src/commands/metrics.ts", + "src/commands/migrate.ts", + "src/commands/provision.ts", + "src/commands/replay-vision.ts", + "src/commands/revenue.ts", + "src/commands/self-driving.ts", + "src/commands/skill-program-options.ts", + "src/commands/skill.ts", + "src/commands/slack.ts", + "src/commands/upload-sourcemaps.ts", + "src/commands/warehouse.ts", + "src/lib/programs/dispatch-family.ts", + "src/lib/runners/resolve-no-telemetry.ts", + "src/lib/runners/run-non-interactive.ts", + "src/lib/runners/run-wizard-ci.ts", + "src/lib/runners/run-wizard-headless.ts", + "src/lib/runners/run-wizard.ts", + "src/ui/tui/hooks/keyboard-hints-utils.ts", + "src/ui/tui/hooks/useKeyBindings.ts", + "src/ui/tui/hooks/useKeyboardHints.tsx", + "src/ui/tui/hooks/useStdoutDimensions.ts", + "src/ui/tui/primitives/ConfirmButton.tsx", + "src/ui/tui/primitives/PickerMenu.tsx", + "src/ui/tui/primitives/PromptLabel.tsx", + "src/ui/tui/primitives/picker-filter.ts", + "src/wizard.ts" + ], + "imports": [ + "add-mcp-server-to-clients.js", + "agent-interface.js", + "agent-runner.js", + "analytics.js", + "api.js", + "ci-install.js", + "debug.js", + "env-api-key.js", + "environment.js", + "errors.js", + "file.js", + "gateway-session.js", + "headless-ui.js", + "interactive.js", + "local-dev.js", + "mint-failure.js", + "non-interactive.js", + "playground.js", + "posthog.js", + "provisioning.js", + "setup-utils.js", + "start-tui.js", + "store.js", + "task-stream.js", + "telemetry.js", + "wizard-abort.js", + "wizard-session.js", + "yara-hooks.js" + ] + }, + "bounded-fs.js": { + "sources": ["src/utils/bounded-fs.ts"], + "imports": ["analytics.js", "debug.js"] + }, + "ci-install.js": { + "sources": ["src/commands/basic-integration/ci-install.ts"], + "imports": [ + "bin.js", + "debug.js", + "errors.js", + "mint-failure.js", + "provisioning.js" + ] + }, + "debug.js": { + "sources": [ + "src/env.ts", + "src/lib/constants.ts", + "src/lib/headless-mode.ts", + "src/lib/health-checks/endpoints.ts", + "src/lib/health-checks/readiness.ts", + "src/lib/version.ts", + "src/ui/index.ts", + "src/ui/logging-ui.ts", + "src/ui/wizard-ui.ts", + "src/utils/debug.ts", + "src/utils/paths.ts" + ], + "imports": ["analytics.js", "local-dev.js"] + }, + "defaults.js": { + "sources": [ + "src/steps/add-mcp-server-to-clients/defaults.ts", + "src/steps/add-mcp-server-to-clients/results.ts" + ], + "imports": [] + }, + "env-api-key.js": { + "sources": ["src/utils/env-api-key.ts"], + "imports": ["bounded-fs.js", "rolldown-runtime.js"] + }, + "environment.js": { + "sources": ["src/utils/environment.ts"], + "imports": ["rolldown-runtime.js"] + }, + "errors.js": { + "sources": [ + "src/lib/agent/signals.ts", + "src/lib/errors/agent-map.ts", + "src/lib/errors/auth.ts", + "src/lib/errors/catalog.ts", + "src/lib/errors/codes.ts", + "src/lib/errors/detect-map.ts", + "src/lib/errors/emit.ts", + "src/lib/errors/run-failure.ts", + "src/lib/errors/sanitize.ts", + "src/lib/errors/skill-map.ts" + ], + "imports": [] + }, + "file.js": { + "sources": ["src/lib/task-stream/destinations/file.ts"], + "imports": ["debug.js"] + }, + "file-watcher.js": { + "sources": ["src/lib/file-watcher.ts"], + "imports": ["debug.js"] + }, + "gateway-session.js": { + "sources": [], + "imports": ["gateway-session.js"] + }, + "headless-ui.js": { + "sources": ["src/ui/headless-ui.ts"], + "imports": ["debug.js"] + }, + "interactive.js": { + "sources": ["src/commands/basic-integration/interactive.ts"], + "imports": ["bin.js", "mint-failure.js"] + }, + "local-dev.js": { + "sources": ["src/lib/local-dev.ts"], + "imports": [] + }, + "mcp.js": { + "sources": ["src/lib/agent/runner/harness/pi/mcp.ts"], + "imports": ["debug.js"] + }, + "mcp-prompt-streaming.js": { + "sources": ["src/lib/agent/mcp-prompt-streaming.ts"], + "imports": [ + "agent-interface.js", + "analytics.js", + "debug.js", + "gateway-session.js" + ] + }, + "mint-failure.js": { + "sources": [ + "src/lib/detection/project-scope.ts", + "src/lib/programs/agent-skill/content/index.tsx", + "src/lib/programs/agent-skill/index.ts", + "src/lib/programs/agent-skill/steps.ts", + "src/lib/programs/ai-observability/index.ts", + "src/lib/programs/audit/detect.ts", + "src/lib/programs/audit/index.ts", + "src/lib/programs/audit/seed.ts", + "src/lib/programs/error-tracking-upload-source-maps/content/index.tsx", + "src/lib/programs/error-tracking-upload-source-maps/detect.ts", + "src/lib/programs/error-tracking-upload-source-maps/index.ts", + "src/lib/programs/error-tracking-upload-source-maps/prompt.ts", + "src/lib/programs/error-tracking-upload-source-maps/steps.ts", + "src/lib/programs/error-tracking/content/index.tsx", + "src/lib/programs/error-tracking/content/tips.ts", + "src/lib/programs/error-tracking/detect-agentic.ts", + "src/lib/programs/error-tracking/index.ts", + "src/lib/programs/events-audit/index.ts", + "src/lib/programs/events-audit/seed.ts", + "src/lib/programs/events-audit/steps.ts", + "src/lib/programs/mcp-analytics/index.ts", + "src/lib/programs/mcp/index.ts", + "src/lib/programs/metrics/index.ts", + "src/lib/programs/migration/content/free-tier.tsx", + "src/lib/programs/migration/content/index.tsx", + "src/lib/programs/migration/content/pricing-structure.tsx", + "src/lib/programs/migration/content/vendor-stack.tsx", + "src/lib/programs/migration/index.ts", + "src/lib/programs/migration/steps.ts", + "src/lib/programs/posthog-doctor/fetch.ts", + "src/lib/programs/posthog-doctor/index.ts", + "src/lib/programs/posthog-doctor/kind-metadata.ts", + "src/lib/programs/posthog-doctor/steps.ts", + "src/lib/programs/posthog-doctor/types.ts", + "src/lib/programs/posthog-integration/content/data-flow.tsx", + "src/lib/programs/posthog-integration/content/funnel.tsx", + "src/lib/programs/posthog-integration/content/index.tsx", + "src/lib/programs/posthog-integration/content/line-chart.tsx", + "src/lib/programs/posthog-integration/content/product-suite.tsx", + "src/lib/programs/posthog-integration/handoff.ts", + "src/lib/programs/posthog-integration/index.ts", + "src/lib/programs/posthog-integration/steps.ts", + "src/lib/programs/program-registry.ts", + "src/lib/programs/replay-vision/index.ts", + "src/lib/programs/revenue-analytics/detect.ts", + "src/lib/programs/revenue-analytics/index.ts", + "src/lib/programs/revenue-analytics/steps.ts", + "src/lib/programs/self-driving/content/index.tsx", + "src/lib/programs/self-driving/content/pipeline-diagram.tsx", + "src/lib/programs/self-driving/content/pricing.ts", + "src/lib/programs/self-driving/content/tips.ts", + "src/lib/programs/self-driving/detect-agentic.ts", + "src/lib/programs/self-driving/detect.ts", + "src/lib/programs/self-driving/index.ts", + "src/lib/programs/self-driving/prompt.ts", + "src/lib/programs/self-driving/step-keys.ts", + "src/lib/programs/self-driving/steps.ts", + "src/lib/programs/shared/health-check-step.ts", + "src/lib/programs/shared/posthog-cli-preinstall.ts", + "src/lib/programs/slack/index.ts", + "src/lib/programs/warehouse-source/index.ts", + "src/lib/programs/warehouse-source/steps.ts", + "src/lib/programs/web-analytics-doctor/detect.ts", + "src/lib/programs/web-analytics-doctor/index.ts", + "src/lib/programs/web-analytics-doctor/steps.ts", + "src/steps/install-cli-steering/index.ts", + "src/ui/mint-failure.ts", + "src/ui/tui/components/StatusPeekTrigger.tsx", + "src/ui/tui/primitives/TextBlock.tsx", + "src/ui/tui/primitives/content-types.ts", + "src/ui/tui/primitives/layout-helpers.ts", + "src/ui/tui/primitives/text-helpers.ts", + "src/ui/tui/styles.ts" + ], + "imports": [ + "agent-interface.js", + "agent-runner.js", + "analytics.js", + "api.js", + "debug.js", + "errors.js", + "package-json.js", + "provisioning.js", + "queue-tools.js", + "registry.js", + "setup-utils.js", + "steps.js", + "telemetry.js", + "wizard-abort.js", + "wizard-session.js", + "yara-hooks.js" + ] + }, + "non-interactive.js": { + "sources": ["src/commands/basic-integration/non-interactive.ts"], + "imports": ["debug.js", "errors.js"] + }, + "orchestrator-tools.js": { + "sources": ["src/lib/agent/runner/harness/pi/orchestrator-tools.ts"], + "imports": ["analytics.js", "queue-tools.js"] + }, + "package-json.js": { + "sources": ["src/utils/package-json.ts"], + "imports": ["rolldown-runtime.js"] + }, + "package-manager.js": { + "sources": [ + "src/frameworks/python/utils.ts", + "src/lib/detection/package-manager.ts" + ], + "imports": ["setup-utils.js"] + }, + "pi.js": { + "sources": [ + "src/lib/agent/aio-capture.ts", + "src/lib/agent/runner/harness/pi/completion.ts", + "src/lib/agent/runner/harness/pi/index.ts" + ], + "imports": [ + "agent-interface.js", + "analytics.js", + "debug.js", + "errors.js", + "gateway-session.js", + "mcp.js", + "security.js", + "subagent.js", + "task.js", + "tasks.js", + "tools.js", + "yara-hooks.js" + ] + }, + "playground.js": { + "sources": [ + "src/commands/basic-integration/playground.ts", + "src/ui/tui/playground/PlaygroundApp.tsx", + "src/ui/tui/playground/demos/AiOptInDemo.tsx", + "src/ui/tui/playground/demos/AskModalDemo.tsx", + "src/ui/tui/playground/demos/AuditChecksDemo.tsx", + "src/ui/tui/playground/demos/DoctorReportDemo.tsx", + "src/ui/tui/playground/demos/EndScreensDemo.tsx", + "src/ui/tui/playground/demos/HealthCheckDemo.tsx", + "src/ui/tui/playground/demos/InputDemo.tsx", + "src/ui/tui/playground/demos/KeyboardHintsDemo.tsx", + "src/ui/tui/playground/demos/LayoutDemo.tsx", + "src/ui/tui/playground/demos/LearnDeckDemo.tsx", + "src/ui/tui/playground/demos/LogDemo.tsx", + "src/ui/tui/playground/demos/McpDemo.tsx", + "src/ui/tui/playground/demos/McpSuggestedPromptsDemo.tsx", + "src/ui/tui/playground/demos/ModalDemo.tsx", + "src/ui/tui/playground/demos/ProgressDemo.tsx", + "src/ui/tui/playground/demos/RunScreenDemo.tsx", + "src/ui/tui/playground/demos/ViewportGuardDemo.tsx", + "src/ui/tui/playground/demos/WelcomeDemo.tsx", + "src/ui/tui/playground/start-playground.ts" + ], + "imports": [ + "bin.js", + "debug.js", + "mint-failure.js", + "setup-utils.js", + "store.js", + "terminal.js" + ] + }, + "posthog.js": { + "sources": ["src/lib/task-stream/destinations/posthog.ts"], + "imports": ["debug.js"] + }, + "provisioning.js": { + "sources": ["src/utils/provisioning.ts", "src/utils/urls.ts"], + "imports": ["analytics.js", "debug.js", "rolldown-runtime.js"] + }, + "queue-tools.js": { + "sources": [ + "src/lib/agent/runner/sequence/orchestrator/queue-tools.ts", + "src/lib/agent/runner/sequence/orchestrator/queue.ts", + "src/lib/agent/runner/switchboard/models.ts", + "src/utils/atomic-ledger.ts" + ], + "imports": ["analytics.js", "debug.js"] + }, + "registry.js": { + "sources": [ + "src/frameworks/android/android-wizard-agent.ts", + "src/frameworks/android/utils.ts", + "src/frameworks/angular/angular-wizard-agent.ts", + "src/frameworks/angular/utils.ts", + "src/frameworks/astro/astro-wizard-agent.ts", + "src/frameworks/astro/utils.ts", + "src/frameworks/django/django-wizard-agent.ts", + "src/frameworks/django/utils.ts", + "src/frameworks/elixir/elixir-wizard-agent.ts", + "src/frameworks/fastapi/fastapi-wizard-agent.ts", + "src/frameworks/fastapi/utils.ts", + "src/frameworks/flask/flask-wizard-agent.ts", + "src/frameworks/flask/utils.ts", + "src/frameworks/flutter/flutter-wizard-agent.ts", + "src/frameworks/go/go-wizard-agent.ts", + "src/frameworks/java/java-wizard-agent.ts", + "src/frameworks/javascript-node/javascript-node-wizard-agent.ts", + "src/frameworks/javascript-web/javascript-web-wizard-agent.ts", + "src/frameworks/javascript-web/utils.ts", + "src/frameworks/kmp/kmp-wizard-agent.ts", + "src/frameworks/laravel/laravel-wizard-agent.ts", + "src/frameworks/laravel/utils.ts", + "src/frameworks/nextjs/nextjs-wizard-agent.ts", + "src/frameworks/nextjs/utils.ts", + "src/frameworks/nuxt/nuxt-wizard-agent.ts", + "src/frameworks/python/python-wizard-agent.ts", + "src/frameworks/rails/rails-wizard-agent.ts", + "src/frameworks/rails/utils.ts", + "src/frameworks/react-native/react-native-wizard-agent.ts", + "src/frameworks/react-native/utils.ts", + "src/frameworks/react-router/react-router-wizard-agent.ts", + "src/frameworks/react-router/utils.ts", + "src/frameworks/ruby/ruby-wizard-agent.ts", + "src/frameworks/ruby/utils.ts", + "src/frameworks/rust/rust-wizard-agent.ts", + "src/frameworks/svelte/svelte-wizard-agent.ts", + "src/frameworks/swift/swift-wizard-agent.ts", + "src/frameworks/swift/utils.ts", + "src/frameworks/tanstack-router/tanstack-router-wizard-agent.ts", + "src/frameworks/tanstack-router/utils.ts", + "src/frameworks/tanstack-start/tanstack-start-wizard-agent.ts", + "src/frameworks/tanstack-start/utils.ts", + "src/frameworks/vue/vue-wizard-agent.ts", + "src/lib/framework-config.ts", + "src/lib/registry.ts" + ], + "imports": [ + "bounded-fs.js", + "debug.js", + "package-json.js", + "package-manager.js", + "rolldown-runtime.js", + "setup-utils.js" + ] + }, + "rolldown-runtime.js": { + "sources": [], + "imports": [] + }, + "security.js": { + "sources": ["src/lib/agent/runner/harness/pi/security.ts"], + "imports": [ + "agent-interface.js", + "analytics.js", + "debug.js", + "yara-hooks.js" + ] + }, + "setup-utils.js": { + "sources": [ + "src/lib/host-resolution.ts", + "src/lib/oauth/program-scopes.ts", + "src/utils/oauth-errors.ts", + "src/utils/oauth.ts", + "src/utils/package-manager.ts", + "src/utils/project-resolution.ts", + "src/utils/semver.ts", + "src/utils/setup-utils.ts" + ], + "imports": [ + "analytics.js", + "api.js", + "bounded-fs.js", + "debug.js", + "local-dev.js", + "provisioning.js", + "rolldown-runtime.js", + "telemetry.js", + "wizard-abort.js" + ] + }, + "start-tui.js": { + "sources": [ + "src/lib/programs/error-tracking-upload-source-maps/detect-agentic.ts", + "src/lib/wizard-spellbook.ts", + "src/steps/add-mcp-server-to-clients/browser-client.ts", + "src/steps/add-mcp-server-to-clients/login-client.ts", + "src/ui/tui/App.tsx", + "src/ui/tui/components/PrivacyPanel.tsx", + "src/ui/tui/exit-line.ts", + "src/ui/tui/hooks/useGithubConnection.ts", + "src/ui/tui/ink-ui.ts", + "src/ui/tui/posthog-integration-intro.ts", + "src/ui/tui/screen-registry.tsx", + "src/ui/tui/screens/AgentSkillIntroScreen.tsx", + "src/ui/tui/screens/AiObservabilityIntroScreen.tsx", + "src/ui/tui/screens/AuthErrorScreen.tsx", + "src/ui/tui/screens/AuthScreen.tsx", + "src/ui/tui/screens/ErrorTrackingDetectScreen.tsx", + "src/ui/tui/screens/ErrorTrackingIntroScreen.tsx", + "src/ui/tui/screens/ExitScreen.tsx", + "src/ui/tui/screens/IntroScreenLayout.tsx", + "src/ui/tui/screens/KeepSkillsScreen.tsx", + "src/ui/tui/screens/ManagedSettingsScreen.tsx", + "src/ui/tui/screens/ManualAuthCodeScreen.tsx", + "src/ui/tui/screens/MetricsIntroScreen.tsx", + "src/ui/tui/screens/MigrationIntroScreen.tsx", + "src/ui/tui/screens/MintFailureScreen.tsx", + "src/ui/tui/screens/PortConflictScreen.tsx", + "src/ui/tui/screens/PostHogIntegrationIntroScreen.tsx", + "src/ui/tui/screens/RevenueIntroScreen.tsx", + "src/ui/tui/screens/RunScreen.tsx", + "src/ui/tui/screens/SelfDrivingGitHubScreen.tsx", + "src/ui/tui/screens/SelfDrivingHandoffScreen.tsx", + "src/ui/tui/screens/SelfDrivingIntegrationCheckScreen.tsx", + "src/ui/tui/screens/SelfDrivingIntegrationDetectScreen.tsx", + "src/ui/tui/screens/SelfDrivingIntroScreen.tsx", + "src/ui/tui/screens/SessionTimeoutScreen.tsx", + "src/ui/tui/screens/SettingsOverrideScreen.tsx", + "src/ui/tui/screens/SetupScreen.tsx", + "src/ui/tui/screens/SourceMapsDetectScreen.tsx", + "src/ui/tui/screens/SourceMapsIntroScreen.tsx", + "src/ui/tui/screens/SourceMapsOutroScreen.tsx", + "src/ui/tui/screens/TaskNoticeScreen.tsx", + "src/ui/tui/screens/WarehouseIntroScreen.tsx", + "src/ui/tui/screens/WizardAskScreen.tsx", + "src/ui/tui/screens/audit/AuditAreaPane.tsx", + "src/ui/tui/screens/audit/AuditChecksOutroSection.tsx", + "src/ui/tui/screens/audit/AuditIntroScreen.tsx", + "src/ui/tui/screens/audit/AuditOutroScreen.tsx", + "src/ui/tui/screens/audit/AuditRunScreen.tsx", + "src/ui/tui/screens/audit/PendingChecksList.tsx", + "src/ui/tui/screens/audit/slides/events-audit/createDashboard.tsx", + "src/ui/tui/screens/audit/slides/events-audit/detectSdk.tsx", + "src/ui/tui/screens/audit/slides/events-audit/enrichSites.tsx", + "src/ui/tui/screens/audit/slides/events-audit/index.ts", + "src/ui/tui/screens/audit/slides/events-audit/queryVolume.tsx", + "src/ui/tui/screens/audit/slides/events-audit/scanSites.tsx", + "src/ui/tui/screens/audit/slides/events-audit/uploadNotebook.tsx", + "src/ui/tui/screens/audit/slides/events-audit/writeReport.tsx", + "src/ui/tui/screens/doctor/DoctorIntroScreen.tsx", + "src/ui/tui/screens/doctor/DoctorReportScreen.tsx", + "src/ui/tui/screens/health/HealthCheckScreen.tsx", + "src/ui/tui/services/coding-agent-launcher.ts", + "src/ui/tui/services/mcp-installer.ts", + "src/ui/tui/services/mcp-suggested-prompts-services.ts", + "src/ui/tui/start-tui.ts", + "src/utils/clipboard.ts" + ], + "imports": [ + "add-mcp-server-to-clients.js", + "agent-interface.js", + "agent-runner.js", + "analytics.js", + "api.js", + "bin.js", + "bounded-fs.js", + "debug.js", + "defaults.js", + "errors.js", + "mcp-prompt-streaming.js", + "mint-failure.js", + "provisioning.js", + "registry.js", + "setup-utils.js", + "store.js", + "telemetry.js", + "terminal.js", + "wizard-abort.js", + "wizard-session.js", + "yara-hooks.js" + ] + }, + "steps.js": { + "sources": [ + "src/steps/upload-environment-variables/EnvironmentProvider.ts", + "src/steps/upload-environment-variables/index.ts", + "src/steps/upload-environment-variables/providers/vercel.ts" + ], + "imports": ["analytics.js", "debug.js", "telemetry.js"] + }, + "store.js": { + "sources": [ + "src/lib/programs/ai-opt-in-gate.ts", + "src/lib/programs/program-step.ts", + "src/ui/tui/router.ts", + "src/ui/tui/screen-sequences.ts", + "src/ui/tui/store.ts" + ], + "imports": [ + "agent-runner.js", + "analytics.js", + "debug.js", + "mint-failure.js", + "rolldown-runtime.js", + "wizard-session.js" + ] + }, + "subagent.js": { + "sources": ["src/lib/agent/runner/harness/pi/subagent.ts"], + "imports": ["debug.js"] + }, + "task.js": { + "sources": ["src/lib/agent/runner/harness/pi/task.ts"], + "imports": [ + "agent-interface.js", + "agent-prompt-loader.js", + "analytics.js", + "debug.js", + "errors.js", + "gateway-session.js", + "mcp.js", + "orchestrator-tools.js", + "pi.js", + "queue-tools.js", + "security.js", + "tools.js", + "yara-hooks.js" + ] + }, + "task-stream.js": { + "sources": [ + "src/lib/task-stream/audit-areas.ts", + "src/lib/task-stream/event-plan-watcher.ts", + "src/lib/task-stream/task-stream-push.ts" + ], + "imports": [ + "debug.js", + "errors.js", + "file-watcher.js", + "file.js", + "posthog.js" + ] + }, + "tasks.js": { + "sources": ["src/lib/agent/runner/harness/pi/tasks.ts"], + "imports": ["debug.js"] + }, + "telemetry.js": { + "sources": ["src/telemetry.ts", "src/utils/links.ts"], + "imports": ["analytics.js"] + }, + "terminal.js": { + "sources": [ + "src/lib/mcp-project-profile.ts", + "src/lib/mcp-role-prompts.copy.json", + "src/lib/mcp-role-prompts.ts", + "src/lib/mcp-seed-events.ts", + "src/ui/tui/components/LearnCard.tsx", + "src/ui/tui/components/PhaseVisuals.tsx", + "src/ui/tui/components/ServiceHealthList.tsx", + "src/ui/tui/components/TipsCard.tsx", + "src/ui/tui/components/TitleBar.tsx", + "src/ui/tui/components/TokenCostHud.tsx", + "src/ui/tui/components/visualizer/CrateStack.tsx", + "src/ui/tui/components/visualizer/DashboardGrid.tsx", + "src/ui/tui/components/visualizer/DiffCascade.tsx", + "src/ui/tui/components/visualizer/LibraryShelf.tsx", + "src/ui/tui/components/visualizer/MatrixRain.tsx", + "src/ui/tui/components/visualizer/Tumblers.tsx", + "src/ui/tui/components/visualizer/grid.ts", + "src/ui/tui/components/visualizer/palette.ts", + "src/ui/tui/components/visualizer/panel.tsx", + "src/ui/tui/hooks/useDismissOnAnyKey.ts", + "src/ui/tui/hooks/useTick.ts", + "src/ui/tui/primitives/CardLayout.tsx", + "src/ui/tui/primitives/ConfirmationInput.tsx", + "src/ui/tui/primitives/ContentSequencer.tsx", + "src/ui/tui/primitives/DissolveTransition.tsx", + "src/ui/tui/primitives/Divider.tsx", + "src/ui/tui/primitives/EventPlanViewer.tsx", + "src/ui/tui/primitives/GroupedPickerMenu.tsx", + "src/ui/tui/primitives/HNViewer.tsx", + "src/ui/tui/primitives/KeyboardHintsBar.tsx", + "src/ui/tui/primitives/LinesBlock.tsx", + "src/ui/tui/primitives/LinkText.tsx", + "src/ui/tui/primitives/LoadingBox.tsx", + "src/ui/tui/primitives/LogViewer.tsx", + "src/ui/tui/primitives/ModalOverlay.tsx", + "src/ui/tui/primitives/NodeBlock.tsx", + "src/ui/tui/primitives/ProgressList.tsx", + "src/ui/tui/primitives/ScreenContainer.tsx", + "src/ui/tui/primitives/ScreenErrorBoundary.tsx", + "src/ui/tui/primitives/SplitView.tsx", + "src/ui/tui/primitives/TabContainer.tsx", + "src/ui/tui/primitives/ViewportTooSmall.tsx", + "src/ui/tui/primitives/link-helpers.ts", + "src/ui/tui/screens/AiOptInRequiredScreen.tsx", + "src/ui/tui/screens/McpScreen.tsx", + "src/ui/tui/screens/McpSuggestedPromptsScreen.tsx", + "src/ui/tui/screens/OutroScreen.tsx", + "src/ui/tui/screens/SkillSourceInfo.tsx", + "src/ui/tui/screens/SlackConnectScreen.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/AreaHeaderRow.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/AuditChecksViewer.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/CheckRow.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/DetailRow.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/Footer.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/Header.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/Legend.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/layout.ts", + "src/ui/tui/screens/audit/AuditChecksViewer/sort.ts", + "src/ui/tui/screens/audit/slides/eventCapture.tsx", + "src/ui/tui/screens/audit/slides/identification.tsx", + "src/ui/tui/screens/audit/slides/index.ts", + "src/ui/tui/screens/audit/slides/installation.tsx", + "src/ui/tui/screens/audit/slides/liveData.tsx", + "src/ui/tui/screens/audit/slides/shared.tsx", + "src/ui/tui/screens/audit/slides/uploadNotebook.tsx", + "src/ui/tui/screens/audit/slides/writeReport.tsx", + "src/ui/tui/screens/doctor/IssueTable.tsx", + "src/ui/tui/terminal.ts" + ], + "imports": [ + "agent-interface.js", + "agent-runner.js", + "analytics.js", + "api.js", + "bin.js", + "debug.js", + "defaults.js", + "mint-failure.js", + "setup-utils.js", + "store.js", + "telemetry.js", + "yara-hooks.js" + ] + }, + "tools.js": { + "sources": ["src/lib/agent/runner/harness/pi/tools.ts"], + "imports": [ + "agent-interface.js", + "analytics.js", + "debug.js", + "package-manager.js", + "pi.js", + "queue-tools.js", + "yara-hooks.js" + ] + }, + "wizard-abort.js": { + "sources": [], + "imports": ["wizard-abort.js"] + }, + "wizard-session.js": { + "sources": ["src/lib/wizard-session.ts"], + "imports": ["local-dev.js"] + }, + "yara-hooks.js": { + "sources": [ + "src/lib/programs/audit/types.ts", + "src/lib/programs/events-audit/constants.ts", + "src/lib/programs/posthog-integration/constants.ts", + "src/lib/skill-install.ts", + "src/lib/yara-hooks.ts", + "src/lib/yara-policy.ts" + ], + "imports": ["analytics.js", "bounded-fs.js", "debug.js"] + } +} diff --git a/scripts/__fixtures__/chunk-manifest.prod.json b/scripts/__fixtures__/chunk-manifest.prod.json new file mode 100644 index 000000000..48605e7f7 --- /dev/null +++ b/scripts/__fixtures__/chunk-manifest.prod.json @@ -0,0 +1,880 @@ +{ + "add-mcp-server-to-clients.js": { + "sources": [ + "src/steps/add-mcp-server-to-clients/MCPClient.ts", + "src/steps/add-mcp-server-to-clients/clients/claude-code.ts", + "src/steps/add-mcp-server-to-clients/clients/claude-web.ts", + "src/steps/add-mcp-server-to-clients/clients/codex.ts", + "src/steps/add-mcp-server-to-clients/clients/cursor.ts", + "src/steps/add-mcp-server-to-clients/clients/opencode.ts", + "src/steps/add-mcp-server-to-clients/clients/visual-studio-code.ts", + "src/steps/add-mcp-server-to-clients/clients/zed.ts", + "src/steps/add-mcp-server-to-clients/index.ts", + "src/steps/add-mcp-server-to-clients/plugin-client.ts" + ], + "imports": [ + "analytics.js", + "debug.js", + "defaults.js", + "rolldown-runtime.js", + "telemetry.js" + ] + }, + "agent-interface.js": { + "sources": [ + "src/lib/agent/agent-env-isolation.ts", + "src/lib/agent/agent-interface.ts", + "src/lib/agent/agent-phase.ts", + "src/lib/agent/bash-fence.ts", + "src/lib/agent/claude-settings.ts", + "src/lib/agent/commandments.ts", + "src/lib/agent/output-signals.ts", + "src/lib/agent/runner/harness/pi/gateway.ts", + "src/lib/agent/runner/harness/pi/runtime-notes.ts", + "src/lib/agent/runner/switchboard/commandments.ts", + "src/lib/agent/stored-login.ts", + "src/lib/agent/triage-provider.ts", + "src/lib/auth-session-state.ts", + "src/lib/fetch-retry.ts", + "src/lib/safe-tools.ts", + "src/lib/secret-vault.ts", + "src/lib/wizard-ask-bridge.ts", + "src/lib/wizard-tools/handoff.ts", + "src/lib/wizard-tools/mcp.ts", + "src/lib/wizard-tools/tools.ts", + "src/utils/custom-headers.ts", + "src/utils/env-scan.ts" + ], + "imports": [ + "analytics.js", + "bounded-fs.js", + "debug.js", + "errors.js", + "gateway-session.js", + "queue-tools.js", + "rolldown-runtime.js", + "wizard-abort.js", + "wizard-session.js", + "yara-hooks.js" + ] + }, + "agent-prompt-loader.js": { + "sources": ["src/lib/agent/agent-prompt-loader.ts"], + "imports": [ + "agent-interface.js", + "analytics.js", + "debug.js", + "queue-tools.js" + ] + }, + "agent-runner.js": { + "sources": [ + "src/lib/agent/agent-prompt.ts", + "src/lib/agent/agent-runner.ts", + "src/lib/agent/runner/harness/anthropic/index.ts", + "src/lib/agent/runner/index.ts", + "src/lib/agent/runner/sequence/linear.ts", + "src/lib/agent/runner/sequence/orchestrator/executor.ts", + "src/lib/agent/runner/sequence/orchestrator/orchestrator-runner.ts", + "src/lib/agent/runner/sequence/orchestrator/run-metrics.ts", + "src/lib/agent/runner/sequence/orchestrator/seeded-deps.ts", + "src/lib/agent/runner/shared/authenticate.ts", + "src/lib/agent/runner/shared/bootstrap.ts", + "src/lib/agent/runner/shared/errors.ts", + "src/lib/agent/runner/switchboard/flags/index.ts", + "src/lib/agent/runner/switchboard/flags/orchestrator.ts", + "src/lib/agent/runner/switchboard/flags/schemes.ts", + "src/lib/agent/runner/switchboard/flags/self-driving.ts", + "src/lib/agent/runner/switchboard/harness.ts", + "src/lib/agent/runner/switchboard/index.ts", + "src/lib/agent/runner/switchboard/sequence.ts", + "src/lib/agent/token-pricing.ts", + "src/lib/detection/agentic.ts", + "src/lib/detection/context.ts", + "src/lib/detection/features.ts", + "src/lib/detection/framework.ts", + "src/lib/middleware/benchmark.ts", + "src/lib/middleware/benchmarks/cache-tracker.ts", + "src/lib/middleware/benchmarks/compaction-tracker.ts", + "src/lib/middleware/benchmarks/context-size-tracker.ts", + "src/lib/middleware/benchmarks/cost-tracker.ts", + "src/lib/middleware/benchmarks/duration-tracker.ts", + "src/lib/middleware/benchmarks/index.ts", + "src/lib/middleware/benchmarks/json-writer.ts", + "src/lib/middleware/benchmarks/summary.ts", + "src/lib/middleware/benchmarks/token-tracker.ts", + "src/lib/middleware/benchmarks/turn-counter.ts", + "src/lib/middleware/config.ts", + "src/lib/middleware/phase-detector.ts", + "src/lib/middleware/pipeline.ts", + "src/lib/programs/audit/ledger-watcher.ts", + "src/lib/programs/posthog-integration/detect.ts", + "src/lib/programs/shared/package-scanning.ts", + "src/lib/programs/warehouse-source/detect.ts", + "src/lib/warehouse-sources/detect.ts", + "src/lib/warehouse-sources/registry.ts", + "src/utils/terminal-bell.ts" + ], + "imports": [ + "agent-interface.js", + "agent-prompt-loader.js", + "analytics.js", + "bounded-fs.js", + "debug.js", + "environment.js", + "errors.js", + "file-watcher.js", + "gateway-session.js", + "package-manager.js", + "pi.js", + "queue-tools.js", + "registry.js", + "rolldown-runtime.js", + "setup-utils.js", + "wizard-abort.js", + "wizard-session.js", + "yara-hooks.js" + ] + }, + "analytics.js": { + "sources": [], + "imports": ["analytics.js"] + }, + "api.js": { + "sources": ["src/lib/api.ts"], + "imports": ["analytics.js", "debug.js", "rolldown-runtime.js"] + }, + "bin.js": { + "sources": [ + "bin.ts", + "src/commands/ai-observability.ts", + "src/commands/audit.ts", + "src/commands/basic-integration/index.ts", + "src/commands/basic-integration/skill.ts", + "src/commands/cli/add.ts", + "src/commands/cli/index.ts", + "src/commands/command.ts", + "src/commands/doctor.ts", + "src/commands/error-tracking.ts", + "src/commands/factories/family-command-factory.ts", + "src/commands/factories/family-picker.tsx", + "src/commands/factories/native-command-factory.ts", + "src/commands/factories/shared.ts", + "src/commands/mcp-analytics.ts", + "src/commands/mcp/add.ts", + "src/commands/mcp/index.ts", + "src/commands/mcp/remove.ts", + "src/commands/mcp/tui-availability.ts", + "src/commands/mcp/tutorial.ts", + "src/commands/metrics.ts", + "src/commands/migrate.ts", + "src/commands/provision.ts", + "src/commands/replay-vision.ts", + "src/commands/revenue.ts", + "src/commands/self-driving.ts", + "src/commands/skill-program-options.ts", + "src/commands/skill.ts", + "src/commands/slack.ts", + "src/commands/upload-sourcemaps.ts", + "src/commands/warehouse.ts", + "src/lib/programs/dispatch-family.ts", + "src/lib/runners/resolve-no-telemetry.ts", + "src/lib/runners/run-non-interactive.ts", + "src/lib/runners/run-wizard-ci.ts", + "src/lib/runners/run-wizard-headless.ts", + "src/lib/runners/run-wizard.ts", + "src/ui/tui/hooks/keyboard-hints-utils.ts", + "src/ui/tui/hooks/useKeyBindings.ts", + "src/ui/tui/hooks/useKeyboardHints.tsx", + "src/ui/tui/hooks/useStdoutDimensions.ts", + "src/ui/tui/primitives/ConfirmButton.tsx", + "src/ui/tui/primitives/PickerMenu.tsx", + "src/ui/tui/primitives/PromptLabel.tsx", + "src/ui/tui/primitives/picker-filter.ts", + "src/wizard.ts" + ], + "imports": [ + "add-mcp-server-to-clients.js", + "agent-interface.js", + "agent-runner.js", + "analytics.js", + "api.js", + "ci-install.js", + "debug.js", + "env-api-key.js", + "environment.js", + "errors.js", + "file.js", + "gateway-session.js", + "headless-ui.js", + "interactive.js", + "local-dev.js", + "mint-failure.js", + "non-interactive.js", + "playground.js", + "posthog.js", + "provisioning.js", + "setup-utils.js", + "start-tui.js", + "store.js", + "task-stream.js", + "telemetry.js", + "wizard-abort.js", + "wizard-session.js", + "yara-hooks.js" + ] + }, + "bounded-fs.js": { + "sources": ["src/utils/bounded-fs.ts"], + "imports": ["analytics.js", "debug.js"] + }, + "ci-install.js": { + "sources": ["src/commands/basic-integration/ci-install.ts"], + "imports": [ + "bin.js", + "debug.js", + "errors.js", + "mint-failure.js", + "provisioning.js" + ] + }, + "debug.js": { + "sources": [ + "src/env.ts", + "src/lib/constants.ts", + "src/lib/headless-mode.ts", + "src/lib/health-checks/endpoints.ts", + "src/lib/health-checks/readiness.ts", + "src/lib/version.ts", + "src/ui/index.ts", + "src/ui/logging-ui.ts", + "src/ui/wizard-ui.ts", + "src/utils/debug.ts", + "src/utils/paths.ts" + ], + "imports": ["analytics.js", "local-dev.js"] + }, + "defaults.js": { + "sources": [ + "src/steps/add-mcp-server-to-clients/defaults.ts", + "src/steps/add-mcp-server-to-clients/results.ts" + ], + "imports": [] + }, + "env-api-key.js": { + "sources": ["src/utils/env-api-key.ts"], + "imports": ["bounded-fs.js", "rolldown-runtime.js"] + }, + "environment.js": { + "sources": ["src/utils/environment.ts"], + "imports": ["rolldown-runtime.js"] + }, + "errors.js": { + "sources": [ + "src/lib/agent/signals.ts", + "src/lib/errors/agent-map.ts", + "src/lib/errors/auth.ts", + "src/lib/errors/catalog.ts", + "src/lib/errors/codes.ts", + "src/lib/errors/detect-map.ts", + "src/lib/errors/emit.ts", + "src/lib/errors/run-failure.ts", + "src/lib/errors/sanitize.ts", + "src/lib/errors/skill-map.ts" + ], + "imports": [] + }, + "file.js": { + "sources": ["src/lib/task-stream/destinations/file.ts"], + "imports": ["debug.js"] + }, + "file-watcher.js": { + "sources": ["src/lib/file-watcher.ts"], + "imports": ["debug.js"] + }, + "gateway-session.js": { + "sources": [], + "imports": ["gateway-session.js"] + }, + "headless-ui.js": { + "sources": ["src/ui/headless-ui.ts"], + "imports": ["debug.js"] + }, + "interactive.js": { + "sources": ["src/commands/basic-integration/interactive.ts"], + "imports": ["bin.js", "mint-failure.js"] + }, + "local-dev.js": { + "sources": ["src/lib/local-dev.ts"], + "imports": [] + }, + "mcp.js": { + "sources": ["src/lib/agent/runner/harness/pi/mcp.ts"], + "imports": ["debug.js"] + }, + "mcp-prompt-streaming.js": { + "sources": ["src/lib/agent/mcp-prompt-streaming.ts"], + "imports": [ + "agent-interface.js", + "analytics.js", + "debug.js", + "gateway-session.js" + ] + }, + "mint-failure.js": { + "sources": [ + "src/lib/detection/project-scope.ts", + "src/lib/programs/agent-skill/content/index.tsx", + "src/lib/programs/agent-skill/index.ts", + "src/lib/programs/agent-skill/steps.ts", + "src/lib/programs/ai-observability/index.ts", + "src/lib/programs/audit/detect.ts", + "src/lib/programs/audit/index.ts", + "src/lib/programs/audit/seed.ts", + "src/lib/programs/error-tracking-upload-source-maps/content/index.tsx", + "src/lib/programs/error-tracking-upload-source-maps/detect.ts", + "src/lib/programs/error-tracking-upload-source-maps/index.ts", + "src/lib/programs/error-tracking-upload-source-maps/prompt.ts", + "src/lib/programs/error-tracking-upload-source-maps/steps.ts", + "src/lib/programs/error-tracking/content/index.tsx", + "src/lib/programs/error-tracking/content/tips.ts", + "src/lib/programs/error-tracking/detect-agentic.ts", + "src/lib/programs/error-tracking/index.ts", + "src/lib/programs/events-audit/index.ts", + "src/lib/programs/events-audit/seed.ts", + "src/lib/programs/events-audit/steps.ts", + "src/lib/programs/mcp-analytics/index.ts", + "src/lib/programs/mcp/index.ts", + "src/lib/programs/metrics/index.ts", + "src/lib/programs/migration/content/free-tier.tsx", + "src/lib/programs/migration/content/index.tsx", + "src/lib/programs/migration/content/pricing-structure.tsx", + "src/lib/programs/migration/content/vendor-stack.tsx", + "src/lib/programs/migration/index.ts", + "src/lib/programs/migration/steps.ts", + "src/lib/programs/posthog-doctor/fetch.ts", + "src/lib/programs/posthog-doctor/index.ts", + "src/lib/programs/posthog-doctor/kind-metadata.ts", + "src/lib/programs/posthog-doctor/steps.ts", + "src/lib/programs/posthog-doctor/types.ts", + "src/lib/programs/posthog-integration/content/data-flow.tsx", + "src/lib/programs/posthog-integration/content/funnel.tsx", + "src/lib/programs/posthog-integration/content/index.tsx", + "src/lib/programs/posthog-integration/content/line-chart.tsx", + "src/lib/programs/posthog-integration/content/product-suite.tsx", + "src/lib/programs/posthog-integration/handoff.ts", + "src/lib/programs/posthog-integration/index.ts", + "src/lib/programs/posthog-integration/steps.ts", + "src/lib/programs/program-registry.ts", + "src/lib/programs/replay-vision/index.ts", + "src/lib/programs/revenue-analytics/detect.ts", + "src/lib/programs/revenue-analytics/index.ts", + "src/lib/programs/revenue-analytics/steps.ts", + "src/lib/programs/self-driving/content/index.tsx", + "src/lib/programs/self-driving/content/pipeline-diagram.tsx", + "src/lib/programs/self-driving/content/pricing.ts", + "src/lib/programs/self-driving/content/tips.ts", + "src/lib/programs/self-driving/detect-agentic.ts", + "src/lib/programs/self-driving/detect.ts", + "src/lib/programs/self-driving/index.ts", + "src/lib/programs/self-driving/prompt.ts", + "src/lib/programs/self-driving/step-keys.ts", + "src/lib/programs/self-driving/steps.ts", + "src/lib/programs/shared/health-check-step.ts", + "src/lib/programs/shared/posthog-cli-preinstall.ts", + "src/lib/programs/slack/index.ts", + "src/lib/programs/warehouse-source/index.ts", + "src/lib/programs/warehouse-source/steps.ts", + "src/lib/programs/web-analytics-doctor/detect.ts", + "src/lib/programs/web-analytics-doctor/index.ts", + "src/lib/programs/web-analytics-doctor/steps.ts", + "src/steps/install-cli-steering/index.ts", + "src/ui/mint-failure.ts", + "src/ui/tui/components/StatusPeekTrigger.tsx", + "src/ui/tui/primitives/TextBlock.tsx", + "src/ui/tui/primitives/content-types.ts", + "src/ui/tui/primitives/layout-helpers.ts", + "src/ui/tui/primitives/text-helpers.ts", + "src/ui/tui/styles.ts" + ], + "imports": [ + "agent-interface.js", + "agent-runner.js", + "analytics.js", + "api.js", + "debug.js", + "errors.js", + "package-json.js", + "provisioning.js", + "queue-tools.js", + "registry.js", + "setup-utils.js", + "steps.js", + "telemetry.js", + "wizard-abort.js", + "wizard-session.js", + "yara-hooks.js" + ] + }, + "non-interactive.js": { + "sources": ["src/commands/basic-integration/non-interactive.ts"], + "imports": ["debug.js", "errors.js"] + }, + "orchestrator-tools.js": { + "sources": ["src/lib/agent/runner/harness/pi/orchestrator-tools.ts"], + "imports": ["analytics.js", "queue-tools.js"] + }, + "package-json.js": { + "sources": ["src/utils/package-json.ts"], + "imports": ["rolldown-runtime.js"] + }, + "package-manager.js": { + "sources": [ + "src/frameworks/python/utils.ts", + "src/lib/detection/package-manager.ts" + ], + "imports": ["setup-utils.js"] + }, + "pi.js": { + "sources": [ + "src/lib/agent/aio-capture.ts", + "src/lib/agent/runner/harness/pi/completion.ts", + "src/lib/agent/runner/harness/pi/index.ts" + ], + "imports": [ + "agent-interface.js", + "analytics.js", + "debug.js", + "errors.js", + "gateway-session.js", + "mcp.js", + "security.js", + "subagent.js", + "task.js", + "tasks.js", + "tools.js", + "yara-hooks.js" + ] + }, + "playground.js": { + "sources": [ + "src/commands/basic-integration/playground.ts", + "src/ui/tui/playground/PlaygroundApp.tsx", + "src/ui/tui/playground/demos/AiOptInDemo.tsx", + "src/ui/tui/playground/demos/AskModalDemo.tsx", + "src/ui/tui/playground/demos/AuditChecksDemo.tsx", + "src/ui/tui/playground/demos/DoctorReportDemo.tsx", + "src/ui/tui/playground/demos/EndScreensDemo.tsx", + "src/ui/tui/playground/demos/HealthCheckDemo.tsx", + "src/ui/tui/playground/demos/InputDemo.tsx", + "src/ui/tui/playground/demos/KeyboardHintsDemo.tsx", + "src/ui/tui/playground/demos/LayoutDemo.tsx", + "src/ui/tui/playground/demos/LearnDeckDemo.tsx", + "src/ui/tui/playground/demos/LogDemo.tsx", + "src/ui/tui/playground/demos/McpDemo.tsx", + "src/ui/tui/playground/demos/McpSuggestedPromptsDemo.tsx", + "src/ui/tui/playground/demos/ModalDemo.tsx", + "src/ui/tui/playground/demos/ProgressDemo.tsx", + "src/ui/tui/playground/demos/RunScreenDemo.tsx", + "src/ui/tui/playground/demos/ViewportGuardDemo.tsx", + "src/ui/tui/playground/demos/WelcomeDemo.tsx", + "src/ui/tui/playground/start-playground.ts" + ], + "imports": [ + "bin.js", + "debug.js", + "mint-failure.js", + "setup-utils.js", + "store.js", + "terminal.js" + ] + }, + "posthog.js": { + "sources": ["src/lib/task-stream/destinations/posthog.ts"], + "imports": ["debug.js"] + }, + "provisioning.js": { + "sources": ["src/utils/provisioning.ts", "src/utils/urls.ts"], + "imports": ["analytics.js", "debug.js", "rolldown-runtime.js"] + }, + "queue-tools.js": { + "sources": [ + "src/lib/agent/runner/sequence/orchestrator/queue-tools.ts", + "src/lib/agent/runner/sequence/orchestrator/queue.ts", + "src/lib/agent/runner/switchboard/models.ts", + "src/utils/atomic-ledger.ts" + ], + "imports": ["analytics.js", "debug.js"] + }, + "registry.js": { + "sources": [ + "src/frameworks/android/android-wizard-agent.ts", + "src/frameworks/android/utils.ts", + "src/frameworks/angular/angular-wizard-agent.ts", + "src/frameworks/angular/utils.ts", + "src/frameworks/astro/astro-wizard-agent.ts", + "src/frameworks/astro/utils.ts", + "src/frameworks/django/django-wizard-agent.ts", + "src/frameworks/django/utils.ts", + "src/frameworks/elixir/elixir-wizard-agent.ts", + "src/frameworks/fastapi/fastapi-wizard-agent.ts", + "src/frameworks/fastapi/utils.ts", + "src/frameworks/flask/flask-wizard-agent.ts", + "src/frameworks/flask/utils.ts", + "src/frameworks/flutter/flutter-wizard-agent.ts", + "src/frameworks/go/go-wizard-agent.ts", + "src/frameworks/java/java-wizard-agent.ts", + "src/frameworks/javascript-node/javascript-node-wizard-agent.ts", + "src/frameworks/javascript-web/javascript-web-wizard-agent.ts", + "src/frameworks/javascript-web/utils.ts", + "src/frameworks/kmp/kmp-wizard-agent.ts", + "src/frameworks/laravel/laravel-wizard-agent.ts", + "src/frameworks/laravel/utils.ts", + "src/frameworks/nextjs/nextjs-wizard-agent.ts", + "src/frameworks/nextjs/utils.ts", + "src/frameworks/nuxt/nuxt-wizard-agent.ts", + "src/frameworks/python/python-wizard-agent.ts", + "src/frameworks/rails/rails-wizard-agent.ts", + "src/frameworks/rails/utils.ts", + "src/frameworks/react-native/react-native-wizard-agent.ts", + "src/frameworks/react-native/utils.ts", + "src/frameworks/react-router/react-router-wizard-agent.ts", + "src/frameworks/react-router/utils.ts", + "src/frameworks/ruby/ruby-wizard-agent.ts", + "src/frameworks/ruby/utils.ts", + "src/frameworks/rust/rust-wizard-agent.ts", + "src/frameworks/svelte/svelte-wizard-agent.ts", + "src/frameworks/swift/swift-wizard-agent.ts", + "src/frameworks/swift/utils.ts", + "src/frameworks/tanstack-router/tanstack-router-wizard-agent.ts", + "src/frameworks/tanstack-router/utils.ts", + "src/frameworks/tanstack-start/tanstack-start-wizard-agent.ts", + "src/frameworks/tanstack-start/utils.ts", + "src/frameworks/vue/vue-wizard-agent.ts", + "src/lib/framework-config.ts", + "src/lib/registry.ts" + ], + "imports": [ + "bounded-fs.js", + "debug.js", + "package-json.js", + "package-manager.js", + "rolldown-runtime.js", + "setup-utils.js" + ] + }, + "rolldown-runtime.js": { + "sources": [], + "imports": [] + }, + "security.js": { + "sources": ["src/lib/agent/runner/harness/pi/security.ts"], + "imports": [ + "agent-interface.js", + "analytics.js", + "debug.js", + "yara-hooks.js" + ] + }, + "setup-utils.js": { + "sources": [ + "src/lib/host-resolution.ts", + "src/lib/oauth/program-scopes.ts", + "src/utils/oauth-errors.ts", + "src/utils/oauth.ts", + "src/utils/package-manager.ts", + "src/utils/project-resolution.ts", + "src/utils/semver.ts", + "src/utils/setup-utils.ts" + ], + "imports": [ + "analytics.js", + "api.js", + "bounded-fs.js", + "debug.js", + "local-dev.js", + "provisioning.js", + "rolldown-runtime.js", + "telemetry.js", + "wizard-abort.js" + ] + }, + "start-tui.js": { + "sources": [ + "src/lib/programs/error-tracking-upload-source-maps/detect-agentic.ts", + "src/lib/wizard-spellbook.ts", + "src/steps/add-mcp-server-to-clients/browser-client.ts", + "src/steps/add-mcp-server-to-clients/login-client.ts", + "src/ui/tui/App.tsx", + "src/ui/tui/components/PrivacyPanel.tsx", + "src/ui/tui/exit-line.ts", + "src/ui/tui/hooks/useGithubConnection.ts", + "src/ui/tui/ink-ui.ts", + "src/ui/tui/posthog-integration-intro.ts", + "src/ui/tui/screen-registry.tsx", + "src/ui/tui/screens/AgentSkillIntroScreen.tsx", + "src/ui/tui/screens/AiObservabilityIntroScreen.tsx", + "src/ui/tui/screens/AuthErrorScreen.tsx", + "src/ui/tui/screens/AuthScreen.tsx", + "src/ui/tui/screens/ErrorTrackingDetectScreen.tsx", + "src/ui/tui/screens/ErrorTrackingIntroScreen.tsx", + "src/ui/tui/screens/ExitScreen.tsx", + "src/ui/tui/screens/IntroScreenLayout.tsx", + "src/ui/tui/screens/KeepSkillsScreen.tsx", + "src/ui/tui/screens/ManagedSettingsScreen.tsx", + "src/ui/tui/screens/ManualAuthCodeScreen.tsx", + "src/ui/tui/screens/MetricsIntroScreen.tsx", + "src/ui/tui/screens/MigrationIntroScreen.tsx", + "src/ui/tui/screens/MintFailureScreen.tsx", + "src/ui/tui/screens/PortConflictScreen.tsx", + "src/ui/tui/screens/PostHogIntegrationIntroScreen.tsx", + "src/ui/tui/screens/RevenueIntroScreen.tsx", + "src/ui/tui/screens/RunScreen.tsx", + "src/ui/tui/screens/SelfDrivingGitHubScreen.tsx", + "src/ui/tui/screens/SelfDrivingHandoffScreen.tsx", + "src/ui/tui/screens/SelfDrivingIntegrationCheckScreen.tsx", + "src/ui/tui/screens/SelfDrivingIntegrationDetectScreen.tsx", + "src/ui/tui/screens/SelfDrivingIntroScreen.tsx", + "src/ui/tui/screens/SessionTimeoutScreen.tsx", + "src/ui/tui/screens/SettingsOverrideScreen.tsx", + "src/ui/tui/screens/SetupScreen.tsx", + "src/ui/tui/screens/SourceMapsDetectScreen.tsx", + "src/ui/tui/screens/SourceMapsIntroScreen.tsx", + "src/ui/tui/screens/SourceMapsOutroScreen.tsx", + "src/ui/tui/screens/TaskNoticeScreen.tsx", + "src/ui/tui/screens/WarehouseIntroScreen.tsx", + "src/ui/tui/screens/WizardAskScreen.tsx", + "src/ui/tui/screens/audit/AuditAreaPane.tsx", + "src/ui/tui/screens/audit/AuditChecksOutroSection.tsx", + "src/ui/tui/screens/audit/AuditIntroScreen.tsx", + "src/ui/tui/screens/audit/AuditOutroScreen.tsx", + "src/ui/tui/screens/audit/AuditRunScreen.tsx", + "src/ui/tui/screens/audit/PendingChecksList.tsx", + "src/ui/tui/screens/audit/slides/events-audit/createDashboard.tsx", + "src/ui/tui/screens/audit/slides/events-audit/detectSdk.tsx", + "src/ui/tui/screens/audit/slides/events-audit/enrichSites.tsx", + "src/ui/tui/screens/audit/slides/events-audit/index.ts", + "src/ui/tui/screens/audit/slides/events-audit/queryVolume.tsx", + "src/ui/tui/screens/audit/slides/events-audit/scanSites.tsx", + "src/ui/tui/screens/audit/slides/events-audit/uploadNotebook.tsx", + "src/ui/tui/screens/audit/slides/events-audit/writeReport.tsx", + "src/ui/tui/screens/doctor/DoctorIntroScreen.tsx", + "src/ui/tui/screens/doctor/DoctorReportScreen.tsx", + "src/ui/tui/screens/health/HealthCheckScreen.tsx", + "src/ui/tui/services/coding-agent-launcher.ts", + "src/ui/tui/services/mcp-installer.ts", + "src/ui/tui/services/mcp-suggested-prompts-services.ts", + "src/ui/tui/start-tui.ts", + "src/utils/clipboard.ts" + ], + "imports": [ + "add-mcp-server-to-clients.js", + "agent-interface.js", + "agent-runner.js", + "analytics.js", + "api.js", + "bin.js", + "bounded-fs.js", + "debug.js", + "defaults.js", + "errors.js", + "mcp-prompt-streaming.js", + "mint-failure.js", + "provisioning.js", + "registry.js", + "setup-utils.js", + "store.js", + "telemetry.js", + "terminal.js", + "wizard-abort.js", + "wizard-session.js", + "yara-hooks.js" + ] + }, + "steps.js": { + "sources": [ + "src/steps/upload-environment-variables/EnvironmentProvider.ts", + "src/steps/upload-environment-variables/index.ts", + "src/steps/upload-environment-variables/providers/vercel.ts" + ], + "imports": ["analytics.js", "debug.js", "telemetry.js"] + }, + "store.js": { + "sources": [ + "src/lib/programs/ai-opt-in-gate.ts", + "src/lib/programs/program-step.ts", + "src/ui/tui/router.ts", + "src/ui/tui/screen-sequences.ts", + "src/ui/tui/store.ts" + ], + "imports": [ + "agent-runner.js", + "analytics.js", + "debug.js", + "mint-failure.js", + "rolldown-runtime.js", + "wizard-session.js" + ] + }, + "subagent.js": { + "sources": ["src/lib/agent/runner/harness/pi/subagent.ts"], + "imports": ["debug.js"] + }, + "task.js": { + "sources": ["src/lib/agent/runner/harness/pi/task.ts"], + "imports": [ + "agent-interface.js", + "agent-prompt-loader.js", + "analytics.js", + "debug.js", + "errors.js", + "gateway-session.js", + "mcp.js", + "orchestrator-tools.js", + "pi.js", + "queue-tools.js", + "security.js", + "tools.js", + "yara-hooks.js" + ] + }, + "task-stream.js": { + "sources": [ + "src/lib/task-stream/audit-areas.ts", + "src/lib/task-stream/event-plan-watcher.ts", + "src/lib/task-stream/task-stream-push.ts" + ], + "imports": [ + "debug.js", + "errors.js", + "file-watcher.js", + "file.js", + "posthog.js" + ] + }, + "tasks.js": { + "sources": ["src/lib/agent/runner/harness/pi/tasks.ts"], + "imports": ["debug.js"] + }, + "telemetry.js": { + "sources": ["src/telemetry.ts", "src/utils/links.ts"], + "imports": ["analytics.js"] + }, + "terminal.js": { + "sources": [ + "src/lib/mcp-project-profile.ts", + "src/lib/mcp-role-prompts.copy.json", + "src/lib/mcp-role-prompts.ts", + "src/lib/mcp-seed-events.ts", + "src/ui/tui/components/LearnCard.tsx", + "src/ui/tui/components/PhaseVisuals.tsx", + "src/ui/tui/components/ServiceHealthList.tsx", + "src/ui/tui/components/TipsCard.tsx", + "src/ui/tui/components/TitleBar.tsx", + "src/ui/tui/components/TokenCostHud.tsx", + "src/ui/tui/components/visualizer/CrateStack.tsx", + "src/ui/tui/components/visualizer/DashboardGrid.tsx", + "src/ui/tui/components/visualizer/DiffCascade.tsx", + "src/ui/tui/components/visualizer/LibraryShelf.tsx", + "src/ui/tui/components/visualizer/MatrixRain.tsx", + "src/ui/tui/components/visualizer/Tumblers.tsx", + "src/ui/tui/components/visualizer/grid.ts", + "src/ui/tui/components/visualizer/palette.ts", + "src/ui/tui/components/visualizer/panel.tsx", + "src/ui/tui/hooks/useDismissOnAnyKey.ts", + "src/ui/tui/hooks/useTick.ts", + "src/ui/tui/primitives/CardLayout.tsx", + "src/ui/tui/primitives/ConfirmationInput.tsx", + "src/ui/tui/primitives/ContentSequencer.tsx", + "src/ui/tui/primitives/DissolveTransition.tsx", + "src/ui/tui/primitives/Divider.tsx", + "src/ui/tui/primitives/EventPlanViewer.tsx", + "src/ui/tui/primitives/GroupedPickerMenu.tsx", + "src/ui/tui/primitives/HNViewer.tsx", + "src/ui/tui/primitives/KeyboardHintsBar.tsx", + "src/ui/tui/primitives/LinesBlock.tsx", + "src/ui/tui/primitives/LinkText.tsx", + "src/ui/tui/primitives/LoadingBox.tsx", + "src/ui/tui/primitives/LogViewer.tsx", + "src/ui/tui/primitives/ModalOverlay.tsx", + "src/ui/tui/primitives/NodeBlock.tsx", + "src/ui/tui/primitives/ProgressList.tsx", + "src/ui/tui/primitives/ScreenContainer.tsx", + "src/ui/tui/primitives/ScreenErrorBoundary.tsx", + "src/ui/tui/primitives/SplitView.tsx", + "src/ui/tui/primitives/TabContainer.tsx", + "src/ui/tui/primitives/ViewportTooSmall.tsx", + "src/ui/tui/primitives/link-helpers.ts", + "src/ui/tui/screens/AiOptInRequiredScreen.tsx", + "src/ui/tui/screens/McpScreen.tsx", + "src/ui/tui/screens/McpSuggestedPromptsScreen.tsx", + "src/ui/tui/screens/OutroScreen.tsx", + "src/ui/tui/screens/SkillSourceInfo.tsx", + "src/ui/tui/screens/SlackConnectScreen.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/AreaHeaderRow.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/AuditChecksViewer.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/CheckRow.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/DetailRow.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/Footer.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/Header.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/Legend.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/layout.ts", + "src/ui/tui/screens/audit/AuditChecksViewer/sort.ts", + "src/ui/tui/screens/audit/slides/eventCapture.tsx", + "src/ui/tui/screens/audit/slides/identification.tsx", + "src/ui/tui/screens/audit/slides/index.ts", + "src/ui/tui/screens/audit/slides/installation.tsx", + "src/ui/tui/screens/audit/slides/liveData.tsx", + "src/ui/tui/screens/audit/slides/shared.tsx", + "src/ui/tui/screens/audit/slides/uploadNotebook.tsx", + "src/ui/tui/screens/audit/slides/writeReport.tsx", + "src/ui/tui/screens/doctor/IssueTable.tsx", + "src/ui/tui/terminal.ts" + ], + "imports": [ + "agent-interface.js", + "agent-runner.js", + "analytics.js", + "api.js", + "bin.js", + "debug.js", + "defaults.js", + "mint-failure.js", + "setup-utils.js", + "store.js", + "telemetry.js", + "yara-hooks.js" + ] + }, + "tools.js": { + "sources": ["src/lib/agent/runner/harness/pi/tools.ts"], + "imports": [ + "agent-interface.js", + "analytics.js", + "debug.js", + "package-manager.js", + "pi.js", + "queue-tools.js", + "yara-hooks.js" + ] + }, + "wizard-abort.js": { + "sources": ["src/utils/wizard-abort.ts"], + "imports": ["analytics.js", "debug.js", "errors.js"] + }, + "wizard-session.js": { + "sources": ["src/lib/wizard-session.ts"], + "imports": ["local-dev.js"] + }, + "yara-hooks.js": { + "sources": [ + "src/lib/programs/audit/types.ts", + "src/lib/programs/events-audit/constants.ts", + "src/lib/programs/posthog-integration/constants.ts", + "src/lib/skill-install.ts", + "src/lib/yara-hooks.ts", + "src/lib/yara-policy.ts" + ], + "imports": ["analytics.js", "bounded-fs.js", "debug.js"] + } +} diff --git a/src/__tests__/architecture/import-boundaries.test.ts b/src/__tests__/architecture/import-boundaries.test.ts new file mode 100644 index 000000000..3e25aae6a --- /dev/null +++ b/src/__tests__/architecture/import-boundaries.test.ts @@ -0,0 +1,413 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import { fileURLToPath } from 'url'; + +export type Surface = 'env' | 'legacy' | 'agent' | 'tui' | 'cli' | 'harness'; + +const HERE = path.dirname(fileURLToPath(import.meta.url)); +const REPO_ROOT = path.resolve(HERE, '../../..'); + +const SURFACE_RULES: ReadonlyArray boolean]> = + [ + ['env', (p) => p === 'src/env.ts'], + [ + 'agent', + (p) => + p.startsWith('src/lib/agent/') || + p.startsWith('src/lib/middleware/') || + p === 'src/lib/gateway-session.ts' || + p === 'src/lib/yara-hooks.ts' || + p === 'src/lib/yara-policy.ts' || + p === 'src/lib/wizard-tools/mcp.ts', + ], + [ + 'tui', + (p) => + p.startsWith('src/ui/tui/') || + p === 'src/ui/logging-ui.ts' || + p === 'src/ui/headless-ui.ts' || + p === 'src/commands/factories/family-picker.tsx' || + /^src\/lib\/programs\/[^/]+\/content\//.test(p) || + /^src\/lib\/programs\/[^/]+\/tips\.ts$/.test(p), + ], + [ + 'cli', + (p) => + p === 'bin.ts' || + p === 'src/wizard.ts' || + p === 'src/telemetry.ts' || + p.startsWith('src/commands/') || + p.startsWith('src/lib/runners/'), + ], + [ + 'harness', + (p) => p.startsWith('e2e-harness/') || p.startsWith('scripts/'), + ], + ]; + +export function classifySurface(relPath: string): Surface { + const p = relPath.split(path.sep).join('/'); + for (const [surface, matches] of SURFACE_RULES) { + if (matches(p)) return surface; + } + return 'legacy'; +} + +export const ALLOWED_IMPORTS: Record< + Exclude, + readonly Surface[] +> = { + env: [], + legacy: ['env', 'legacy'], + agent: ['env', 'legacy', 'agent'], + tui: ['env', 'legacy', 'tui'], + cli: ['env', 'legacy', 'agent', 'tui', 'cli'], +}; + +const TUI_ONLY_PACKAGES = ['ink', 'react', '@inkjs/ui', 'ink-testing-library']; + +const SKIP_DIRS = new Set([ + '__tests__', + '__mocks__', + '__fixtures__', + '__snapshots__', + 'node_modules', + 'dist', + 'coverage', +]); + +const SPECIFIER_PATTERNS = [ + /import\s+(?:type\s+)?[^'"]*?from\s*['"]([^'"]+)['"]/g, + /import\s*['"]([^'"]+)['"]/g, + /export\s+(?:type\s+)?[^'"]*?from\s*['"]([^'"]+)['"]/g, + /import\(\s*['"]([^'"]+)['"]\s*\)/g, + /require\(\s*['"]([^'"]+)['"]\s*\)/g, +]; + +const REGEX_PRECEDERS = new Set([ + '\n', + '(', + ')', + ',', + '=', + ':', + '[', + '!', + '&', + '|', + '?', + '{', + '}', + ';', + '+', + '-', + '*', + '%', + '^', + '~', + '<', + '>', +]); + +function endOfString(source: string, start: number, quote: string): number { + let i = start + 1; + while (i < source.length) { + if (source[i] === '\\') { + i += 2; + continue; + } + if (source[i] === quote) return i + 1; + i++; + } + return source.length; +} + +function endOfRegex(source: string, start: number): number { + let i = start + 1; + let inClass = false; + while (i < source.length) { + const c = source[i]; + if (c === '\\') { + i += 2; + continue; + } + if (c === '\n') return start + 1; + if (c === '[') inClass = true; + else if (c === ']') inClass = false; + else if (c === '/' && !inClass) return i + 1; + i++; + } + return source.length; +} + +function stripComments(source: string): string { + let out = ''; + let prev = '\n'; + let i = 0; + while (i < source.length) { + const c = source[i]; + const next = source[i + 1]; + if (c === '/' && next === '/') { + while (i < source.length && source[i] !== '\n') i++; + continue; + } + if (c === '/' && next === '*') { + i += 2; + while (i < source.length && !(source[i] === '*' && source[i + 1] === '/')) + i++; + i += 2; + out += ' '; + continue; + } + if (c === '"' || c === "'" || c === '`') { + const end = endOfString(source, i, c); + out += source.slice(i, end); + prev = c; + i = end; + continue; + } + if (c === '/' && REGEX_PRECEDERS.has(prev)) { + const end = endOfRegex(source, i); + out += source.slice(i, end); + prev = '/'; + i = end; + continue; + } + out += c; + if (c === '\n' || !/\s/.test(c)) prev = c; + i++; + } + return out; +} + +function toRepoRelative(abs: string): string { + return path.relative(REPO_ROOT, abs).split(path.sep).join('/'); +} + +function isFile(abs: string): boolean { + return fs.statSync(abs, { throwIfNoEntry: false })?.isFile() ?? false; +} + +function collectFiles(absDir: string, into: string[]): void { + for (const entry of fs.readdirSync(absDir, { withFileTypes: true })) { + const abs = path.join(absDir, entry.name); + if (entry.isDirectory()) { + if (!SKIP_DIRS.has(entry.name)) collectFiles(abs, into); + continue; + } + if (!entry.isFile()) continue; + if (!/\.tsx?$/.test(entry.name)) continue; + if (/\.d\.ts$/.test(entry.name) || /\.test\.tsx?$/.test(entry.name)) + continue; + into.push(toRepoRelative(abs)); + } +} + +function loadAliases(): ReadonlyArray { + const tsconfig = JSON.parse( + fs.readFileSync(path.join(REPO_ROOT, 'tsconfig.build.json'), 'utf8'), + ) as { compilerOptions?: { paths?: Record } }; + return Object.entries(tsconfig.compilerOptions?.paths ?? {}).map( + ([pattern, targets]) => [pattern, targets[0]] as const, + ); +} + +function aliasTarget( + spec: string, + aliases: ReadonlyArray, +): string | null { + for (const [pattern, target] of aliases) { + if (pattern.endsWith('*')) { + const prefix = pattern.slice(0, -1); + if (spec.startsWith(prefix)) { + return path.resolve( + REPO_ROOT, + target.slice(0, -1) + spec.slice(prefix.length), + ); + } + } else if (spec === pattern) { + return path.resolve(REPO_ROOT, target); + } + } + return null; +} + +function probe(base: string): string | null { + const candidates: string[] = []; + if (base.endsWith('.js')) { + const stem = base.slice(0, -3); + candidates.push(`${stem}.ts`, `${stem}.tsx`); + } + candidates.push( + `${base}.ts`, + `${base}.tsx`, + path.join(base, 'index.ts'), + path.join(base, 'index.tsx'), + base, + ); + return candidates.find(isFile) ?? null; +} + +function specifiersIn(text: string): string[] { + const found = new Set(); + for (const pattern of SPECIFIER_PATTERNS) { + pattern.lastIndex = 0; + let match = pattern.exec(text); + while (match !== null) { + found.add(match[1]); + match = pattern.exec(text); + } + } + return [...found]; +} + +type Analysis = { + files: string[]; + edges: string[]; + violations: ReadonlyArray<{ key: string; rule: string }>; + unresolved: string[]; +}; + +function analyze(): Analysis { + const files: string[] = ['bin.ts']; + collectFiles(path.join(REPO_ROOT, 'src'), files); + files.sort(); + + const aliases = loadAliases(); + const edges = new Set(); + const violations = new Map(); + const unresolved = new Set(); + + for (const file of files) { + const text = stripComments( + fs.readFileSync(path.join(REPO_ROOT, file), 'utf8'), + ); + const from = classifySurface(file); + const allowed = from === 'harness' ? [] : ALLOWED_IMPORTS[from]; + + for (const spec of specifiersIn(text)) { + const base = spec.startsWith('.') + ? path.resolve(REPO_ROOT, path.dirname(file), spec) + : aliasTarget(spec, aliases); + + if (base === null) { + const tuiOnly = + TUI_ONLY_PACKAGES.includes(spec) || spec.startsWith('react/'); + if (tuiOnly && from !== 'tui') { + violations.set(`${file} -> pkg:${spec}`, 'ink-outside-tui'); + } + continue; + } + + const resolved = probe(base); + if (resolved === null) { + unresolved.add(`${file} -> ${spec}`); + continue; + } + + const target = toRepoRelative(resolved); + const key = `${file} -> ${target}`; + edges.add(key); + + const to = classifySurface(target); + if (to === 'harness') violations.set(key, 'harness'); + else if (!allowed.includes(to)) + violations.set(key, `matrix:${from}->${to}`); + } + } + + return { + files, + edges: [...edges].sort(), + violations: [...violations] + .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)) + .map(([key, rule]) => ({ key, rule })), + unresolved: [...unresolved].sort(), + }; +} + +const analysis = analyze(); + +const known = ( + JSON.parse( + fs.readFileSync(path.join(HERE, 'known-violations.json'), 'utf8'), + ) as { violations: string[] } +).violations; + +if (process.env.PRINT_VIOLATIONS) { + const byRule = new Map(); + const byImporter = new Map(); + for (const { key, rule } of analysis.violations) { + byRule.set(rule, (byRule.get(rule) ?? 0) + 1); + const file = key.split(' -> ')[0]; + byImporter.set(file, (byImporter.get(file) ?? 0) + 1); + } + const lines = [ + `files scanned: ${analysis.files.length}`, + `edges: ${analysis.edges.length}`, + `violations: ${analysis.violations.length}`, + `unresolved: ${analysis.unresolved.length}`, + ...analysis.unresolved.map((u) => ` unresolved: ${u}`), + ...[...byRule] + .sort((a, b) => b[1] - a[1]) + .map(([rule, count]) => ` ${rule}: ${count}`), + 'top importers:', + ...[...byImporter] + .sort((a, b) => b[1] - a[1]) + .slice(0, 10) + .map(([file, count]) => ` ${file}: ${count}`), + ]; + process.stderr.write(`${lines.join('\n')}\n`); + process.stderr.write( + `${JSON.stringify( + { violations: analysis.violations.map((v) => v.key) }, + null, + 2, + )}\n`, + ); +} + +describe('import boundaries', () => { + it('resolves every internal specifier', () => { + expect(analysis.unresolved).toEqual([]); + }); + + it('introduces no violation outside known-violations.json', () => { + const knownSet = new Set(known); + const added = analysis.violations + .filter(({ key }) => !knownSet.has(key)) + .map(({ key, rule }) => `${key} [${rule}]`); + expect(added).toEqual([]); + }); + + it('keeps known-violations.json free of stale entries', () => { + const current = new Set(analysis.violations.map((v) => v.key)); + const stale = known.filter((key) => !current.has(key)); + expect( + stale, + 'stale entries, delete them from known-violations.json', + ).toEqual([]); + }); +}); + +describe('surface classification', () => { + it('maps representative paths to their surface', () => { + expect(classifySurface('src/env.ts')).toBe('env'); + expect(classifySurface('src/utils/analytics.ts')).toBe('legacy'); + expect(classifySurface('src/lib/agent/agent-runner.ts')).toBe('agent'); + expect(classifySurface('src/ui/tui/App.tsx')).toBe('tui'); + expect(classifySurface('bin.ts')).toBe('cli'); + expect(classifySurface('e2e-harness/e2e-profile.ts')).toBe('harness'); + expect(classifySurface('src/lib/wizard-tools/mcp.ts')).toBe('agent'); + expect(classifySurface('src/lib/wizard-tools/tools.ts')).toBe('legacy'); + expect(classifySurface('src/commands/factories/family-picker.tsx')).toBe( + 'tui', + ); + expect( + classifySurface('src/lib/programs/posthog-integration/content/index.tsx'), + ).toBe('tui'); + expect( + classifySurface('src/lib/programs/posthog-integration/index.ts'), + ).toBe('legacy'); + }); +}); diff --git a/src/__tests__/architecture/known-violations.json b/src/__tests__/architecture/known-violations.json new file mode 100644 index 000000000..d523b2a73 --- /dev/null +++ b/src/__tests__/architecture/known-violations.json @@ -0,0 +1,76 @@ +{ + "violations": [ + "src/commands/factories/family-picker.tsx -> src/commands/command.ts", + "src/env.ts -> src/lib/headless-mode.ts", + "src/lib/agent/mcp-prompt-streaming.ts -> src/ui/tui/services/mcp-suggested-prompts-services.ts", + "src/lib/detection/agentic.ts -> src/lib/agent/agent-interface.ts", + "src/lib/detection/project-scope.ts -> src/lib/agent/runner/shared/authenticate.ts", + "src/lib/errors/agent-map.ts -> src/lib/agent/signals.ts", + "src/lib/programs/agent-skill/index.ts -> src/lib/agent/agent-runner.ts", + "src/lib/programs/agent-skill/index.ts -> src/lib/programs/agent-skill/content/index.tsx", + "src/lib/programs/ai-observability/index.ts -> src/lib/programs/agent-skill/content/index.tsx", + "src/lib/programs/audit/detect.ts -> src/lib/agent/agent-runner.ts", + "src/lib/programs/audit/index.ts -> src/lib/agent/agent-runner.ts", + "src/lib/programs/dispatch-family.ts -> src/commands/command.ts", + "src/lib/programs/dispatch-family.ts -> src/commands/factories/shared.ts", + "src/lib/programs/error-tracking-upload-source-maps/detect.ts -> src/lib/agent/agent-runner.ts", + "src/lib/programs/error-tracking-upload-source-maps/index.ts -> src/lib/agent/agent-runner.ts", + "src/lib/programs/error-tracking-upload-source-maps/index.ts -> src/lib/programs/error-tracking-upload-source-maps/content/index.tsx", + "src/lib/programs/error-tracking-upload-source-maps/prompt.ts -> src/lib/agent/agent-interface.ts", + "src/lib/programs/error-tracking/index.ts -> src/lib/agent/runner/shared/types.ts", + "src/lib/programs/error-tracking/index.ts -> src/lib/programs/error-tracking/content/index.tsx", + "src/lib/programs/error-tracking/index.ts -> src/lib/programs/error-tracking/content/tips.ts", + "src/lib/programs/events-audit/index.ts -> src/lib/agent/agent-runner.ts", + "src/lib/programs/mcp-analytics/index.ts -> src/lib/agent/agent-runner.ts", + "src/lib/programs/metrics/index.ts -> src/lib/programs/agent-skill/content/index.tsx", + "src/lib/programs/migration/index.ts -> src/lib/agent/agent-runner.ts", + "src/lib/programs/migration/index.ts -> src/lib/programs/migration/content/index.tsx", + "src/lib/programs/posthog-integration/index.ts -> src/lib/agent/agent-interface.ts", + "src/lib/programs/posthog-integration/index.ts -> src/lib/agent/agent-runner.ts", + "src/lib/programs/posthog-integration/index.ts -> src/lib/agent/runner/shared/bootstrap.ts", + "src/lib/programs/posthog-integration/index.ts -> src/lib/programs/posthog-integration/content/index.tsx", + "src/lib/programs/program-registry.ts -> src/lib/programs/agent-skill/content/index.tsx", + "src/lib/programs/program-step.ts -> src/lib/agent/agent-runner.ts", + "src/lib/programs/program-step.ts -> src/ui/tui/components/TipsCard.tsx", + "src/lib/programs/program-step.ts -> src/ui/tui/primitives/index.ts", + "src/lib/programs/program-step.ts -> src/ui/tui/store.ts", + "src/lib/programs/replay-vision/index.ts -> src/lib/agent/agent-runner.ts", + "src/lib/programs/revenue-analytics/detect.ts -> src/lib/agent/agent-runner.ts", + "src/lib/programs/revenue-analytics/index.ts -> src/lib/programs/revenue-analytics/content/index.tsx", + "src/lib/programs/self-driving/detect.ts -> src/lib/agent/agent-runner.ts", + "src/lib/programs/self-driving/index.ts -> src/lib/agent/agent-runner.ts", + "src/lib/programs/self-driving/index.ts -> src/lib/programs/self-driving/content/index.tsx", + "src/lib/programs/self-driving/index.ts -> src/lib/programs/self-driving/content/pricing.ts", + "src/lib/programs/self-driving/index.ts -> src/lib/programs/self-driving/content/tips.ts", + "src/lib/programs/self-driving/prompt.ts -> src/lib/agent/agent-interface.ts", + "src/lib/programs/self-driving/prompt.ts -> src/lib/agent/agent-runner.ts", + "src/lib/programs/warehouse-source/detect.ts -> src/lib/agent/agent-runner.ts", + "src/lib/programs/warehouse-source/index.ts -> src/lib/agent/agent-runner.ts", + "src/lib/programs/warehouse-source/index.ts -> src/lib/programs/warehouse-source/content/index.tsx", + "src/lib/programs/web-analytics-doctor/detect.ts -> src/lib/agent/agent-runner.ts", + "src/lib/task-stream/event-plan-watcher.ts -> src/ui/tui/store.ts", + "src/lib/task-stream/task-stream-push.ts -> src/ui/tui/store.ts", + "src/lib/wizard-session.ts -> src/lib/agent/claude-settings.ts", + "src/lib/wizard-tools/index.ts -> src/lib/wizard-tools/mcp.ts", + "src/lib/wizard-tools/tools.ts -> src/lib/yara-hooks.ts", + "src/steps/add-mcp-server-to-clients/index.ts -> src/telemetry.ts", + "src/steps/add-or-update-environment-variables.ts -> src/telemetry.ts", + "src/steps/run-prettier.ts -> src/telemetry.ts", + "src/steps/upload-environment-variables/index.ts -> src/telemetry.ts", + "src/ui/index.ts -> src/ui/logging-ui.ts", + "src/ui/logging-ui.ts -> src/lib/agent/claude-settings.ts", + "src/ui/tui/components/PhaseVisuals.tsx -> src/lib/agent/agent-phase.ts", + "src/ui/tui/components/TokenCostHud.tsx -> src/lib/agent/token-pricing.ts", + "src/ui/tui/exit-line.ts -> src/lib/agent/token-pricing.ts", + "src/ui/tui/ink-ui.ts -> src/lib/agent/claude-settings.ts", + "src/ui/tui/playground/demos/RunScreenDemo.tsx -> src/lib/agent/agent-phase.ts", + "src/ui/tui/screens/ManagedSettingsScreen.tsx -> src/lib/agent/claude-settings.ts", + "src/ui/tui/services/mcp-suggested-prompts-services.ts -> src/lib/agent/mcp-prompt-streaming.ts", + "src/ui/tui/store.ts -> src/lib/agent/claude-settings.ts", + "src/ui/tui/store.ts -> src/lib/agent/token-pricing.ts", + "src/ui/wizard-ui.ts -> src/lib/agent/claude-settings.ts", + "src/utils/package-manager.ts -> src/telemetry.ts", + "src/utils/setup-utils.ts -> src/telemetry.ts", + "src/utils/wizard-abort.ts -> src/ui/logging-ui.ts" + ] +} diff --git a/src/lib/programs/__tests__/__snapshots__/flow-traces.test.ts.snap b/src/lib/programs/__tests__/__snapshots__/flow-traces.test.ts.snap new file mode 100644 index 000000000..cc4a39428 --- /dev/null +++ b/src/lib/programs/__tests__/__snapshots__/flow-traces.test.ts.snap @@ -0,0 +1,1104 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`flow traces per program > agent-skill (node) 1`] = ` +{ + "events": [ + { + "event": "screen health-check", + "from": "agent-skill-intro", + "program": "agent-skill", + }, + { + "event": "screen auth", + "from": "health-check", + "program": "agent-skill", + }, + { + "event": "screen run", + "from": "auth", + "program": "agent-skill", + }, + { + "event": "screen ai-opt-in", + "from": "run", + "program": "agent-skill", + }, + { + "event": "screen run", + "from": "ai-opt-in", + "program": "agent-skill", + }, + { + "event": "screen outro", + "from": "run", + "program": "agent-skill", + }, + { + "event": "screen keep-skills", + "from": "outro", + "program": "agent-skill", + }, + ], + "program": "agent-skill", + "screens": [ + "agent-skill-intro", + "health-check", + "auth", + "ai-opt-in", + "run", + "outro", + "keep-skills", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > ai-observability (node) 1`] = ` +{ + "events": [ + { + "event": "screen health-check", + "from": "ai-observability-intro", + "program": "ai-observability", + }, + { + "event": "screen auth", + "from": "health-check", + "program": "ai-observability", + }, + { + "event": "screen run", + "from": "auth", + "program": "ai-observability", + }, + { + "event": "screen ai-opt-in", + "from": "run", + "program": "ai-observability", + }, + { + "event": "screen run", + "from": "ai-opt-in", + "program": "ai-observability", + }, + { + "event": "screen outro", + "from": "run", + "program": "ai-observability", + }, + { + "event": "screen keep-skills", + "from": "outro", + "program": "ai-observability", + }, + ], + "program": "ai-observability", + "screens": [ + "ai-observability-intro", + "health-check", + "auth", + "ai-opt-in", + "run", + "outro", + "keep-skills", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > audit (node) 1`] = ` +{ + "events": [ + { + "event": "screen health-check", + "from": "audit-intro", + "program": "audit", + }, + { + "event": "screen auth", + "from": "health-check", + "program": "audit", + }, + { + "event": "screen audit-run", + "from": "auth", + "program": "audit", + }, + { + "event": "screen ai-opt-in", + "from": "audit-run", + "program": "audit", + }, + { + "event": "screen audit-run", + "from": "ai-opt-in", + "program": "audit", + }, + { + "event": "screen audit-outro", + "from": "audit-run", + "program": "audit", + }, + { + "event": "screen keep-skills", + "from": "audit-outro", + "program": "audit", + }, + ], + "program": "audit", + "screens": [ + "audit-intro", + "health-check", + "auth", + "ai-opt-in", + "audit-run", + "audit-outro", + "keep-skills", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > error-tracking (node) 1`] = ` +{ + "events": [ + { + "event": "screen health-check", + "from": "error-tracking-intro", + "program": "error-tracking", + }, + { + "event": "screen auth", + "from": "health-check", + "program": "error-tracking", + }, + { + "event": "screen run", + "from": "auth", + "program": "error-tracking", + }, + { + "event": "screen ai-opt-in", + "from": "run", + "program": "error-tracking", + }, + { + "event": "screen run", + "from": "ai-opt-in", + "program": "error-tracking", + }, + { + "event": "screen outro", + "from": "run", + "program": "error-tracking", + }, + { + "event": "screen keep-skills", + "from": "outro", + "program": "error-tracking", + }, + ], + "program": "error-tracking", + "screens": [ + "error-tracking-intro", + "health-check", + "auth", + "ai-opt-in", + "run", + "outro", + "keep-skills", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > error-tracking-upload-source-maps (node) 1`] = ` +{ + "events": [ + { + "event": "screen auth", + "from": "source-maps-intro", + "program": "error-tracking-upload-source-maps", + }, + { + "event": "screen source-maps-detect", + "from": "auth", + "program": "error-tracking-upload-source-maps", + }, + { + "event": "screen ai-opt-in", + "from": "source-maps-detect", + "program": "error-tracking-upload-source-maps", + }, + { + "event": "screen source-maps-detect", + "from": "ai-opt-in", + "program": "error-tracking-upload-source-maps", + }, + { + "event": "screen run", + "from": "source-maps-detect", + "program": "error-tracking-upload-source-maps", + }, + { + "event": "screen source-maps-outro", + "from": "run", + "program": "error-tracking-upload-source-maps", + }, + { + "event": "screen keep-skills", + "from": "source-maps-outro", + "program": "error-tracking-upload-source-maps", + }, + ], + "program": "error-tracking-upload-source-maps", + "screens": [ + "source-maps-intro", + "auth", + "ai-opt-in", + "source-maps-detect", + "run", + "source-maps-outro", + "keep-skills", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > events-audit (node) 1`] = ` +{ + "events": [ + { + "event": "screen health-check", + "from": "audit-intro", + "program": "events-audit", + }, + { + "event": "screen auth", + "from": "health-check", + "program": "events-audit", + }, + { + "event": "screen audit-run", + "from": "auth", + "program": "events-audit", + }, + { + "event": "screen ai-opt-in", + "from": "audit-run", + "program": "events-audit", + }, + { + "event": "screen audit-run", + "from": "ai-opt-in", + "program": "events-audit", + }, + { + "event": "screen mcp", + "from": "audit-run", + "program": "events-audit", + }, + { + "event": "screen audit-outro", + "from": "mcp", + "program": "events-audit", + }, + { + "event": "screen keep-skills", + "from": "audit-outro", + "program": "events-audit", + }, + ], + "program": "events-audit", + "screens": [ + "audit-intro", + "health-check", + "auth", + "ai-opt-in", + "audit-run", + "mcp", + "audit-outro", + "keep-skills", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > mcp-add (node) 1`] = ` +{ + "events": [ + { + "event": "screen exit", + "from": "mcp-add", + "program": "mcp-add", + }, + ], + "program": "mcp-add", + "screens": [ + "mcp-add", + "exit", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > mcp-analytics (node) 1`] = ` +{ + "events": [ + { + "event": "screen health-check", + "from": "agent-skill-intro", + "program": "mcp-analytics", + }, + { + "event": "screen auth", + "from": "health-check", + "program": "mcp-analytics", + }, + { + "event": "screen run", + "from": "auth", + "program": "mcp-analytics", + }, + { + "event": "screen ai-opt-in", + "from": "run", + "program": "mcp-analytics", + }, + { + "event": "screen run", + "from": "ai-opt-in", + "program": "mcp-analytics", + }, + { + "event": "screen outro", + "from": "run", + "program": "mcp-analytics", + }, + { + "event": "screen keep-skills", + "from": "outro", + "program": "mcp-analytics", + }, + ], + "program": "mcp-analytics", + "screens": [ + "agent-skill-intro", + "health-check", + "auth", + "ai-opt-in", + "run", + "outro", + "keep-skills", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > mcp-remove (node) 1`] = ` +{ + "events": [ + { + "event": "screen exit", + "from": "mcp-remove", + "program": "mcp-remove", + }, + ], + "program": "mcp-remove", + "screens": [ + "mcp-remove", + "exit", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > mcp-tutorial (node) 1`] = ` +{ + "events": [ + { + "event": "screen slack-connect", + "from": "mcp-suggested-prompts", + "program": "mcp-tutorial", + }, + { + "event": "screen exit", + "from": "slack-connect", + "program": "mcp-tutorial", + }, + ], + "program": "mcp-tutorial", + "screens": [ + "mcp-suggested-prompts", + "slack-connect", + "exit", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > metrics (node) 1`] = ` +{ + "events": [ + { + "event": "screen health-check", + "from": "metrics-intro", + "program": "metrics", + }, + { + "event": "screen auth", + "from": "health-check", + "program": "metrics", + }, + { + "event": "screen run", + "from": "auth", + "program": "metrics", + }, + { + "event": "screen ai-opt-in", + "from": "run", + "program": "metrics", + }, + { + "event": "screen run", + "from": "ai-opt-in", + "program": "metrics", + }, + { + "event": "screen outro", + "from": "run", + "program": "metrics", + }, + { + "event": "screen keep-skills", + "from": "outro", + "program": "metrics", + }, + ], + "program": "metrics", + "screens": [ + "metrics-intro", + "health-check", + "auth", + "ai-opt-in", + "run", + "outro", + "keep-skills", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > migration (node) 1`] = ` +{ + "events": [ + { + "event": "screen health-check", + "from": "migration-intro", + "program": "migration", + }, + { + "event": "screen auth", + "from": "health-check", + "program": "migration", + }, + { + "event": "screen run", + "from": "auth", + "program": "migration", + }, + { + "event": "screen ai-opt-in", + "from": "run", + "program": "migration", + }, + { + "event": "screen run", + "from": "ai-opt-in", + "program": "migration", + }, + { + "event": "screen outro", + "from": "run", + "program": "migration", + }, + { + "event": "screen keep-skills", + "from": "outro", + "program": "migration", + }, + ], + "program": "migration", + "screens": [ + "migration-intro", + "health-check", + "auth", + "ai-opt-in", + "run", + "outro", + "keep-skills", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > posthog-doctor (node) 1`] = ` +{ + "events": [ + { + "event": "screen health-check", + "from": "doctor-intro", + "program": "posthog-doctor", + }, + { + "event": "screen auth", + "from": "health-check", + "program": "posthog-doctor", + }, + { + "event": "screen doctor-report", + "from": "auth", + "program": "posthog-doctor", + }, + { + "event": "screen outro", + "from": "doctor-report", + "program": "posthog-doctor", + }, + { + "event": "screen exit", + "from": "outro", + "program": "posthog-doctor", + }, + ], + "program": "posthog-doctor", + "screens": [ + "doctor-intro", + "health-check", + "auth", + "doctor-report", + "outro", + "exit", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > posthog-integration (nextjs, with a setup question) 1`] = ` +{ + "events": [ + { + "event": "screen health-check", + "from": "intro", + "program": "posthog-integration", + }, + { + "event": "screen setup", + "from": "health-check", + "program": "posthog-integration", + }, + { + "event": "screen auth", + "from": "setup", + "program": "posthog-integration", + }, + { + "event": "screen run", + "from": "auth", + "program": "posthog-integration", + }, + { + "event": "screen ai-opt-in", + "from": "run", + "program": "posthog-integration", + }, + { + "event": "screen run", + "from": "ai-opt-in", + "program": "posthog-integration", + }, + { + "event": "screen outro", + "from": "run", + "program": "posthog-integration", + }, + { + "event": "screen mcp", + "from": "outro", + "program": "posthog-integration", + }, + { + "event": "screen slack-connect", + "from": "mcp", + "program": "posthog-integration", + }, + { + "event": "screen keep-skills", + "from": "slack-connect", + "program": "posthog-integration", + }, + ], + "program": "posthog-integration", + "screens": [ + "intro", + "health-check", + "setup", + "auth", + "ai-opt-in", + "run", + "outro", + "mcp", + "slack-connect", + "keep-skills", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > posthog-integration (no framework detected) 1`] = ` +{ + "events": [ + { + "event": "screen health-check", + "from": "intro", + "program": "posthog-integration", + }, + { + "event": "screen auth", + "from": "health-check", + "program": "posthog-integration", + }, + { + "event": "screen run", + "from": "auth", + "program": "posthog-integration", + }, + { + "event": "screen ai-opt-in", + "from": "run", + "program": "posthog-integration", + }, + { + "event": "screen run", + "from": "ai-opt-in", + "program": "posthog-integration", + }, + { + "event": "screen outro", + "from": "run", + "program": "posthog-integration", + }, + { + "event": "screen mcp", + "from": "outro", + "program": "posthog-integration", + }, + { + "event": "screen slack-connect", + "from": "mcp", + "program": "posthog-integration", + }, + { + "event": "screen keep-skills", + "from": "slack-connect", + "program": "posthog-integration", + }, + ], + "program": "posthog-integration", + "screens": [ + "intro", + "health-check", + "auth", + "ai-opt-in", + "run", + "outro", + "mcp", + "slack-connect", + "keep-skills", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > posthog-integration (node) 1`] = ` +{ + "events": [ + { + "event": "screen health-check", + "from": "intro", + "program": "posthog-integration", + }, + { + "event": "screen auth", + "from": "health-check", + "program": "posthog-integration", + }, + { + "event": "screen run", + "from": "auth", + "program": "posthog-integration", + }, + { + "event": "screen ai-opt-in", + "from": "run", + "program": "posthog-integration", + }, + { + "event": "screen run", + "from": "ai-opt-in", + "program": "posthog-integration", + }, + { + "event": "screen outro", + "from": "run", + "program": "posthog-integration", + }, + { + "event": "screen mcp", + "from": "outro", + "program": "posthog-integration", + }, + { + "event": "screen slack-connect", + "from": "mcp", + "program": "posthog-integration", + }, + { + "event": "screen keep-skills", + "from": "slack-connect", + "program": "posthog-integration", + }, + ], + "program": "posthog-integration", + "screens": [ + "intro", + "health-check", + "auth", + "ai-opt-in", + "run", + "outro", + "mcp", + "slack-connect", + "keep-skills", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > replay-vision (node) 1`] = ` +{ + "events": [ + { + "event": "screen health-check", + "from": "agent-skill-intro", + "program": "replay-vision", + }, + { + "event": "screen auth", + "from": "health-check", + "program": "replay-vision", + }, + { + "event": "screen run", + "from": "auth", + "program": "replay-vision", + }, + { + "event": "screen ai-opt-in", + "from": "run", + "program": "replay-vision", + }, + { + "event": "screen run", + "from": "ai-opt-in", + "program": "replay-vision", + }, + { + "event": "screen outro", + "from": "run", + "program": "replay-vision", + }, + { + "event": "screen keep-skills", + "from": "outro", + "program": "replay-vision", + }, + ], + "program": "replay-vision", + "screens": [ + "agent-skill-intro", + "health-check", + "auth", + "ai-opt-in", + "run", + "outro", + "keep-skills", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > revenue-analytics-setup (node) 1`] = ` +{ + "events": [ + { + "event": "screen health-check", + "from": "revenue-intro", + "program": "revenue-analytics-setup", + }, + { + "event": "screen auth", + "from": "health-check", + "program": "revenue-analytics-setup", + }, + { + "event": "screen run", + "from": "auth", + "program": "revenue-analytics-setup", + }, + { + "event": "screen ai-opt-in", + "from": "run", + "program": "revenue-analytics-setup", + }, + { + "event": "screen run", + "from": "ai-opt-in", + "program": "revenue-analytics-setup", + }, + { + "event": "screen outro", + "from": "run", + "program": "revenue-analytics-setup", + }, + { + "event": "screen keep-skills", + "from": "outro", + "program": "revenue-analytics-setup", + }, + ], + "program": "revenue-analytics-setup", + "screens": [ + "revenue-intro", + "health-check", + "auth", + "ai-opt-in", + "run", + "outro", + "keep-skills", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > self-driving (node) 1`] = ` +{ + "events": [ + { + "event": "screen self-driving-integration-check", + "from": "self-driving-intro", + "program": "self-driving", + }, + { + "event": "screen health-check", + "from": "self-driving-integration-check", + "program": "self-driving", + }, + { + "event": "screen auth", + "from": "health-check", + "program": "self-driving", + }, + { + "event": "screen run", + "from": "auth", + "program": "self-driving", + }, + { + "event": "screen ai-opt-in", + "from": "run", + "program": "self-driving", + }, + { + "event": "screen run", + "from": "ai-opt-in", + "program": "self-driving", + }, + { + "event": "screen self-driving-handoff", + "from": "run", + "program": "self-driving", + }, + { + "event": "screen self-driving-github", + "from": "self-driving-handoff", + "program": "self-driving", + }, + { + "event": "screen run", + "from": "self-driving-github", + "program": "self-driving", + }, + { + "event": "screen outro", + "from": "run", + "program": "self-driving", + }, + { + "event": "screen exit", + "from": "outro", + "program": "self-driving", + }, + ], + "program": "self-driving", + "screens": [ + "self-driving-intro", + "self-driving-integration-check", + "health-check", + "auth", + "ai-opt-in", + "run", + "self-driving-handoff", + "self-driving-github", + "run", + "outro", + "exit", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > slack (node) 1`] = ` +{ + "events": [ + { + "event": "screen exit", + "from": "slack-connect", + "program": "slack", + }, + ], + "program": "slack", + "screens": [ + "slack-connect", + "exit", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > warehouse-source (node) 1`] = ` +{ + "events": [ + { + "event": "screen auth", + "from": "warehouse-intro", + "program": "warehouse-source", + }, + { + "event": "screen run", + "from": "auth", + "program": "warehouse-source", + }, + { + "event": "screen ai-opt-in", + "from": "run", + "program": "warehouse-source", + }, + { + "event": "screen run", + "from": "ai-opt-in", + "program": "warehouse-source", + }, + { + "event": "screen outro", + "from": "run", + "program": "warehouse-source", + }, + { + "event": "screen keep-skills", + "from": "outro", + "program": "warehouse-source", + }, + ], + "program": "warehouse-source", + "screens": [ + "warehouse-intro", + "auth", + "ai-opt-in", + "run", + "outro", + "keep-skills", + ], + "stoppedOn": null, +} +`; + +exports[`flow traces per program > web-analytics-doctor (node) 1`] = ` +{ + "events": [ + { + "event": "screen health-check", + "from": "agent-skill-intro", + "program": "web-analytics-doctor", + }, + { + "event": "screen auth", + "from": "health-check", + "program": "web-analytics-doctor", + }, + { + "event": "screen run", + "from": "auth", + "program": "web-analytics-doctor", + }, + { + "event": "screen ai-opt-in", + "from": "run", + "program": "web-analytics-doctor", + }, + { + "event": "screen run", + "from": "ai-opt-in", + "program": "web-analytics-doctor", + }, + { + "event": "screen outro", + "from": "run", + "program": "web-analytics-doctor", + }, + { + "event": "screen keep-skills", + "from": "outro", + "program": "web-analytics-doctor", + }, + ], + "program": "web-analytics-doctor", + "screens": [ + "agent-skill-intro", + "health-check", + "auth", + "ai-opt-in", + "run", + "outro", + "keep-skills", + ], + "stoppedOn": null, +} +`; + +exports[`headless walk analytics > audit: run phases without a TUI 1`] = ` +{ + "events": [], + "program": "audit", + "screen": "audit-intro", +} +`; + +exports[`headless walk analytics > posthog-integration: run phases without a TUI 1`] = ` +{ + "events": [], + "program": "posthog-integration", + "screen": "intro", +} +`; diff --git a/src/lib/programs/__tests__/__snapshots__/post-auth-gates.test.ts.snap b/src/lib/programs/__tests__/__snapshots__/post-auth-gates.test.ts.snap new file mode 100644 index 000000000..764f5263a --- /dev/null +++ b/src/lib/programs/__tests__/__snapshots__/post-auth-gates.test.ts.snap @@ -0,0 +1,28 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`post-auth gate ids per program > match the golden 1`] = ` +{ + "agent-skill": [], + "ai-observability": [], + "audit": [], + "error-tracking": [], + "error-tracking-upload-source-maps": [ + "detect", + ], + "events-audit": [], + "mcp-add": [], + "mcp-analytics": [], + "mcp-remove": [], + "mcp-tutorial": [], + "metrics": [], + "migration": [], + "posthog-doctor": [], + "posthog-integration": [], + "replay-vision": [], + "revenue-analytics-setup": [], + "self-driving": [], + "slack": [], + "warehouse-source": [], + "web-analytics-doctor": [], +} +`; diff --git a/src/lib/programs/__tests__/flow-traces.test.ts b/src/lib/programs/__tests__/flow-traces.test.ts new file mode 100644 index 000000000..acf23d064 --- /dev/null +++ b/src/lib/programs/__tests__/flow-traces.test.ts @@ -0,0 +1,231 @@ +/** + * Golden screen sequences and `screen ` analytics per program, produced + * by walking each program's steps through the store with a generic advance per + * screen. Baseline for the surface split: must stay byte identical. + */ +import { WizardStore, ScreenId, RunPhase, McpOutcome } from '@ui/tui/store'; +import { InkUI } from '@ui/tui/ink-ui'; +import { setUI } from '@ui/index'; +import { + buildSession, + OutroKind, + type WizardSession, +} from '@lib/wizard-session'; +import { Integration } from '@lib/constants'; +import { FRAMEWORK_REGISTRY } from '@lib/registry'; +import { HostResolution } from '@lib/host-resolution'; +import { WizardReadiness } from '@lib/health-checks/readiness'; +import { analytics } from '@utils/analytics'; +import { + PROGRAM_REGISTRY, + getProgramConfig, + type ProgramId, +} from '../program-registry'; +import { SELF_DRIVING_INTEGRATE_PATH_KEY } from '../self-driving/detect'; +import { ERROR_TRACKING_PROJECT_PATH_KEY } from '../error-tracking/detect-agentic'; +import { SOURCE_MAPS_CONTEXT_KEYS } from '../error-tracking-upload-source-maps/detect'; + +vi.mock('@utils/analytics', () => ({ + analytics: { + capture: vi.fn(), + wizardCapture: vi.fn(), + setTag: vi.fn(), + captureException: vi.fn(), + shutdown: vi.fn().mockResolvedValue(undefined), + }, + sessionProperties: vi.fn(() => ({})), +})); + +const wizardCapture = analytics.wizardCapture as Mock; + +interface ScreenEvent { + event: string; + from: unknown; + program: unknown; +} + +function screenEvents(): ScreenEvent[] { + return wizardCapture.mock.calls + .filter(([name]) => typeof name === 'string' && name.startsWith('screen ')) + .map(([name, props]) => ({ + event: name as string, + from: (props as Record)?.from_screen, + program: (props as Record)?.program_id, + })); +} + +const NODE = FRAMEWORK_REGISTRY[Integration.javascriptNode]; + +function createStore(program: ProgramId, integration: Integration | null) { + const store = new WizardStore(program); + setUI(new InkUI(store)); + const session = buildSession({ installDir: '/app', ci: false }); + if (integration) { + session.integration = integration; + session.frameworkConfig = FRAMEWORK_REGISTRY[integration]; + } + store.session = session; + return store; +} + +const approved = (ok: boolean) => + ({ + organization: { is_ai_data_processing_approved: ok }, + } as unknown as WizardSession['apiUser']); + +/** Commit what a user, the runner, or the agent would commit on this screen. */ +function advance(store: WizardStore, screen: string): boolean { + const s = store.session; + if (screen === ScreenId.Intro || screen.endsWith('-intro')) { + store.completeSetup(); + return true; + } + switch (screen) { + case ScreenId.HealthCheck: + store.setReadinessResult({ + decision: WizardReadiness.Yes, + health: {} as never, + reasons: [], + }); + return true; + case ScreenId.Setup: { + const questions = s.frameworkConfig?.metadata.setup?.questions ?? []; + for (const q of questions) { + if (!(q.key in s.frameworkContext)) { + store.setFrameworkContext(q.key, q.options[0].value); + } + } + return true; + } + case ScreenId.Auth: + store.setCredentials({ + accessToken: 'phx_test', + projectApiKey: 'phc_test', + host: HostResolution.fromApiHost('https://us.posthog.com'), + projectId: 1, + }); + store.setApiUser(approved(false)); + return true; + case ScreenId.AiOptIn: + store.setApiUser(approved(true)); + return true; + case ScreenId.Run: + case ScreenId.AuditRun: { + const steps = getProgramConfig(store.router.activeProgram).steps; + const runStep = steps.find( + (st) => + st.screenId === screen && + (!st.show || st.show(s)) && + (!st.isComplete || !st.isComplete(s)), + ); + if (runStep?.run) { + store.completeRunStep(runStep.id); + } else { + store.setRunPhase(RunPhase.Running); + store.setRunPhase(RunPhase.Completed); + } + return true; + } + case ScreenId.Outro: + case ScreenId.AuditOutro: + case ScreenId.SourceMapsOutro: + store.setOutroDismissed(); + return true; + case ScreenId.DoctorReport: + store.setOutroData({ kind: OutroKind.Success, message: 'done' }); + return true; + case ScreenId.Mcp: + case ScreenId.McpAdd: + case ScreenId.McpRemove: + store.setMcpComplete(McpOutcome.Skipped); + return true; + case ScreenId.McpSuggestedPrompts: + store.setMcpSuggestedPromptsDismissed(); + return true; + case ScreenId.SlackConnect: + store.setSlackStepDismissed(); + return true; + case ScreenId.KeepSkills: + store.setSkillsComplete(true); + return true; + case ScreenId.SelfDrivingIntegrationCheck: + store.setIntegrate(true); + return true; + case ScreenId.SelfDrivingIntegrationDetect: + store.setFrameworkContext(SELF_DRIVING_INTEGRATE_PATH_KEY, '.'); + store.setFrameworkConfig(Integration.javascriptNode, NODE); + return true; + case ScreenId.SelfDrivingHandoff: + store.confirmSelfDrivingHandoff(); + return true; + case ScreenId.SelfDrivingGithub: + store.setGithubConnected(true); + return true; + case ScreenId.ErrorTrackingDetect: + store.setFrameworkContext(ERROR_TRACKING_PROJECT_PATH_KEY, '.'); + store.setFrameworkConfig(Integration.javascriptNode, NODE); + return true; + case ScreenId.SourceMapsDetect: + store.setFrameworkContext( + SOURCE_MAPS_CONTEXT_KEYS.selectedVariant, + 'node', + ); + store.setFrameworkContext(SOURCE_MAPS_CONTEXT_KEYS.selectedPath, '.'); + return true; + default: + return false; + } +} + +function trace(program: ProgramId, integration: Integration | null) { + wizardCapture.mockClear(); + const store = createStore(program, integration); + const screens: string[] = []; + let stoppedOn: string | null = null; + for (let guard = 0; guard < 40; guard++) { + const screen = store.router.resolve(store.session); + screens.push(screen); + if (screen === ScreenId.Exit) break; + if (!advance(store, screen)) { + stoppedOn = screen; + break; + } + if (store.session.skillsComplete) break; + } + return { program, screens, stoppedOn, events: screenEvents() }; +} + +describe('flow traces per program', () => { + for (const config of PROGRAM_REGISTRY) { + it(`${config.id} (node)`, () => { + expect(trace(config.id, Integration.javascriptNode)).toMatchSnapshot(); + }); + } + + it('posthog-integration (nextjs, with a setup question)', () => { + expect(trace('posthog-integration', Integration.nextjs)).toMatchSnapshot(); + }); + + it('posthog-integration (no framework detected)', () => { + expect(trace('posthog-integration', null)).toMatchSnapshot(); + }); +}); + +describe('headless walk analytics', () => { + for (const program of ['posthog-integration', 'audit'] as ProgramId[]) { + it(`${program}: run phases without a TUI`, () => { + wizardCapture.mockClear(); + const store = new WizardStore(program); + setUI(new InkUI(store)); + store.session = buildSession({ installDir: '/app', ci: true }); + store.setRunPhase(RunPhase.Running); + store.setOutroData({ kind: OutroKind.Success, message: 'done' }); + store.setRunPhase(RunPhase.Completed); + expect({ + program, + screen: store.router.resolve(store.session), + events: screenEvents(), + }).toMatchSnapshot(); + }); + } +}); diff --git a/src/lib/programs/__tests__/post-auth-gates.test.ts b/src/lib/programs/__tests__/post-auth-gates.test.ts new file mode 100644 index 000000000..01ad25efd --- /dev/null +++ b/src/lib/programs/__tests__/post-auth-gates.test.ts @@ -0,0 +1,26 @@ +/** + * Golden of the post-auth gate ids the agent runner awaits per program + * (the walk at runner/shared/bootstrap.ts between the `auth` and `run` steps). + */ +import { PROGRAM_REGISTRY } from '../program-registry'; + +function legacyPostAuthGateIds( + steps: (typeof PROGRAM_REGISTRY)[number]['steps'], +): string[] { + const authIndex = steps.findIndex((s) => s.screenId === 'auth'); + const runIndex = steps.findIndex((s) => s.screenId === 'run'); + if (authIndex === -1 || runIndex <= authIndex) return []; + return steps + .slice(authIndex + 1, runIndex) + .filter((s) => s.gate) + .map((s) => s.id); +} + +describe('post-auth gate ids per program', () => { + it('match the golden', () => { + const gates = Object.fromEntries( + PROGRAM_REGISTRY.map((c) => [c.id, legacyPostAuthGateIds(c.steps)]), + ); + expect(gates).toMatchSnapshot(); + }); +}); diff --git a/src/ui/tui/__tests__/__snapshots__/frames/agent-skill-intro-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/agent-skill-intro-120x40.txt new file mode 100644 index 000000000..a507eb1ba --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/agent-skill-intro-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + + + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + .env* file contents will not leave your machine. + + Let's run the unknown skill. + + Directory ✔ /app + + ▸ Continue + More info + Privacy & data + Cancel + + + + + + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/agent-skill-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/agent-skill-intro-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/agent-skill-intro-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/ai-observability-intro-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/ai-observability-intro-120x40.txt new file mode 100644 index 000000000..dee366aea --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/ai-observability-intro-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + + + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + .env* file contents will not leave your machine. + + Let's instrument your LLM calls with PostHog AI Observability. + + Directory ✔ /app + + ▸ Continue + More info + Privacy & data + Cancel + + + + + + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/ai-observability-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/ai-observability-intro-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/ai-observability-intro-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/ai-opt-in-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/ai-opt-in-120x40.txt new file mode 100644 index 000000000..9cb0e0106 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/ai-opt-in-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + PostHog Setup Wizard + + ⚠ PostHog AI services are disabled for your organization + + The wizard uses Anthropic Claude. To proceed, enable "Enable PostHog + features that use third-party AI services" in your organization + settings. + + http://localhost:8010/project/42/settings/organization-details#organization-ai-consent + + + [O] Open settings in browser + [S] Show how to use your own AI + [R] Retry (after the toggle is enabled) + [E] Exit + + + + + + + + + + + + + + + + + + + + O open settings S show skill R retry E exit diff --git a/src/ui/tui/__tests__/__snapshots__/frames/ai-opt-in-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/ai-opt-in-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/ai-opt-in-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/audit-intro-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/audit-intro-120x40.txt new file mode 100644 index 000000000..8132aed5d --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/audit-intro-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + + + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + .env* file contents will not leave your machine. + + Let's review your existing PostHog setup for best practices. + + Directory ✔ /app + + ▸ Continue + More info + Privacy & data + Cancel + + + + + + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/audit-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/audit-intro-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/audit-intro-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/audit-outro-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/audit-outro-120x40.txt new file mode 100644 index 000000000..9727f363f --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/audit-outro-120x40.txt @@ -0,0 +1,17 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + ✔ PostHog is set up! + + Report saved to: + /app/posthog-setup-report.md + A markdown file in your project folder. Open it in any editor to read the full audit. + + Items audited: + 14 checks · 0 errors · 0 warnings · 0 suggestions + • No issues found. + + Learn more: https://posthog.com/docs + + Press any key to continue diff --git a/src/ui/tui/__tests__/__snapshots__/frames/audit-outro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/audit-outro-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/audit-outro-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/audit-run-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/audit-run-120x40.txt new file mode 100644 index 000000000..12c5a9ca5 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/audit-run-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + Verifying installation Checks + + ┌──────────────────────────────────────────────────────┐ ⠋ Installation (0/4) + │ app boot │ ◌ PostHog SDK installed + │ ▼ posthog.init(...) once │ ◌ SDK version up to date + │ │ │ ◌ Initialization is correct + │ ▼ posthog.capture('pageview') │ ◌ One initialization per runtime + │ posthog.capture('signup') │ + │ posthog.capture('purchase') │ Identification (0/4) + └──────────────────────────────────────────────────────┘ ◌ Stable distinct_id (not session UUID) + ◌ identify() called before captures / flag evals + PostHog releases frequent SDK updates to fix bugs and ◌ Same distinct_id across client and server + add new features. We're checking your project's SDK ◌ reset() called on logout / account switch + version and making sure it's up to date. + Event Capture (0/3) + We're also checking that your SDK is initialized ◌ Event names are static and consistent + correctly and in the right part of your app's lifecycle. ◌ Captures route through a reverse proxy + ◌ Key activation events captured + This ensures you won't miss any autocaptured events. + Live Data (0/1) + [O] Learn more ◌ Open findings in PostHog + + Write report (0/1) + ◌ Create posthog-audit-report.md + + Upload notebook (0/1) + ◌ Write the report into a PostHog notebook + + + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ◆ Reviewing autocapture coverage + + Status Audit plan Tail logs HN + + ←→ switch tab s toggle status diff --git a/src/ui/tui/__tests__/__snapshots__/frames/audit-run-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/audit-run-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/audit-run-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/auth-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/auth-120x40.txt new file mode 100644 index 000000000..694cc94f1 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/auth-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + PostHog Setup Wizard + + Privacy & data + • Source files are read by Claude for AI context + • .env* and secrets stay on your machine + • Press [I] for full privacy & usage info + + ⠋ Waiting for authentication... + + If the browser didn't open, copy and paste this URL: + + https://us.posthog.com/login?next=/oauth/authorize + + Press [C] to copy the link · on a remote machine or devbox? Press [P] to paste the callback URL. + + + + + + + + + + + + + + + + + + + + + P paste auth code C copy link I privacy & data diff --git a/src/ui/tui/__tests__/__snapshots__/frames/auth-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/auth-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/auth-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/auth-error-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/auth-error-120x40.txt new file mode 100644 index 000000000..5629b373b --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/auth-error-120x40.txt @@ -0,0 +1,18 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + ✘ Authentication error + + The Wizard couldn't connect to the PostHog LLM Gateway. Claude Code settings on this machine override the Wizard's + credentials. + + • /app/.claude/settings.json sets ANTHROPIC_BASE_URL + + Remove those keys from the file(s) above, or log out of Claude Code, then re-run the Wizard: + + claude auth logout + + Verbose log: /tmp/posthog-wizard.log + + Press any key to exit diff --git a/src/ui/tui/__tests__/__snapshots__/frames/auth-error-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/auth-error-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/auth-error-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/doctor-intro-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/doctor-intro-120x40.txt new file mode 100644 index 000000000..0ec73cc4e --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/doctor-intro-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + PostHog Doctor + Scan your project configuration for issues that may need attention. + + The wizard will: + • Sign you in to PostHog + • Fetch active health issues for your project + • Show you what needs to be resolved, with docs links + + ▸ Continue + Cancel + + + + + + + + + + + + + + + + + + + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/doctor-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/doctor-intro-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/doctor-intro-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/doctor-report-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/doctor-report-120x40.txt new file mode 100644 index 000000000..8b2c637da --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/doctor-report-120x40.txt @@ -0,0 +1,16 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + PostHog Doctor Report + Project 42 • https://us.posthog.com + + 2 active issues: 1 critical, 1 warning + + Critical (1) + ◼ Ingestion is delayed https://posthog.com/docs/support/troubleshooting + + Warning (1) + ◼ SDK version is out of date https://posthog.com/docs/libraries + + ▸ Continue diff --git a/src/ui/tui/__tests__/__snapshots__/frames/doctor-report-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/doctor-report-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/doctor-report-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-detect-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-detect-120x40.txt new file mode 100644 index 000000000..66d32065c --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-detect-120x40.txt @@ -0,0 +1,9 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + Detecting your project... + + ⠋ Scanning the repo for frameworks and PostHog SDKs... + + Starting up the detection agent… diff --git a/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-detect-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-detect-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-detect-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-intro-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-intro-120x40.txt new file mode 100644 index 000000000..545a8bb2b --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-intro-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + + + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + .env* file contents will not leave your machine. + + Let's make uncaught errors reach PostHog with readable stack traces. + + Directory ✔ /app + + ▸ Continue + More info + Privacy & data + Cancel + + + + + + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-intro-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-intro-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/exit-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/exit-120x40.txt new file mode 100644 index 000000000..48456b7b9 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/exit-120x40.txt @@ -0,0 +1,3 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide diff --git a/src/ui/tui/__tests__/__snapshots__/frames/exit-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/exit-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/exit-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/health-check-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/health-check-120x40.txt new file mode 100644 index 000000000..c8a2f4974 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/health-check-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + + + + ╭──────────────────────────────────────────────────────────────────────╮ + │ │ + │ Ongoing service disruptions │ + │ │ + │ ◼ Down ◼ Degraded ◼ No connection │ + │ │ + │ ◼ Skills download │ + │ │ + │ The Wizard can't download the skills it needs — neither GitHub │ + │ Releases nor PostHog's mirror is reachable right now. │ + │ │ + │ ──────────────────────────────────────────────────────────────── │ + │ │ + │ │ + │ ▸ Exit [Esc] │ + │ │ + ╰──────────────────────────────────────────────────────────────────────╯ + + + + + + + + + + ←→ switch esc cancel enter confirm diff --git a/src/ui/tui/__tests__/__snapshots__/frames/health-check-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/health-check-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/health-check-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/intro-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/intro-120x40.txt new file mode 100644 index 000000000..724976efa --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/intro-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + Review what data is shared in "Privacy & data." + .env* values stay on your machine. + + Let's do two hours of work in eight minutes. + + Directory ✔ /app + Framework ✔ Next.js (detected) + + ▸ Continue + Change framework + More info + Privacy & data + Cancel + + + + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/intro-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/intro-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/keep-skills-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/keep-skills-120x40.txt new file mode 100644 index 000000000..56e20ea52 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/keep-skills-120x40.txt @@ -0,0 +1,7 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + Keep the skills? + + Checking installed skills... diff --git a/src/ui/tui/__tests__/__snapshots__/frames/keep-skills-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/keep-skills-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/keep-skills-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/managed-settings-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/managed-settings-120x40.txt new file mode 100644 index 000000000..0d95de9a7 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/managed-settings-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + + ╭──────────────────────────────────────────────────────────────────────╮ + │ │ + │ ⚠ Settings conflict │ + │ │ + │ These Claude Code settings override credentials and prevent the │ + │ Wizard from reaching the PostHog LLM Gateway. │ + │ │ + │ Organization-managed settings │ + │ /Library/Application Support/ClaudeCode/managed-settings.json │ + │ • ANTHROPIC_BASE_URL │ + │ │ + │ Remove these keys (or run "claude auth logout"). Managed files │ + │ are root-owned — ask your IT administrator. │ + │ │ + │ ──────────────────────────────────────────────────────────────── │ + │ │ + │ Fix the file(s) above, then re-run the Wizard. │ + │ │ + │ ▸ Exit [Esc] │ + │ │ + ╰──────────────────────────────────────────────────────────────────────╯ + + + + + + + + ←→ switch esc cancel enter confirm diff --git a/src/ui/tui/__tests__/__snapshots__/frames/managed-settings-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/managed-settings-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/managed-settings-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/manual-auth-code-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/manual-auth-code-120x40.txt new file mode 100644 index 000000000..41a786da6 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/manual-auth-code-120x40.txt @@ -0,0 +1,11 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + ◆ Paste authorization code + + After authorizing, paste the callback URL it lands on — or just the code from it — here: + + http://localhost:8239/callback?code=… or the code + + ENTER submit · ESC cancel diff --git a/src/ui/tui/__tests__/__snapshots__/frames/manual-auth-code-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/manual-auth-code-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/manual-auth-code-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/mcp-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/mcp-120x40.txt new file mode 100644 index 000000000..782547112 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/mcp-120x40.txt @@ -0,0 +1,15 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + Install the MCP so you can chat to your data + + • Ask your agent: "List my feature flags" — and it does. + • Run SQL, build dashboards, ship flags, all from your IDE. + • No copy-pasting tokens or context. Your agent has the keys. + + Detected: Claude Code, Cursor + + Install the PostHog MCP server and plugin? + + ▸ Install No thanks diff --git a/src/ui/tui/__tests__/__snapshots__/frames/mcp-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/mcp-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/mcp-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/mcp-add-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/mcp-add-120x40.txt new file mode 100644 index 000000000..782547112 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/mcp-add-120x40.txt @@ -0,0 +1,15 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + Install the MCP so you can chat to your data + + • Ask your agent: "List my feature flags" — and it does. + • Run SQL, build dashboards, ship flags, all from your IDE. + • No copy-pasting tokens or context. Your agent has the keys. + + Detected: Claude Code, Cursor + + Install the PostHog MCP server and plugin? + + ▸ Install No thanks diff --git a/src/ui/tui/__tests__/__snapshots__/frames/mcp-add-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/mcp-add-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/mcp-add-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/mcp-remove-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/mcp-remove-120x40.txt new file mode 100644 index 000000000..e725c3cc8 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/mcp-remove-120x40.txt @@ -0,0 +1,11 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + Remove the PostHog MCP + + Detected: Claude Code, Cursor + + Remove the PostHog MCP server and plugin? + + ▸ Remove No thanks diff --git a/src/ui/tui/__tests__/__snapshots__/frames/mcp-remove-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/mcp-remove-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/mcp-remove-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/mcp-suggested-prompts-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/mcp-suggested-prompts-120x40.txt new file mode 100644 index 000000000..89e26e46e --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/mcp-suggested-prompts-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + PostHog MCP + + With MCP your agent works directly with the PostHog platform. You can prompt it to: + + ◆ Build dashboards + ◆ Run SQL queries + ◆ Deploy feature flags + ◆ Debug exceptions and errors + ◆ And lots more... + + Want a live demo using real data from your project? + ▸ Start MCP tutorial + Exit + + + + + + + + + + + + + + + + + + + + + ↑↓ navigate p pick new prompt esc exit enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/mcp-suggested-prompts-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/mcp-suggested-prompts-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/mcp-suggested-prompts-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/metrics-intro-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/metrics-intro-120x40.txt new file mode 100644 index 000000000..ac846908d --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/metrics-intro-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + + + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + .env* file contents will not leave your machine. + + Let's instrument your service with PostHog application metrics. + + Directory ✔ /app + + ▸ Continue + More info + Privacy & data + Cancel + + + + + + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/metrics-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/metrics-intro-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/metrics-intro-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/migration-intro-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/migration-intro-120x40.txt new file mode 100644 index 000000000..70e454685 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/migration-intro-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + + + + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + .env* file contents will not leave your machine. + + Let's migrate this project to PostHog. + + Directory ✔ /app + + ▸ Continue + Privacy & data + Cancel + + + + + + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/migration-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/migration-intro-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/migration-intro-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/mint-failure-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/mint-failure-120x40.txt new file mode 100644 index 000000000..8a6356d08 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/mint-failure-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + + + + + + + + ██ The Wizard's a little busy 🦔 + + The wizard can still share spells. Grab a skill and let your agent take over. + + ▸ Save skill + Open in Claude Code + Open in Codex + Report this issue + Exit + + + + + + + + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/mint-failure-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/mint-failure-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/mint-failure-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/outro-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/outro-120x40.txt new file mode 100644 index 000000000..acc954cc4 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/outro-120x40.txt @@ -0,0 +1,20 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + ✔ PostHog is set up! + + Events will start flowing once you run the app. + + Check ./posthog-setup-report.md for details + + What the agent did: + • Added posthog-js + • Wired the provider + + Learn more: https://posthog.com/docs?utm_source=wizard&utm_medium=cli&utm_content=outro-docs + + Note: This wizard uses an LLM agent to analyze and modify your project. Please review the changes made. + How did this work for you? Drop us a line: wizard@posthog.com + + Press any key to continue diff --git a/src/ui/tui/__tests__/__snapshots__/frames/outro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/outro-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/outro-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/port-conflict-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/port-conflict-120x40.txt new file mode 100644 index 000000000..8de35ce48 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/port-conflict-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + ╭──────────────────────────────────────────────────────────────────────╮ + │ │ + │ OAuth ports in use │ + │ │ + │ The wizard needs a local port for OAuth. We tried these ports │ + │ which are all in use: │ + │ │ + │ Port 8239 │ + │ Port 8238 │ + │ Port 8240 │ + │ Port 8237 │ + │ Port 8236 │ + │ Port 8235 │ + │ │ + │ Please free one of these ports and retry. │ + │ │ + │ ──────────────────────────────────────────────────────────────── │ + │ │ + │ Retry after freeing ports? │ + │ │ + │ ▸ Retry [Enter] Exit [Esc] │ + │ │ + ╰──────────────────────────────────────────────────────────────────────╯ + + + + + + + ←→ switch esc cancel enter confirm diff --git a/src/ui/tui/__tests__/__snapshots__/frames/port-conflict-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/port-conflict-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/port-conflict-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-120x40.txt new file mode 100644 index 000000000..18b366381 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + .env* file contents will not leave your machine. + + Let's create revenue analytics with Stripe and PostHog. + + Link purchases to product data. + + Directory ✔ /app + + ▸ Continue + More info + Privacy & data + Cancel + + + + + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/run-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/run-120x40.txt new file mode 100644 index 000000000..4fa1590f9 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/run-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + Learn Tasks + + ◼ Install posthog-js + ▶ Wiring the provider + ◻ Capture a test event + + ⠋ Progress: 1/3 completed + + + + + + + + + + + + + + + + + + + + + + + ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + ◆ Editing app/layout.tsx + + Status Event plan Tail logs Visualizer HN + + ←→ switch tab s toggle status diff --git a/src/ui/tui/__tests__/__snapshots__/frames/run-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/run-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/run-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-github-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-github-120x40.txt new file mode 100644 index 000000000..dac2e9023 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-github-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + Connect GitHub + + Self-driving needs GitHub access to research findings in your code and open fixes, so setup cannot finish without it. + + ◆ Grant it the repos you want Self-driving to work with — include this project's repo so it can also watch its issues. + + Install it: https://us.posthog.com/api/environments/42/integrations/authorize?kind=github + + ▸ Open GitHub App install + I can't connect right now + + + + + + + + + + + + + + + + + + + + + + + + ↑↓ navigate esc end setup enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-github-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-github-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-github-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-handoff-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-handoff-120x40.txt new file mode 100644 index 000000000..5fba8e669 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-handoff-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + ✔ PostHog is installed + + Now let's make your product self-driving. + + Next, the agent connects GitHub, turns on signal sources, and tunes the scouts that watch your product data. + + About 10 more minutes, and it needs your input a few times. Keep this terminal open. + + ▸ Set up Self-driving [Enter] + + You can find your PostHog integration report at ./posthog-setup-report.md + + + + + + + + + + + + + + + + + + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-handoff-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-handoff-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-handoff-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-check-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-check-120x40.txt new file mode 100644 index 000000000..402292cfb --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-check-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + No PostHog integration found + + This will kick off an agent to explore your project and find existing PostHog integrations. Self-driving reads PostHog + data, so we'll set that up first: it gives your signal sources something to watch. To do that we need to connect to + PostHog — do you already have an account? + + ▸ Yes, log me in (opens PostHog to authorize) + No, create one for me (we'll email you a login link) + + [I] Privacy & data + + + + + + + + + + + + + + + + + + + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-check-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-check-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-check-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-detect-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-detect-120x40.txt new file mode 100644 index 000000000..ad8b12c10 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-detect-120x40.txt @@ -0,0 +1,9 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + Detecting your project. Stick around, this will take a few seconds... + + ⠋ Scanning the repo for frameworks and PostHog SDKs... + + Starting up the detection agent… diff --git a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-detect-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-detect-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-detect-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-intro-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-intro-120x40.txt new file mode 100644 index 000000000..47914a5eb --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-intro-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + + + + ███ PostHog Wizard 🦔 + + We'll use .env* file contents will not leave your machine.lf-driving. + + + Let's set up PostHog Self-driving. + + PostHog watches how people really use your product, finds issues, and proposes fixes. + + An agent wAbout 10 minutes, with a few questions along the way.our scouts. + Agents charge a flat $15 per pull request they ship. + Directory ✔ /app + + ▸ Continue + More info + Privacy & data + Cancel + + + + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-intro-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-intro-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/session-timeout-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/session-timeout-120x40.txt new file mode 100644 index 000000000..ad1add63d --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/session-timeout-120x40.txt @@ -0,0 +1,11 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + ✘ Login timed out + + The OAuth link timed out after 30 minutes. + + Re-run the wizard to get a fresh link and try again. + + Press any key to exit diff --git a/src/ui/tui/__tests__/__snapshots__/frames/session-timeout-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/session-timeout-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/session-timeout-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/settings-override-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/settings-override-120x40.txt new file mode 100644 index 000000000..67fa2fb3e --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/settings-override-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + + + ╭──────────────────────────────────────────────────────────────╮ + │ │ + │ ⚠ Settings conflict │ + │ │ + │ Your settings file at /app/.claude/settings.json sets: │ + │ • ANTHROPIC_BASE_URL │ + │ • apiKeyHelper │ + │ │ + │ These settings override credentials and prevent the │ + │ Wizard from reaching the PostHog LLM Gateway. We can │ + │ back up the file and continue. │ + │ │ + │ ──────────────────────────────────────────────────────── │ + │ │ + │ Back up to .wizard-backup and continue? │ + │ │ + │ ▸ Backup & continue [Enter] Exit [Esc] │ + │ │ + ╰──────────────────────────────────────────────────────────────╯ + + + + + + + + + ←→ switch esc cancel enter confirm diff --git a/src/ui/tui/__tests__/__snapshots__/frames/settings-override-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/settings-override-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/settings-override-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/setup-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/setup-120x40.txt new file mode 100644 index 000000000..59b1eb3f8 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/setup-120x40.txt @@ -0,0 +1,10 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + Project Setup + Configuring Next.js integration + + Which Next.js router are you using? + ▸ App Router + Pages Router diff --git a/src/ui/tui/__tests__/__snapshots__/frames/setup-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/setup-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/setup-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/slack-connect-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/slack-connect-120x40.txt new file mode 100644 index 000000000..4f524734d --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/slack-connect-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + @PostHog in Slack + + Ask about your product data, debug issues, and generate PRs without leaving the thread. + + ◆ Tag @PostHog with a bug, edit, or a feature idea. It will spin up a sandboxed environment, plan, edit files, run + tests, and open a draft PR. + + ◆ Tag @PostHog with any data question. It's the same SQL-writing, statistically-minded assistant as PostHog AI, but it + responds where you send work memes. + + Connect it: + https://app.posthog.com/integrations/slack?utm_source=wizard&utm_medium=cli&utm_content=slack-connect-setup + Learn more: https://posthog.com/slack?utm_source=wizard&utm_medium=cli&utm_content=slack-connect-learn-more + + ▸ Open Slack setup + Skip / Continue + + + + + + + + + + + + + + + + + + ↑↓ navigate esc skip enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/slack-connect-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/slack-connect-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/slack-connect-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/source-maps-detect-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-detect-120x40.txt new file mode 100644 index 000000000..66d32065c --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-detect-120x40.txt @@ -0,0 +1,9 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + Detecting your project... + + ⠋ Scanning the repo for frameworks and PostHog SDKs... + + Starting up the detection agent… diff --git a/src/ui/tui/__tests__/__snapshots__/frames/source-maps-detect-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-detect-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-detect-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/source-maps-intro-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-intro-120x40.txt new file mode 100644 index 000000000..c65253abf --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-intro-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + .env* file contents will not leave your machine. + + The Wizard will run an agent to detect your project's + framework(s), download the relevant docs, and implement + source-map uploads for you. + + Ready? + + Directory ✔ /app + + ▸ Continue + More info + Privacy & data + Cancel + + + + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/source-maps-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-intro-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-intro-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/source-maps-outro-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-outro-120x40.txt new file mode 100644 index 000000000..e899fff37 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-outro-120x40.txt @@ -0,0 +1,24 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + ✔ PostHog is set up! + + What the wizard did: + • Installed the packages needed for source map upload. + • Wrote the PostHog upload credentials to your .env file. + + How uploads work now: + • Every build now uploads source maps to PostHog automatically — no extra command to remember. + • Run your app from the built output. Source maps only resolve for errors thrown by the build that was uploaded. + • In CI, the build job needs the same upload credentials. If the wizard wired your pipeline, add the referenced + secrets to your CI provider (e.g. GitHub repo secrets) before your next deploy. + + Details in /app/posthog-setup-report.md + + Learn more: https://posthog.com/docs + + Note: This wizard uses an LLM agent to analyze and modify your project. Please review the changes made. + How did this work for you? Drop us a line: wizard@posthog.com + + Press any key to continue diff --git a/src/ui/tui/__tests__/__snapshots__/frames/source-maps-outro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-outro-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-outro-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/task-notice-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/task-notice-120x40.txt new file mode 100644 index 000000000..367dd053c --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/task-notice-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + + + + + ╭──────────────────────────────────────────────────────────────────────────╮ + │ │ + │ Connect your data sources │ + │ │ + │ We detected warehouse sources in this project. │ + │ │ + │ Postgres, Stripe │ + │ │ + │ ──────────────────────────────────────────────────────────────────── │ + │ │ + │ Connect these during setup? │ + │ │ + │ ▸ Continue [Enter] Skip [Esc] │ + │ │ + ╰──────────────────────────────────────────────────────────────────────────╯ + + + + + + + + + + + ←→ switch esc cancel enter confirm diff --git a/src/ui/tui/__tests__/__snapshots__/frames/task-notice-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/task-notice-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/task-notice-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/warehouse-intro-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/warehouse-intro-120x40.txt new file mode 100644 index 000000000..4d35faa52 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/warehouse-intro-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + + + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + .env* file contents will not leave your machine. + + Let's connect your data to PostHog's data warehouse. + + Directory ✔ /app + + ▸ Continue + More info + Privacy & data + Cancel + + + + + + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/warehouse-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/warehouse-intro-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/warehouse-intro-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/wizard-ask-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/wizard-ask-120x40.txt new file mode 100644 index 000000000..a176b216c --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/wizard-ask-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + + + + + + + ╭──────────────────────────────────────────────────────────────────────╮ + │ │ + │ ◆ integration-nextjs │ + │ │ + │ Which router does this app use? │ + │ │ + │ ▸ App Router │ + │ Pages Router │ + │ │ + │ ESC skip │ + │ │ + ╰──────────────────────────────────────────────────────────────────────╯ + + + + + + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/wizard-ask-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/wizard-ask-60x15.txt new file mode 100644 index 000000000..cebaf5c47 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/wizard-ask-60x15.txt @@ -0,0 +1,9 @@ + + + + + + The Wizard needs more room to display required text. + Please make this terminal bigger. + + Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/keyboard-equivalence.test.tsx.snap b/src/ui/tui/__tests__/__snapshots__/keyboard-equivalence.test.tsx.snap new file mode 100644 index 000000000..c9b7a24f5 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/keyboard-equivalence.test.tsx.snap @@ -0,0 +1,241 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`keyboard commit vs control action commit > audit-outro: any key vs dismiss_outro 1`] = ` +{ + "action": { + "outroDismissed": true, + "screen": "keep-skills", + }, + "equal": false, + "keyboard": { + "outroDismissed": true, + "screen": "keep-skills", + "skillsComplete": true, + }, +} +`; + +exports[`keyboard commit vs control action commit > intro: enter on Continue vs confirm_setup 1`] = ` +{ + "action": { + "screen": "health-check", + "setupConfirmed": true, + }, + "equal": false, + "keyboard": { + "scanConsent": "granted", + "screen": "health-check", + "setupConfirmed": true, + "warehouseSourcesReported": true, + }, +} +`; + +exports[`keyboard commit vs control action commit > keep-skills: mount with no skills dir vs keep_skills 1`] = ` +{ + "action": { + "skillsComplete": true, + }, + "equal": false, + "keyboard": {}, +} +`; + +exports[`keyboard commit vs control action commit > manual-auth-code: escape vs dismiss_auth_code 1`] = ` +{ + "action": { + "overlay": false, + "screen": "auth", + }, + "equal": true, + "keyboard": { + "overlay": false, + "screen": "auth", + }, +} +`; + +exports[`keyboard commit vs control action commit > manual-auth-code: paste code and enter vs submit_auth_code 1`] = ` +{ + "action": { + "overlay": false, + "screen": "auth", + }, + "equal": true, + "keyboard": { + "overlay": false, + "screen": "auth", + }, +} +`; + +exports[`keyboard commit vs control action commit > mcp: decline install vs set_mcp_outcome skipped 1`] = ` +{ + "action": { + "mcpComplete": true, + "mcpOutcome": "skipped", + "screen": "slack-connect", + }, + "equal": false, + "keyboard": { + "mcpComplete": true, + "mcpOutcome": "skipped", + "screen": "slack-connect", + "slackConnected": false, + }, +} +`; + +exports[`keyboard commit vs control action commit > outro: any key vs dismiss_outro 1`] = ` +{ + "action": { + "outroDismissed": true, + "screen": "mcp", + }, + "equal": true, + "keyboard": { + "outroDismissed": true, + "screen": "mcp", + }, +} +`; + +exports[`keyboard commit vs control action commit > port-conflict: enter vs resolve_port_conflict 1`] = ` +{ + "action": { + "overlay": false, + "portConflictProcess": null, + "screen": "auth", + }, + "equal": true, + "keyboard": { + "overlay": false, + "portConflictProcess": null, + "screen": "auth", + }, +} +`; + +exports[`keyboard commit vs control action commit > self-driving-handoff: enter vs confirm_self_driving_handoff 1`] = ` +{ + "action": { + "screen": "self-driving-github", + "selfDrivingHandoffConfirmed": true, + }, + "equal": true, + "keyboard": { + "screen": "self-driving-github", + "selfDrivingHandoffConfirmed": true, + }, +} +`; + +exports[`keyboard commit vs control action commit > self-driving-integration-check: log me in vs set_integrate true 1`] = ` +{ + "action": { + "integrate": true, + "screen": "health-check", + }, + "equal": true, + "keyboard": { + "integrate": true, + "screen": "health-check", + }, +} +`; + +exports[`keyboard commit vs control action commit > setup: enter on first router option vs choose 1`] = ` +{ + "action": { + "frameworkContext": { + "router": "app-router", + }, + "screen": "auth", + }, + "equal": true, + "keyboard": { + "frameworkContext": { + "router": "app-router", + }, + "screen": "auth", + }, +} +`; + +exports[`keyboard commit vs control action commit > slack-connect: skip vs dismiss_slack 1`] = ` +{ + "action": { + "screen": "keep-skills", + "slackStepDismissed": true, + }, + "equal": false, + "keyboard": { + "screen": "keep-skills", + "skillsComplete": true, + "slackStepDismissed": true, + }, +} +`; + +exports[`keyboard commit vs control action commit > source-maps-outro: any key vs dismiss_outro 1`] = ` +{ + "action": { + "outroDismissed": true, + "screen": "keep-skills", + }, + "equal": false, + "keyboard": { + "outroDismissed": true, + "screen": "keep-skills", + "skillsComplete": true, + }, +} +`; + +exports[`keyboard commit vs control action commit > task-notice: enter vs resolve_notice keep 1`] = ` +{ + "action": { + "overlay": false, + "screen": "intro", + "taskNotice": null, + }, + "equal": true, + "keyboard": { + "overlay": false, + "screen": "intro", + "taskNotice": null, + }, +} +`; + +exports[`keyboard commit vs control action commit > task-notice: escape vs resolve_notice decline 1`] = ` +{ + "action": { + "overlay": false, + "screen": "intro", + "taskNotice": null, + }, + "equal": true, + "keyboard": { + "overlay": false, + "screen": "intro", + "taskNotice": null, + }, +} +`; + +exports[`keyboard commit vs control action commit > wizard-ask: type answer and enter vs answer_question 1`] = ` +{ + "action": { + "overlay": false, + "pendingQuestion": null, + "screen": "intro", + }, + "equal": true, + "keyboard": { + "overlay": false, + "pendingQuestion": null, + "screen": "intro", + }, +} +`; diff --git a/src/ui/tui/__tests__/frames.test.tsx b/src/ui/tui/__tests__/frames.test.tsx new file mode 100644 index 000000000..bd7f5ca91 --- /dev/null +++ b/src/ui/tui/__tests__/frames.test.tsx @@ -0,0 +1,587 @@ +// Behaviour baseline: every ScreenId and Overlay through real Ink at two sizes. +// Every fixture arranges session state until the router resolves to its target, +// so each frame carries the full ScreenContainer chrome. No screen needs a +// bare, router-bypassing render. + +import { vi, it, expect, describe, beforeAll, afterEach } from 'vitest'; +import { cleanup } from 'ink-testing-library'; + +vi.mock('ink', () => + vi.importActual('../../../../node_modules/ink/build/index.js'), +); + +const { pending } = vi.hoisted(() => ({ + pending: () => new Promise(() => undefined), +})); + +vi.mock('opn', () => ({ default: vi.fn(pending) })); +vi.mock('@utils/analytics', () => ({ + analytics: { + capture: vi.fn(), + wizardCapture: vi.fn(), + captureException: vi.fn(), + setTag: vi.fn(), + shutdown: vi.fn().mockResolvedValue(undefined), + }, + sessionProperties: vi.fn(() => ({})), +})); +vi.mock('@utils/clipboard', () => ({ + copyToClipboard: vi.fn().mockResolvedValue(true), + openInBrowser: vi.fn().mockResolvedValue(true), + browserOpenCommands: vi.fn(() => []), +})); +vi.mock('@utils/links', async (actual) => ({ + ...(await actual>()), + openTrackedLink: vi.fn(), +})); +vi.mock('@utils/debug', async (actual) => ({ + ...(await actual>()), + getLogFilePath: () => '/tmp/posthog-wizard.log', + logToFile: vi.fn(), + debug: vi.fn(), +})); +vi.mock('@utils/setup-utils', async (actual) => ({ + ...(await actual>()), + getOrAskForProjectData: vi.fn(pending), +})); +vi.mock('@lib/api', async (actual) => ({ + ...(await actual>()), + fetchUserData: vi.fn(pending), + fetchSlackConnected: vi.fn(pending), + fetchGithubConnected: vi.fn(pending), +})); +vi.mock('@lib/wizard-tools', async (actual) => ({ + ...(await actual>()), + fetchSkillMenu: vi.fn(pending), + downloadSkill: vi.fn(pending), +})); +vi.mock('@ui/tui/hooks/useGithubConnection', () => ({ + useGithubConnection: () => undefined, + fetchLoginUrl: vi.fn().mockResolvedValue(null), +})); +vi.mock('@lib/programs/self-driving/detect-agentic', async (actual) => ({ + ...(await actual>()), + detectSelfDrivingIntegrationProjects: vi.fn(pending), +})); +vi.mock('@lib/programs/error-tracking/detect-agentic', async (actual) => ({ + ...(await actual>()), + detectErrorTrackingProjects: vi.fn(pending), +})); +vi.mock( + '@lib/programs/error-tracking-upload-source-maps/detect-agentic', + async (actual) => ({ + ...(await actual>()), + detectSourceMapsProjects: vi.fn(pending), + }), +); +vi.mock('@lib/programs/posthog-doctor/fetch', () => ({ + fetchHealthIssues: vi.fn().mockResolvedValue([ + { + id: 'issue-1', + kind: 'ingestion_lag', + severity: 'critical', + status: 'active', + dismissed: false, + created_at: '2026-01-01T00:00:00Z', + updated_at: '2026-01-01T00:00:00Z', + }, + { + id: 'issue-2', + kind: 'sdk_outdated', + severity: 'warning', + status: 'active', + dismissed: false, + created_at: '2026-01-01T00:00:00Z', + updated_at: '2026-01-01T00:00:00Z', + }, + ]), +})); + +import { WizardStore, TaskStatus, type ScreenName } from '@ui/tui/store'; +import { InkUI } from '@ui/tui/ink-ui'; +import { setUI } from '@ui/index'; +import { ScreenId, Overlay } from '@ui/tui/router'; +import { createServices, type ScreenServices } from '@ui/tui/screen-registry'; +import { + buildSession, + OutroKind, + RunPhase, + McpOutcome, +} from '@lib/wizard-session'; +import { HostResolution } from '@lib/host-resolution'; +import { Integration } from '@lib/constants'; +import { FRAMEWORK_REGISTRY } from '@lib/registry'; +import type { FrameworkConfig } from '@lib/framework-config'; +import { Program, type ProgramId } from '@lib/programs/program-registry'; +import { + WizardReadiness, + type WizardReadinessResult, +} from '@lib/health-checks/readiness'; +import { ServiceHealthStatus } from '@lib/health-checks/types'; +import { SOURCE_MAPS_CONTEXT_KEYS } from '@lib/programs/error-tracking-upload-source-maps/detect'; +import { AUDIT_CHECKS_KEY } from '@lib/programs/audit/types'; +import { AUDIT_SEED_CHECKS } from '@lib/programs/audit/seed'; +import type { McpInstaller } from '@ui/tui/services/mcp-installer'; +import type { McpSuggestedPromptsServices } from '@ui/tui/services/mcp-suggested-prompts-services'; +import { + renderScreen, + screenShell, + type TerminalSize, +} from './helpers/render-screen.no-jest'; + +const SIZES: TerminalSize[] = [ + { columns: 120, rows: 40 }, + { columns: 60, rows: 15 }, +]; + +const CREDENTIALS = { + accessToken: 'phx_test_token', + projectApiKey: 'phc_test_key', + host: HostResolution.fromApiHost('https://us.posthog.com'), + projectId: 42, +}; + +const HEALTHY: WizardReadinessResult = { + decision: WizardReadiness.Yes, + health: { skillsOrigin: { status: ServiceHealthStatus.Healthy } }, + reasons: [], +}; + +const OUTAGE: WizardReadinessResult = { + decision: WizardReadiness.No, + health: { skillsOrigin: { status: ServiceHealthStatus.Down } }, + reasons: ['Skill downloads are unavailable.'], +}; + +const SUCCESS_OUTRO = { + kind: OutroKind.Success, + message: 'PostHog is set up!', + body: 'Events will start flowing once you run the app.', + changes: ['Added posthog-js', 'Wired the provider'], + reportFile: 'posthog-setup-report.md', + docsUrl: 'https://posthog.com/docs', +}; + +/** Next.js config with its setup question stubbed so detection never touches disk. */ +function staticFrameworkConfig(): FrameworkConfig { + const base = FRAMEWORK_REGISTRY[Integration.nextjs]; + const setup = base.metadata.setup; + if (!setup) return base; + return { + ...base, + metadata: { + ...base.metadata, + setup: { + ...setup, + questions: setup.questions.map((q) => ({ + ...q, + detect: () => Promise.resolve(null), + })), + }, + }, + }; +} + +const fakeInstaller: McpInstaller = { + detectClients: () => + Promise.resolve([ + { name: 'Claude Code', supportsPlugin: true, pluginBundlesMcp: false }, + { name: 'Cursor', supportsPlugin: false, pluginBundlesMcp: false }, + ]), + install: pending, + remove: pending, + installPlugins: pending, +}; + +const inertPromptsServices = { + performLogin: pending, + runPromptStreaming: () => ({ + [Symbol.asyncIterator]: () => ({ next: pending }), + }), + probeProjectData: pending, + seedDemoEvents: pending, +} as unknown as McpSuggestedPromptsServices; + +function makeStore(program: ProgramId): WizardStore { + const store = new WizardStore(program); + setUI(new InkUI(store)); + store.version = '0.0.0-test'; + store.session = buildSession({ installDir: '/app' }); + return store; +} + +function makeServices(store: WizardStore): ScreenServices { + return { + ...createServices(store), + mcpInstaller: fakeInstaller, + mcpSuggestedPromptsServices: inertPromptsServices, + }; +} + +function authed(store: WizardStore): void { + store.completeSetup(); + store.setReadinessResult(HEALTHY); + store.setCredentials(CREDENTIALS); +} + +function ranSuccessfully(store: WizardStore): void { + store.setRunPhase(RunPhase.Completed); + store.setOutroData(SUCCESS_OUTRO); +} + +interface Fixture { + program: ProgramId; + arrange?: (store: WizardStore) => void; +} + +const FIXTURES: Record = { + // ── Overlays ─────────────────────────────────────────────────── + [Overlay.SettingsOverride]: { + program: Program.PostHogIntegration, + arrange: (s) => + void s.showSettingsOverride( + [ + { + source: 'project', + path: '/app/.claude/settings.json', + keys: ['ANTHROPIC_BASE_URL', 'apiKeyHelper'], + writable: true, + }, + ], + () => true, + ), + }, + [Overlay.ManagedSettings]: { + program: Program.PostHogIntegration, + arrange: (s) => + void s.showSettingsOverride( + [ + { + source: 'managed', + path: '/Library/Application Support/ClaudeCode/managed-settings.json', + keys: ['ANTHROPIC_BASE_URL'], + writable: false, + }, + ], + () => true, + ), + }, + [Overlay.PortConflict]: { + program: Program.PostHogIntegration, + arrange: (s) => + void s.showPortConflict({ + command: 'node', + pid: '4242', + port: 8010, + user: 'wizard', + }), + }, + [Overlay.TaskNotice]: { + program: Program.PostHogIntegration, + arrange: (s) => + void s.showTaskNotice({ + title: 'Connect your data sources', + body: ['We detected warehouse sources in this project.'], + items: ['Postgres', 'Stripe'], + confirmLabel: 'Continue [Enter]', + cancelLabel: 'Skip [Esc]', + prompt: 'Connect these during setup?', + }), + }, + [Overlay.ManualAuthCode]: { + program: Program.PostHogIntegration, + arrange: (s) => { + s.completeSetup(); + s.setReadinessResult(HEALTHY); + s.showManualAuthCode(); + }, + }, + [Overlay.AuthError]: { + program: Program.PostHogIntegration, + arrange: (s) => + s.showAuthError({ + hasSettingsConflict: true, + conflicts: [ + { + source: 'project', + path: '/app/.claude/settings.json', + keys: ['ANTHROPIC_BASE_URL'], + writable: true, + }, + ], + credentialPlaces: ['ANTHROPIC_API_KEY in your shell profile'], + logFilePath: '/tmp/posthog-wizard.log', + }), + }, + [Overlay.SessionTimeout]: { + program: Program.PostHogIntegration, + arrange: (s) => s.showSessionTimeout(), + }, + [Overlay.WizardAsk]: { + program: Program.PostHogIntegration, + arrange: (s) => + void s.requestQuestion({ + id: 'q1', + source: 'integration-nextjs', + questions: [ + { + id: 'router', + prompt: 'Which router does this app use?', + kind: 'single', + options: [ + { label: 'App Router', value: 'app' }, + { label: 'Pages Router', value: 'pages' }, + ], + }, + ], + }), + }, + + // ── Program screens ──────────────────────────────────────────── + [ScreenId.Intro]: { + program: Program.PostHogIntegration, + arrange: (s) => { + s.setFrameworkConfig(Integration.nextjs, staticFrameworkConfig()); + s.setDetectedFramework('Next.js'); + s.setSkillId('nextjs'); + s.setDetectionComplete(); + }, + }, + [ScreenId.RevenueIntro]: { program: Program.RevenueAnalyticsSetup }, + [ScreenId.WarehouseIntro]: { program: Program.WarehouseSource }, + [ScreenId.SourceMapsIntro]: { + program: Program.ErrorTrackingUploadSourceMaps, + }, + [ScreenId.SourceMapsDetect]: { + program: Program.ErrorTrackingUploadSourceMaps, + arrange: (s) => { + s.completeSetup(); + s.setCredentials(CREDENTIALS); + }, + }, + [ScreenId.SourceMapsOutro]: { + program: Program.ErrorTrackingUploadSourceMaps, + arrange: (s) => { + s.completeSetup(); + s.setCredentials(CREDENTIALS); + s.setFrameworkContext(SOURCE_MAPS_CONTEXT_KEYS.selectedVariant, 'node'); + s.setFrameworkContext(SOURCE_MAPS_CONTEXT_KEYS.selectedPath, '.'); + ranSuccessfully(s); + }, + }, + [ScreenId.MigrationIntro]: { program: Program.Migration }, + [ScreenId.AgentSkillIntro]: { program: Program.AgentSkill }, + [ScreenId.AiObservabilityIntro]: { program: Program.AiObservability }, + [ScreenId.MetricsIntro]: { program: Program.Metrics }, + [ScreenId.ErrorTrackingIntro]: { program: Program.ErrorTracking }, + [ScreenId.ErrorTrackingDetect]: { + program: Program.ErrorTracking, + arrange: authed, + }, + [ScreenId.SelfDrivingIntro]: { program: Program.SelfDriving }, + [ScreenId.SelfDrivingIntegrationCheck]: { + program: Program.SelfDriving, + arrange: (s) => s.completeSetup(), + }, + [ScreenId.SelfDrivingIntegrationDetect]: { + program: Program.SelfDriving, + arrange: (s) => { + s.setIntegrate(true); + authed(s); + }, + }, + [ScreenId.SelfDrivingHandoff]: { + program: Program.SelfDriving, + arrange: (s) => { + s.setIntegrate(true); + authed(s); + s.setFrameworkConfig(Integration.nextjs, staticFrameworkConfig()); + s.completeRunStep('integrate-run'); + }, + }, + [ScreenId.SelfDrivingGithub]: { + program: Program.SelfDriving, + arrange: (s) => { + s.setIntegrate(true); + authed(s); + s.setFrameworkConfig(Integration.nextjs, staticFrameworkConfig()); + s.completeRunStep('integrate-run'); + s.confirmSelfDrivingHandoff(); + s.setGithubConnected(false); + }, + }, + [ScreenId.AuditIntro]: { program: Program.Audit }, + [ScreenId.AuditRun]: { + program: Program.Audit, + arrange: (s) => { + authed(s); + s.setFrameworkContext(AUDIT_CHECKS_KEY, AUDIT_SEED_CHECKS); + s.pushStatus('Reviewing autocapture coverage'); + }, + }, + [ScreenId.AuditOutro]: { + program: Program.Audit, + arrange: (s) => { + authed(s); + s.setFrameworkContext(AUDIT_CHECKS_KEY, AUDIT_SEED_CHECKS); + ranSuccessfully(s); + }, + }, + [ScreenId.HealthCheck]: { + program: Program.PostHogIntegration, + arrange: (s) => { + s.completeSetup(); + s.setReadinessResult(OUTAGE); + }, + }, + [ScreenId.DoctorIntro]: { program: Program.PosthogDoctor }, + [ScreenId.DoctorReport]: { + program: Program.PosthogDoctor, + arrange: authed, + }, + [ScreenId.Setup]: { + program: Program.PostHogIntegration, + arrange: (s) => { + s.setFrameworkConfig(Integration.nextjs, staticFrameworkConfig()); + s.completeSetup(); + s.setReadinessResult(HEALTHY); + }, + }, + [ScreenId.Auth]: { + program: Program.PostHogIntegration, + arrange: (s) => { + s.completeSetup(); + s.setReadinessResult(HEALTHY); + s.setLoginUrl('https://us.posthog.com/login?next=/oauth/authorize'); + }, + }, + [ScreenId.AiOptIn]: { + program: Program.PostHogIntegration, + arrange: (s) => { + authed(s); + s.setApiUser(apiUser(false)); + }, + }, + [ScreenId.Run]: { + program: Program.PostHogIntegration, + arrange: (s) => { + authed(s); + s.setRunPhase(RunPhase.Running); + s.syncTodos([ + { content: 'Install posthog-js', status: TaskStatus.Completed }, + { + content: 'Wire the provider', + status: TaskStatus.InProgress, + activeForm: 'Wiring the provider', + }, + { content: 'Capture a test event', status: TaskStatus.Pending }, + ]); + s.setEventPlan([ + { name: 'signup_completed', description: 'A new account was created' }, + ]); + s.pushStatus('Editing app/layout.tsx'); + }, + }, + [ScreenId.Mcp]: { + program: Program.PostHogIntegration, + arrange: (s) => { + authed(s); + ranSuccessfully(s); + s.setOutroDismissed(); + }, + }, + [ScreenId.McpSuggestedPrompts]: { program: Program.McpTutorial }, + [ScreenId.SlackConnect]: { + program: Program.SlackConnect, + arrange: (s) => { + s.setCredentials(CREDENTIALS); + s.setSlackConnected(false); + }, + }, + [ScreenId.KeepSkills]: { + program: Program.PostHogIntegration, + arrange: (s) => { + authed(s); + ranSuccessfully(s); + s.setOutroDismissed(); + s.setMcpComplete(McpOutcome.Skipped); + s.setSlackStepDismissed(); + }, + }, + [ScreenId.Outro]: { + program: Program.PostHogIntegration, + arrange: (s) => { + authed(s); + ranSuccessfully(s); + s.setDashboardUrl('https://us.posthog.com/project/42/dashboard/7'); + }, + }, + [ScreenId.MintFailure]: { + program: Program.PostHogIntegration, + arrange: (s) => { + authed(s); + s.setRunPhase(RunPhase.Error); + s.setOutroData({ + kind: OutroKind.Error, + message: 'The agent run failed', + }); + }, + }, + [ScreenId.Exit]: { + program: Program.PostHogIntegration, + arrange: (s) => { + authed(s); + s.setRunPhase(RunPhase.Error); + s.setOutroData({ + kind: OutroKind.Error, + message: 'The agent run failed', + }); + s.setMintHandoff('exit'); + }, + }, + [ScreenId.McpAdd]: { program: Program.McpAdd }, + [ScreenId.McpRemove]: { program: Program.McpRemove }, +}; + +/** Only the org's AI consent and membership level drive the gate screen. */ +function apiUser(approved: boolean): WizardStore['session']['apiUser'] { + return { + distinct_id: 'user-1', + team: { id: 42, organization: '00000000-0000-0000-0000-000000000000' }, + organization: { + id: '00000000-0000-0000-0000-000000000000', + name: 'Hedgehogs Inc', + membership_level: 8, + is_ai_data_processing_approved: approved, + }, + } as unknown as WizardStore['session']['apiUser']; +} + +beforeAll(() => { + vi.useFakeTimers(); + vi.setSystemTime(new Date('2026-01-01T00:00:00Z')); + vi.spyOn(process, 'exit').mockImplementation(() => undefined as never); + vi.spyOn(Math, 'random').mockReturnValue(0.42); +}); + +afterEach(cleanup); + +describe.each(Object.entries(FIXTURES))('%s', (name, fixture) => { + it.each(SIZES)(`at $columns x $rows`, async (size) => { + const screen = name as ScreenName; + const store = makeStore(fixture.program); + fixture.arrange?.(store); + expect(store.currentScreen).toBe(screen); + + const { frame } = await renderScreen( + store, + screenShell(store, makeServices(store)), + size, + ); + await expect(frame).toMatchFileSnapshot(snapshotPath(screen, size)); + }); +}); + +function snapshotPath(screen: ScreenName, size: TerminalSize): string { + return `__snapshots__/frames/${screen}-${size.columns}x${size.rows}.txt`; +} diff --git a/src/ui/tui/__tests__/helpers/render-screen.no-jest.tsx b/src/ui/tui/__tests__/helpers/render-screen.no-jest.tsx new file mode 100644 index 000000000..60e16196b --- /dev/null +++ b/src/ui/tui/__tests__/helpers/render-screen.no-jest.tsx @@ -0,0 +1,60 @@ +import { render } from 'ink-testing-library'; +import type { ReactNode } from 'react'; +import { vi } from 'vitest'; +import { ScreenContainer } from '@ui/tui/primitives/ScreenContainer'; +import { createScreens, type ScreenServices } from '@ui/tui/screen-registry'; +import type { WizardStore } from '@ui/tui/store'; + +export interface TerminalSize { + columns: number; + rows: number; +} + +export interface RenderedScreen { + app: ReturnType; + frame: string; +} + +// OSC 8 hyperlinks (LinkText) as well as the usual CSI colour/cursor codes. +// eslint-disable-next-line no-control-regex +const OSC_RE = /\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)/g; +// eslint-disable-next-line no-control-regex +const CSI_RE = /[\x1b\x9b][[()#;?]*[0-9;]*[A-Za-z]/g; + +export function toFrameText(raw: string | undefined): string { + return `${(raw ?? '').replace(OSC_RE, '').replace(CSI_RE, '')}\n` + .split('\n') + .map((line) => line.replace(/[ \t]+$/, '')) + .join('\n') + .replace(/\n+$/, '\n'); +} + +export async function flushInk(ms = 50): Promise { + await vi.advanceTimersByTimeAsync(ms); +} + +/** The shell App.tsx builds: router-resolved screen inside the full chrome. */ +export function screenShell( + store: WizardStore, + services: ScreenServices, +): ReactNode { + return ( + + ); +} + +export async function renderScreen( + store: WizardStore, + element: ReactNode, + { columns, rows }: TerminalSize, +): Promise { + const app = render(<>{element}); + const dimensions = { columns, rows, isTTY: true }; + for (const [key, value] of Object.entries(dimensions)) { + Object.defineProperty(app.stdout, key, { value, configurable: true }); + } + app.stdout.emit('resize'); + store.emitChange(); + await flushInk(); + return { app, frame: toFrameText(app.lastFrame()) }; +} diff --git a/src/ui/tui/__tests__/keyboard-equivalence.test.tsx b/src/ui/tui/__tests__/keyboard-equivalence.test.tsx new file mode 100644 index 000000000..330523f58 --- /dev/null +++ b/src/ui/tui/__tests__/keyboard-equivalence.test.tsx @@ -0,0 +1,457 @@ +/** + * Baseline: for each screen a controller can act on, drive the real screen by + * keyboard on one store and apply the control action on another, then golden + * both session diffs. Pairs whose diffs differ today are recorded, not hidden. + */ +import { vi, describe, it, expect, afterEach, beforeAll } from 'vitest'; +import { render, cleanup } from 'ink-testing-library'; +import { + WizardStore, + Program, + ScreenId, + Overlay, + RunPhase, + McpOutcome, + type ProgramId, +} from '../store'; +import { InkUI } from '../ink-ui'; +import { setUI } from '@ui/index'; +import { + buildSession, + OutroKind, + type WizardSession, +} from '@lib/wizard-session'; +import { Integration } from '@lib/constants'; +import { FRAMEWORK_REGISTRY } from '@lib/registry'; +import { HostResolution } from '@lib/host-resolution'; +import { WizardReadiness } from '@lib/health-checks/readiness'; +import { SOURCE_MAPS_CONTEXT_KEYS } from '@lib/programs/error-tracking-upload-source-maps/detect'; +import { SELF_DRIVING_INTEGRATE_PATH_KEY } from '@lib/programs/self-driving/detect'; +import { ScreenContainer } from '../primitives/ScreenContainer'; +import { + createScreens, + createServices, + type ScreenServices, +} from '../screen-registry'; +import { ACTION_REGISTRY } from '@e2e-harness/action-registry'; + +vi.mock('ink', () => + vi.importActual('../../../../node_modules/ink/build/index.js'), +); +vi.mock('@utils/analytics', () => ({ + analytics: { + capture: vi.fn(), + wizardCapture: vi.fn(), + setTag: vi.fn(), + captureException: vi.fn(), + shutdown: vi.fn().mockResolvedValue(undefined), + }, + sessionProperties: vi.fn(() => ({})), +})); +vi.mock('@utils/links', async (importOriginal) => ({ + ...(await importOriginal()), + openTrackedLink: vi.fn(), +})); +vi.mock('@utils/clipboard', async (importOriginal) => ({ + ...(await importOriginal()), + copyToClipboard: vi.fn().mockResolvedValue(false), + openInBrowser: vi.fn().mockResolvedValue(false), +})); +vi.mock('opn', () => ({ default: vi.fn() })); +vi.mock('@lib/api', async (importOriginal) => ({ + ...(await importOriginal()), + fetchSlackConnected: vi.fn().mockResolvedValue(false), + fetchUserData: vi.fn(() => new Promise(() => undefined)), +})); +vi.mock('@lib/wizard-tools', async (importOriginal) => ({ + ...(await importOriginal()), + fetchSkillMenu: vi.fn(() => new Promise(() => undefined)), +})); +vi.mock('@utils/setup-utils', async (importOriginal) => ({ + ...(await importOriginal()), + getOrAskForProjectData: vi.fn(() => new Promise(() => undefined)), +})); +vi.mock('@utils/wizard-abort', async (importOriginal) => ({ + ...(await importOriginal()), + wizardAbort: vi.fn().mockResolvedValue(undefined), +})); + +const ENTER = '\r'; +const ESC = '\u001B'; +const DOWN = '\u001B[B'; +const tick = (ms = 40) => new Promise((r) => setTimeout(r, ms)); + +const clean = { + decision: WizardReadiness.Yes, + health: {} as never, + reasons: [] as string[], +}; +const approved = (ok: boolean) => + ({ + organization: { is_ai_data_processing_approved: ok }, + } as unknown as WizardSession['apiUser']); + +const confirmed = (s: WizardStore) => { + s.completeSetup(); + s.setReadinessResult(clean); +}; +const authed = (s: WizardStore) => { + s.setCredentials({ + accessToken: 'phx_test', + projectApiKey: 'phc_test', + host: HostResolution.fromApiHost('https://us.posthog.com'), + projectId: 1, + }); + s.setApiUser(approved(true)); +}; +const ran = (s: WizardStore) => { + s.setRunPhase(RunPhase.Running); + s.setOutroData({ kind: OutroKind.Success, message: 'done' }); + s.setRunPhase(RunPhase.Completed); +}; + +const fakeInstaller = { + detectClients: () => + Promise.resolve([ + { name: 'Cursor', supportsPlugin: false }, + { name: 'Claude Code', supportsPlugin: true }, + ]), + install: () => Promise.resolve([]), +} as unknown as ScreenServices['mcpInstaller']; + +interface Pair { + name: string; + program: ProgramId; + integration?: Integration; + screen: string; + arrange: (s: WizardStore) => void; + keys: string[]; + action: string; + params?: Record; +} + +const nextjsRouterFirst = () => { + const setup = FRAMEWORK_REGISTRY[Integration.nextjs].metadata.setup; + if (!setup) throw new Error('nextjs setup questions missing'); + return setup.questions[0].options[0].value; +}; + +const PAIRS: Pair[] = [ + { + name: 'intro: enter on Continue vs confirm_setup', + program: Program.PostHogIntegration, + screen: ScreenId.Intro, + arrange: () => undefined, + keys: [ENTER], + action: 'confirm_setup', + }, + { + name: 'setup: enter on first router option vs choose', + program: Program.PostHogIntegration, + integration: Integration.nextjs, + screen: ScreenId.Setup, + arrange: confirmed, + keys: [ENTER], + action: 'choose', + params: { key: 'router', value: nextjsRouterFirst() }, + }, + { + name: 'outro: any key vs dismiss_outro', + program: Program.PostHogIntegration, + screen: ScreenId.Outro, + arrange: (s) => { + confirmed(s); + authed(s); + ran(s); + }, + keys: [ENTER], + action: 'dismiss_outro', + }, + { + name: 'mcp: decline install vs set_mcp_outcome skipped', + program: Program.PostHogIntegration, + screen: ScreenId.Mcp, + arrange: (s) => { + confirmed(s); + authed(s); + ran(s); + s.setOutroDismissed(); + }, + keys: [ESC], + action: 'set_mcp_outcome', + params: { outcome: 'skipped' }, + }, + { + name: 'slack-connect: skip vs dismiss_slack', + program: Program.PostHogIntegration, + screen: ScreenId.SlackConnect, + arrange: (s) => { + confirmed(s); + authed(s); + ran(s); + s.setOutroDismissed(); + s.setMcpComplete(McpOutcome.Skipped); + }, + keys: [DOWN, ENTER], + action: 'dismiss_slack', + }, + { + name: 'keep-skills: mount with no skills dir vs keep_skills', + program: Program.PostHogIntegration, + screen: ScreenId.KeepSkills, + arrange: (s) => { + confirmed(s); + authed(s); + ran(s); + s.setOutroDismissed(); + s.setMcpComplete(McpOutcome.Skipped); + s.setSlackStepDismissed(); + }, + keys: [], + action: 'keep_skills', + params: { kept: true }, + }, + { + name: 'audit-outro: any key vs dismiss_outro', + program: Program.Audit, + screen: ScreenId.AuditOutro, + arrange: (s) => { + confirmed(s); + authed(s); + ran(s); + }, + keys: [ENTER], + action: 'dismiss_outro', + }, + { + name: 'source-maps-outro: any key vs dismiss_outro', + program: Program.ErrorTrackingUploadSourceMaps, + screen: ScreenId.SourceMapsOutro, + arrange: (s) => { + s.completeSetup(); + authed(s); + s.setFrameworkContext(SOURCE_MAPS_CONTEXT_KEYS.selectedVariant, 'node'); + s.setFrameworkContext(SOURCE_MAPS_CONTEXT_KEYS.selectedPath, '.'); + ran(s); + }, + keys: [ENTER], + action: 'dismiss_outro', + }, + { + name: 'self-driving-integration-check: log me in vs set_integrate true', + program: Program.SelfDriving, + screen: ScreenId.SelfDrivingIntegrationCheck, + arrange: (s) => { + s.setFrameworkContext('postHogPresent', false); + s.completeSetup(); + }, + keys: [ENTER], + action: 'set_integrate', + params: { integrate: true }, + }, + { + name: 'self-driving-handoff: enter vs confirm_self_driving_handoff', + program: Program.SelfDriving, + screen: ScreenId.SelfDrivingHandoff, + arrange: (s) => { + s.setFrameworkContext('postHogPresent', false); + s.completeSetup(); + s.setIntegrate(true); + s.setReadinessResult(clean); + authed(s); + s.setFrameworkContext(SELF_DRIVING_INTEGRATE_PATH_KEY, '.'); + s.setFrameworkConfig( + Integration.javascriptNode, + FRAMEWORK_REGISTRY[Integration.javascriptNode], + ); + s.completeRunStep('integrate-run'); + }, + keys: [ENTER], + action: 'confirm_self_driving_handoff', + }, + { + name: 'wizard-ask: type answer and enter vs answer_question', + program: Program.PostHogIntegration, + screen: Overlay.WizardAsk, + arrange: (s) => { + void s.requestQuestion({ + id: 'ask-1', + source: 'test', + questions: [{ id: 'name', prompt: 'Name?', kind: 'text' }], + }); + }, + keys: ['yes', ENTER], + action: 'answer_question', + params: { answers: { name: 'yes' } }, + }, + { + name: 'task-notice: enter vs resolve_notice keep', + program: Program.PostHogIntegration, + screen: Overlay.TaskNotice, + arrange: (s) => { + void s.showTaskNotice({ + title: 'Optional step', + body: ['Body'], + prompt: 'Run it?', + confirmLabel: 'Yes', + cancelLabel: 'No', + }); + }, + keys: [ENTER], + action: 'resolve_notice', + params: { keep: true }, + }, + { + name: 'task-notice: escape vs resolve_notice decline', + program: Program.PostHogIntegration, + screen: Overlay.TaskNotice, + arrange: (s) => { + void s.showTaskNotice({ + title: 'Optional step', + body: ['Body'], + prompt: 'Run it?', + confirmLabel: 'Yes', + cancelLabel: 'No', + }); + }, + keys: [ESC], + action: 'resolve_notice', + params: { keep: false }, + }, + { + name: 'port-conflict: enter vs resolve_port_conflict', + program: Program.PostHogIntegration, + screen: Overlay.PortConflict, + arrange: (s) => { + confirmed(s); + void s.showPortConflict({ + command: 'node', + pid: '1', + port: 8000, + user: 'me', + }); + }, + keys: [ENTER], + action: 'resolve_port_conflict', + }, + { + name: 'manual-auth-code: paste code and enter vs submit_auth_code', + program: Program.PostHogIntegration, + screen: Overlay.ManualAuthCode, + arrange: (s) => { + confirmed(s); + s.showManualAuthCode(); + }, + keys: ['https://app.test/callback?code=abc123', ENTER], + action: 'submit_auth_code', + params: { code: 'abc123' }, + }, + { + name: 'manual-auth-code: escape vs dismiss_auth_code', + program: Program.PostHogIntegration, + screen: Overlay.ManualAuthCode, + arrange: (s) => { + confirmed(s); + s.showManualAuthCode(); + }, + keys: [ESC], + action: 'dismiss_auth_code', + }, +]; + +function makeStore(pair: Pair): WizardStore { + const store = new WizardStore(pair.program); + store.version = '0.0.0-test'; + setUI(new InkUI(store)); + const session = buildSession({ installDir: '/app', ci: false }); + const integration = pair.integration ?? Integration.javascriptNode; + session.integration = integration; + session.frameworkConfig = FRAMEWORK_REGISTRY[integration]; + store.session = session; + store.setDetectionComplete(); + pair.arrange(store); + return store; +} + +interface Snap { + screen: string; + overlay: boolean; + session: Record; +} + +function snap(store: WizardStore): Snap { + const session: Record = {}; + for (const [k, v] of Object.entries(store.session)) { + session[k] = k === 'frameworkConfig' ? (v ? '[config]' : null) : v; + } + return { + screen: store.currentScreen, + overlay: store.router.hasOverlay, + session, + }; +} + +function diff(before: Snap, after: Snap): Record { + const out: Record = {}; + if (before.screen !== after.screen) out.screen = after.screen; + if (before.overlay !== after.overlay) out.overlay = after.overlay; + for (const key of Object.keys(after.session)) { + if ( + JSON.stringify(before.session[key]) !== JSON.stringify(after.session[key]) + ) { + out[key] = after.session[key]; + } + } + return out; +} + +async function driveKeyboard(pair: Pair): Promise> { + const store = makeStore(pair); + const services = { ...createServices(store), mcpInstaller: fakeInstaller }; + const screens = createScreens(store, services); + const { stdin, unmount } = render( + , + ); + await tick(60); + expect(store.currentScreen).toBe(pair.screen); + const before = snap(store); + for (const key of pair.keys) { + stdin.write(key); + await tick(); + } + await tick(60); + const after = snap(store); + unmount(); + return diff(before, after); +} + +function applyAction(pair: Pair): Record { + const store = makeStore(pair); + expect(store.currentScreen).toBe(pair.screen); + const before = snap(store); + const action = ACTION_REGISTRY[pair.screen as ScreenId]?.find( + (a) => a.id === pair.action, + ); + if (!action) throw new Error(`no action ${pair.action} on ${pair.screen}`); + action.apply(store, pair.params ?? {}); + return diff(before, snap(store)); +} + +describe('keyboard commit vs control action commit', () => { + beforeAll(() => { + vi.spyOn(process, 'exit').mockImplementation(() => undefined as never); + }); + afterEach(() => cleanup()); + + for (const pair of PAIRS) { + it(pair.name, async () => { + const keyboard = await driveKeyboard(pair); + const action = applyAction(pair); + expect({ + keyboard, + action, + equal: JSON.stringify(keyboard) === JSON.stringify(action), + }).toMatchSnapshot(); + }); + } +}); diff --git a/src/ui/tui/__tests__/store-invariants.test.ts b/src/ui/tui/__tests__/store-invariants.test.ts new file mode 100644 index 000000000..8977738e7 --- /dev/null +++ b/src/ui/tui/__tests__/store-invariants.test.ts @@ -0,0 +1,873 @@ +/** + * Behaviour baseline for WizardStore + WizardRouter, taken before a refactor. + * Every expectation here pins what the code does today, exceptions included. + */ + +import { + WizardStore, + TaskStatus, + Program, + type ProgramId, + ScreenId, + Overlay, + RunPhase, + McpOutcome, + type ScreenName, +} from '@ui/tui/store'; +import { + buildSession, + AdditionalFeature, + DiscoveredFeature, + OutroKind, + type AskAnswers, + type PendingQuestion, + type TaskNotice, + type WizardSession, +} from '@lib/wizard-session'; +import { EXPANDED_COUNT } from '@ui/tui/constants'; +import { PROGRAM_SEQUENCES } from '@ui/tui/screen-sequences'; +import { WizardReadiness } from '@lib/health-checks/readiness'; +import { HostResolution } from '@lib/host-resolution'; +import { Integration } from '@lib/constants'; +import { FRAMEWORK_REGISTRY } from '@lib/registry'; +import { analytics } from '@utils/analytics'; +import { PROGRAM_REGISTRY } from '@lib/programs/program-registry'; +import type { SettingsConflict } from '@lib/agent/claude-settings'; + +vi.mock('../../../utils/analytics.js', () => ({ + analytics: { + capture: vi.fn(), + wizardCapture: vi.fn(), + captureException: vi.fn(), + setTag: vi.fn(), + shutdown: vi.fn().mockResolvedValue(undefined), + }, + sessionProperties: vi.fn(() => ({})), +})); + +vi.mock('../../../lib/health-checks/readiness.js', () => ({ + evaluateWizardReadiness: vi.fn().mockResolvedValue({ + decision: 'yes', + health: {}, + reasons: [], + }), + WizardReadiness: { + Yes: 'yes', + No: 'no', + YesWithWarnings: 'yes-with-warnings', + }, + SERVICE_LABELS: {}, + // Generated signup sessions reach the branch that reads this config. + SIGNUP_WIZARD_READINESS_CONFIG: {}, + getBlockingServiceKeys: vi.fn(() => []), +})); + +const wizardCaptureMock = analytics.wizardCapture as Mock; +const setTagMock = analytics.setTag as Mock; + +const CREDENTIALS = { + accessToken: 'tok', + projectApiKey: 'pk', + host: HostResolution.fromApiHost('https://app.posthog.com'), + projectId: 1, +}; + +const CLEAN_READINESS = { + decision: WizardReadiness.Yes, + health: {} as never, + reasons: [], +}; + +const SETTINGS_CONFLICT: SettingsConflict = { + source: 'project', + path: '/app/.claude/settings.json', + keys: ['ANTHROPIC_BASE_URL'], + writable: true, +}; + +const TASK_NOTICE: TaskNotice = { + title: 'Connect your sources', + body: ['body'], + confirmLabel: 'Continue', + cancelLabel: 'Skip', + prompt: 'Connect these?', +}; + +const PENDING_QUESTION: PendingQuestion = { + id: 'ask-1', + questions: [{ id: 'a', prompt: 'p', kind: 'text' }], + source: 'test-skill', +}; + +const ANSWERS: AskAnswers = { a: 'yes' }; + +const aiUser = (approved: boolean): WizardSession['apiUser'] => + ({ organization: { is_ai_data_processing_approved: approved } } as never); + +function createStore(program?: ProgramId): WizardStore { + return new WizardStore(program); +} + +async function flushMicrotasks(): Promise { + await Promise.resolve(); + await Promise.resolve(); +} + +function tracked(promise: Promise): { resolved: boolean } { + const state = { resolved: false }; + void promise.then(() => { + state.resolved = true; + }); + return state; +} + +function countEmissions(store: WizardStore, act: () => void): number { + let count = 0; + const unsubscribe = store.subscribe(() => { + count += 1; + }); + act(); + unsubscribe(); + return count; +} + +interface MutationCase { + name: string; + /** Untracked setup — emissions it fires are excluded from the count. */ + prepare?: (store: WizardStore) => void; + invoke: (store: WizardStore) => void; + emits: number; +} + +const MUTATIONS: MutationCase[] = [ + { + name: 'setCurrentStage', + invoke: (s) => s.setCurrentStage('stage'), + emits: 1, + }, + { + name: 'toggleStatusExpanded', + invoke: (s) => s.toggleStatusExpanded(), + emits: 1, + }, + { + name: 'setStatusExpanded', + invoke: (s) => s.setStatusExpanded(true), + emits: 1, + }, + { name: 'completeSetup', invoke: (s) => s.completeSetup(), emits: 1 }, + { name: 'grantSharing', invoke: (s) => s.grantSharing(), emits: 1 }, + { name: 'declineSharing', invoke: (s) => s.declineSharing(), emits: 1 }, + { + name: 'setRunPhase', + invoke: (s) => s.setRunPhase(RunPhase.Running), + emits: 1, + }, + { + name: 'setCredentials', + invoke: (s) => s.setCredentials(CREDENTIALS), + emits: 1, + }, + { + name: 'setAccessToken', + invoke: (s) => s.setAccessToken(CREDENTIALS), + emits: 1, + }, + { + name: 'setRoleAtOrganization', + invoke: (s) => s.setRoleAtOrganization('engineer'), + emits: 1, + }, + { name: 'setApiUser', invoke: (s) => s.setApiUser(aiUser(true)), emits: 1 }, + { + name: 'setFrameworkConfig', + invoke: (s) => + s.setFrameworkConfig( + Integration.javascriptNode, + FRAMEWORK_REGISTRY[Integration.javascriptNode], + ), + emits: 1, + }, + { + name: 'setDetectionComplete', + invoke: (s) => s.setDetectionComplete(), + emits: 1, + }, + { + name: 'setDetectedFramework', + invoke: (s) => s.setDetectedFramework('Node.js'), + emits: 1, + }, + { + name: 'setPosthogSdkDetected', + invoke: (s) => s.setPosthogSdkDetected(true), + emits: 1, + }, + { + name: 'setSpellbook', + invoke: (s) => s.setSpellbook({ path: '/app/skill', skillsIncluded: true }), + emits: 1, + }, + { + name: 'setMintHandoff', + invoke: (s) => s.setMintHandoff('continue'), + emits: 1, + }, + { + name: 'setSkillId', + invoke: (s) => s.setSkillId('integration-nextjs'), + emits: 1, + }, + { + name: 'setUnsupportedVersion', + invoke: (s) => + s.setUnsupportedVersion({ current: '1', minimum: '2', docsUrl: 'u' }), + emits: 1, + }, + { + name: 'setLoginUrl', + invoke: (s) => s.setLoginUrl('http://localhost:8010'), + emits: 1, + }, + { + name: 'setAuthorizeUrl', + invoke: (s) => s.setAuthorizeUrl('https://app.posthog.com'), + emits: 1, + }, + { + name: 'setReadinessResult', + invoke: (s) => s.setReadinessResult(CLEAN_READINESS), + emits: 1, + }, + { name: 'dismissOutage', invoke: (s) => s.dismissOutage(), emits: 1 }, + { + name: 'showSettingsOverride', + invoke: (s) => void s.showSettingsOverride([SETTINGS_CONFLICT], () => true), + emits: 1, + }, + { + name: 'showPortConflict', + invoke: (s) => + void s.showPortConflict({ + command: 'node', + pid: '1', + port: 8010, + user: 'u', + }), + emits: 1, + }, + { + name: 'resolvePortConflict', + prepare: (s) => + void s.showPortConflict({ + command: 'node', + pid: '1', + port: 8010, + user: 'u', + }), + invoke: (s) => s.resolvePortConflict(), + emits: 1, + }, + { + name: 'showTaskNotice', + invoke: (s) => void s.showTaskNotice(TASK_NOTICE), + emits: 1, + }, + { + name: 'resolveTaskNotice', + prepare: (s) => void s.showTaskNotice(TASK_NOTICE), + invoke: (s) => s.resolveTaskNotice(true), + emits: 1, + }, + // No overlay push — the modal is opened separately by showManualAuthCode. + { + name: 'waitForManualAuthCode', + invoke: (s) => void s.waitForManualAuthCode(), + emits: 0, + }, + { + name: 'showManualAuthCode', + invoke: (s) => s.showManualAuthCode(), + emits: 1, + }, + { + name: 'dismissManualAuthCode', + prepare: (s) => s.showManualAuthCode(), + invoke: (s) => s.dismissManualAuthCode(), + emits: 1, + }, + { + name: 'submitManualAuthCode', + prepare: (s) => s.showManualAuthCode(), + invoke: (s) => s.submitManualAuthCode('code'), + emits: 1, + }, + { + name: 'requestQuestion', + invoke: (s) => void s.requestQuestion(PENDING_QUESTION), + emits: 1, + }, + { + name: 'resolvePendingQuestion', + prepare: (s) => void s.requestQuestion(PENDING_QUESTION), + invoke: (s) => s.resolvePendingQuestion(ANSWERS), + emits: 1, + }, + { + name: 'cancelPendingQuestion', + prepare: (s) => void s.requestQuestion(PENDING_QUESTION), + invoke: (s) => s.cancelPendingQuestion(), + emits: 1, + }, + { + name: 'backupAndFixSettingsOverride', + prepare: (s) => + void s.showSettingsOverride([SETTINGS_CONFLICT], () => true), + invoke: (s) => void s.backupAndFixSettingsOverride(), + emits: 1, + }, + { + name: 'showAuthError', + invoke: (s) => + s.showAuthError({ hasSettingsConflict: false, logFilePath: '/tmp/log' }), + emits: 1, + }, + { + name: 'showSessionTimeout', + invoke: (s) => s.showSessionTimeout(), + emits: 1, + }, + { + name: 'addDiscoveredFeature', + invoke: (s) => s.addDiscoveredFeature(DiscoveredFeature.Stripe), + emits: 1, + }, + { + name: 'enableFeature', + invoke: (s) => s.enableFeature(AdditionalFeature.LLM), + emits: 1, + }, + { + name: 'setMcpComplete', + invoke: (s) => s.setMcpComplete(McpOutcome.Installed, ['claude'], 'all'), + emits: 1, + }, + { + name: 'setSkillsComplete', + invoke: (s) => s.setSkillsComplete(true), + emits: 1, + }, + { + name: 'setMcpSuggestedPromptsDismissed', + invoke: (s) => s.setMcpSuggestedPromptsDismissed(), + emits: 1, + }, + { + name: 'setSlackStepDismissed', + invoke: (s) => s.setSlackStepDismissed(), + emits: 1, + }, + { + name: 'setSlackConnected', + invoke: (s) => s.setSlackConnected(true), + emits: 1, + }, + { + name: 'setGithubConnected', + invoke: (s) => s.setGithubConnected(true), + emits: 1, + }, + { + name: 'declineGithub', + invoke: (s) => + s.declineGithub({ kind: OutroKind.Cancel, message: 'declined' }), + emits: 1, + }, + { + name: 'setIntegrate', + invoke: (s) => s.setIntegrate(true, { via: 'screen' }), + emits: 1, + }, + { + name: 'chooseProvisionAccount', + invoke: (s) => s.chooseProvisionAccount('a@b.com', 'us'), + emits: 1, + }, + { + name: 'confirmSelfDrivingHandoff', + invoke: (s) => s.confirmSelfDrivingHandoff(), + emits: 1, + }, + { + name: 'completeRunStep', + invoke: (s) => s.completeRunStep('integrate-run'), + emits: 1, + }, + { name: 'setOutroDismissed', invoke: (s) => s.setOutroDismissed(), emits: 1 }, + { + name: 'setOutroData', + invoke: (s) => s.setOutroData({ kind: OutroKind.Success, message: 'done' }), + emits: 1, + }, + { + name: 'setDashboardUrl', + invoke: (s) => s.setDashboardUrl('https://d'), + emits: 1, + }, + { + name: 'setNotebookUrl', + invoke: (s) => s.setNotebookUrl('https://n'), + emits: 1, + }, + { + name: 'setFrameworkContext', + invoke: (s) => s.setFrameworkContext('k', 'v'), + emits: 1, + }, + { + name: 'switchProgram', + invoke: (s) => s.switchProgram(Program.Metrics), + emits: 1, + }, + { + name: 'pushOverlay', + invoke: (s) => s.pushOverlay(Overlay.WizardAsk), + emits: 1, + }, + { + name: 'popOverlay', + prepare: (s) => s.pushOverlay(Overlay.WizardAsk), + invoke: (s) => s.popOverlay(), + emits: 1, + }, + { name: 'pushStatus', invoke: (s) => s.pushStatus('working'), emits: 1 }, + { name: 'toggleTokenHud', invoke: (s) => s.toggleTokenHud(), emits: 1 }, + { + name: 'addTokenUsage', + invoke: (s) => + s.addTokenUsage({ + inputTokens: 10, + outputTokens: 5, + cacheReadTokens: 0, + cacheCreationTokens: 0, + cacheCreation5m: 0, + cacheCreation1h: 0, + }), + emits: 1, + }, + { + name: 'setFinalTokenCostUsd', + invoke: (s) => s.setFinalTokenCostUsd(1.25), + emits: 1, + }, + { + name: 'setTasks', + invoke: (s) => + s.setTasks([{ label: 'a', status: TaskStatus.Pending, done: false }]), + emits: 1, + }, + { + name: 'updateTask', + prepare: (s) => + s.setTasks([{ label: 'a', status: TaskStatus.Pending, done: false }]), + invoke: (s) => s.updateTask(0, true), + emits: 1, + }, + { + name: 'setEventPlan', + invoke: (s) => s.setEventPlan([{ name: 'signed_up', description: 'd' }]), + emits: 1, + }, + { + name: 'setHandoffText', + invoke: (s) => s.setHandoffText('handoff'), + emits: 1, + }, + // Render-only cursor: the learn card drives its own re-render. + { + name: 'setLearnCardBlockIdx', + invoke: (s) => s.setLearnCardBlockIdx(2), + emits: 0, + }, + { + name: 'setLearnCardComplete', + invoke: (s) => s.setLearnCardComplete(), + emits: 1, + }, + { + name: 'syncTodos', + invoke: (s) => s.syncTodos([{ content: 'a', status: 'pending' }]), + emits: 1, + }, +]; + +/** Read-only or notification-plumbing methods, excluded by the task brief. */ +const NON_MUTATING = [ + 'subscribe', + 'getSnapshot', + 'getVersion', + 'runInitHooks', + 'runReadyHooks', + 'getGate', + 'waitUntil', + 'onEnterScreen', + 'emitChange', +]; + +describe('store invariants', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + describe('one notification per mutation', () => { + it('enumerates every public method on the class', () => { + const methods = Object.getOwnPropertyNames(WizardStore.prototype).filter( + (name) => { + const descriptor = Object.getOwnPropertyDescriptor( + WizardStore.prototype, + name, + ); + return ( + typeof descriptor?.value === 'function' && + name !== 'constructor' && + !name.startsWith('_') + ); + }, + ); + const covered = new Set([ + ...MUTATIONS.map((c) => c.name), + ...NON_MUTATING, + ]); + + expect(methods.filter((name) => !covered.has(name))).toEqual([]); + expect([...covered].filter((name) => !methods.includes(name))).toEqual( + [], + ); + }); + + it.each(MUTATIONS)( + '$name notifies $emits time(s)', + ({ prepare, invoke, emits }) => { + const store = createStore(); + prepare?.(store); + expect(countEmissions(store, () => invoke(store))).toBe(emits); + }, + ); + + it('cancelPendingQuestion with no question pending notifies nothing', () => { + const store = createStore(); + expect(countEmissions(store, () => store.cancelPendingQuestion())).toBe( + 0, + ); + }); + + it('backupAndFixSettingsOverride with no pending fix notifies nothing', () => { + const store = createStore(); + expect( + countEmissions(store, () => void store.backupAndFixSettingsOverride()), + ).toBe(0); + }); + + it('updateTask on a missing index notifies nothing', () => { + const store = createStore(); + expect(countEmissions(store, () => store.updateTask(3, true))).toBe(0); + }); + + it('switchProgram to the active program notifies nothing', () => { + const store = createStore(); + expect( + countEmissions(store, () => + store.switchProgram(Program.PostHogIntegration), + ), + ).toBe(0); + }); + + it('setStatusExpanded to the current value notifies nothing', () => { + const store = createStore(); + expect(countEmissions(store, () => store.setStatusExpanded(false))).toBe( + 0, + ); + }); + + it('setCurrentStage with the same stage notifies nothing', () => { + const store = createStore(); + store.setCurrentStage('stage'); + expect(countEmissions(store, () => store.setCurrentStage('stage'))).toBe( + 0, + ); + }); + + it('setHandoffText with identical text notifies nothing', () => { + const store = createStore(); + store.setHandoffText('handoff'); + expect(countEmissions(store, () => store.setHandoffText('handoff'))).toBe( + 0, + ); + }); + }); + + describe('gates latch once', () => { + it('resolves when the predicate turns true and stays resolved after it turns false', async () => { + const store = createStore(); + const gate = tracked(store.getGate('intro')); + await flushMicrotasks(); + expect(gate.resolved).toBe(false); + + store.completeSetup(); + await flushMicrotasks(); + expect(gate.resolved).toBe(true); + + store.session = buildSession({}); + await flushMicrotasks(); + expect(store.session.setupConfirmed).toBe(false); + + const relatched = tracked(store.getGate('intro')); + await flushMicrotasks(); + expect(relatched.resolved).toBe(true); + }); + + it('returns an already resolved promise for an unknown step', async () => { + const store = createStore(); + const gate = tracked(store.getGate('nonexistent')); + await flushMicrotasks(); + expect(gate.resolved).toBe(true); + }); + + it('waitUntil resolves on the next commit that matches', async () => { + const store = createStore(); + const waiter = tracked(store.waitUntil((s) => s.credentials !== null)); + await flushMicrotasks(); + expect(waiter.resolved).toBe(false); + + store.setDetectionComplete(); + await flushMicrotasks(); + expect(waiter.resolved).toBe(false); + + store.setCredentials(CREDENTIALS); + await flushMicrotasks(); + expect(waiter.resolved).toBe(true); + }); + + it('waitUntil evaluates live, so an already true predicate resolves immediately', async () => { + const store = createStore(); + store.completeSetup(); + const waiter = tracked(store.waitUntil((s) => s.setupConfirmed)); + await flushMicrotasks(); + expect(waiter.resolved).toBe(true); + }); + }); + + describe('overlays are LIFO', () => { + it('unwinds in reverse order back to the program screen', () => { + const store = createStore(); + expect(store.router.hasOverlay).toBe(false); + + store.pushOverlay(Overlay.AuthError); + store.pushOverlay(Overlay.SessionTimeout); + expect(store.router.resolve(store.session)).toBe(Overlay.SessionTimeout); + expect(store.router.hasOverlay).toBe(true); + + store.popOverlay(); + expect(store.router.resolve(store.session)).toBe(Overlay.AuthError); + expect(store.router.hasOverlay).toBe(true); + + store.popOverlay(); + expect(store.router.hasOverlay).toBe(false); + expect(store.router.resolve(store.session)).toBe(ScreenId.Intro); + }); + + it('tracks the nav direction across emits and overlay moves', () => { + const store = createStore(); + expect(store.lastNavDirection).toBeNull(); + + store.emitChange(); + expect(store.lastNavDirection).toBe('push'); + + store.pushOverlay(Overlay.AuthError); + expect(store.lastNavDirection).toBe('push'); + + store.popOverlay(); + expect(store.lastNavDirection).toBe('pop'); + + store.emitChange(); + expect(store.lastNavDirection).toBe('push'); + }); + }); + + describe('status ring', () => { + it('skips consecutive duplicates but keeps a repeat that is not adjacent', () => { + const store = createStore(); + store.pushStatus('a'); + store.pushStatus('a'); + store.pushStatus('b'); + store.pushStatus('a'); + expect(store.statusMessages).toEqual(['a', 'b', 'a']); + }); + + it('caps at the expanded window, dropping the oldest', () => { + const store = createStore(); + const total = EXPANDED_COUNT + 3; + for (let i = 0; i < total; i++) store.pushStatus(`m${i}`); + + expect(store.statusMessages).toHaveLength(EXPANDED_COUNT); + expect(store.statusMessages[0]).toBe(`m${total - EXPANDED_COUNT}`); + expect(store.statusMessages[EXPANDED_COUNT - 1]).toBe(`m${total - 1}`); + }); + }); + + describe('screen resolution is total', () => { + const PROGRAM_IDS = PROGRAM_REGISTRY.map((config) => config.id); + const SCREEN_NAMES = new Set([ + ...Object.values(ScreenId), + ...Object.values(Overlay), + ]); + const SEED = 0x5eed; + const SESSION_COUNT = 200; + + function mulberry32(seed: number): () => number { + let a = seed >>> 0; + return () => { + a = (a + 0x6d2b79f5) >>> 0; + let t = Math.imul(a ^ (a >>> 15), 1 | a); + t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; + return ((t ^ (t >>> 14)) >>> 0) / 4294967296; + }; + } + + function randomSession(rand: () => number): WizardSession { + const pick = (values: readonly T[]): T => + values[Math.floor(rand() * values.length)]; + const flip = (): boolean => rand() < 0.5; + + const session = buildSession({ installDir: '/app', ci: flip() }); + session.setupConfirmed = flip(); + session.credentials = flip() ? CREDENTIALS : null; + session.apiUser = pick([null, aiUser(true), aiUser(false)]); + session.runPhase = pick(Object.values(RunPhase)); + session.outroDismissed = flip(); + session.outroData = flip() + ? { kind: OutroKind.Error, message: 'x' } + : null; + session.mintHandoff = pick([null, 'exit', 'continue'] as const); + session.mcpComplete = flip(); + session.mcpOutcome = pick([null, ...Object.values(McpOutcome)]); + session.slackStepDismissed = flip(); + session.skillsComplete = flip(); + session.integrate = pick([null, true, false]); + if (flip()) { + session.integration = Integration.javascriptNode; + session.frameworkConfig = + FRAMEWORK_REGISTRY[Integration.javascriptNode]; + } + session.selfDrivingHandoffConfirmed = flip(); + session.githubConnected = pick([null, true, false]); + session.githubDeclined = flip(); + session.readinessResult = flip() ? CLEAN_READINESS : null; + session.outageDismissed = flip(); + if (flip()) session.frameworkContext = { postHogPresent: flip() }; + session.completedRuns = flip() ? ['integrate-run'] : []; + session.detectionComplete = flip(); + session.signup = flip(); + return session; + } + + function resolveAll(program: ProgramId): ScreenName[] { + const store = createStore(program); + const rand = mulberry32(SEED); + const screens: ScreenName[] = []; + for (let i = 0; i < SESSION_COUNT; i++) { + screens.push(store.router.resolve(randomSession(rand))); + } + return screens; + } + + it.each(PROGRAM_IDS)( + 'resolves a known screen for every session in %s', + (program) => { + const screens = resolveAll(program); + expect(screens).toHaveLength(SESSION_COUNT); + expect(screens.filter((screen) => !SCREEN_NAMES.has(screen))).toEqual( + [], + ); + }, + ); + + it.each(PROGRAM_IDS)('%s sequence ends on the exit screen', (program) => { + const sequence = PROGRAM_SEQUENCES[program]; + expect(sequence[sequence.length - 1].id).toBe(ScreenId.Exit); + }); + + it('generates the same sessions from the same seed', () => { + expect(resolveAll(Program.PostHogIntegration)).toEqual( + resolveAll(Program.PostHogIntegration), + ); + }); + }); + + describe('transition analytics shape', () => { + function driveIntegrationFlow(): void { + const store = createStore(); + store.completeSetup(); + store.setReadinessResult(CLEAN_READINESS); + store.setCredentials(CREDENTIALS); + store.setRunPhase(RunPhase.Running); + store.setRunPhase(RunPhase.Completed); + store.setOutroDismissed(); + } + + it('captures one screen event per transition', () => { + driveIntegrationFlow(); + + const screenEvents = wizardCaptureMock.mock.calls + .filter(([event]) => String(event).startsWith('screen ')) + .map(([event, props]) => ({ + event, + from_screen: props.from_screen, + program_id: props.program_id, + })); + + expect(screenEvents).toMatchInlineSnapshot(` + [ + { + "event": "screen auth", + "from_screen": "health-check", + "program_id": "posthog-integration", + }, + { + "event": "screen run", + "from_screen": "auth", + "program_id": "posthog-integration", + }, + { + "event": "screen outro", + "from_screen": "run", + "program_id": "posthog-integration", + }, + { + "event": "screen mcp", + "from_screen": "outro", + "program_id": "posthog-integration", + }, + ] + `); + }); + + it('tags $screen_name on every transition', () => { + driveIntegrationFlow(); + + const screenTags = setTagMock.mock.calls + .filter(([key]) => key === '$screen_name') + .map(([, value]) => value); + + expect(screenTags).toMatchInlineSnapshot(` + [ + "health-check", + "auth", + "run", + "outro", + "mcp", + ] + `); + }); + }); +}); From 426ce057f6ea45ba2d31a2110029060c6f82dfd9 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Mon, 21 Sep 2026 14:52:55 -0400 Subject: [PATCH 4/9] chore(test): address the P0 baseline review Frames record at 120x40 and 80x28, the ScreenContainer minimum, with one 60x15 case pinning the viewport guard. A revenue-intro detect-error case covers the Set spread fix that shipped in the typecheck commit. The keyboard test asserts equality and names the six known divergences instead of snapshotting a boolean, and uses a temp install dir so no host path leaks in. The post-auth gate golden reads the production walk, now exported as postAuthGateSteps. The three control fixtures had no reader and are gone. The bundle job diffs the chunk manifests against their fixtures so the audit can fail. The surfaces workflow drops the test matrix and lint, both already run by build.yml, and declares read permissions. Tests outside __tests__ land in legacy rather than nowhere. The dead harness surface rule is removed. The flow-trace golden documents the run, ai-opt-in, run triple as a known defect. Generated-By: PostHog Desktop Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589 --- .github/workflows/surfaces.yml | 52 +++------ .../__fixtures__/control-frame-auth.txt | 49 -------- .../__fixtures__/control-frame-intro.txt | 49 -------- .../__fixtures__/control-state-baseline.json | 107 ------------------ package.json | 2 +- .../architecture/import-boundaries.test.ts | 18 +-- src/lib/agent/runner/shared/bootstrap.ts | 19 ++-- .../programs/__tests__/flow-traces.test.ts | 7 ++ .../__tests__/post-auth-gates.test.ts | 22 ++-- src/lib/programs/program-step.ts | 11 ++ .../frames/agent-skill-intro-60x15.txt | 9 -- .../frames/agent-skill-intro-80x28.txt | 27 +++++ .../frames/ai-observability-intro-60x15.txt | 9 -- .../frames/ai-observability-intro-80x28.txt | 27 +++++ .../__snapshots__/frames/ai-opt-in-60x15.txt | 9 -- .../__snapshots__/frames/ai-opt-in-80x28.txt | 27 +++++ .../frames/audit-intro-60x15.txt | 9 -- .../frames/audit-intro-80x28.txt | 27 +++++ .../frames/audit-outro-60x15.txt | 9 -- .../frames/audit-outro-80x28.txt | 18 +++ .../__snapshots__/frames/audit-run-60x15.txt | 9 -- .../__snapshots__/frames/audit-run-80x28.txt | 27 +++++ .../__snapshots__/frames/auth-60x15.txt | 9 -- .../__snapshots__/frames/auth-80x28.txt | 27 +++++ .../__snapshots__/frames/auth-error-60x15.txt | 9 -- .../__snapshots__/frames/auth-error-80x28.txt | 19 ++++ .../frames/doctor-intro-60x15.txt | 9 -- .../frames/doctor-intro-80x28.txt | 27 +++++ .../frames/doctor-report-60x15.txt | 9 -- .../frames/doctor-report-80x28.txt | 18 +++ .../frames/error-tracking-detect-60x15.txt | 9 -- .../frames/error-tracking-detect-80x28.txt | 9 ++ .../frames/error-tracking-intro-60x15.txt | 9 -- .../frames/error-tracking-intro-80x28.txt | 27 +++++ .../__snapshots__/frames/exit-60x15.txt | 9 -- .../__snapshots__/frames/exit-80x28.txt | 3 + .../frames/health-check-60x15.txt | 9 -- .../frames/health-check-80x28.txt | 27 +++++ .../__snapshots__/frames/intro-80x28.txt | 27 +++++ .../frames/keep-skills-60x15.txt | 9 -- .../frames/keep-skills-80x28.txt | 7 ++ .../frames/managed-settings-60x15.txt | 9 -- .../frames/managed-settings-80x28.txt | 27 +++++ .../frames/manual-auth-code-60x15.txt | 9 -- .../frames/manual-auth-code-80x28.txt | 12 ++ .../__snapshots__/frames/mcp-60x15.txt | 9 -- .../__snapshots__/frames/mcp-80x28.txt | 15 +++ .../__snapshots__/frames/mcp-add-60x15.txt | 9 -- .../__snapshots__/frames/mcp-add-80x28.txt | 15 +++ .../__snapshots__/frames/mcp-remove-60x15.txt | 9 -- .../__snapshots__/frames/mcp-remove-80x28.txt | 11 ++ .../frames/mcp-suggested-prompts-60x15.txt | 9 -- .../frames/mcp-suggested-prompts-80x28.txt | 27 +++++ .../frames/metrics-intro-60x15.txt | 9 -- .../frames/metrics-intro-80x28.txt | 27 +++++ .../frames/migration-intro-60x15.txt | 9 -- .../frames/migration-intro-80x28.txt | 27 +++++ .../frames/mint-failure-60x15.txt | 9 -- .../frames/mint-failure-80x28.txt | 27 +++++ .../__snapshots__/frames/outro-60x15.txt | 9 -- .../__snapshots__/frames/outro-80x28.txt | 22 ++++ .../frames/port-conflict-60x15.txt | 9 -- .../frames/port-conflict-80x28.txt | 27 +++++ .../frames/revenue-intro-60x15.txt | 9 -- .../frames/revenue-intro-80x28.txt | 27 +++++ .../revenue-intro-detect-error-120x40.txt | 39 +++++++ .../revenue-intro-detect-error-80x28.txt | 27 +++++ .../__snapshots__/frames/run-60x15.txt | 9 -- .../__snapshots__/frames/run-80x28.txt | 27 +++++ .../frames/self-driving-github-60x15.txt | 9 -- .../frames/self-driving-github-80x28.txt | 27 +++++ .../frames/self-driving-handoff-60x15.txt | 9 -- .../frames/self-driving-handoff-80x28.txt | 27 +++++ .../self-driving-integration-check-60x15.txt | 9 -- .../self-driving-integration-check-80x28.txt | 27 +++++ .../self-driving-integration-detect-60x15.txt | 9 -- .../self-driving-integration-detect-80x28.txt | 9 ++ .../frames/self-driving-intro-60x15.txt | 9 -- .../frames/self-driving-intro-80x28.txt | 27 +++++ .../frames/session-timeout-60x15.txt | 9 -- .../frames/session-timeout-80x28.txt | 11 ++ .../frames/settings-override-60x15.txt | 9 -- .../frames/settings-override-80x28.txt | 27 +++++ .../__snapshots__/frames/setup-60x15.txt | 9 -- .../__snapshots__/frames/setup-80x28.txt | 10 ++ .../frames/slack-connect-60x15.txt | 9 -- .../frames/slack-connect-80x28.txt | 27 +++++ .../frames/source-maps-detect-60x15.txt | 9 -- .../frames/source-maps-detect-80x28.txt | 9 ++ .../frames/source-maps-intro-60x15.txt | 9 -- .../frames/source-maps-intro-80x28.txt | 27 +++++ .../frames/source-maps-outro-60x15.txt | 9 -- .../frames/source-maps-outro-80x28.txt | 25 ++++ .../frames/task-notice-60x15.txt | 9 -- .../frames/task-notice-80x28.txt | 27 +++++ .../frames/warehouse-intro-60x15.txt | 9 -- .../frames/warehouse-intro-80x28.txt | 27 +++++ .../__snapshots__/frames/wizard-ask-60x15.txt | 9 -- .../__snapshots__/frames/wizard-ask-80x28.txt | 27 +++++ .../keyboard-equivalence.test.tsx.snap | 16 --- src/ui/tui/__tests__/frames.test.tsx | 42 ++++++- .../__tests__/keyboard-equivalence.test.tsx | 42 ++++++- vitest.config.ts | 9 +- 103 files changed, 1173 insertions(+), 694 deletions(-) delete mode 100644 e2e-harness/__fixtures__/control-frame-auth.txt delete mode 100644 e2e-harness/__fixtures__/control-frame-intro.txt delete mode 100644 e2e-harness/__fixtures__/control-state-baseline.json delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/agent-skill-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/agent-skill-intro-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/ai-observability-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/ai-observability-intro-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/ai-opt-in-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/ai-opt-in-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/audit-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/audit-intro-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/audit-outro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/audit-outro-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/audit-run-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/audit-run-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/auth-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/auth-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/auth-error-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/auth-error-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/doctor-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/doctor-intro-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/doctor-report-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/doctor-report-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/error-tracking-detect-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/error-tracking-detect-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/error-tracking-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/error-tracking-intro-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/exit-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/exit-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/health-check-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/health-check-80x28.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/intro-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/keep-skills-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/keep-skills-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/managed-settings-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/managed-settings-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/manual-auth-code-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/manual-auth-code-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/mcp-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/mcp-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/mcp-add-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/mcp-add-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/mcp-remove-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/mcp-remove-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/mcp-suggested-prompts-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/mcp-suggested-prompts-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/metrics-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/metrics-intro-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/migration-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/migration-intro-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/mint-failure-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/mint-failure-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/outro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/outro-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/port-conflict-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/port-conflict-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-80x28.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-detect-error-120x40.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-detect-error-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/run-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/run-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/self-driving-github-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/self-driving-github-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/self-driving-handoff-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/self-driving-handoff-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-check-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-check-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-detect-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-detect-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/self-driving-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/self-driving-intro-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/session-timeout-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/session-timeout-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/settings-override-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/settings-override-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/setup-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/setup-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/slack-connect-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/slack-connect-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/source-maps-detect-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/source-maps-detect-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/source-maps-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/source-maps-intro-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/source-maps-outro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/source-maps-outro-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/task-notice-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/task-notice-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/warehouse-intro-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/warehouse-intro-80x28.txt delete mode 100644 src/ui/tui/__tests__/__snapshots__/frames/wizard-ask-60x15.txt create mode 100644 src/ui/tui/__tests__/__snapshots__/frames/wizard-ask-80x28.txt diff --git a/.github/workflows/surfaces.yml b/.github/workflows/surfaces.yml index aa04ae6e8..8e11424aa 100644 --- a/.github/workflows/surfaces.yml +++ b/.github/workflows/surfaces.yml @@ -5,6 +5,11 @@ on: - main pull_request: +permissions: + contents: read + +# Unit tests run once, in build.yml. This workflow owns the two checks that +# workflow does not: the import-boundary test and the bundle shape. jobs: architecture: name: Architecture @@ -23,36 +28,8 @@ jobs: - run: pnpm install --frozen-lockfile - run: node scripts/generate-version.cjs - run: pnpm typecheck - - run: pnpm lint - run: pnpm test:arch - surface: - name: ${{ matrix.project }} - runs-on: ubuntu-latest - timeout-minutes: 15 - strategy: - fail-fast: false - matrix: - project: [legacy, agent, tui, cli, harness] - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - - uses: pnpm/action-setup@eae0cfeb286e66ffb5155f1a79b90583a127a68b # v2.4.1 - with: - version: 10.34.5 - run_install: false - - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 - with: - node-version-file: 'package.json' - cache: 'pnpm' - - run: pnpm install --frozen-lockfile - - run: node scripts/generate-version.cjs - - run: pnpm test:${{ matrix.project }} --coverage - - uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # pin@v5.3.1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - fail_ci_if_error: false - flags: ${{ matrix.project }} - bundle: name: Bundle audit runs-on: ubuntu-latest @@ -70,17 +47,20 @@ jobs: - run: pnpm install --frozen-lockfile - name: Production build and smoke test run: pnpm build - - name: Production chunk manifest - run: - npx tsx scripts/chunk-manifest.no-jest.ts dist > - chunk-manifest.prod.json + - name: Production chunk manifest matches the fixture + run: | + npx tsx scripts/chunk-manifest.no-jest.ts dist > chunk-manifest.prod.json + npx prettier --write chunk-manifest.prod.json + diff scripts/__fixtures__/chunk-manifest.prod.json chunk-manifest.prod.json - name: CI build and smoke test run: pnpm build:ci - - name: CI chunk manifest - run: - npx tsx scripts/chunk-manifest.no-jest.ts dist > - chunk-manifest.ci.json + - name: CI chunk manifest matches the fixture + run: | + npx tsx scripts/chunk-manifest.no-jest.ts dist > chunk-manifest.ci.json + npx prettier --write chunk-manifest.ci.json + diff scripts/__fixtures__/chunk-manifest.ci.json chunk-manifest.ci.json - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + if: failure() with: name: chunk-manifests-${{ github.sha }} path: chunk-manifest.*.json diff --git a/e2e-harness/__fixtures__/control-frame-auth.txt b/e2e-harness/__fixtures__/control-frame-auth.txt deleted file mode 100644 index 644e86286..000000000 --- a/e2e-harness/__fixtures__/control-frame-auth.txt +++ /dev/null @@ -1,49 +0,0 @@ - PostHog Wizard v2.76.0 Feedback: wizard@posthog.com - - PostHog Setup Wizard - ✔ Framework: Node.js - - Privacy & data - • Source files are read by Claude for AI context - • .env* and secrets stay on your machine - • Press [I] for full privacy & usage info - - ⠴ Waiting for authentication... - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - I privacy & data diff --git a/e2e-harness/__fixtures__/control-frame-intro.txt b/e2e-harness/__fixtures__/control-frame-intro.txt deleted file mode 100644 index 493bdcb50..000000000 --- a/e2e-harness/__fixtures__/control-frame-intro.txt +++ /dev/null @@ -1,49 +0,0 @@ - PostHog Wizard v2.76.0 Feedback: wizard@posthog.com - - - - - - - - - - - - - - - - - ███ PostHog Wizard 🦔 - - We'll use AI to analyze your project and complete work. - Review what data is shared in "Privacy & data." - .env* values stay on your machine. - - Let's do two hours of work in eight minutes. - - Directory ✔ /wz-baseline-express-todo - Framework ✔ Node.js (detected) - - ▸ Continue - Change framework - More info - Privacy & data - Cancel - - - - - - - - - - - - - - - - ↑↓ navigate enter select diff --git a/e2e-harness/__fixtures__/control-state-baseline.json b/e2e-harness/__fixtures__/control-state-baseline.json deleted file mode 100644 index 9797a94c0..000000000 --- a/e2e-harness/__fixtures__/control-state-baseline.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "recordedFrom": "scripts/tui-host.no-jest.ts MODE=serve via scripts/wizard-ci-mcp.no-jest.ts, wizard 2.76.0", - "app": "wizard-workbench/apps/basic-integration/javascript-node/express-todo (throwaway copy, detection only, no key)", - "projectId": "228144", - "steps": [ - { - "call": "open_app", - "state": { - "currentScreen": "intro", - "hasOverlay": false, - "runPhase": "idle", - "session": { - "installDir": "", - "integration": "javascript_node", - "detectedFrameworkLabel": "Node.js", - "detectionComplete": true, - "setupConfirmed": false, - "integrate": null, - "hasCredentials": false, - "projectId": null, - "mcpComplete": false, - "slackStepDismissed": false, - "skillsComplete": false, - "outroDismissed": false, - "llmOptIn": false, - "discoveredFeatures": [] - }, - "tasks": [], - "statusMessages": [], - "eventPlan": [], - "pendingQuestion": null, - "taskNotice": null, - "setupQuestions": [], - "actions": [ - { "id": "confirm_setup", "description": "Confirm the intro and continue (sets setupConfirmed)." } - ], - "integration": "idle", - "integrationError": null - } - }, - { - "call": "perform_action", - "action": "confirm_setup", - "state": { - "currentScreen": "auth", - "hasOverlay": false, - "runPhase": "idle", - "session": { - "installDir": "", - "integration": "javascript_node", - "detectedFrameworkLabel": "Node.js", - "detectionComplete": true, - "setupConfirmed": true, - "integrate": null, - "hasCredentials": false, - "projectId": null, - "mcpComplete": false, - "slackStepDismissed": false, - "skillsComplete": false, - "outroDismissed": false, - "llmOptIn": false, - "discoveredFeatures": [] - }, - "tasks": [], - "statusMessages": [], - "eventPlan": [], - "pendingQuestion": null, - "taskNotice": null, - "setupQuestions": [], - "actions": [] - } - }, - { - "call": "read_state", - "state": { - "currentScreen": "auth", - "hasOverlay": false, - "runPhase": "idle", - "session": { - "installDir": "", - "integration": "javascript_node", - "detectedFrameworkLabel": "Node.js", - "detectionComplete": true, - "setupConfirmed": true, - "integrate": null, - "hasCredentials": false, - "projectId": null, - "mcpComplete": false, - "slackStepDismissed": false, - "skillsComplete": false, - "outroDismissed": false, - "llmOptIn": false, - "discoveredFeatures": [] - }, - "tasks": [], - "statusMessages": [], - "eventPlan": [], - "pendingQuestion": null, - "taskNotice": null, - "setupQuestions": [], - "actions": [], - "integration": "idle", - "integrationError": null - } - } - ] -} diff --git a/package.json b/package.json index 554ca512b..61cf60883 100644 --- a/package.json +++ b/package.json @@ -138,7 +138,7 @@ "test:cli": "vitest run --project cli", "test:harness": "vitest run --project harness", "test:arch": "vitest run --project architecture", - "test:goldens:update": "vitest run --project tui --project legacy -u", + "test:goldens:update": "vitest run -u", "test:coverage": "pnpm build && vitest run --coverage", "test:e2e": "pnpm build && ./e2e-tests/run.sh", "test:e2e-record": "export RECORD_FIXTURES=true && pnpm build && ./e2e-tests/run.sh", diff --git a/src/__tests__/architecture/import-boundaries.test.ts b/src/__tests__/architecture/import-boundaries.test.ts index 3e25aae6a..8220182ae 100644 --- a/src/__tests__/architecture/import-boundaries.test.ts +++ b/src/__tests__/architecture/import-boundaries.test.ts @@ -2,7 +2,7 @@ import * as fs from 'fs'; import * as path from 'path'; import { fileURLToPath } from 'url'; -export type Surface = 'env' | 'legacy' | 'agent' | 'tui' | 'cli' | 'harness'; +export type Surface = 'env' | 'legacy' | 'agent' | 'tui' | 'cli'; const HERE = path.dirname(fileURLToPath(import.meta.url)); const REPO_ROOT = path.resolve(HERE, '../../..'); @@ -39,10 +39,6 @@ const SURFACE_RULES: ReadonlyArray boolean]> = p.startsWith('src/commands/') || p.startsWith('src/lib/runners/'), ], - [ - 'harness', - (p) => p.startsWith('e2e-harness/') || p.startsWith('scripts/'), - ], ]; export function classifySurface(relPath: string): Surface { @@ -53,10 +49,7 @@ export function classifySurface(relPath: string): Surface { return 'legacy'; } -export const ALLOWED_IMPORTS: Record< - Exclude, - readonly Surface[] -> = { +export const ALLOWED_IMPORTS: Record = { env: [], legacy: ['env', 'legacy'], agent: ['env', 'legacy', 'agent'], @@ -283,7 +276,7 @@ function analyze(): Analysis { fs.readFileSync(path.join(REPO_ROOT, file), 'utf8'), ); const from = classifySurface(file); - const allowed = from === 'harness' ? [] : ALLOWED_IMPORTS[from]; + const allowed = ALLOWED_IMPORTS[from]; for (const spec of specifiersIn(text)) { const base = spec.startsWith('.') @@ -310,9 +303,7 @@ function analyze(): Analysis { edges.add(key); const to = classifySurface(target); - if (to === 'harness') violations.set(key, 'harness'); - else if (!allowed.includes(to)) - violations.set(key, `matrix:${from}->${to}`); + if (!allowed.includes(to)) violations.set(key, `matrix:${from}->${to}`); } } @@ -397,7 +388,6 @@ describe('surface classification', () => { expect(classifySurface('src/lib/agent/agent-runner.ts')).toBe('agent'); expect(classifySurface('src/ui/tui/App.tsx')).toBe('tui'); expect(classifySurface('bin.ts')).toBe('cli'); - expect(classifySurface('e2e-harness/e2e-profile.ts')).toBe('harness'); expect(classifySurface('src/lib/wizard-tools/mcp.ts')).toBe('agent'); expect(classifySurface('src/lib/wizard-tools/tools.ts')).toBe('legacy'); expect(classifySurface('src/commands/factories/family-picker.tsx')).toBe( diff --git a/src/lib/agent/runner/shared/bootstrap.ts b/src/lib/agent/runner/shared/bootstrap.ts index 6c2bd794e..dc12a2b60 100644 --- a/src/lib/agent/runner/shared/bootstrap.ts +++ b/src/lib/agent/runner/shared/bootstrap.ts @@ -36,7 +36,10 @@ import { CallType, getSkillsBaseUrl, IS_DEV } from '@lib/constants'; import { VERSION } from '@lib/version'; import { mcpUrlFor } from '@lib/host-resolution'; import type { WizardRunOptions } from '@utils/types'; -import type { ProgramConfig } from '@lib/programs/program-step'; +import { + postAuthGateSteps, + type ProgramConfig, +} from '@lib/programs/program-step'; import type { ProgramRun, BootstrapResult } from './types'; // ── Helpers ────────────────────────────────────────────────────────── @@ -270,16 +273,10 @@ export async function bootstrapProgram( // but BEFORE the agent runs — e.g. the source-maps project picker, which // needs credentials to scan and writes its choice to frameworkContext that // the run prompt reads. Generic: await every gated step between auth and run. - const authIndex = programConfig.steps.findIndex((s) => s.screenId === 'auth'); - const runIndex = programConfig.steps.findIndex((s) => s.screenId === 'run'); - if (authIndex !== -1 && runIndex > authIndex) { - for (const step of programConfig.steps.slice(authIndex + 1, runIndex)) { - if (step.gate) { - logToFile(`[agent-runner] awaiting post-auth gate: ${step.id}`); - await getUI().waitForGate(step.id); - logToFile(`[agent-runner] post-auth gate cleared: ${step.id}`); - } - } + for (const step of postAuthGateSteps(programConfig.steps)) { + logToFile(`[agent-runner] awaiting post-auth gate: ${step.id}`); + await getUI().waitForGate(step.id); + logToFile(`[agent-runner] post-auth gate cleared: ${step.id}`); } // Feature flags. Both arms need these, and the fork decision reads the flags. diff --git a/src/lib/programs/__tests__/flow-traces.test.ts b/src/lib/programs/__tests__/flow-traces.test.ts index acf23d064..43b532b89 100644 --- a/src/lib/programs/__tests__/flow-traces.test.ts +++ b/src/lib/programs/__tests__/flow-traces.test.ts @@ -2,6 +2,13 @@ * Golden screen sequences and `screen ` analytics per program, produced * by walking each program's steps through the store with a generic advance per * screen. Baseline for the surface split: must stay byte identical. + * + * Known defect recorded as-is: gated programs show `screen run`, + * `screen ai-opt-in`, `screen run`. authenticate.ts sets credentials before + * apiUser and the AI opt-in gate hides itself while apiUser is null, so the + * router visits `run` twice. Fixing the ordering is a production analytics + * change and belongs in its own PR; when it lands, re-record and add an + * assertion that no trace visits `run` twice. */ import { WizardStore, ScreenId, RunPhase, McpOutcome } from '@ui/tui/store'; import { InkUI } from '@ui/tui/ink-ui'; diff --git a/src/lib/programs/__tests__/post-auth-gates.test.ts b/src/lib/programs/__tests__/post-auth-gates.test.ts index 01ad25efd..3dd2052bc 100644 --- a/src/lib/programs/__tests__/post-auth-gates.test.ts +++ b/src/lib/programs/__tests__/post-auth-gates.test.ts @@ -1,25 +1,17 @@ /** - * Golden of the post-auth gate ids the agent runner awaits per program - * (the walk at runner/shared/bootstrap.ts between the `auth` and `run` steps). + * Golden of the post-auth gate ids the agent runner awaits per program. Reads + * the same `postAuthGateSteps` walk that runner/shared/bootstrap.ts awaits. */ import { PROGRAM_REGISTRY } from '../program-registry'; - -function legacyPostAuthGateIds( - steps: (typeof PROGRAM_REGISTRY)[number]['steps'], -): string[] { - const authIndex = steps.findIndex((s) => s.screenId === 'auth'); - const runIndex = steps.findIndex((s) => s.screenId === 'run'); - if (authIndex === -1 || runIndex <= authIndex) return []; - return steps - .slice(authIndex + 1, runIndex) - .filter((s) => s.gate) - .map((s) => s.id); -} +import { postAuthGateSteps } from '../program-step'; describe('post-auth gate ids per program', () => { it('match the golden', () => { const gates = Object.fromEntries( - PROGRAM_REGISTRY.map((c) => [c.id, legacyPostAuthGateIds(c.steps)]), + PROGRAM_REGISTRY.map((c) => [ + c.id, + postAuthGateSteps(c.steps).map((s) => s.id), + ]), ); expect(gates).toMatchSnapshot(); }); diff --git a/src/lib/programs/program-step.ts b/src/lib/programs/program-step.ts index 9388bee79..81e55a655 100644 --- a/src/lib/programs/program-step.ts +++ b/src/lib/programs/program-step.ts @@ -351,6 +351,17 @@ export interface ProgramConfig { * This intentional separation keeps the router focused on one question: * "Which screen should be rendered right now?" */ +/** + * The gated steps the agent runner awaits after `auth` and before `run`, in + * step order. Empty when a program has no auth step or runs before it. + */ +export function postAuthGateSteps(steps: ProgramStep[]): ProgramStep[] { + const authIndex = steps.findIndex((s) => s.screenId === 'auth'); + const runIndex = steps.findIndex((s) => s.screenId === 'run'); + if (authIndex === -1 || runIndex <= authIndex) return []; + return steps.slice(authIndex + 1, runIndex).filter((s) => s.gate); +} + export function createProgramSequence(steps: ProgramStep[]): Array<{ id: string; show?: (session: WizardSession) => boolean; diff --git a/src/ui/tui/__tests__/__snapshots__/frames/agent-skill-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/agent-skill-intro-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/agent-skill-intro-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/agent-skill-intro-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/agent-skill-intro-80x28.txt new file mode 100644 index 000000000..5b1884fae --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/agent-skill-intro-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + .env* file contents will not leave your machine. + + Let's run the unknown skill. + + Directory ✔ /app + + ▸ Continue + More info + Privacy & data + Cancel + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/ai-observability-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/ai-observability-intro-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/ai-observability-intro-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/ai-observability-intro-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/ai-observability-intro-80x28.txt new file mode 100644 index 000000000..6d3fce7b2 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/ai-observability-intro-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + .env* file contents will not leave your machine. + + Let's instrument your LLM calls with PostHog AI Observability. + + Directory ✔ /app + + ▸ Continue + More info + Privacy & data + Cancel + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/ai-opt-in-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/ai-opt-in-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/ai-opt-in-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/ai-opt-in-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/ai-opt-in-80x28.txt new file mode 100644 index 000000000..022a8a31c --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/ai-opt-in-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + PostHog Setup Wizard + + ⚠ PostHog AI services are disabled for your organization + + The wizard uses Anthropic Claude. To proceed, enable "Enable PostHog + features that use third-party AI services" in your organization + settings. + + http://localhost:8010/project/42/settings/organization-details#organization-ai + -consent + + + [O] Open settings in browser + [S] Show how to use your own AI + [R] Retry (after the toggle is enabled) + [E] Exit + + + + + + + O open settings S show skill R retry E exit diff --git a/src/ui/tui/__tests__/__snapshots__/frames/audit-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/audit-intro-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/audit-intro-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/audit-intro-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/audit-intro-80x28.txt new file mode 100644 index 000000000..11b7c3c20 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/audit-intro-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + .env* file contents will not leave your machine. + + Let's review your existing PostHog setup for best practices. + + Directory ✔ /app + + ▸ Continue + More info + Privacy & data + Cancel + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/audit-outro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/audit-outro-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/audit-outro-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/audit-outro-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/audit-outro-80x28.txt new file mode 100644 index 000000000..a56f15cee --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/audit-outro-80x28.txt @@ -0,0 +1,18 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + ✔ PostHog is set up! + + Report saved to: + /app/posthog-setup-report.md + A markdown file in your project folder. Open it in any editor to read the full + audit. + + Items audited: + 14 checks · 0 errors · 0 warnings · 0 suggestions + • No issues found. + + Learn more: https://posthog.com/docs + + Press any key to continue diff --git a/src/ui/tui/__tests__/__snapshots__/frames/audit-run-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/audit-run-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/audit-run-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/audit-run-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/audit-run-80x28.txt new file mode 100644 index 000000000..f042274c3 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/audit-run-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + Verifying installation hecks + ┌──────────────────────────────────┐ ◌ SDK version up to date + │ ▼ posthog.init(...) once │ ◌ One initialization per runtime + │ ▼ posthog.capture('pageview') │ + │ posthog.capture('signup') │ ◌ Stable distinct_id (not session + │ posthog.capture('purchase') │ ◌ Same distinct_id across client and + └──────────────────────────────────┘ ◌ reset() called on logout / account + switch + PostHog releases frequent SDK + updates to fix bugs and add new + features. We're checking your ◌ Event names are static and + project's SDK version and making ◌ Key activation events capturedse + We're also checking that your SDK is proxy + initialized correctly and in the ◌ Open findings in PostHog + right part of your app's lifecycle. + This ensures you won't miss any ◌ Create posthog-audit-report.md + autocaptured events. + [O] Learn more ◌ Write the report into a PostHog + notebook + ────────────────────────────────────────────────────────────────────────────── + + Status Audit plan Tail logs HN + ←→ switch tab s toggle status diff --git a/src/ui/tui/__tests__/__snapshots__/frames/auth-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/auth-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/auth-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/auth-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/auth-80x28.txt new file mode 100644 index 000000000..26da42381 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/auth-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + PostHog Setup Wizard + + Privacy & data + • Source files are read by Claude for AI context + • .env* and secrets stay on your machine + • Press [I] for full privacy & usage info + + ⠋ Waiting for authentication... + + If the browser didn't open, copy and paste this URL: + + https://us.posthog.com/login?next=/oauth/authorize + + Press [C] to copy the link · on a remote machine or devbox? Press [P] to paste + the callback URL. + + + + + + + + P paste auth code C copy link I privacy & data diff --git a/src/ui/tui/__tests__/__snapshots__/frames/auth-error-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/auth-error-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/auth-error-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/auth-error-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/auth-error-80x28.txt new file mode 100644 index 000000000..03d097d56 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/auth-error-80x28.txt @@ -0,0 +1,19 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + ✘ Authentication error + + The Wizard couldn't connect to the PostHog LLM Gateway. Claude Code settings + on this machine override the Wizard's credentials. + + • /app/.claude/settings.json sets ANTHROPIC_BASE_URL + + Remove those keys from the file(s) above, or log out of Claude Code, then + re-run the Wizard: + + claude auth logout + + Verbose log: /tmp/posthog-wizard.log + + Press any key to exit diff --git a/src/ui/tui/__tests__/__snapshots__/frames/doctor-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/doctor-intro-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/doctor-intro-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/doctor-intro-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/doctor-intro-80x28.txt new file mode 100644 index 000000000..cc0c1852a --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/doctor-intro-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + PostHog Doctor + Scan your project configuration for issues that may need attention. + + The wizard will: + • Sign you in to PostHog + • Fetch active health issues for your project + • Show you what needs to be resolved, with docs links + + ▸ Continue + Cancel + + + + + + + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/doctor-report-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/doctor-report-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/doctor-report-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/doctor-report-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/doctor-report-80x28.txt new file mode 100644 index 000000000..1a365db89 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/doctor-report-80x28.txt @@ -0,0 +1,18 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + PostHog Doctor Report + Project 42 • https://us.posthog.com + + 2 active issues: 1 critical, 1 warning + + Critical (1) + ◼ Ingestion is delayed + https://posthog.com/docs/support/troubleshooting + + Warning (1) + ◼ SDK version is out of date + https://posthog.com/docs/libraries + + ▸ Continue diff --git a/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-detect-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-detect-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-detect-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-detect-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-detect-80x28.txt new file mode 100644 index 000000000..0adcafd67 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-detect-80x28.txt @@ -0,0 +1,9 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + Detecting your project... + + ⠋ Scanning the repo for frameworks and PostHog SDKs... + + Starting up the detection agent… diff --git a/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-intro-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-intro-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-intro-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-intro-80x28.txt new file mode 100644 index 000000000..4cd8b5634 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/error-tracking-intro-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + .env* file contents will not leave your machine. + + Let's make uncaught errors reach PostHog with readable stack traces. + + Directory ✔ /app + + ▸ Continue + More info + Privacy & data + Cancel + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/exit-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/exit-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/exit-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/exit-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/exit-80x28.txt new file mode 100644 index 000000000..78f797570 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/exit-80x28.txt @@ -0,0 +1,3 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide diff --git a/src/ui/tui/__tests__/__snapshots__/frames/health-check-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/health-check-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/health-check-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/health-check-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/health-check-80x28.txt new file mode 100644 index 000000000..f7e5e84f9 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/health-check-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + ╭──────────────────────────────────────────────────────────────────────╮ + │ │ + │ Ongoing service disruptions │ + │ │ + │ ◼ Down ◼ Degraded ◼ No connection │ + │ │ + │ ◼ Skills download │ + │ │ + │ The Wizard can't download the skills it needs — neither GitHub │ + │ Releases nor PostHog's mirror is reachable right now. │ + │ │ + │ ──────────────────────────────────────────────────────────────── │ + │ │ + │ │ + │ ▸ Exit [Esc] │ + │ │ + ╰──────────────────────────────────────────────────────────────────────╯ + + + + ←→ switch esc cancel enter confirm diff --git a/src/ui/tui/__tests__/__snapshots__/frames/intro-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/intro-80x28.txt new file mode 100644 index 000000000..957bf2cfd --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/intro-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + Review what data is shared in "Privacy & data." + .env* values stay on your machine. + + Let's do two hours of work in eight minutes. + + Directory ✔ /app + Framework ✔ Next.js (detected) + + ▸ Continue + Change framework + More info + Privacy & data + Cancel + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/keep-skills-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/keep-skills-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/keep-skills-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/keep-skills-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/keep-skills-80x28.txt new file mode 100644 index 000000000..1e8d16bb3 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/keep-skills-80x28.txt @@ -0,0 +1,7 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + Keep the skills? + + Checking installed skills... diff --git a/src/ui/tui/__tests__/__snapshots__/frames/managed-settings-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/managed-settings-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/managed-settings-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/managed-settings-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/managed-settings-80x28.txt new file mode 100644 index 000000000..d99506077 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/managed-settings-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + ╭──────────────────────────────────────────────────────────────────────╮ + │ │ + │ ⚠ Settings conflict │ + │ │ + │ These Claude Code settings override credentials and prevent the │ + │ Wizard from reaching the PostHog LLM Gateway. │ + │ │ + │ Organization-managed settings │ + │ /Library/Application Support/ClaudeCode/managed-settings.json │ + │ • ANTHROPIC_BASE_URL │ + │ │ + │ Remove these keys (or run "claude auth logout"). Managed files │ + │ are root-owned — ask your IT administrator. │ + │ │ + │ ──────────────────────────────────────────────────────────────── │ + │ │ + │ Fix the file(s) above, then re-run the Wizard. │ + │ │ + │ ▸ Exit [Esc] │ + │ │ + ╰──────────────────────────────────────────────────────────────────────╯ + + ←→ switch esc cancel enter confirm diff --git a/src/ui/tui/__tests__/__snapshots__/frames/manual-auth-code-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/manual-auth-code-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/manual-auth-code-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/manual-auth-code-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/manual-auth-code-80x28.txt new file mode 100644 index 000000000..75ec9891d --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/manual-auth-code-80x28.txt @@ -0,0 +1,12 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + ◆ Paste authorization code + + After authorizing, paste the callback URL it lands on — or just the code from + it — here: + + http://localhost:8239/callback?code=… or the code + + ENTER submit · ESC cancel diff --git a/src/ui/tui/__tests__/__snapshots__/frames/mcp-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/mcp-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/mcp-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/mcp-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/mcp-80x28.txt new file mode 100644 index 000000000..7abbafc8a --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/mcp-80x28.txt @@ -0,0 +1,15 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + Install the MCP so you can chat to your data + + • Ask your agent: "List my feature flags" — and it does. + • Run SQL, build dashboards, ship flags, all from your IDE. + • No copy-pasting tokens or context. Your agent has the keys. + + Detected: Claude Code, Cursor + + Install the PostHog MCP server and plugin? + + ▸ Install No thanks diff --git a/src/ui/tui/__tests__/__snapshots__/frames/mcp-add-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/mcp-add-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/mcp-add-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/mcp-add-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/mcp-add-80x28.txt new file mode 100644 index 000000000..7abbafc8a --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/mcp-add-80x28.txt @@ -0,0 +1,15 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + Install the MCP so you can chat to your data + + • Ask your agent: "List my feature flags" — and it does. + • Run SQL, build dashboards, ship flags, all from your IDE. + • No copy-pasting tokens or context. Your agent has the keys. + + Detected: Claude Code, Cursor + + Install the PostHog MCP server and plugin? + + ▸ Install No thanks diff --git a/src/ui/tui/__tests__/__snapshots__/frames/mcp-remove-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/mcp-remove-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/mcp-remove-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/mcp-remove-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/mcp-remove-80x28.txt new file mode 100644 index 000000000..37de4b0bc --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/mcp-remove-80x28.txt @@ -0,0 +1,11 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + Remove the PostHog MCP + + Detected: Claude Code, Cursor + + Remove the PostHog MCP server and plugin? + + ▸ Remove No thanks diff --git a/src/ui/tui/__tests__/__snapshots__/frames/mcp-suggested-prompts-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/mcp-suggested-prompts-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/mcp-suggested-prompts-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/mcp-suggested-prompts-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/mcp-suggested-prompts-80x28.txt new file mode 100644 index 000000000..8d28a8678 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/mcp-suggested-prompts-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + PostHog MCP + + With MCP your agent works directly with the PostHog platform. You can prompt + it to: + + ◆ Build dashboards + ◆ Run SQL queries + ◆ Deploy feature flags + ◆ Debug exceptions and errors + ◆ And lots more... + + Want a live demo using real data from your project? + ▸ Start MCP tutorial + Exit + + + + + + + + ↑↓ navigate p pick new prompt esc exit enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/metrics-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/metrics-intro-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/metrics-intro-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/metrics-intro-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/metrics-intro-80x28.txt new file mode 100644 index 000000000..af16a1fa7 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/metrics-intro-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + .env* file contents will not leave your machine. + + Let's instrument your service with PostHog application metrics. + + Directory ✔ /app + + ▸ Continue + More info + Privacy & data + Cancel + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/migration-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/migration-intro-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/migration-intro-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/migration-intro-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/migration-intro-80x28.txt new file mode 100644 index 000000000..e4b3127ab --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/migration-intro-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + .env* file contents will not leave your machine. + + Let's migrate this project to PostHog. + + Directory ✔ /app + + ▸ Continue + Privacy & data + Cancel + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/mint-failure-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/mint-failure-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/mint-failure-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/mint-failure-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/mint-failure-80x28.txt new file mode 100644 index 000000000..4a6e9c44f --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/mint-failure-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + + ██ The Wizard's a little busy 🦔 + + The wizard can still share spells. Grab a skill and let your agent take + over. + + ▸ Save skill + Open in Claude Code + Open in Codex + Report this issue + Exit + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/outro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/outro-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/outro-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/outro-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/outro-80x28.txt new file mode 100644 index 000000000..30d0e4480 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/outro-80x28.txt @@ -0,0 +1,22 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + ✔ PostHog is set up! + + Events will start flowing once you run the app. + + Check ./posthog-setup-report.md for details + + What the agent did: + • Added posthog-js + • Wired the provider + + Learn more: https://posthog.com/docs?utm_source=wizard&utm_medium=cli&utm_cont + ent=outro-docs + + Note: This wizard uses an LLM agent to analyze and modify your project. Please + review the changes made. + How did this work for you? Drop us a line: wizard@posthog.com + + Press any key to continue diff --git a/src/ui/tui/__tests__/__snapshots__/frames/port-conflict-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/port-conflict-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/port-conflict-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/port-conflict-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/port-conflict-80x28.txt new file mode 100644 index 000000000..5be86f33e --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/port-conflict-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + ╭──────────────────────────────────────────────────────────────────────╮ + │ │ + │ OAuth ports in use │ + │ The wizard needs a local port for OAuth. We tried these ports │ + │ which are all in use: │ + │ │ + │ │ + │ Port 8238 │ + │ Port 8237 │ + │ Port 8236 │ + │ Port 8235 │ + │ │ + │ Please free one of these ports and retry. │ + │ │ + │ ──────────────────────────────────────────────────────────────── │ + │ │ + │ Retry after freeing ports? │ + │ │ + │ ▸ Retry [Enter] Exit [Esc] │ + │ │ + ╰──────────────────────────────────────────────────────────────────────╯ + + ←→ switch esc cancel enter confirm diff --git a/src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-80x28.txt new file mode 100644 index 000000000..9c0b3bb65 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + .env* file contents will not leave your machine. + + Let's create revenue analytics with Stripe and PostHog. + + Link purchases to product data. + + Directory ✔ /app + + ▸ Continue + More info + Privacy & data + Cancel + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-detect-error-120x40.txt b/src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-detect-error-120x40.txt new file mode 100644 index 000000000..1ab72510e --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-detect-error-120x40.txt @@ -0,0 +1,39 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + + + + + + ███ PostHog Wizard 🦔 + + ✘ Cannot set up revenue analytics + + Neither PostHog nor Stripe SDKs detected (scanned 2 package.json files). + + Revenue analytics requires: + • A PostHog SDK (posthog-js, posthog-node, posthog-react-native, …) + • A Stripe SDK (stripe, @stripe/stripe-js, @stripe/react-stripe-js) + + Install Stripe and run npx @posthog/wizard to set up PostHog. + + ▸ Exit + + + + + + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-detect-error-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-detect-error-80x28.txt new file mode 100644 index 000000000..32d138c27 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/revenue-intro-detect-error-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + ███ PostHog Wizard 🦔 + + ✘ Cannot set up revenue analytics + + Neither PostHog nor Stripe SDKs detected (scanned 2 package.json files). + + Revenue analytics requires: + • A PostHog SDK (posthog-js, posthog-node, posthog-react-native, …) + • A Stripe SDK (stripe, @stripe/stripe-js, @stripe/react-stripe-js) + + Install Stripe and run npx @posthog/wizard to set up PostHog. + + ▸ Exit + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/run-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/run-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/run-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/run-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/run-80x28.txt new file mode 100644 index 000000000..796530ae6 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/run-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + Learn Tasks + + ◼ Install posthog-js + ▶ Wiring the provider + ◻ Capture a test event + + ⠋ Progress: 1/3 completed + + + + + + + + + + + ────────────────────────────────────────────────────────────────────────────── + ◆ Editing app/layout.tsx + + Status Event plan Tail logs Visualizer HN + + ←→ switch tab s toggle status diff --git a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-github-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-github-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-github-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-github-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-github-80x28.txt new file mode 100644 index 000000000..6e24aa30a --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-github-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + Connect GitHub + + Self-driving needs GitHub access to research findings in your code and open + fixes, so setup cannot finish without it. + + ◆ Grant it the repos you want Self-driving to work with — include this + project's repo so it can also watch its issues. + + Install it: + https://us.posthog.com/api/environments/42/integrations/authorize?kind=github + + ▸ Open GitHub App install + I can't connect right now + + + + + + + + + ↑↓ navigate esc end setup enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-handoff-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-handoff-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-handoff-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-handoff-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-handoff-80x28.txt new file mode 100644 index 000000000..7ab3602fe --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-handoff-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + ✔ PostHog is installed + + Now let's make your product self-driving. + + Next, the agent connects GitHub, turns on signal sources, and tunes the scouts + that watch your product data. + + About 10 more minutes, and it needs your input a few times. Keep this terminal + open. + + ▸ Set up Self-driving [Enter] + + You can find your PostHog integration report at ./posthog-setup-report.md + + + + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-check-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-check-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-check-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-check-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-check-80x28.txt new file mode 100644 index 000000000..6a3833e0e --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-check-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + No PostHog integration found + + This will kick off an agent to explore your project and find existing PostHog + integrations. Self-driving reads PostHog data, so we'll set that up first: it + gives your signal sources something to watch. To do that we need to connect to + PostHog — do you already have an account? + + ▸ Yes, log me in (opens PostHog to authorize) + No, create one for me (we'll email you a login link) + + [I] Privacy & data + + + + + + + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-detect-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-detect-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-detect-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-detect-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-detect-80x28.txt new file mode 100644 index 000000000..ecc9d4fcc --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-integration-detect-80x28.txt @@ -0,0 +1,9 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + Detecting your project. Stick around, this will take a few seconds... + + ⠋ Scanning the repo for frameworks and PostHog SDKs... + + Starting up the detection agent… diff --git a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-intro-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-intro-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/self-driving-intro-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-intro-80x28.txt new file mode 100644 index 000000000..a05d591a2 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/self-driving-intro-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + ███ PostHog Wizard 🦔 + + We'll use .env* file contents will not leave your machine.lf-driving. + + + Let's set up PostHog Self-driving. + + PostHog watches how people really use your product, finds issues, and proposes + fixes. + + An agent wAbout 10 minutes, with a few questions along the way.our scouts. + Agents charge a flat $15 per pull request they ship. + + Directory ✔ /app + + ▸ Continue + More info + Privacy & data + Cancel + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/session-timeout-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/session-timeout-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/session-timeout-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/session-timeout-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/session-timeout-80x28.txt new file mode 100644 index 000000000..8951ba29f --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/session-timeout-80x28.txt @@ -0,0 +1,11 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + ✘ Login timed out + + The OAuth link timed out after 30 minutes. + + Re-run the wizard to get a fresh link and try again. + + Press any key to exit diff --git a/src/ui/tui/__tests__/__snapshots__/frames/settings-override-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/settings-override-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/settings-override-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/settings-override-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/settings-override-80x28.txt new file mode 100644 index 000000000..95bcc3d9b --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/settings-override-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + ╭──────────────────────────────────────────────────────────────╮ + │ │ + │ ⚠ Settings conflict │ + │ │ + │ Your settings file at /app/.claude/settings.json sets: │ + │ • ANTHROPIC_BASE_URL │ + │ • apiKeyHelper │ + │ │ + │ These settings override credentials and prevent the │ + │ Wizard from reaching the PostHog LLM Gateway. We can │ + │ back up the file and continue. │ + │ │ + │ ──────────────────────────────────────────────────────── │ + │ │ + │ Back up to .wizard-backup and continue? │ + │ │ + │ ▸ Backup & continue [Enter] Exit [Esc] │ + │ │ + ╰──────────────────────────────────────────────────────────────╯ + + + ←→ switch esc cancel enter confirm diff --git a/src/ui/tui/__tests__/__snapshots__/frames/setup-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/setup-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/setup-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/setup-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/setup-80x28.txt new file mode 100644 index 000000000..ca0bc32f2 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/setup-80x28.txt @@ -0,0 +1,10 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + Project Setup + Configuring Next.js integration + + Which Next.js router are you using? + ▸ App Router + Pages Router diff --git a/src/ui/tui/__tests__/__snapshots__/frames/slack-connect-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/slack-connect-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/slack-connect-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/slack-connect-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/slack-connect-80x28.txt new file mode 100644 index 000000000..e5008626e --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/slack-connect-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + @PostHog in Slack + + Ask about your product data, debug issues, and generate PRs without leaving + the thread. + + ◆ Tag @PostHog with a bug, edit, or a feature idea. It will spin up a + sandboxed environment, plan, edit files, run tests, and open a draft PR. + + ◆ Tag @PostHog with any data question. It's the same SQL-writing, + statistically-minded assistant as PostHog AI, but it responds where you send + work memes. + + Connect it: https://app.posthog.com/integrations/slack?utm_source=wizard&utm_m + edium=cli&utm_content=slack-connect-setup + Learn more: https://posthog.com/slack?utm_source=wizard&utm_medium=cli&utm_con + tent=slack-connect-learn-more + + ▸ Open Slack setup + Skip / Continue + + + ↑↓ navigate esc skip enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/source-maps-detect-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-detect-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/source-maps-detect-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/source-maps-detect-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-detect-80x28.txt new file mode 100644 index 000000000..0adcafd67 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-detect-80x28.txt @@ -0,0 +1,9 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + Detecting your project... + + ⠋ Scanning the repo for frameworks and PostHog SDKs... + + Starting up the detection agent… diff --git a/src/ui/tui/__tests__/__snapshots__/frames/source-maps-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-intro-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/source-maps-intro-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/source-maps-intro-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-intro-80x28.txt new file mode 100644 index 000000000..90fe762f7 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-intro-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + .env* file contents will not leave your machine. + + The Wizard will run an agent to detect your project's + framework(s), download the relevant docs, and implement + source-map uploads for you. + + Ready? + + Directory ✔ /app + + ▸ Continue + More info + Privacy & data + Cancel + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/source-maps-outro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-outro-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/source-maps-outro-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/source-maps-outro-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-outro-80x28.txt new file mode 100644 index 000000000..75cb08e2e --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/source-maps-outro-80x28.txt @@ -0,0 +1,25 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + ✔ PostHog is set up! + + • Installed the packages needed for source map upload. + • Wrote the PostHog upload credentials to your .env file. + + • Every build now uploads source maps to PostHog automatically — no extra + command to remember. + • Run your app from the built output. Source maps only resolve for errors + thrown by the build that was uploaded. + • In CI, the build job needs the same upload credentials. If the wizard wired + your pipeline, add the referenced secrets to your CI provider (e.g. GitHub + repo secrets) before your next deploy. + + Details in /app/posthog-setup-report.md + + Learn more: https://posthog.com/docs + + Note: This wizard uses an LLM agent to analyze and modify your project. Please + How did this work for you? Drop us a line: wizard@posthog.com + + Press any key to continue diff --git a/src/ui/tui/__tests__/__snapshots__/frames/task-notice-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/task-notice-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/task-notice-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/task-notice-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/task-notice-80x28.txt new file mode 100644 index 000000000..90cf62fbb --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/task-notice-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + ╭──────────────────────────────────────────────────────────────────────────╮ + │ │ + │ Connect your data sources │ + │ │ + │ We detected warehouse sources in this project. │ + │ │ + │ Postgres, Stripe │ + │ │ + │ ──────────────────────────────────────────────────────────────────── │ + │ │ + │ Connect these during setup? │ + │ │ + │ ▸ Continue [Enter] Skip [Esc] │ + │ │ + ╰──────────────────────────────────────────────────────────────────────────╯ + + + + + ←→ switch esc cancel enter confirm diff --git a/src/ui/tui/__tests__/__snapshots__/frames/warehouse-intro-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/warehouse-intro-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/warehouse-intro-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/warehouse-intro-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/warehouse-intro-80x28.txt new file mode 100644 index 000000000..6adeab826 --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/warehouse-intro-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + ███ PostHog Wizard 🦔 + + We'll use AI to analyze your project and complete work. + .env* file contents will not leave your machine. + + Let's connect your data to PostHog's data warehouse. + + Directory ✔ /app + + ▸ Continue + More info + Privacy & data + Cancel + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/frames/wizard-ask-60x15.txt b/src/ui/tui/__tests__/__snapshots__/frames/wizard-ask-60x15.txt deleted file mode 100644 index cebaf5c47..000000000 --- a/src/ui/tui/__tests__/__snapshots__/frames/wizard-ask-60x15.txt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - The Wizard needs more room to display required text. - Please make this terminal bigger. - - Currently 60×15, needs at least 80×28. diff --git a/src/ui/tui/__tests__/__snapshots__/frames/wizard-ask-80x28.txt b/src/ui/tui/__tests__/__snapshots__/frames/wizard-ask-80x28.txt new file mode 100644 index 000000000..0c76cd16b --- /dev/null +++ b/src/ui/tui/__tests__/__snapshots__/frames/wizard-ask-80x28.txt @@ -0,0 +1,27 @@ + PostHog Wizard v0.0.0-test Feedback: wizard@posthog.com + + Cost (running): $0.00 · no agent turns yet Ctrl+T to hide + + + + + + + ╭──────────────────────────────────────────────────────────────────────╮ + │ │ + │ ◆ integration-nextjs │ + │ │ + │ Which router does this app use? │ + │ │ + │ ▸ App Router │ + │ Pages Router │ + │ │ + │ ESC skip │ + │ │ + ╰──────────────────────────────────────────────────────────────────────╯ + + + + + + ↑↓ navigate enter select diff --git a/src/ui/tui/__tests__/__snapshots__/keyboard-equivalence.test.tsx.snap b/src/ui/tui/__tests__/__snapshots__/keyboard-equivalence.test.tsx.snap index c9b7a24f5..e5355cb55 100644 --- a/src/ui/tui/__tests__/__snapshots__/keyboard-equivalence.test.tsx.snap +++ b/src/ui/tui/__tests__/__snapshots__/keyboard-equivalence.test.tsx.snap @@ -6,7 +6,6 @@ exports[`keyboard commit vs control action commit > audit-outro: any key vs dism "outroDismissed": true, "screen": "keep-skills", }, - "equal": false, "keyboard": { "outroDismissed": true, "screen": "keep-skills", @@ -21,7 +20,6 @@ exports[`keyboard commit vs control action commit > intro: enter on Continue vs "screen": "health-check", "setupConfirmed": true, }, - "equal": false, "keyboard": { "scanConsent": "granted", "screen": "health-check", @@ -36,7 +34,6 @@ exports[`keyboard commit vs control action commit > keep-skills: mount with no s "action": { "skillsComplete": true, }, - "equal": false, "keyboard": {}, } `; @@ -47,7 +44,6 @@ exports[`keyboard commit vs control action commit > manual-auth-code: escape vs "overlay": false, "screen": "auth", }, - "equal": true, "keyboard": { "overlay": false, "screen": "auth", @@ -61,7 +57,6 @@ exports[`keyboard commit vs control action commit > manual-auth-code: paste code "overlay": false, "screen": "auth", }, - "equal": true, "keyboard": { "overlay": false, "screen": "auth", @@ -76,7 +71,6 @@ exports[`keyboard commit vs control action commit > mcp: decline install vs set_ "mcpOutcome": "skipped", "screen": "slack-connect", }, - "equal": false, "keyboard": { "mcpComplete": true, "mcpOutcome": "skipped", @@ -92,7 +86,6 @@ exports[`keyboard commit vs control action commit > outro: any key vs dismiss_ou "outroDismissed": true, "screen": "mcp", }, - "equal": true, "keyboard": { "outroDismissed": true, "screen": "mcp", @@ -107,7 +100,6 @@ exports[`keyboard commit vs control action commit > port-conflict: enter vs reso "portConflictProcess": null, "screen": "auth", }, - "equal": true, "keyboard": { "overlay": false, "portConflictProcess": null, @@ -122,7 +114,6 @@ exports[`keyboard commit vs control action commit > self-driving-handoff: enter "screen": "self-driving-github", "selfDrivingHandoffConfirmed": true, }, - "equal": true, "keyboard": { "screen": "self-driving-github", "selfDrivingHandoffConfirmed": true, @@ -136,7 +127,6 @@ exports[`keyboard commit vs control action commit > self-driving-integration-che "integrate": true, "screen": "health-check", }, - "equal": true, "keyboard": { "integrate": true, "screen": "health-check", @@ -152,7 +142,6 @@ exports[`keyboard commit vs control action commit > setup: enter on first router }, "screen": "auth", }, - "equal": true, "keyboard": { "frameworkContext": { "router": "app-router", @@ -168,7 +157,6 @@ exports[`keyboard commit vs control action commit > slack-connect: skip vs dismi "screen": "keep-skills", "slackStepDismissed": true, }, - "equal": false, "keyboard": { "screen": "keep-skills", "skillsComplete": true, @@ -183,7 +171,6 @@ exports[`keyboard commit vs control action commit > source-maps-outro: any key v "outroDismissed": true, "screen": "keep-skills", }, - "equal": false, "keyboard": { "outroDismissed": true, "screen": "keep-skills", @@ -199,7 +186,6 @@ exports[`keyboard commit vs control action commit > task-notice: enter vs resolv "screen": "intro", "taskNotice": null, }, - "equal": true, "keyboard": { "overlay": false, "screen": "intro", @@ -215,7 +201,6 @@ exports[`keyboard commit vs control action commit > task-notice: escape vs resol "screen": "intro", "taskNotice": null, }, - "equal": true, "keyboard": { "overlay": false, "screen": "intro", @@ -231,7 +216,6 @@ exports[`keyboard commit vs control action commit > wizard-ask: type answer and "pendingQuestion": null, "screen": "intro", }, - "equal": true, "keyboard": { "overlay": false, "pendingQuestion": null, diff --git a/src/ui/tui/__tests__/frames.test.tsx b/src/ui/tui/__tests__/frames.test.tsx index bd7f5ca91..2a2b805f6 100644 --- a/src/ui/tui/__tests__/frames.test.tsx +++ b/src/ui/tui/__tests__/frames.test.tsx @@ -129,10 +129,13 @@ import { type TerminalSize, } from './helpers/render-screen.no-jest'; +// 80x28 is the ScreenContainer minimum. Anything smaller renders the +// viewport guard instead of the screen, which the last describe pins once. const SIZES: TerminalSize[] = [ { columns: 120, rows: 40 }, - { columns: 60, rows: 15 }, + { columns: 80, rows: 28 }, ]; +const TOO_SMALL: TerminalSize = { columns: 60, rows: 15 }; const CREDENTIALS = { accessToken: 'phx_test_token', @@ -582,6 +585,43 @@ describe.each(Object.entries(FIXTURES))('%s', (name, fixture) => { }); }); +describe('viewport guard', () => { + it('replaces every screen below 80x28 with the too-small message', async () => { + const store = makeStore(FIXTURES[ScreenId.Intro].program); + FIXTURES[ScreenId.Intro].arrange?.(store); + const { frame } = await renderScreen( + store, + screenShell(store, makeServices(store)), + TOO_SMALL, + ); + expect(frame).toContain('needs at least 80×28'); + await expect(frame).toMatchFileSnapshot( + snapshotPath(ScreenId.Intro, TOO_SMALL), + ); + }); +}); + +describe('revenue-intro with a detect error', () => { + // Covers the detect-error branch of RevenueIntroScreen, which spreads the + // POSTHOG_SDKS / STRIPE_SDKS sets before calling array methods. + it.each(SIZES)(`at $columns x $rows`, async (size) => { + const store = makeStore(Program.RevenueAnalyticsSetup); + store.setFrameworkContext('detectError', { + kind: 'no-sdks', + scannedCount: 2, + }); + expect(store.currentScreen).toBe(ScreenId.RevenueIntro); + const { frame } = await renderScreen( + store, + screenShell(store, makeServices(store)), + size, + ); + await expect(frame).toMatchFileSnapshot( + `__snapshots__/frames/revenue-intro-detect-error-${size.columns}x${size.rows}.txt`, + ); + }); +}); + function snapshotPath(screen: ScreenName, size: TerminalSize): string { return `__snapshots__/frames/${screen}-${size.columns}x${size.rows}.txt`; } diff --git a/src/ui/tui/__tests__/keyboard-equivalence.test.tsx b/src/ui/tui/__tests__/keyboard-equivalence.test.tsx index 330523f58..790487197 100644 --- a/src/ui/tui/__tests__/keyboard-equivalence.test.tsx +++ b/src/ui/tui/__tests__/keyboard-equivalence.test.tsx @@ -5,6 +5,9 @@ */ import { vi, describe, it, expect, afterEach, beforeAll } from 'vitest'; import { render, cleanup } from 'ink-testing-library'; +import { mkdtempSync } from 'fs'; +import { tmpdir } from 'os'; +import { join } from 'path'; import { WizardStore, Program, @@ -76,9 +79,17 @@ vi.mock('@utils/wizard-abort', async (importOriginal) => ({ wizardAbort: vi.fn().mockResolvedValue(undefined), })); +// A temp dir so KeepSkillsScreen's readdir of `/.claude/skills` +// never sees a host directory. +const INSTALL_DIR = mkdtempSync(join(tmpdir(), 'wizard-kb-')); + const ENTER = '\r'; const ESC = '\u001B'; const DOWN = '\u001B[B'; +// Real timers on purpose: Ink delivers stdin writes through the event loop, +// and under vi.useFakeTimers the key handlers never run (verified: every +// keyboard diff came back empty). The frames test can fake time since it +// never presses a key. const tick = (ms = 40) => new Promise((r) => setTimeout(r, ms)); const clean = { @@ -121,6 +132,12 @@ const fakeInstaller = { interface Pair { name: string; + /** + * Set when the keyboard path and the control action are known to commit + * different state today. The test asserts the divergence so a fix must + * clear this field rather than silently re-record. + */ + knownDivergence?: string; program: ProgramId; integration?: Integration; screen: string; @@ -139,6 +156,8 @@ const nextjsRouterFirst = () => { const PAIRS: Pair[] = [ { name: 'intro: enter on Continue vs confirm_setup', + knownDivergence: + 'keyboard grants scan sharing before completeSetup, confirm_setup only completes setup', program: Program.PostHogIntegration, screen: ScreenId.Intro, arrange: () => undefined, @@ -169,6 +188,8 @@ const PAIRS: Pair[] = [ }, { name: 'mcp: decline install vs set_mcp_outcome skipped', + knownDivergence: + 'keyboard path records extra MCP state the action does not', program: Program.PostHogIntegration, screen: ScreenId.Mcp, arrange: (s) => { @@ -183,6 +204,8 @@ const PAIRS: Pair[] = [ }, { name: 'slack-connect: skip vs dismiss_slack', + knownDivergence: + 'keyboard path and dismiss_slack commit different slack step state', program: Program.PostHogIntegration, screen: ScreenId.SlackConnect, arrange: (s) => { @@ -197,6 +220,8 @@ const PAIRS: Pair[] = [ }, { name: 'keep-skills: mount with no skills dir vs keep_skills', + knownDivergence: + 'keyboard path runs the skills-dir scan effect, the action only flips the flag', program: Program.PostHogIntegration, screen: ScreenId.KeepSkills, arrange: (s) => { @@ -213,6 +238,8 @@ const PAIRS: Pair[] = [ }, { name: 'audit-outro: any key vs dismiss_outro', + knownDivergence: + 'keyboard path commits mintHandoff alongside outroDismissed', program: Program.Audit, screen: ScreenId.AuditOutro, arrange: (s) => { @@ -225,6 +252,8 @@ const PAIRS: Pair[] = [ }, { name: 'source-maps-outro: any key vs dismiss_outro', + knownDivergence: + 'keyboard path commits mintHandoff alongside outroDismissed', program: Program.ErrorTrackingUploadSourceMaps, screen: ScreenId.SourceMapsOutro, arrange: (s) => { @@ -363,7 +392,7 @@ function makeStore(pair: Pair): WizardStore { const store = new WizardStore(pair.program); store.version = '0.0.0-test'; setUI(new InkUI(store)); - const session = buildSession({ installDir: '/app', ci: false }); + const session = buildSession({ installDir: INSTALL_DIR, ci: false }); const integration = pair.integration ?? Integration.javascriptNode; session.integration = integration; session.frameworkConfig = FRAMEWORK_REGISTRY[integration]; @@ -447,11 +476,12 @@ describe('keyboard commit vs control action commit', () => { it(pair.name, async () => { const keyboard = await driveKeyboard(pair); const action = applyAction(pair); - expect({ - keyboard, - action, - equal: JSON.stringify(keyboard) === JSON.stringify(action), - }).toMatchSnapshot(); + if (pair.knownDivergence) { + expect(keyboard, pair.knownDivergence).not.toEqual(action); + } else { + expect(keyboard).toEqual(action); + } + expect({ keyboard, action }).toMatchSnapshot(); }); } }); diff --git a/vitest.config.ts b/vitest.config.ts index e95dbab94..7985ed29d 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -48,7 +48,10 @@ const CLI_TESTS = [ 'src/__tests__/wizard.test.ts', 'src/__tests__/headless-scope.test.ts', ]; -const HARNESS_TESTS = [`e2e-harness/${TESTS}`]; +const HARNESS_TESTS = [ + `e2e-harness/${TESTS}`, + 'e2e-harness/**/*.{test,spec}.{js,jsx,ts,tsx}', +]; const ARCH_TESTS = ['src/__tests__/architecture/**/*.{ts,tsx}']; const EXCLUDE = [ '**/node_modules/**', @@ -105,7 +108,9 @@ export default defineConfig({ project('architecture', ARCH_TESTS), project( 'legacy', - [`src/**/${TESTS}`], + // The second glob keeps the pre-split behavior: a test file outside + // a __tests__ directory still runs, here, rather than nowhere. + [`src/**/${TESTS}`, 'src/**/*.{test,spec}.{js,jsx,ts,tsx}'], [...AGENT_TESTS, ...TUI_TESTS, ...CLI_TESTS, ...ARCH_TESTS], ), ], From 2da15c628bf0ff8745b3d69fec8014af26e14a1d Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Mon, 21 Sep 2026 15:00:52 -0400 Subject: [PATCH 5/9] chore(build): gate the bundle audit on a platform-stable summary Rolldown assigns shared modules such as analytics and yara-hooks to different chunks on macOS and Linux, so a byte diff of the per-chunk manifest failed on the runner against a fixture recorded locally. The script gains --summary: chunk names plus the sorted set of bundled sources, identical on both platforms. The fixtures become that summary and the Surfaces workflow diffs it. The full manifests still upload as artifacts. Generated-By: PostHog Desktop Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589 --- .github/workflows/surfaces.yml | 20 +- scripts/README.md | 32 +- scripts/__fixtures__/chunk-manifest.ci.json | 1412 +++++++---------- scripts/__fixtures__/chunk-manifest.prod.json | 1411 +++++++--------- scripts/chunk-manifest.no-jest.ts | 20 +- 5 files changed, 1113 insertions(+), 1782 deletions(-) diff --git a/.github/workflows/surfaces.yml b/.github/workflows/surfaces.yml index 8e11424aa..f8a05e2bf 100644 --- a/.github/workflows/surfaces.yml +++ b/.github/workflows/surfaces.yml @@ -47,20 +47,24 @@ jobs: - run: pnpm install --frozen-lockfile - name: Production build and smoke test run: pnpm build - - name: Production chunk manifest matches the fixture + - name: Production chunk summary matches the fixture run: | npx tsx scripts/chunk-manifest.no-jest.ts dist > chunk-manifest.prod.json - npx prettier --write chunk-manifest.prod.json - diff scripts/__fixtures__/chunk-manifest.prod.json chunk-manifest.prod.json + npx tsx scripts/chunk-manifest.no-jest.ts dist --summary > chunk-summary.prod.json + npx prettier --write chunk-summary.prod.json + diff scripts/__fixtures__/chunk-manifest.prod.json chunk-summary.prod.json - name: CI build and smoke test run: pnpm build:ci - - name: CI chunk manifest matches the fixture + - name: CI chunk summary matches the fixture run: | npx tsx scripts/chunk-manifest.no-jest.ts dist > chunk-manifest.ci.json - npx prettier --write chunk-manifest.ci.json - diff scripts/__fixtures__/chunk-manifest.ci.json chunk-manifest.ci.json + npx tsx scripts/chunk-manifest.no-jest.ts dist --summary > chunk-summary.ci.json + npx prettier --write chunk-summary.ci.json + diff scripts/__fixtures__/chunk-manifest.ci.json chunk-summary.ci.json - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - if: failure() + if: always() with: name: chunk-manifests-${{ github.sha }} - path: chunk-manifest.*.json + path: | + chunk-manifest.*.json + chunk-summary.*.json diff --git a/scripts/README.md b/scripts/README.md index 725eda866..eefd481d7 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -12,18 +12,18 @@ real ink render) and is driven purely by store state manipulation; a PTY parent ([`e2e-harness/tui-capture.ts`](../e2e-harness/tui-capture.ts), node-pty + `@xterm/headless`) captures the real rendered screen. -| Script | What it does | Needs | -| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | -| **`tui-host.no-jest.ts`** | Real TUI host: `MODE=fixed` follows a profile; `MODE=serve` accepts socket commands. | `APP_DIR`, `PROJECT_ID`, key for a full run, `SNAP_CTRL`; run under a PTY, with `CONTROL_SOCK` in serve mode | -| **`tui-snapshots.no-jest.ts`** | Runs the fixed host and saves colored `SNAP_OUT/NN-.ans` frames, including within-screen progress. | `SNAP_OUT`, `APP_DIR`, `PROJECT_ID`, `POSTHOG_KEY_FILE` or `POSTHOG_PERSONAL_API_KEY` | -| **`wizard-ci-mcp.no-jest.ts`** | Stdio MCP server: `open_app`, `read_state`, `perform_action`, `render_screen`, `run_agent`. Screen output is plain text. | Spawns the host; `open_app` requires `appDir` and `projectId`, with optional `keyFile`, `apiKey`, `region` | -| **`chunk-manifest.no-jest.ts`** | Prints a structural manifest of `dist/`: per chunk, the source files it contains and the chunks it imports, hash suffixes stripped. Baselines live in `scripts/__fixtures__/chunk-manifest.{prod,ci}.json`. | A built `dist/` | -| **`wizard-ci-explore.no-jest.ts`** | `pnpm wizard-ci-explore`: opens an app, confirms setup, reads state, prints one frame, and exits. It does not run the agent. | `APP_DIR`, `PROJECT_ID`; optional `POSTHOG_KEY_FILE` | +| Script | What it does | Needs | +| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | +| **`tui-host.no-jest.ts`** | Real TUI host: `MODE=fixed` follows a profile; `MODE=serve` accepts socket commands. | `APP_DIR`, `PROJECT_ID`, key for a full run, `SNAP_CTRL`; run under a PTY, with `CONTROL_SOCK` in serve mode | +| **`tui-snapshots.no-jest.ts`** | Runs the fixed host and saves colored `SNAP_OUT/NN-.ans` frames, including within-screen progress. | `SNAP_OUT`, `APP_DIR`, `PROJECT_ID`, `POSTHOG_KEY_FILE` or `POSTHOG_PERSONAL_API_KEY` | +| **`wizard-ci-mcp.no-jest.ts`** | Stdio MCP server: `open_app`, `read_state`, `perform_action`, `render_screen`, `run_agent`. Screen output is plain text. | Spawns the host; `open_app` requires `appDir` and `projectId`, with optional `keyFile`, `apiKey`, `region` | +| **`chunk-manifest.no-jest.ts`** | Prints a structural manifest of `dist/`: per chunk, the source files it contains and the chunks it imports, hash suffixes stripped. `--summary` prints the chunk names and the sorted source set, which is stable across macOS and Linux. The Surfaces workflow diffs that summary against `scripts/__fixtures__/chunk-manifest.{prod,ci}.json`. | A built `dist/` | +| **`wizard-ci-explore.no-jest.ts`** | `pnpm wizard-ci-explore`: opens an app, confirms setup, reads state, prints one frame, and exits. It does not run the agent. | `APP_DIR`, `PROJECT_ID`; optional `POSTHOG_KEY_FILE` | > You usually don't call these directly — `pnpm wizard-ci-snapshots` (in > [wizard-workbench](https://github.com/PostHog/wizard-workbench)) orchestrates -> the snapshot route; the MCP server is registered in this repo's `.mcp.json` and -> used via the `exploring-the-wizard` skill. +> the snapshot route; the MCP server is registered in this repo's `.mcp.json` +> and used via the `exploring-the-wizard` skill. `PROGRAM`, `SNAP_HARNESS`, `SNAP_SEQUENCE`, `SNAP_MODEL`, and `E2E_ASK` are host environment inputs, inherited from the launcher; they are not MCP tool @@ -35,11 +35,11 @@ before choosing credentials or an EU project. ## Credentials for full agent runs Full TUI host and snapshot runs require both the personal API key (or -`POSTHOG_KEY_FILE`) and `WIZARD_CI_GATEWAY_TOKEN_FILE`, plus `PROJECT_ID`. -For MCP runs, pass the personal key through `open_app` and set the gateway -token file path in the server environment before launch. Restart the server -after changing it; the gateway path is not an MCP tool argument. -Detection-only exploration does not need either secret. See +`POSTHOG_KEY_FILE`) and `WIZARD_CI_GATEWAY_TOKEN_FILE`, plus `PROJECT_ID`. For +MCP runs, pass the personal key through `open_app` and set the gateway token +file path in the server environment before launch. Restart the server after +changing it; the gateway path is not an MCP tool argument. Detection-only +exploration does not need either secret. See [local credential setup](../docs/local-dev.md#credentials-for-local-ci-and-headless-runs). ## Background @@ -47,5 +47,5 @@ Detection-only exploration does not need either secret. See The control plane lives in [`e2e-harness/`](../e2e-harness/) — out of `src/`, so none of it ships in prod. `WizardCiDriver` (read/act over the store), the screen→action registry, the e2e profiles, and `tui-capture` (real-TUI PTY -capture). See [`ARCHITECTURE.md`](../e2e-harness/ARCHITECTURE.md) for how the two -routes drive these (env strip, scoped project id, gotchas). +capture). See [`ARCHITECTURE.md`](../e2e-harness/ARCHITECTURE.md) for how the +two routes drive these (env strip, scoped project id, gotchas). diff --git a/scripts/__fixtures__/chunk-manifest.ci.json b/scripts/__fixtures__/chunk-manifest.ci.json index a8ecaa206..852306aa5 100644 --- a/scripts/__fixtures__/chunk-manifest.ci.json +++ b/scripts/__fixtures__/chunk-manifest.ci.json @@ -1,880 +1,536 @@ { - "add-mcp-server-to-clients.js": { - "sources": [ - "src/steps/add-mcp-server-to-clients/MCPClient.ts", - "src/steps/add-mcp-server-to-clients/clients/claude-code.ts", - "src/steps/add-mcp-server-to-clients/clients/claude-web.ts", - "src/steps/add-mcp-server-to-clients/clients/codex.ts", - "src/steps/add-mcp-server-to-clients/clients/cursor.ts", - "src/steps/add-mcp-server-to-clients/clients/opencode.ts", - "src/steps/add-mcp-server-to-clients/clients/visual-studio-code.ts", - "src/steps/add-mcp-server-to-clients/clients/zed.ts", - "src/steps/add-mcp-server-to-clients/index.ts", - "src/steps/add-mcp-server-to-clients/plugin-client.ts" - ], - "imports": [ - "analytics.js", - "debug.js", - "defaults.js", - "rolldown-runtime.js", - "telemetry.js" - ] - }, - "agent-interface.js": { - "sources": [ - "src/lib/agent/agent-env-isolation.ts", - "src/lib/agent/agent-interface.ts", - "src/lib/agent/agent-phase.ts", - "src/lib/agent/bash-fence.ts", - "src/lib/agent/claude-settings.ts", - "src/lib/agent/commandments.ts", - "src/lib/agent/output-signals.ts", - "src/lib/agent/runner/harness/pi/gateway.ts", - "src/lib/agent/runner/harness/pi/runtime-notes.ts", - "src/lib/agent/runner/switchboard/commandments.ts", - "src/lib/agent/stored-login.ts", - "src/lib/agent/triage-provider.ts", - "src/lib/auth-session-state.ts", - "src/lib/fetch-retry.ts", - "src/lib/safe-tools.ts", - "src/lib/secret-vault.ts", - "src/lib/wizard-ask-bridge.ts", - "src/lib/wizard-tools/handoff.ts", - "src/lib/wizard-tools/mcp.ts", - "src/lib/wizard-tools/tools.ts", - "src/utils/custom-headers.ts", - "src/utils/env-scan.ts" - ], - "imports": [ - "analytics.js", - "bounded-fs.js", - "debug.js", - "errors.js", - "gateway-session.js", - "queue-tools.js", - "rolldown-runtime.js", - "wizard-abort.js", - "wizard-session.js", - "yara-hooks.js" - ] - }, - "agent-prompt-loader.js": { - "sources": ["src/lib/agent/agent-prompt-loader.ts"], - "imports": [ - "agent-interface.js", - "analytics.js", - "debug.js", - "queue-tools.js" - ] - }, - "agent-runner.js": { - "sources": [ - "src/lib/agent/agent-prompt.ts", - "src/lib/agent/agent-runner.ts", - "src/lib/agent/runner/harness/anthropic/index.ts", - "src/lib/agent/runner/index.ts", - "src/lib/agent/runner/sequence/linear.ts", - "src/lib/agent/runner/sequence/orchestrator/executor.ts", - "src/lib/agent/runner/sequence/orchestrator/orchestrator-runner.ts", - "src/lib/agent/runner/sequence/orchestrator/run-metrics.ts", - "src/lib/agent/runner/sequence/orchestrator/seeded-deps.ts", - "src/lib/agent/runner/shared/authenticate.ts", - "src/lib/agent/runner/shared/bootstrap.ts", - "src/lib/agent/runner/shared/errors.ts", - "src/lib/agent/runner/switchboard/flags/index.ts", - "src/lib/agent/runner/switchboard/flags/orchestrator.ts", - "src/lib/agent/runner/switchboard/flags/schemes.ts", - "src/lib/agent/runner/switchboard/flags/self-driving.ts", - "src/lib/agent/runner/switchboard/harness.ts", - "src/lib/agent/runner/switchboard/index.ts", - "src/lib/agent/runner/switchboard/sequence.ts", - "src/lib/agent/token-pricing.ts", - "src/lib/detection/agentic.ts", - "src/lib/detection/context.ts", - "src/lib/detection/features.ts", - "src/lib/detection/framework.ts", - "src/lib/middleware/benchmark.ts", - "src/lib/middleware/benchmarks/cache-tracker.ts", - "src/lib/middleware/benchmarks/compaction-tracker.ts", - "src/lib/middleware/benchmarks/context-size-tracker.ts", - "src/lib/middleware/benchmarks/cost-tracker.ts", - "src/lib/middleware/benchmarks/duration-tracker.ts", - "src/lib/middleware/benchmarks/index.ts", - "src/lib/middleware/benchmarks/json-writer.ts", - "src/lib/middleware/benchmarks/summary.ts", - "src/lib/middleware/benchmarks/token-tracker.ts", - "src/lib/middleware/benchmarks/turn-counter.ts", - "src/lib/middleware/config.ts", - "src/lib/middleware/phase-detector.ts", - "src/lib/middleware/pipeline.ts", - "src/lib/programs/audit/ledger-watcher.ts", - "src/lib/programs/posthog-integration/detect.ts", - "src/lib/programs/shared/package-scanning.ts", - "src/lib/programs/warehouse-source/detect.ts", - "src/lib/warehouse-sources/detect.ts", - "src/lib/warehouse-sources/registry.ts", - "src/utils/terminal-bell.ts" - ], - "imports": [ - "agent-interface.js", - "agent-prompt-loader.js", - "analytics.js", - "bounded-fs.js", - "debug.js", - "environment.js", - "errors.js", - "file-watcher.js", - "gateway-session.js", - "package-manager.js", - "pi.js", - "queue-tools.js", - "registry.js", - "rolldown-runtime.js", - "setup-utils.js", - "wizard-abort.js", - "wizard-session.js", - "yara-hooks.js" - ] - }, - "analytics.js": { - "sources": ["src/utils/analytics.ts", "src/utils/ci-flag-overrides.ts"], - "imports": ["debug.js", "wizard-session.js"] - }, - "api.js": { - "sources": ["src/lib/api.ts"], - "imports": ["analytics.js", "debug.js", "rolldown-runtime.js"] - }, - "bin.js": { - "sources": [ - "bin.ts", - "src/commands/ai-observability.ts", - "src/commands/audit.ts", - "src/commands/basic-integration/index.ts", - "src/commands/basic-integration/skill.ts", - "src/commands/cli/add.ts", - "src/commands/cli/index.ts", - "src/commands/command.ts", - "src/commands/doctor.ts", - "src/commands/error-tracking.ts", - "src/commands/factories/family-command-factory.ts", - "src/commands/factories/family-picker.tsx", - "src/commands/factories/native-command-factory.ts", - "src/commands/factories/shared.ts", - "src/commands/mcp-analytics.ts", - "src/commands/mcp/add.ts", - "src/commands/mcp/index.ts", - "src/commands/mcp/remove.ts", - "src/commands/mcp/tui-availability.ts", - "src/commands/mcp/tutorial.ts", - "src/commands/metrics.ts", - "src/commands/migrate.ts", - "src/commands/provision.ts", - "src/commands/replay-vision.ts", - "src/commands/revenue.ts", - "src/commands/self-driving.ts", - "src/commands/skill-program-options.ts", - "src/commands/skill.ts", - "src/commands/slack.ts", - "src/commands/upload-sourcemaps.ts", - "src/commands/warehouse.ts", - "src/lib/programs/dispatch-family.ts", - "src/lib/runners/resolve-no-telemetry.ts", - "src/lib/runners/run-non-interactive.ts", - "src/lib/runners/run-wizard-ci.ts", - "src/lib/runners/run-wizard-headless.ts", - "src/lib/runners/run-wizard.ts", - "src/ui/tui/hooks/keyboard-hints-utils.ts", - "src/ui/tui/hooks/useKeyBindings.ts", - "src/ui/tui/hooks/useKeyboardHints.tsx", - "src/ui/tui/hooks/useStdoutDimensions.ts", - "src/ui/tui/primitives/ConfirmButton.tsx", - "src/ui/tui/primitives/PickerMenu.tsx", - "src/ui/tui/primitives/PromptLabel.tsx", - "src/ui/tui/primitives/picker-filter.ts", - "src/wizard.ts" - ], - "imports": [ - "add-mcp-server-to-clients.js", - "agent-interface.js", - "agent-runner.js", - "analytics.js", - "api.js", - "ci-install.js", - "debug.js", - "env-api-key.js", - "environment.js", - "errors.js", - "file.js", - "gateway-session.js", - "headless-ui.js", - "interactive.js", - "local-dev.js", - "mint-failure.js", - "non-interactive.js", - "playground.js", - "posthog.js", - "provisioning.js", - "setup-utils.js", - "start-tui.js", - "store.js", - "task-stream.js", - "telemetry.js", - "wizard-abort.js", - "wizard-session.js", - "yara-hooks.js" - ] - }, - "bounded-fs.js": { - "sources": ["src/utils/bounded-fs.ts"], - "imports": ["analytics.js", "debug.js"] - }, - "ci-install.js": { - "sources": ["src/commands/basic-integration/ci-install.ts"], - "imports": [ - "bin.js", - "debug.js", - "errors.js", - "mint-failure.js", - "provisioning.js" - ] - }, - "debug.js": { - "sources": [ - "src/env.ts", - "src/lib/constants.ts", - "src/lib/headless-mode.ts", - "src/lib/health-checks/endpoints.ts", - "src/lib/health-checks/readiness.ts", - "src/lib/version.ts", - "src/ui/index.ts", - "src/ui/logging-ui.ts", - "src/ui/wizard-ui.ts", - "src/utils/debug.ts", - "src/utils/paths.ts" - ], - "imports": ["analytics.js", "local-dev.js"] - }, - "defaults.js": { - "sources": [ - "src/steps/add-mcp-server-to-clients/defaults.ts", - "src/steps/add-mcp-server-to-clients/results.ts" - ], - "imports": [] - }, - "env-api-key.js": { - "sources": ["src/utils/env-api-key.ts"], - "imports": ["bounded-fs.js", "rolldown-runtime.js"] - }, - "environment.js": { - "sources": ["src/utils/environment.ts"], - "imports": ["rolldown-runtime.js"] - }, - "errors.js": { - "sources": [ - "src/lib/agent/signals.ts", - "src/lib/errors/agent-map.ts", - "src/lib/errors/auth.ts", - "src/lib/errors/catalog.ts", - "src/lib/errors/codes.ts", - "src/lib/errors/detect-map.ts", - "src/lib/errors/emit.ts", - "src/lib/errors/run-failure.ts", - "src/lib/errors/sanitize.ts", - "src/lib/errors/skill-map.ts" - ], - "imports": [] - }, - "file.js": { - "sources": ["src/lib/task-stream/destinations/file.ts"], - "imports": ["debug.js"] - }, - "file-watcher.js": { - "sources": ["src/lib/file-watcher.ts"], - "imports": ["debug.js"] - }, - "gateway-session.js": { - "sources": [], - "imports": ["gateway-session.js"] - }, - "headless-ui.js": { - "sources": ["src/ui/headless-ui.ts"], - "imports": ["debug.js"] - }, - "interactive.js": { - "sources": ["src/commands/basic-integration/interactive.ts"], - "imports": ["bin.js", "mint-failure.js"] - }, - "local-dev.js": { - "sources": ["src/lib/local-dev.ts"], - "imports": [] - }, - "mcp.js": { - "sources": ["src/lib/agent/runner/harness/pi/mcp.ts"], - "imports": ["debug.js"] - }, - "mcp-prompt-streaming.js": { - "sources": ["src/lib/agent/mcp-prompt-streaming.ts"], - "imports": [ - "agent-interface.js", - "analytics.js", - "debug.js", - "gateway-session.js" - ] - }, - "mint-failure.js": { - "sources": [ - "src/lib/detection/project-scope.ts", - "src/lib/programs/agent-skill/content/index.tsx", - "src/lib/programs/agent-skill/index.ts", - "src/lib/programs/agent-skill/steps.ts", - "src/lib/programs/ai-observability/index.ts", - "src/lib/programs/audit/detect.ts", - "src/lib/programs/audit/index.ts", - "src/lib/programs/audit/seed.ts", - "src/lib/programs/error-tracking-upload-source-maps/content/index.tsx", - "src/lib/programs/error-tracking-upload-source-maps/detect.ts", - "src/lib/programs/error-tracking-upload-source-maps/index.ts", - "src/lib/programs/error-tracking-upload-source-maps/prompt.ts", - "src/lib/programs/error-tracking-upload-source-maps/steps.ts", - "src/lib/programs/error-tracking/content/index.tsx", - "src/lib/programs/error-tracking/content/tips.ts", - "src/lib/programs/error-tracking/detect-agentic.ts", - "src/lib/programs/error-tracking/index.ts", - "src/lib/programs/events-audit/index.ts", - "src/lib/programs/events-audit/seed.ts", - "src/lib/programs/events-audit/steps.ts", - "src/lib/programs/mcp-analytics/index.ts", - "src/lib/programs/mcp/index.ts", - "src/lib/programs/metrics/index.ts", - "src/lib/programs/migration/content/free-tier.tsx", - "src/lib/programs/migration/content/index.tsx", - "src/lib/programs/migration/content/pricing-structure.tsx", - "src/lib/programs/migration/content/vendor-stack.tsx", - "src/lib/programs/migration/index.ts", - "src/lib/programs/migration/steps.ts", - "src/lib/programs/posthog-doctor/fetch.ts", - "src/lib/programs/posthog-doctor/index.ts", - "src/lib/programs/posthog-doctor/kind-metadata.ts", - "src/lib/programs/posthog-doctor/steps.ts", - "src/lib/programs/posthog-doctor/types.ts", - "src/lib/programs/posthog-integration/content/data-flow.tsx", - "src/lib/programs/posthog-integration/content/funnel.tsx", - "src/lib/programs/posthog-integration/content/index.tsx", - "src/lib/programs/posthog-integration/content/line-chart.tsx", - "src/lib/programs/posthog-integration/content/product-suite.tsx", - "src/lib/programs/posthog-integration/handoff.ts", - "src/lib/programs/posthog-integration/index.ts", - "src/lib/programs/posthog-integration/steps.ts", - "src/lib/programs/program-registry.ts", - "src/lib/programs/replay-vision/index.ts", - "src/lib/programs/revenue-analytics/detect.ts", - "src/lib/programs/revenue-analytics/index.ts", - "src/lib/programs/revenue-analytics/steps.ts", - "src/lib/programs/self-driving/content/index.tsx", - "src/lib/programs/self-driving/content/pipeline-diagram.tsx", - "src/lib/programs/self-driving/content/pricing.ts", - "src/lib/programs/self-driving/content/tips.ts", - "src/lib/programs/self-driving/detect-agentic.ts", - "src/lib/programs/self-driving/detect.ts", - "src/lib/programs/self-driving/index.ts", - "src/lib/programs/self-driving/prompt.ts", - "src/lib/programs/self-driving/step-keys.ts", - "src/lib/programs/self-driving/steps.ts", - "src/lib/programs/shared/health-check-step.ts", - "src/lib/programs/shared/posthog-cli-preinstall.ts", - "src/lib/programs/slack/index.ts", - "src/lib/programs/warehouse-source/index.ts", - "src/lib/programs/warehouse-source/steps.ts", - "src/lib/programs/web-analytics-doctor/detect.ts", - "src/lib/programs/web-analytics-doctor/index.ts", - "src/lib/programs/web-analytics-doctor/steps.ts", - "src/steps/install-cli-steering/index.ts", - "src/ui/mint-failure.ts", - "src/ui/tui/components/StatusPeekTrigger.tsx", - "src/ui/tui/primitives/TextBlock.tsx", - "src/ui/tui/primitives/content-types.ts", - "src/ui/tui/primitives/layout-helpers.ts", - "src/ui/tui/primitives/text-helpers.ts", - "src/ui/tui/styles.ts" - ], - "imports": [ - "agent-interface.js", - "agent-runner.js", - "analytics.js", - "api.js", - "debug.js", - "errors.js", - "package-json.js", - "provisioning.js", - "queue-tools.js", - "registry.js", - "setup-utils.js", - "steps.js", - "telemetry.js", - "wizard-abort.js", - "wizard-session.js", - "yara-hooks.js" - ] - }, - "non-interactive.js": { - "sources": ["src/commands/basic-integration/non-interactive.ts"], - "imports": ["debug.js", "errors.js"] - }, - "orchestrator-tools.js": { - "sources": ["src/lib/agent/runner/harness/pi/orchestrator-tools.ts"], - "imports": ["analytics.js", "queue-tools.js"] - }, - "package-json.js": { - "sources": ["src/utils/package-json.ts"], - "imports": ["rolldown-runtime.js"] - }, - "package-manager.js": { - "sources": [ - "src/frameworks/python/utils.ts", - "src/lib/detection/package-manager.ts" - ], - "imports": ["setup-utils.js"] - }, - "pi.js": { - "sources": [ - "src/lib/agent/aio-capture.ts", - "src/lib/agent/runner/harness/pi/completion.ts", - "src/lib/agent/runner/harness/pi/index.ts" - ], - "imports": [ - "agent-interface.js", - "analytics.js", - "debug.js", - "errors.js", - "gateway-session.js", - "mcp.js", - "security.js", - "subagent.js", - "task.js", - "tasks.js", - "tools.js", - "yara-hooks.js" - ] - }, - "playground.js": { - "sources": [ - "src/commands/basic-integration/playground.ts", - "src/ui/tui/playground/PlaygroundApp.tsx", - "src/ui/tui/playground/demos/AiOptInDemo.tsx", - "src/ui/tui/playground/demos/AskModalDemo.tsx", - "src/ui/tui/playground/demos/AuditChecksDemo.tsx", - "src/ui/tui/playground/demos/DoctorReportDemo.tsx", - "src/ui/tui/playground/demos/EndScreensDemo.tsx", - "src/ui/tui/playground/demos/HealthCheckDemo.tsx", - "src/ui/tui/playground/demos/InputDemo.tsx", - "src/ui/tui/playground/demos/KeyboardHintsDemo.tsx", - "src/ui/tui/playground/demos/LayoutDemo.tsx", - "src/ui/tui/playground/demos/LearnDeckDemo.tsx", - "src/ui/tui/playground/demos/LogDemo.tsx", - "src/ui/tui/playground/demos/McpDemo.tsx", - "src/ui/tui/playground/demos/McpSuggestedPromptsDemo.tsx", - "src/ui/tui/playground/demos/ModalDemo.tsx", - "src/ui/tui/playground/demos/ProgressDemo.tsx", - "src/ui/tui/playground/demos/RunScreenDemo.tsx", - "src/ui/tui/playground/demos/ViewportGuardDemo.tsx", - "src/ui/tui/playground/demos/WelcomeDemo.tsx", - "src/ui/tui/playground/start-playground.ts" - ], - "imports": [ - "bin.js", - "debug.js", - "mint-failure.js", - "setup-utils.js", - "store.js", - "terminal.js" - ] - }, - "posthog.js": { - "sources": ["src/lib/task-stream/destinations/posthog.ts"], - "imports": ["debug.js"] - }, - "provisioning.js": { - "sources": ["src/utils/provisioning.ts", "src/utils/urls.ts"], - "imports": ["analytics.js", "debug.js", "rolldown-runtime.js"] - }, - "queue-tools.js": { - "sources": [ - "src/lib/agent/runner/sequence/orchestrator/queue-tools.ts", - "src/lib/agent/runner/sequence/orchestrator/queue.ts", - "src/lib/agent/runner/switchboard/models.ts", - "src/utils/atomic-ledger.ts" - ], - "imports": ["analytics.js", "debug.js"] - }, - "registry.js": { - "sources": [ - "src/frameworks/android/android-wizard-agent.ts", - "src/frameworks/android/utils.ts", - "src/frameworks/angular/angular-wizard-agent.ts", - "src/frameworks/angular/utils.ts", - "src/frameworks/astro/astro-wizard-agent.ts", - "src/frameworks/astro/utils.ts", - "src/frameworks/django/django-wizard-agent.ts", - "src/frameworks/django/utils.ts", - "src/frameworks/elixir/elixir-wizard-agent.ts", - "src/frameworks/fastapi/fastapi-wizard-agent.ts", - "src/frameworks/fastapi/utils.ts", - "src/frameworks/flask/flask-wizard-agent.ts", - "src/frameworks/flask/utils.ts", - "src/frameworks/flutter/flutter-wizard-agent.ts", - "src/frameworks/go/go-wizard-agent.ts", - "src/frameworks/java/java-wizard-agent.ts", - "src/frameworks/javascript-node/javascript-node-wizard-agent.ts", - "src/frameworks/javascript-web/javascript-web-wizard-agent.ts", - "src/frameworks/javascript-web/utils.ts", - "src/frameworks/kmp/kmp-wizard-agent.ts", - "src/frameworks/laravel/laravel-wizard-agent.ts", - "src/frameworks/laravel/utils.ts", - "src/frameworks/nextjs/nextjs-wizard-agent.ts", - "src/frameworks/nextjs/utils.ts", - "src/frameworks/nuxt/nuxt-wizard-agent.ts", - "src/frameworks/python/python-wizard-agent.ts", - "src/frameworks/rails/rails-wizard-agent.ts", - "src/frameworks/rails/utils.ts", - "src/frameworks/react-native/react-native-wizard-agent.ts", - "src/frameworks/react-native/utils.ts", - "src/frameworks/react-router/react-router-wizard-agent.ts", - "src/frameworks/react-router/utils.ts", - "src/frameworks/ruby/ruby-wizard-agent.ts", - "src/frameworks/ruby/utils.ts", - "src/frameworks/rust/rust-wizard-agent.ts", - "src/frameworks/svelte/svelte-wizard-agent.ts", - "src/frameworks/swift/swift-wizard-agent.ts", - "src/frameworks/swift/utils.ts", - "src/frameworks/tanstack-router/tanstack-router-wizard-agent.ts", - "src/frameworks/tanstack-router/utils.ts", - "src/frameworks/tanstack-start/tanstack-start-wizard-agent.ts", - "src/frameworks/tanstack-start/utils.ts", - "src/frameworks/vue/vue-wizard-agent.ts", - "src/lib/framework-config.ts", - "src/lib/registry.ts" - ], - "imports": [ - "bounded-fs.js", - "debug.js", - "package-json.js", - "package-manager.js", - "rolldown-runtime.js", - "setup-utils.js" - ] - }, - "rolldown-runtime.js": { - "sources": [], - "imports": [] - }, - "security.js": { - "sources": ["src/lib/agent/runner/harness/pi/security.ts"], - "imports": [ - "agent-interface.js", - "analytics.js", - "debug.js", - "yara-hooks.js" - ] - }, - "setup-utils.js": { - "sources": [ - "src/lib/host-resolution.ts", - "src/lib/oauth/program-scopes.ts", - "src/utils/oauth-errors.ts", - "src/utils/oauth.ts", - "src/utils/package-manager.ts", - "src/utils/project-resolution.ts", - "src/utils/semver.ts", - "src/utils/setup-utils.ts" - ], - "imports": [ - "analytics.js", - "api.js", - "bounded-fs.js", - "debug.js", - "local-dev.js", - "provisioning.js", - "rolldown-runtime.js", - "telemetry.js", - "wizard-abort.js" - ] - }, - "start-tui.js": { - "sources": [ - "src/lib/programs/error-tracking-upload-source-maps/detect-agentic.ts", - "src/lib/wizard-spellbook.ts", - "src/steps/add-mcp-server-to-clients/browser-client.ts", - "src/steps/add-mcp-server-to-clients/login-client.ts", - "src/ui/tui/App.tsx", - "src/ui/tui/components/PrivacyPanel.tsx", - "src/ui/tui/exit-line.ts", - "src/ui/tui/hooks/useGithubConnection.ts", - "src/ui/tui/ink-ui.ts", - "src/ui/tui/posthog-integration-intro.ts", - "src/ui/tui/screen-registry.tsx", - "src/ui/tui/screens/AgentSkillIntroScreen.tsx", - "src/ui/tui/screens/AiObservabilityIntroScreen.tsx", - "src/ui/tui/screens/AuthErrorScreen.tsx", - "src/ui/tui/screens/AuthScreen.tsx", - "src/ui/tui/screens/ErrorTrackingDetectScreen.tsx", - "src/ui/tui/screens/ErrorTrackingIntroScreen.tsx", - "src/ui/tui/screens/ExitScreen.tsx", - "src/ui/tui/screens/IntroScreenLayout.tsx", - "src/ui/tui/screens/KeepSkillsScreen.tsx", - "src/ui/tui/screens/ManagedSettingsScreen.tsx", - "src/ui/tui/screens/ManualAuthCodeScreen.tsx", - "src/ui/tui/screens/MetricsIntroScreen.tsx", - "src/ui/tui/screens/MigrationIntroScreen.tsx", - "src/ui/tui/screens/MintFailureScreen.tsx", - "src/ui/tui/screens/PortConflictScreen.tsx", - "src/ui/tui/screens/PostHogIntegrationIntroScreen.tsx", - "src/ui/tui/screens/RevenueIntroScreen.tsx", - "src/ui/tui/screens/RunScreen.tsx", - "src/ui/tui/screens/SelfDrivingGitHubScreen.tsx", - "src/ui/tui/screens/SelfDrivingHandoffScreen.tsx", - "src/ui/tui/screens/SelfDrivingIntegrationCheckScreen.tsx", - "src/ui/tui/screens/SelfDrivingIntegrationDetectScreen.tsx", - "src/ui/tui/screens/SelfDrivingIntroScreen.tsx", - "src/ui/tui/screens/SessionTimeoutScreen.tsx", - "src/ui/tui/screens/SettingsOverrideScreen.tsx", - "src/ui/tui/screens/SetupScreen.tsx", - "src/ui/tui/screens/SourceMapsDetectScreen.tsx", - "src/ui/tui/screens/SourceMapsIntroScreen.tsx", - "src/ui/tui/screens/SourceMapsOutroScreen.tsx", - "src/ui/tui/screens/TaskNoticeScreen.tsx", - "src/ui/tui/screens/WarehouseIntroScreen.tsx", - "src/ui/tui/screens/WizardAskScreen.tsx", - "src/ui/tui/screens/audit/AuditAreaPane.tsx", - "src/ui/tui/screens/audit/AuditChecksOutroSection.tsx", - "src/ui/tui/screens/audit/AuditIntroScreen.tsx", - "src/ui/tui/screens/audit/AuditOutroScreen.tsx", - "src/ui/tui/screens/audit/AuditRunScreen.tsx", - "src/ui/tui/screens/audit/PendingChecksList.tsx", - "src/ui/tui/screens/audit/slides/events-audit/createDashboard.tsx", - "src/ui/tui/screens/audit/slides/events-audit/detectSdk.tsx", - "src/ui/tui/screens/audit/slides/events-audit/enrichSites.tsx", - "src/ui/tui/screens/audit/slides/events-audit/index.ts", - "src/ui/tui/screens/audit/slides/events-audit/queryVolume.tsx", - "src/ui/tui/screens/audit/slides/events-audit/scanSites.tsx", - "src/ui/tui/screens/audit/slides/events-audit/uploadNotebook.tsx", - "src/ui/tui/screens/audit/slides/events-audit/writeReport.tsx", - "src/ui/tui/screens/doctor/DoctorIntroScreen.tsx", - "src/ui/tui/screens/doctor/DoctorReportScreen.tsx", - "src/ui/tui/screens/health/HealthCheckScreen.tsx", - "src/ui/tui/services/coding-agent-launcher.ts", - "src/ui/tui/services/mcp-installer.ts", - "src/ui/tui/services/mcp-suggested-prompts-services.ts", - "src/ui/tui/start-tui.ts", - "src/utils/clipboard.ts" - ], - "imports": [ - "add-mcp-server-to-clients.js", - "agent-interface.js", - "agent-runner.js", - "analytics.js", - "api.js", - "bin.js", - "bounded-fs.js", - "debug.js", - "defaults.js", - "errors.js", - "mcp-prompt-streaming.js", - "mint-failure.js", - "provisioning.js", - "registry.js", - "setup-utils.js", - "store.js", - "telemetry.js", - "terminal.js", - "wizard-abort.js", - "wizard-session.js", - "yara-hooks.js" - ] - }, - "steps.js": { - "sources": [ - "src/steps/upload-environment-variables/EnvironmentProvider.ts", - "src/steps/upload-environment-variables/index.ts", - "src/steps/upload-environment-variables/providers/vercel.ts" - ], - "imports": ["analytics.js", "debug.js", "telemetry.js"] - }, - "store.js": { - "sources": [ - "src/lib/programs/ai-opt-in-gate.ts", - "src/lib/programs/program-step.ts", - "src/ui/tui/router.ts", - "src/ui/tui/screen-sequences.ts", - "src/ui/tui/store.ts" - ], - "imports": [ - "agent-runner.js", - "analytics.js", - "debug.js", - "mint-failure.js", - "rolldown-runtime.js", - "wizard-session.js" - ] - }, - "subagent.js": { - "sources": ["src/lib/agent/runner/harness/pi/subagent.ts"], - "imports": ["debug.js"] - }, - "task.js": { - "sources": ["src/lib/agent/runner/harness/pi/task.ts"], - "imports": [ - "agent-interface.js", - "agent-prompt-loader.js", - "analytics.js", - "debug.js", - "errors.js", - "gateway-session.js", - "mcp.js", - "orchestrator-tools.js", - "pi.js", - "queue-tools.js", - "security.js", - "tools.js", - "yara-hooks.js" - ] - }, - "task-stream.js": { - "sources": [ - "src/lib/task-stream/audit-areas.ts", - "src/lib/task-stream/event-plan-watcher.ts", - "src/lib/task-stream/task-stream-push.ts" - ], - "imports": [ - "debug.js", - "errors.js", - "file-watcher.js", - "file.js", - "posthog.js" - ] - }, - "tasks.js": { - "sources": ["src/lib/agent/runner/harness/pi/tasks.ts"], - "imports": ["debug.js"] - }, - "telemetry.js": { - "sources": ["src/telemetry.ts", "src/utils/links.ts"], - "imports": ["analytics.js"] - }, - "terminal.js": { - "sources": [ - "src/lib/mcp-project-profile.ts", - "src/lib/mcp-role-prompts.copy.json", - "src/lib/mcp-role-prompts.ts", - "src/lib/mcp-seed-events.ts", - "src/ui/tui/components/LearnCard.tsx", - "src/ui/tui/components/PhaseVisuals.tsx", - "src/ui/tui/components/ServiceHealthList.tsx", - "src/ui/tui/components/TipsCard.tsx", - "src/ui/tui/components/TitleBar.tsx", - "src/ui/tui/components/TokenCostHud.tsx", - "src/ui/tui/components/visualizer/CrateStack.tsx", - "src/ui/tui/components/visualizer/DashboardGrid.tsx", - "src/ui/tui/components/visualizer/DiffCascade.tsx", - "src/ui/tui/components/visualizer/LibraryShelf.tsx", - "src/ui/tui/components/visualizer/MatrixRain.tsx", - "src/ui/tui/components/visualizer/Tumblers.tsx", - "src/ui/tui/components/visualizer/grid.ts", - "src/ui/tui/components/visualizer/palette.ts", - "src/ui/tui/components/visualizer/panel.tsx", - "src/ui/tui/hooks/useDismissOnAnyKey.ts", - "src/ui/tui/hooks/useTick.ts", - "src/ui/tui/primitives/CardLayout.tsx", - "src/ui/tui/primitives/ConfirmationInput.tsx", - "src/ui/tui/primitives/ContentSequencer.tsx", - "src/ui/tui/primitives/DissolveTransition.tsx", - "src/ui/tui/primitives/Divider.tsx", - "src/ui/tui/primitives/EventPlanViewer.tsx", - "src/ui/tui/primitives/GroupedPickerMenu.tsx", - "src/ui/tui/primitives/HNViewer.tsx", - "src/ui/tui/primitives/KeyboardHintsBar.tsx", - "src/ui/tui/primitives/LinesBlock.tsx", - "src/ui/tui/primitives/LinkText.tsx", - "src/ui/tui/primitives/LoadingBox.tsx", - "src/ui/tui/primitives/LogViewer.tsx", - "src/ui/tui/primitives/ModalOverlay.tsx", - "src/ui/tui/primitives/NodeBlock.tsx", - "src/ui/tui/primitives/ProgressList.tsx", - "src/ui/tui/primitives/ScreenContainer.tsx", - "src/ui/tui/primitives/ScreenErrorBoundary.tsx", - "src/ui/tui/primitives/SplitView.tsx", - "src/ui/tui/primitives/TabContainer.tsx", - "src/ui/tui/primitives/ViewportTooSmall.tsx", - "src/ui/tui/primitives/link-helpers.ts", - "src/ui/tui/screens/AiOptInRequiredScreen.tsx", - "src/ui/tui/screens/McpScreen.tsx", - "src/ui/tui/screens/McpSuggestedPromptsScreen.tsx", - "src/ui/tui/screens/OutroScreen.tsx", - "src/ui/tui/screens/SkillSourceInfo.tsx", - "src/ui/tui/screens/SlackConnectScreen.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/AreaHeaderRow.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/AuditChecksViewer.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/CheckRow.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/DetailRow.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/Footer.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/Header.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/Legend.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/layout.ts", - "src/ui/tui/screens/audit/AuditChecksViewer/sort.ts", - "src/ui/tui/screens/audit/slides/eventCapture.tsx", - "src/ui/tui/screens/audit/slides/identification.tsx", - "src/ui/tui/screens/audit/slides/index.ts", - "src/ui/tui/screens/audit/slides/installation.tsx", - "src/ui/tui/screens/audit/slides/liveData.tsx", - "src/ui/tui/screens/audit/slides/shared.tsx", - "src/ui/tui/screens/audit/slides/uploadNotebook.tsx", - "src/ui/tui/screens/audit/slides/writeReport.tsx", - "src/ui/tui/screens/doctor/IssueTable.tsx", - "src/ui/tui/terminal.ts" - ], - "imports": [ - "agent-interface.js", - "agent-runner.js", - "analytics.js", - "api.js", - "bin.js", - "debug.js", - "defaults.js", - "mint-failure.js", - "setup-utils.js", - "store.js", - "telemetry.js", - "yara-hooks.js" - ] - }, - "tools.js": { - "sources": ["src/lib/agent/runner/harness/pi/tools.ts"], - "imports": [ - "agent-interface.js", - "analytics.js", - "debug.js", - "package-manager.js", - "pi.js", - "queue-tools.js", - "yara-hooks.js" - ] - }, - "wizard-abort.js": { - "sources": [], - "imports": ["wizard-abort.js"] - }, - "wizard-session.js": { - "sources": ["src/lib/wizard-session.ts"], - "imports": ["local-dev.js"] - }, - "yara-hooks.js": { - "sources": [ - "src/lib/programs/audit/types.ts", - "src/lib/programs/events-audit/constants.ts", - "src/lib/programs/posthog-integration/constants.ts", - "src/lib/skill-install.ts", - "src/lib/yara-hooks.ts", - "src/lib/yara-policy.ts" - ], - "imports": ["analytics.js", "bounded-fs.js", "debug.js"] - } + "chunks": [ + "add-mcp-server-to-clients.js", + "agent-interface.js", + "agent-prompt-loader.js", + "agent-runner.js", + "analytics.js", + "api.js", + "bin.js", + "bounded-fs.js", + "ci-install.js", + "debug.js", + "defaults.js", + "env-api-key.js", + "environment.js", + "errors.js", + "file-watcher.js", + "file.js", + "gateway-session.js", + "headless-ui.js", + "interactive.js", + "local-dev.js", + "mcp-prompt-streaming.js", + "mcp.js", + "mint-failure.js", + "non-interactive.js", + "orchestrator-tools.js", + "package-json.js", + "package-manager.js", + "pi.js", + "playground.js", + "posthog.js", + "provisioning.js", + "queue-tools.js", + "registry.js", + "rolldown-runtime.js", + "security.js", + "setup-utils.js", + "start-tui.js", + "steps.js", + "store.js", + "subagent.js", + "task-stream.js", + "task.js", + "tasks.js", + "telemetry.js", + "terminal.js", + "tools.js", + "wizard-abort.js", + "wizard-session.js", + "yara-hooks.js" + ], + "sources": [ + "bin.ts", + "src/commands/ai-observability.ts", + "src/commands/audit.ts", + "src/commands/basic-integration/ci-install.ts", + "src/commands/basic-integration/index.ts", + "src/commands/basic-integration/interactive.ts", + "src/commands/basic-integration/non-interactive.ts", + "src/commands/basic-integration/playground.ts", + "src/commands/basic-integration/skill.ts", + "src/commands/cli/add.ts", + "src/commands/cli/index.ts", + "src/commands/command.ts", + "src/commands/doctor.ts", + "src/commands/error-tracking.ts", + "src/commands/factories/family-command-factory.ts", + "src/commands/factories/family-picker.tsx", + "src/commands/factories/native-command-factory.ts", + "src/commands/factories/shared.ts", + "src/commands/mcp-analytics.ts", + "src/commands/mcp/add.ts", + "src/commands/mcp/index.ts", + "src/commands/mcp/remove.ts", + "src/commands/mcp/tui-availability.ts", + "src/commands/mcp/tutorial.ts", + "src/commands/metrics.ts", + "src/commands/migrate.ts", + "src/commands/provision.ts", + "src/commands/replay-vision.ts", + "src/commands/revenue.ts", + "src/commands/self-driving.ts", + "src/commands/skill-program-options.ts", + "src/commands/skill.ts", + "src/commands/slack.ts", + "src/commands/upload-sourcemaps.ts", + "src/commands/warehouse.ts", + "src/env.ts", + "src/frameworks/android/android-wizard-agent.ts", + "src/frameworks/android/utils.ts", + "src/frameworks/angular/angular-wizard-agent.ts", + "src/frameworks/angular/utils.ts", + "src/frameworks/astro/astro-wizard-agent.ts", + "src/frameworks/astro/utils.ts", + "src/frameworks/django/django-wizard-agent.ts", + "src/frameworks/django/utils.ts", + "src/frameworks/elixir/elixir-wizard-agent.ts", + "src/frameworks/fastapi/fastapi-wizard-agent.ts", + "src/frameworks/fastapi/utils.ts", + "src/frameworks/flask/flask-wizard-agent.ts", + "src/frameworks/flask/utils.ts", + "src/frameworks/flutter/flutter-wizard-agent.ts", + "src/frameworks/go/go-wizard-agent.ts", + "src/frameworks/java/java-wizard-agent.ts", + "src/frameworks/javascript-node/javascript-node-wizard-agent.ts", + "src/frameworks/javascript-web/javascript-web-wizard-agent.ts", + "src/frameworks/javascript-web/utils.ts", + "src/frameworks/kmp/kmp-wizard-agent.ts", + "src/frameworks/laravel/laravel-wizard-agent.ts", + "src/frameworks/laravel/utils.ts", + "src/frameworks/nextjs/nextjs-wizard-agent.ts", + "src/frameworks/nextjs/utils.ts", + "src/frameworks/nuxt/nuxt-wizard-agent.ts", + "src/frameworks/python/python-wizard-agent.ts", + "src/frameworks/python/utils.ts", + "src/frameworks/rails/rails-wizard-agent.ts", + "src/frameworks/rails/utils.ts", + "src/frameworks/react-native/react-native-wizard-agent.ts", + "src/frameworks/react-native/utils.ts", + "src/frameworks/react-router/react-router-wizard-agent.ts", + "src/frameworks/react-router/utils.ts", + "src/frameworks/ruby/ruby-wizard-agent.ts", + "src/frameworks/ruby/utils.ts", + "src/frameworks/rust/rust-wizard-agent.ts", + "src/frameworks/svelte/svelte-wizard-agent.ts", + "src/frameworks/swift/swift-wizard-agent.ts", + "src/frameworks/swift/utils.ts", + "src/frameworks/tanstack-router/tanstack-router-wizard-agent.ts", + "src/frameworks/tanstack-router/utils.ts", + "src/frameworks/tanstack-start/tanstack-start-wizard-agent.ts", + "src/frameworks/tanstack-start/utils.ts", + "src/frameworks/vue/vue-wizard-agent.ts", + "src/lib/agent/agent-env-isolation.ts", + "src/lib/agent/agent-interface.ts", + "src/lib/agent/agent-phase.ts", + "src/lib/agent/agent-prompt-loader.ts", + "src/lib/agent/agent-prompt.ts", + "src/lib/agent/agent-runner.ts", + "src/lib/agent/aio-capture.ts", + "src/lib/agent/bash-fence.ts", + "src/lib/agent/claude-settings.ts", + "src/lib/agent/commandments.ts", + "src/lib/agent/mcp-prompt-streaming.ts", + "src/lib/agent/output-signals.ts", + "src/lib/agent/runner/harness/anthropic/index.ts", + "src/lib/agent/runner/harness/pi/completion.ts", + "src/lib/agent/runner/harness/pi/gateway.ts", + "src/lib/agent/runner/harness/pi/index.ts", + "src/lib/agent/runner/harness/pi/mcp.ts", + "src/lib/agent/runner/harness/pi/orchestrator-tools.ts", + "src/lib/agent/runner/harness/pi/runtime-notes.ts", + "src/lib/agent/runner/harness/pi/security.ts", + "src/lib/agent/runner/harness/pi/subagent.ts", + "src/lib/agent/runner/harness/pi/task.ts", + "src/lib/agent/runner/harness/pi/tasks.ts", + "src/lib/agent/runner/harness/pi/tools.ts", + "src/lib/agent/runner/index.ts", + "src/lib/agent/runner/sequence/linear.ts", + "src/lib/agent/runner/sequence/orchestrator/executor.ts", + "src/lib/agent/runner/sequence/orchestrator/orchestrator-runner.ts", + "src/lib/agent/runner/sequence/orchestrator/queue-tools.ts", + "src/lib/agent/runner/sequence/orchestrator/queue.ts", + "src/lib/agent/runner/sequence/orchestrator/run-metrics.ts", + "src/lib/agent/runner/sequence/orchestrator/seeded-deps.ts", + "src/lib/agent/runner/shared/authenticate.ts", + "src/lib/agent/runner/shared/bootstrap.ts", + "src/lib/agent/runner/shared/errors.ts", + "src/lib/agent/runner/switchboard/commandments.ts", + "src/lib/agent/runner/switchboard/flags/index.ts", + "src/lib/agent/runner/switchboard/flags/orchestrator.ts", + "src/lib/agent/runner/switchboard/flags/schemes.ts", + "src/lib/agent/runner/switchboard/flags/self-driving.ts", + "src/lib/agent/runner/switchboard/harness.ts", + "src/lib/agent/runner/switchboard/index.ts", + "src/lib/agent/runner/switchboard/models.ts", + "src/lib/agent/runner/switchboard/sequence.ts", + "src/lib/agent/signals.ts", + "src/lib/agent/stored-login.ts", + "src/lib/agent/token-pricing.ts", + "src/lib/agent/triage-provider.ts", + "src/lib/api.ts", + "src/lib/auth-session-state.ts", + "src/lib/constants.ts", + "src/lib/detection/agentic.ts", + "src/lib/detection/context.ts", + "src/lib/detection/features.ts", + "src/lib/detection/framework.ts", + "src/lib/detection/package-manager.ts", + "src/lib/detection/project-scope.ts", + "src/lib/errors/agent-map.ts", + "src/lib/errors/auth.ts", + "src/lib/errors/catalog.ts", + "src/lib/errors/codes.ts", + "src/lib/errors/detect-map.ts", + "src/lib/errors/emit.ts", + "src/lib/errors/run-failure.ts", + "src/lib/errors/sanitize.ts", + "src/lib/errors/skill-map.ts", + "src/lib/fetch-retry.ts", + "src/lib/file-watcher.ts", + "src/lib/framework-config.ts", + "src/lib/headless-mode.ts", + "src/lib/health-checks/endpoints.ts", + "src/lib/health-checks/readiness.ts", + "src/lib/host-resolution.ts", + "src/lib/local-dev.ts", + "src/lib/mcp-project-profile.ts", + "src/lib/mcp-role-prompts.copy.json", + "src/lib/mcp-role-prompts.ts", + "src/lib/mcp-seed-events.ts", + "src/lib/middleware/benchmark.ts", + "src/lib/middleware/benchmarks/cache-tracker.ts", + "src/lib/middleware/benchmarks/compaction-tracker.ts", + "src/lib/middleware/benchmarks/context-size-tracker.ts", + "src/lib/middleware/benchmarks/cost-tracker.ts", + "src/lib/middleware/benchmarks/duration-tracker.ts", + "src/lib/middleware/benchmarks/index.ts", + "src/lib/middleware/benchmarks/json-writer.ts", + "src/lib/middleware/benchmarks/summary.ts", + "src/lib/middleware/benchmarks/token-tracker.ts", + "src/lib/middleware/benchmarks/turn-counter.ts", + "src/lib/middleware/config.ts", + "src/lib/middleware/phase-detector.ts", + "src/lib/middleware/pipeline.ts", + "src/lib/oauth/program-scopes.ts", + "src/lib/programs/agent-skill/content/index.tsx", + "src/lib/programs/agent-skill/index.ts", + "src/lib/programs/agent-skill/steps.ts", + "src/lib/programs/ai-observability/index.ts", + "src/lib/programs/ai-opt-in-gate.ts", + "src/lib/programs/audit/detect.ts", + "src/lib/programs/audit/index.ts", + "src/lib/programs/audit/ledger-watcher.ts", + "src/lib/programs/audit/seed.ts", + "src/lib/programs/audit/types.ts", + "src/lib/programs/dispatch-family.ts", + "src/lib/programs/error-tracking-upload-source-maps/content/index.tsx", + "src/lib/programs/error-tracking-upload-source-maps/detect-agentic.ts", + "src/lib/programs/error-tracking-upload-source-maps/detect.ts", + "src/lib/programs/error-tracking-upload-source-maps/index.ts", + "src/lib/programs/error-tracking-upload-source-maps/prompt.ts", + "src/lib/programs/error-tracking-upload-source-maps/steps.ts", + "src/lib/programs/error-tracking/content/index.tsx", + "src/lib/programs/error-tracking/content/tips.ts", + "src/lib/programs/error-tracking/detect-agentic.ts", + "src/lib/programs/error-tracking/index.ts", + "src/lib/programs/events-audit/constants.ts", + "src/lib/programs/events-audit/index.ts", + "src/lib/programs/events-audit/seed.ts", + "src/lib/programs/events-audit/steps.ts", + "src/lib/programs/mcp-analytics/index.ts", + "src/lib/programs/mcp/index.ts", + "src/lib/programs/metrics/index.ts", + "src/lib/programs/migration/content/free-tier.tsx", + "src/lib/programs/migration/content/index.tsx", + "src/lib/programs/migration/content/pricing-structure.tsx", + "src/lib/programs/migration/content/vendor-stack.tsx", + "src/lib/programs/migration/index.ts", + "src/lib/programs/migration/steps.ts", + "src/lib/programs/posthog-doctor/fetch.ts", + "src/lib/programs/posthog-doctor/index.ts", + "src/lib/programs/posthog-doctor/kind-metadata.ts", + "src/lib/programs/posthog-doctor/steps.ts", + "src/lib/programs/posthog-doctor/types.ts", + "src/lib/programs/posthog-integration/constants.ts", + "src/lib/programs/posthog-integration/content/data-flow.tsx", + "src/lib/programs/posthog-integration/content/funnel.tsx", + "src/lib/programs/posthog-integration/content/index.tsx", + "src/lib/programs/posthog-integration/content/line-chart.tsx", + "src/lib/programs/posthog-integration/content/product-suite.tsx", + "src/lib/programs/posthog-integration/detect.ts", + "src/lib/programs/posthog-integration/handoff.ts", + "src/lib/programs/posthog-integration/index.ts", + "src/lib/programs/posthog-integration/steps.ts", + "src/lib/programs/program-registry.ts", + "src/lib/programs/program-step.ts", + "src/lib/programs/replay-vision/index.ts", + "src/lib/programs/revenue-analytics/detect.ts", + "src/lib/programs/revenue-analytics/index.ts", + "src/lib/programs/revenue-analytics/steps.ts", + "src/lib/programs/self-driving/content/index.tsx", + "src/lib/programs/self-driving/content/pipeline-diagram.tsx", + "src/lib/programs/self-driving/content/pricing.ts", + "src/lib/programs/self-driving/content/tips.ts", + "src/lib/programs/self-driving/detect-agentic.ts", + "src/lib/programs/self-driving/detect.ts", + "src/lib/programs/self-driving/index.ts", + "src/lib/programs/self-driving/prompt.ts", + "src/lib/programs/self-driving/step-keys.ts", + "src/lib/programs/self-driving/steps.ts", + "src/lib/programs/shared/health-check-step.ts", + "src/lib/programs/shared/package-scanning.ts", + "src/lib/programs/shared/posthog-cli-preinstall.ts", + "src/lib/programs/slack/index.ts", + "src/lib/programs/warehouse-source/detect.ts", + "src/lib/programs/warehouse-source/index.ts", + "src/lib/programs/warehouse-source/steps.ts", + "src/lib/programs/web-analytics-doctor/detect.ts", + "src/lib/programs/web-analytics-doctor/index.ts", + "src/lib/programs/web-analytics-doctor/steps.ts", + "src/lib/registry.ts", + "src/lib/runners/resolve-no-telemetry.ts", + "src/lib/runners/run-non-interactive.ts", + "src/lib/runners/run-wizard-ci.ts", + "src/lib/runners/run-wizard-headless.ts", + "src/lib/runners/run-wizard.ts", + "src/lib/safe-tools.ts", + "src/lib/secret-vault.ts", + "src/lib/skill-install.ts", + "src/lib/task-stream/audit-areas.ts", + "src/lib/task-stream/destinations/file.ts", + "src/lib/task-stream/destinations/posthog.ts", + "src/lib/task-stream/event-plan-watcher.ts", + "src/lib/task-stream/task-stream-push.ts", + "src/lib/version.ts", + "src/lib/warehouse-sources/detect.ts", + "src/lib/warehouse-sources/registry.ts", + "src/lib/wizard-ask-bridge.ts", + "src/lib/wizard-session.ts", + "src/lib/wizard-spellbook.ts", + "src/lib/wizard-tools/handoff.ts", + "src/lib/wizard-tools/mcp.ts", + "src/lib/wizard-tools/tools.ts", + "src/lib/yara-hooks.ts", + "src/lib/yara-policy.ts", + "src/steps/add-mcp-server-to-clients/MCPClient.ts", + "src/steps/add-mcp-server-to-clients/browser-client.ts", + "src/steps/add-mcp-server-to-clients/clients/claude-code.ts", + "src/steps/add-mcp-server-to-clients/clients/claude-web.ts", + "src/steps/add-mcp-server-to-clients/clients/codex.ts", + "src/steps/add-mcp-server-to-clients/clients/cursor.ts", + "src/steps/add-mcp-server-to-clients/clients/opencode.ts", + "src/steps/add-mcp-server-to-clients/clients/visual-studio-code.ts", + "src/steps/add-mcp-server-to-clients/clients/zed.ts", + "src/steps/add-mcp-server-to-clients/defaults.ts", + "src/steps/add-mcp-server-to-clients/index.ts", + "src/steps/add-mcp-server-to-clients/login-client.ts", + "src/steps/add-mcp-server-to-clients/plugin-client.ts", + "src/steps/add-mcp-server-to-clients/results.ts", + "src/steps/install-cli-steering/index.ts", + "src/steps/upload-environment-variables/EnvironmentProvider.ts", + "src/steps/upload-environment-variables/index.ts", + "src/steps/upload-environment-variables/providers/vercel.ts", + "src/telemetry.ts", + "src/ui/headless-ui.ts", + "src/ui/index.ts", + "src/ui/logging-ui.ts", + "src/ui/mint-failure.ts", + "src/ui/tui/App.tsx", + "src/ui/tui/components/LearnCard.tsx", + "src/ui/tui/components/PhaseVisuals.tsx", + "src/ui/tui/components/PrivacyPanel.tsx", + "src/ui/tui/components/ServiceHealthList.tsx", + "src/ui/tui/components/StatusPeekTrigger.tsx", + "src/ui/tui/components/TipsCard.tsx", + "src/ui/tui/components/TitleBar.tsx", + "src/ui/tui/components/TokenCostHud.tsx", + "src/ui/tui/components/visualizer/CrateStack.tsx", + "src/ui/tui/components/visualizer/DashboardGrid.tsx", + "src/ui/tui/components/visualizer/DiffCascade.tsx", + "src/ui/tui/components/visualizer/LibraryShelf.tsx", + "src/ui/tui/components/visualizer/MatrixRain.tsx", + "src/ui/tui/components/visualizer/Tumblers.tsx", + "src/ui/tui/components/visualizer/grid.ts", + "src/ui/tui/components/visualizer/palette.ts", + "src/ui/tui/components/visualizer/panel.tsx", + "src/ui/tui/exit-line.ts", + "src/ui/tui/hooks/keyboard-hints-utils.ts", + "src/ui/tui/hooks/useDismissOnAnyKey.ts", + "src/ui/tui/hooks/useGithubConnection.ts", + "src/ui/tui/hooks/useKeyBindings.ts", + "src/ui/tui/hooks/useKeyboardHints.tsx", + "src/ui/tui/hooks/useStdoutDimensions.ts", + "src/ui/tui/hooks/useTick.ts", + "src/ui/tui/ink-ui.ts", + "src/ui/tui/playground/PlaygroundApp.tsx", + "src/ui/tui/playground/demos/AiOptInDemo.tsx", + "src/ui/tui/playground/demos/AskModalDemo.tsx", + "src/ui/tui/playground/demos/AuditChecksDemo.tsx", + "src/ui/tui/playground/demos/DoctorReportDemo.tsx", + "src/ui/tui/playground/demos/EndScreensDemo.tsx", + "src/ui/tui/playground/demos/HealthCheckDemo.tsx", + "src/ui/tui/playground/demos/InputDemo.tsx", + "src/ui/tui/playground/demos/KeyboardHintsDemo.tsx", + "src/ui/tui/playground/demos/LayoutDemo.tsx", + "src/ui/tui/playground/demos/LearnDeckDemo.tsx", + "src/ui/tui/playground/demos/LogDemo.tsx", + "src/ui/tui/playground/demos/McpDemo.tsx", + "src/ui/tui/playground/demos/McpSuggestedPromptsDemo.tsx", + "src/ui/tui/playground/demos/ModalDemo.tsx", + "src/ui/tui/playground/demos/ProgressDemo.tsx", + "src/ui/tui/playground/demos/RunScreenDemo.tsx", + "src/ui/tui/playground/demos/ViewportGuardDemo.tsx", + "src/ui/tui/playground/demos/WelcomeDemo.tsx", + "src/ui/tui/playground/start-playground.ts", + "src/ui/tui/posthog-integration-intro.ts", + "src/ui/tui/primitives/CardLayout.tsx", + "src/ui/tui/primitives/ConfirmButton.tsx", + "src/ui/tui/primitives/ConfirmationInput.tsx", + "src/ui/tui/primitives/ContentSequencer.tsx", + "src/ui/tui/primitives/DissolveTransition.tsx", + "src/ui/tui/primitives/Divider.tsx", + "src/ui/tui/primitives/EventPlanViewer.tsx", + "src/ui/tui/primitives/GroupedPickerMenu.tsx", + "src/ui/tui/primitives/HNViewer.tsx", + "src/ui/tui/primitives/KeyboardHintsBar.tsx", + "src/ui/tui/primitives/LinesBlock.tsx", + "src/ui/tui/primitives/LinkText.tsx", + "src/ui/tui/primitives/LoadingBox.tsx", + "src/ui/tui/primitives/LogViewer.tsx", + "src/ui/tui/primitives/ModalOverlay.tsx", + "src/ui/tui/primitives/NodeBlock.tsx", + "src/ui/tui/primitives/PickerMenu.tsx", + "src/ui/tui/primitives/ProgressList.tsx", + "src/ui/tui/primitives/PromptLabel.tsx", + "src/ui/tui/primitives/ScreenContainer.tsx", + "src/ui/tui/primitives/ScreenErrorBoundary.tsx", + "src/ui/tui/primitives/SplitView.tsx", + "src/ui/tui/primitives/TabContainer.tsx", + "src/ui/tui/primitives/TextBlock.tsx", + "src/ui/tui/primitives/ViewportTooSmall.tsx", + "src/ui/tui/primitives/content-types.ts", + "src/ui/tui/primitives/layout-helpers.ts", + "src/ui/tui/primitives/link-helpers.ts", + "src/ui/tui/primitives/picker-filter.ts", + "src/ui/tui/primitives/text-helpers.ts", + "src/ui/tui/router.ts", + "src/ui/tui/screen-registry.tsx", + "src/ui/tui/screen-sequences.ts", + "src/ui/tui/screens/AgentSkillIntroScreen.tsx", + "src/ui/tui/screens/AiObservabilityIntroScreen.tsx", + "src/ui/tui/screens/AiOptInRequiredScreen.tsx", + "src/ui/tui/screens/AuthErrorScreen.tsx", + "src/ui/tui/screens/AuthScreen.tsx", + "src/ui/tui/screens/ErrorTrackingDetectScreen.tsx", + "src/ui/tui/screens/ErrorTrackingIntroScreen.tsx", + "src/ui/tui/screens/ExitScreen.tsx", + "src/ui/tui/screens/IntroScreenLayout.tsx", + "src/ui/tui/screens/KeepSkillsScreen.tsx", + "src/ui/tui/screens/ManagedSettingsScreen.tsx", + "src/ui/tui/screens/ManualAuthCodeScreen.tsx", + "src/ui/tui/screens/McpScreen.tsx", + "src/ui/tui/screens/McpSuggestedPromptsScreen.tsx", + "src/ui/tui/screens/MetricsIntroScreen.tsx", + "src/ui/tui/screens/MigrationIntroScreen.tsx", + "src/ui/tui/screens/MintFailureScreen.tsx", + "src/ui/tui/screens/OutroScreen.tsx", + "src/ui/tui/screens/PortConflictScreen.tsx", + "src/ui/tui/screens/PostHogIntegrationIntroScreen.tsx", + "src/ui/tui/screens/RevenueIntroScreen.tsx", + "src/ui/tui/screens/RunScreen.tsx", + "src/ui/tui/screens/SelfDrivingGitHubScreen.tsx", + "src/ui/tui/screens/SelfDrivingHandoffScreen.tsx", + "src/ui/tui/screens/SelfDrivingIntegrationCheckScreen.tsx", + "src/ui/tui/screens/SelfDrivingIntegrationDetectScreen.tsx", + "src/ui/tui/screens/SelfDrivingIntroScreen.tsx", + "src/ui/tui/screens/SessionTimeoutScreen.tsx", + "src/ui/tui/screens/SettingsOverrideScreen.tsx", + "src/ui/tui/screens/SetupScreen.tsx", + "src/ui/tui/screens/SkillSourceInfo.tsx", + "src/ui/tui/screens/SlackConnectScreen.tsx", + "src/ui/tui/screens/SourceMapsDetectScreen.tsx", + "src/ui/tui/screens/SourceMapsIntroScreen.tsx", + "src/ui/tui/screens/SourceMapsOutroScreen.tsx", + "src/ui/tui/screens/TaskNoticeScreen.tsx", + "src/ui/tui/screens/WarehouseIntroScreen.tsx", + "src/ui/tui/screens/WizardAskScreen.tsx", + "src/ui/tui/screens/audit/AuditAreaPane.tsx", + "src/ui/tui/screens/audit/AuditChecksOutroSection.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/AreaHeaderRow.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/AuditChecksViewer.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/CheckRow.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/DetailRow.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/Footer.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/Header.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/Legend.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/layout.ts", + "src/ui/tui/screens/audit/AuditChecksViewer/sort.ts", + "src/ui/tui/screens/audit/AuditIntroScreen.tsx", + "src/ui/tui/screens/audit/AuditOutroScreen.tsx", + "src/ui/tui/screens/audit/AuditRunScreen.tsx", + "src/ui/tui/screens/audit/PendingChecksList.tsx", + "src/ui/tui/screens/audit/slides/eventCapture.tsx", + "src/ui/tui/screens/audit/slides/events-audit/createDashboard.tsx", + "src/ui/tui/screens/audit/slides/events-audit/detectSdk.tsx", + "src/ui/tui/screens/audit/slides/events-audit/enrichSites.tsx", + "src/ui/tui/screens/audit/slides/events-audit/index.ts", + "src/ui/tui/screens/audit/slides/events-audit/queryVolume.tsx", + "src/ui/tui/screens/audit/slides/events-audit/scanSites.tsx", + "src/ui/tui/screens/audit/slides/events-audit/uploadNotebook.tsx", + "src/ui/tui/screens/audit/slides/events-audit/writeReport.tsx", + "src/ui/tui/screens/audit/slides/identification.tsx", + "src/ui/tui/screens/audit/slides/index.ts", + "src/ui/tui/screens/audit/slides/installation.tsx", + "src/ui/tui/screens/audit/slides/liveData.tsx", + "src/ui/tui/screens/audit/slides/shared.tsx", + "src/ui/tui/screens/audit/slides/uploadNotebook.tsx", + "src/ui/tui/screens/audit/slides/writeReport.tsx", + "src/ui/tui/screens/doctor/DoctorIntroScreen.tsx", + "src/ui/tui/screens/doctor/DoctorReportScreen.tsx", + "src/ui/tui/screens/doctor/IssueTable.tsx", + "src/ui/tui/screens/health/HealthCheckScreen.tsx", + "src/ui/tui/services/coding-agent-launcher.ts", + "src/ui/tui/services/mcp-installer.ts", + "src/ui/tui/services/mcp-suggested-prompts-services.ts", + "src/ui/tui/start-tui.ts", + "src/ui/tui/store.ts", + "src/ui/tui/styles.ts", + "src/ui/tui/terminal.ts", + "src/ui/wizard-ui.ts", + "src/utils/analytics.ts", + "src/utils/atomic-ledger.ts", + "src/utils/bounded-fs.ts", + "src/utils/ci-flag-overrides.ts", + "src/utils/clipboard.ts", + "src/utils/custom-headers.ts", + "src/utils/debug.ts", + "src/utils/env-api-key.ts", + "src/utils/env-scan.ts", + "src/utils/environment.ts", + "src/utils/links.ts", + "src/utils/oauth-errors.ts", + "src/utils/oauth.ts", + "src/utils/package-json.ts", + "src/utils/package-manager.ts", + "src/utils/paths.ts", + "src/utils/project-resolution.ts", + "src/utils/provisioning.ts", + "src/utils/semver.ts", + "src/utils/setup-utils.ts", + "src/utils/terminal-bell.ts", + "src/utils/urls.ts", + "src/wizard.ts" + ] } diff --git a/scripts/__fixtures__/chunk-manifest.prod.json b/scripts/__fixtures__/chunk-manifest.prod.json index 48605e7f7..345100dcd 100644 --- a/scripts/__fixtures__/chunk-manifest.prod.json +++ b/scripts/__fixtures__/chunk-manifest.prod.json @@ -1,880 +1,535 @@ { - "add-mcp-server-to-clients.js": { - "sources": [ - "src/steps/add-mcp-server-to-clients/MCPClient.ts", - "src/steps/add-mcp-server-to-clients/clients/claude-code.ts", - "src/steps/add-mcp-server-to-clients/clients/claude-web.ts", - "src/steps/add-mcp-server-to-clients/clients/codex.ts", - "src/steps/add-mcp-server-to-clients/clients/cursor.ts", - "src/steps/add-mcp-server-to-clients/clients/opencode.ts", - "src/steps/add-mcp-server-to-clients/clients/visual-studio-code.ts", - "src/steps/add-mcp-server-to-clients/clients/zed.ts", - "src/steps/add-mcp-server-to-clients/index.ts", - "src/steps/add-mcp-server-to-clients/plugin-client.ts" - ], - "imports": [ - "analytics.js", - "debug.js", - "defaults.js", - "rolldown-runtime.js", - "telemetry.js" - ] - }, - "agent-interface.js": { - "sources": [ - "src/lib/agent/agent-env-isolation.ts", - "src/lib/agent/agent-interface.ts", - "src/lib/agent/agent-phase.ts", - "src/lib/agent/bash-fence.ts", - "src/lib/agent/claude-settings.ts", - "src/lib/agent/commandments.ts", - "src/lib/agent/output-signals.ts", - "src/lib/agent/runner/harness/pi/gateway.ts", - "src/lib/agent/runner/harness/pi/runtime-notes.ts", - "src/lib/agent/runner/switchboard/commandments.ts", - "src/lib/agent/stored-login.ts", - "src/lib/agent/triage-provider.ts", - "src/lib/auth-session-state.ts", - "src/lib/fetch-retry.ts", - "src/lib/safe-tools.ts", - "src/lib/secret-vault.ts", - "src/lib/wizard-ask-bridge.ts", - "src/lib/wizard-tools/handoff.ts", - "src/lib/wizard-tools/mcp.ts", - "src/lib/wizard-tools/tools.ts", - "src/utils/custom-headers.ts", - "src/utils/env-scan.ts" - ], - "imports": [ - "analytics.js", - "bounded-fs.js", - "debug.js", - "errors.js", - "gateway-session.js", - "queue-tools.js", - "rolldown-runtime.js", - "wizard-abort.js", - "wizard-session.js", - "yara-hooks.js" - ] - }, - "agent-prompt-loader.js": { - "sources": ["src/lib/agent/agent-prompt-loader.ts"], - "imports": [ - "agent-interface.js", - "analytics.js", - "debug.js", - "queue-tools.js" - ] - }, - "agent-runner.js": { - "sources": [ - "src/lib/agent/agent-prompt.ts", - "src/lib/agent/agent-runner.ts", - "src/lib/agent/runner/harness/anthropic/index.ts", - "src/lib/agent/runner/index.ts", - "src/lib/agent/runner/sequence/linear.ts", - "src/lib/agent/runner/sequence/orchestrator/executor.ts", - "src/lib/agent/runner/sequence/orchestrator/orchestrator-runner.ts", - "src/lib/agent/runner/sequence/orchestrator/run-metrics.ts", - "src/lib/agent/runner/sequence/orchestrator/seeded-deps.ts", - "src/lib/agent/runner/shared/authenticate.ts", - "src/lib/agent/runner/shared/bootstrap.ts", - "src/lib/agent/runner/shared/errors.ts", - "src/lib/agent/runner/switchboard/flags/index.ts", - "src/lib/agent/runner/switchboard/flags/orchestrator.ts", - "src/lib/agent/runner/switchboard/flags/schemes.ts", - "src/lib/agent/runner/switchboard/flags/self-driving.ts", - "src/lib/agent/runner/switchboard/harness.ts", - "src/lib/agent/runner/switchboard/index.ts", - "src/lib/agent/runner/switchboard/sequence.ts", - "src/lib/agent/token-pricing.ts", - "src/lib/detection/agentic.ts", - "src/lib/detection/context.ts", - "src/lib/detection/features.ts", - "src/lib/detection/framework.ts", - "src/lib/middleware/benchmark.ts", - "src/lib/middleware/benchmarks/cache-tracker.ts", - "src/lib/middleware/benchmarks/compaction-tracker.ts", - "src/lib/middleware/benchmarks/context-size-tracker.ts", - "src/lib/middleware/benchmarks/cost-tracker.ts", - "src/lib/middleware/benchmarks/duration-tracker.ts", - "src/lib/middleware/benchmarks/index.ts", - "src/lib/middleware/benchmarks/json-writer.ts", - "src/lib/middleware/benchmarks/summary.ts", - "src/lib/middleware/benchmarks/token-tracker.ts", - "src/lib/middleware/benchmarks/turn-counter.ts", - "src/lib/middleware/config.ts", - "src/lib/middleware/phase-detector.ts", - "src/lib/middleware/pipeline.ts", - "src/lib/programs/audit/ledger-watcher.ts", - "src/lib/programs/posthog-integration/detect.ts", - "src/lib/programs/shared/package-scanning.ts", - "src/lib/programs/warehouse-source/detect.ts", - "src/lib/warehouse-sources/detect.ts", - "src/lib/warehouse-sources/registry.ts", - "src/utils/terminal-bell.ts" - ], - "imports": [ - "agent-interface.js", - "agent-prompt-loader.js", - "analytics.js", - "bounded-fs.js", - "debug.js", - "environment.js", - "errors.js", - "file-watcher.js", - "gateway-session.js", - "package-manager.js", - "pi.js", - "queue-tools.js", - "registry.js", - "rolldown-runtime.js", - "setup-utils.js", - "wizard-abort.js", - "wizard-session.js", - "yara-hooks.js" - ] - }, - "analytics.js": { - "sources": [], - "imports": ["analytics.js"] - }, - "api.js": { - "sources": ["src/lib/api.ts"], - "imports": ["analytics.js", "debug.js", "rolldown-runtime.js"] - }, - "bin.js": { - "sources": [ - "bin.ts", - "src/commands/ai-observability.ts", - "src/commands/audit.ts", - "src/commands/basic-integration/index.ts", - "src/commands/basic-integration/skill.ts", - "src/commands/cli/add.ts", - "src/commands/cli/index.ts", - "src/commands/command.ts", - "src/commands/doctor.ts", - "src/commands/error-tracking.ts", - "src/commands/factories/family-command-factory.ts", - "src/commands/factories/family-picker.tsx", - "src/commands/factories/native-command-factory.ts", - "src/commands/factories/shared.ts", - "src/commands/mcp-analytics.ts", - "src/commands/mcp/add.ts", - "src/commands/mcp/index.ts", - "src/commands/mcp/remove.ts", - "src/commands/mcp/tui-availability.ts", - "src/commands/mcp/tutorial.ts", - "src/commands/metrics.ts", - "src/commands/migrate.ts", - "src/commands/provision.ts", - "src/commands/replay-vision.ts", - "src/commands/revenue.ts", - "src/commands/self-driving.ts", - "src/commands/skill-program-options.ts", - "src/commands/skill.ts", - "src/commands/slack.ts", - "src/commands/upload-sourcemaps.ts", - "src/commands/warehouse.ts", - "src/lib/programs/dispatch-family.ts", - "src/lib/runners/resolve-no-telemetry.ts", - "src/lib/runners/run-non-interactive.ts", - "src/lib/runners/run-wizard-ci.ts", - "src/lib/runners/run-wizard-headless.ts", - "src/lib/runners/run-wizard.ts", - "src/ui/tui/hooks/keyboard-hints-utils.ts", - "src/ui/tui/hooks/useKeyBindings.ts", - "src/ui/tui/hooks/useKeyboardHints.tsx", - "src/ui/tui/hooks/useStdoutDimensions.ts", - "src/ui/tui/primitives/ConfirmButton.tsx", - "src/ui/tui/primitives/PickerMenu.tsx", - "src/ui/tui/primitives/PromptLabel.tsx", - "src/ui/tui/primitives/picker-filter.ts", - "src/wizard.ts" - ], - "imports": [ - "add-mcp-server-to-clients.js", - "agent-interface.js", - "agent-runner.js", - "analytics.js", - "api.js", - "ci-install.js", - "debug.js", - "env-api-key.js", - "environment.js", - "errors.js", - "file.js", - "gateway-session.js", - "headless-ui.js", - "interactive.js", - "local-dev.js", - "mint-failure.js", - "non-interactive.js", - "playground.js", - "posthog.js", - "provisioning.js", - "setup-utils.js", - "start-tui.js", - "store.js", - "task-stream.js", - "telemetry.js", - "wizard-abort.js", - "wizard-session.js", - "yara-hooks.js" - ] - }, - "bounded-fs.js": { - "sources": ["src/utils/bounded-fs.ts"], - "imports": ["analytics.js", "debug.js"] - }, - "ci-install.js": { - "sources": ["src/commands/basic-integration/ci-install.ts"], - "imports": [ - "bin.js", - "debug.js", - "errors.js", - "mint-failure.js", - "provisioning.js" - ] - }, - "debug.js": { - "sources": [ - "src/env.ts", - "src/lib/constants.ts", - "src/lib/headless-mode.ts", - "src/lib/health-checks/endpoints.ts", - "src/lib/health-checks/readiness.ts", - "src/lib/version.ts", - "src/ui/index.ts", - "src/ui/logging-ui.ts", - "src/ui/wizard-ui.ts", - "src/utils/debug.ts", - "src/utils/paths.ts" - ], - "imports": ["analytics.js", "local-dev.js"] - }, - "defaults.js": { - "sources": [ - "src/steps/add-mcp-server-to-clients/defaults.ts", - "src/steps/add-mcp-server-to-clients/results.ts" - ], - "imports": [] - }, - "env-api-key.js": { - "sources": ["src/utils/env-api-key.ts"], - "imports": ["bounded-fs.js", "rolldown-runtime.js"] - }, - "environment.js": { - "sources": ["src/utils/environment.ts"], - "imports": ["rolldown-runtime.js"] - }, - "errors.js": { - "sources": [ - "src/lib/agent/signals.ts", - "src/lib/errors/agent-map.ts", - "src/lib/errors/auth.ts", - "src/lib/errors/catalog.ts", - "src/lib/errors/codes.ts", - "src/lib/errors/detect-map.ts", - "src/lib/errors/emit.ts", - "src/lib/errors/run-failure.ts", - "src/lib/errors/sanitize.ts", - "src/lib/errors/skill-map.ts" - ], - "imports": [] - }, - "file.js": { - "sources": ["src/lib/task-stream/destinations/file.ts"], - "imports": ["debug.js"] - }, - "file-watcher.js": { - "sources": ["src/lib/file-watcher.ts"], - "imports": ["debug.js"] - }, - "gateway-session.js": { - "sources": [], - "imports": ["gateway-session.js"] - }, - "headless-ui.js": { - "sources": ["src/ui/headless-ui.ts"], - "imports": ["debug.js"] - }, - "interactive.js": { - "sources": ["src/commands/basic-integration/interactive.ts"], - "imports": ["bin.js", "mint-failure.js"] - }, - "local-dev.js": { - "sources": ["src/lib/local-dev.ts"], - "imports": [] - }, - "mcp.js": { - "sources": ["src/lib/agent/runner/harness/pi/mcp.ts"], - "imports": ["debug.js"] - }, - "mcp-prompt-streaming.js": { - "sources": ["src/lib/agent/mcp-prompt-streaming.ts"], - "imports": [ - "agent-interface.js", - "analytics.js", - "debug.js", - "gateway-session.js" - ] - }, - "mint-failure.js": { - "sources": [ - "src/lib/detection/project-scope.ts", - "src/lib/programs/agent-skill/content/index.tsx", - "src/lib/programs/agent-skill/index.ts", - "src/lib/programs/agent-skill/steps.ts", - "src/lib/programs/ai-observability/index.ts", - "src/lib/programs/audit/detect.ts", - "src/lib/programs/audit/index.ts", - "src/lib/programs/audit/seed.ts", - "src/lib/programs/error-tracking-upload-source-maps/content/index.tsx", - "src/lib/programs/error-tracking-upload-source-maps/detect.ts", - "src/lib/programs/error-tracking-upload-source-maps/index.ts", - "src/lib/programs/error-tracking-upload-source-maps/prompt.ts", - "src/lib/programs/error-tracking-upload-source-maps/steps.ts", - "src/lib/programs/error-tracking/content/index.tsx", - "src/lib/programs/error-tracking/content/tips.ts", - "src/lib/programs/error-tracking/detect-agentic.ts", - "src/lib/programs/error-tracking/index.ts", - "src/lib/programs/events-audit/index.ts", - "src/lib/programs/events-audit/seed.ts", - "src/lib/programs/events-audit/steps.ts", - "src/lib/programs/mcp-analytics/index.ts", - "src/lib/programs/mcp/index.ts", - "src/lib/programs/metrics/index.ts", - "src/lib/programs/migration/content/free-tier.tsx", - "src/lib/programs/migration/content/index.tsx", - "src/lib/programs/migration/content/pricing-structure.tsx", - "src/lib/programs/migration/content/vendor-stack.tsx", - "src/lib/programs/migration/index.ts", - "src/lib/programs/migration/steps.ts", - "src/lib/programs/posthog-doctor/fetch.ts", - "src/lib/programs/posthog-doctor/index.ts", - "src/lib/programs/posthog-doctor/kind-metadata.ts", - "src/lib/programs/posthog-doctor/steps.ts", - "src/lib/programs/posthog-doctor/types.ts", - "src/lib/programs/posthog-integration/content/data-flow.tsx", - "src/lib/programs/posthog-integration/content/funnel.tsx", - "src/lib/programs/posthog-integration/content/index.tsx", - "src/lib/programs/posthog-integration/content/line-chart.tsx", - "src/lib/programs/posthog-integration/content/product-suite.tsx", - "src/lib/programs/posthog-integration/handoff.ts", - "src/lib/programs/posthog-integration/index.ts", - "src/lib/programs/posthog-integration/steps.ts", - "src/lib/programs/program-registry.ts", - "src/lib/programs/replay-vision/index.ts", - "src/lib/programs/revenue-analytics/detect.ts", - "src/lib/programs/revenue-analytics/index.ts", - "src/lib/programs/revenue-analytics/steps.ts", - "src/lib/programs/self-driving/content/index.tsx", - "src/lib/programs/self-driving/content/pipeline-diagram.tsx", - "src/lib/programs/self-driving/content/pricing.ts", - "src/lib/programs/self-driving/content/tips.ts", - "src/lib/programs/self-driving/detect-agentic.ts", - "src/lib/programs/self-driving/detect.ts", - "src/lib/programs/self-driving/index.ts", - "src/lib/programs/self-driving/prompt.ts", - "src/lib/programs/self-driving/step-keys.ts", - "src/lib/programs/self-driving/steps.ts", - "src/lib/programs/shared/health-check-step.ts", - "src/lib/programs/shared/posthog-cli-preinstall.ts", - "src/lib/programs/slack/index.ts", - "src/lib/programs/warehouse-source/index.ts", - "src/lib/programs/warehouse-source/steps.ts", - "src/lib/programs/web-analytics-doctor/detect.ts", - "src/lib/programs/web-analytics-doctor/index.ts", - "src/lib/programs/web-analytics-doctor/steps.ts", - "src/steps/install-cli-steering/index.ts", - "src/ui/mint-failure.ts", - "src/ui/tui/components/StatusPeekTrigger.tsx", - "src/ui/tui/primitives/TextBlock.tsx", - "src/ui/tui/primitives/content-types.ts", - "src/ui/tui/primitives/layout-helpers.ts", - "src/ui/tui/primitives/text-helpers.ts", - "src/ui/tui/styles.ts" - ], - "imports": [ - "agent-interface.js", - "agent-runner.js", - "analytics.js", - "api.js", - "debug.js", - "errors.js", - "package-json.js", - "provisioning.js", - "queue-tools.js", - "registry.js", - "setup-utils.js", - "steps.js", - "telemetry.js", - "wizard-abort.js", - "wizard-session.js", - "yara-hooks.js" - ] - }, - "non-interactive.js": { - "sources": ["src/commands/basic-integration/non-interactive.ts"], - "imports": ["debug.js", "errors.js"] - }, - "orchestrator-tools.js": { - "sources": ["src/lib/agent/runner/harness/pi/orchestrator-tools.ts"], - "imports": ["analytics.js", "queue-tools.js"] - }, - "package-json.js": { - "sources": ["src/utils/package-json.ts"], - "imports": ["rolldown-runtime.js"] - }, - "package-manager.js": { - "sources": [ - "src/frameworks/python/utils.ts", - "src/lib/detection/package-manager.ts" - ], - "imports": ["setup-utils.js"] - }, - "pi.js": { - "sources": [ - "src/lib/agent/aio-capture.ts", - "src/lib/agent/runner/harness/pi/completion.ts", - "src/lib/agent/runner/harness/pi/index.ts" - ], - "imports": [ - "agent-interface.js", - "analytics.js", - "debug.js", - "errors.js", - "gateway-session.js", - "mcp.js", - "security.js", - "subagent.js", - "task.js", - "tasks.js", - "tools.js", - "yara-hooks.js" - ] - }, - "playground.js": { - "sources": [ - "src/commands/basic-integration/playground.ts", - "src/ui/tui/playground/PlaygroundApp.tsx", - "src/ui/tui/playground/demos/AiOptInDemo.tsx", - "src/ui/tui/playground/demos/AskModalDemo.tsx", - "src/ui/tui/playground/demos/AuditChecksDemo.tsx", - "src/ui/tui/playground/demos/DoctorReportDemo.tsx", - "src/ui/tui/playground/demos/EndScreensDemo.tsx", - "src/ui/tui/playground/demos/HealthCheckDemo.tsx", - "src/ui/tui/playground/demos/InputDemo.tsx", - "src/ui/tui/playground/demos/KeyboardHintsDemo.tsx", - "src/ui/tui/playground/demos/LayoutDemo.tsx", - "src/ui/tui/playground/demos/LearnDeckDemo.tsx", - "src/ui/tui/playground/demos/LogDemo.tsx", - "src/ui/tui/playground/demos/McpDemo.tsx", - "src/ui/tui/playground/demos/McpSuggestedPromptsDemo.tsx", - "src/ui/tui/playground/demos/ModalDemo.tsx", - "src/ui/tui/playground/demos/ProgressDemo.tsx", - "src/ui/tui/playground/demos/RunScreenDemo.tsx", - "src/ui/tui/playground/demos/ViewportGuardDemo.tsx", - "src/ui/tui/playground/demos/WelcomeDemo.tsx", - "src/ui/tui/playground/start-playground.ts" - ], - "imports": [ - "bin.js", - "debug.js", - "mint-failure.js", - "setup-utils.js", - "store.js", - "terminal.js" - ] - }, - "posthog.js": { - "sources": ["src/lib/task-stream/destinations/posthog.ts"], - "imports": ["debug.js"] - }, - "provisioning.js": { - "sources": ["src/utils/provisioning.ts", "src/utils/urls.ts"], - "imports": ["analytics.js", "debug.js", "rolldown-runtime.js"] - }, - "queue-tools.js": { - "sources": [ - "src/lib/agent/runner/sequence/orchestrator/queue-tools.ts", - "src/lib/agent/runner/sequence/orchestrator/queue.ts", - "src/lib/agent/runner/switchboard/models.ts", - "src/utils/atomic-ledger.ts" - ], - "imports": ["analytics.js", "debug.js"] - }, - "registry.js": { - "sources": [ - "src/frameworks/android/android-wizard-agent.ts", - "src/frameworks/android/utils.ts", - "src/frameworks/angular/angular-wizard-agent.ts", - "src/frameworks/angular/utils.ts", - "src/frameworks/astro/astro-wizard-agent.ts", - "src/frameworks/astro/utils.ts", - "src/frameworks/django/django-wizard-agent.ts", - "src/frameworks/django/utils.ts", - "src/frameworks/elixir/elixir-wizard-agent.ts", - "src/frameworks/fastapi/fastapi-wizard-agent.ts", - "src/frameworks/fastapi/utils.ts", - "src/frameworks/flask/flask-wizard-agent.ts", - "src/frameworks/flask/utils.ts", - "src/frameworks/flutter/flutter-wizard-agent.ts", - "src/frameworks/go/go-wizard-agent.ts", - "src/frameworks/java/java-wizard-agent.ts", - "src/frameworks/javascript-node/javascript-node-wizard-agent.ts", - "src/frameworks/javascript-web/javascript-web-wizard-agent.ts", - "src/frameworks/javascript-web/utils.ts", - "src/frameworks/kmp/kmp-wizard-agent.ts", - "src/frameworks/laravel/laravel-wizard-agent.ts", - "src/frameworks/laravel/utils.ts", - "src/frameworks/nextjs/nextjs-wizard-agent.ts", - "src/frameworks/nextjs/utils.ts", - "src/frameworks/nuxt/nuxt-wizard-agent.ts", - "src/frameworks/python/python-wizard-agent.ts", - "src/frameworks/rails/rails-wizard-agent.ts", - "src/frameworks/rails/utils.ts", - "src/frameworks/react-native/react-native-wizard-agent.ts", - "src/frameworks/react-native/utils.ts", - "src/frameworks/react-router/react-router-wizard-agent.ts", - "src/frameworks/react-router/utils.ts", - "src/frameworks/ruby/ruby-wizard-agent.ts", - "src/frameworks/ruby/utils.ts", - "src/frameworks/rust/rust-wizard-agent.ts", - "src/frameworks/svelte/svelte-wizard-agent.ts", - "src/frameworks/swift/swift-wizard-agent.ts", - "src/frameworks/swift/utils.ts", - "src/frameworks/tanstack-router/tanstack-router-wizard-agent.ts", - "src/frameworks/tanstack-router/utils.ts", - "src/frameworks/tanstack-start/tanstack-start-wizard-agent.ts", - "src/frameworks/tanstack-start/utils.ts", - "src/frameworks/vue/vue-wizard-agent.ts", - "src/lib/framework-config.ts", - "src/lib/registry.ts" - ], - "imports": [ - "bounded-fs.js", - "debug.js", - "package-json.js", - "package-manager.js", - "rolldown-runtime.js", - "setup-utils.js" - ] - }, - "rolldown-runtime.js": { - "sources": [], - "imports": [] - }, - "security.js": { - "sources": ["src/lib/agent/runner/harness/pi/security.ts"], - "imports": [ - "agent-interface.js", - "analytics.js", - "debug.js", - "yara-hooks.js" - ] - }, - "setup-utils.js": { - "sources": [ - "src/lib/host-resolution.ts", - "src/lib/oauth/program-scopes.ts", - "src/utils/oauth-errors.ts", - "src/utils/oauth.ts", - "src/utils/package-manager.ts", - "src/utils/project-resolution.ts", - "src/utils/semver.ts", - "src/utils/setup-utils.ts" - ], - "imports": [ - "analytics.js", - "api.js", - "bounded-fs.js", - "debug.js", - "local-dev.js", - "provisioning.js", - "rolldown-runtime.js", - "telemetry.js", - "wizard-abort.js" - ] - }, - "start-tui.js": { - "sources": [ - "src/lib/programs/error-tracking-upload-source-maps/detect-agentic.ts", - "src/lib/wizard-spellbook.ts", - "src/steps/add-mcp-server-to-clients/browser-client.ts", - "src/steps/add-mcp-server-to-clients/login-client.ts", - "src/ui/tui/App.tsx", - "src/ui/tui/components/PrivacyPanel.tsx", - "src/ui/tui/exit-line.ts", - "src/ui/tui/hooks/useGithubConnection.ts", - "src/ui/tui/ink-ui.ts", - "src/ui/tui/posthog-integration-intro.ts", - "src/ui/tui/screen-registry.tsx", - "src/ui/tui/screens/AgentSkillIntroScreen.tsx", - "src/ui/tui/screens/AiObservabilityIntroScreen.tsx", - "src/ui/tui/screens/AuthErrorScreen.tsx", - "src/ui/tui/screens/AuthScreen.tsx", - "src/ui/tui/screens/ErrorTrackingDetectScreen.tsx", - "src/ui/tui/screens/ErrorTrackingIntroScreen.tsx", - "src/ui/tui/screens/ExitScreen.tsx", - "src/ui/tui/screens/IntroScreenLayout.tsx", - "src/ui/tui/screens/KeepSkillsScreen.tsx", - "src/ui/tui/screens/ManagedSettingsScreen.tsx", - "src/ui/tui/screens/ManualAuthCodeScreen.tsx", - "src/ui/tui/screens/MetricsIntroScreen.tsx", - "src/ui/tui/screens/MigrationIntroScreen.tsx", - "src/ui/tui/screens/MintFailureScreen.tsx", - "src/ui/tui/screens/PortConflictScreen.tsx", - "src/ui/tui/screens/PostHogIntegrationIntroScreen.tsx", - "src/ui/tui/screens/RevenueIntroScreen.tsx", - "src/ui/tui/screens/RunScreen.tsx", - "src/ui/tui/screens/SelfDrivingGitHubScreen.tsx", - "src/ui/tui/screens/SelfDrivingHandoffScreen.tsx", - "src/ui/tui/screens/SelfDrivingIntegrationCheckScreen.tsx", - "src/ui/tui/screens/SelfDrivingIntegrationDetectScreen.tsx", - "src/ui/tui/screens/SelfDrivingIntroScreen.tsx", - "src/ui/tui/screens/SessionTimeoutScreen.tsx", - "src/ui/tui/screens/SettingsOverrideScreen.tsx", - "src/ui/tui/screens/SetupScreen.tsx", - "src/ui/tui/screens/SourceMapsDetectScreen.tsx", - "src/ui/tui/screens/SourceMapsIntroScreen.tsx", - "src/ui/tui/screens/SourceMapsOutroScreen.tsx", - "src/ui/tui/screens/TaskNoticeScreen.tsx", - "src/ui/tui/screens/WarehouseIntroScreen.tsx", - "src/ui/tui/screens/WizardAskScreen.tsx", - "src/ui/tui/screens/audit/AuditAreaPane.tsx", - "src/ui/tui/screens/audit/AuditChecksOutroSection.tsx", - "src/ui/tui/screens/audit/AuditIntroScreen.tsx", - "src/ui/tui/screens/audit/AuditOutroScreen.tsx", - "src/ui/tui/screens/audit/AuditRunScreen.tsx", - "src/ui/tui/screens/audit/PendingChecksList.tsx", - "src/ui/tui/screens/audit/slides/events-audit/createDashboard.tsx", - "src/ui/tui/screens/audit/slides/events-audit/detectSdk.tsx", - "src/ui/tui/screens/audit/slides/events-audit/enrichSites.tsx", - "src/ui/tui/screens/audit/slides/events-audit/index.ts", - "src/ui/tui/screens/audit/slides/events-audit/queryVolume.tsx", - "src/ui/tui/screens/audit/slides/events-audit/scanSites.tsx", - "src/ui/tui/screens/audit/slides/events-audit/uploadNotebook.tsx", - "src/ui/tui/screens/audit/slides/events-audit/writeReport.tsx", - "src/ui/tui/screens/doctor/DoctorIntroScreen.tsx", - "src/ui/tui/screens/doctor/DoctorReportScreen.tsx", - "src/ui/tui/screens/health/HealthCheckScreen.tsx", - "src/ui/tui/services/coding-agent-launcher.ts", - "src/ui/tui/services/mcp-installer.ts", - "src/ui/tui/services/mcp-suggested-prompts-services.ts", - "src/ui/tui/start-tui.ts", - "src/utils/clipboard.ts" - ], - "imports": [ - "add-mcp-server-to-clients.js", - "agent-interface.js", - "agent-runner.js", - "analytics.js", - "api.js", - "bin.js", - "bounded-fs.js", - "debug.js", - "defaults.js", - "errors.js", - "mcp-prompt-streaming.js", - "mint-failure.js", - "provisioning.js", - "registry.js", - "setup-utils.js", - "store.js", - "telemetry.js", - "terminal.js", - "wizard-abort.js", - "wizard-session.js", - "yara-hooks.js" - ] - }, - "steps.js": { - "sources": [ - "src/steps/upload-environment-variables/EnvironmentProvider.ts", - "src/steps/upload-environment-variables/index.ts", - "src/steps/upload-environment-variables/providers/vercel.ts" - ], - "imports": ["analytics.js", "debug.js", "telemetry.js"] - }, - "store.js": { - "sources": [ - "src/lib/programs/ai-opt-in-gate.ts", - "src/lib/programs/program-step.ts", - "src/ui/tui/router.ts", - "src/ui/tui/screen-sequences.ts", - "src/ui/tui/store.ts" - ], - "imports": [ - "agent-runner.js", - "analytics.js", - "debug.js", - "mint-failure.js", - "rolldown-runtime.js", - "wizard-session.js" - ] - }, - "subagent.js": { - "sources": ["src/lib/agent/runner/harness/pi/subagent.ts"], - "imports": ["debug.js"] - }, - "task.js": { - "sources": ["src/lib/agent/runner/harness/pi/task.ts"], - "imports": [ - "agent-interface.js", - "agent-prompt-loader.js", - "analytics.js", - "debug.js", - "errors.js", - "gateway-session.js", - "mcp.js", - "orchestrator-tools.js", - "pi.js", - "queue-tools.js", - "security.js", - "tools.js", - "yara-hooks.js" - ] - }, - "task-stream.js": { - "sources": [ - "src/lib/task-stream/audit-areas.ts", - "src/lib/task-stream/event-plan-watcher.ts", - "src/lib/task-stream/task-stream-push.ts" - ], - "imports": [ - "debug.js", - "errors.js", - "file-watcher.js", - "file.js", - "posthog.js" - ] - }, - "tasks.js": { - "sources": ["src/lib/agent/runner/harness/pi/tasks.ts"], - "imports": ["debug.js"] - }, - "telemetry.js": { - "sources": ["src/telemetry.ts", "src/utils/links.ts"], - "imports": ["analytics.js"] - }, - "terminal.js": { - "sources": [ - "src/lib/mcp-project-profile.ts", - "src/lib/mcp-role-prompts.copy.json", - "src/lib/mcp-role-prompts.ts", - "src/lib/mcp-seed-events.ts", - "src/ui/tui/components/LearnCard.tsx", - "src/ui/tui/components/PhaseVisuals.tsx", - "src/ui/tui/components/ServiceHealthList.tsx", - "src/ui/tui/components/TipsCard.tsx", - "src/ui/tui/components/TitleBar.tsx", - "src/ui/tui/components/TokenCostHud.tsx", - "src/ui/tui/components/visualizer/CrateStack.tsx", - "src/ui/tui/components/visualizer/DashboardGrid.tsx", - "src/ui/tui/components/visualizer/DiffCascade.tsx", - "src/ui/tui/components/visualizer/LibraryShelf.tsx", - "src/ui/tui/components/visualizer/MatrixRain.tsx", - "src/ui/tui/components/visualizer/Tumblers.tsx", - "src/ui/tui/components/visualizer/grid.ts", - "src/ui/tui/components/visualizer/palette.ts", - "src/ui/tui/components/visualizer/panel.tsx", - "src/ui/tui/hooks/useDismissOnAnyKey.ts", - "src/ui/tui/hooks/useTick.ts", - "src/ui/tui/primitives/CardLayout.tsx", - "src/ui/tui/primitives/ConfirmationInput.tsx", - "src/ui/tui/primitives/ContentSequencer.tsx", - "src/ui/tui/primitives/DissolveTransition.tsx", - "src/ui/tui/primitives/Divider.tsx", - "src/ui/tui/primitives/EventPlanViewer.tsx", - "src/ui/tui/primitives/GroupedPickerMenu.tsx", - "src/ui/tui/primitives/HNViewer.tsx", - "src/ui/tui/primitives/KeyboardHintsBar.tsx", - "src/ui/tui/primitives/LinesBlock.tsx", - "src/ui/tui/primitives/LinkText.tsx", - "src/ui/tui/primitives/LoadingBox.tsx", - "src/ui/tui/primitives/LogViewer.tsx", - "src/ui/tui/primitives/ModalOverlay.tsx", - "src/ui/tui/primitives/NodeBlock.tsx", - "src/ui/tui/primitives/ProgressList.tsx", - "src/ui/tui/primitives/ScreenContainer.tsx", - "src/ui/tui/primitives/ScreenErrorBoundary.tsx", - "src/ui/tui/primitives/SplitView.tsx", - "src/ui/tui/primitives/TabContainer.tsx", - "src/ui/tui/primitives/ViewportTooSmall.tsx", - "src/ui/tui/primitives/link-helpers.ts", - "src/ui/tui/screens/AiOptInRequiredScreen.tsx", - "src/ui/tui/screens/McpScreen.tsx", - "src/ui/tui/screens/McpSuggestedPromptsScreen.tsx", - "src/ui/tui/screens/OutroScreen.tsx", - "src/ui/tui/screens/SkillSourceInfo.tsx", - "src/ui/tui/screens/SlackConnectScreen.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/AreaHeaderRow.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/AuditChecksViewer.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/CheckRow.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/DetailRow.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/Footer.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/Header.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/Legend.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/layout.ts", - "src/ui/tui/screens/audit/AuditChecksViewer/sort.ts", - "src/ui/tui/screens/audit/slides/eventCapture.tsx", - "src/ui/tui/screens/audit/slides/identification.tsx", - "src/ui/tui/screens/audit/slides/index.ts", - "src/ui/tui/screens/audit/slides/installation.tsx", - "src/ui/tui/screens/audit/slides/liveData.tsx", - "src/ui/tui/screens/audit/slides/shared.tsx", - "src/ui/tui/screens/audit/slides/uploadNotebook.tsx", - "src/ui/tui/screens/audit/slides/writeReport.tsx", - "src/ui/tui/screens/doctor/IssueTable.tsx", - "src/ui/tui/terminal.ts" - ], - "imports": [ - "agent-interface.js", - "agent-runner.js", - "analytics.js", - "api.js", - "bin.js", - "debug.js", - "defaults.js", - "mint-failure.js", - "setup-utils.js", - "store.js", - "telemetry.js", - "yara-hooks.js" - ] - }, - "tools.js": { - "sources": ["src/lib/agent/runner/harness/pi/tools.ts"], - "imports": [ - "agent-interface.js", - "analytics.js", - "debug.js", - "package-manager.js", - "pi.js", - "queue-tools.js", - "yara-hooks.js" - ] - }, - "wizard-abort.js": { - "sources": ["src/utils/wizard-abort.ts"], - "imports": ["analytics.js", "debug.js", "errors.js"] - }, - "wizard-session.js": { - "sources": ["src/lib/wizard-session.ts"], - "imports": ["local-dev.js"] - }, - "yara-hooks.js": { - "sources": [ - "src/lib/programs/audit/types.ts", - "src/lib/programs/events-audit/constants.ts", - "src/lib/programs/posthog-integration/constants.ts", - "src/lib/skill-install.ts", - "src/lib/yara-hooks.ts", - "src/lib/yara-policy.ts" - ], - "imports": ["analytics.js", "bounded-fs.js", "debug.js"] - } + "chunks": [ + "add-mcp-server-to-clients.js", + "agent-interface.js", + "agent-prompt-loader.js", + "agent-runner.js", + "analytics.js", + "api.js", + "bin.js", + "bounded-fs.js", + "ci-install.js", + "debug.js", + "defaults.js", + "env-api-key.js", + "environment.js", + "errors.js", + "file-watcher.js", + "file.js", + "gateway-session.js", + "headless-ui.js", + "interactive.js", + "local-dev.js", + "mcp-prompt-streaming.js", + "mcp.js", + "mint-failure.js", + "non-interactive.js", + "orchestrator-tools.js", + "package-json.js", + "package-manager.js", + "pi.js", + "playground.js", + "posthog.js", + "provisioning.js", + "queue-tools.js", + "registry.js", + "rolldown-runtime.js", + "security.js", + "setup-utils.js", + "start-tui.js", + "steps.js", + "store.js", + "subagent.js", + "task-stream.js", + "task.js", + "tasks.js", + "telemetry.js", + "terminal.js", + "tools.js", + "wizard-abort.js", + "wizard-session.js", + "yara-hooks.js" + ], + "sources": [ + "bin.ts", + "src/commands/ai-observability.ts", + "src/commands/audit.ts", + "src/commands/basic-integration/ci-install.ts", + "src/commands/basic-integration/index.ts", + "src/commands/basic-integration/interactive.ts", + "src/commands/basic-integration/non-interactive.ts", + "src/commands/basic-integration/playground.ts", + "src/commands/basic-integration/skill.ts", + "src/commands/cli/add.ts", + "src/commands/cli/index.ts", + "src/commands/command.ts", + "src/commands/doctor.ts", + "src/commands/error-tracking.ts", + "src/commands/factories/family-command-factory.ts", + "src/commands/factories/family-picker.tsx", + "src/commands/factories/native-command-factory.ts", + "src/commands/factories/shared.ts", + "src/commands/mcp-analytics.ts", + "src/commands/mcp/add.ts", + "src/commands/mcp/index.ts", + "src/commands/mcp/remove.ts", + "src/commands/mcp/tui-availability.ts", + "src/commands/mcp/tutorial.ts", + "src/commands/metrics.ts", + "src/commands/migrate.ts", + "src/commands/provision.ts", + "src/commands/replay-vision.ts", + "src/commands/revenue.ts", + "src/commands/self-driving.ts", + "src/commands/skill-program-options.ts", + "src/commands/skill.ts", + "src/commands/slack.ts", + "src/commands/upload-sourcemaps.ts", + "src/commands/warehouse.ts", + "src/env.ts", + "src/frameworks/android/android-wizard-agent.ts", + "src/frameworks/android/utils.ts", + "src/frameworks/angular/angular-wizard-agent.ts", + "src/frameworks/angular/utils.ts", + "src/frameworks/astro/astro-wizard-agent.ts", + "src/frameworks/astro/utils.ts", + "src/frameworks/django/django-wizard-agent.ts", + "src/frameworks/django/utils.ts", + "src/frameworks/elixir/elixir-wizard-agent.ts", + "src/frameworks/fastapi/fastapi-wizard-agent.ts", + "src/frameworks/fastapi/utils.ts", + "src/frameworks/flask/flask-wizard-agent.ts", + "src/frameworks/flask/utils.ts", + "src/frameworks/flutter/flutter-wizard-agent.ts", + "src/frameworks/go/go-wizard-agent.ts", + "src/frameworks/java/java-wizard-agent.ts", + "src/frameworks/javascript-node/javascript-node-wizard-agent.ts", + "src/frameworks/javascript-web/javascript-web-wizard-agent.ts", + "src/frameworks/javascript-web/utils.ts", + "src/frameworks/kmp/kmp-wizard-agent.ts", + "src/frameworks/laravel/laravel-wizard-agent.ts", + "src/frameworks/laravel/utils.ts", + "src/frameworks/nextjs/nextjs-wizard-agent.ts", + "src/frameworks/nextjs/utils.ts", + "src/frameworks/nuxt/nuxt-wizard-agent.ts", + "src/frameworks/python/python-wizard-agent.ts", + "src/frameworks/python/utils.ts", + "src/frameworks/rails/rails-wizard-agent.ts", + "src/frameworks/rails/utils.ts", + "src/frameworks/react-native/react-native-wizard-agent.ts", + "src/frameworks/react-native/utils.ts", + "src/frameworks/react-router/react-router-wizard-agent.ts", + "src/frameworks/react-router/utils.ts", + "src/frameworks/ruby/ruby-wizard-agent.ts", + "src/frameworks/ruby/utils.ts", + "src/frameworks/rust/rust-wizard-agent.ts", + "src/frameworks/svelte/svelte-wizard-agent.ts", + "src/frameworks/swift/swift-wizard-agent.ts", + "src/frameworks/swift/utils.ts", + "src/frameworks/tanstack-router/tanstack-router-wizard-agent.ts", + "src/frameworks/tanstack-router/utils.ts", + "src/frameworks/tanstack-start/tanstack-start-wizard-agent.ts", + "src/frameworks/tanstack-start/utils.ts", + "src/frameworks/vue/vue-wizard-agent.ts", + "src/lib/agent/agent-env-isolation.ts", + "src/lib/agent/agent-interface.ts", + "src/lib/agent/agent-phase.ts", + "src/lib/agent/agent-prompt-loader.ts", + "src/lib/agent/agent-prompt.ts", + "src/lib/agent/agent-runner.ts", + "src/lib/agent/aio-capture.ts", + "src/lib/agent/bash-fence.ts", + "src/lib/agent/claude-settings.ts", + "src/lib/agent/commandments.ts", + "src/lib/agent/mcp-prompt-streaming.ts", + "src/lib/agent/output-signals.ts", + "src/lib/agent/runner/harness/anthropic/index.ts", + "src/lib/agent/runner/harness/pi/completion.ts", + "src/lib/agent/runner/harness/pi/gateway.ts", + "src/lib/agent/runner/harness/pi/index.ts", + "src/lib/agent/runner/harness/pi/mcp.ts", + "src/lib/agent/runner/harness/pi/orchestrator-tools.ts", + "src/lib/agent/runner/harness/pi/runtime-notes.ts", + "src/lib/agent/runner/harness/pi/security.ts", + "src/lib/agent/runner/harness/pi/subagent.ts", + "src/lib/agent/runner/harness/pi/task.ts", + "src/lib/agent/runner/harness/pi/tasks.ts", + "src/lib/agent/runner/harness/pi/tools.ts", + "src/lib/agent/runner/index.ts", + "src/lib/agent/runner/sequence/linear.ts", + "src/lib/agent/runner/sequence/orchestrator/executor.ts", + "src/lib/agent/runner/sequence/orchestrator/orchestrator-runner.ts", + "src/lib/agent/runner/sequence/orchestrator/queue-tools.ts", + "src/lib/agent/runner/sequence/orchestrator/queue.ts", + "src/lib/agent/runner/sequence/orchestrator/run-metrics.ts", + "src/lib/agent/runner/sequence/orchestrator/seeded-deps.ts", + "src/lib/agent/runner/shared/authenticate.ts", + "src/lib/agent/runner/shared/bootstrap.ts", + "src/lib/agent/runner/shared/errors.ts", + "src/lib/agent/runner/switchboard/commandments.ts", + "src/lib/agent/runner/switchboard/flags/index.ts", + "src/lib/agent/runner/switchboard/flags/orchestrator.ts", + "src/lib/agent/runner/switchboard/flags/schemes.ts", + "src/lib/agent/runner/switchboard/flags/self-driving.ts", + "src/lib/agent/runner/switchboard/harness.ts", + "src/lib/agent/runner/switchboard/index.ts", + "src/lib/agent/runner/switchboard/models.ts", + "src/lib/agent/runner/switchboard/sequence.ts", + "src/lib/agent/signals.ts", + "src/lib/agent/stored-login.ts", + "src/lib/agent/token-pricing.ts", + "src/lib/agent/triage-provider.ts", + "src/lib/api.ts", + "src/lib/auth-session-state.ts", + "src/lib/constants.ts", + "src/lib/detection/agentic.ts", + "src/lib/detection/context.ts", + "src/lib/detection/features.ts", + "src/lib/detection/framework.ts", + "src/lib/detection/package-manager.ts", + "src/lib/detection/project-scope.ts", + "src/lib/errors/agent-map.ts", + "src/lib/errors/auth.ts", + "src/lib/errors/catalog.ts", + "src/lib/errors/codes.ts", + "src/lib/errors/detect-map.ts", + "src/lib/errors/emit.ts", + "src/lib/errors/run-failure.ts", + "src/lib/errors/sanitize.ts", + "src/lib/errors/skill-map.ts", + "src/lib/fetch-retry.ts", + "src/lib/file-watcher.ts", + "src/lib/framework-config.ts", + "src/lib/headless-mode.ts", + "src/lib/health-checks/endpoints.ts", + "src/lib/health-checks/readiness.ts", + "src/lib/host-resolution.ts", + "src/lib/local-dev.ts", + "src/lib/mcp-project-profile.ts", + "src/lib/mcp-role-prompts.copy.json", + "src/lib/mcp-role-prompts.ts", + "src/lib/mcp-seed-events.ts", + "src/lib/middleware/benchmark.ts", + "src/lib/middleware/benchmarks/cache-tracker.ts", + "src/lib/middleware/benchmarks/compaction-tracker.ts", + "src/lib/middleware/benchmarks/context-size-tracker.ts", + "src/lib/middleware/benchmarks/cost-tracker.ts", + "src/lib/middleware/benchmarks/duration-tracker.ts", + "src/lib/middleware/benchmarks/index.ts", + "src/lib/middleware/benchmarks/json-writer.ts", + "src/lib/middleware/benchmarks/summary.ts", + "src/lib/middleware/benchmarks/token-tracker.ts", + "src/lib/middleware/benchmarks/turn-counter.ts", + "src/lib/middleware/config.ts", + "src/lib/middleware/phase-detector.ts", + "src/lib/middleware/pipeline.ts", + "src/lib/oauth/program-scopes.ts", + "src/lib/programs/agent-skill/content/index.tsx", + "src/lib/programs/agent-skill/index.ts", + "src/lib/programs/agent-skill/steps.ts", + "src/lib/programs/ai-observability/index.ts", + "src/lib/programs/ai-opt-in-gate.ts", + "src/lib/programs/audit/detect.ts", + "src/lib/programs/audit/index.ts", + "src/lib/programs/audit/ledger-watcher.ts", + "src/lib/programs/audit/seed.ts", + "src/lib/programs/audit/types.ts", + "src/lib/programs/dispatch-family.ts", + "src/lib/programs/error-tracking-upload-source-maps/content/index.tsx", + "src/lib/programs/error-tracking-upload-source-maps/detect-agentic.ts", + "src/lib/programs/error-tracking-upload-source-maps/detect.ts", + "src/lib/programs/error-tracking-upload-source-maps/index.ts", + "src/lib/programs/error-tracking-upload-source-maps/prompt.ts", + "src/lib/programs/error-tracking-upload-source-maps/steps.ts", + "src/lib/programs/error-tracking/content/index.tsx", + "src/lib/programs/error-tracking/content/tips.ts", + "src/lib/programs/error-tracking/detect-agentic.ts", + "src/lib/programs/error-tracking/index.ts", + "src/lib/programs/events-audit/constants.ts", + "src/lib/programs/events-audit/index.ts", + "src/lib/programs/events-audit/seed.ts", + "src/lib/programs/events-audit/steps.ts", + "src/lib/programs/mcp-analytics/index.ts", + "src/lib/programs/mcp/index.ts", + "src/lib/programs/metrics/index.ts", + "src/lib/programs/migration/content/free-tier.tsx", + "src/lib/programs/migration/content/index.tsx", + "src/lib/programs/migration/content/pricing-structure.tsx", + "src/lib/programs/migration/content/vendor-stack.tsx", + "src/lib/programs/migration/index.ts", + "src/lib/programs/migration/steps.ts", + "src/lib/programs/posthog-doctor/fetch.ts", + "src/lib/programs/posthog-doctor/index.ts", + "src/lib/programs/posthog-doctor/kind-metadata.ts", + "src/lib/programs/posthog-doctor/steps.ts", + "src/lib/programs/posthog-doctor/types.ts", + "src/lib/programs/posthog-integration/constants.ts", + "src/lib/programs/posthog-integration/content/data-flow.tsx", + "src/lib/programs/posthog-integration/content/funnel.tsx", + "src/lib/programs/posthog-integration/content/index.tsx", + "src/lib/programs/posthog-integration/content/line-chart.tsx", + "src/lib/programs/posthog-integration/content/product-suite.tsx", + "src/lib/programs/posthog-integration/detect.ts", + "src/lib/programs/posthog-integration/handoff.ts", + "src/lib/programs/posthog-integration/index.ts", + "src/lib/programs/posthog-integration/steps.ts", + "src/lib/programs/program-registry.ts", + "src/lib/programs/program-step.ts", + "src/lib/programs/replay-vision/index.ts", + "src/lib/programs/revenue-analytics/detect.ts", + "src/lib/programs/revenue-analytics/index.ts", + "src/lib/programs/revenue-analytics/steps.ts", + "src/lib/programs/self-driving/content/index.tsx", + "src/lib/programs/self-driving/content/pipeline-diagram.tsx", + "src/lib/programs/self-driving/content/pricing.ts", + "src/lib/programs/self-driving/content/tips.ts", + "src/lib/programs/self-driving/detect-agentic.ts", + "src/lib/programs/self-driving/detect.ts", + "src/lib/programs/self-driving/index.ts", + "src/lib/programs/self-driving/prompt.ts", + "src/lib/programs/self-driving/step-keys.ts", + "src/lib/programs/self-driving/steps.ts", + "src/lib/programs/shared/health-check-step.ts", + "src/lib/programs/shared/package-scanning.ts", + "src/lib/programs/shared/posthog-cli-preinstall.ts", + "src/lib/programs/slack/index.ts", + "src/lib/programs/warehouse-source/detect.ts", + "src/lib/programs/warehouse-source/index.ts", + "src/lib/programs/warehouse-source/steps.ts", + "src/lib/programs/web-analytics-doctor/detect.ts", + "src/lib/programs/web-analytics-doctor/index.ts", + "src/lib/programs/web-analytics-doctor/steps.ts", + "src/lib/registry.ts", + "src/lib/runners/resolve-no-telemetry.ts", + "src/lib/runners/run-non-interactive.ts", + "src/lib/runners/run-wizard-ci.ts", + "src/lib/runners/run-wizard-headless.ts", + "src/lib/runners/run-wizard.ts", + "src/lib/safe-tools.ts", + "src/lib/secret-vault.ts", + "src/lib/skill-install.ts", + "src/lib/task-stream/audit-areas.ts", + "src/lib/task-stream/destinations/file.ts", + "src/lib/task-stream/destinations/posthog.ts", + "src/lib/task-stream/event-plan-watcher.ts", + "src/lib/task-stream/task-stream-push.ts", + "src/lib/version.ts", + "src/lib/warehouse-sources/detect.ts", + "src/lib/warehouse-sources/registry.ts", + "src/lib/wizard-ask-bridge.ts", + "src/lib/wizard-session.ts", + "src/lib/wizard-spellbook.ts", + "src/lib/wizard-tools/handoff.ts", + "src/lib/wizard-tools/mcp.ts", + "src/lib/wizard-tools/tools.ts", + "src/lib/yara-hooks.ts", + "src/lib/yara-policy.ts", + "src/steps/add-mcp-server-to-clients/MCPClient.ts", + "src/steps/add-mcp-server-to-clients/browser-client.ts", + "src/steps/add-mcp-server-to-clients/clients/claude-code.ts", + "src/steps/add-mcp-server-to-clients/clients/claude-web.ts", + "src/steps/add-mcp-server-to-clients/clients/codex.ts", + "src/steps/add-mcp-server-to-clients/clients/cursor.ts", + "src/steps/add-mcp-server-to-clients/clients/opencode.ts", + "src/steps/add-mcp-server-to-clients/clients/visual-studio-code.ts", + "src/steps/add-mcp-server-to-clients/clients/zed.ts", + "src/steps/add-mcp-server-to-clients/defaults.ts", + "src/steps/add-mcp-server-to-clients/index.ts", + "src/steps/add-mcp-server-to-clients/login-client.ts", + "src/steps/add-mcp-server-to-clients/plugin-client.ts", + "src/steps/add-mcp-server-to-clients/results.ts", + "src/steps/install-cli-steering/index.ts", + "src/steps/upload-environment-variables/EnvironmentProvider.ts", + "src/steps/upload-environment-variables/index.ts", + "src/steps/upload-environment-variables/providers/vercel.ts", + "src/telemetry.ts", + "src/ui/headless-ui.ts", + "src/ui/index.ts", + "src/ui/logging-ui.ts", + "src/ui/mint-failure.ts", + "src/ui/tui/App.tsx", + "src/ui/tui/components/LearnCard.tsx", + "src/ui/tui/components/PhaseVisuals.tsx", + "src/ui/tui/components/PrivacyPanel.tsx", + "src/ui/tui/components/ServiceHealthList.tsx", + "src/ui/tui/components/StatusPeekTrigger.tsx", + "src/ui/tui/components/TipsCard.tsx", + "src/ui/tui/components/TitleBar.tsx", + "src/ui/tui/components/TokenCostHud.tsx", + "src/ui/tui/components/visualizer/CrateStack.tsx", + "src/ui/tui/components/visualizer/DashboardGrid.tsx", + "src/ui/tui/components/visualizer/DiffCascade.tsx", + "src/ui/tui/components/visualizer/LibraryShelf.tsx", + "src/ui/tui/components/visualizer/MatrixRain.tsx", + "src/ui/tui/components/visualizer/Tumblers.tsx", + "src/ui/tui/components/visualizer/grid.ts", + "src/ui/tui/components/visualizer/palette.ts", + "src/ui/tui/components/visualizer/panel.tsx", + "src/ui/tui/exit-line.ts", + "src/ui/tui/hooks/keyboard-hints-utils.ts", + "src/ui/tui/hooks/useDismissOnAnyKey.ts", + "src/ui/tui/hooks/useGithubConnection.ts", + "src/ui/tui/hooks/useKeyBindings.ts", + "src/ui/tui/hooks/useKeyboardHints.tsx", + "src/ui/tui/hooks/useStdoutDimensions.ts", + "src/ui/tui/hooks/useTick.ts", + "src/ui/tui/ink-ui.ts", + "src/ui/tui/playground/PlaygroundApp.tsx", + "src/ui/tui/playground/demos/AiOptInDemo.tsx", + "src/ui/tui/playground/demos/AskModalDemo.tsx", + "src/ui/tui/playground/demos/AuditChecksDemo.tsx", + "src/ui/tui/playground/demos/DoctorReportDemo.tsx", + "src/ui/tui/playground/demos/EndScreensDemo.tsx", + "src/ui/tui/playground/demos/HealthCheckDemo.tsx", + "src/ui/tui/playground/demos/InputDemo.tsx", + "src/ui/tui/playground/demos/KeyboardHintsDemo.tsx", + "src/ui/tui/playground/demos/LayoutDemo.tsx", + "src/ui/tui/playground/demos/LearnDeckDemo.tsx", + "src/ui/tui/playground/demos/LogDemo.tsx", + "src/ui/tui/playground/demos/McpDemo.tsx", + "src/ui/tui/playground/demos/McpSuggestedPromptsDemo.tsx", + "src/ui/tui/playground/demos/ModalDemo.tsx", + "src/ui/tui/playground/demos/ProgressDemo.tsx", + "src/ui/tui/playground/demos/RunScreenDemo.tsx", + "src/ui/tui/playground/demos/ViewportGuardDemo.tsx", + "src/ui/tui/playground/demos/WelcomeDemo.tsx", + "src/ui/tui/playground/start-playground.ts", + "src/ui/tui/posthog-integration-intro.ts", + "src/ui/tui/primitives/CardLayout.tsx", + "src/ui/tui/primitives/ConfirmButton.tsx", + "src/ui/tui/primitives/ConfirmationInput.tsx", + "src/ui/tui/primitives/ContentSequencer.tsx", + "src/ui/tui/primitives/DissolveTransition.tsx", + "src/ui/tui/primitives/Divider.tsx", + "src/ui/tui/primitives/EventPlanViewer.tsx", + "src/ui/tui/primitives/GroupedPickerMenu.tsx", + "src/ui/tui/primitives/HNViewer.tsx", + "src/ui/tui/primitives/KeyboardHintsBar.tsx", + "src/ui/tui/primitives/LinesBlock.tsx", + "src/ui/tui/primitives/LinkText.tsx", + "src/ui/tui/primitives/LoadingBox.tsx", + "src/ui/tui/primitives/LogViewer.tsx", + "src/ui/tui/primitives/ModalOverlay.tsx", + "src/ui/tui/primitives/NodeBlock.tsx", + "src/ui/tui/primitives/PickerMenu.tsx", + "src/ui/tui/primitives/ProgressList.tsx", + "src/ui/tui/primitives/PromptLabel.tsx", + "src/ui/tui/primitives/ScreenContainer.tsx", + "src/ui/tui/primitives/ScreenErrorBoundary.tsx", + "src/ui/tui/primitives/SplitView.tsx", + "src/ui/tui/primitives/TabContainer.tsx", + "src/ui/tui/primitives/TextBlock.tsx", + "src/ui/tui/primitives/ViewportTooSmall.tsx", + "src/ui/tui/primitives/content-types.ts", + "src/ui/tui/primitives/layout-helpers.ts", + "src/ui/tui/primitives/link-helpers.ts", + "src/ui/tui/primitives/picker-filter.ts", + "src/ui/tui/primitives/text-helpers.ts", + "src/ui/tui/router.ts", + "src/ui/tui/screen-registry.tsx", + "src/ui/tui/screen-sequences.ts", + "src/ui/tui/screens/AgentSkillIntroScreen.tsx", + "src/ui/tui/screens/AiObservabilityIntroScreen.tsx", + "src/ui/tui/screens/AiOptInRequiredScreen.tsx", + "src/ui/tui/screens/AuthErrorScreen.tsx", + "src/ui/tui/screens/AuthScreen.tsx", + "src/ui/tui/screens/ErrorTrackingDetectScreen.tsx", + "src/ui/tui/screens/ErrorTrackingIntroScreen.tsx", + "src/ui/tui/screens/ExitScreen.tsx", + "src/ui/tui/screens/IntroScreenLayout.tsx", + "src/ui/tui/screens/KeepSkillsScreen.tsx", + "src/ui/tui/screens/ManagedSettingsScreen.tsx", + "src/ui/tui/screens/ManualAuthCodeScreen.tsx", + "src/ui/tui/screens/McpScreen.tsx", + "src/ui/tui/screens/McpSuggestedPromptsScreen.tsx", + "src/ui/tui/screens/MetricsIntroScreen.tsx", + "src/ui/tui/screens/MigrationIntroScreen.tsx", + "src/ui/tui/screens/MintFailureScreen.tsx", + "src/ui/tui/screens/OutroScreen.tsx", + "src/ui/tui/screens/PortConflictScreen.tsx", + "src/ui/tui/screens/PostHogIntegrationIntroScreen.tsx", + "src/ui/tui/screens/RevenueIntroScreen.tsx", + "src/ui/tui/screens/RunScreen.tsx", + "src/ui/tui/screens/SelfDrivingGitHubScreen.tsx", + "src/ui/tui/screens/SelfDrivingHandoffScreen.tsx", + "src/ui/tui/screens/SelfDrivingIntegrationCheckScreen.tsx", + "src/ui/tui/screens/SelfDrivingIntegrationDetectScreen.tsx", + "src/ui/tui/screens/SelfDrivingIntroScreen.tsx", + "src/ui/tui/screens/SessionTimeoutScreen.tsx", + "src/ui/tui/screens/SettingsOverrideScreen.tsx", + "src/ui/tui/screens/SetupScreen.tsx", + "src/ui/tui/screens/SkillSourceInfo.tsx", + "src/ui/tui/screens/SlackConnectScreen.tsx", + "src/ui/tui/screens/SourceMapsDetectScreen.tsx", + "src/ui/tui/screens/SourceMapsIntroScreen.tsx", + "src/ui/tui/screens/SourceMapsOutroScreen.tsx", + "src/ui/tui/screens/TaskNoticeScreen.tsx", + "src/ui/tui/screens/WarehouseIntroScreen.tsx", + "src/ui/tui/screens/WizardAskScreen.tsx", + "src/ui/tui/screens/audit/AuditAreaPane.tsx", + "src/ui/tui/screens/audit/AuditChecksOutroSection.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/AreaHeaderRow.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/AuditChecksViewer.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/CheckRow.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/DetailRow.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/Footer.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/Header.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/Legend.tsx", + "src/ui/tui/screens/audit/AuditChecksViewer/layout.ts", + "src/ui/tui/screens/audit/AuditChecksViewer/sort.ts", + "src/ui/tui/screens/audit/AuditIntroScreen.tsx", + "src/ui/tui/screens/audit/AuditOutroScreen.tsx", + "src/ui/tui/screens/audit/AuditRunScreen.tsx", + "src/ui/tui/screens/audit/PendingChecksList.tsx", + "src/ui/tui/screens/audit/slides/eventCapture.tsx", + "src/ui/tui/screens/audit/slides/events-audit/createDashboard.tsx", + "src/ui/tui/screens/audit/slides/events-audit/detectSdk.tsx", + "src/ui/tui/screens/audit/slides/events-audit/enrichSites.tsx", + "src/ui/tui/screens/audit/slides/events-audit/index.ts", + "src/ui/tui/screens/audit/slides/events-audit/queryVolume.tsx", + "src/ui/tui/screens/audit/slides/events-audit/scanSites.tsx", + "src/ui/tui/screens/audit/slides/events-audit/uploadNotebook.tsx", + "src/ui/tui/screens/audit/slides/events-audit/writeReport.tsx", + "src/ui/tui/screens/audit/slides/identification.tsx", + "src/ui/tui/screens/audit/slides/index.ts", + "src/ui/tui/screens/audit/slides/installation.tsx", + "src/ui/tui/screens/audit/slides/liveData.tsx", + "src/ui/tui/screens/audit/slides/shared.tsx", + "src/ui/tui/screens/audit/slides/uploadNotebook.tsx", + "src/ui/tui/screens/audit/slides/writeReport.tsx", + "src/ui/tui/screens/doctor/DoctorIntroScreen.tsx", + "src/ui/tui/screens/doctor/DoctorReportScreen.tsx", + "src/ui/tui/screens/doctor/IssueTable.tsx", + "src/ui/tui/screens/health/HealthCheckScreen.tsx", + "src/ui/tui/services/coding-agent-launcher.ts", + "src/ui/tui/services/mcp-installer.ts", + "src/ui/tui/services/mcp-suggested-prompts-services.ts", + "src/ui/tui/start-tui.ts", + "src/ui/tui/store.ts", + "src/ui/tui/styles.ts", + "src/ui/tui/terminal.ts", + "src/ui/wizard-ui.ts", + "src/utils/atomic-ledger.ts", + "src/utils/bounded-fs.ts", + "src/utils/clipboard.ts", + "src/utils/custom-headers.ts", + "src/utils/debug.ts", + "src/utils/env-api-key.ts", + "src/utils/env-scan.ts", + "src/utils/environment.ts", + "src/utils/links.ts", + "src/utils/oauth-errors.ts", + "src/utils/oauth.ts", + "src/utils/package-json.ts", + "src/utils/package-manager.ts", + "src/utils/paths.ts", + "src/utils/project-resolution.ts", + "src/utils/provisioning.ts", + "src/utils/semver.ts", + "src/utils/setup-utils.ts", + "src/utils/terminal-bell.ts", + "src/utils/urls.ts", + "src/utils/wizard-abort.ts", + "src/wizard.ts" + ] } diff --git a/scripts/chunk-manifest.no-jest.ts b/scripts/chunk-manifest.no-jest.ts index 623c2e064..a82eb982e 100644 --- a/scripts/chunk-manifest.no-jest.ts +++ b/scripts/chunk-manifest.no-jest.ts @@ -4,11 +4,19 @@ * Hash suffixes are stripped so the output is stable across builds. * * tsx scripts/chunk-manifest.no-jest.ts [distDir] > manifest.json + * tsx scripts/chunk-manifest.no-jest.ts [distDir] --summary > summary.json + * + * `--summary` prints only what is stable across platforms: the chunk names + * and the sorted set of every bundled source. Rolldown assigns shared + * modules to different chunks on macOS and Linux, so the per-chunk view is + * for reading, and the summary is what CI diffs against the fixture. */ import fs from 'fs'; import path from 'path'; -const dist = path.resolve(process.argv[2] ?? 'dist'); +const args = process.argv.slice(2); +const summary = args.includes('--summary'); +const dist = path.resolve(args.find((a) => !a.startsWith('--')) ?? 'dist'); const root = path.resolve(dist, '..'); const stripHash = (file: string): string => @@ -37,4 +45,12 @@ for (const file of fs manifest[stripHash(file)] = { sources, imports: [...imports].sort() }; } -process.stdout.write(JSON.stringify(manifest, null, 2) + '\n'); +const output = summary + ? { + chunks: Object.keys(manifest).sort(), + sources: [ + ...new Set(Object.values(manifest).flatMap((c) => c.sources)), + ].sort(), + } + : manifest; +process.stdout.write(JSON.stringify(output, null, 2) + '\n'); From 260a040e8cbd1e902a5fa341ccbfb54c0f35c574 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Mon, 21 Sep 2026 15:06:20 -0400 Subject: [PATCH 6/9] chore(build): record the bundle fixtures from the workflow artifact Sourcemap sources differ between macOS and Linux, so a locally recorded summary can never match the runner. The prod fixture now comes from the Surfaces artifact. The job builds both variants and uploads both summaries before diffing, so a drift still leaves the files to re-record from. Generated-By: PostHog Desktop Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589 --- .github/workflows/surfaces.yml | 15 +++++++++------ scripts/README.md | 14 +++++++------- scripts/__fixtures__/chunk-manifest.prod.json | 8 ++------ scripts/chunk-manifest.no-jest.ts | 9 +++++---- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/.github/workflows/surfaces.yml b/.github/workflows/surfaces.yml index f8a05e2bf..fcaac8de8 100644 --- a/.github/workflows/surfaces.yml +++ b/.github/workflows/surfaces.yml @@ -47,20 +47,17 @@ jobs: - run: pnpm install --frozen-lockfile - name: Production build and smoke test run: pnpm build - - name: Production chunk summary matches the fixture + - name: Production chunk manifest and summary run: | npx tsx scripts/chunk-manifest.no-jest.ts dist > chunk-manifest.prod.json npx tsx scripts/chunk-manifest.no-jest.ts dist --summary > chunk-summary.prod.json - npx prettier --write chunk-summary.prod.json - diff scripts/__fixtures__/chunk-manifest.prod.json chunk-summary.prod.json - name: CI build and smoke test run: pnpm build:ci - - name: CI chunk summary matches the fixture + - name: CI chunk manifest and summary run: | npx tsx scripts/chunk-manifest.no-jest.ts dist > chunk-manifest.ci.json npx tsx scripts/chunk-manifest.no-jest.ts dist --summary > chunk-summary.ci.json - npx prettier --write chunk-summary.ci.json - diff scripts/__fixtures__/chunk-manifest.ci.json chunk-summary.ci.json + - run: npx prettier --write chunk-summary.prod.json chunk-summary.ci.json - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 if: always() with: @@ -68,3 +65,9 @@ jobs: path: | chunk-manifest.*.json chunk-summary.*.json + # Both summaries are uploaded above, so a drift here still leaves the + # artifact to re-record the fixtures from. + - name: Summaries match the fixtures + run: | + diff scripts/__fixtures__/chunk-manifest.prod.json chunk-summary.prod.json + diff scripts/__fixtures__/chunk-manifest.ci.json chunk-summary.ci.json diff --git a/scripts/README.md b/scripts/README.md index eefd481d7..2ff25b674 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -12,13 +12,13 @@ real ink render) and is driven purely by store state manipulation; a PTY parent ([`e2e-harness/tui-capture.ts`](../e2e-harness/tui-capture.ts), node-pty + `@xterm/headless`) captures the real rendered screen. -| Script | What it does | Needs | -| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | -| **`tui-host.no-jest.ts`** | Real TUI host: `MODE=fixed` follows a profile; `MODE=serve` accepts socket commands. | `APP_DIR`, `PROJECT_ID`, key for a full run, `SNAP_CTRL`; run under a PTY, with `CONTROL_SOCK` in serve mode | -| **`tui-snapshots.no-jest.ts`** | Runs the fixed host and saves colored `SNAP_OUT/NN-.ans` frames, including within-screen progress. | `SNAP_OUT`, `APP_DIR`, `PROJECT_ID`, `POSTHOG_KEY_FILE` or `POSTHOG_PERSONAL_API_KEY` | -| **`wizard-ci-mcp.no-jest.ts`** | Stdio MCP server: `open_app`, `read_state`, `perform_action`, `render_screen`, `run_agent`. Screen output is plain text. | Spawns the host; `open_app` requires `appDir` and `projectId`, with optional `keyFile`, `apiKey`, `region` | -| **`chunk-manifest.no-jest.ts`** | Prints a structural manifest of `dist/`: per chunk, the source files it contains and the chunks it imports, hash suffixes stripped. `--summary` prints the chunk names and the sorted source set, which is stable across macOS and Linux. The Surfaces workflow diffs that summary against `scripts/__fixtures__/chunk-manifest.{prod,ci}.json`. | A built `dist/` | -| **`wizard-ci-explore.no-jest.ts`** | `pnpm wizard-ci-explore`: opens an app, confirms setup, reads state, prints one frame, and exits. It does not run the agent. | `APP_DIR`, `PROJECT_ID`; optional `POSTHOG_KEY_FILE` | +| Script | What it does | Needs | +| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| **`tui-host.no-jest.ts`** | Real TUI host: `MODE=fixed` follows a profile; `MODE=serve` accepts socket commands. | `APP_DIR`, `PROJECT_ID`, key for a full run, `SNAP_CTRL`; run under a PTY, with `CONTROL_SOCK` in serve mode | +| **`tui-snapshots.no-jest.ts`** | Runs the fixed host and saves colored `SNAP_OUT/NN-.ans` frames, including within-screen progress. | `SNAP_OUT`, `APP_DIR`, `PROJECT_ID`, `POSTHOG_KEY_FILE` or `POSTHOG_PERSONAL_API_KEY` | +| **`wizard-ci-mcp.no-jest.ts`** | Stdio MCP server: `open_app`, `read_state`, `perform_action`, `render_screen`, `run_agent`. Screen output is plain text. | Spawns the host; `open_app` requires `appDir` and `projectId`, with optional `keyFile`, `apiKey`, `region` | +| **`chunk-manifest.no-jest.ts`** | Prints a structural manifest of `dist/`: per chunk, the source files it contains and the chunks it imports, hash suffixes stripped. `--summary` prints the chunk names and the sorted source set. The Surfaces workflow diffs that summary against `scripts/__fixtures__/chunk-manifest.{prod,ci}.json`. Sourcemap sources differ between macOS and Linux, so record the fixtures from the workflow's `chunk-manifests-` artifact, never from a local build. | A built `dist/` | +| **`wizard-ci-explore.no-jest.ts`** | `pnpm wizard-ci-explore`: opens an app, confirms setup, reads state, prints one frame, and exits. It does not run the agent. | `APP_DIR`, `PROJECT_ID`; optional `POSTHOG_KEY_FILE` | > You usually don't call these directly — `pnpm wizard-ci-snapshots` (in > [wizard-workbench](https://github.com/PostHog/wizard-workbench)) orchestrates diff --git a/scripts/__fixtures__/chunk-manifest.prod.json b/scripts/__fixtures__/chunk-manifest.prod.json index 345100dcd..acac6f86b 100644 --- a/scripts/__fixtures__/chunk-manifest.prod.json +++ b/scripts/__fixtures__/chunk-manifest.prod.json @@ -233,7 +233,6 @@ "src/lib/programs/audit/index.ts", "src/lib/programs/audit/ledger-watcher.ts", "src/lib/programs/audit/seed.ts", - "src/lib/programs/audit/types.ts", "src/lib/programs/dispatch-family.ts", "src/lib/programs/error-tracking-upload-source-maps/content/index.tsx", "src/lib/programs/error-tracking-upload-source-maps/detect-agentic.ts", @@ -245,7 +244,6 @@ "src/lib/programs/error-tracking/content/tips.ts", "src/lib/programs/error-tracking/detect-agentic.ts", "src/lib/programs/error-tracking/index.ts", - "src/lib/programs/events-audit/constants.ts", "src/lib/programs/events-audit/index.ts", "src/lib/programs/events-audit/seed.ts", "src/lib/programs/events-audit/steps.ts", @@ -263,7 +261,6 @@ "src/lib/programs/posthog-doctor/kind-metadata.ts", "src/lib/programs/posthog-doctor/steps.ts", "src/lib/programs/posthog-doctor/types.ts", - "src/lib/programs/posthog-integration/constants.ts", "src/lib/programs/posthog-integration/content/data-flow.tsx", "src/lib/programs/posthog-integration/content/funnel.tsx", "src/lib/programs/posthog-integration/content/index.tsx", @@ -307,7 +304,6 @@ "src/lib/runners/run-wizard.ts", "src/lib/safe-tools.ts", "src/lib/secret-vault.ts", - "src/lib/skill-install.ts", "src/lib/task-stream/audit-areas.ts", "src/lib/task-stream/destinations/file.ts", "src/lib/task-stream/destinations/posthog.ts", @@ -322,8 +318,6 @@ "src/lib/wizard-tools/handoff.ts", "src/lib/wizard-tools/mcp.ts", "src/lib/wizard-tools/tools.ts", - "src/lib/yara-hooks.ts", - "src/lib/yara-policy.ts", "src/steps/add-mcp-server-to-clients/MCPClient.ts", "src/steps/add-mcp-server-to-clients/browser-client.ts", "src/steps/add-mcp-server-to-clients/clients/claude-code.ts", @@ -509,8 +503,10 @@ "src/ui/tui/styles.ts", "src/ui/tui/terminal.ts", "src/ui/wizard-ui.ts", + "src/utils/analytics.ts", "src/utils/atomic-ledger.ts", "src/utils/bounded-fs.ts", + "src/utils/ci-flag-overrides.ts", "src/utils/clipboard.ts", "src/utils/custom-headers.ts", "src/utils/debug.ts", diff --git a/scripts/chunk-manifest.no-jest.ts b/scripts/chunk-manifest.no-jest.ts index a82eb982e..507d672f9 100644 --- a/scripts/chunk-manifest.no-jest.ts +++ b/scripts/chunk-manifest.no-jest.ts @@ -6,10 +6,11 @@ * tsx scripts/chunk-manifest.no-jest.ts [distDir] > manifest.json * tsx scripts/chunk-manifest.no-jest.ts [distDir] --summary > summary.json * - * `--summary` prints only what is stable across platforms: the chunk names - * and the sorted set of every bundled source. Rolldown assigns shared - * modules to different chunks on macOS and Linux, so the per-chunk view is - * for reading, and the summary is what CI diffs against the fixture. + * `--summary` prints the chunk names and the sorted set of every bundled + * source. Rolldown assigns shared modules to different chunks on macOS and + * Linux and the sourcemaps list different sources, so the fixtures under + * scripts/__fixtures__ are recorded from the Surfaces workflow's artifact, + * never from a local build. Locally, use the full manifest for reading. */ import fs from 'fs'; import path from 'path'; From 14b3bd9bd9825b4c0486ea4f235464455eddaec5 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Mon, 21 Sep 2026 15:07:52 -0400 Subject: [PATCH 7/9] chore(build): record the CI bundle fixture from the workflow artifact Same source as the prod fixture one commit earlier. The prod summary from this run matched its fixture byte for byte, so the gate holds on Linux. Generated-By: PostHog Desktop Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589 --- scripts/__fixtures__/chunk-manifest.ci.json | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/scripts/__fixtures__/chunk-manifest.ci.json b/scripts/__fixtures__/chunk-manifest.ci.json index 852306aa5..a8c1b57b4 100644 --- a/scripts/__fixtures__/chunk-manifest.ci.json +++ b/scripts/__fixtures__/chunk-manifest.ci.json @@ -86,7 +86,6 @@ "src/commands/slack.ts", "src/commands/upload-sourcemaps.ts", "src/commands/warehouse.ts", - "src/env.ts", "src/frameworks/android/android-wizard-agent.ts", "src/frameworks/android/utils.ts", "src/frameworks/angular/angular-wizard-agent.ts", @@ -181,7 +180,6 @@ "src/lib/agent/triage-provider.ts", "src/lib/api.ts", "src/lib/auth-session-state.ts", - "src/lib/constants.ts", "src/lib/detection/agentic.ts", "src/lib/detection/context.ts", "src/lib/detection/features.ts", @@ -200,9 +198,6 @@ "src/lib/fetch-retry.ts", "src/lib/file-watcher.ts", "src/lib/framework-config.ts", - "src/lib/headless-mode.ts", - "src/lib/health-checks/endpoints.ts", - "src/lib/health-checks/readiness.ts", "src/lib/host-resolution.ts", "src/lib/local-dev.ts", "src/lib/mcp-project-profile.ts", @@ -313,7 +308,6 @@ "src/lib/task-stream/destinations/posthog.ts", "src/lib/task-stream/event-plan-watcher.ts", "src/lib/task-stream/task-stream-push.ts", - "src/lib/version.ts", "src/lib/warehouse-sources/detect.ts", "src/lib/warehouse-sources/registry.ts", "src/lib/wizard-ask-bridge.ts", @@ -344,8 +338,6 @@ "src/steps/upload-environment-variables/providers/vercel.ts", "src/telemetry.ts", "src/ui/headless-ui.ts", - "src/ui/index.ts", - "src/ui/logging-ui.ts", "src/ui/mint-failure.ts", "src/ui/tui/App.tsx", "src/ui/tui/components/LearnCard.tsx", @@ -508,14 +500,10 @@ "src/ui/tui/store.ts", "src/ui/tui/styles.ts", "src/ui/tui/terminal.ts", - "src/ui/wizard-ui.ts", - "src/utils/analytics.ts", "src/utils/atomic-ledger.ts", "src/utils/bounded-fs.ts", - "src/utils/ci-flag-overrides.ts", "src/utils/clipboard.ts", "src/utils/custom-headers.ts", - "src/utils/debug.ts", "src/utils/env-api-key.ts", "src/utils/env-scan.ts", "src/utils/environment.ts", @@ -524,7 +512,6 @@ "src/utils/oauth.ts", "src/utils/package-json.ts", "src/utils/package-manager.ts", - "src/utils/paths.ts", "src/utils/project-resolution.ts", "src/utils/provisioning.ts", "src/utils/semver.ts", From d6705947ac1f6dde2f05e271f8539617ee43e7e5 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Mon, 21 Sep 2026 15:14:19 -0400 Subject: [PATCH 8/9] chore(ci): report surface drift without blocking the pull request Architecture and Bundle audit run with continue-on-error. Drift in the import edges or the chunk summaries lands in the job summary with the diff and the file to re-record. The unit-test goldens in build.yml still block. Generated-By: PostHog Desktop Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589 --- .github/workflows/surfaces.yml | 44 ++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/.github/workflows/surfaces.yml b/.github/workflows/surfaces.yml index fcaac8de8..adb987363 100644 --- a/.github/workflows/surfaces.yml +++ b/.github/workflows/surfaces.yml @@ -9,12 +9,14 @@ permissions: contents: read # Unit tests run once, in build.yml. This workflow owns the two checks that -# workflow does not: the import-boundary test and the bundle shape. +# workflow does not: the import-boundary test and the bundle shape. Both +# report drift in the job summary and never block a pull request, for now. jobs: architecture: name: Architecture runs-on: ubuntu-latest timeout-minutes: 10 + continue-on-error: true steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - uses: pnpm/action-setup@eae0cfeb286e66ffb5155f1a79b90583a127a68b # v2.4.1 @@ -28,12 +30,29 @@ jobs: - run: pnpm install --frozen-lockfile - run: node scripts/generate-version.cjs - run: pnpm typecheck - - run: pnpm test:arch + - name: Import boundaries (drift is reported, not blocking) + run: | + set +e + pnpm test:arch 2>&1 | tee arch.log + status=${PIPESTATUS[0]} + if [ "$status" -ne 0 ]; then + { + echo '## Import boundary drift' + echo + echo 'A cross-surface edge changed. Update `src/__tests__/architecture/known-violations.json` if intended.' + echo + echo '```' + grep -E 'matrix:|ink-outside-tui|->' arch.log | head -40 + echo '```' + } >> "$GITHUB_STEP_SUMMARY" + fi + exit $status bundle: name: Bundle audit runs-on: ubuntu-latest timeout-minutes: 15 + continue-on-error: true steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - uses: pnpm/action-setup@eae0cfeb286e66ffb5155f1a79b90583a127a68b # v2.4.1 @@ -67,7 +86,22 @@ jobs: chunk-summary.*.json # Both summaries are uploaded above, so a drift here still leaves the # artifact to re-record the fixtures from. - - name: Summaries match the fixtures + - name: Summaries match the fixtures (drift is reported, not blocking) run: | - diff scripts/__fixtures__/chunk-manifest.prod.json chunk-summary.prod.json - diff scripts/__fixtures__/chunk-manifest.ci.json chunk-summary.ci.json + set +e + status=0 + for v in prod ci; do + if ! diff scripts/__fixtures__/chunk-manifest.$v.json chunk-summary.$v.json > drift.$v.txt; then + status=1 + { + echo "## Bundle drift ($v build)" + echo + echo "Chunk names or bundled sources changed. Re-record \`scripts/__fixtures__/chunk-manifest.$v.json\` from this run's artifact if intended." + echo + echo '```diff' + cat drift.$v.txt + echo '```' + } >> "$GITHUB_STEP_SUMMARY" + fi + done + exit $status From 730848e4669375d5a77b6a6df44c22c8bcc53d3d Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Mon, 21 Sep 2026 15:19:30 -0400 Subject: [PATCH 9/9] chore(ci): drop the surfaces workflow and the bundle fixtures The architecture test already runs inside pnpm test. The bundle audit was a platform-dependent proxy for the startup-closure check, which belongs in a unit test on dist once src/agent exists. chunk-manifest.no-jest.ts stays as a reading tool. Generated-By: PostHog Desktop Task-Id: d14e92bb-6ee1-49b5-8502-39cb80079589 --- .github/workflows/surfaces.yml | 107 ---- scripts/README.md | 14 +- scripts/__fixtures__/chunk-manifest.ci.json | 523 ----------------- scripts/__fixtures__/chunk-manifest.prod.json | 531 ------------------ scripts/chunk-manifest.no-jest.ts | 6 +- 5 files changed, 9 insertions(+), 1172 deletions(-) delete mode 100644 .github/workflows/surfaces.yml delete mode 100644 scripts/__fixtures__/chunk-manifest.ci.json delete mode 100644 scripts/__fixtures__/chunk-manifest.prod.json diff --git a/.github/workflows/surfaces.yml b/.github/workflows/surfaces.yml deleted file mode 100644 index adb987363..000000000 --- a/.github/workflows/surfaces.yml +++ /dev/null @@ -1,107 +0,0 @@ -name: 'Surfaces' -on: - push: - branches: - - main - pull_request: - -permissions: - contents: read - -# Unit tests run once, in build.yml. This workflow owns the two checks that -# workflow does not: the import-boundary test and the bundle shape. Both -# report drift in the job summary and never block a pull request, for now. -jobs: - architecture: - name: Architecture - runs-on: ubuntu-latest - timeout-minutes: 10 - continue-on-error: true - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - - uses: pnpm/action-setup@eae0cfeb286e66ffb5155f1a79b90583a127a68b # v2.4.1 - with: - version: 10.34.5 - run_install: false - - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 - with: - node-version-file: 'package.json' - cache: 'pnpm' - - run: pnpm install --frozen-lockfile - - run: node scripts/generate-version.cjs - - run: pnpm typecheck - - name: Import boundaries (drift is reported, not blocking) - run: | - set +e - pnpm test:arch 2>&1 | tee arch.log - status=${PIPESTATUS[0]} - if [ "$status" -ne 0 ]; then - { - echo '## Import boundary drift' - echo - echo 'A cross-surface edge changed. Update `src/__tests__/architecture/known-violations.json` if intended.' - echo - echo '```' - grep -E 'matrix:|ink-outside-tui|->' arch.log | head -40 - echo '```' - } >> "$GITHUB_STEP_SUMMARY" - fi - exit $status - - bundle: - name: Bundle audit - runs-on: ubuntu-latest - timeout-minutes: 15 - continue-on-error: true - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 - - uses: pnpm/action-setup@eae0cfeb286e66ffb5155f1a79b90583a127a68b # v2.4.1 - with: - version: 10.34.5 - run_install: false - - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 - with: - node-version-file: 'package.json' - cache: 'pnpm' - - run: pnpm install --frozen-lockfile - - name: Production build and smoke test - run: pnpm build - - name: Production chunk manifest and summary - run: | - npx tsx scripts/chunk-manifest.no-jest.ts dist > chunk-manifest.prod.json - npx tsx scripts/chunk-manifest.no-jest.ts dist --summary > chunk-summary.prod.json - - name: CI build and smoke test - run: pnpm build:ci - - name: CI chunk manifest and summary - run: | - npx tsx scripts/chunk-manifest.no-jest.ts dist > chunk-manifest.ci.json - npx tsx scripts/chunk-manifest.no-jest.ts dist --summary > chunk-summary.ci.json - - run: npx prettier --write chunk-summary.prod.json chunk-summary.ci.json - - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - if: always() - with: - name: chunk-manifests-${{ github.sha }} - path: | - chunk-manifest.*.json - chunk-summary.*.json - # Both summaries are uploaded above, so a drift here still leaves the - # artifact to re-record the fixtures from. - - name: Summaries match the fixtures (drift is reported, not blocking) - run: | - set +e - status=0 - for v in prod ci; do - if ! diff scripts/__fixtures__/chunk-manifest.$v.json chunk-summary.$v.json > drift.$v.txt; then - status=1 - { - echo "## Bundle drift ($v build)" - echo - echo "Chunk names or bundled sources changed. Re-record \`scripts/__fixtures__/chunk-manifest.$v.json\` from this run's artifact if intended." - echo - echo '```diff' - cat drift.$v.txt - echo '```' - } >> "$GITHUB_STEP_SUMMARY" - fi - done - exit $status diff --git a/scripts/README.md b/scripts/README.md index 2ff25b674..4fb836878 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -12,13 +12,13 @@ real ink render) and is driven purely by store state manipulation; a PTY parent ([`e2e-harness/tui-capture.ts`](../e2e-harness/tui-capture.ts), node-pty + `@xterm/headless`) captures the real rendered screen. -| Script | What it does | Needs | -| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | -| **`tui-host.no-jest.ts`** | Real TUI host: `MODE=fixed` follows a profile; `MODE=serve` accepts socket commands. | `APP_DIR`, `PROJECT_ID`, key for a full run, `SNAP_CTRL`; run under a PTY, with `CONTROL_SOCK` in serve mode | -| **`tui-snapshots.no-jest.ts`** | Runs the fixed host and saves colored `SNAP_OUT/NN-.ans` frames, including within-screen progress. | `SNAP_OUT`, `APP_DIR`, `PROJECT_ID`, `POSTHOG_KEY_FILE` or `POSTHOG_PERSONAL_API_KEY` | -| **`wizard-ci-mcp.no-jest.ts`** | Stdio MCP server: `open_app`, `read_state`, `perform_action`, `render_screen`, `run_agent`. Screen output is plain text. | Spawns the host; `open_app` requires `appDir` and `projectId`, with optional `keyFile`, `apiKey`, `region` | -| **`chunk-manifest.no-jest.ts`** | Prints a structural manifest of `dist/`: per chunk, the source files it contains and the chunks it imports, hash suffixes stripped. `--summary` prints the chunk names and the sorted source set. The Surfaces workflow diffs that summary against `scripts/__fixtures__/chunk-manifest.{prod,ci}.json`. Sourcemap sources differ between macOS and Linux, so record the fixtures from the workflow's `chunk-manifests-` artifact, never from a local build. | A built `dist/` | -| **`wizard-ci-explore.no-jest.ts`** | `pnpm wizard-ci-explore`: opens an app, confirms setup, reads state, prints one frame, and exits. It does not run the agent. | `APP_DIR`, `PROJECT_ID`; optional `POSTHOG_KEY_FILE` | +| Script | What it does | Needs | +| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| **`tui-host.no-jest.ts`** | Real TUI host: `MODE=fixed` follows a profile; `MODE=serve` accepts socket commands. | `APP_DIR`, `PROJECT_ID`, key for a full run, `SNAP_CTRL`; run under a PTY, with `CONTROL_SOCK` in serve mode | +| **`tui-snapshots.no-jest.ts`** | Runs the fixed host and saves colored `SNAP_OUT/NN-.ans` frames, including within-screen progress. | `SNAP_OUT`, `APP_DIR`, `PROJECT_ID`, `POSTHOG_KEY_FILE` or `POSTHOG_PERSONAL_API_KEY` | +| **`wizard-ci-mcp.no-jest.ts`** | Stdio MCP server: `open_app`, `read_state`, `perform_action`, `render_screen`, `run_agent`. Screen output is plain text. | Spawns the host; `open_app` requires `appDir` and `projectId`, with optional `keyFile`, `apiKey`, `region` | +| **`chunk-manifest.no-jest.ts`** | Prints a structural manifest of `dist/`: per chunk, the source files it contains and the chunks it imports, hash suffixes stripped. `--summary` prints chunk names plus the sorted source set. A reading tool, nothing diffs its output. | A built `dist/` | +| **`wizard-ci-explore.no-jest.ts`** | `pnpm wizard-ci-explore`: opens an app, confirms setup, reads state, prints one frame, and exits. It does not run the agent. | `APP_DIR`, `PROJECT_ID`; optional `POSTHOG_KEY_FILE` | > You usually don't call these directly — `pnpm wizard-ci-snapshots` (in > [wizard-workbench](https://github.com/PostHog/wizard-workbench)) orchestrates diff --git a/scripts/__fixtures__/chunk-manifest.ci.json b/scripts/__fixtures__/chunk-manifest.ci.json deleted file mode 100644 index a8c1b57b4..000000000 --- a/scripts/__fixtures__/chunk-manifest.ci.json +++ /dev/null @@ -1,523 +0,0 @@ -{ - "chunks": [ - "add-mcp-server-to-clients.js", - "agent-interface.js", - "agent-prompt-loader.js", - "agent-runner.js", - "analytics.js", - "api.js", - "bin.js", - "bounded-fs.js", - "ci-install.js", - "debug.js", - "defaults.js", - "env-api-key.js", - "environment.js", - "errors.js", - "file-watcher.js", - "file.js", - "gateway-session.js", - "headless-ui.js", - "interactive.js", - "local-dev.js", - "mcp-prompt-streaming.js", - "mcp.js", - "mint-failure.js", - "non-interactive.js", - "orchestrator-tools.js", - "package-json.js", - "package-manager.js", - "pi.js", - "playground.js", - "posthog.js", - "provisioning.js", - "queue-tools.js", - "registry.js", - "rolldown-runtime.js", - "security.js", - "setup-utils.js", - "start-tui.js", - "steps.js", - "store.js", - "subagent.js", - "task-stream.js", - "task.js", - "tasks.js", - "telemetry.js", - "terminal.js", - "tools.js", - "wizard-abort.js", - "wizard-session.js", - "yara-hooks.js" - ], - "sources": [ - "bin.ts", - "src/commands/ai-observability.ts", - "src/commands/audit.ts", - "src/commands/basic-integration/ci-install.ts", - "src/commands/basic-integration/index.ts", - "src/commands/basic-integration/interactive.ts", - "src/commands/basic-integration/non-interactive.ts", - "src/commands/basic-integration/playground.ts", - "src/commands/basic-integration/skill.ts", - "src/commands/cli/add.ts", - "src/commands/cli/index.ts", - "src/commands/command.ts", - "src/commands/doctor.ts", - "src/commands/error-tracking.ts", - "src/commands/factories/family-command-factory.ts", - "src/commands/factories/family-picker.tsx", - "src/commands/factories/native-command-factory.ts", - "src/commands/factories/shared.ts", - "src/commands/mcp-analytics.ts", - "src/commands/mcp/add.ts", - "src/commands/mcp/index.ts", - "src/commands/mcp/remove.ts", - "src/commands/mcp/tui-availability.ts", - "src/commands/mcp/tutorial.ts", - "src/commands/metrics.ts", - "src/commands/migrate.ts", - "src/commands/provision.ts", - "src/commands/replay-vision.ts", - "src/commands/revenue.ts", - "src/commands/self-driving.ts", - "src/commands/skill-program-options.ts", - "src/commands/skill.ts", - "src/commands/slack.ts", - "src/commands/upload-sourcemaps.ts", - "src/commands/warehouse.ts", - "src/frameworks/android/android-wizard-agent.ts", - "src/frameworks/android/utils.ts", - "src/frameworks/angular/angular-wizard-agent.ts", - "src/frameworks/angular/utils.ts", - "src/frameworks/astro/astro-wizard-agent.ts", - "src/frameworks/astro/utils.ts", - "src/frameworks/django/django-wizard-agent.ts", - "src/frameworks/django/utils.ts", - "src/frameworks/elixir/elixir-wizard-agent.ts", - "src/frameworks/fastapi/fastapi-wizard-agent.ts", - "src/frameworks/fastapi/utils.ts", - "src/frameworks/flask/flask-wizard-agent.ts", - "src/frameworks/flask/utils.ts", - "src/frameworks/flutter/flutter-wizard-agent.ts", - "src/frameworks/go/go-wizard-agent.ts", - "src/frameworks/java/java-wizard-agent.ts", - "src/frameworks/javascript-node/javascript-node-wizard-agent.ts", - "src/frameworks/javascript-web/javascript-web-wizard-agent.ts", - "src/frameworks/javascript-web/utils.ts", - "src/frameworks/kmp/kmp-wizard-agent.ts", - "src/frameworks/laravel/laravel-wizard-agent.ts", - "src/frameworks/laravel/utils.ts", - "src/frameworks/nextjs/nextjs-wizard-agent.ts", - "src/frameworks/nextjs/utils.ts", - "src/frameworks/nuxt/nuxt-wizard-agent.ts", - "src/frameworks/python/python-wizard-agent.ts", - "src/frameworks/python/utils.ts", - "src/frameworks/rails/rails-wizard-agent.ts", - "src/frameworks/rails/utils.ts", - "src/frameworks/react-native/react-native-wizard-agent.ts", - "src/frameworks/react-native/utils.ts", - "src/frameworks/react-router/react-router-wizard-agent.ts", - "src/frameworks/react-router/utils.ts", - "src/frameworks/ruby/ruby-wizard-agent.ts", - "src/frameworks/ruby/utils.ts", - "src/frameworks/rust/rust-wizard-agent.ts", - "src/frameworks/svelte/svelte-wizard-agent.ts", - "src/frameworks/swift/swift-wizard-agent.ts", - "src/frameworks/swift/utils.ts", - "src/frameworks/tanstack-router/tanstack-router-wizard-agent.ts", - "src/frameworks/tanstack-router/utils.ts", - "src/frameworks/tanstack-start/tanstack-start-wizard-agent.ts", - "src/frameworks/tanstack-start/utils.ts", - "src/frameworks/vue/vue-wizard-agent.ts", - "src/lib/agent/agent-env-isolation.ts", - "src/lib/agent/agent-interface.ts", - "src/lib/agent/agent-phase.ts", - "src/lib/agent/agent-prompt-loader.ts", - "src/lib/agent/agent-prompt.ts", - "src/lib/agent/agent-runner.ts", - "src/lib/agent/aio-capture.ts", - "src/lib/agent/bash-fence.ts", - "src/lib/agent/claude-settings.ts", - "src/lib/agent/commandments.ts", - "src/lib/agent/mcp-prompt-streaming.ts", - "src/lib/agent/output-signals.ts", - "src/lib/agent/runner/harness/anthropic/index.ts", - "src/lib/agent/runner/harness/pi/completion.ts", - "src/lib/agent/runner/harness/pi/gateway.ts", - "src/lib/agent/runner/harness/pi/index.ts", - "src/lib/agent/runner/harness/pi/mcp.ts", - "src/lib/agent/runner/harness/pi/orchestrator-tools.ts", - "src/lib/agent/runner/harness/pi/runtime-notes.ts", - "src/lib/agent/runner/harness/pi/security.ts", - "src/lib/agent/runner/harness/pi/subagent.ts", - "src/lib/agent/runner/harness/pi/task.ts", - "src/lib/agent/runner/harness/pi/tasks.ts", - "src/lib/agent/runner/harness/pi/tools.ts", - "src/lib/agent/runner/index.ts", - "src/lib/agent/runner/sequence/linear.ts", - "src/lib/agent/runner/sequence/orchestrator/executor.ts", - "src/lib/agent/runner/sequence/orchestrator/orchestrator-runner.ts", - "src/lib/agent/runner/sequence/orchestrator/queue-tools.ts", - "src/lib/agent/runner/sequence/orchestrator/queue.ts", - "src/lib/agent/runner/sequence/orchestrator/run-metrics.ts", - "src/lib/agent/runner/sequence/orchestrator/seeded-deps.ts", - "src/lib/agent/runner/shared/authenticate.ts", - "src/lib/agent/runner/shared/bootstrap.ts", - "src/lib/agent/runner/shared/errors.ts", - "src/lib/agent/runner/switchboard/commandments.ts", - "src/lib/agent/runner/switchboard/flags/index.ts", - "src/lib/agent/runner/switchboard/flags/orchestrator.ts", - "src/lib/agent/runner/switchboard/flags/schemes.ts", - "src/lib/agent/runner/switchboard/flags/self-driving.ts", - "src/lib/agent/runner/switchboard/harness.ts", - "src/lib/agent/runner/switchboard/index.ts", - "src/lib/agent/runner/switchboard/models.ts", - "src/lib/agent/runner/switchboard/sequence.ts", - "src/lib/agent/signals.ts", - "src/lib/agent/stored-login.ts", - "src/lib/agent/token-pricing.ts", - "src/lib/agent/triage-provider.ts", - "src/lib/api.ts", - "src/lib/auth-session-state.ts", - "src/lib/detection/agentic.ts", - "src/lib/detection/context.ts", - "src/lib/detection/features.ts", - "src/lib/detection/framework.ts", - "src/lib/detection/package-manager.ts", - "src/lib/detection/project-scope.ts", - "src/lib/errors/agent-map.ts", - "src/lib/errors/auth.ts", - "src/lib/errors/catalog.ts", - "src/lib/errors/codes.ts", - "src/lib/errors/detect-map.ts", - "src/lib/errors/emit.ts", - "src/lib/errors/run-failure.ts", - "src/lib/errors/sanitize.ts", - "src/lib/errors/skill-map.ts", - "src/lib/fetch-retry.ts", - "src/lib/file-watcher.ts", - "src/lib/framework-config.ts", - "src/lib/host-resolution.ts", - "src/lib/local-dev.ts", - "src/lib/mcp-project-profile.ts", - "src/lib/mcp-role-prompts.copy.json", - "src/lib/mcp-role-prompts.ts", - "src/lib/mcp-seed-events.ts", - "src/lib/middleware/benchmark.ts", - "src/lib/middleware/benchmarks/cache-tracker.ts", - "src/lib/middleware/benchmarks/compaction-tracker.ts", - "src/lib/middleware/benchmarks/context-size-tracker.ts", - "src/lib/middleware/benchmarks/cost-tracker.ts", - "src/lib/middleware/benchmarks/duration-tracker.ts", - "src/lib/middleware/benchmarks/index.ts", - "src/lib/middleware/benchmarks/json-writer.ts", - "src/lib/middleware/benchmarks/summary.ts", - "src/lib/middleware/benchmarks/token-tracker.ts", - "src/lib/middleware/benchmarks/turn-counter.ts", - "src/lib/middleware/config.ts", - "src/lib/middleware/phase-detector.ts", - "src/lib/middleware/pipeline.ts", - "src/lib/oauth/program-scopes.ts", - "src/lib/programs/agent-skill/content/index.tsx", - "src/lib/programs/agent-skill/index.ts", - "src/lib/programs/agent-skill/steps.ts", - "src/lib/programs/ai-observability/index.ts", - "src/lib/programs/ai-opt-in-gate.ts", - "src/lib/programs/audit/detect.ts", - "src/lib/programs/audit/index.ts", - "src/lib/programs/audit/ledger-watcher.ts", - "src/lib/programs/audit/seed.ts", - "src/lib/programs/audit/types.ts", - "src/lib/programs/dispatch-family.ts", - "src/lib/programs/error-tracking-upload-source-maps/content/index.tsx", - "src/lib/programs/error-tracking-upload-source-maps/detect-agentic.ts", - "src/lib/programs/error-tracking-upload-source-maps/detect.ts", - "src/lib/programs/error-tracking-upload-source-maps/index.ts", - "src/lib/programs/error-tracking-upload-source-maps/prompt.ts", - "src/lib/programs/error-tracking-upload-source-maps/steps.ts", - "src/lib/programs/error-tracking/content/index.tsx", - "src/lib/programs/error-tracking/content/tips.ts", - "src/lib/programs/error-tracking/detect-agentic.ts", - "src/lib/programs/error-tracking/index.ts", - "src/lib/programs/events-audit/constants.ts", - "src/lib/programs/events-audit/index.ts", - "src/lib/programs/events-audit/seed.ts", - "src/lib/programs/events-audit/steps.ts", - "src/lib/programs/mcp-analytics/index.ts", - "src/lib/programs/mcp/index.ts", - "src/lib/programs/metrics/index.ts", - "src/lib/programs/migration/content/free-tier.tsx", - "src/lib/programs/migration/content/index.tsx", - "src/lib/programs/migration/content/pricing-structure.tsx", - "src/lib/programs/migration/content/vendor-stack.tsx", - "src/lib/programs/migration/index.ts", - "src/lib/programs/migration/steps.ts", - "src/lib/programs/posthog-doctor/fetch.ts", - "src/lib/programs/posthog-doctor/index.ts", - "src/lib/programs/posthog-doctor/kind-metadata.ts", - "src/lib/programs/posthog-doctor/steps.ts", - "src/lib/programs/posthog-doctor/types.ts", - "src/lib/programs/posthog-integration/constants.ts", - "src/lib/programs/posthog-integration/content/data-flow.tsx", - "src/lib/programs/posthog-integration/content/funnel.tsx", - "src/lib/programs/posthog-integration/content/index.tsx", - "src/lib/programs/posthog-integration/content/line-chart.tsx", - "src/lib/programs/posthog-integration/content/product-suite.tsx", - "src/lib/programs/posthog-integration/detect.ts", - "src/lib/programs/posthog-integration/handoff.ts", - "src/lib/programs/posthog-integration/index.ts", - "src/lib/programs/posthog-integration/steps.ts", - "src/lib/programs/program-registry.ts", - "src/lib/programs/program-step.ts", - "src/lib/programs/replay-vision/index.ts", - "src/lib/programs/revenue-analytics/detect.ts", - "src/lib/programs/revenue-analytics/index.ts", - "src/lib/programs/revenue-analytics/steps.ts", - "src/lib/programs/self-driving/content/index.tsx", - "src/lib/programs/self-driving/content/pipeline-diagram.tsx", - "src/lib/programs/self-driving/content/pricing.ts", - "src/lib/programs/self-driving/content/tips.ts", - "src/lib/programs/self-driving/detect-agentic.ts", - "src/lib/programs/self-driving/detect.ts", - "src/lib/programs/self-driving/index.ts", - "src/lib/programs/self-driving/prompt.ts", - "src/lib/programs/self-driving/step-keys.ts", - "src/lib/programs/self-driving/steps.ts", - "src/lib/programs/shared/health-check-step.ts", - "src/lib/programs/shared/package-scanning.ts", - "src/lib/programs/shared/posthog-cli-preinstall.ts", - "src/lib/programs/slack/index.ts", - "src/lib/programs/warehouse-source/detect.ts", - "src/lib/programs/warehouse-source/index.ts", - "src/lib/programs/warehouse-source/steps.ts", - "src/lib/programs/web-analytics-doctor/detect.ts", - "src/lib/programs/web-analytics-doctor/index.ts", - "src/lib/programs/web-analytics-doctor/steps.ts", - "src/lib/registry.ts", - "src/lib/runners/resolve-no-telemetry.ts", - "src/lib/runners/run-non-interactive.ts", - "src/lib/runners/run-wizard-ci.ts", - "src/lib/runners/run-wizard-headless.ts", - "src/lib/runners/run-wizard.ts", - "src/lib/safe-tools.ts", - "src/lib/secret-vault.ts", - "src/lib/skill-install.ts", - "src/lib/task-stream/audit-areas.ts", - "src/lib/task-stream/destinations/file.ts", - "src/lib/task-stream/destinations/posthog.ts", - "src/lib/task-stream/event-plan-watcher.ts", - "src/lib/task-stream/task-stream-push.ts", - "src/lib/warehouse-sources/detect.ts", - "src/lib/warehouse-sources/registry.ts", - "src/lib/wizard-ask-bridge.ts", - "src/lib/wizard-session.ts", - "src/lib/wizard-spellbook.ts", - "src/lib/wizard-tools/handoff.ts", - "src/lib/wizard-tools/mcp.ts", - "src/lib/wizard-tools/tools.ts", - "src/lib/yara-hooks.ts", - "src/lib/yara-policy.ts", - "src/steps/add-mcp-server-to-clients/MCPClient.ts", - "src/steps/add-mcp-server-to-clients/browser-client.ts", - "src/steps/add-mcp-server-to-clients/clients/claude-code.ts", - "src/steps/add-mcp-server-to-clients/clients/claude-web.ts", - "src/steps/add-mcp-server-to-clients/clients/codex.ts", - "src/steps/add-mcp-server-to-clients/clients/cursor.ts", - "src/steps/add-mcp-server-to-clients/clients/opencode.ts", - "src/steps/add-mcp-server-to-clients/clients/visual-studio-code.ts", - "src/steps/add-mcp-server-to-clients/clients/zed.ts", - "src/steps/add-mcp-server-to-clients/defaults.ts", - "src/steps/add-mcp-server-to-clients/index.ts", - "src/steps/add-mcp-server-to-clients/login-client.ts", - "src/steps/add-mcp-server-to-clients/plugin-client.ts", - "src/steps/add-mcp-server-to-clients/results.ts", - "src/steps/install-cli-steering/index.ts", - "src/steps/upload-environment-variables/EnvironmentProvider.ts", - "src/steps/upload-environment-variables/index.ts", - "src/steps/upload-environment-variables/providers/vercel.ts", - "src/telemetry.ts", - "src/ui/headless-ui.ts", - "src/ui/mint-failure.ts", - "src/ui/tui/App.tsx", - "src/ui/tui/components/LearnCard.tsx", - "src/ui/tui/components/PhaseVisuals.tsx", - "src/ui/tui/components/PrivacyPanel.tsx", - "src/ui/tui/components/ServiceHealthList.tsx", - "src/ui/tui/components/StatusPeekTrigger.tsx", - "src/ui/tui/components/TipsCard.tsx", - "src/ui/tui/components/TitleBar.tsx", - "src/ui/tui/components/TokenCostHud.tsx", - "src/ui/tui/components/visualizer/CrateStack.tsx", - "src/ui/tui/components/visualizer/DashboardGrid.tsx", - "src/ui/tui/components/visualizer/DiffCascade.tsx", - "src/ui/tui/components/visualizer/LibraryShelf.tsx", - "src/ui/tui/components/visualizer/MatrixRain.tsx", - "src/ui/tui/components/visualizer/Tumblers.tsx", - "src/ui/tui/components/visualizer/grid.ts", - "src/ui/tui/components/visualizer/palette.ts", - "src/ui/tui/components/visualizer/panel.tsx", - "src/ui/tui/exit-line.ts", - "src/ui/tui/hooks/keyboard-hints-utils.ts", - "src/ui/tui/hooks/useDismissOnAnyKey.ts", - "src/ui/tui/hooks/useGithubConnection.ts", - "src/ui/tui/hooks/useKeyBindings.ts", - "src/ui/tui/hooks/useKeyboardHints.tsx", - "src/ui/tui/hooks/useStdoutDimensions.ts", - "src/ui/tui/hooks/useTick.ts", - "src/ui/tui/ink-ui.ts", - "src/ui/tui/playground/PlaygroundApp.tsx", - "src/ui/tui/playground/demos/AiOptInDemo.tsx", - "src/ui/tui/playground/demos/AskModalDemo.tsx", - "src/ui/tui/playground/demos/AuditChecksDemo.tsx", - "src/ui/tui/playground/demos/DoctorReportDemo.tsx", - "src/ui/tui/playground/demos/EndScreensDemo.tsx", - "src/ui/tui/playground/demos/HealthCheckDemo.tsx", - "src/ui/tui/playground/demos/InputDemo.tsx", - "src/ui/tui/playground/demos/KeyboardHintsDemo.tsx", - "src/ui/tui/playground/demos/LayoutDemo.tsx", - "src/ui/tui/playground/demos/LearnDeckDemo.tsx", - "src/ui/tui/playground/demos/LogDemo.tsx", - "src/ui/tui/playground/demos/McpDemo.tsx", - "src/ui/tui/playground/demos/McpSuggestedPromptsDemo.tsx", - "src/ui/tui/playground/demos/ModalDemo.tsx", - "src/ui/tui/playground/demos/ProgressDemo.tsx", - "src/ui/tui/playground/demos/RunScreenDemo.tsx", - "src/ui/tui/playground/demos/ViewportGuardDemo.tsx", - "src/ui/tui/playground/demos/WelcomeDemo.tsx", - "src/ui/tui/playground/start-playground.ts", - "src/ui/tui/posthog-integration-intro.ts", - "src/ui/tui/primitives/CardLayout.tsx", - "src/ui/tui/primitives/ConfirmButton.tsx", - "src/ui/tui/primitives/ConfirmationInput.tsx", - "src/ui/tui/primitives/ContentSequencer.tsx", - "src/ui/tui/primitives/DissolveTransition.tsx", - "src/ui/tui/primitives/Divider.tsx", - "src/ui/tui/primitives/EventPlanViewer.tsx", - "src/ui/tui/primitives/GroupedPickerMenu.tsx", - "src/ui/tui/primitives/HNViewer.tsx", - "src/ui/tui/primitives/KeyboardHintsBar.tsx", - "src/ui/tui/primitives/LinesBlock.tsx", - "src/ui/tui/primitives/LinkText.tsx", - "src/ui/tui/primitives/LoadingBox.tsx", - "src/ui/tui/primitives/LogViewer.tsx", - "src/ui/tui/primitives/ModalOverlay.tsx", - "src/ui/tui/primitives/NodeBlock.tsx", - "src/ui/tui/primitives/PickerMenu.tsx", - "src/ui/tui/primitives/ProgressList.tsx", - "src/ui/tui/primitives/PromptLabel.tsx", - "src/ui/tui/primitives/ScreenContainer.tsx", - "src/ui/tui/primitives/ScreenErrorBoundary.tsx", - "src/ui/tui/primitives/SplitView.tsx", - "src/ui/tui/primitives/TabContainer.tsx", - "src/ui/tui/primitives/TextBlock.tsx", - "src/ui/tui/primitives/ViewportTooSmall.tsx", - "src/ui/tui/primitives/content-types.ts", - "src/ui/tui/primitives/layout-helpers.ts", - "src/ui/tui/primitives/link-helpers.ts", - "src/ui/tui/primitives/picker-filter.ts", - "src/ui/tui/primitives/text-helpers.ts", - "src/ui/tui/router.ts", - "src/ui/tui/screen-registry.tsx", - "src/ui/tui/screen-sequences.ts", - "src/ui/tui/screens/AgentSkillIntroScreen.tsx", - "src/ui/tui/screens/AiObservabilityIntroScreen.tsx", - "src/ui/tui/screens/AiOptInRequiredScreen.tsx", - "src/ui/tui/screens/AuthErrorScreen.tsx", - "src/ui/tui/screens/AuthScreen.tsx", - "src/ui/tui/screens/ErrorTrackingDetectScreen.tsx", - "src/ui/tui/screens/ErrorTrackingIntroScreen.tsx", - "src/ui/tui/screens/ExitScreen.tsx", - "src/ui/tui/screens/IntroScreenLayout.tsx", - "src/ui/tui/screens/KeepSkillsScreen.tsx", - "src/ui/tui/screens/ManagedSettingsScreen.tsx", - "src/ui/tui/screens/ManualAuthCodeScreen.tsx", - "src/ui/tui/screens/McpScreen.tsx", - "src/ui/tui/screens/McpSuggestedPromptsScreen.tsx", - "src/ui/tui/screens/MetricsIntroScreen.tsx", - "src/ui/tui/screens/MigrationIntroScreen.tsx", - "src/ui/tui/screens/MintFailureScreen.tsx", - "src/ui/tui/screens/OutroScreen.tsx", - "src/ui/tui/screens/PortConflictScreen.tsx", - "src/ui/tui/screens/PostHogIntegrationIntroScreen.tsx", - "src/ui/tui/screens/RevenueIntroScreen.tsx", - "src/ui/tui/screens/RunScreen.tsx", - "src/ui/tui/screens/SelfDrivingGitHubScreen.tsx", - "src/ui/tui/screens/SelfDrivingHandoffScreen.tsx", - "src/ui/tui/screens/SelfDrivingIntegrationCheckScreen.tsx", - "src/ui/tui/screens/SelfDrivingIntegrationDetectScreen.tsx", - "src/ui/tui/screens/SelfDrivingIntroScreen.tsx", - "src/ui/tui/screens/SessionTimeoutScreen.tsx", - "src/ui/tui/screens/SettingsOverrideScreen.tsx", - "src/ui/tui/screens/SetupScreen.tsx", - "src/ui/tui/screens/SkillSourceInfo.tsx", - "src/ui/tui/screens/SlackConnectScreen.tsx", - "src/ui/tui/screens/SourceMapsDetectScreen.tsx", - "src/ui/tui/screens/SourceMapsIntroScreen.tsx", - "src/ui/tui/screens/SourceMapsOutroScreen.tsx", - "src/ui/tui/screens/TaskNoticeScreen.tsx", - "src/ui/tui/screens/WarehouseIntroScreen.tsx", - "src/ui/tui/screens/WizardAskScreen.tsx", - "src/ui/tui/screens/audit/AuditAreaPane.tsx", - "src/ui/tui/screens/audit/AuditChecksOutroSection.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/AreaHeaderRow.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/AuditChecksViewer.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/CheckRow.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/DetailRow.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/Footer.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/Header.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/Legend.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/layout.ts", - "src/ui/tui/screens/audit/AuditChecksViewer/sort.ts", - "src/ui/tui/screens/audit/AuditIntroScreen.tsx", - "src/ui/tui/screens/audit/AuditOutroScreen.tsx", - "src/ui/tui/screens/audit/AuditRunScreen.tsx", - "src/ui/tui/screens/audit/PendingChecksList.tsx", - "src/ui/tui/screens/audit/slides/eventCapture.tsx", - "src/ui/tui/screens/audit/slides/events-audit/createDashboard.tsx", - "src/ui/tui/screens/audit/slides/events-audit/detectSdk.tsx", - "src/ui/tui/screens/audit/slides/events-audit/enrichSites.tsx", - "src/ui/tui/screens/audit/slides/events-audit/index.ts", - "src/ui/tui/screens/audit/slides/events-audit/queryVolume.tsx", - "src/ui/tui/screens/audit/slides/events-audit/scanSites.tsx", - "src/ui/tui/screens/audit/slides/events-audit/uploadNotebook.tsx", - "src/ui/tui/screens/audit/slides/events-audit/writeReport.tsx", - "src/ui/tui/screens/audit/slides/identification.tsx", - "src/ui/tui/screens/audit/slides/index.ts", - "src/ui/tui/screens/audit/slides/installation.tsx", - "src/ui/tui/screens/audit/slides/liveData.tsx", - "src/ui/tui/screens/audit/slides/shared.tsx", - "src/ui/tui/screens/audit/slides/uploadNotebook.tsx", - "src/ui/tui/screens/audit/slides/writeReport.tsx", - "src/ui/tui/screens/doctor/DoctorIntroScreen.tsx", - "src/ui/tui/screens/doctor/DoctorReportScreen.tsx", - "src/ui/tui/screens/doctor/IssueTable.tsx", - "src/ui/tui/screens/health/HealthCheckScreen.tsx", - "src/ui/tui/services/coding-agent-launcher.ts", - "src/ui/tui/services/mcp-installer.ts", - "src/ui/tui/services/mcp-suggested-prompts-services.ts", - "src/ui/tui/start-tui.ts", - "src/ui/tui/store.ts", - "src/ui/tui/styles.ts", - "src/ui/tui/terminal.ts", - "src/utils/atomic-ledger.ts", - "src/utils/bounded-fs.ts", - "src/utils/clipboard.ts", - "src/utils/custom-headers.ts", - "src/utils/env-api-key.ts", - "src/utils/env-scan.ts", - "src/utils/environment.ts", - "src/utils/links.ts", - "src/utils/oauth-errors.ts", - "src/utils/oauth.ts", - "src/utils/package-json.ts", - "src/utils/package-manager.ts", - "src/utils/project-resolution.ts", - "src/utils/provisioning.ts", - "src/utils/semver.ts", - "src/utils/setup-utils.ts", - "src/utils/terminal-bell.ts", - "src/utils/urls.ts", - "src/wizard.ts" - ] -} diff --git a/scripts/__fixtures__/chunk-manifest.prod.json b/scripts/__fixtures__/chunk-manifest.prod.json deleted file mode 100644 index acac6f86b..000000000 --- a/scripts/__fixtures__/chunk-manifest.prod.json +++ /dev/null @@ -1,531 +0,0 @@ -{ - "chunks": [ - "add-mcp-server-to-clients.js", - "agent-interface.js", - "agent-prompt-loader.js", - "agent-runner.js", - "analytics.js", - "api.js", - "bin.js", - "bounded-fs.js", - "ci-install.js", - "debug.js", - "defaults.js", - "env-api-key.js", - "environment.js", - "errors.js", - "file-watcher.js", - "file.js", - "gateway-session.js", - "headless-ui.js", - "interactive.js", - "local-dev.js", - "mcp-prompt-streaming.js", - "mcp.js", - "mint-failure.js", - "non-interactive.js", - "orchestrator-tools.js", - "package-json.js", - "package-manager.js", - "pi.js", - "playground.js", - "posthog.js", - "provisioning.js", - "queue-tools.js", - "registry.js", - "rolldown-runtime.js", - "security.js", - "setup-utils.js", - "start-tui.js", - "steps.js", - "store.js", - "subagent.js", - "task-stream.js", - "task.js", - "tasks.js", - "telemetry.js", - "terminal.js", - "tools.js", - "wizard-abort.js", - "wizard-session.js", - "yara-hooks.js" - ], - "sources": [ - "bin.ts", - "src/commands/ai-observability.ts", - "src/commands/audit.ts", - "src/commands/basic-integration/ci-install.ts", - "src/commands/basic-integration/index.ts", - "src/commands/basic-integration/interactive.ts", - "src/commands/basic-integration/non-interactive.ts", - "src/commands/basic-integration/playground.ts", - "src/commands/basic-integration/skill.ts", - "src/commands/cli/add.ts", - "src/commands/cli/index.ts", - "src/commands/command.ts", - "src/commands/doctor.ts", - "src/commands/error-tracking.ts", - "src/commands/factories/family-command-factory.ts", - "src/commands/factories/family-picker.tsx", - "src/commands/factories/native-command-factory.ts", - "src/commands/factories/shared.ts", - "src/commands/mcp-analytics.ts", - "src/commands/mcp/add.ts", - "src/commands/mcp/index.ts", - "src/commands/mcp/remove.ts", - "src/commands/mcp/tui-availability.ts", - "src/commands/mcp/tutorial.ts", - "src/commands/metrics.ts", - "src/commands/migrate.ts", - "src/commands/provision.ts", - "src/commands/replay-vision.ts", - "src/commands/revenue.ts", - "src/commands/self-driving.ts", - "src/commands/skill-program-options.ts", - "src/commands/skill.ts", - "src/commands/slack.ts", - "src/commands/upload-sourcemaps.ts", - "src/commands/warehouse.ts", - "src/env.ts", - "src/frameworks/android/android-wizard-agent.ts", - "src/frameworks/android/utils.ts", - "src/frameworks/angular/angular-wizard-agent.ts", - "src/frameworks/angular/utils.ts", - "src/frameworks/astro/astro-wizard-agent.ts", - "src/frameworks/astro/utils.ts", - "src/frameworks/django/django-wizard-agent.ts", - "src/frameworks/django/utils.ts", - "src/frameworks/elixir/elixir-wizard-agent.ts", - "src/frameworks/fastapi/fastapi-wizard-agent.ts", - "src/frameworks/fastapi/utils.ts", - "src/frameworks/flask/flask-wizard-agent.ts", - "src/frameworks/flask/utils.ts", - "src/frameworks/flutter/flutter-wizard-agent.ts", - "src/frameworks/go/go-wizard-agent.ts", - "src/frameworks/java/java-wizard-agent.ts", - "src/frameworks/javascript-node/javascript-node-wizard-agent.ts", - "src/frameworks/javascript-web/javascript-web-wizard-agent.ts", - "src/frameworks/javascript-web/utils.ts", - "src/frameworks/kmp/kmp-wizard-agent.ts", - "src/frameworks/laravel/laravel-wizard-agent.ts", - "src/frameworks/laravel/utils.ts", - "src/frameworks/nextjs/nextjs-wizard-agent.ts", - "src/frameworks/nextjs/utils.ts", - "src/frameworks/nuxt/nuxt-wizard-agent.ts", - "src/frameworks/python/python-wizard-agent.ts", - "src/frameworks/python/utils.ts", - "src/frameworks/rails/rails-wizard-agent.ts", - "src/frameworks/rails/utils.ts", - "src/frameworks/react-native/react-native-wizard-agent.ts", - "src/frameworks/react-native/utils.ts", - "src/frameworks/react-router/react-router-wizard-agent.ts", - "src/frameworks/react-router/utils.ts", - "src/frameworks/ruby/ruby-wizard-agent.ts", - "src/frameworks/ruby/utils.ts", - "src/frameworks/rust/rust-wizard-agent.ts", - "src/frameworks/svelte/svelte-wizard-agent.ts", - "src/frameworks/swift/swift-wizard-agent.ts", - "src/frameworks/swift/utils.ts", - "src/frameworks/tanstack-router/tanstack-router-wizard-agent.ts", - "src/frameworks/tanstack-router/utils.ts", - "src/frameworks/tanstack-start/tanstack-start-wizard-agent.ts", - "src/frameworks/tanstack-start/utils.ts", - "src/frameworks/vue/vue-wizard-agent.ts", - "src/lib/agent/agent-env-isolation.ts", - "src/lib/agent/agent-interface.ts", - "src/lib/agent/agent-phase.ts", - "src/lib/agent/agent-prompt-loader.ts", - "src/lib/agent/agent-prompt.ts", - "src/lib/agent/agent-runner.ts", - "src/lib/agent/aio-capture.ts", - "src/lib/agent/bash-fence.ts", - "src/lib/agent/claude-settings.ts", - "src/lib/agent/commandments.ts", - "src/lib/agent/mcp-prompt-streaming.ts", - "src/lib/agent/output-signals.ts", - "src/lib/agent/runner/harness/anthropic/index.ts", - "src/lib/agent/runner/harness/pi/completion.ts", - "src/lib/agent/runner/harness/pi/gateway.ts", - "src/lib/agent/runner/harness/pi/index.ts", - "src/lib/agent/runner/harness/pi/mcp.ts", - "src/lib/agent/runner/harness/pi/orchestrator-tools.ts", - "src/lib/agent/runner/harness/pi/runtime-notes.ts", - "src/lib/agent/runner/harness/pi/security.ts", - "src/lib/agent/runner/harness/pi/subagent.ts", - "src/lib/agent/runner/harness/pi/task.ts", - "src/lib/agent/runner/harness/pi/tasks.ts", - "src/lib/agent/runner/harness/pi/tools.ts", - "src/lib/agent/runner/index.ts", - "src/lib/agent/runner/sequence/linear.ts", - "src/lib/agent/runner/sequence/orchestrator/executor.ts", - "src/lib/agent/runner/sequence/orchestrator/orchestrator-runner.ts", - "src/lib/agent/runner/sequence/orchestrator/queue-tools.ts", - "src/lib/agent/runner/sequence/orchestrator/queue.ts", - "src/lib/agent/runner/sequence/orchestrator/run-metrics.ts", - "src/lib/agent/runner/sequence/orchestrator/seeded-deps.ts", - "src/lib/agent/runner/shared/authenticate.ts", - "src/lib/agent/runner/shared/bootstrap.ts", - "src/lib/agent/runner/shared/errors.ts", - "src/lib/agent/runner/switchboard/commandments.ts", - "src/lib/agent/runner/switchboard/flags/index.ts", - "src/lib/agent/runner/switchboard/flags/orchestrator.ts", - "src/lib/agent/runner/switchboard/flags/schemes.ts", - "src/lib/agent/runner/switchboard/flags/self-driving.ts", - "src/lib/agent/runner/switchboard/harness.ts", - "src/lib/agent/runner/switchboard/index.ts", - "src/lib/agent/runner/switchboard/models.ts", - "src/lib/agent/runner/switchboard/sequence.ts", - "src/lib/agent/signals.ts", - "src/lib/agent/stored-login.ts", - "src/lib/agent/token-pricing.ts", - "src/lib/agent/triage-provider.ts", - "src/lib/api.ts", - "src/lib/auth-session-state.ts", - "src/lib/constants.ts", - "src/lib/detection/agentic.ts", - "src/lib/detection/context.ts", - "src/lib/detection/features.ts", - "src/lib/detection/framework.ts", - "src/lib/detection/package-manager.ts", - "src/lib/detection/project-scope.ts", - "src/lib/errors/agent-map.ts", - "src/lib/errors/auth.ts", - "src/lib/errors/catalog.ts", - "src/lib/errors/codes.ts", - "src/lib/errors/detect-map.ts", - "src/lib/errors/emit.ts", - "src/lib/errors/run-failure.ts", - "src/lib/errors/sanitize.ts", - "src/lib/errors/skill-map.ts", - "src/lib/fetch-retry.ts", - "src/lib/file-watcher.ts", - "src/lib/framework-config.ts", - "src/lib/headless-mode.ts", - "src/lib/health-checks/endpoints.ts", - "src/lib/health-checks/readiness.ts", - "src/lib/host-resolution.ts", - "src/lib/local-dev.ts", - "src/lib/mcp-project-profile.ts", - "src/lib/mcp-role-prompts.copy.json", - "src/lib/mcp-role-prompts.ts", - "src/lib/mcp-seed-events.ts", - "src/lib/middleware/benchmark.ts", - "src/lib/middleware/benchmarks/cache-tracker.ts", - "src/lib/middleware/benchmarks/compaction-tracker.ts", - "src/lib/middleware/benchmarks/context-size-tracker.ts", - "src/lib/middleware/benchmarks/cost-tracker.ts", - "src/lib/middleware/benchmarks/duration-tracker.ts", - "src/lib/middleware/benchmarks/index.ts", - "src/lib/middleware/benchmarks/json-writer.ts", - "src/lib/middleware/benchmarks/summary.ts", - "src/lib/middleware/benchmarks/token-tracker.ts", - "src/lib/middleware/benchmarks/turn-counter.ts", - "src/lib/middleware/config.ts", - "src/lib/middleware/phase-detector.ts", - "src/lib/middleware/pipeline.ts", - "src/lib/oauth/program-scopes.ts", - "src/lib/programs/agent-skill/content/index.tsx", - "src/lib/programs/agent-skill/index.ts", - "src/lib/programs/agent-skill/steps.ts", - "src/lib/programs/ai-observability/index.ts", - "src/lib/programs/ai-opt-in-gate.ts", - "src/lib/programs/audit/detect.ts", - "src/lib/programs/audit/index.ts", - "src/lib/programs/audit/ledger-watcher.ts", - "src/lib/programs/audit/seed.ts", - "src/lib/programs/dispatch-family.ts", - "src/lib/programs/error-tracking-upload-source-maps/content/index.tsx", - "src/lib/programs/error-tracking-upload-source-maps/detect-agentic.ts", - "src/lib/programs/error-tracking-upload-source-maps/detect.ts", - "src/lib/programs/error-tracking-upload-source-maps/index.ts", - "src/lib/programs/error-tracking-upload-source-maps/prompt.ts", - "src/lib/programs/error-tracking-upload-source-maps/steps.ts", - "src/lib/programs/error-tracking/content/index.tsx", - "src/lib/programs/error-tracking/content/tips.ts", - "src/lib/programs/error-tracking/detect-agentic.ts", - "src/lib/programs/error-tracking/index.ts", - "src/lib/programs/events-audit/index.ts", - "src/lib/programs/events-audit/seed.ts", - "src/lib/programs/events-audit/steps.ts", - "src/lib/programs/mcp-analytics/index.ts", - "src/lib/programs/mcp/index.ts", - "src/lib/programs/metrics/index.ts", - "src/lib/programs/migration/content/free-tier.tsx", - "src/lib/programs/migration/content/index.tsx", - "src/lib/programs/migration/content/pricing-structure.tsx", - "src/lib/programs/migration/content/vendor-stack.tsx", - "src/lib/programs/migration/index.ts", - "src/lib/programs/migration/steps.ts", - "src/lib/programs/posthog-doctor/fetch.ts", - "src/lib/programs/posthog-doctor/index.ts", - "src/lib/programs/posthog-doctor/kind-metadata.ts", - "src/lib/programs/posthog-doctor/steps.ts", - "src/lib/programs/posthog-doctor/types.ts", - "src/lib/programs/posthog-integration/content/data-flow.tsx", - "src/lib/programs/posthog-integration/content/funnel.tsx", - "src/lib/programs/posthog-integration/content/index.tsx", - "src/lib/programs/posthog-integration/content/line-chart.tsx", - "src/lib/programs/posthog-integration/content/product-suite.tsx", - "src/lib/programs/posthog-integration/detect.ts", - "src/lib/programs/posthog-integration/handoff.ts", - "src/lib/programs/posthog-integration/index.ts", - "src/lib/programs/posthog-integration/steps.ts", - "src/lib/programs/program-registry.ts", - "src/lib/programs/program-step.ts", - "src/lib/programs/replay-vision/index.ts", - "src/lib/programs/revenue-analytics/detect.ts", - "src/lib/programs/revenue-analytics/index.ts", - "src/lib/programs/revenue-analytics/steps.ts", - "src/lib/programs/self-driving/content/index.tsx", - "src/lib/programs/self-driving/content/pipeline-diagram.tsx", - "src/lib/programs/self-driving/content/pricing.ts", - "src/lib/programs/self-driving/content/tips.ts", - "src/lib/programs/self-driving/detect-agentic.ts", - "src/lib/programs/self-driving/detect.ts", - "src/lib/programs/self-driving/index.ts", - "src/lib/programs/self-driving/prompt.ts", - "src/lib/programs/self-driving/step-keys.ts", - "src/lib/programs/self-driving/steps.ts", - "src/lib/programs/shared/health-check-step.ts", - "src/lib/programs/shared/package-scanning.ts", - "src/lib/programs/shared/posthog-cli-preinstall.ts", - "src/lib/programs/slack/index.ts", - "src/lib/programs/warehouse-source/detect.ts", - "src/lib/programs/warehouse-source/index.ts", - "src/lib/programs/warehouse-source/steps.ts", - "src/lib/programs/web-analytics-doctor/detect.ts", - "src/lib/programs/web-analytics-doctor/index.ts", - "src/lib/programs/web-analytics-doctor/steps.ts", - "src/lib/registry.ts", - "src/lib/runners/resolve-no-telemetry.ts", - "src/lib/runners/run-non-interactive.ts", - "src/lib/runners/run-wizard-ci.ts", - "src/lib/runners/run-wizard-headless.ts", - "src/lib/runners/run-wizard.ts", - "src/lib/safe-tools.ts", - "src/lib/secret-vault.ts", - "src/lib/task-stream/audit-areas.ts", - "src/lib/task-stream/destinations/file.ts", - "src/lib/task-stream/destinations/posthog.ts", - "src/lib/task-stream/event-plan-watcher.ts", - "src/lib/task-stream/task-stream-push.ts", - "src/lib/version.ts", - "src/lib/warehouse-sources/detect.ts", - "src/lib/warehouse-sources/registry.ts", - "src/lib/wizard-ask-bridge.ts", - "src/lib/wizard-session.ts", - "src/lib/wizard-spellbook.ts", - "src/lib/wizard-tools/handoff.ts", - "src/lib/wizard-tools/mcp.ts", - "src/lib/wizard-tools/tools.ts", - "src/steps/add-mcp-server-to-clients/MCPClient.ts", - "src/steps/add-mcp-server-to-clients/browser-client.ts", - "src/steps/add-mcp-server-to-clients/clients/claude-code.ts", - "src/steps/add-mcp-server-to-clients/clients/claude-web.ts", - "src/steps/add-mcp-server-to-clients/clients/codex.ts", - "src/steps/add-mcp-server-to-clients/clients/cursor.ts", - "src/steps/add-mcp-server-to-clients/clients/opencode.ts", - "src/steps/add-mcp-server-to-clients/clients/visual-studio-code.ts", - "src/steps/add-mcp-server-to-clients/clients/zed.ts", - "src/steps/add-mcp-server-to-clients/defaults.ts", - "src/steps/add-mcp-server-to-clients/index.ts", - "src/steps/add-mcp-server-to-clients/login-client.ts", - "src/steps/add-mcp-server-to-clients/plugin-client.ts", - "src/steps/add-mcp-server-to-clients/results.ts", - "src/steps/install-cli-steering/index.ts", - "src/steps/upload-environment-variables/EnvironmentProvider.ts", - "src/steps/upload-environment-variables/index.ts", - "src/steps/upload-environment-variables/providers/vercel.ts", - "src/telemetry.ts", - "src/ui/headless-ui.ts", - "src/ui/index.ts", - "src/ui/logging-ui.ts", - "src/ui/mint-failure.ts", - "src/ui/tui/App.tsx", - "src/ui/tui/components/LearnCard.tsx", - "src/ui/tui/components/PhaseVisuals.tsx", - "src/ui/tui/components/PrivacyPanel.tsx", - "src/ui/tui/components/ServiceHealthList.tsx", - "src/ui/tui/components/StatusPeekTrigger.tsx", - "src/ui/tui/components/TipsCard.tsx", - "src/ui/tui/components/TitleBar.tsx", - "src/ui/tui/components/TokenCostHud.tsx", - "src/ui/tui/components/visualizer/CrateStack.tsx", - "src/ui/tui/components/visualizer/DashboardGrid.tsx", - "src/ui/tui/components/visualizer/DiffCascade.tsx", - "src/ui/tui/components/visualizer/LibraryShelf.tsx", - "src/ui/tui/components/visualizer/MatrixRain.tsx", - "src/ui/tui/components/visualizer/Tumblers.tsx", - "src/ui/tui/components/visualizer/grid.ts", - "src/ui/tui/components/visualizer/palette.ts", - "src/ui/tui/components/visualizer/panel.tsx", - "src/ui/tui/exit-line.ts", - "src/ui/tui/hooks/keyboard-hints-utils.ts", - "src/ui/tui/hooks/useDismissOnAnyKey.ts", - "src/ui/tui/hooks/useGithubConnection.ts", - "src/ui/tui/hooks/useKeyBindings.ts", - "src/ui/tui/hooks/useKeyboardHints.tsx", - "src/ui/tui/hooks/useStdoutDimensions.ts", - "src/ui/tui/hooks/useTick.ts", - "src/ui/tui/ink-ui.ts", - "src/ui/tui/playground/PlaygroundApp.tsx", - "src/ui/tui/playground/demos/AiOptInDemo.tsx", - "src/ui/tui/playground/demos/AskModalDemo.tsx", - "src/ui/tui/playground/demos/AuditChecksDemo.tsx", - "src/ui/tui/playground/demos/DoctorReportDemo.tsx", - "src/ui/tui/playground/demos/EndScreensDemo.tsx", - "src/ui/tui/playground/demos/HealthCheckDemo.tsx", - "src/ui/tui/playground/demos/InputDemo.tsx", - "src/ui/tui/playground/demos/KeyboardHintsDemo.tsx", - "src/ui/tui/playground/demos/LayoutDemo.tsx", - "src/ui/tui/playground/demos/LearnDeckDemo.tsx", - "src/ui/tui/playground/demos/LogDemo.tsx", - "src/ui/tui/playground/demos/McpDemo.tsx", - "src/ui/tui/playground/demos/McpSuggestedPromptsDemo.tsx", - "src/ui/tui/playground/demos/ModalDemo.tsx", - "src/ui/tui/playground/demos/ProgressDemo.tsx", - "src/ui/tui/playground/demos/RunScreenDemo.tsx", - "src/ui/tui/playground/demos/ViewportGuardDemo.tsx", - "src/ui/tui/playground/demos/WelcomeDemo.tsx", - "src/ui/tui/playground/start-playground.ts", - "src/ui/tui/posthog-integration-intro.ts", - "src/ui/tui/primitives/CardLayout.tsx", - "src/ui/tui/primitives/ConfirmButton.tsx", - "src/ui/tui/primitives/ConfirmationInput.tsx", - "src/ui/tui/primitives/ContentSequencer.tsx", - "src/ui/tui/primitives/DissolveTransition.tsx", - "src/ui/tui/primitives/Divider.tsx", - "src/ui/tui/primitives/EventPlanViewer.tsx", - "src/ui/tui/primitives/GroupedPickerMenu.tsx", - "src/ui/tui/primitives/HNViewer.tsx", - "src/ui/tui/primitives/KeyboardHintsBar.tsx", - "src/ui/tui/primitives/LinesBlock.tsx", - "src/ui/tui/primitives/LinkText.tsx", - "src/ui/tui/primitives/LoadingBox.tsx", - "src/ui/tui/primitives/LogViewer.tsx", - "src/ui/tui/primitives/ModalOverlay.tsx", - "src/ui/tui/primitives/NodeBlock.tsx", - "src/ui/tui/primitives/PickerMenu.tsx", - "src/ui/tui/primitives/ProgressList.tsx", - "src/ui/tui/primitives/PromptLabel.tsx", - "src/ui/tui/primitives/ScreenContainer.tsx", - "src/ui/tui/primitives/ScreenErrorBoundary.tsx", - "src/ui/tui/primitives/SplitView.tsx", - "src/ui/tui/primitives/TabContainer.tsx", - "src/ui/tui/primitives/TextBlock.tsx", - "src/ui/tui/primitives/ViewportTooSmall.tsx", - "src/ui/tui/primitives/content-types.ts", - "src/ui/tui/primitives/layout-helpers.ts", - "src/ui/tui/primitives/link-helpers.ts", - "src/ui/tui/primitives/picker-filter.ts", - "src/ui/tui/primitives/text-helpers.ts", - "src/ui/tui/router.ts", - "src/ui/tui/screen-registry.tsx", - "src/ui/tui/screen-sequences.ts", - "src/ui/tui/screens/AgentSkillIntroScreen.tsx", - "src/ui/tui/screens/AiObservabilityIntroScreen.tsx", - "src/ui/tui/screens/AiOptInRequiredScreen.tsx", - "src/ui/tui/screens/AuthErrorScreen.tsx", - "src/ui/tui/screens/AuthScreen.tsx", - "src/ui/tui/screens/ErrorTrackingDetectScreen.tsx", - "src/ui/tui/screens/ErrorTrackingIntroScreen.tsx", - "src/ui/tui/screens/ExitScreen.tsx", - "src/ui/tui/screens/IntroScreenLayout.tsx", - "src/ui/tui/screens/KeepSkillsScreen.tsx", - "src/ui/tui/screens/ManagedSettingsScreen.tsx", - "src/ui/tui/screens/ManualAuthCodeScreen.tsx", - "src/ui/tui/screens/McpScreen.tsx", - "src/ui/tui/screens/McpSuggestedPromptsScreen.tsx", - "src/ui/tui/screens/MetricsIntroScreen.tsx", - "src/ui/tui/screens/MigrationIntroScreen.tsx", - "src/ui/tui/screens/MintFailureScreen.tsx", - "src/ui/tui/screens/OutroScreen.tsx", - "src/ui/tui/screens/PortConflictScreen.tsx", - "src/ui/tui/screens/PostHogIntegrationIntroScreen.tsx", - "src/ui/tui/screens/RevenueIntroScreen.tsx", - "src/ui/tui/screens/RunScreen.tsx", - "src/ui/tui/screens/SelfDrivingGitHubScreen.tsx", - "src/ui/tui/screens/SelfDrivingHandoffScreen.tsx", - "src/ui/tui/screens/SelfDrivingIntegrationCheckScreen.tsx", - "src/ui/tui/screens/SelfDrivingIntegrationDetectScreen.tsx", - "src/ui/tui/screens/SelfDrivingIntroScreen.tsx", - "src/ui/tui/screens/SessionTimeoutScreen.tsx", - "src/ui/tui/screens/SettingsOverrideScreen.tsx", - "src/ui/tui/screens/SetupScreen.tsx", - "src/ui/tui/screens/SkillSourceInfo.tsx", - "src/ui/tui/screens/SlackConnectScreen.tsx", - "src/ui/tui/screens/SourceMapsDetectScreen.tsx", - "src/ui/tui/screens/SourceMapsIntroScreen.tsx", - "src/ui/tui/screens/SourceMapsOutroScreen.tsx", - "src/ui/tui/screens/TaskNoticeScreen.tsx", - "src/ui/tui/screens/WarehouseIntroScreen.tsx", - "src/ui/tui/screens/WizardAskScreen.tsx", - "src/ui/tui/screens/audit/AuditAreaPane.tsx", - "src/ui/tui/screens/audit/AuditChecksOutroSection.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/AreaHeaderRow.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/AuditChecksViewer.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/CheckRow.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/DetailRow.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/Footer.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/Header.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/Legend.tsx", - "src/ui/tui/screens/audit/AuditChecksViewer/layout.ts", - "src/ui/tui/screens/audit/AuditChecksViewer/sort.ts", - "src/ui/tui/screens/audit/AuditIntroScreen.tsx", - "src/ui/tui/screens/audit/AuditOutroScreen.tsx", - "src/ui/tui/screens/audit/AuditRunScreen.tsx", - "src/ui/tui/screens/audit/PendingChecksList.tsx", - "src/ui/tui/screens/audit/slides/eventCapture.tsx", - "src/ui/tui/screens/audit/slides/events-audit/createDashboard.tsx", - "src/ui/tui/screens/audit/slides/events-audit/detectSdk.tsx", - "src/ui/tui/screens/audit/slides/events-audit/enrichSites.tsx", - "src/ui/tui/screens/audit/slides/events-audit/index.ts", - "src/ui/tui/screens/audit/slides/events-audit/queryVolume.tsx", - "src/ui/tui/screens/audit/slides/events-audit/scanSites.tsx", - "src/ui/tui/screens/audit/slides/events-audit/uploadNotebook.tsx", - "src/ui/tui/screens/audit/slides/events-audit/writeReport.tsx", - "src/ui/tui/screens/audit/slides/identification.tsx", - "src/ui/tui/screens/audit/slides/index.ts", - "src/ui/tui/screens/audit/slides/installation.tsx", - "src/ui/tui/screens/audit/slides/liveData.tsx", - "src/ui/tui/screens/audit/slides/shared.tsx", - "src/ui/tui/screens/audit/slides/uploadNotebook.tsx", - "src/ui/tui/screens/audit/slides/writeReport.tsx", - "src/ui/tui/screens/doctor/DoctorIntroScreen.tsx", - "src/ui/tui/screens/doctor/DoctorReportScreen.tsx", - "src/ui/tui/screens/doctor/IssueTable.tsx", - "src/ui/tui/screens/health/HealthCheckScreen.tsx", - "src/ui/tui/services/coding-agent-launcher.ts", - "src/ui/tui/services/mcp-installer.ts", - "src/ui/tui/services/mcp-suggested-prompts-services.ts", - "src/ui/tui/start-tui.ts", - "src/ui/tui/store.ts", - "src/ui/tui/styles.ts", - "src/ui/tui/terminal.ts", - "src/ui/wizard-ui.ts", - "src/utils/analytics.ts", - "src/utils/atomic-ledger.ts", - "src/utils/bounded-fs.ts", - "src/utils/ci-flag-overrides.ts", - "src/utils/clipboard.ts", - "src/utils/custom-headers.ts", - "src/utils/debug.ts", - "src/utils/env-api-key.ts", - "src/utils/env-scan.ts", - "src/utils/environment.ts", - "src/utils/links.ts", - "src/utils/oauth-errors.ts", - "src/utils/oauth.ts", - "src/utils/package-json.ts", - "src/utils/package-manager.ts", - "src/utils/paths.ts", - "src/utils/project-resolution.ts", - "src/utils/provisioning.ts", - "src/utils/semver.ts", - "src/utils/setup-utils.ts", - "src/utils/terminal-bell.ts", - "src/utils/urls.ts", - "src/utils/wizard-abort.ts", - "src/wizard.ts" - ] -} diff --git a/scripts/chunk-manifest.no-jest.ts b/scripts/chunk-manifest.no-jest.ts index 507d672f9..51d5b731d 100644 --- a/scripts/chunk-manifest.no-jest.ts +++ b/scripts/chunk-manifest.no-jest.ts @@ -7,10 +7,8 @@ * tsx scripts/chunk-manifest.no-jest.ts [distDir] --summary > summary.json * * `--summary` prints the chunk names and the sorted set of every bundled - * source. Rolldown assigns shared modules to different chunks on macOS and - * Linux and the sourcemaps list different sources, so the fixtures under - * scripts/__fixtures__ are recorded from the Surfaces workflow's artifact, - * never from a local build. Locally, use the full manifest for reading. + * source. Output differs between macOS and Linux (chunk assignment and + * sourcemap sources), so this is a reading tool, not a golden. */ import fs from 'fs'; import path from 'path';