@posthog/wizard 2.8.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 (240) hide show
  1. package/README.md +11 -0
  2. package/dist/bin.js +286 -167
  3. package/dist/bin.js.map +1 -1
  4. package/dist/src/__tests__/cli.test.js +92 -59
  5. package/dist/src/__tests__/cli.test.js.map +1 -1
  6. package/dist/src/__tests__/wizard-abort.test.js +34 -13
  7. package/dist/src/__tests__/wizard-abort.test.js.map +1 -1
  8. package/dist/src/frameworks/android/android-wizard-agent.js +2 -2
  9. package/dist/src/frameworks/android/android-wizard-agent.js.map +1 -1
  10. package/dist/src/frameworks/angular/angular-wizard-agent.js +2 -2
  11. package/dist/src/frameworks/angular/angular-wizard-agent.js.map +1 -1
  12. package/dist/src/frameworks/astro/astro-wizard-agent.js +2 -2
  13. package/dist/src/frameworks/astro/astro-wizard-agent.js.map +1 -1
  14. package/dist/src/frameworks/django/django-wizard-agent.js +2 -2
  15. package/dist/src/frameworks/django/django-wizard-agent.js.map +1 -1
  16. package/dist/src/frameworks/fastapi/fastapi-wizard-agent.js +2 -2
  17. package/dist/src/frameworks/fastapi/fastapi-wizard-agent.js.map +1 -1
  18. package/dist/src/frameworks/flask/flask-wizard-agent.js +2 -2
  19. package/dist/src/frameworks/flask/flask-wizard-agent.js.map +1 -1
  20. package/dist/src/frameworks/javascript-node/javascript-node-wizard-agent.js +2 -2
  21. package/dist/src/frameworks/javascript-node/javascript-node-wizard-agent.js.map +1 -1
  22. package/dist/src/frameworks/javascript-web/javascript-web-wizard-agent.js +2 -2
  23. package/dist/src/frameworks/javascript-web/javascript-web-wizard-agent.js.map +1 -1
  24. package/dist/src/frameworks/laravel/laravel-wizard-agent.js +2 -2
  25. package/dist/src/frameworks/laravel/laravel-wizard-agent.js.map +1 -1
  26. package/dist/src/frameworks/nextjs/nextjs-wizard-agent.js +2 -2
  27. package/dist/src/frameworks/nextjs/nextjs-wizard-agent.js.map +1 -1
  28. package/dist/src/frameworks/nuxt/nuxt-wizard-agent.js +2 -2
  29. package/dist/src/frameworks/nuxt/nuxt-wizard-agent.js.map +1 -1
  30. package/dist/src/frameworks/python/python-wizard-agent.js +2 -2
  31. package/dist/src/frameworks/python/python-wizard-agent.js.map +1 -1
  32. package/dist/src/frameworks/rails/rails-wizard-agent.js +2 -2
  33. package/dist/src/frameworks/rails/rails-wizard-agent.js.map +1 -1
  34. package/dist/src/frameworks/react-native/react-native-wizard-agent.js +2 -2
  35. package/dist/src/frameworks/react-native/react-native-wizard-agent.js.map +1 -1
  36. package/dist/src/frameworks/react-router/react-router-wizard-agent.js +2 -2
  37. package/dist/src/frameworks/react-router/react-router-wizard-agent.js.map +1 -1
  38. package/dist/src/frameworks/ruby/ruby-wizard-agent.js +2 -2
  39. package/dist/src/frameworks/ruby/ruby-wizard-agent.js.map +1 -1
  40. package/dist/src/frameworks/svelte/svelte-wizard-agent.js +2 -2
  41. package/dist/src/frameworks/svelte/svelte-wizard-agent.js.map +1 -1
  42. package/dist/src/frameworks/swift/swift-wizard-agent.js +2 -2
  43. package/dist/src/frameworks/swift/swift-wizard-agent.js.map +1 -1
  44. package/dist/src/frameworks/tanstack-router/tanstack-router-wizard-agent.js +2 -2
  45. package/dist/src/frameworks/tanstack-router/tanstack-router-wizard-agent.js.map +1 -1
  46. package/dist/src/frameworks/tanstack-start/tanstack-start-wizard-agent.js +2 -2
  47. package/dist/src/frameworks/tanstack-start/tanstack-start-wizard-agent.js.map +1 -1
  48. package/dist/src/frameworks/vue/vue-wizard-agent.js +2 -2
  49. package/dist/src/frameworks/vue/vue-wizard-agent.js.map +1 -1
  50. package/dist/src/lib/__tests__/agent-interface.test.js +29 -1
  51. package/dist/src/lib/__tests__/agent-interface.test.js.map +1 -1
  52. package/dist/src/lib/agent/__tests__/agent-prompt.test.js +57 -0
  53. package/dist/src/lib/agent/__tests__/agent-prompt.test.js.map +1 -0
  54. package/dist/src/lib/{agent-interface.d.ts → agent/agent-interface.d.ts} +18 -6
  55. package/dist/src/lib/{agent-interface.js → agent/agent-interface.js} +63 -13
  56. package/dist/src/lib/agent/agent-interface.js.map +1 -0
  57. package/dist/src/lib/agent/agent-prompt.d.ts +23 -0
  58. package/dist/src/lib/agent/agent-prompt.js +47 -0
  59. package/dist/src/lib/agent/agent-prompt.js.map +1 -0
  60. package/dist/src/lib/agent/agent-runner.d.ts +78 -0
  61. package/dist/src/lib/agent/agent-runner.js +325 -0
  62. package/dist/src/lib/agent/agent-runner.js.map +1 -0
  63. package/dist/src/lib/agent/commandments.js.map +1 -0
  64. package/dist/src/lib/constants.d.ts +10 -1
  65. package/dist/src/lib/constants.js +13 -1
  66. package/dist/src/lib/constants.js.map +1 -1
  67. package/dist/src/lib/detection/__tests__/context.test.js +72 -0
  68. package/dist/src/lib/detection/__tests__/context.test.js.map +1 -0
  69. package/dist/src/lib/detection/__tests__/features.test.d.ts +1 -0
  70. package/dist/src/lib/detection/__tests__/features.test.js +75 -0
  71. package/dist/src/lib/detection/__tests__/features.test.js.map +1 -0
  72. package/dist/src/lib/detection/__tests__/package-manager.test.d.ts +1 -0
  73. package/dist/src/lib/{__tests__/package-manager-detection.test.js → detection/__tests__/package-manager.test.js} +25 -25
  74. package/dist/src/lib/detection/__tests__/package-manager.test.js.map +1 -0
  75. package/dist/src/lib/detection/context.d.ts +31 -0
  76. package/dist/src/lib/detection/context.js +92 -0
  77. package/dist/src/lib/detection/context.js.map +1 -0
  78. package/dist/src/lib/detection/features.d.ts +16 -0
  79. package/dist/src/lib/detection/features.js +56 -0
  80. package/dist/src/lib/detection/features.js.map +1 -0
  81. package/dist/src/lib/detection/framework.d.ts +14 -0
  82. package/dist/src/lib/detection/framework.js +35 -0
  83. package/dist/src/lib/detection/framework.js.map +1 -0
  84. package/dist/src/lib/detection/index.d.ts +3 -0
  85. package/dist/src/lib/detection/index.js +11 -0
  86. package/dist/src/lib/detection/index.js.map +1 -0
  87. package/dist/src/lib/{package-manager-detection.js → detection/package-manager.js} +3 -3
  88. package/dist/src/lib/detection/package-manager.js.map +1 -0
  89. package/dist/src/lib/framework-config.d.ts +1 -1
  90. package/dist/src/lib/framework-config.js.map +1 -1
  91. package/dist/src/lib/health-checks/endpoints.js +2 -1
  92. package/dist/src/lib/health-checks/endpoints.js.map +1 -1
  93. package/dist/src/lib/middleware/benchmark.js +1 -1
  94. package/dist/src/lib/middleware/benchmark.js.map +1 -1
  95. package/dist/src/lib/middleware/benchmarks/compaction-tracker.js +1 -1
  96. package/dist/src/lib/middleware/benchmarks/compaction-tracker.js.map +1 -1
  97. package/dist/src/lib/middleware/benchmarks/json-writer.js +1 -1
  98. package/dist/src/lib/middleware/benchmarks/json-writer.js.map +1 -1
  99. package/dist/src/lib/middleware/benchmarks/summary.js +1 -1
  100. package/dist/src/lib/middleware/benchmarks/summary.js.map +1 -1
  101. package/dist/src/lib/middleware/config.js +1 -1
  102. package/dist/src/lib/middleware/config.js.map +1 -1
  103. package/dist/src/lib/version.d.ts +1 -1
  104. package/dist/src/lib/version.js +1 -1
  105. package/dist/src/lib/version.js.map +1 -1
  106. package/dist/src/lib/wizard-session.d.ts +16 -7
  107. package/dist/src/lib/wizard-session.js +2 -0
  108. package/dist/src/lib/wizard-session.js.map +1 -1
  109. package/dist/src/lib/wizard-tools.d.ts +28 -1
  110. package/dist/src/lib/wizard-tools.js +24 -0
  111. package/dist/src/lib/wizard-tools.js.map +1 -1
  112. package/dist/src/lib/workflows/__tests__/agent-skill.test.d.ts +1 -0
  113. package/dist/src/lib/workflows/__tests__/agent-skill.test.js +73 -0
  114. package/dist/src/lib/workflows/__tests__/agent-skill.test.js.map +1 -0
  115. package/dist/src/lib/workflows/__tests__/revenue-analytics-detect.test.d.ts +1 -0
  116. package/dist/src/lib/workflows/__tests__/revenue-analytics-detect.test.js +101 -0
  117. package/dist/src/lib/workflows/__tests__/revenue-analytics-detect.test.js.map +1 -0
  118. package/dist/src/lib/workflows/__tests__/workflow-registry.test.d.ts +1 -0
  119. package/dist/src/lib/workflows/__tests__/workflow-registry.test.js +32 -0
  120. package/dist/src/lib/workflows/__tests__/workflow-registry.test.js.map +1 -0
  121. package/dist/src/lib/workflows/__tests__/workflow-step.test.d.ts +1 -0
  122. package/dist/src/lib/workflows/__tests__/workflow-step.test.js +54 -0
  123. package/dist/src/lib/workflows/__tests__/workflow-step.test.js.map +1 -0
  124. package/dist/src/lib/workflows/agent-skill/index.d.ts +44 -0
  125. package/dist/src/lib/workflows/agent-skill/index.js +47 -0
  126. package/dist/src/lib/workflows/agent-skill/index.js.map +1 -0
  127. package/dist/src/lib/workflows/agent-skill/steps.d.ts +8 -0
  128. package/dist/src/lib/workflows/agent-skill/steps.js +43 -0
  129. package/dist/src/lib/workflows/agent-skill/steps.js.map +1 -0
  130. package/dist/src/lib/workflows/posthog-integration/detect.d.ts +12 -0
  131. package/dist/src/lib/workflows/posthog-integration/detect.js +57 -0
  132. package/dist/src/lib/workflows/posthog-integration/detect.js.map +1 -0
  133. package/dist/src/lib/workflows/posthog-integration/index.d.ts +3 -0
  134. package/dist/src/lib/workflows/posthog-integration/index.js +152 -0
  135. package/dist/src/lib/workflows/posthog-integration/index.js.map +1 -0
  136. package/dist/src/lib/workflows/posthog-integration/steps.d.ts +9 -0
  137. package/dist/src/lib/workflows/posthog-integration/steps.js +100 -0
  138. package/dist/src/lib/workflows/posthog-integration/steps.js.map +1 -0
  139. package/dist/src/lib/workflows/revenue-analytics/detect.d.ts +40 -0
  140. package/dist/src/lib/workflows/revenue-analytics/detect.js +156 -0
  141. package/dist/src/lib/workflows/revenue-analytics/detect.js.map +1 -0
  142. package/dist/src/lib/workflows/revenue-analytics/index.d.ts +4 -0
  143. package/dist/src/lib/workflows/revenue-analytics/index.js +30 -0
  144. package/dist/src/lib/workflows/revenue-analytics/index.js.map +1 -0
  145. package/dist/src/lib/workflows/revenue-analytics/steps.d.ts +8 -0
  146. package/dist/src/lib/workflows/revenue-analytics/steps.js +53 -0
  147. package/dist/src/lib/workflows/revenue-analytics/steps.js.map +1 -0
  148. package/dist/src/lib/workflows/workflow-registry.d.ts +18 -0
  149. package/dist/src/lib/workflows/workflow-registry.js +32 -0
  150. package/dist/src/lib/workflows/workflow-registry.js.map +1 -0
  151. package/dist/src/lib/workflows/workflow-step.d.ts +126 -0
  152. package/dist/src/lib/workflows/workflow-step.js +28 -0
  153. package/dist/src/lib/workflows/workflow-step.js.map +1 -0
  154. package/dist/src/steps/add-mcp-server-to-clients/index.d.ts +2 -1
  155. package/dist/src/steps/add-mcp-server-to-clients/index.js.map +1 -1
  156. package/dist/src/ui/logging-ui.d.ts +6 -3
  157. package/dist/src/ui/logging-ui.js +7 -0
  158. package/dist/src/ui/logging-ui.js.map +1 -1
  159. package/dist/src/ui/tui/__tests__/flows.test.d.ts +1 -0
  160. package/dist/src/ui/tui/__tests__/flows.test.js +115 -0
  161. package/dist/src/ui/tui/__tests__/flows.test.js.map +1 -0
  162. package/dist/src/ui/tui/__tests__/router.test.d.ts +1 -0
  163. package/dist/src/ui/tui/__tests__/router.test.js +87 -0
  164. package/dist/src/ui/tui/__tests__/router.test.js.map +1 -0
  165. package/dist/src/ui/tui/__tests__/store.test.js +149 -13
  166. package/dist/src/ui/tui/__tests__/store.test.js.map +1 -1
  167. package/dist/src/ui/tui/flows.d.ts +19 -7
  168. package/dist/src/ui/tui/flows.js +30 -53
  169. package/dist/src/ui/tui/flows.js.map +1 -1
  170. package/dist/src/ui/tui/ink-ui.d.ts +6 -3
  171. package/dist/src/ui/tui/ink-ui.js +7 -0
  172. package/dist/src/ui/tui/ink-ui.js.map +1 -1
  173. package/dist/src/ui/tui/playground/PlaygroundApp.js +6 -0
  174. package/dist/src/ui/tui/playground/PlaygroundApp.js.map +1 -1
  175. package/dist/src/ui/tui/playground/demos/McpDemo.d.ts +12 -0
  176. package/dist/src/ui/tui/playground/demos/McpDemo.js +27 -0
  177. package/dist/src/ui/tui/playground/demos/McpDemo.js.map +1 -0
  178. package/dist/src/ui/tui/router.js +1 -1
  179. package/dist/src/ui/tui/router.js.map +1 -1
  180. package/dist/src/ui/tui/screen-registry.js +8 -4
  181. package/dist/src/ui/tui/screen-registry.js.map +1 -1
  182. package/dist/src/ui/tui/screens/AgentSkillIntroScreen.d.ts +12 -0
  183. package/dist/src/ui/tui/screens/AgentSkillIntroScreen.js +75 -0
  184. package/dist/src/ui/tui/screens/AgentSkillIntroScreen.js.map +1 -0
  185. package/dist/src/ui/tui/screens/IntroScreenLayout.d.ts +46 -0
  186. package/dist/src/ui/tui/screens/IntroScreenLayout.js +33 -0
  187. package/dist/src/ui/tui/screens/IntroScreenLayout.js.map +1 -0
  188. package/dist/src/ui/tui/screens/{SkillsScreen.d.ts → KeepSkillsScreen.d.ts} +3 -3
  189. package/dist/src/ui/tui/screens/{SkillsScreen.js → KeepSkillsScreen.js} +8 -5
  190. package/dist/src/ui/tui/screens/KeepSkillsScreen.js.map +1 -0
  191. package/dist/src/ui/tui/screens/ManagedSettingsScreen.js.map +1 -1
  192. package/dist/src/ui/tui/screens/McpScreen.js +4 -1
  193. package/dist/src/ui/tui/screens/McpScreen.js.map +1 -1
  194. package/dist/src/ui/tui/screens/OutroScreen.js +1 -1
  195. package/dist/src/ui/tui/screens/OutroScreen.js.map +1 -1
  196. package/dist/src/ui/tui/screens/PostHogIntegrationIntroScreen.d.ts +15 -0
  197. package/dist/src/ui/tui/screens/PostHogIntegrationIntroScreen.js +135 -0
  198. package/dist/src/ui/tui/screens/PostHogIntegrationIntroScreen.js.map +1 -0
  199. package/dist/src/ui/tui/screens/RevenueIntroScreen.d.ts +16 -0
  200. package/dist/src/ui/tui/screens/RevenueIntroScreen.js +89 -0
  201. package/dist/src/ui/tui/screens/RevenueIntroScreen.js.map +1 -0
  202. package/dist/src/ui/tui/screens/SettingsOverrideScreen.js.map +1 -1
  203. package/dist/src/ui/tui/screens/health/HealthCheckScreen.js +2 -2
  204. package/dist/src/ui/tui/screens/health/HealthCheckScreen.js.map +1 -1
  205. package/dist/src/ui/tui/start-tui.js +2 -2
  206. package/dist/src/ui/tui/start-tui.js.map +1 -1
  207. package/dist/src/ui/tui/store.d.ts +46 -21
  208. package/dist/src/ui/tui/store.js +107 -47
  209. package/dist/src/ui/tui/store.js.map +1 -1
  210. package/dist/src/ui/wizard-ui.d.ts +13 -3
  211. package/dist/src/ui/wizard-ui.js.map +1 -1
  212. package/dist/src/utils/file-utils.d.ts +8 -0
  213. package/dist/src/utils/file-utils.js +32 -0
  214. package/dist/src/utils/file-utils.js.map +1 -1
  215. package/dist/src/utils/wizard-abort.d.ts +3 -0
  216. package/dist/src/utils/wizard-abort.js +5 -3
  217. package/dist/src/utils/wizard-abort.js.map +1 -1
  218. package/npm-shrinkwrap.json +2 -2
  219. package/package.json +1 -1
  220. package/dist/src/__tests__/run.test.js +0 -95
  221. package/dist/src/__tests__/run.test.js.map +0 -1
  222. package/dist/src/lib/__tests__/package-manager-detection.test.js.map +0 -1
  223. package/dist/src/lib/agent-interface.js.map +0 -1
  224. package/dist/src/lib/agent-runner.d.ts +0 -9
  225. package/dist/src/lib/agent-runner.js +0 -385
  226. package/dist/src/lib/agent-runner.js.map +0 -1
  227. package/dist/src/lib/commandments.js.map +0 -1
  228. package/dist/src/lib/package-manager-detection.js.map +0 -1
  229. package/dist/src/run.d.ts +0 -23
  230. package/dist/src/run.js +0 -154
  231. package/dist/src/run.js.map +0 -1
  232. package/dist/src/ui/tui/screens/IntroScreen.d.ts +0 -16
  233. package/dist/src/ui/tui/screens/IntroScreen.js +0 -79
  234. package/dist/src/ui/tui/screens/IntroScreen.js.map +0 -1
  235. package/dist/src/ui/tui/screens/SkillsScreen.js.map +0 -1
  236. /package/dist/src/{__tests__/run.test.d.ts → lib/agent/__tests__/agent-prompt.test.d.ts} +0 -0
  237. /package/dist/src/lib/{commandments.d.ts → agent/commandments.d.ts} +0 -0
  238. /package/dist/src/lib/{commandments.js → agent/commandments.js} +0 -0
  239. /package/dist/src/lib/{__tests__/package-manager-detection.test.d.ts → detection/__tests__/context.test.d.ts} +0 -0
  240. /package/dist/src/lib/{package-manager-detection.d.ts → detection/package-manager.d.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"ink-ui.js","sourceRoot":"","sources":["../../../../src/ui/tui/ink-ui.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * InkUI — Ink-backed implementation of WizardUI.\n *\n * Translates business logic calls into store setter calls.\n * No direct session mutation. No imperative screen transitions.\n * The router derives the active screen from session state.\n */\n\nimport type { WizardUI, SpinnerHandle } from '../wizard-ui.js';\nimport type { WizardStore } from './store.js';\nimport type { SettingsConflict } from '../../lib/agent-interface.js';\nimport { RunPhase, OutroKind } from '../../lib/wizard-session.js';\n\n// Strip ANSI escape codes (chalk formatting) from strings\n// eslint-disable-next-line no-control-regex\nconst ANSI_RE = /\\x1b\\[[0-9;]*m/g;\nfunction stripAnsi(s: string): string {\n return s.replace(ANSI_RE, '');\n}\n\nexport class InkUI implements WizardUI {\n constructor(private store: WizardStore) {}\n\n intro(message: string): void {\n this.store.pushStatus(message);\n }\n\n outro(message: string): void {\n this.store.pushStatus(stripAnsi(message));\n\n if (!this.store.session.outroData) {\n this.store.setOutroData({\n kind: OutroKind.Success,\n message: stripAnsi(message),\n });\n }\n\n // Signal that the main work is done — router resolves to mcp or outro\n if (this.store.session.runPhase === RunPhase.Running) {\n this.store.setRunPhase(RunPhase.Completed);\n }\n }\n\n setCredentials(credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n }): void {\n this.store.setCredentials(credentials);\n }\n\n setDetectedFramework(label: string): void {\n this.store.setDetectedFramework(label);\n }\n\n onEnterScreen(screen: string, fn: () => void): void {\n this.store.onEnterScreen(\n screen as Parameters<WizardStore['onEnterScreen']>[0],\n fn,\n );\n }\n\n setLoginUrl(url: string | null): void {\n this.store.setLoginUrl(url);\n }\n\n showBlockingOutage(\n result: import('../../lib/health-checks/readiness.js').WizardReadinessResult,\n ): Promise<void> {\n // In the TUI, the HealthCheckScreen handles outage display.\n // This is only called from agent-runner for the CI fallback path.\n this.store.setReadinessResult(result);\n return Promise.resolve();\n }\n\n setReadinessWarnings(\n result: import('../../lib/health-checks/readiness.js').WizardReadinessResult,\n ): void {\n this.store.setReadinessResult(result);\n }\n\n showPortConflict(processInfo: {\n command: string;\n pid: string;\n user: string;\n }): Promise<void> {\n return this.store.showPortConflict(processInfo);\n }\n\n showSettingsOverride(\n conflicts: SettingsConflict[],\n backupAndFix: () => boolean,\n ): Promise<void> {\n return this.store.showSettingsOverride(conflicts, backupAndFix);\n }\n\n showAuthError(): void {\n this.store.showAuthError();\n }\n\n startRun(): void {\n this.store.setRunPhase(RunPhase.Running);\n }\n\n cancel(message: string): void {\n this.store.pushStatus(message);\n }\n\n log = {\n info: (message: string): void => {\n this.store.pushStatus(message);\n },\n warn: (message: string): void => {\n this.store.pushStatus(message);\n },\n error: (message: string): void => {\n this.store.pushStatus(message);\n },\n success: (message: string): void => {\n this.store.pushStatus(message);\n },\n step: (message: string): void => {\n this.store.pushStatus(message);\n },\n };\n\n note(message: string): void {\n this.store.pushStatus(message);\n }\n\n spinner(): SpinnerHandle {\n return {\n start: (message?: string) => {\n if (message) this.store.pushStatus(message);\n },\n stop: (message?: string) => {\n if (message) this.store.pushStatus(message);\n },\n message: (msg?: string) => {\n if (msg) this.store.pushStatus(msg);\n },\n };\n }\n\n pushStatus(message: string): void {\n this.store.pushStatus(message);\n }\n\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void {\n this.store.syncTodos(todos);\n }\n\n setEventPlan(events: Array<{ name: string; description: string }>): void {\n this.store.setEventPlan(events);\n }\n}\n"]}
