@posthog/wizard 2.9.0 → 2.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/bin.js +2 -5
  2. package/dist/bin.js.map +1 -1
  3. package/dist/src/lib/agent/agent-runner.js +2 -0
  4. package/dist/src/lib/agent/agent-runner.js.map +1 -1
  5. package/dist/src/lib/constants.d.ts +1 -1
  6. package/dist/src/lib/version.d.ts +1 -1
  7. package/dist/src/lib/version.js +1 -1
  8. package/dist/src/lib/version.js.map +1 -1
  9. package/dist/src/lib/workflows/__tests__/agent-skill.test.js +9 -2
  10. package/dist/src/lib/workflows/__tests__/agent-skill.test.js.map +1 -1
  11. package/dist/src/lib/workflows/agent-skill/steps.d.ts +2 -2
  12. package/dist/src/lib/workflows/agent-skill/steps.js +13 -2
  13. package/dist/src/lib/workflows/agent-skill/steps.js.map +1 -1
  14. package/dist/src/lib/workflows/posthog-integration/steps.js +3 -3
  15. package/dist/src/lib/workflows/posthog-integration/steps.js.map +1 -1
  16. package/dist/src/lib/workflows/revenue-analytics/steps.js +5 -0
  17. package/dist/src/lib/workflows/revenue-analytics/steps.js.map +1 -1
  18. package/dist/src/ui/tui/__tests__/store.test.js +49 -3
  19. package/dist/src/ui/tui/__tests__/store.test.js.map +1 -1
  20. package/dist/src/ui/tui/flows.d.ts +2 -1
  21. package/dist/src/ui/tui/flows.js +2 -1
  22. package/dist/src/ui/tui/flows.js.map +1 -1
  23. package/dist/src/ui/tui/playground/PlaygroundApp.js +6 -0
  24. package/dist/src/ui/tui/playground/PlaygroundApp.js.map +1 -1
  25. package/dist/src/ui/tui/playground/demos/McpDemo.d.ts +12 -0
  26. package/dist/src/ui/tui/playground/demos/McpDemo.js +27 -0
  27. package/dist/src/ui/tui/playground/demos/McpDemo.js.map +1 -0
  28. package/dist/src/ui/tui/primitives/ProgressList.d.ts +1 -3
  29. package/dist/src/ui/tui/primitives/ProgressList.js +2 -2
  30. package/dist/src/ui/tui/primitives/ProgressList.js.map +1 -1
  31. package/dist/src/ui/tui/screen-registry.js +6 -4
  32. package/dist/src/ui/tui/screen-registry.js.map +1 -1
  33. package/dist/src/ui/tui/screens/AgentSkillIntroScreen.d.ts +12 -0
  34. package/dist/src/ui/tui/screens/AgentSkillIntroScreen.js +75 -0
  35. package/dist/src/ui/tui/screens/AgentSkillIntroScreen.js.map +1 -0
  36. package/dist/src/ui/tui/screens/IntroScreenLayout.d.ts +46 -0
  37. package/dist/src/ui/tui/screens/IntroScreenLayout.js +33 -0
  38. package/dist/src/ui/tui/screens/IntroScreenLayout.js.map +1 -0
  39. package/dist/src/ui/tui/screens/{SkillsScreen.d.ts → KeepSkillsScreen.d.ts} +3 -3
  40. package/dist/src/ui/tui/screens/{SkillsScreen.js → KeepSkillsScreen.js} +8 -5
  41. package/dist/src/ui/tui/screens/KeepSkillsScreen.js.map +1 -0
  42. package/dist/src/ui/tui/screens/McpScreen.js +4 -1
  43. package/dist/src/ui/tui/screens/McpScreen.js.map +1 -1
  44. package/dist/src/ui/tui/screens/PostHogIntegrationIntroScreen.d.ts +15 -0
  45. package/dist/src/ui/tui/screens/PostHogIntegrationIntroScreen.js +135 -0
  46. package/dist/src/ui/tui/screens/PostHogIntegrationIntroScreen.js.map +1 -0
  47. package/dist/src/ui/tui/screens/RevenueIntroScreen.d.ts +3 -3
  48. package/dist/src/ui/tui/screens/RevenueIntroScreen.js +57 -32
  49. package/dist/src/ui/tui/screens/RevenueIntroScreen.js.map +1 -1
  50. package/dist/src/ui/tui/screens/RunScreen.js +1 -1
  51. package/dist/src/ui/tui/screens/RunScreen.js.map +1 -1
  52. package/dist/src/ui/tui/store.js +2 -0
  53. package/dist/src/ui/tui/store.js.map +1 -1
  54. package/npm-shrinkwrap.json +2 -2
  55. package/package.json +1 -1
  56. package/dist/src/ui/tui/screens/IntroScreen.d.ts +0 -16
  57. package/dist/src/ui/tui/screens/IntroScreen.js +0 -79
  58. package/dist/src/ui/tui/screens/IntroScreen.js.map +0 -1
  59. package/dist/src/ui/tui/screens/SkillsScreen.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ProgressList.js","sourceRoot":"","sources":["../../../../../src/ui/tui/primitives/ProgressList.tsx"],"names":[],"mappings":";AAAA;;;GAGG;AAEH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAe7C,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAC3B,KAAK,EACL,KAAK,EACL,aAAa,EACb,OAAO,GACW,EAAE,EAAE;IACtB,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC;IACvE,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;IAE3B,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACxB,KAAK,IAAI,CACR,8BACE,KAAC,IAAI,IAAC,IAAI,kBAAE,KAAK,GAAQ,EACzB,KAAC,IAAI,oBAAS,IACb,CACJ,EACA,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAC,UAAU,IAAC,OAAO,EAAC,sBAAsB,GAAG,EACnE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;gBACrB,MAAM,IAAI,GACR,IAAI,CAAC,MAAM,KAAK,WAAW;oBACzB,CAAC,CAAC,KAAK,CAAC,YAAY;oBACpB,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,aAAa;wBAC/B,CAAC,CAAC,KAAK,CAAC,aAAa;wBACrB,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC;gBACvB,MAAM,KAAK,GACT,IAAI,CAAC,MAAM,KAAK,WAAW;oBACzB,CAAC,CAAC,MAAM,CAAC,OAAO;oBAChB,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,aAAa;wBAC/B,CAAC,CAAC,MAAM,CAAC,OAAO;wBAChB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;gBACnB,MAAM,KAAK,GACT,IAAI,CAAC,MAAM,KAAK,aAAa,IAAI,IAAI,CAAC,UAAU;oBAC9C,CAAC,CAAC,IAAI,CAAC,UAAU;oBACjB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;gBAEjB,OAAO,CACL,MAAC,IAAI,eACH,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,YAAG,IAAI,GAAQ,EACjC,MAAC,IAAI,IAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,KAAK,SAAS,kBAAI,KAAK,IAAQ,KAFjD,CAAC,CAGL,CACR,CAAC;YACJ,CAAC,CAAC,EACD,KAAK,GAAG,CAAC,IAAI,CACZ,MAAC,GAAG,IAAC,SAAS,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,aACvB,KAAC,OAAO,KAAG,EACX,KAAC,IAAI,IAAC,QAAQ,kBACX,SAAS,GAAG,KAAK;4BAChB,CAAC,CAAC,aAAa,SAAS,IAAI,KAAK,YAAY;4BAC7C,CAAC,CAAC,gBAAgB,GACf,IACH,CACP,EACA,CAAC,aAAa,IAAI,OAAO,CAAC,IAAI,CAC7B,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,SAAS,EAAE,CAAC,aACrC,aAAa,IAAI,MAAC,IAAI,IAAC,QAAQ,iCAAY,aAAa,IAAQ,EAChE,OAAO,IAAI,MAAC,IAAI,IAAC,QAAQ,8BAAS,OAAO,IAAQ,IAC9C,CACP,IACG,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * ProgressList — Reusable task checklist with status icons.\n * Extracted from StatusTab logic.\n */\n\nimport { Box, Text } from 'ink';\nimport { Spinner } from '@inkjs/ui';\nimport { Colors, Icons } from '../styles.js';\nimport { LoadingBox } from './LoadingBox.js';\n\nexport interface ProgressItem {\n label: string;\n activeForm?: string;\n status: 'pending' | 'in_progress' | 'completed';\n}\n\ninterface ProgressListProps {\n items: ProgressItem[];\n title?: string;\n workflowLabel?: string | null;\n skillId?: string | null;\n}\n\nexport const ProgressList = ({\n items,\n title,\n workflowLabel,\n skillId,\n}: ProgressListProps) => {\n const completed = items.filter((t) => t.status === 'completed').length;\n const total = items.length;\n\n return (\n <Box flexDirection=\"column\">\n {title && (\n <>\n <Text bold>{title}</Text>\n <Text> </Text>\n </>\n )}\n {items.length === 0 && <LoadingBox message=\"Analyzing project...\" />}\n {items.map((item, i) => {\n const icon =\n item.status === 'completed'\n ? Icons.squareFilled\n : item.status === 'in_progress'\n ? Icons.triangleRight\n : Icons.squareOpen;\n const color =\n item.status === 'completed'\n ? Colors.success\n : item.status === 'in_progress'\n ? Colors.primary\n : Colors.muted;\n const label =\n item.status === 'in_progress' && item.activeForm\n ? item.activeForm\n : item.label;\n\n return (\n <Text key={i}>\n <Text color={color}>{icon}</Text>\n <Text dimColor={item.status === 'pending'}> {label}</Text>\n </Text>\n );\n })}\n {total > 0 && (\n <Box marginTop={1} gap={1}>\n <Spinner />\n <Text dimColor>\n {completed < total\n ? `Progress: ${completed}/${total} completed`\n : 'Cleaning up...'}\n </Text>\n </Box>\n )}\n {(workflowLabel || skillId) && (\n <Box flexDirection=\"column\" marginTop={2}>\n {workflowLabel && <Text dimColor>workflow: {workflowLabel}</Text>}\n {skillId && <Text dimColor>skill: {skillId}</Text>}\n </Box>\n )}\n </Box>\n );\n};\n"]}