1
+ {"version":3,"file":"ink-ui.js","sourceRoot":"","sources":["../../../../src/ui/tui/ink-ui.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * InkUI — Ink-backed implementation of WizardUI.\n *\n * Translates business logic calls into store setter calls.\n * No direct session mutation. No imperative screen transitions.\n * The router derives the active screen from session state.\n */\n\nimport type { WizardUI, SpinnerHandle } from '../wizard-ui.js';\nimport type { WizardStore } from './store.js';\nimport type { SettingsConflict } from '../../lib/agent/agent-interface.js';\nimport type { WizardReadinessResult } from '../../lib/health-checks/readiness.js';\nimport type { OutroData } from '../../lib/wizard-session.js';\nimport { RunPhase, OutroKind } from '../../lib/wizard-session.js';\n\n// Strip ANSI escape codes (chalk formatting) from strings\n// eslint-disable-next-line no-control-regex\nconst ANSI_RE = /\\x1b\\[[0-9;]*m/g;\nfunction stripAnsi(s: string): string {\n return s.replace(ANSI_RE, '');\n}\n\nexport class InkUI implements WizardUI {\n constructor(private store: WizardStore) {}\n\n intro(message: string): void {\n this.store.pushStatus(message);\n }\n\n outro(message: string): void {\n this.store.pushStatus(stripAnsi(message));\n\n if (!this.store.session.outroData) {\n this.store.setOutroData({\n kind: OutroKind.Success,\n message: stripAnsi(message),\n });\n }\n\n // Signal that the main work is done — router resolves to mcp or outro\n if (this.store.session.runPhase === RunPhase.Running) {\n this.store.setRunPhase(RunPhase.Completed);\n }\n }\n\n outroError(data: OutroData): void {\n this.store.setOutroData(data);\n // Advance router past the run step so the outro screen renders\n if (this.store.session.runPhase !== RunPhase.Error) {\n this.store.setRunPhase(RunPhase.Error);\n }\n }\n\n setCredentials(credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n }): void {\n this.store.setCredentials(credentials);\n }\n\n setDetectedFramework(label: string): void {\n this.store.setDetectedFramework(label);\n }\n\n onEnterScreen(screen: string, fn: () => void): void {\n this.store.onEnterScreen(\n screen as Parameters<WizardStore['onEnterScreen']>[0],\n fn,\n );\n }\n\n setLoginUrl(url: string | null): void {\n this.store.setLoginUrl(url);\n }\n\n showBlockingOutage(result: WizardReadinessResult): Promise<void> {\n // In the TUI, the HealthCheckScreen handles outage display.\n // This is only called from agent-runner for the CI fallback path.\n this.store.setReadinessResult(result);\n return Promise.resolve();\n }\n\n setReadinessWarnings(result: WizardReadinessResult): void {\n this.store.setReadinessResult(result);\n }\n\n showPortConflict(processInfo: {\n command: string;\n pid: string;\n user: string;\n }): Promise<void> {\n return this.store.showPortConflict(processInfo);\n }\n\n showSettingsOverride(\n conflicts: SettingsConflict[],\n backupAndFix: () => boolean,\n ): Promise<void> {\n return this.store.showSettingsOverride(conflicts, backupAndFix);\n }\n\n showAuthError(): void {\n this.store.showAuthError();\n }\n\n startRun(): void {\n this.store.setRunPhase(RunPhase.Running);\n }\n\n cancel(message: string): void {\n this.store.pushStatus(message);\n }\n\n log = {\n info: (message: string): void => {\n this.store.pushStatus(message);\n },\n warn: (message: string): void => {\n this.store.pushStatus(message);\n },\n error: (message: string): void => {\n this.store.pushStatus(message);\n },\n success: (message: string): void => {\n this.store.pushStatus(message);\n },\n step: (message: string): void => {\n this.store.pushStatus(message);\n },\n };\n\n note(message: string): void {\n this.store.pushStatus(message);\n }\n\n spinner(): SpinnerHandle {\n return {\n start: (message?: string) => {\n if (message) this.store.pushStatus(message);\n },\n stop: (message?: string) => {\n if (message) this.store.pushStatus(message);\n },\n message: (msg?: string) => {\n if (msg) this.store.pushStatus(msg);\n },\n };\n }\n\n pushStatus(message: string): void {\n this.store.pushStatus(message);\n }\n\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void {\n this.store.syncTodos(todos);\n }\n\n setEventPlan(events: Array<{ name: string; description: string }>): void {\n this.store.setEventPlan(events);\n }\n}\n"]}
@@ -14,6 +14,7 @@ import { LogDemo } from './demos/LogDemo.js';
14
14
  import { RunScreenDemo } from './demos/RunScreenDemo.js';