1
+ {"version":3,"file":"ProgressList.js","sourceRoot":"","sources":["../../../../../src/ui/tui/primitives/ProgressList.tsx"],"names":[],"mappings":";AAAA;;;GAGG;AAEH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAa7C,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,EAAqB,EAAE,EAAE;IAClE,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC;IACvE,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;IAE3B,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACxB,KAAK,IAAI,CACR,8BACE,KAAC,IAAI,IAAC,IAAI,kBAAE,KAAK,GAAQ,EACzB,KAAC,IAAI,oBAAS,IACb,CACJ,EACA,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAC,UAAU,IAAC,OAAO,EAAC,sBAAsB,GAAG,EACnE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;gBACrB,MAAM,IAAI,GACR,IAAI,CAAC,MAAM,KAAK,WAAW;oBACzB,CAAC,CAAC,KAAK,CAAC,YAAY;oBACpB,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,aAAa;wBAC/B,CAAC,CAAC,KAAK,CAAC,aAAa;wBACrB,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC;gBACvB,MAAM,KAAK,GACT,IAAI,CAAC,MAAM,KAAK,WAAW;oBACzB,CAAC,CAAC,MAAM,CAAC,OAAO;oBAChB,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,aAAa;wBAC/B,CAAC,CAAC,MAAM,CAAC,OAAO;wBAChB,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;gBACnB,MAAM,KAAK,GACT,IAAI,CAAC,MAAM,KAAK,aAAa,IAAI,IAAI,CAAC,UAAU;oBAC9C,CAAC,CAAC,IAAI,CAAC,UAAU;oBACjB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;gBAEjB,OAAO,CACL,MAAC,IAAI,eACH,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,YAAG,IAAI,GAAQ,EACjC,MAAC,IAAI,IAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,KAAK,SAAS,kBAAI,KAAK,IAAQ,KAFjD,CAAC,CAGL,CACR,CAAC;YACJ,CAAC,CAAC,EACD,KAAK,GAAG,CAAC,IAAI,CACZ,MAAC,GAAG,IAAC,SAAS,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,aACvB,KAAC,OAAO,KAAG,EACX,KAAC,IAAI,IAAC,QAAQ,kBACX,SAAS,GAAG,KAAK;4BAChB,CAAC,CAAC,aAAa,SAAS,IAAI,KAAK,YAAY;4BAC7C,CAAC,CAAC,gBAAgB,GACf,IACH,CACP,IACG,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * ProgressList — Reusable task checklist with status icons.\n * Extracted from StatusTab logic.\n */\n\nimport { Box, Text } from 'ink';\nimport { Spinner } from '@inkjs/ui';\nimport { Colors, Icons } from '../styles.js';\nimport { LoadingBox } from './LoadingBox.js';\n\nexport interface ProgressItem {\n label: string;\n activeForm?: string;\n status: 'pending' | 'in_progress' | 'completed';\n}\n\ninterface ProgressListProps {\n items: ProgressItem[];\n title?: string;\n}\n\nexport const ProgressList = ({ items, title }: ProgressListProps) => {\n const completed = items.filter((t) => t.status === 'completed').length;\n const total = items.length;\n\n return (\n <Box flexDirection=\"column\">\n {title && (\n <>\n <Text bold>{title}</Text>\n <Text> </Text>\n </>\n )}\n {items.length === 0 && <LoadingBox message=\"Analyzing project...\" />}\n {items.map((item, i) => {\n const icon =\n item.status === 'completed'\n ? Icons.squareFilled\n : item.status === 'in_progress'\n ? Icons.triangleRight\n : Icons.squareOpen;\n const color =\n item.status === 'completed'\n ? Colors.success\n : item.status === 'in_progress'\n ? Colors.primary\n : Colors.muted;\n const label =\n item.status === 'in_progress' && item.activeForm\n ? item.activeForm\n : item.label;\n\n return (\n <Text key={i}>\n <Text color={color}>{icon}</Text>\n <Text dimColor={item.status === 'pending'}> {label}</Text>\n </Text>\n );\n })}\n {total > 0 && (\n <Box marginTop={1} gap={1}>\n <Spinner />\n <Text dimColor>\n {completed < total\n ? `Progress: ${completed}/${total} completed`\n : 'Cleaning up...'}\n </Text>\n </Box>\n )}\n </Box>\n );\n};\n"]}
@@ -4,13 +4,14 @@ import { HealthCheckScreen } from './screens/health/HealthCheckScreen.js';
4
4
  import { SettingsOverrideScreen } from './screens/SettingsOverrideScreen.js';
5
5
  import { ManagedSettingsScreen } from './screens/ManagedSettingsScreen.js';
6
6
  import { PortConflictScreen } from './screens/PortConflictScreen.js';
7
- import { IntroScreen } from './screens/IntroScreen.js';
7
+ import { PostHogIntegrationIntroScreen } from './screens/PostHogIntegrationIntroScreen.js';
8
8
  import { RevenueIntroScreen } from './screens/RevenueIntroScreen.js';
9
+ import { AgentSkillIntroScreen } from './screens/AgentSkillIntroScreen.js';
9
10
  import { SetupScreen } from './screens/SetupScreen.js';
10
11
  import { AuthScreen } from './screens/AuthScreen.js';
11
12
  import { RunScreen } from './screens/RunScreen.js';
12
13
  import { McpScreen } from './screens/McpScreen.js';
13
- import { SkillsScreen } from './screens/SkillsScreen.js';
14
+ import { KeepSkillsScreen } from './screens/KeepSkillsScreen.js';
14
15
  import { OutroScreen } from './screens/OutroScreen.js';
15
16
  import { AuthErrorScreen } from './screens/AuthErrorScreen.js';
16
17
  import { createMcpInstaller } from './services/mcp-installer.js';
@@ -27,14 +28,15 @@ export function createScreens(store, services) {
27
28
  [Overlay.PortConflict]: _jsx(PortConflictScreen, { store: store }),
28
29
  [Overlay.AuthError]: _jsx(AuthErrorScreen, {}),
29
30
  // Wizard flow
30
- [Screen.Intro]: _jsx(IntroScreen, { store: store }),
31
+ [Screen.Intro]: _jsx(PostHogIntegrationIntroScreen, { store: store }),
31
32
  [Screen.RevenueIntro]: _jsx(RevenueIntroScreen, { store: store }),
33
+ [Screen.AgentSkillIntro]: _jsx(AgentSkillIntroScreen, { store: store }),
32
34
  [Screen.HealthCheck]: _jsx(HealthCheckScreen, { store: store }),
33
35
  [Screen.Setup]: _jsx(SetupScreen, { store: store }),
34
36
  [Screen.Auth]: _jsx(AuthScreen, { store: store }),
35
37
  [Screen.Run]: _jsx(RunScreen, { store: store }),
36
38
  [Screen.Mcp]: _jsx(McpScreen, { store: store, installer: services.mcpInstaller }),
37
- [Screen.Skills]: _jsx(SkillsScreen, { store: store }),
39
+ [Screen.KeepSkills]: _jsx(KeepSkillsScreen, { store: store }),
38
40
  [Screen.Outro]: _jsx(OutroScreen, { store: store }),
39
41
  // Standalone MCP flows
40
42
  [Screen.McpAdd]: (_jsx(McpScreen, { store: store, installer: services.mcpInstaller, standalone: true })),
@@ -1 +1 @@
1
- {"version":3,"file":"screen-registry.js","sourceRoot":"","sources":["../../../../src/ui/tui/screen-registry.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Screen registry — maps screen names to React components.\n *\n * Adding a new screen:\n * 1. Create the component in screens/\n * 2. Add an entry here\n * 3. Add the screen name to the router flow (router.ts)\n *\n * App.tsx never needs to change.\n */\n\nimport type { ReactNode } from 'react';\nimport type { WizardStore } from './store.js';\nimport { Screen, Overlay, type ScreenName } from './router.js';\n\nimport { HealthCheckScreen } from './screens/health/HealthCheckScreen.js';\nimport { SettingsOverrideScreen } from './screens/SettingsOverrideScreen.js';\nimport { ManagedSettingsScreen } from './screens/ManagedSettingsScreen.js';\nimport { PortConflictScreen } from './screens/PortConflictScreen.js';\nimport { IntroScreen } from './screens/IntroScreen.js';\nimport { RevenueIntroScreen } from './screens/RevenueIntroScreen.js';\nimport { SetupScreen } from './screens/SetupScreen.js';\nimport { AuthScreen } from './screens/AuthScreen.js';\nimport { RunScreen } from './screens/RunScreen.js';\nimport { McpScreen } from './screens/McpScreen.js';\nimport { SkillsScreen } from './screens/SkillsScreen.js';\nimport { OutroScreen } from './screens/OutroScreen.js';\nimport { AuthErrorScreen } from './screens/AuthErrorScreen.js';\nimport { createMcpInstaller } from './services/mcp-installer.js';\nimport type { McpInstaller } from './services/mcp-installer.js';\n\nexport interface ScreenServices {\n mcpInstaller: McpInstaller;\n}\n\nexport function createServices(): ScreenServices {\n return {\n mcpInstaller: createMcpInstaller(),\n };\n}\n\nexport function createScreens(\n store: WizardStore,\n services: ScreenServices,\n): Record<ScreenName, ReactNode> {\n return {\n // Overlays\n [Overlay.SettingsOverride]: <SettingsOverrideScreen store={store} />,\n [Overlay.ManagedSettings]: <ManagedSettingsScreen store={store} />,\n [Overlay.PortConflict]: <PortConflictScreen store={store} />,\n [Overlay.AuthError]: <AuthErrorScreen />,\n\n // Wizard flow\n [Screen.Intro]: <IntroScreen store={store} />,\n [Screen.RevenueIntro]: <RevenueIntroScreen store={store} />,\n [Screen.HealthCheck]: <HealthCheckScreen store={store} />,\n [Screen.Setup]: <SetupScreen store={store} />,\n [Screen.Auth]: <AuthScreen store={store} />,\n [Screen.Run]: <RunScreen store={store} />,\n [Screen.Mcp]: <McpScreen store={store} installer={services.mcpInstaller} />,\n [Screen.Skills]: <SkillsScreen store={store} />,\n [Screen.Outro]: <OutroScreen store={store} />,\n\n // Standalone MCP flows\n [Screen.McpAdd]: (\n <McpScreen store={store} installer={services.mcpInstaller} standalone />\n ),\n [Screen.McpRemove]: (\n <McpScreen\n store={store}\n installer={services.mcpInstaller}\n mode=\"remove\"\n standalone\n />\n ),\n };\n}\n"]}
1
+ {"version":3,"file":"screen-registry.js","sourceRoot":"","sources":["../../../../src/ui/tui/screen-registry.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Screen registry — maps screen names to React components.\n *\n * Adding a new screen:\n * 1. Create the component in screens/\n * 2. Add an entry here\n * 3. Add the screen name to the router flow (router.ts)\n *\n * App.tsx never needs to change.\n */\n\nimport type { ReactNode } from 'react';\nimport type { WizardStore } from './store.js';\nimport { Screen, Overlay, type ScreenName } from './router.js';\n\nimport { HealthCheckScreen } from './screens/health/HealthCheckScreen.js';\nimport { SettingsOverrideScreen } from './screens/SettingsOverrideScreen.js';\nimport { ManagedSettingsScreen } from './screens/ManagedSettingsScreen.js';\nimport { PortConflictScreen } from './screens/PortConflictScreen.js';\nimport { PostHogIntegrationIntroScreen } from './screens/PostHogIntegrationIntroScreen.js';\nimport { RevenueIntroScreen } from './screens/RevenueIntroScreen.js';\nimport { AgentSkillIntroScreen } from './screens/AgentSkillIntroScreen.js';\nimport { SetupScreen } from './screens/SetupScreen.js';\nimport { AuthScreen } from './screens/AuthScreen.js';\nimport { RunScreen } from './screens/RunScreen.js';\nimport { McpScreen } from './screens/McpScreen.js';\nimport { KeepSkillsScreen } from './screens/KeepSkillsScreen.js';\nimport { OutroScreen } from './screens/OutroScreen.js';\nimport { AuthErrorScreen } from './screens/AuthErrorScreen.js';\nimport { createMcpInstaller } from './services/mcp-installer.js';\nimport type { McpInstaller } from './services/mcp-installer.js';\n\nexport interface ScreenServices {\n mcpInstaller: McpInstaller;\n}\n\nexport function createServices(): ScreenServices {\n return {\n mcpInstaller: createMcpInstaller(),\n };\n}\n\nexport function createScreens(\n store: WizardStore,\n services: ScreenServices,\n): Record<ScreenName, ReactNode> {\n return {\n // Overlays\n [Overlay.SettingsOverride]: <SettingsOverrideScreen store={store} />,\n [Overlay.ManagedSettings]: <ManagedSettingsScreen store={store} />,\n [Overlay.PortConflict]: <PortConflictScreen store={store} />,\n [Overlay.AuthError]: <AuthErrorScreen />,\n\n // Wizard flow\n [Screen.Intro]: <PostHogIntegrationIntroScreen store={store} />,\n [Screen.RevenueIntro]: <RevenueIntroScreen store={store} />,\n [Screen.AgentSkillIntro]: <AgentSkillIntroScreen store={store} />,\n [Screen.HealthCheck]: <HealthCheckScreen store={store} />,\n [Screen.Setup]: <SetupScreen store={store} />,\n [Screen.Auth]: <AuthScreen store={store} />,\n [Screen.Run]: <RunScreen store={store} />,\n [Screen.Mcp]: <McpScreen store={store} installer={services.mcpInstaller} />,\n [Screen.KeepSkills]: <KeepSkillsScreen store={store} />,\n [Screen.Outro]: <OutroScreen store={store} />,\n\n // Standalone MCP flows\n [Screen.McpAdd]: (\n <McpScreen store={store} installer={services.mcpInstaller} standalone />\n ),\n [Screen.McpRemove]: (\n <McpScreen\n store={store}\n installer={services.mcpInstaller}\n mode=\"remove\"\n standalone\n />\n ),\n };\n}\n"]}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * AgentSkillIntroScreen — Intro screen for the generic agent-skill workflow.
3
+ *
4
+ * Main menu: one-liner body, detection rows, continue/cancel.
5
+ * More info: skill name, download URL fetched from the skill menu.
6
+ */
7
+ import type { WizardStore } from '../store.js';
8
+ interface AgentSkillIntroScreenProps {
9
+ store: WizardStore;
10
+ }
11
+ export declare const AgentSkillIntroScreen: ({ store, }: AgentSkillIntroScreenProps) => import("react/jsx-runtime").JSX.Element;
12
+ export {};
@@ -0,0 +1,75 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * AgentSkillIntroScreen — Intro screen for the generic agent-skill workflow.
4
+ *
5
+ * Main menu: one-liner body, detection rows, continue/cancel.
6
+ * More info: skill name, download URL fetched from the skill menu.
7
+ */
8
+ import { Box, Text } from 'ink';
9
+ import { useState, useEffect, useSyncExternalStore } from 'react';
10
+ import { IntroScreenLayout } from './IntroScreenLayout.js';
11
+ import { fetchSkillMenu } from '../../../lib/wizard-tools.js';
12
+ import { getSkillsBaseUrl } from '../../../lib/constants.js';
13
+ export const AgentSkillIntroScreen = ({ store, }) => {
14
+ useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
15
+ const [showingMoreInfo, setShowingMoreInfo] = useState(false);
16
+ const [skillEntry, setSkillEntry] = useState(null);
17
+ const [fetchFailed, setFetchFailed] = useState(false);
18
+ const { session } = store;
19
+ const skillId = session.skillId ?? 'unknown';
20
+ const isMainMenu = !showingMoreInfo;
21
+ // Fetch skill entry from the menu when more-info is first opened
22
+ useEffect(() => {
23
+ if (!showingMoreInfo || skillEntry || fetchFailed)
24
+ return;
25
+ const baseUrl = getSkillsBaseUrl(session.localMcp);
26
+ void fetchSkillMenu(baseUrl).then((menu) => {
27
+ if (!menu) {
28
+ setFetchFailed(true);
29
+ return;
30
+ }
31
+ const allSkills = Object.values(menu.categories).flat();
32
+ const match = allSkills.find((s) => s.id === skillId);
33
+ if (match) {
34
+ setSkillEntry(match);
35
+ }
36
+ else {
37
+ setFetchFailed(true);
38
+ }
39
+ });
40
+ }, [showingMoreInfo, skillEntry, fetchFailed, skillId, session.localMcp]);
41
+ // ── Body ─────────────────────────────────────────────────────────────
42
+ let body;
43
+ if (showingMoreInfo) {
44
+ body = (_jsxs(Box, { flexDirection: "column", width: 56, children: [_jsxs(Text, { children: ["Skill:", ' ', _jsx(Text, { italic: true, color: "cyan", children: skillEntry?.id ?? skillId })] }), _jsxs(Text, { children: ["URL:", ' ', _jsx(Text, { color: "cyan", children: skillEntry?.downloadUrl ??
45
+ (fetchFailed ? 'unavailable' : 'Loading...') })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: skillEntry?.name ?? (fetchFailed ? skillId : 'Loading...') }) })] }));
46
+ }
47
+ else {
48
+ body = (_jsxs(Text, { children: ["Let's run the", ' ', _jsx(Text, { italic: true, color: "cyan", children: skillId }), ' ', "skill."] }));
49
+ }
50
+ // ── Menu ─────────────────────────────────────────────────────────────
51
+ const menuOptions = showingMoreInfo
52
+ ? [{ label: 'Back', value: 'back' }]
53
+ : [
54
+ { label: 'Continue', value: 'continue' },
55
+ { label: 'More info', value: 'more-info' },
56
+ { label: 'Cancel', value: 'cancel' },
57
+ ];
58
+ const handleSelect = (value) => {
59
+ if (value === 'cancel') {
60
+ process.exit(0);
61
+ }
62
+ else if (value === 'more-info') {
63
+ setShowingMoreInfo(true);
64
+ }
65
+ else if (value === 'back') {
66
+ setShowingMoreInfo(false);
67
+ }
68
+ else {
69
+ store.completeSetup();
70
+ }
71
+ };
72
+ // ── Render ───────────────────────────────────────────────────────────
73
+ return (_jsx(IntroScreenLayout, { installDir: session.installDir, body: body, showDetection: isMainMenu, workflowLabel: session.workflowLabel, skillId: session.skillId, menuOptions: menuOptions, onSelect: handleSelect }));
74
+ };
75
+ //# sourceMappingURL=AgentSkillIntroScreen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AgentSkillIntroScreen.js","sourceRoot":"","sources":["../../../../../src/ui/tui/screens/AgentSkillIntroScreen.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * AgentSkillIntroScreen — Intro screen for the generic agent-skill workflow.\n *\n * Main menu: one-liner body, detection rows, continue/cancel.\n * More info: skill name, download URL fetched from the skill menu.\n */\n\nimport { Box, Text } from 'ink';\nimport type { ReactNode } from 'react';\nimport { useState, useEffect, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '../store.js';\nimport { IntroScreenLayout } from './IntroScreenLayout.js';\nimport { fetchSkillMenu, type SkillEntry } from '../../../lib/wizard-tools.js';\nimport { getSkillsBaseUrl } from '../../../lib/constants.js';\n\ninterface AgentSkillIntroScreenProps {\n store: WizardStore;\n}\n\nexport const AgentSkillIntroScreen = ({\n store,\n}: AgentSkillIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [showingMoreInfo, setShowingMoreInfo] = useState(false);\n const [skillEntry, setSkillEntry] = useState<SkillEntry | null>(null);\n const [fetchFailed, setFetchFailed] = useState(false);\n\n const { session } = store;\n const skillId = session.skillId ?? 'unknown';\n const isMainMenu = !showingMoreInfo;\n\n // Fetch skill entry from the menu when more-info is first opened\n useEffect(() => {\n if (!showingMoreInfo || skillEntry || fetchFailed) return;\n\n const baseUrl = getSkillsBaseUrl(session.localMcp);\n void fetchSkillMenu(baseUrl).then((menu) => {\n if (!menu) {\n setFetchFailed(true);\n return;\n }\n const allSkills = Object.values(menu.categories).flat();\n const match = allSkills.find((s) => s.id === skillId);\n if (match) {\n setSkillEntry(match);\n } else {\n setFetchFailed(true);\n }\n });\n }, [showingMoreInfo, skillEntry, fetchFailed, skillId, session.localMcp]);\n\n // ── Body ─────────────────────────────────────────────────────────────\n\n let body: ReactNode;\n\n if (showingMoreInfo) {\n body = (\n <Box flexDirection=\"column\" width={56}>\n <Text>\n Skill:{' '}\n <Text italic color=\"cyan\">\n {skillEntry?.id ?? skillId}\n </Text>\n </Text>\n <Text>\n URL:{' '}\n <Text color=\"cyan\">\n {skillEntry?.downloadUrl ??\n (fetchFailed ? 'unavailable' : 'Loading...')}\n </Text>\n </Text>\n <Box marginTop={1}>\n <Text dimColor>\n {skillEntry?.name ?? (fetchFailed ? skillId : 'Loading...')}\n </Text>\n </Box>\n </Box>\n );\n } else {\n body = (\n <Text>\n Let's run the{' '}\n <Text italic color=\"cyan\">\n {skillId}\n </Text>{' '}\n skill.\n </Text>\n );\n }\n\n // ── Menu ─────────────────────────────────────────────────────────────\n\n const menuOptions = showingMoreInfo\n ? [{ label: 'Back', value: 'back' }]\n : [\n { label: 'Continue', value: 'continue' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n ];\n\n const handleSelect = (value: string) => {\n if (value === 'cancel') {\n process.exit(0);\n } else if (value === 'more-info') {\n setShowingMoreInfo(true);\n } else if (value === 'back') {\n setShowingMoreInfo(false);\n } else {\n store.completeSetup();\n }\n };\n\n // ── Render ───────────────────────────────────────────────────────────\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n body={body}\n showDetection={isMainMenu}\n workflowLabel={session.workflowLabel}\n skillId={session.skillId}\n menuOptions={menuOptions}\n onSelect={handleSelect}\n />\n );\n};\n"]}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * IntroScreenLayout ��� Shared visual shell for all workflow intro screens.
3
+ *
4
+ * Purely presentational — no store subscription. Parent components own
5
+ * the store subscription and pass derived data as props.
6
+ *
7
+ * Slots:
8
+ * body — free-form content below the title bar (copy, spinners, pickers, etc.)
9
+ * children — between detection rows and menu (extra info, warnings)
10
+ * errorView — replaces the entire body for fatal error states
11
+ */
12
+ import type { ReactNode } from 'react';
13
+ export interface DetectionRow {
14
+ label: string;
15
+ value: string;
16
+ suffix?: string;
17
+ }
18
+ interface IntroScreenLayoutProps {
19
+ /** Absolute path to the project directory */
20
+ installDir: string;
21
+ /** Title text after the colored blocks, e.g. "PostHog Wizard 🦔" */
22
+ title?: string;
23
+ /** Free-form content below the title (copy, spinners, pickers, notices) */
24
+ body?: ReactNode;
25
+ /** Show the detection block (Directory, detection rows, Workflow, Skill). Default true. */
26
+ showDetection?: boolean;
27
+ /** Extra detection row items rendered as "Label ✔ value suffix" */
28
+ detectionRows?: DetectionRow[];
29
+ /** Content rendered between detection rows and the menu */
30
+ children?: ReactNode;
31
+ /** Menu options. Pass null to hide the menu entirely. */
32
+ menuOptions?: {
33
+ label: string;
34
+ value: string;
35
+ }[] | null;
36
+ /** Called when the user picks a menu option */
37
+ onSelect?: (value: string) => void;
38
+ /** Workflow label shown at the bottom */
39
+ workflowLabel?: string | null;
40
+ /** Skill ID shown at the bottom */
41
+ skillId?: string | null;
42
+ /** Replaces the entire body (topContent + rows + children + menu) for fatal error views */
43
+ errorView?: ReactNode;
44
+ }
45
+ export declare const IntroScreenLayout: ({ installDir, title, body, showDetection, detectionRows, children, menuOptions, onSelect, workflowLabel, skillId, errorView, }: IntroScreenLayoutProps) => import("react/jsx-runtime").JSX.Element;
46
+ export {};
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /**
3
+ * IntroScreenLayout ��� Shared visual shell for all workflow intro screens.
4
+ *
5
+ * Purely presentational — no store subscription. Parent components own
6
+ * the store subscription and pass derived data as props.
7
+ *
8
+ * Slots:
9
+ * body — free-form content below the title bar (copy, spinners, pickers, etc.)
10
+ * children — between detection rows and menu (extra info, warnings)
11
+ * errorView — replaces the entire body for fatal error states
12
+ */
13
+ import path from 'path';
14
+ import { Box, Text } from 'ink';
15
+ import { PickerMenu } from '../primitives/index.js';
16
+ const WizardTitle = ({ title }) => (_jsxs(Text, { bold: true, children: [_jsx(Text, { color: "#1D4AFF", children: '\u2588' }), _jsx(Text, { color: "#F54E00", children: '\u2588' }), _jsx(Text, { color: "#F9BD2B", children: '\u2588' }), " ", title] }));
17
+ export const IntroScreenLayout = ({ installDir, title = 'PostHog Wizard 🦔', body, showDetection = true, detectionRows, children, menuOptions, onSelect, workflowLabel, skillId, errorView, }) => {
18
+ // Default menu: Continue / Cancel
19
+ const resolvedMenuOptions = menuOptions === undefined
20
+ ? [
21
+ { label: 'Continue', value: 'continue' },
22
+ { label: 'Cancel', value: 'cancel' },
23
+ ]
24
+ : menuOptions;
25
+ if (errorView) {
26
+ return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, alignItems: "center", justifyContent: "center", children: [_jsx(Box, { flexDirection: "column", alignItems: "center", marginBottom: 1, children: _jsx(WizardTitle, { title: title }) }), errorView] }));
27
+ }
28
+ return (_jsx(_Fragment, { children: _jsxs(Box, { flexDirection: "column", flexGrow: 1, alignItems: "center", justifyContent: "center", children: [_jsxs(Box, { flexDirection: "column", alignItems: "center", children: [_jsx(WizardTitle, { title: title }), _jsxs(Box, { flexDirection: "column", alignItems: "center", marginTop: 1, children: [_jsx(Text, { dimColor: true, children: "We'll use AI to analyze your project and complete work." }), _jsx(Text, { dimColor: true, children: ".env* file contents will not leave your machine." })] }), body && (_jsx(Box, { flexDirection: "column", alignItems: "center", marginTop: 1, children: body }))] }), children, showDetection && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { children: [_jsxs(Text, { children: ["Directory ", _jsx(Text, { color: "green", children: '\u2714' }), ' '] }), _jsxs(Text, { children: ['/', path.basename(installDir)] })] }), detectionRows?.map((row) => (_jsxs(Text, { children: [_jsxs(Text, { children: [row.label, " ", _jsx(Text, { color: "green", children: '\u2714' }), ' '] }), _jsxs(Text, { children: [row.value, row.suffix ? ` ${row.suffix}` : ''] })] }, row.label))), workflowLabel && (_jsxs(Text, { children: ["Workflow", ' ', _jsx(Text, { color: "green", children: '\u2714' }), " ", workflowLabel] })), workflowLabel === 'agent-skill' && skillId && (_jsxs(Text, { children: ["Skill", ' ', _jsx(Text, { color: "green", children: '\u2714' }), " ", skillId] }))] })), _jsx(Box, { width: 24, children: resolvedMenuOptions && onSelect && (_jsx(Box, { justifyContent: "center", children: _jsx(PickerMenu, { options: resolvedMenuOptions, onSelect: (value) => {
29
+ const choice = Array.isArray(value) ? value[0] : value;
30
+ onSelect(choice);
31
+ } }, resolvedMenuOptions.map((o) => o.value).join(',')) })) })] }) }));
32
+ };
33
+ //# sourceMappingURL=IntroScreenLayout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IntroScreenLayout.js","sourceRoot":"","sources":["../../../../../src/ui/tui/screens/IntroScreenLayout.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * IntroScreenLayout ��� Shared visual shell for all workflow intro screens.\n *\n * Purely presentational — no store subscription. Parent components own\n * the store subscription and pass derived data as props.\n *\n * Slots:\n * body — free-form content below the title bar (copy, spinners, pickers, etc.)\n * children — between detection rows and menu (extra info, warnings)\n * errorView — replaces the entire body for fatal error states\n */\n\nimport path from 'path';\nimport { Box, Text } from 'ink';\nimport type { ReactNode } from 'react';\nimport { PickerMenu } from '../primitives/index.js';\n\nexport interface DetectionRow {\n label: string;\n value: string;\n suffix?: string;\n}\n\ninterface IntroScreenLayoutProps {\n /** Absolute path to the project directory */\n installDir: string;\n\n /** Title text after the colored blocks, e.g. \"PostHog Wizard 🦔\" */\n title?: string;\n\n /** Free-form content below the title (copy, spinners, pickers, notices) */\n body?: ReactNode;\n\n /** Show the detection block (Directory, detection rows, Workflow, Skill). Default true. */\n showDetection?: boolean;\n\n /** Extra detection row items rendered as \"Label ✔ value suffix\" */\n detectionRows?: DetectionRow[];\n\n /** Content rendered between detection rows and the menu */\n children?: ReactNode;\n\n /** Menu options. Pass null to hide the menu entirely. */\n menuOptions?: { label: string; value: string }[] | null;\n\n /** Called when the user picks a menu option */\n onSelect?: (value: string) => void;\n\n /** Workflow label shown at the bottom */\n workflowLabel?: string | null;\n\n /** Skill ID shown at the bottom */\n skillId?: string | null;\n\n /** Replaces the entire body (topContent + rows + children + menu) for fatal error views */\n errorView?: ReactNode;\n}\n\nconst WizardTitle = ({ title }: { title: string }) => (\n <Text bold>\n <Text color=\"#1D4AFF\">{'\\u2588'}</Text>\n <Text color=\"#F54E00\">{'\\u2588'}</Text>\n <Text color=\"#F9BD2B\">{'\\u2588'}</Text> {title}\n </Text>\n);\n\nexport const IntroScreenLayout = ({\n installDir,\n title = 'PostHog Wizard 🦔',\n body,\n showDetection = true,\n detectionRows,\n children,\n menuOptions,\n onSelect,\n workflowLabel,\n skillId,\n errorView,\n}: IntroScreenLayoutProps) => {\n // Default menu: Continue / Cancel\n const resolvedMenuOptions =\n menuOptions === undefined\n ? [\n { label: 'Continue', value: 'continue' },\n { label: 'Cancel', value: 'cancel' },\n ]\n : menuOptions;\n\n if (errorView) {\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <Box flexDirection=\"column\" alignItems=\"center\" marginBottom={1}>\n <WizardTitle title={title} />\n </Box>\n {errorView}\n </Box>\n );\n }\n\n return (\n <>\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <Box flexDirection=\"column\" alignItems=\"center\">\n <WizardTitle title={title} />\n\n <Box flexDirection=\"column\" alignItems=\"center\" marginTop={1}>\n <Text dimColor>\n We'll use AI to analyze your project and complete work.\n </Text>\n <Text dimColor>\n .env* file contents will not leave your machine.\n </Text>\n </Box>\n\n {body && (\n <Box flexDirection=\"column\" alignItems=\"center\" marginTop={1}>\n {body}\n </Box>\n )}\n </Box>\n\n {children}\n\n {showDetection && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n <Text>\n Directory <Text color=\"green\">{'\\u2714'}</Text>{' '}\n </Text>\n <Text>\n {'/'}\n {path.basename(installDir)}\n </Text>\n </Text>\n\n {detectionRows?.map((row) => (\n <Text key={row.label}>\n <Text>\n {row.label} <Text color=\"green\">{'\\u2714'}</Text>{' '}\n </Text>\n <Text>\n {row.value}\n {row.suffix ? ` ${row.suffix}` : ''}\n </Text>\n </Text>\n ))}\n\n {workflowLabel && (\n <Text>\n Workflow{' '}\n <Text color=\"green\">{'\\u2714'}</Text> {workflowLabel}\n </Text>\n )}\n\n {workflowLabel === 'agent-skill' && skillId && (\n <Text>\n Skill{' '}\n <Text color=\"green\">{'\\u2714'}</Text> {skillId}\n </Text>\n )}\n </Box>\n )}\n\n <Box width={24}>\n {resolvedMenuOptions && onSelect && (\n <Box justifyContent=\"center\">\n <PickerMenu\n key={resolvedMenuOptions.map((o) => o.value).join(',')}\n options={resolvedMenuOptions}\n onSelect={(value) => {\n const choice = Array.isArray(value) ? value[0] : value;\n onSelect(choice);\n }}\n />\n </Box>\n )}\n </Box>\n </Box>\n </>\n );\n};\n"]}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * SkillsScreen — Ask whether to keep installed skills in .claude/skills/.
2
+ * KeepSkillsScreen — Ask whether to keep installed skills in .claude/skills/.
3
3
  *