15
15
  import { HealthCheckDemo } from './demos/HealthCheckDemo.js';
16
16
  import { ModalDemo } from './demos/ModalDemo.js';
17
+ import { McpDemo } from './demos/McpDemo.js';
17
18
  export const PlaygroundApp = ({ store }) => {
18
19
  const tabs = [
19
20
  { id: 'layout', label: 'Layout', component: _jsx(LayoutDemo, {}) },
@@ -35,6 +36,11 @@ export const PlaygroundApp = ({ store }) => {
35
36
  label: 'Modal',
36
37
  component: _jsx(ModalDemo, {}),
37
38
  },
39
+ {
40
+ id: 'mcp',
41
+ label: 'MCP',
42
+ component: _jsx(McpDemo, { store: store }),
43
+ },
38
44
  ];
39
45
  return (_jsx(ScreenContainer, { store: store, screens: {
40
46
  intro: _jsx(WelcomeDemo, { store: store }),
@@ -1 +1 @@
1
- {"version":3,"file":"PlaygroundApp.js","sourceRoot":"","sources":["../../../../../src/ui/tui/playground/PlaygroundApp.tsx"],"names":[],"mappings":";AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEvE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAMjD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,EAAE,KAAK,EAAsB,EAAE,EAAE;IAC7D,MAAM,IAAI,GAAG;QACX,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAC,UAAU,KAAG,EAAE;QAC5D,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,KAAC,SAAS,KAAG,EAAE;QACzD,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,KAAC,YAAY,KAAG,EAAE;QAClE,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,KAAC,OAAO,KAAG,EAAE;QACrD;YACE,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,WAAW;YAClB,SAAS,EAAE,KAAC,aAAa,IAAC,KAAK,EAAE,KAAK,GAAI;SAC3C;QACD;YACE,EAAE,EAAE,QAAQ;YACZ,KAAK,EAAE,aAAa;YACpB,SAAS,EAAE,KAAC,eAAe,KAAG;SAC/B;QACD;YACE,EAAE,EAAE,OAAO;YACX,KAAK,EAAE,OAAO;YACd,SAAS,EAAE,KAAC,SAAS,KAAG;SACzB;KACF,CAAC;IAEF,OAAO,CACL,KAAC,eAAe,IACd,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE;YACP,KAAK,EAAE,KAAC,WAAW,IAAC,KAAK,EAAE,KAAK,GAAI;YACpC,GAAG,EAAE,CACH,KAAC,YAAY,IACX,IAAI,EAAE,IAAI,EACV,aAAa,EAAC,4DAAuD,GACrE,CACH;SACF,GACD,CACH,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * PlaygroundApp — Root component for the primitives playground.\n *\n * Two screens mirroring the real wizard flow:\n * intro → (press enter) → run (tabbed demo view)\n */\n\nimport { ScreenContainer, TabContainer } from '../primitives/index.js';\nimport type { WizardStore } from '../store.js';\nimport { WelcomeDemo } from './demos/WelcomeDemo.js';\nimport { LayoutDemo } from './demos/LayoutDemo.js';\nimport { InputDemo } from './demos/InputDemo.js';\nimport { ProgressDemo } from './demos/ProgressDemo.js';\nimport { LogDemo } from './demos/LogDemo.js';\nimport { RunScreenDemo } from './demos/RunScreenDemo.js';\nimport { HealthCheckDemo } from './demos/HealthCheckDemo.js';\nimport { ModalDemo } from './demos/ModalDemo.js';\n\ninterface PlaygroundAppProps {\n store: WizardStore;\n}\n\nexport const PlaygroundApp = ({ store }: PlaygroundAppProps) => {\n const tabs = [\n { id: 'layout', label: 'Layout', component: <LayoutDemo /> },\n { id: 'input', label: 'Input', component: <InputDemo /> },\n { id: 'progress', label: 'Progress', component: <ProgressDemo /> },\n { id: 'logs', label: 'Logs', component: <LogDemo /> },\n {\n id: 'run',\n label: 'RunScreen',\n component: <RunScreenDemo store={store} />,\n },\n {\n id: 'health',\n label: 'HealthCheck',\n component: <HealthCheckDemo />,\n },\n {\n id: 'modal',\n label: 'Modal',\n component: <ModalDemo />,\n },\n ];\n\n return (\n <ScreenContainer\n store={store}\n screens={{\n intro: <WelcomeDemo store={store} />,\n run: (\n <TabContainer\n tabs={tabs}\n statusMessage=\"Primitives Playground — use arrow keys to switch tabs\"\n />\n ),\n }}\n />\n );\n};\n"]}
1
+ {"version":3,"file":"PlaygroundApp.js","sourceRoot":"","sources":["../../../../../src/ui/tui/playground/PlaygroundApp.tsx"],"names":[],"mappings":";AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEvE,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAM7C,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,EAAE,KAAK,EAAsB,EAAE,EAAE;IAC7D,MAAM,IAAI,GAAG;QACX,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAC,UAAU,KAAG,EAAE;QAC5D,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,KAAC,SAAS,KAAG,EAAE;QACzD,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,KAAC,YAAY,KAAG,EAAE;QAClE,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,KAAC,OAAO,KAAG,EAAE;QACrD;YACE,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,WAAW;YAClB,SAAS,EAAE,KAAC,aAAa,IAAC,KAAK,EAAE,KAAK,GAAI;SAC3C;QACD;YACE,EAAE,EAAE,QAAQ;YACZ,KAAK,EAAE,aAAa;YACpB,SAAS,EAAE,KAAC,eAAe,KAAG;SAC/B;QACD;YACE,EAAE,EAAE,OAAO;YACX,KAAK,EAAE,OAAO;YACd,SAAS,EAAE,KAAC,SAAS,KAAG;SACzB;QACD;YACE,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,KAAK;YACZ,SAAS,EAAE,KAAC,OAAO,IAAC,KAAK,EAAE,KAAK,GAAI;SACrC;KACF,CAAC;IAEF,OAAO,CACL,KAAC,eAAe,IACd,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE;YACP,KAAK,EAAE,KAAC,WAAW,IAAC,KAAK,EAAE,KAAK,GAAI;YACpC,GAAG,EAAE,CACH,KAAC,YAAY,IACX,IAAI,EAAE,IAAI,EACV,aAAa,EAAC,4DAAuD,GACrE,CACH;SACF,GACD,CACH,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * PlaygroundApp — Root component for the primitives playground.\n *\n * Two screens mirroring the real wizard flow:\n * intro → (press enter) → run (tabbed demo view)\n */\n\nimport { ScreenContainer, TabContainer } from '../primitives/index.js';\nimport type { WizardStore } from '../store.js';\nimport { WelcomeDemo } from './demos/WelcomeDemo.js';\nimport { LayoutDemo } from './demos/LayoutDemo.js';\nimport { InputDemo } from './demos/InputDemo.js';\nimport { ProgressDemo } from './demos/ProgressDemo.js';\nimport { LogDemo } from './demos/LogDemo.js';\nimport { RunScreenDemo } from './demos/RunScreenDemo.js';\nimport { HealthCheckDemo } from './demos/HealthCheckDemo.js';\nimport { ModalDemo } from './demos/ModalDemo.js';\nimport { McpDemo } from './demos/McpDemo.js';\n\ninterface PlaygroundAppProps {\n store: WizardStore;\n}\n\nexport const PlaygroundApp = ({ store }: PlaygroundAppProps) => {\n const tabs = [\n { id: 'layout', label: 'Layout', component: <LayoutDemo /> },\n { id: 'input', label: 'Input', component: <InputDemo /> },\n { id: 'progress', label: 'Progress', component: <ProgressDemo /> },\n { id: 'logs', label: 'Logs', component: <LogDemo /> },\n {\n id: 'run',\n label: 'RunScreen',\n component: <RunScreenDemo store={store} />,\n },\n {\n id: 'health',\n label: 'HealthCheck',\n component: <HealthCheckDemo />,\n },\n {\n id: 'modal',\n label: 'Modal',\n component: <ModalDemo />,\n },\n {\n id: 'mcp',\n label: 'MCP',\n component: <McpDemo store={store} />,\n },\n ];\n\n return (\n <ScreenContainer\n store={store}\n screens={{\n intro: <WelcomeDemo store={store} />,\n run: (\n <TabContainer\n tabs={tabs}\n statusMessage=\"Primitives Playground — use arrow keys to switch tabs\"\n />\n ),\n }}\n />\n );\n};\n"]}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * McpDemo — Playground demo for the MCP client selection screen.
3
+ *
4
+ * Uses a mock McpInstaller that simulates detecting three editors,
5
+ * a short install delay, and a successful result.
6
+ */
7
+ import { WizardStore } from '../../store.js';
8
+ interface McpDemoProps {
9
+ store: WizardStore;
10
+ }
11
+ export declare const McpDemo: ({ store }: McpDemoProps) => import("react/jsx-runtime").JSX.Element;
12
+ export {};
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { McpScreen } from '../../screens/McpScreen.js';
3
+ const MOCK_CLIENTS = [
4
+ { name: 'VS Code' },
5
+ { name: 'Cursor' },
6
+ { name: 'Windsurf' },
7
+ ];
8
+ function createMockInstaller() {
9
+ return {
10
+ async detectClients() {
11
+ await new Promise((r) => setTimeout(r, 800));
12
+ return MOCK_CLIENTS;
13
+ },
14
+ async install(clientNames) {
15
+ await new Promise((r) => setTimeout(r, 1500));
16
+ return clientNames;
17
+ },
18
+ async remove() {
19
+ await new Promise((r) => setTimeout(r, 1000));
20
+ return MOCK_CLIENTS.map((c) => c.name);
21
+ },
22
+ };
23
+ }
24
+ export const McpDemo = ({ store }) => {
25
+ return (_jsx(McpScreen, { store: store, installer: createMockInstaller(), mode: "install" }));
26
+ };
27
+ //# sourceMappingURL=McpDemo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"McpDemo.js","sourceRoot":"","sources":["../../../../../../src/ui/tui/playground/demos/McpDemo.tsx"],"names":[],"mappings":";AAQA,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAGvD,MAAM,YAAY,GAAG;IACnB,EAAE,IAAI,EAAE,SAAS,EAAE;IACnB,EAAE,IAAI,EAAE,QAAQ,EAAE;IAClB,EAAE,IAAI,EAAE,UAAU,EAAE;CACrB,CAAC;AAEF,SAAS,mBAAmB;IAC1B,OAAO;QACL,KAAK,CAAC,aAAa;YACjB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YAC7C,OAAO,YAAY,CAAC;QACtB,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,WAAW;YACvB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;YAC9C,OAAO,WAAW,CAAC;QACrB,CAAC;QACD,KAAK,CAAC,MAAM;YACV,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;YAC9C,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACzC,CAAC;KACF,CAAC;AACJ,CAAC;AAMD,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,EAAE,KAAK,EAAgB,EAAE,EAAE;IACjD,OAAO,CACL,KAAC,SAAS,IAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,mBAAmB,EAAE,EAAE,IAAI,EAAC,SAAS,GAAG,CAC7E,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * McpDemo — Playground demo for the MCP client selection screen.\n *\n * Uses a mock McpInstaller that simulates detecting three editors,\n * a short install delay, and a successful result.\n */\n\nimport { WizardStore } from '../../store.js';\nimport { McpScreen } from '../../screens/McpScreen.js';\nimport type { McpInstaller } from '../../services/mcp-installer.js';\n\nconst MOCK_CLIENTS = [\n { name: 'VS Code' },\n { name: 'Cursor' },\n { name: 'Windsurf' },\n];\n\nfunction createMockInstaller(): McpInstaller {\n return {\n async detectClients() {\n await new Promise((r) => setTimeout(r, 800));\n return MOCK_CLIENTS;\n },\n async install(clientNames) {\n await new Promise((r) => setTimeout(r, 1500));\n return clientNames;\n },\n async remove() {\n await new Promise((r) => setTimeout(r, 1000));\n return MOCK_CLIENTS.map((c) => c.name);\n },\n };\n}\n\ninterface McpDemoProps {\n store: WizardStore;\n}\n\nexport const McpDemo = ({ store }: McpDemoProps) => {\n return (\n <McpScreen store={store} installer={createMockInstaller()} mode=\"install\" />\n );\n};\n"]}
@@ -28,7 +28,7 @@ export class WizardRouter {
28
28
  flow;
29
29
  flowName;
30
30
  overlays = [];
31
- constructor(flowName = Flow.Wizard) {
31
+ constructor(flowName = Flow.PostHogIntegration) {
32
32
  this.flowName = flowName;
33
33
  this.flow = FLOWS[flowName];
34
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"router.js","sourceRoot":"","sources":["../../../../src/ui/tui/router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAkB,MAAM,YAAY,CAAC;AAEjE,gEAAgE;AAChE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAGxB,yEAAyE;AAEzE,+CAA+C;AAC/C,MAAM,CAAN,IAAY,OAKX;AALD,WAAY,OAAO;IACjB,iDAAsC,CAAA;IACtC,+CAAoC,CAAA;IACpC,yCAA8B,CAAA;IAC9B,mCAAwB,CAAA;AAC1B,CAAC,EALW,OAAO,KAAP,OAAO,QAKlB;AAKD,yEAAyE;AAEzE,MAAM,OAAO,YAAY;IACf,IAAI,CAAc;IAClB,QAAQ,CAAO;IACf,QAAQ,GAAc,EAAE,CAAC;IAEjC,YAAY,WAAiB,IAAI,CAAC,MAAM;QACtC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAED;;;;OAIG;IACH,OAAO,CAAC,OAAsB;QAC5B,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACjD,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC9B,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;gBAAE,SAAS;YACjD,IAAI,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,SAAS;YAC5D,OAAO,KAAK,CAAC,MAAM,CAAC;QACtB,CAAC;QAED,sDAAsD;QACtD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;IAChD,CAAC;IAED,oDAAoD;IACpD,IAAI,YAAY;QACd,uDAAuD;QACvD,uEAAuE;QACvE,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,mCAAmC;IACnC,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,8CAA8C;IAC9C,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IAClC,CAAC;IAED;;;OAGG;IACH,WAAW,CAAC,OAAgB;QAC1B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,UAAU;QACR,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;IACtB,CAAC;IAED;;OAEG;IACK,cAAc,GAA0B,IAAI,CAAC;IAErD,IAAI,gBAAgB;QAClB,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED,6DAA6D;IAC7D,aAAa,CAAC,GAA0B;QACtC,IAAI,CAAC,cAAc,GAAG,GAAG,CAAC;IAC5B,CAAC;CACF","sourcesContent":["/**\n * WizardRouter — declarative flow pipelines + overlay stack.\n *\n * Two layers:\n * Flow cursor — linear pipeline of screens, advanced with next()\n * Overlay stack — interrupts (outage, auth-expired, etc.) that push/pop\n *\n * The visible screen is: top of overlay stack if non-empty, otherwise the flow cursor.\n *\n * Adding a flow screen = append to a pipeline array.\n * Adding an overlay = call pushOverlay() from anywhere.\n * No switch statements, no hardcoded transitions in business logic.\n */\n\nimport type { WizardSession } from '../../lib/wizard-session.js';\nimport { FLOWS, Screen, Flow, type FlowEntry } from './flows.js';\n\n// Re-export so existing imports from './router.js' keep working\nexport { Screen, Flow };\nexport type { FlowEntry };\n\n// ── Screen name taxonomy ──────────────────────────────────────────────\n\n/** Screens that interrupt flows as overlays */\nexport enum Overlay {\n SettingsOverride = 'settings-override',\n ManagedSettings = 'managed-settings',\n PortConflict = 'port-conflict',\n AuthError = 'auth-error',\n}\n\n/** Union of all screen names */\nexport type ScreenName = Screen | Overlay;\n\n// ── Router ────────────────────────────────────────────────────────────\n\nexport class WizardRouter {\n private flow: FlowEntry[];\n private flowName: Flow;\n private overlays: Overlay[] = [];\n\n constructor(flowName: Flow = Flow.Wizard) {\n this.flowName = flowName;\n this.flow = FLOWS[flowName];\n }\n\n /**\n * Resolve which screen should be active based on session state.\n * Walks the flow pipeline, skipping hidden entries and completed entries,\n * returns the first incomplete screen.\n */\n resolve(session: WizardSession): ScreenName {\n if (this.overlays.length > 0) {\n return this.overlays[this.overlays.length - 1];\n }\n\n for (const entry of this.flow) {\n if (entry.show && !entry.show(session)) continue;\n if (entry.isComplete && entry.isComplete(session)) continue;\n return entry.screen;\n }\n\n // All entries complete — show the last screen (outro)\n return this.flow[this.flow.length - 1].screen;\n }\n\n /** The screen that should be rendered right now. */\n get activeScreen(): ScreenName {\n // Overlays take priority — resolve() handles this too,\n // but activeScreen is called before session is available in some paths\n if (this.overlays.length > 0) {\n return this.overlays[this.overlays.length - 1];\n }\n return this.flow[0].screen;\n }\n\n /** The name of the active flow. */\n get activeFlow(): Flow {\n return this.flowName;\n }\n\n /** Whether an overlay is currently active. */\n get hasOverlay(): boolean {\n return this.overlays.length > 0;\n }\n\n /**\n * Push an overlay that interrupts the current flow.\n * The flow resumes when the overlay is dismissed via popOverlay().\n */\n pushOverlay(overlay: Overlay): void {\n this.overlays.push(overlay);\n }\n\n /**\n * Dismiss the topmost overlay. The flow screen underneath resumes.\n */\n popOverlay(): void {\n this.overlays.pop();\n }\n\n /**\n * Direction hint for screen transitions.\n */\n private _lastDirection: 'push' | 'pop' | null = null;\n\n get lastNavDirection(): 'push' | 'pop' | null {\n return this._lastDirection;\n }\n\n /** @internal — called by store wrapper to track direction */\n _setDirection(dir: 'push' | 'pop' | null): void {\n this._lastDirection = dir;\n }\n}\n"]}
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../../../src/ui/tui/router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAkB,MAAM,YAAY,CAAC;AAEjE,gEAAgE;AAChE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAGxB,yEAAyE;AAEzE,+CAA+C;AAC/C,MAAM,CAAN,IAAY,OAKX;AALD,WAAY,OAAO;IACjB,iDAAsC,CAAA;IACtC,+CAAoC,CAAA;IACpC,yCAA8B,CAAA;IAC9B,mCAAwB,CAAA;AAC1B,CAAC,EALW,OAAO,KAAP,OAAO,QAKlB;AAKD,yEAAyE;AAEzE,MAAM,OAAO,YAAY;IACf,IAAI,CAAc;IAClB,QAAQ,CAAO;IACf,QAAQ,GAAc,EAAE,CAAC;IAEjC,YAAY,WAAiB,IAAI,CAAC,kBAAkB;QAClD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAED;;;;OAIG;IACH,OAAO,CAAC,OAAsB;QAC5B,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACjD,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC9B,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;gBAAE,SAAS;YACjD,IAAI,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,SAAS;YAC5D,OAAO,KAAK,CAAC,MAAM,CAAC;QACtB,CAAC;QAED,sDAAsD;QACtD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;IAChD,CAAC;IAED,oDAAoD;IACpD,IAAI,YAAY;QACd,uDAAuD;QACvD,uEAAuE;QACvE,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,mCAAmC;IACnC,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,8CAA8C;IAC9C,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IAClC,CAAC;IAED;;;OAGG;IACH,WAAW,CAAC,OAAgB;QAC1B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,UAAU;QACR,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;IACtB,CAAC;IAED;;OAEG;IACK,cAAc,GAA0B,IAAI,CAAC;IAErD,IAAI,gBAAgB;QAClB,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED,6DAA6D;IAC7D,aAAa,CAAC,GAA0B;QACtC,IAAI,CAAC,cAAc,GAAG,GAAG,CAAC;IAC5B,CAAC;CACF","sourcesContent":["/**\n * WizardRouter — declarative flow pipelines + overlay stack.\n *\n * Two layers:\n * Flow cursor — linear pipeline of screens, advanced with next()\n * Overlay stack — interrupts (outage, auth-expired, etc.) that push/pop\n *\n * The visible screen is: top of overlay stack if non-empty, otherwise the flow cursor.\n *\n * Adding a flow screen = append to a pipeline array.\n * Adding an overlay = call pushOverlay() from anywhere.\n * No switch statements, no hardcoded transitions in business logic.\n */\n\nimport type { WizardSession } from '../../lib/wizard-session.js';\nimport { FLOWS, Screen, Flow, type FlowEntry } from './flows.js';\n\n// Re-export so existing imports from './router.js' keep working\nexport { Screen, Flow };\nexport type { FlowEntry };\n\n// ── Screen name taxonomy ──────────────────────────────────────────────\n\n/** Screens that interrupt flows as overlays */\nexport enum Overlay {\n SettingsOverride = 'settings-override',\n ManagedSettings = 'managed-settings',\n PortConflict = 'port-conflict',\n AuthError = 'auth-error',\n}\n\n/** Union of all screen names */\nexport type ScreenName = Screen | Overlay;\n\n// ── Router ────────────────────────────────────────────────────────────\n\nexport class WizardRouter {\n private flow: FlowEntry[];\n private flowName: Flow;\n private overlays: Overlay[] = [];\n\n constructor(flowName: Flow = Flow.PostHogIntegration) {\n this.flowName = flowName;\n this.flow = FLOWS[flowName];\n }\n\n /**\n * Resolve which screen should be active based on session state.\n * Walks the flow pipeline, skipping hidden entries and completed entries,\n * returns the first incomplete screen.\n */\n resolve(session: WizardSession): ScreenName {\n if (this.overlays.length > 0) {\n return this.overlays[this.overlays.length - 1];\n }\n\n for (const entry of this.flow) {\n if (entry.show && !entry.show(session)) continue;\n if (entry.isComplete && entry.isComplete(session)) continue;\n return entry.screen;\n }\n\n // All entries complete — show the last screen (outro)\n return this.flow[this.flow.length - 1].screen;\n }\n\n /** The screen that should be rendered right now. */\n get activeScreen(): ScreenName {\n // Overlays take priority — resolve() handles this too,\n // but activeScreen is called before session is available in some paths\n if (this.overlays.length > 0) {\n return this.overlays[this.overlays.length - 1];\n }\n return this.flow[0].screen;\n }\n\n /** The name of the active flow. */\n get activeFlow(): Flow {\n return this.flowName;\n }\n\n /** Whether an overlay is currently active. */\n get hasOverlay(): boolean {\n return this.overlays.length > 0;\n }\n\n /**\n * Push an overlay that interrupts the current flow.\n * The flow resumes when the overlay is dismissed via popOverlay().\n */\n pushOverlay(overlay: Overlay): void {\n this.overlays.push(overlay);\n }\n\n /**\n * Dismiss the topmost overlay. The flow screen underneath resumes.\n */\n popOverlay(): void {\n this.overlays.pop();\n }\n\n /**\n * Direction hint for screen transitions.\n */\n private _lastDirection: 'push' | 'pop' | null = null;\n\n get lastNavDirection(): 'push' | 'pop' | null {\n return this._lastDirection;\n }\n\n /** @internal — called by store wrapper to track direction */\n _setDirection(dir: 'push' | 'pop' | null): void {\n this._lastDirection = dir;\n }\n}\n"]}
@@ -4,12 +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
+ import { RevenueIntroScreen } from './screens/RevenueIntroScreen.js';
9
+ import { AgentSkillIntroScreen } from './screens/AgentSkillIntroScreen.js';
8
10
  import { SetupScreen } from './screens/SetupScreen.js';
9
11
  import { AuthScreen } from './screens/AuthScreen.js';
10
12
  import { RunScreen } from './screens/RunScreen.js';
11
13
  import { McpScreen } from './screens/McpScreen.js';
12
- import { SkillsScreen } from './screens/SkillsScreen.js';
14
+ import { KeepSkillsScreen } from './screens/KeepSkillsScreen.js';
13
15
  import { OutroScreen } from './screens/OutroScreen.js';
14
16
  import { AuthErrorScreen } from './screens/AuthErrorScreen.js';
15
17
  import { createMcpInstaller } from './services/mcp-installer.js';
@@ -26,13 +28,15 @@ export function createScreens(store, services) {
26
28
  [Overlay.PortConflict]: _jsx(PortConflictScreen, { store: store }),
27
29
  [Overlay.AuthError]: _jsx(AuthErrorScreen, {}),
28
30
  // Wizard flow
29
- [Screen.Intro]: _jsx(IntroScreen, { store: store }),
31
+ [Screen.Intro]: _jsx(PostHogIntegrationIntroScreen, { store: store }),
32
+ [Screen.RevenueIntro]: _jsx(RevenueIntroScreen, { store: store }),
33
+ [Screen.AgentSkillIntro]: _jsx(AgentSkillIntroScreen, { store: store }),
30
34
  [Screen.HealthCheck]: _jsx(HealthCheckScreen, { store: store }),
31
35
  [Screen.Setup]: _jsx(SetupScreen, { store: store }),
32
36
  [Screen.Auth]: _jsx(AuthScreen, { store: store }),
33
37
  [Screen.Run]: _jsx(RunScreen, { store: store }),
34
38
  [Screen.Mcp]: _jsx(McpScreen, { store: store, installer: services.mcpInstaller }),
35
- [Screen.Skills]: _jsx(SkillsScreen, { store: store }),
39
+ [Screen.KeepSkills]: _jsx(KeepSkillsScreen, { store: store }),
36
40
  [Screen.Outro]: _jsx(OutroScreen, { store: store }),
37
41
  // Standalone MCP flows
38
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":";AAaA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAmB,MAAM,aAAa,CAAC;AAE/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAOjE,MAAM,UAAU,cAAc;IAC5B,OAAO;QACL,YAAY,EAAE,kBAAkB,EAAE;KACnC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,KAAkB,EAClB,QAAwB;IAExB,OAAO;QACL,WAAW;QACX,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,KAAC,sBAAsB,IAAC,KAAK,EAAE,KAAK,GAAI;QACpE,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,KAAC,qBAAqB,IAAC,KAAK,EAAE,KAAK,GAAI;QAClE,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,KAAC,kBAAkB,IAAC,KAAK,EAAE,KAAK,GAAI;QAC5D,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,KAAC,eAAe,KAAG;QAExC,cAAc;QACd,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAC,WAAW,IAAC,KAAK,EAAE,KAAK,GAAI;QAC7C,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,KAAC,iBAAiB,IAAC,KAAK,EAAE,KAAK,GAAI;QACzD,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAC,WAAW,IAAC,KAAK,EAAE,KAAK,GAAI;QAC7C,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAC,UAAU,IAAC,KAAK,EAAE,KAAK,GAAI;QAC3C,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAC,SAAS,IAAC,KAAK,EAAE,KAAK,GAAI;QACzC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAC,SAAS,IAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,YAAY,GAAI;QAC3E,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,KAAC,YAAY,IAAC,KAAK,EAAE,KAAK,GAAI;QAC/C,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAC,WAAW,IAAC,KAAK,EAAE,KAAK,GAAI;QAE7C,uBAAuB;QACvB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CACf,KAAC,SAAS,IAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,YAAY,EAAE,UAAU,SAAG,CACzE;QACD,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAClB,KAAC,SAAS,IACR,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,QAAQ,CAAC,YAAY,EAChC,IAAI,EAAC,QAAQ,EACb,UAAU,SACV,CACH;KACF,CAAC;AACJ,CAAC","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 { 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.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"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ManagedSettingsScreen.js","sourceRoot":"","sources":["../../../../../src/ui/tui/screens/ManagedSettingsScreen.tsx"],"names":[],"mappings":";AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAE7C,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAGrC,SAAS,WAAW,CAAC,MAAkC;IACrD,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,SAAS;YACZ,OAAO,mCAAmC,CAAC;QAC7C,KAAK,SAAS;YACZ,OAAO,uBAAuB,CAAC;QACjC;YACE,OAAO,MAAM,CAAC;IAClB,CAAC;AACH,CAAC;AAMD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,EACpC,KAAK,GACsB,EAAE,EAAE;IAC/B,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,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC;IAClD,MAAM,iBAAiB,GAAG,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAEhE,IAAI,CAAC,iBAAiB,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CACL,MAAC,YAAY,IACX,WAAW,EAAC,KAAK,EACjB,KAAK,EAAE,GAAG,KAAK,CAAC,OAAO,iCAAiC,EACxD,KAAK,EAAE,EAAE,EACT,MAAM,EACJ,KAAC,iBAAiB,IAChB,OAAO,EAAC,gDAAgD,EACxD,YAAY,EAAC,EAAE,EACf,WAAW,EAAC,YAAY,EACxB,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAChC,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAC/B,aAGJ,KAAC,IAAI,IAAC,QAAQ,4IAGP,EACN,iBAAiB,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CACnC,MAAC,GAAG,IAAuB,aAAa,EAAC,QAAQ,EAAC,SAAS,EAAE,CAAC,aAC5D,KAAC,IAAI,IAAC,IAAI,kBAAE,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAQ,EAChD,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,WAAW,EAAE,CAAC,YACvC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAC1B,MAAC,IAAI,eACF,KAAK,CAAC,MAAM,EAAE,GAAG,EAClB,KAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,EAAC,IAAI,kBACtB,GAAG,GACC,KAJE,GAAG,CAKP,CACR,CAAC,GACE,KAXE,QAAQ,CAAC,MAAM,CAYnB,CACP,CAAC,EACF,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,IAAI,IAAC,QAAQ,2GAGP,GACH,IACO,CAChB,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * ManagedSettingsScreen — Modal when IT/org-managed settings contain overrides\n * that block the Wizard from reaching the PostHog LLM Gateway.\n *\n * Unlike SettingsOverrideScreen, the wizard cannot back up or modify these files.\n * The user must contact their IT administrator to resolve the conflict.\n */\n\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '../store.js';\nimport { ConfirmationInput, ModalOverlay } from '../primitives/index.js';\nimport { Icons } from '../styles.js';\nimport type { SettingsConflict } from '../../../lib/agent-interface.js';\n\nfunction sourceLabel(source: SettingsConflict['source']): string {\n switch (source) {\n case 'managed':\n return 'Managed settings (IT/org-managed)';\n case 'project':\n return '.claude/settings.json';\n default:\n return source;\n }\n}\n\ninterface ManagedSettingsScreenProps {\n store: WizardStore;\n}\n\nexport const ManagedSettingsScreen = ({\n store,\n}: ManagedSettingsScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const conflicts = store.session.settingsConflicts;\n const readOnlyConflicts = conflicts?.filter((c) => !c.writable);\n\n if (!readOnlyConflicts || readOnlyConflicts.length === 0) {\n return null;\n }\n\n return (\n <ModalOverlay\n borderColor=\"red\"\n title={`${Icons.warning} Organization settings conflict`}\n width={68}\n footer={\n <ConfirmationInput\n message=\"Contact your IT administrator to resolve this.\"\n confirmLabel=\"\"\n cancelLabel=\"Exit [Esc]\"\n onConfirm={() => process.exit(1)}\n onCancel={() => process.exit(1)}\n />\n }\n >\n <Text dimColor>\n Your organization&apos;s managed settings contain overrides that prevent\n the Wizard from reaching the PostHog LLM Gateway.\n </Text>\n {readOnlyConflicts.map((conflict) => (\n <Box key={conflict.source} flexDirection=\"column\" marginTop={1}>\n <Text bold>{sourceLabel(conflict.source)}</Text>\n <Box flexDirection=\"column\" paddingLeft={2}>\n {conflict.keys.map((key) => (\n <Text key={key}>\n {Icons.bullet}{' '}\n <Text color=\"yellow\" bold>\n {key}\n </Text>\n </Text>\n ))}\n </Box>\n </Box>\n ))}\n <Box marginTop={1}>\n <Text dimColor>\n Try running \"claude auth logout\" or contact your IT administrator to\n resolve this.\n </Text>\n </Box>\n </ModalOverlay>\n );\n};\n"]}
1
+ {"version":3,"file":"ManagedSettingsScreen.js","sourceRoot":"","sources":["../../../../../src/ui/tui/screens/ManagedSettingsScreen.tsx"],"names":[],"mappings":";AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAE7C,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAGrC,SAAS,WAAW,CAAC,MAAkC;IACrD,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,SAAS;YACZ,OAAO,mCAAmC,CAAC;QAC7C,KAAK,SAAS;YACZ,OAAO,uBAAuB,CAAC;QACjC;YACE,OAAO,MAAM,CAAC;IAClB,CAAC;AACH,CAAC;AAMD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,EACpC,KAAK,GACsB,EAAE,EAAE;IAC/B,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,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC;IAClD,MAAM,iBAAiB,GAAG,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAEhE,IAAI,CAAC,iBAAiB,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CACL,MAAC,YAAY,IACX,WAAW,EAAC,KAAK,EACjB,KAAK,EAAE,GAAG,KAAK,CAAC,OAAO,iCAAiC,EACxD,KAAK,EAAE,EAAE,EACT,MAAM,EACJ,KAAC,iBAAiB,IAChB,OAAO,EAAC,gDAAgD,EACxD,YAAY,EAAC,EAAE,EACf,WAAW,EAAC,YAAY,EACxB,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAChC,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAC/B,aAGJ,KAAC,IAAI,IAAC,QAAQ,4IAGP,EACN,iBAAiB,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CACnC,MAAC,GAAG,IAAuB,aAAa,EAAC,QAAQ,EAAC,SAAS,EAAE,CAAC,aAC5D,KAAC,IAAI,IAAC,IAAI,kBAAE,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAQ,EAChD,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,WAAW,EAAE,CAAC,YACvC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAC1B,MAAC,IAAI,eACF,KAAK,CAAC,MAAM,EAAE,GAAG,EAClB,KAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,EAAC,IAAI,kBACtB,GAAG,GACC,KAJE,GAAG,CAKP,CACR,CAAC,GACE,KAXE,QAAQ,CAAC,MAAM,CAYnB,CACP,CAAC,EACF,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,IAAI,IAAC,QAAQ,2GAGP,GACH,IACO,CAChB,CAAC;AACJ,CAAC,CAAC","sourcesContent":["/**\n * ManagedSettingsScreen — Modal when IT/org-managed settings contain overrides\n * that block the Wizard from reaching the PostHog LLM Gateway.\n *\n * Unlike SettingsOverrideScreen, the wizard cannot back up or modify these files.\n * The user must contact their IT administrator to resolve the conflict.\n */\n\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '../store.js';\nimport { ConfirmationInput, ModalOverlay } from '../primitives/index.js';\nimport { Icons } from '../styles.js';\nimport type { SettingsConflict } from '../../../lib/agent/agent-interface.js';\n\nfunction sourceLabel(source: SettingsConflict['source']): string {\n switch (source) {\n case 'managed':\n return 'Managed settings (IT/org-managed)';\n case 'project':\n return '.claude/settings.json';\n default:\n return source;\n }\n}\n\ninterface ManagedSettingsScreenProps {\n store: WizardStore;\n}\n\nexport const ManagedSettingsScreen = ({\n store,\n}: ManagedSettingsScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const conflicts = store.session.settingsConflicts;\n const readOnlyConflicts = conflicts?.filter((c) => !c.writable);\n\n if (!readOnlyConflicts || readOnlyConflicts.length === 0) {\n return null;\n }\n\n return (\n <ModalOverlay\n borderColor=\"red\"\n title={`${Icons.warning} Organization settings conflict`}\n width={68}\n footer={\n <ConfirmationInput\n message=\"Contact your IT administrator to resolve this.\"\n confirmLabel=\"\"\n cancelLabel=\"Exit [Esc]\"\n onConfirm={() => process.exit(1)}\n onCancel={() => process.exit(1)}\n />\n }\n >\n <Text dimColor>\n Your organization&apos;s managed settings contain overrides that prevent\n the Wizard from reaching the PostHog LLM Gateway.\n </Text>\n {readOnlyConflicts.map((conflict) => (\n <Box key={conflict.source} flexDirection=\"column\" marginTop={1}>\n <Text bold>{sourceLabel(conflict.source)}</Text>\n <Box flexDirection=\"column\" paddingLeft={2}>\n {conflict.keys.map((key) => (\n <Text key={key}>\n {Icons.bullet}{' '}\n <Text color=\"yellow\" bold>\n {key}\n </Text>\n </Text>\n ))}\n </Box>\n </Box>\n ))}\n <Box marginTop={1}>\n <Text dimColor>\n Try running \"claude auth logout\" or contact your IT administrator to\n resolve this.\n </Text>\n </Box>\n </ModalOverlay>\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([]);