4
4
  * Shown after the outro summary so users see the agent's output first,
5
5
  * then decide whether to keep the skills that powered it.
@@ -7,8 +7,8 @@
7
7
  * When done, calls store.setSkillsComplete() and exits the process.
8
8
  */
9
9
  import type { WizardStore } from '../store.js';
10
- interface SkillsScreenProps {
10
+ interface KeepSkillsScreenProps {
11
11
  store: WizardStore;
12
12
  }
13
- export declare const SkillsScreen: ({ store }: SkillsScreenProps) => import("react/jsx-runtime").JSX.Element;
13
+ export declare const KeepSkillsScreen: ({ store }: KeepSkillsScreenProps) => import("react/jsx-runtime").JSX.Element;
14
14
  export {};
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  /**
3
- * SkillsScreen — Ask whether to keep installed skills in .claude/skills/.
3
+ * KeepSkillsScreen — Ask whether to keep installed skills in .claude/skills/.
4
4
  *
5
5
  * Shown after the outro summary so users see the agent's output first,
6
6
  * then decide whether to keep the skills that powered it.
@@ -22,7 +22,7 @@ var Phase;
22
22
  Phase["Removing"] = "removing";
23
23
  Phase["Done"] = "done";
24
24
  })(Phase || (Phase = {}));
25
- export const SkillsScreen = ({ store }) => {
25
+ export const KeepSkillsScreen = ({ store }) => {
26
26
  useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
27
27
  const [phase, setPhase] = useState(Phase.Loading);
28
28
  const [skills, setSkills] = useState([]);
@@ -63,9 +63,12 @@ export const SkillsScreen = ({ store }) => {
63
63
  // Best-effort removal
64
64
  }
65
65
  setPhase(Phase.Done);
66
- store.setSkillsComplete(false);
67
- process.exit(0);
66
+ // Give React a tick to paint the "Skills removed." message before exit
67
+ setTimeout(() => {
68
+ store.setSkillsComplete(false);
69
+ process.exit(0);
70
+ }, 600);
68
71
  };
69
72
  return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsx(Text, { bold: true, color: Colors.accent, children: "Keep the skills?" }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [phase === Phase.Loading && (_jsx(Text, { dimColor: true, children: "Checking installed skills..." })), phase === Phase.Ask && (_jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: "The wizard installed open-source skills that help AI coding agents integrate PostHog into your project:" }), _jsxs(Box, { marginTop: 1, flexDirection: "column", marginLeft: 2, children: [_jsx(Text, { dimColor: true, children: ".claude/" }), _jsx(Text, { dimColor: true, children: " skills/" }), skills.map((skill) => (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { dimColor: true, children: [" ", skill.name, "/"] }), skill.children.map((child) => (_jsxs(Text, { dimColor: true, children: [' ', child] }, child)))] }, skill.name)))] }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Source: ", _jsx(Text, { color: "cyan", children: CONTEXT_MILL_URL })] }) }), _jsx(Box, { marginTop: 1, children: _jsx(ConfirmationInput, { message: "Keep the installed skills?", confirmLabel: "Keep [Enter]", cancelLabel: "Remove [Esc]", onConfirm: handleKeep, onCancel: () => void handleRemove() }) })] })), phase === Phase.Removing && _jsx(Text, { dimColor: true, children: "Removing skills..." }), phase === Phase.Done && _jsx(Text, { dimColor: true, children: "Skills removed." })] })] }));
70
73
  };
71
- //# sourceMappingURL=SkillsScreen.js.map
74
+ //# sourceMappingURL=KeepSkillsScreen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KeepSkillsScreen.js","sourceRoot":"","sources":["../../../../../src/ui/tui/screens/KeepSkillsScreen.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * KeepSkillsScreen — Ask whether to keep installed skills in .claude/skills/.\n *\n * Shown after the outro summary so users see the agent's output first,\n * then decide whether to keep the skills that powered it.\n *\n * When done, calls store.setSkillsComplete() and exits the process.\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useEffect } from 'react';\nimport { useSyncExternalStore } from 'react';\nimport { readdir, rm } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { WizardStore } from '../store.js';\nimport { ConfirmationInput } from '../primitives/index.js';\nimport { Colors } from '../styles.js';\nimport { CONTEXT_MILL_URL } from '../../../lib/constants.js';\n\ninterface KeepSkillsScreenProps {\n store: WizardStore;\n}\n\ninterface SkillEntry {\n name: string;\n children: string[];\n}\n\nenum Phase {\n Loading = 'loading',\n Ask = 'ask',\n Removing = 'removing',\n Done = 'done',\n}\n\nexport const KeepSkillsScreen = ({ store }: KeepSkillsScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [phase, setPhase] = useState<Phase>(Phase.Loading);\n const [skills, setSkills] = useState<SkillEntry[]>([]);\n\n const skillsDir = join(store.session.installDir, '.claude', 'skills');\n\n useEffect(() => {\n void (async () => {\n try {\n const entries = await readdir(skillsDir, { withFileTypes: true });\n const dirs = entries.filter((e) => e.isDirectory());\n const result: SkillEntry[] = [];\n for (const dir of dirs) {\n const children = await readdir(join(skillsDir, dir.name));\n result.push({ name: dir.name, children });\n }\n if (result.length === 0) {\n store.setSkillsComplete(true);\n process.exit(0);\n }\n setSkills(result);\n setPhase(Phase.Ask);\n } catch {\n store.setSkillsComplete(true);\n process.exit(0);\n }\n })();\n }, []); // eslint-disable-line\n\n const handleKeep = () => {\n store.setSkillsComplete(true);\n process.exit(0);\n };\n\n const handleRemove = async () => {\n setPhase(Phase.Removing);\n try {\n await rm(skillsDir, { recursive: true, force: true });\n } catch {\n // Best-effort removal\n }\n setPhase(Phase.Done);\n // Give React a tick to paint the \"Skills removed.\" message before exit\n setTimeout(() => {\n store.setSkillsComplete(false);\n process.exit(0);\n }, 600);\n };\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n Keep the skills?\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n {phase === Phase.Loading && (\n <Text dimColor>Checking installed skills...</Text>\n )}\n\n {phase === Phase.Ask && (\n <>\n <Text dimColor>\n The wizard installed open-source skills that help AI coding agents\n integrate PostHog into your project:\n </Text>\n <Box marginTop={1} flexDirection=\"column\" marginLeft={2}>\n <Text dimColor>.claude/</Text>\n <Text dimColor> skills/</Text>\n {skills.map((skill) => (\n <Box key={skill.name} flexDirection=\"column\">\n <Text dimColor> {skill.name}/</Text>\n {skill.children.map((child) => (\n <Text key={child} dimColor>\n {' '}\n {child}\n </Text>\n ))}\n </Box>\n ))}\n </Box>\n <Box marginTop={1}>\n <Text dimColor>\n Source: <Text color=\"cyan\">{CONTEXT_MILL_URL}</Text>\n </Text>\n </Box>\n <Box marginTop={1}>\n <ConfirmationInput\n message=\"Keep the installed skills?\"\n confirmLabel=\"Keep [Enter]\"\n cancelLabel=\"Remove [Esc]\"\n onConfirm={handleKeep}\n onCancel={() => void handleRemove()}\n />\n </Box>\n </>\n )}\n\n {phase === Phase.Removing && <Text dimColor>Removing skills...</Text>}\n\n {phase === Phase.Done && <Text dimColor>Skills removed.</Text>}\n </Box>\n </Box>\n );\n};\n"]}
@@ -11,7 +11,7 @@ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-run
11
11
  *
12
12
  * When done, calls store.setMcpComplete(). The router resolves to outro.
13
13
  */
14
- import { Box, Text } from 'ink';
14
+ import { Box, Text, useInput } from 'ink';
15
15
  import { useState, useEffect } from 'react';
16
16
  import { useSyncExternalStore } from 'react';
17
17
  import { McpOutcome } from '../store.js';
@@ -36,6 +36,9 @@ const markDone = (store, outcome, clients = [], standalone = false) => {
36
36
  };
37
37
  export const McpScreen = ({ store, installer, mode = 'install', standalone = false, }) => {
38
38
  useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
39
+ // Keep stdin active from mount so Windows cmd.exe doesn't drop
40
+ // the first keypress when ConfirmationInput appears after detection.
41
+ useInput(() => undefined);
39
42
  const isRemove = mode === 'remove';
40
43
  const [phase, setPhase] = useState(Phase.Detecting);
41
44
  const [clients, setClients] = useState([]);
@@ -1 +1 @@
1
- {"version":3,"file":"McpScreen.js","sourceRoot":"","sources":["../../../../../src/ui/tui/screens/McpScreen.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAoB,UAAU,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EACL,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,sDAAsD,CAAC;AAY9D,IAAK,KAQJ;AARD,WAAK,KAAK;IACR,gCAAuB,CAAA;IACvB,oBAAW,CAAA;IACX,sBAAa,CAAA;IACb,yCAAgC,CAAA;IAChC,4BAAmB,CAAA;IACnB,sBAAa,CAAA;IACb,sBAAa,CAAA;AACf,CAAC,EARI,KAAK,KAAL,KAAK,QAQT;AAED,MAAM,QAAQ,GAAG,CACf,KAAkB,EAClB,OAAmB,EACnB,UAAoB,EAAE,EACtB,UAAU,GAAG,KAAK,EAClB,EAAE;IACF,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACvC,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,EACxB,KAAK,EACL,SAAS,EACT,IAAI,GAAG,SAAS,EAChB,UAAU,GAAG,KAAK,GACH,EAAE,EAAE;IACnB,oBAAoB,CAClB,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,EAC3B,GAAG,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAC1B,CAAC;IAEF,MAAM,QAAQ,GAAG,IAAI,KAAK,QAAQ,CAAC;IAEnC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAQ,KAAK,CAAC,SAAS,CAAC,CAAC;IAC3D,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAkB,EAAE,CAAC,CAAC;IAC5D,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAC;IAC7E,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAW,EAAE,CAAC,CAAC;IAEjE,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,aAAa,EAAE,CAAC;gBACjD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC1B,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBACrB,UAAU,CACR,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,SAAS,EAAE,EAAE,EAAE,UAAU,CAAC,EAC3D,IAAI,CACL,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,UAAU,CAAC,QAAQ,CAAC,CAAC;oBACrB,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACtB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACrB,UAAU,CACR,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,EAAE,EAAE,UAAU,CAAC,EACxD,IAAI,CACL,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;IACP,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,sBAAsB;IAEvC,MAAM,+BAA+B,GAAG,CAAC,WAAqB,EAAE,EAAE;QAChE,sBAAsB,CAAC,WAAW,CAAC,CAAC;QACpC,wDAAwD;QACxD,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YAC9B,KAAK,SAAS,CAAC,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACzD,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAChC,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,GAAG,EAAE;QACzB,IAAI,QAAQ,EAAE,CAAC;YACb,KAAK,QAAQ,EAAE,CAAC;QAClB,CAAC;aAAM,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,+BAA+B,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;IACtD,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,KAAK,EAAE,KAAe,EAAE,QAAmB,EAAE,EAAE;QAC/D,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACxB,IAAI,MAAM,GAAa,EAAE,CAAC;QAC1B,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACxE,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,gBAAgB,CAAC,EAAE,CAAC,CAAC;QACvB,CAAC;QACD,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACrB,MAAM,OAAO,GACX,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;QAC/D,UAAU,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;IACvE,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACxB,IAAI,MAAM,GAAa,EAAE,CAAC;QAC1B,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,CAAC;YAClC,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,gBAAgB,CAAC,EAAE,CAAC,CAAC;QACvB,CAAC;QACD,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACrB,MAAM,OAAO,GACX,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;QAC/D,UAAU,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;IACvE,CAAC,CAAC;IAEF,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,aACrC,MAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,4BACjB,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,IACrC,EAEP,MAAC,GAAG,IAAC,SAAS,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ,aACtC,KAAK,KAAK,KAAK,CAAC,SAAS,IAAI,CAC5B,KAAC,IAAI,IAAC,QAAQ,qDAAsC,CACrD,EAEA,KAAK,KAAK,KAAK,CAAC,IAAI,IAAI,CACvB,MAAC,IAAI,IAAC,QAAQ,0BACR,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,0CAEnC,CACR,EAEA,KAAK,KAAK,KAAK,CAAC,GAAG,IAAI,CACtB,8BACE,MAAC,IAAI,IAAC,QAAQ,iCACD,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAC3C,EACP,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,iBAAiB,IAChB,OAAO,EACL,QAAQ;wCACN,CAAC,CAAC,iDAAiD;wCACnD,CAAC,CAAC,gDAAgD,EAEtD,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa,EACrD,WAAW,EAAC,WAAW,EACvB,SAAS,EAAE,aAAa,EACxB,QAAQ,EAAE,UAAU,GACpB,GACE,IACL,CACJ,EAEA,KAAK,KAAK,KAAK,CAAC,IAAI,IAAI,CACvB,KAAC,UAAU,IACT,OAAO,EAAC,qCAAqC,EAC7C,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;4BAC3B,KAAK,EAAE,CAAC,CAAC,IAAI;4BACb,KAAK,EAAE,CAAC,CAAC,IAAI;yBACd,CAAC,CAAC,EACH,IAAI,EAAC,OAAO,EACZ,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE;4BACrB,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;4BAC9D,+BAA+B,CAAC,KAAK,CAAC,CAAC;wBACzC,CAAC,GACD,CACH,EAEA,KAAK,KAAK,KAAK,CAAC,aAAa,IAAI,CAChC,KAAC,iBAAiB,IAChB,OAAO,EAAC,2BAA2B,EACnC,MAAM,EAAE,kBAAkB,EAC1B,eAAe,EAAE,CAAC,GAAG,kBAAkB,CAAC,EACxC,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE;4BACrB,KAAK,SAAS,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC;wBAChD,CAAC,GACD,CACH,EAEA,KAAK,KAAK,KAAK,CAAC,OAAO,IAAI,CAC1B,MAAC,IAAI,IAAC,QAAQ,mBACX,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,sBAChC,CACR,EAEA,KAAK,KAAK,KAAK,CAAC,IAAI,IAAI,CACvB,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,YACxB,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAC1B,8BACE,MAAC,IAAI,IAAC,KAAK,EAAC,OAAO,EAAC,IAAI,mBACrB,QAAQ,iBAAa,GAAG,EACxB,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,eAAe,SACvC,EACN,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAC9B,MAAC,IAAI,eACF,GAAG,EACH,QAAQ,OAAG,IAAI,KAFP,CAAC,CAGL,CACR,CAAC,IACD,CACJ,CAAC,CAAC,CAAC,CACF,MAAC,IAAI,IAAC,QAAQ,mBACX,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,iBACjC,CACR,GACG,CACP,IACG,IACF,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * McpScreen — MCP server install/remove flow.\n *\n * Uses an McpInstaller service (passed via props) instead of\n * importing business logic directly. Testable, no dynamic imports.\n *\n * Supports two modes via the `mode` prop:\n * - 'install': detect clients → confirm → [pick clients] → pick features → install\n * - 'remove': detect installed clients → confirm → remove\n *\n * When done, calls store.setMcpComplete(). The router resolves to outro.\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useEffect } from 'react';\nimport { useSyncExternalStore } from 'react';\nimport { type WizardStore, McpOutcome } from '../store.js';\nimport {\n ConfirmationInput,\n PickerMenu,\n GroupedPickerMenu,\n} from '../primitives/index.js';\nimport { Colors } from '../styles.js';\nimport type { McpInstaller, McpClientInfo } from '../services/mcp-installer.js';\nimport {\n AVAILABLE_FEATURES,\n ALL_FEATURE_VALUES,\n} from '../../../steps/add-mcp-server-to-clients/defaults.js';\n\nexport type McpMode = 'install' | 'remove';\n\ninterface McpScreenProps {\n store: WizardStore;\n installer: McpInstaller;\n mode?: McpMode;\n /** When true, exit the process after completion instead of routing to outro. */\n standalone?: boolean;\n}\n\nenum Phase {\n Detecting = 'detecting',\n Ask = 'ask',\n Pick = 'pick',\n FeatureSelect = 'feature-select',\n Working = 'working',\n Done = 'done',\n None = 'none',\n}\n\nconst markDone = (\n store: WizardStore,\n outcome: McpOutcome,\n clients: string[] = [],\n standalone = false,\n) => {\n store.setMcpComplete(outcome, clients);\n if (standalone) {\n process.exit(0);\n }\n};\n\nexport const McpScreen = ({\n store,\n installer,\n mode = 'install',\n standalone = false,\n}: McpScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const isRemove = mode === 'remove';\n\n const [phase, setPhase] = useState<Phase>(Phase.Detecting);\n const [clients, setClients] = useState<McpClientInfo[]>([]);\n const [selectedClientNames, setSelectedClientNames] = useState<string[]>([]);\n const [resultClients, setResultClients] = useState<string[]>([]);\n\n useEffect(() => {\n void (async () => {\n try {\n const detected = await installer.detectClients();\n if (detected.length === 0) {\n setPhase(Phase.None);\n setTimeout(\n () => markDone(store, McpOutcome.NoClients, [], standalone),\n 1500,\n );\n } else {\n setClients(detected);\n setPhase(Phase.Ask);\n }\n } catch {\n setPhase(Phase.None);\n setTimeout(\n () => markDone(store, McpOutcome.Failed, [], standalone),\n 1500,\n );\n }\n })();\n }, [installer]); // eslint-disable-line\n\n const proceedToFeatureSelectOrInstall = (clientNames: string[]) => {\n setSelectedClientNames(clientNames);\n // Skip feature picker if CLI already specified features\n if (store.session.mcpFeatures) {\n void doInstall(clientNames, store.session.mcpFeatures);\n } else {\n setPhase(Phase.FeatureSelect);\n }\n };\n\n const handleConfirm = () => {\n if (isRemove) {\n void doRemove();\n } else if (clients.length === 1) {\n proceedToFeatureSelectOrInstall(clients.map((c) => c.name));\n } else {\n setPhase(Phase.Pick);\n }\n };\n\n const handleSkip = () => {\n markDone(store, McpOutcome.Skipped, [], standalone);\n };\n\n const doInstall = async (names: string[], features?: string[]) => {\n setPhase(Phase.Working);\n let result: string[] = [];\n try {\n result = await installer.install(names, features, store.session.apiKey);\n setResultClients(result);\n } catch {\n setResultClients([]);\n }\n setPhase(Phase.Done);\n const outcome =\n result.length > 0 ? McpOutcome.Installed : McpOutcome.Failed;\n setTimeout(() => markDone(store, outcome, result, standalone), 2000);\n };\n\n const doRemove = async () => {\n setPhase(Phase.Working);\n let result: string[] = [];\n try {\n result = await installer.remove();\n setResultClients(result);\n } catch {\n setResultClients([]);\n }\n setPhase(Phase.Done);\n const outcome =\n result.length > 0 ? McpOutcome.Installed : McpOutcome.Failed;\n setTimeout(() => markDone(store, outcome, result, standalone), 2000);\n };\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n MCP Server {isRemove ? 'Removal' : 'Setup'}\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n {phase === Phase.Detecting && (\n <Text dimColor>Detecting supported editors...</Text>\n )}\n\n {phase === Phase.None && (\n <Text dimColor>\n No {isRemove ? 'installed' : 'supported'} MCP clients detected.\n Skipping...\n </Text>\n )}\n\n {phase === Phase.Ask && (\n <>\n <Text dimColor>\n Detected: {clients.map((c) => c.name).join(', ')}\n </Text>\n <Box marginTop={1}>\n <ConfirmationInput\n message={\n isRemove\n ? 'Remove the PostHog MCP server from your editor?'\n : 'Install the PostHog MCP server to your editor?'\n }\n confirmLabel={isRemove ? 'Remove MCP' : 'Install MCP'}\n cancelLabel=\"No thanks\"\n onConfirm={handleConfirm}\n onCancel={handleSkip}\n />\n </Box>\n </>\n )}\n\n {phase === Phase.Pick && (\n <PickerMenu\n message=\"Select editor to install MCP server\"\n options={clients.map((c) => ({\n label: c.name,\n value: c.name,\n }))}\n mode=\"multi\"\n onSelect={(selected) => {\n const names = Array.isArray(selected) ? selected : [selected];\n proceedToFeatureSelectOrInstall(names);\n }}\n />\n )}\n\n {phase === Phase.FeatureSelect && (\n <GroupedPickerMenu\n message=\"Select features to enable\"\n groups={AVAILABLE_FEATURES}\n initialSelected={[...ALL_FEATURE_VALUES]}\n onSelect={(features) => {\n void doInstall(selectedClientNames, features);\n }}\n />\n )}\n\n {phase === Phase.Working && (\n <Text dimColor>\n {isRemove ? 'Removing' : 'Installing'} MCP server...\n </Text>\n )}\n\n {phase === Phase.Done && (\n <Box flexDirection=\"column\">\n {resultClients.length > 0 ? (\n <>\n <Text color=\"green\" bold>\n {'\\u2714'} MCP server{' '}\n {isRemove ? 'removed from' : 'installed for'}:\n </Text>\n {resultClients.map((name, i) => (\n <Text key={i}>\n {' '}\n {'\\u2022'} {name}\n </Text>\n ))}\n </>\n ) : (\n <Text dimColor>\n {isRemove ? 'Removal' : 'Installation'} skipped.\n </Text>\n )}\n </Box>\n )}\n </Box>\n </Box>\n );\n};\n"]}
1
+ {"version":3,"file":"McpScreen.js","sourceRoot":"","sources":["../../../../../src/ui/tui/screens/McpScreen.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * McpScreen — MCP server install/remove flow.\n *\n * Uses an McpInstaller service (passed via props) instead of\n * importing business logic directly. Testable, no dynamic imports.\n *\n * Supports two modes via the `mode` prop:\n * - 'install': detect clients → confirm → [pick clients] → pick features → install\n * - 'remove': detect installed clients → confirm → remove\n *\n * When done, calls store.setMcpComplete(). The router resolves to outro.\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport { useState, useEffect } from 'react';\nimport { useSyncExternalStore } from 'react';\nimport { type WizardStore, McpOutcome } from '../store.js';\nimport {\n ConfirmationInput,\n PickerMenu,\n GroupedPickerMenu,\n} from '../primitives/index.js';\nimport { Colors } from '../styles.js';\nimport type { McpInstaller, McpClientInfo } from '../services/mcp-installer.js';\nimport {\n AVAILABLE_FEATURES,\n ALL_FEATURE_VALUES,\n} from '../../../steps/add-mcp-server-to-clients/defaults.js';\n\nexport type McpMode = 'install' | 'remove';\n\ninterface McpScreenProps {\n store: WizardStore;\n installer: McpInstaller;\n mode?: McpMode;\n /** When true, exit the process after completion instead of routing to outro. */\n standalone?: boolean;\n}\n\nenum Phase {\n Detecting = 'detecting',\n Ask = 'ask',\n Pick = 'pick',\n FeatureSelect = 'feature-select',\n Working = 'working',\n Done = 'done',\n None = 'none',\n}\n\nconst markDone = (\n store: WizardStore,\n outcome: McpOutcome,\n clients: string[] = [],\n standalone = false,\n) => {\n store.setMcpComplete(outcome, clients);\n if (standalone) {\n process.exit(0);\n }\n};\n\nexport const McpScreen = ({\n store,\n installer,\n mode = 'install',\n standalone = false,\n}: McpScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n // Keep stdin active from mount so Windows cmd.exe doesn't drop\n // the first keypress when ConfirmationInput appears after detection.\n useInput(() => undefined);\n\n const isRemove = mode === 'remove';\n\n const [phase, setPhase] = useState<Phase>(Phase.Detecting);\n const [clients, setClients] = useState<McpClientInfo[]>([]);\n const [selectedClientNames, setSelectedClientNames] = useState<string[]>([]);\n const [resultClients, setResultClients] = useState<string[]>([]);\n\n useEffect(() => {\n void (async () => {\n try {\n const detected = await installer.detectClients();\n if (detected.length === 0) {\n setPhase(Phase.None);\n setTimeout(\n () => markDone(store, McpOutcome.NoClients, [], standalone),\n 1500,\n );\n } else {\n setClients(detected);\n setPhase(Phase.Ask);\n }\n } catch {\n setPhase(Phase.None);\n setTimeout(\n () => markDone(store, McpOutcome.Failed, [], standalone),\n 1500,\n );\n }\n })();\n }, [installer]); // eslint-disable-line\n\n const proceedToFeatureSelectOrInstall = (clientNames: string[]) => {\n setSelectedClientNames(clientNames);\n // Skip feature picker if CLI already specified features\n if (store.session.mcpFeatures) {\n void doInstall(clientNames, store.session.mcpFeatures);\n } else {\n setPhase(Phase.FeatureSelect);\n }\n };\n\n const handleConfirm = () => {\n if (isRemove) {\n void doRemove();\n } else if (clients.length === 1) {\n proceedToFeatureSelectOrInstall(clients.map((c) => c.name));\n } else {\n setPhase(Phase.Pick);\n }\n };\n\n const handleSkip = () => {\n markDone(store, McpOutcome.Skipped, [], standalone);\n };\n\n const doInstall = async (names: string[], features?: string[]) => {\n setPhase(Phase.Working);\n let result: string[] = [];\n try {\n result = await installer.install(names, features, store.session.apiKey);\n setResultClients(result);\n } catch {\n setResultClients([]);\n }\n setPhase(Phase.Done);\n const outcome =\n result.length > 0 ? McpOutcome.Installed : McpOutcome.Failed;\n setTimeout(() => markDone(store, outcome, result, standalone), 2000);\n };\n\n const doRemove = async () => {\n setPhase(Phase.Working);\n let result: string[] = [];\n try {\n result = await installer.remove();\n setResultClients(result);\n } catch {\n setResultClients([]);\n }\n setPhase(Phase.Done);\n const outcome =\n result.length > 0 ? McpOutcome.Installed : McpOutcome.Failed;\n setTimeout(() => markDone(store, outcome, result, standalone), 2000);\n };\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n MCP Server {isRemove ? 'Removal' : 'Setup'}\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n {phase === Phase.Detecting && (\n <Text dimColor>Detecting supported editors...</Text>\n )}\n\n {phase === Phase.None && (\n <Text dimColor>\n No {isRemove ? 'installed' : 'supported'} MCP clients detected.\n Skipping...\n </Text>\n )}\n\n {phase === Phase.Ask && (\n <>\n <Text dimColor>\n Detected: {clients.map((c) => c.name).join(', ')}\n </Text>\n <Box marginTop={1}>\n <ConfirmationInput\n message={\n isRemove\n ? 'Remove the PostHog MCP server from your editor?'\n : 'Install the PostHog MCP server to your editor?'\n }\n confirmLabel={isRemove ? 'Remove MCP' : 'Install MCP'}\n cancelLabel=\"No thanks\"\n onConfirm={handleConfirm}\n onCancel={handleSkip}\n />\n </Box>\n </>\n )}\n\n {phase === Phase.Pick && (\n <PickerMenu\n message=\"Select editor to install MCP server\"\n options={clients.map((c) => ({\n label: c.name,\n value: c.name,\n }))}\n mode=\"multi\"\n onSelect={(selected) => {\n const names = Array.isArray(selected) ? selected : [selected];\n proceedToFeatureSelectOrInstall(names);\n }}\n />\n )}\n\n {phase === Phase.FeatureSelect && (\n <GroupedPickerMenu\n message=\"Select features to enable\"\n groups={AVAILABLE_FEATURES}\n initialSelected={[...ALL_FEATURE_VALUES]}\n onSelect={(features) => {\n void doInstall(selectedClientNames, features);\n }}\n />\n )}\n\n {phase === Phase.Working && (\n <Text dimColor>\n {isRemove ? 'Removing' : 'Installing'} MCP server...\n </Text>\n )}\n\n {phase === Phase.Done && (\n <Box flexDirection=\"column\">\n {resultClients.length > 0 ? (\n <>\n <Text color=\"green\" bold>\n {'\\u2714'} MCP server{' '}\n {isRemove ? 'removed from' : 'installed for'}:\n </Text>\n {resultClients.map((name, i) => (\n <Text key={i}>\n {' '}\n {'\\u2022'} {name}\n </Text>\n ))}\n </>\n ) : (\n <Text dimColor>\n {isRemove ? 'Removal' : 'Installation'} skipped.\n </Text>\n )}\n </Box>\n )}\n </Box>\n </Box>\n );\n};\n"]}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * PostHogIntegrationIntroScreen — Intro screen for the core PostHog integration.
3
+ *
4
+ * Composes IntroScreenLayout with framework-detection-specific state:
5
+ * 1. Detecting: spinner while detection runs
6
+ * 2. Detection failed: framework picker
7
+ * 3. Unsupported version: upgrade prompt
8
+ * 4. Detection succeeded: continue/change-framework/cancel
9
+ */
10
+ import type { WizardStore } from '../store.js';
11
+ interface PostHogIntegrationIntroScreenProps {
12
+ store: WizardStore;
13
+ }
14
+ export declare const PostHogIntegrationIntroScreen: ({ store, }: PostHogIntegrationIntroScreenProps) => import("react/jsx-runtime").JSX.Element;
15
+ export {};