@posthog/wizard 2.8.0 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. package/README.md +11 -0
  2. package/dist/bin.js +289 -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 +323 -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 +66 -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 +32 -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 +48 -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 +100 -10
  166. package/dist/src/ui/tui/__tests__/store.test.js.map +1 -1
  167. package/dist/src/ui/tui/flows.d.ts +17 -6
  168. package/dist/src/ui/tui/flows.js +28 -52
  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/primitives/ProgressList.d.ts +3 -1
  174. package/dist/src/ui/tui/primitives/ProgressList.js +2 -2
  175. package/dist/src/ui/tui/primitives/ProgressList.js.map +1 -1
  176. package/dist/src/ui/tui/router.js +1 -1
  177. package/dist/src/ui/tui/router.js.map +1 -1
  178. package/dist/src/ui/tui/screen-registry.js +2 -0
  179. package/dist/src/ui/tui/screen-registry.js.map +1 -1
  180. package/dist/src/ui/tui/screens/ManagedSettingsScreen.js.map +1 -1
  181. package/dist/src/ui/tui/screens/OutroScreen.js +1 -1
  182. package/dist/src/ui/tui/screens/OutroScreen.js.map +1 -1
  183. package/dist/src/ui/tui/screens/RevenueIntroScreen.d.ts +16 -0
  184. package/dist/src/ui/tui/screens/RevenueIntroScreen.js +64 -0
  185. package/dist/src/ui/tui/screens/RevenueIntroScreen.js.map +1 -0
  186. package/dist/src/ui/tui/screens/RunScreen.js +1 -1
  187. package/dist/src/ui/tui/screens/RunScreen.js.map +1 -1
  188. package/dist/src/ui/tui/screens/SettingsOverrideScreen.js.map +1 -1
  189. package/dist/src/ui/tui/screens/health/HealthCheckScreen.js +2 -2
  190. package/dist/src/ui/tui/screens/health/HealthCheckScreen.js.map +1 -1
  191. package/dist/src/ui/tui/start-tui.js +2 -2
  192. package/dist/src/ui/tui/start-tui.js.map +1 -1
  193. package/dist/src/ui/tui/store.d.ts +46 -21
  194. package/dist/src/ui/tui/store.js +105 -47
  195. package/dist/src/ui/tui/store.js.map +1 -1
  196. package/dist/src/ui/wizard-ui.d.ts +13 -3
  197. package/dist/src/ui/wizard-ui.js.map +1 -1
  198. package/dist/src/utils/file-utils.d.ts +8 -0
  199. package/dist/src/utils/file-utils.js +32 -0
  200. package/dist/src/utils/file-utils.js.map +1 -1
  201. package/dist/src/utils/wizard-abort.d.ts +3 -0
  202. package/dist/src/utils/wizard-abort.js +5 -3
  203. package/dist/src/utils/wizard-abort.js.map +1 -1
  204. package/npm-shrinkwrap.json +2 -2
  205. package/package.json +1 -1
  206. package/dist/src/__tests__/run.test.js +0 -95
  207. package/dist/src/__tests__/run.test.js.map +0 -1
  208. package/dist/src/lib/__tests__/package-manager-detection.test.js.map +0 -1
  209. package/dist/src/lib/agent-interface.js.map +0 -1
  210. package/dist/src/lib/agent-runner.d.ts +0 -9
  211. package/dist/src/lib/agent-runner.js +0 -385
  212. package/dist/src/lib/agent-runner.js.map +0 -1
  213. package/dist/src/lib/commandments.js.map +0 -1
  214. package/dist/src/lib/package-manager-detection.js.map +0 -1
  215. package/dist/src/run.d.ts +0 -23
  216. package/dist/src/run.js +0 -154
  217. package/dist/src/run.js.map +0 -1
  218. /package/dist/src/{__tests__/run.test.d.ts → lib/agent/__tests__/agent-prompt.test.d.ts} +0 -0
  219. /package/dist/src/lib/{commandments.d.ts → agent/commandments.d.ts} +0 -0
  220. /package/dist/src/lib/{commandments.js → agent/commandments.js} +0 -0
  221. /package/dist/src/lib/{__tests__/package-manager-detection.test.d.ts → detection/__tests__/context.test.d.ts} +0 -0
  222. /package/dist/src/lib/{package-manager-detection.d.ts → detection/package-manager.d.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../../src/ui/tui/store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * WizardStore — Nanostore-backed reactive store for the TUI.\n * React components subscribe via useSyncExternalStore.\n *\n * Navigation is delegated to WizardRouter.\n * The active screen is derived from session state — not imperatively set.\n * Overlays (settings-override, port-conflict) are the only imperative navigation.\n *\n * All session mutations that affect screen resolution go through\n * explicit setters so emitChange() is always called.\n */\n\nimport { atom, map } from 'nanostores';\nimport { TaskStatus } from '../wizard-ui.js';\nimport {\n type WizardSession,\n type OutroData,\n type DiscoveredFeature,\n AdditionalFeature,\n McpOutcome,\n RunPhase,\n buildSession,\n} from '../../lib/wizard-session.js';\nimport type { SettingsConflict } from '../../lib/agent-interface.js';\nimport {\n WizardRouter,\n type ScreenName,\n Screen,\n Overlay,\n Flow,\n} from './router.js';\nimport { analytics, sessionProperties } from '../../utils/analytics.js';\nimport {\n evaluateWizardReadiness,\n WizardReadiness,\n} from '../../lib/health-checks/readiness.js';\n\nexport { TaskStatus, Screen, Overlay, Flow, RunPhase, McpOutcome };\nexport type { ScreenName, OutroData, WizardSession };\n\nexport interface TaskItem {\n label: string;\n activeForm?: string;\n status: TaskStatus;\n /** Legacy compat */\n done: boolean;\n}\n\nexport interface PlannedEvent {\n name: string;\n description: string;\n}\n\nexport class WizardStore {\n // ── Internal nanostore atoms ─────────────────────────────────────\n private $session = map<WizardSession>(buildSession({}));\n private $statusMessages = atom<string[]>([]);\n private $statusExpanded = atom(false);\n private $tasks = atom<TaskItem[]>([]);\n private $eventPlan = atom<PlannedEvent[]>([]);\n private $learnCardBlockIdx = atom(0);\n private $learnCardComplete = atom(false);\n private $version = atom(0);\n\n /** Last screen seen — used to detect screen transitions for analytics. */\n private _lastScreen: ScreenName | null = null;\n\n /** Hooks run when transitioning onto a screen. */\n private _enterScreenHooks = new Map<ScreenName, (() => void)[]>();\n\n version = '';\n\n /** Navigation router — resolves active screen from session state. */\n readonly router: WizardRouter;\n\n /**\n * Setup promise — IntroScreen resolves this when the user confirms.\n * bin.ts awaits it before calling runWizard.\n */\n private _resolveSetup!: () => void;\n readonly setupComplete: Promise<void> = new Promise((resolve) => {\n this._resolveSetup = resolve;\n });\n\n /** Blocks agent execution until the settings-override overlay is dismissed. */\n private _resolveSettingsOverride: (() => void) | null = null;\n private _backupAndFixSettings: (() => boolean) | null = null;\n\n /** Blocks OAuth flow until the port-conflict overlay is dismissed. */\n private _resolvePortConflict: (() => void) | null = null;\n\n /**\n * Resolves when the health-check screen is done — either auto-advanced\n * (healthy) or user-dismissed (outage). bin.ts awaits this before runWizard().\n */\n private _resolveHealthGate!: () => void;\n readonly healthGateComplete: Promise<void> = new Promise((resolve) => {\n this._resolveHealthGate = resolve;\n });\n\n constructor(flow: Flow = Flow.Wizard) {\n this.router = new WizardRouter(flow);\n\n // Fire health check immediately for Wizard flow so results arrive\n // while the user is still on IntroScreen.\n if (flow === Flow.Wizard) {\n this._initHealthCheck();\n } else {\n this._resolveHealthGate();\n }\n }\n\n /**\n * Kick off the health check. Stores the result and resolves the\n * health gate if non-blocking.\n */\n private _initHealthCheck(): void {\n evaluateWizardReadiness()\n .then((readiness) => {\n this.setReadinessResult(readiness);\n if (readiness.decision !== WizardReadiness.No) {\n this._resolveHealthGate();\n }\n })\n .catch(() => {\n this.setReadinessResult({\n decision: WizardReadiness.Yes,\n health: {} as never,\n reasons: [],\n });\n this._resolveHealthGate();\n });\n }\n\n // ── State accessors (read from atoms) ────────────────────────────\n\n get session(): WizardSession {\n return this.$session.get();\n }\n\n set session(value: WizardSession) {\n this.$session.set(value);\n }\n\n get statusMessages(): string[] {\n return this.$statusMessages.get();\n }\n\n get tasks(): TaskItem[] {\n return this.$tasks.get();\n }\n\n get eventPlan(): PlannedEvent[] {\n return this.$eventPlan.get();\n }\n\n get statusExpanded(): boolean {\n return this.$statusExpanded.get();\n }\n\n toggleStatusExpanded(): void {\n this.$statusExpanded.set(!this.$statusExpanded.get());\n this.emitChange();\n }\n\n setStatusExpanded(expanded: boolean): void {\n if (this.$statusExpanded.get() !== expanded) {\n this.$statusExpanded.set(expanded);\n this.emitChange();\n }\n }\n\n // ── Session setters ─────────────────────────────────────────────\n // Every setter that affects screen resolution calls emitChange().\n // Business logic calls these instead of mutating session directly.\n\n /** Unblocks bin.ts via the setupComplete promise. */\n completeSetup(): void {\n this.$session.setKey('setupConfirmed', true);\n analytics.wizardCapture('setup confirmed', sessionProperties(this.session));\n this._resolveSetup();\n this.emitChange();\n }\n\n setRunPhase(phase: RunPhase): void {\n this.$session.setKey('runPhase', phase);\n this.emitChange();\n }\n\n setCredentials(credentials: WizardSession['credentials']): void {\n this.$session.setKey('credentials', credentials);\n analytics.wizardCapture('auth complete', {\n project_id: credentials?.projectId,\n });\n this.emitChange();\n }\n\n setFrameworkConfig(\n integration: WizardSession['integration'],\n config: WizardSession['frameworkConfig'],\n ): void {\n this.$session.setKey('integration', integration);\n this.$session.setKey('frameworkConfig', config);\n this.$session.setKey('unsupportedVersion', null);\n this.emitChange();\n }\n\n setDetectionComplete(): void {\n this.$session.setKey('detectionComplete', true);\n this.emitChange();\n }\n\n setDetectedFramework(label: string): void {\n this.$session.setKey('detectedFrameworkLabel', label);\n this.emitChange();\n }\n\n setUnsupportedVersion(info: {\n current: string;\n minimum: string;\n docsUrl: string;\n }): void {\n this.$session.setKey('unsupportedVersion', info);\n this.emitChange();\n }\n\n setLoginUrl(url: string | null): void {\n this.$session.setKey('loginUrl', url);\n this.emitChange();\n }\n\n setReadinessResult(\n result:\n | import('../../lib/health-checks/readiness.js').WizardReadinessResult\n | null,\n ): void {\n this.$session.setKey('readinessResult', result);\n this.emitChange();\n }\n\n /** User dismissed the blocking outage screen. Unblocks bin.ts. */\n dismissOutage(): void {\n this.$session.setKey('outageDismissed', true);\n this._resolveHealthGate();\n this.emitChange();\n }\n\n /**\n * Push the settings-override overlay and return a promise that blocks\n * until the user dismisses it via backupAndFixSettingsOverride().\n */\n showSettingsOverride(\n conflicts: SettingsConflict[],\n backupAndFix: () => boolean,\n ): Promise<void> {\n const allKeys = conflicts.flatMap((c) => c.keys);\n this.$session.setKey('settingsOverrideKeys', allKeys);\n this.$session.setKey('settingsConflicts', conflicts);\n this._backupAndFixSettings = backupAndFix;\n\n const hasReadOnly = conflicts.some((c) => !c.writable);\n if (hasReadOnly) {\n this.pushOverlay(Overlay.ManagedSettings);\n } else {\n this.pushOverlay(Overlay.SettingsOverride);\n }\n\n return new Promise((resolve) => {\n this._resolveSettingsOverride = resolve;\n });\n }\n\n /**\n * Push the port-conflict overlay and return a promise that blocks\n * until the user kills the blocking process or exits.\n */\n showPortConflict(processInfo: {\n command: string;\n pid: string;\n user: string;\n }): Promise<void> {\n this.$session.setKey('portConflictProcess', processInfo);\n this.pushOverlay(Overlay.PortConflict);\n return new Promise((resolve) => {\n this._resolvePortConflict = resolve;\n });\n }\n\n /** Dismiss the port-conflict overlay after the user kills the process. */\n resolvePortConflict(): void {\n this.$session.setKey('portConflictProcess', null);\n this.popOverlay();\n this._resolvePortConflict?.();\n this._resolvePortConflict = null;\n }\n\n /**\n * Back up .claude/settings.json. Dismisses the overlay on success.\n */\n backupAndFixSettingsOverride(): boolean {\n const ok = this._backupAndFixSettings?.() ?? false;\n if (ok) {\n this.$session.setKey('settingsOverrideKeys', null);\n this.$session.setKey('settingsConflicts', null);\n this.popOverlay();\n this._resolveSettingsOverride?.();\n this._resolveSettingsOverride = null;\n this._backupAndFixSettings = null;\n }\n return ok;\n }\n\n /** Push the auth-error overlay (no dismiss — user must exit). */\n showAuthError(): void {\n this.pushOverlay(Overlay.AuthError);\n }\n\n addDiscoveredFeature(feature: DiscoveredFeature): void {\n if (!this.session.discoveredFeatures.includes(feature)) {\n this.session.discoveredFeatures.push(feature);\n this.emitChange();\n }\n }\n\n /**\n * Enable an additional feature: enqueue it for the stop hook\n * and set any feature-specific session flags.\n */\n enableFeature(feature: AdditionalFeature): void {\n if (!this.session.additionalFeatureQueue.includes(feature)) {\n this.session.additionalFeatureQueue.push(feature);\n }\n // Feature-specific flags\n if (feature === AdditionalFeature.LLM) {\n this.session.llmOptIn = true;\n }\n analytics.wizardCapture('feature enabled', { feature });\n this.emitChange();\n }\n\n setMcpComplete(\n outcome: McpOutcome = McpOutcome.Skipped,\n installedClients: string[] = [],\n ): void {\n this.$session.setKey('mcpComplete', true);\n this.$session.setKey('mcpOutcome', outcome);\n this.$session.setKey('mcpInstalledClients', installedClients);\n analytics.wizardCapture('mcp complete', {\n mcp_outcome: outcome,\n mcp_installed_clients: installedClients,\n ...sessionProperties(this.session),\n });\n this.emitChange();\n }\n\n setSkillsComplete(kept: boolean): void {\n this.$session.setKey('skillsComplete', true);\n analytics.wizardCapture('skills complete', {\n skills_kept: kept,\n ...sessionProperties(this.session),\n });\n this.emitChange();\n }\n\n setOutroDismissed(): void {\n this.$session.setKey('outroDismissed', true);\n this.emitChange();\n }\n\n setOutroData(data: OutroData): void {\n this.$session.setKey('outroData', data);\n this.emitChange();\n }\n\n setFrameworkContext(key: string, value: unknown): void {\n const ctx = { ...this.$session.get().frameworkContext, [key]: value };\n this.$session.setKey('frameworkContext', ctx);\n this.emitChange();\n }\n\n // ── Derived state ───────────────────────────────────────────────\n\n /**\n * The screen that should be rendered right now.\n * Derived from session state via the router.\n */\n get currentScreen(): ScreenName {\n return this.router.resolve(this.session);\n }\n\n /** Direction hint for screen transitions. */\n get lastNavDirection(): 'push' | 'pop' | null {\n return this.router.lastNavDirection;\n }\n\n // ── Change notification ─────────────────────────────────────────\n\n getVersion(): number {\n return this.$version.get();\n }\n\n /**\n * Notify React that state has changed.\n * The router re-resolves the active screen on next render.\n */\n emitChange(): void {\n this.router._setDirection('push');\n this.$version.set(this.$version.get() + 1);\n this._detectTransition();\n }\n\n // ── Overlay navigation ──────────────────────────────────────────\n\n pushOverlay(overlay: Overlay): void {\n this.router._setDirection('push');\n this.router.pushOverlay(overlay);\n this.$version.set(this.$version.get() + 1);\n this._detectTransition();\n }\n\n popOverlay(): void {\n this.router._setDirection('pop');\n this.router.popOverlay();\n this.$version.set(this.$version.get() + 1);\n this._detectTransition();\n }\n\n // ── Screen transition analytics ─────────────────────────────────\n\n /**\n * Register a callback to run when transitioning onto the given screen.\n * Fires after every transition that lands on this screen.\n */\n onEnterScreen(screen: ScreenName, fn: () => void): void {\n const list = this._enterScreenHooks.get(screen) ?? [];\n list.push(fn);\n this._enterScreenHooks.set(screen, list);\n }\n\n /**\n * Detect screen transitions, run enter-screen hooks, and fire analytics.\n * Called at the end of emitChange/pushOverlay/popOverlay.\n */\n private _detectTransition(): void {\n const next = this.router.resolve(this.session);\n const prev = this._lastScreen;\n if (prev !== null && next !== prev) {\n const hooks = this._enterScreenHooks.get(next);\n if (hooks) {\n for (const fn of hooks) fn();\n }\n analytics.wizardCapture(`screen ${next}`, {\n from_screen: prev,\n ...sessionProperties(this.session),\n });\n }\n this._lastScreen = next;\n }\n\n // ── Agent observation state ─────────────────────────────────────\n\n pushStatus(message: string): void {\n const msgs = this.$statusMessages.get();\n // Skip consecutive duplicate messages\n if (msgs.length > 0 && msgs[msgs.length - 1] === message) return;\n this.$statusMessages.set([...msgs, message]);\n this.emitChange();\n }\n\n setTasks(tasks: TaskItem[]): void {\n this.$tasks.set(tasks);\n this.emitChange();\n }\n\n updateTask(index: number, done: boolean): void {\n const tasks = this.$tasks.get();\n if (tasks[index]) {\n const updated = [...tasks];\n updated[index] = {\n ...updated[index],\n done,\n status: done ? TaskStatus.Completed : TaskStatus.Pending,\n };\n this.$tasks.set(updated);\n this.emitChange();\n }\n }\n\n setEventPlan(events: PlannedEvent[]): void {\n this.$eventPlan.set(events);\n this.emitChange();\n }\n\n get learnCardBlockIdx(): number {\n return this.$learnCardBlockIdx.get();\n }\n\n setLearnCardBlockIdx(idx: number): void {\n this.$learnCardBlockIdx.set(idx);\n }\n\n get learnCardComplete(): boolean {\n return this.$learnCardComplete.get();\n }\n\n setLearnCardComplete(): void {\n this.$learnCardComplete.set(true);\n this.emitChange();\n }\n\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void {\n const incoming = todos.map((t) => ({\n label: t.content,\n activeForm: t.activeForm,\n status: (t.status as TaskStatus) || TaskStatus.Pending,\n done: t.status === TaskStatus.Completed,\n }));\n\n const incomingLabels = new Set(incoming.map((t) => t.label));\n\n const retained = this.$tasks\n .get()\n .filter((t) => t.done && !incomingLabels.has(t.label));\n\n this.$tasks.set([...retained, ...incoming]);\n this.emitChange();\n }\n\n // ── React integration ───────────────────────────────────────────\n\n subscribe(callback: () => void): () => void {\n return this.$version.listen(() => callback());\n }\n\n getSnapshot(): number {\n return this.$version.get();\n }\n}\n"]}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../../src/ui/tui/store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * WizardStore — Nanostore-backed reactive store for the TUI.\n * React components subscribe via useSyncExternalStore.\n *\n * The active screen is derived from session state — WizardRouter walks\n * the flow and shows the first step whose `isComplete` is still false.\n *\n * Define a step `gate` if your screen needs to await user interactions.\n * bin.ts calls `await store.getGate(stepId)` to pause until the gate\n * predicate becomes true.\n *\n * All session mutations that affect screen resolution go through\n * explicit setters so emitChange() is always called.\n */\n\nimport { atom, map } from 'nanostores';\nimport { TaskStatus } from '../wizard-ui.js';\nimport {\n type WizardSession,\n type OutroData,\n type DiscoveredFeature,\n AdditionalFeature,\n McpOutcome,\n RunPhase,\n buildSession,\n} from '../../lib/wizard-session.js';\nimport type { SettingsConflict } from '../../lib/agent/agent-interface.js';\nimport type { WizardReadinessResult } from '../../lib/health-checks/readiness.js';\nimport {\n WizardRouter,\n type ScreenName,\n Screen,\n Overlay,\n Flow,\n} from './router.js';\nimport { analytics, sessionProperties } from '../../utils/analytics.js';\nimport type {\n StoreInitContext,\n WorkflowReadyContext,\n} from '../../lib/workflows/workflow-step.js';\nimport { WORKFLOW_STEPS } from './flows.js';\n\nexport { TaskStatus, Screen, Overlay, Flow, RunPhase, McpOutcome };\nexport type { ScreenName, OutroData, WizardSession };\n\nexport interface TaskItem {\n label: string;\n activeForm?: string;\n status: TaskStatus;\n /** Legacy compat */\n done: boolean;\n}\n\nexport interface PlannedEvent {\n name: string;\n description: string;\n}\n\ninterface GateEntry {\n predicate: (session: WizardSession) => boolean;\n promise: Promise<void>;\n resolve: () => void;\n resolved: boolean;\n}\n\nexport class WizardStore {\n // ── Internal nanostore atoms ─────────────────────────────────────\n private $session = map<WizardSession>(buildSession({}));\n private $statusMessages = atom<string[]>([]);\n private $statusExpanded = atom(false);\n private $tasks = atom<TaskItem[]>([]);\n private $eventPlan = atom<PlannedEvent[]>([]);\n private $learnCardBlockIdx = atom(0);\n private $learnCardComplete = atom(false);\n private $version = atom(0);\n\n /** Last screen seen — used to detect screen transitions for analytics. */\n private _lastScreen: ScreenName | null = null;\n\n /** Hooks run when transitioning onto a screen. */\n private _enterScreenHooks = new Map<ScreenName, (() => void)[]>();\n\n /** Gate promises derived from workflow step definitions. */\n private _gates = new Map<string, GateEntry>();\n\n version = '';\n\n /** Navigation router — resolves active screen from session state. */\n readonly router: WizardRouter;\n\n /** Blocks agent execution until the settings-override overlay is dismissed. */\n private _resolveSettingsOverride: (() => void) | null = null;\n private _backupAndFixSettings: (() => boolean) | null = null;\n\n /** Blocks OAuth flow until the port-conflict overlay is dismissed. */\n private _resolvePortConflict: (() => void) | null = null;\n\n constructor(flow: Flow = Flow.PostHogIntegration) {\n this.router = new WizardRouter(flow);\n this._initFromWorkflow(flow);\n }\n\n /**\n * Scan workflow steps for gate predicates and onInit callbacks.\n * Creates gate promises and fires init work.\n */\n private _initFromWorkflow(flow: Flow): void {\n const steps = WORKFLOW_STEPS[flow];\n if (!steps) return;\n\n // Create gate promises from steps that define them\n for (const step of steps) {\n if (step.gate) {\n let resolve!: () => void;\n const promise = new Promise<void>((r) => {\n resolve = r;\n });\n this._gates.set(step.id, {\n predicate: step.gate,\n promise,\n resolve,\n resolved: false,\n });\n }\n }\n\n // Run onInit callbacks with a minimal context interface.\n // Arrow functions capture `this` from _initFromWorkflow so we don't\n // need to alias it.\n const getSession = (): WizardSession => this.session;\n const ctx: StoreInitContext = {\n get session() {\n return getSession();\n },\n setReadinessResult: (r) => this.setReadinessResult(r),\n setFrameworkContext: (k, v) => this.setFrameworkContext(k, v),\n emitChange: () => this.emitChange(),\n };\n for (const step of steps) {\n step.onInit?.(ctx);\n }\n }\n\n /**\n * Run all `onReady` hooks declared by the current flow's steps, in\n * order. Must be called after `store.session = session` so hooks see\n * the real installDir. bin.ts calls this generically — it doesn't\n * need to know which workflow has which pre-flow work.\n */\n async runReadyHooks(): Promise<void> {\n const steps = WORKFLOW_STEPS[this.router.activeFlow];\n if (!steps) return;\n const ctx: WorkflowReadyContext = {\n session: this.session,\n setFrameworkContext: (k, v) => this.setFrameworkContext(k, v),\n setFrameworkConfig: (i, c) => this.setFrameworkConfig(i, c),\n setDetectedFramework: (l) => this.setDetectedFramework(l),\n setUnsupportedVersion: (info) => this.setUnsupportedVersion(info),\n addDiscoveredFeature: (f) => this.addDiscoveredFeature(f),\n setDetectionComplete: () => this.setDetectionComplete(),\n };\n for (const step of steps) {\n if (step.onReady) {\n await step.onReady(ctx);\n }\n }\n }\n\n // ── Gate API ────────────────────────────────────────────────────\n\n /**\n * Get a gate promise by step ID — the primary blocking checkpoint API\n * for bin.ts. `await store.getGate('...')` parks the caller until the\n * corresponding workflow step's gate predicate flips to true (if the\n * predicate stays false, the caller stays parked indefinitely — the\n * TUI keeps rendering so the user can resolve whatever is blocking).\n *\n * If the workflow doesn't define a step with this ID, or the step\n * has no `gate` predicate, this returns an already-resolved promise\n * so bin.ts flows straight through. This lets workflows opt in to\n * gates on a per-step basis without bin.ts needing to know which\n * gates exist in which flow.\n */\n getGate(stepId: string): Promise<void> {\n return this._gates.get(stepId)?.promise ?? Promise.resolve();\n }\n\n /**\n * Re-evaluate every gate predicate against the current session and\n * resolve any whose predicate now returns true. Called after every\n * emitChange(), so gates unblock as soon as the session mutation\n * that satisfies them lands. Gates only resolve once — a predicate\n * that goes true → false → true will NOT re-block a caller that\n * already awaited through.\n */\n private _checkGates(): void {\n for (const [, gate] of this._gates) {\n if (!gate.resolved && gate.predicate(this.session)) {\n gate.resolved = true;\n gate.resolve();\n }\n }\n }\n\n // ── State accessors (read from atoms) ────────────────────────────\n\n get session(): WizardSession {\n return this.$session.get();\n }\n\n set session(value: WizardSession) {\n this.$session.set(value);\n }\n\n get statusMessages(): string[] {\n return this.$statusMessages.get();\n }\n\n get tasks(): TaskItem[] {\n return this.$tasks.get();\n }\n\n get eventPlan(): PlannedEvent[] {\n return this.$eventPlan.get();\n }\n\n get statusExpanded(): boolean {\n return this.$statusExpanded.get();\n }\n\n toggleStatusExpanded(): void {\n this.$statusExpanded.set(!this.$statusExpanded.get());\n this.emitChange();\n }\n\n setStatusExpanded(expanded: boolean): void {\n if (this.$statusExpanded.get() !== expanded) {\n this.$statusExpanded.set(expanded);\n this.emitChange();\n }\n }\n\n // ── Session setters ─────────────────────────────────────────────\n // Every setter that affects screen resolution calls emitChange().\n // Business logic calls these instead of mutating session directly.\n\n /** Sets setupConfirmed. Gate resolves via _checkGates(). */\n completeSetup(): void {\n this.$session.setKey('setupConfirmed', true);\n analytics.wizardCapture('setup confirmed', sessionProperties(this.session));\n this.emitChange();\n }\n\n setRunPhase(phase: RunPhase): void {\n this.$session.setKey('runPhase', phase);\n this.emitChange();\n }\n\n setCredentials(credentials: WizardSession['credentials']): void {\n this.$session.setKey('credentials', credentials);\n analytics.wizardCapture('auth complete', {\n project_id: credentials?.projectId,\n });\n this.emitChange();\n }\n\n setFrameworkConfig(\n integration: WizardSession['integration'],\n config: WizardSession['frameworkConfig'],\n ): void {\n this.$session.setKey('integration', integration);\n this.$session.setKey('frameworkConfig', config);\n this.$session.setKey('unsupportedVersion', null);\n this.emitChange();\n }\n\n setDetectionComplete(): void {\n this.$session.setKey('detectionComplete', true);\n this.emitChange();\n }\n\n setDetectedFramework(label: string): void {\n this.$session.setKey('detectedFrameworkLabel', label);\n this.emitChange();\n }\n\n setUnsupportedVersion(info: {\n current: string;\n minimum: string;\n docsUrl: string;\n }): void {\n this.$session.setKey('unsupportedVersion', info);\n this.emitChange();\n }\n\n setLoginUrl(url: string | null): void {\n this.$session.setKey('loginUrl', url);\n this.emitChange();\n }\n\n setReadinessResult(result: WizardReadinessResult | null): void {\n this.$session.setKey('readinessResult', result);\n this.emitChange();\n }\n\n /** User dismissed the blocking outage screen. Gate resolves via _checkGates(). */\n dismissOutage(): void {\n this.$session.setKey('outageDismissed', true);\n this.emitChange();\n }\n\n /**\n * Push the settings-override overlay and return a promise that blocks\n * until the user dismisses it via backupAndFixSettingsOverride().\n */\n showSettingsOverride(\n conflicts: SettingsConflict[],\n backupAndFix: () => boolean,\n ): Promise<void> {\n const allKeys = conflicts.flatMap((c) => c.keys);\n this.$session.setKey('settingsOverrideKeys', allKeys);\n this.$session.setKey('settingsConflicts', conflicts);\n this._backupAndFixSettings = backupAndFix;\n\n const hasReadOnly = conflicts.some((c) => !c.writable);\n if (hasReadOnly) {\n this.pushOverlay(Overlay.ManagedSettings);\n } else {\n this.pushOverlay(Overlay.SettingsOverride);\n }\n\n return new Promise((resolve) => {\n this._resolveSettingsOverride = resolve;\n });\n }\n\n /**\n * Push the port-conflict overlay and return a promise that blocks\n * until the user kills the blocking process or exits.\n */\n showPortConflict(processInfo: {\n command: string;\n pid: string;\n user: string;\n }): Promise<void> {\n this.$session.setKey('portConflictProcess', processInfo);\n this.pushOverlay(Overlay.PortConflict);\n return new Promise((resolve) => {\n this._resolvePortConflict = resolve;\n });\n }\n\n /** Dismiss the port-conflict overlay after the user kills the process. */\n resolvePortConflict(): void {\n this.$session.setKey('portConflictProcess', null);\n this.popOverlay();\n this._resolvePortConflict?.();\n this._resolvePortConflict = null;\n }\n\n /**\n * Back up .claude/settings.json. Dismisses the overlay on success.\n */\n backupAndFixSettingsOverride(): boolean {\n const ok = this._backupAndFixSettings?.() ?? false;\n if (ok) {\n this.$session.setKey('settingsOverrideKeys', null);\n this.$session.setKey('settingsConflicts', null);\n this.popOverlay();\n this._resolveSettingsOverride?.();\n this._resolveSettingsOverride = null;\n this._backupAndFixSettings = null;\n }\n return ok;\n }\n\n /** Push the auth-error overlay (no dismiss — user must exit). */\n showAuthError(): void {\n this.pushOverlay(Overlay.AuthError);\n }\n\n addDiscoveredFeature(feature: DiscoveredFeature): void {\n if (!this.session.discoveredFeatures.includes(feature)) {\n this.session.discoveredFeatures.push(feature);\n this.emitChange();\n }\n }\n\n /**\n * Enable an additional feature: enqueue it for the stop hook\n * and set any feature-specific session flags.\n */\n enableFeature(feature: AdditionalFeature): void {\n if (!this.session.additionalFeatureQueue.includes(feature)) {\n this.session.additionalFeatureQueue.push(feature);\n }\n // Feature-specific flags\n if (feature === AdditionalFeature.LLM) {\n this.session.llmOptIn = true;\n }\n analytics.wizardCapture('feature enabled', { feature });\n this.emitChange();\n }\n\n setMcpComplete(\n outcome: McpOutcome = McpOutcome.Skipped,\n installedClients: string[] = [],\n ): void {\n this.$session.setKey('mcpComplete', true);\n this.$session.setKey('mcpOutcome', outcome);\n this.$session.setKey('mcpInstalledClients', installedClients);\n analytics.wizardCapture('mcp complete', {\n mcp_outcome: outcome,\n mcp_installed_clients: installedClients,\n ...sessionProperties(this.session),\n });\n this.emitChange();\n }\n\n setSkillsComplete(kept: boolean): void {\n this.$session.setKey('skillsComplete', true);\n analytics.wizardCapture('skills complete', {\n skills_kept: kept,\n ...sessionProperties(this.session),\n });\n this.emitChange();\n }\n\n setOutroDismissed(): void {\n this.$session.setKey('outroDismissed', true);\n this.emitChange();\n }\n\n setOutroData(data: OutroData): void {\n this.$session.setKey('outroData', data);\n this.emitChange();\n }\n\n setFrameworkContext(key: string, value: unknown): void {\n const ctx = { ...this.$session.get().frameworkContext, [key]: value };\n this.$session.setKey('frameworkContext', ctx);\n this.emitChange();\n }\n\n // ── Derived state ───────────────────────────────────────────────\n\n /**\n * The screen that should be rendered right now.\n * Derived from session state via the router.\n */\n get currentScreen(): ScreenName {\n return this.router.resolve(this.session);\n }\n\n /** Direction hint for screen transitions. */\n get lastNavDirection(): 'push' | 'pop' | null {\n return this.router.lastNavDirection;\n }\n\n // ── Change notification ─────────────────────────────────────────\n\n getVersion(): number {\n return this.$version.get();\n }\n\n /**\n * Notify React that state has changed.\n * The router re-resolves the active screen on next render.\n * Gate predicates are checked and resolved if ready.\n */\n emitChange(): void {\n this.router._setDirection('push');\n this.$version.set(this.$version.get() + 1);\n this._checkGates();\n this._detectTransition();\n }\n\n // ── Overlay navigation ──────────────────────────────────────────\n\n pushOverlay(overlay: Overlay): void {\n this.router._setDirection('push');\n this.router.pushOverlay(overlay);\n this.$version.set(this.$version.get() + 1);\n this._detectTransition();\n }\n\n popOverlay(): void {\n this.router._setDirection('pop');\n this.router.popOverlay();\n this.$version.set(this.$version.get() + 1);\n this._detectTransition();\n }\n\n // ── Screen transition analytics ─────────────────────────────────\n\n /**\n * Register a callback to run when transitioning onto the given screen.\n * Fires after every transition that lands on this screen.\n */\n onEnterScreen(screen: ScreenName, fn: () => void): void {\n const list = this._enterScreenHooks.get(screen) ?? [];\n list.push(fn);\n this._enterScreenHooks.set(screen, list);\n }\n\n /**\n * Detect screen transitions, run enter-screen hooks, and fire analytics.\n * Called at the end of emitChange/pushOverlay/popOverlay.\n */\n private _detectTransition(): void {\n const next = this.router.resolve(this.session);\n const prev = this._lastScreen;\n if (prev !== null && next !== prev) {\n const hooks = this._enterScreenHooks.get(next);\n if (hooks) {\n for (const fn of hooks) fn();\n }\n analytics.wizardCapture(`screen ${next}`, {\n from_screen: prev,\n ...sessionProperties(this.session),\n });\n }\n this._lastScreen = next;\n }\n\n // ── Agent observation state ─────────────────────────────────────\n\n pushStatus(message: string): void {\n const msgs = this.$statusMessages.get();\n // Skip consecutive duplicate messages\n if (msgs.length > 0 && msgs[msgs.length - 1] === message) return;\n this.$statusMessages.set([...msgs, message]);\n this.emitChange();\n }\n\n setTasks(tasks: TaskItem[]): void {\n this.$tasks.set(tasks);\n this.emitChange();\n }\n\n updateTask(index: number, done: boolean): void {\n const tasks = this.$tasks.get();\n if (tasks[index]) {\n const updated = [...tasks];\n updated[index] = {\n ...updated[index],\n done,\n status: done ? TaskStatus.Completed : TaskStatus.Pending,\n };\n this.$tasks.set(updated);\n this.emitChange();\n }\n }\n\n setEventPlan(events: PlannedEvent[]): void {\n this.$eventPlan.set(events);\n this.emitChange();\n }\n\n get learnCardBlockIdx(): number {\n return this.$learnCardBlockIdx.get();\n }\n\n setLearnCardBlockIdx(idx: number): void {\n this.$learnCardBlockIdx.set(idx);\n }\n\n get learnCardComplete(): boolean {\n return this.$learnCardComplete.get();\n }\n\n setLearnCardComplete(): void {\n this.$learnCardComplete.set(true);\n this.emitChange();\n }\n\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void {\n const incoming = todos.map((t) => ({\n label: t.content,\n activeForm: t.activeForm,\n status: (t.status as TaskStatus) || TaskStatus.Pending,\n done: t.status === TaskStatus.Completed,\n }));\n\n const incomingLabels = new Set(incoming.map((t) => t.label));\n\n const retained = this.$tasks\n .get()\n .filter((t) => t.done && !incomingLabels.has(t.label));\n\n this.$tasks.set([...retained, ...incoming]);\n this.emitChange();\n }\n\n // ── React integration ───────────────────────────────────────────\n\n subscribe(callback: () => void): () => void {\n return this.$version.listen(() => callback());\n }\n\n getSnapshot(): number {\n return this.$version.get();\n }\n}\n"]}
@@ -7,7 +7,9 @@
7
7
  * No prompt methods — the TUI screens own all user input.
8
8
  * Session-mutating methods trigger reactive screen resolution in the TUI.
9
9
  */
10
- import type { SettingsConflict } from '../lib/agent-interface';
10
+ import type { SettingsConflict } from '../lib/agent/agent-interface';
11
+ import type { WizardReadinessResult } from '../lib/health-checks/readiness.js';
12
+ import type { OutroData } from '../lib/wizard-session';
11
13
  export declare enum TaskStatus {
12
14
  Pending = "pending",
13
15
  InProgress = "in_progress",
@@ -20,7 +22,15 @@ export interface SpinnerHandle {
20
22
  }
21
23
  export interface WizardUI {
22
24
  intro(message: string): void;
25
+ /** Success outro with a plain text message. */
23
26
  outro(message: string): void;
27
+ /**
28
+ * Error outro. Sets structured outroData and transitions run phase so
29
+ * the router advances to the outro screen. Use for abort/failure paths
30
+ * that need a custom error render — do NOT build the outroData by
31
+ * mutating session directly (nanostore holds a shallow copy).
32
+ */
33
+ outroError(data: OutroData): void;
24
34
  cancel(message: string): void;
25
35
  log: {
26
36
  info(message: string): void;
@@ -42,9 +52,9 @@ export interface WizardUI {
42
52
  projectId: number;
43
53
  }): void;
44
54
  /** Show blocking service outage (pushes outage overlay in TUI). Blocks until dismissed. */
45
- showBlockingOutage(result: import('../lib/health-checks/readiness.js').WizardReadinessResult): Promise<void>;
55
+ showBlockingOutage(result: WizardReadinessResult): Promise<void>;
46
56
  /** Store non-blocking readiness warnings (shown as Health tab in RunScreen). */
47
- setReadinessWarnings(result: import('../lib/health-checks/readiness.js').WizardReadinessResult): void;
57
+ setReadinessWarnings(result: WizardReadinessResult): void;
48
58
  /** Warn that another process is blocking the OAuth port (pushes overlay in TUI). */
49
59
  showPortConflict(processInfo: {
50
60
  command: string;
@@ -1 +1 @@
1
- {"version":3,"file":"wizard-ui.js","sourceRoot":"","sources":["../../../src/ui/wizard-ui.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAIH,IAAY,UAIX;AAJD,WAAY,UAAU;IACpB,iCAAmB,CAAA;IACnB,wCAA0B,CAAA;IAC1B,qCAAuB,CAAA;AACzB,CAAC,EAJW,UAAU,0BAAV,UAAU,QAIrB","sourcesContent":["/**\n * WizardUI — abstraction layer for all user-facing operations.\n *\n * Business logic calls `getUI()` instead of importing the store directly.\n * Implementations: InkUI (TUI), LoggingUI (CI).\n *\n * No prompt methods — the TUI screens own all user input.\n * Session-mutating methods trigger reactive screen resolution in the TUI.\n */\n\nimport type { SettingsConflict } from '../lib/agent-interface';\n\nexport enum TaskStatus {\n Pending = 'pending',\n InProgress = 'in_progress',\n Completed = 'completed',\n}\n\nexport interface SpinnerHandle {\n start(message?: string): void;\n stop(message?: string): void;\n message(msg?: string): void;\n}\n\nexport interface WizardUI {\n // ── Lifecycle messages ────────────────────────────────────────────\n intro(message: string): void;\n outro(message: string): void;\n cancel(message: string): void;\n\n // ── Logging ───────────────────────────────────────────────────────\n log: {\n info(message: string): void;\n warn(message: string): void;\n error(message: string): void;\n success(message: string): void;\n step(message: string): void;\n };\n\n note(message: string): void;\n pushStatus(message: string): void;\n\n // ── Spinner ───────────────────────────────────────────────────────\n spinner(): SpinnerHandle;\n\n // ── Session state (triggers reactive screen resolution in TUI) ────\n /** Signal that the main work (agent run) has started. */\n startRun(): void;\n\n /** Store OAuth/API credentials. Resolves past AuthScreen in TUI. */\n setCredentials(credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n }): void;\n\n /** Show blocking service outage (pushes outage overlay in TUI). Blocks until dismissed. */\n showBlockingOutage(\n result: import('../lib/health-checks/readiness.js').WizardReadinessResult,\n ): Promise<void>;\n\n /** Store non-blocking readiness warnings (shown as Health tab in RunScreen). */\n setReadinessWarnings(\n result: import('../lib/health-checks/readiness.js').WizardReadinessResult,\n ): void;\n\n /** Warn that another process is blocking the OAuth port (pushes overlay in TUI). */\n showPortConflict(processInfo: {\n command: string;\n pid: string;\n user: string;\n }): Promise<void>;\n\n showSettingsOverride(\n conflicts: SettingsConflict[],\n backupAndFix: () => boolean,\n ): Promise<void>;\n\n /** Show auth error overlay when Anthropic API returns 401. */\n showAuthError(): void;\n\n // ── Display state ──────────────────────────────────────────────────\n /** Set the detected framework label (e.g., \"Django with Wagtail CMS\") */\n setDetectedFramework(label: string): void;\n\n /** Register a callback to run when the TUI transitions onto the given screen. */\n onEnterScreen(screen: string, fn: () => void): void;\n\n setLoginUrl(url: string | null): void;\n\n // ── Todo tracking from SDK TodoWrite events ───────────────────────\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void;\n\n // ── Event plan from .posthog-events.json ────────────────────\n setEventPlan(events: Array<{ name: string; description: string }>): void;\n}\n"]}
1
+ {"version":3,"file":"wizard-ui.js","sourceRoot":"","sources":["../../../src/ui/wizard-ui.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAMH,IAAY,UAIX;AAJD,WAAY,UAAU;IACpB,iCAAmB,CAAA;IACnB,wCAA0B,CAAA;IAC1B,qCAAuB,CAAA;AACzB,CAAC,EAJW,UAAU,0BAAV,UAAU,QAIrB","sourcesContent":["/**\n * WizardUI — abstraction layer for all user-facing operations.\n *\n * Business logic calls `getUI()` instead of importing the store directly.\n * Implementations: InkUI (TUI), LoggingUI (CI).\n *\n * No prompt methods — the TUI screens own all user input.\n * Session-mutating methods trigger reactive screen resolution in the TUI.\n */\n\nimport type { SettingsConflict } from '../lib/agent/agent-interface';\nimport type { WizardReadinessResult } from '../lib/health-checks/readiness.js';\nimport type { OutroData } from '../lib/wizard-session';\n\nexport enum TaskStatus {\n Pending = 'pending',\n InProgress = 'in_progress',\n Completed = 'completed',\n}\n\nexport interface SpinnerHandle {\n start(message?: string): void;\n stop(message?: string): void;\n message(msg?: string): void;\n}\n\nexport interface WizardUI {\n // ── Lifecycle messages ────────────────────────────────────────────\n intro(message: string): void;\n /** Success outro with a plain text message. */\n outro(message: string): void;\n /**\n * Error outro. Sets structured outroData and transitions run phase so\n * the router advances to the outro screen. Use for abort/failure paths\n * that need a custom error render — do NOT build the outroData by\n * mutating session directly (nanostore holds a shallow copy).\n */\n outroError(data: OutroData): void;\n cancel(message: string): void;\n\n // ── Logging ───────────────────────────────────────────────────────\n log: {\n info(message: string): void;\n warn(message: string): void;\n error(message: string): void;\n success(message: string): void;\n step(message: string): void;\n };\n\n note(message: string): void;\n pushStatus(message: string): void;\n\n // ── Spinner ───────────────────────────────────────────────────────\n spinner(): SpinnerHandle;\n\n // ── Session state (triggers reactive screen resolution in TUI) ────\n /** Signal that the main work (agent run) has started. */\n startRun(): void;\n\n /** Store OAuth/API credentials. Resolves past AuthScreen in TUI. */\n setCredentials(credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n }): void;\n\n /** Show blocking service outage (pushes outage overlay in TUI). Blocks until dismissed. */\n showBlockingOutage(result: WizardReadinessResult): Promise<void>;\n\n /** Store non-blocking readiness warnings (shown as Health tab in RunScreen). */\n setReadinessWarnings(result: WizardReadinessResult): void;\n\n /** Warn that another process is blocking the OAuth port (pushes overlay in TUI). */\n showPortConflict(processInfo: {\n command: string;\n pid: string;\n user: string;\n }): Promise<void>;\n\n showSettingsOverride(\n conflicts: SettingsConflict[],\n backupAndFix: () => boolean,\n ): Promise<void>;\n\n /** Show auth error overlay when Anthropic API returns 401. */\n showAuthError(): void;\n\n // ── Display state ──────────────────────────────────────────────────\n /** Set the detected framework label (e.g., \"Django with Wagtail CMS\") */\n setDetectedFramework(label: string): void;\n\n /** Register a callback to run when the TUI transitions onto the given screen. */\n onEnterScreen(screen: string, fn: () => void): void;\n\n setLoginUrl(url: string | null): void;\n\n // ── Todo tracking from SDK TodoWrite events ───────────────────────\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void;\n\n // ── Event plan from .posthog-events.json ────────────────────\n setEventPlan(events: Array<{ name: string; description: string }>): void;\n}\n"]}
@@ -1,2 +1,10 @@
1
1
  import type { WizardOptions } from './types';
2
2
  export declare function getDotGitignore({ installDir, }: Pick<WizardOptions, 'installDir'>): string | undefined;
3
+ /**
4
+ * Directory names to skip when recursively scanning a project tree.
5
+ * Used by detection logic (e.g. finding all package.json files) to avoid
6
+ * dependency directories, build output, virtual environments, etc.
7
+ *
8
+ * For fast-glob `ignore` patterns, map this to `**\/<name>/**`.
9
+ */
10
+ export declare const IGNORED_DIRS: Set<string>;
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.IGNORED_DIRS = void 0;
6
7
  exports.getDotGitignore = getDotGitignore;
7
8
  const path_1 = __importDefault(require("path"));
8
9
  const fs_1 = __importDefault(require("fs"));
@@ -14,4 +15,35 @@ function getDotGitignore({ installDir, }) {
14
15
  }
15
16
  return undefined;
16
17
  }
18
+ /**
19
+ * Directory names to skip when recursively scanning a project tree.
20
+ * Used by detection logic (e.g. finding all package.json files) to avoid
21
+ * dependency directories, build output, virtual environments, etc.
22
+ *
23
+ * For fast-glob `ignore` patterns, map this to `**\/<name>/**`.
24
+ */
25
+ exports.IGNORED_DIRS = new Set([
26
+ 'node_modules',
27
+ '.git',
28
+ '.next',
29
+ '.nuxt',
30
+ '.svelte-kit',
31
+ '.turbo',
32
+ '.cache',
33
+ '.parcel-cache',
34
+ 'dist',
35
+ 'build',
36
+ 'out',
37
+ 'coverage',
38
+ '.coverage',
39
+ 'venv',
40
+ '.venv',
41
+ '__pycache__',
42
+ '.pytest_cache',
43
+ 'vendor',
44
+ 'target',
45
+ '.gradle',
46
+ '.idea',
47
+ '.vscode',
48
+ ]);
17
49
  //# sourceMappingURL=file-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-utils.js","sourceRoot":"","sources":["../../../src/utils/file-utils.ts"],"names":[],"mappings":";;;;;AAIA,0CAWC;AAfD,gDAAwB;AACxB,4CAAoB;AAGpB,SAAgB,eAAe,CAAC,EAC9B,UAAU,GACwB;IAClC,MAAM,aAAa,GAAG,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAC1D,MAAM,eAAe,GAAG,YAAE,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAErD,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import path from 'path';\nimport fs from 'fs';\nimport type { WizardOptions } from './types';\n\nexport function getDotGitignore({\n installDir,\n}: Pick<WizardOptions, 'installDir'>) {\n const gitignorePath = path.join(installDir, '.gitignore');\n const gitignoreExists = fs.existsSync(gitignorePath);\n\n if (gitignoreExists) {\n return gitignorePath;\n }\n\n return undefined;\n}\n"]}
1
+ {"version":3,"file":"file-utils.js","sourceRoot":"","sources":["../../../src/utils/file-utils.ts"],"names":[],"mappings":";;;;;;AAIA,0CAWC;AAfD,gDAAwB;AACxB,4CAAoB;AAGpB,SAAgB,eAAe,CAAC,EAC9B,UAAU,GACwB;IAClC,MAAM,aAAa,GAAG,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAC1D,MAAM,eAAe,GAAG,YAAE,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAErD,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACU,QAAA,YAAY,GAAG,IAAI,GAAG,CAAS;IAC1C,cAAc;IACd,MAAM;IACN,OAAO;IACP,OAAO;IACP,aAAa;IACb,QAAQ;IACR,QAAQ;IACR,eAAe;IACf,MAAM;IACN,OAAO;IACP,KAAK;IACL,UAAU;IACV,WAAW;IACX,MAAM;IACN,OAAO;IACP,aAAa;IACb,eAAe;IACf,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,OAAO;IACP,SAAS;CACV,CAAC,CAAC","sourcesContent":["import path from 'path';\nimport fs from 'fs';\nimport type { WizardOptions } from './types';\n\nexport function getDotGitignore({\n installDir,\n}: Pick<WizardOptions, 'installDir'>) {\n const gitignorePath = path.join(installDir, '.gitignore');\n const gitignoreExists = fs.existsSync(gitignorePath);\n\n if (gitignoreExists) {\n return gitignorePath;\n }\n\n return undefined;\n}\n\n/**\n * Directory names to skip when recursively scanning a project tree.\n * Used by detection logic (e.g. finding all package.json files) to avoid\n * dependency directories, build output, virtual environments, etc.\n *\n * For fast-glob `ignore` patterns, map this to `**\\/<name>/**`.\n */\nexport const IGNORED_DIRS = new Set<string>([\n 'node_modules',\n '.git',\n '.next',\n '.nuxt',\n '.svelte-kit',\n '.turbo',\n '.cache',\n '.parcel-cache',\n 'dist',\n 'build',\n 'out',\n 'coverage',\n '.coverage',\n 'venv',\n '.venv',\n '__pycache__',\n '.pytest_cache',\n 'vendor',\n 'target',\n '.gradle',\n '.idea',\n '.vscode',\n]);\n"]}
@@ -1,9 +1,12 @@
1
+ import { type OutroData } from '../lib/wizard-session';
1
2
  export declare class WizardError extends Error {
2
3
  readonly context?: Record<string, unknown> | undefined;
3
4
  constructor(message: string, context?: Record<string, unknown> | undefined);
4
5
  }
5
6
  interface WizardAbortOptions {
6
7
  message?: string;
8
+ /** Structured error data. Renders via `outroError` instead of `outro`. */
9
+ outroData?: OutroData;
7
10
  error?: Error | WizardError;
8
11
  exitCode?: number;
9
12
  }
@@ -14,6 +14,7 @@ exports.wizardAbort = wizardAbort;
14
14
  */
15
15
  const analytics_1 = require("./analytics");
16
16
  const ui_1 = require("../ui");
17
+ const wizard_session_1 = require("../lib/wizard-session");
17
18
  class WizardError extends Error {
18
19
  context;
19
20
  constructor(message, context) {
@@ -31,7 +32,7 @@ function clearCleanup() {
31
32
  cleanupFns.length = 0;
32
33
  }
33
34
  async function wizardAbort(options) {
34
- const { message = 'Wizard setup cancelled.', error, exitCode = 1, } = options ?? {};
35
+ const { message = 'Wizard setup cancelled.', outroData, error, exitCode = 1, } = options ?? {};
35
36
  // 1. Run registered cleanup functions
36
37
  for (const fn of cleanupFns) {
37
38
  try {
@@ -49,8 +50,9 @@ async function wizardAbort(options) {
49
50
  }
50
51
  // 3. Shutdown analytics
51
52
  await analytics_1.analytics.shutdown(error ? 'error' : 'cancelled');
52
- // 4. Display message to user
53
- (0, ui_1.getUI)().outro(message);
53
+ // 4. Render the error outro. Synthesize OutroData from `message`
54
+ // when the caller didn't provide structured data.
55
+ (0, ui_1.getUI)().outroError(outroData ?? { kind: wizard_session_1.OutroKind.Error, message });
54
56
  // 5. Exit (fires 'exit' event so TUI cleanup runs)
55
57
  return process.exit(exitCode);
56
58
  }
@@ -1 +1 @@
1
- {"version":3,"file":"wizard-abort.js","sourceRoot":"","sources":["../../../src/utils/wizard-abort.ts"],"names":[],"mappings":";;;AA6BA,0CAEC;AAED,oCAEC;AAED,kCAiCC;AAtED;;;;;;;GAOG;AACH,2CAAwC;AACxC,8BAA8B;AAE9B,MAAa,WAAY,SAAQ,KAAK;IAGlB;IAFlB,YACE,OAAe,EACC,OAAiC;QAEjD,KAAK,CAAC,OAAO,CAAC,CAAC;QAFC,YAAO,GAAP,OAAO,CAA0B;QAGjD,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AARD,kCAQC;AAQD,MAAM,UAAU,GAAsB,EAAE,CAAC;AAEzC,SAAgB,eAAe,CAAC,EAAc;IAC5C,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACtB,CAAC;AAED,SAAgB,YAAY;IAC1B,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;AACxB,CAAC;AAEM,KAAK,UAAU,WAAW,CAC/B,OAA4B;IAE5B,MAAM,EACJ,OAAO,GAAG,yBAAyB,EACnC,KAAK,EACL,QAAQ,GAAG,CAAC,GACb,GAAG,OAAO,IAAI,EAAE,CAAC;IAElB,sCAAsC;IACtC,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,EAAE,EAAE,CAAC;QACP,CAAC;QAAC,MAAM,CAAC;YACP,qCAAqC;QACvC,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,IAAI,KAAK,EAAE,CAAC;QACV,qBAAS,CAAC,gBAAgB,CAAC,KAAK,EAAE;YAChC,GAAG,CAAC,CAAC,KAAK,YAAY,WAAW,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;SAC3D,CAAC,CAAC;IACL,CAAC;IAED,wBAAwB;IACxB,MAAM,qBAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAExD,6BAA6B;IAC7B,IAAA,UAAK,GAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAEvB,mDAAmD;IACnD,OAAO,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC","sourcesContent":["/**\n * Single exit point for the wizard. Use instead of process.exit() directly.\n *\n * Sequence: cleanup -> error capture (optional) -> analytics shutdown -> outro -> process.exit\n *\n * WizardError is a data carrier passed to wizardAbort() for analytics context, never thrown.\n * The legacy abort() in setup-utils.ts delegates here.\n */\nimport { analytics } from './analytics';\nimport { getUI } from '../ui';\n\nexport class WizardError extends Error {\n constructor(\n message: string,\n public readonly context?: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'WizardError';\n }\n}\n\ninterface WizardAbortOptions {\n message?: string;\n error?: Error | WizardError;\n exitCode?: number;\n}\n\nconst cleanupFns: Array<() => void> = [];\n\nexport function registerCleanup(fn: () => void): void {\n cleanupFns.push(fn);\n}\n\nexport function clearCleanup(): void {\n cleanupFns.length = 0;\n}\n\nexport async function wizardAbort(\n options?: WizardAbortOptions,\n): Promise<never> {\n const {\n message = 'Wizard setup cancelled.',\n error,\n exitCode = 1,\n } = options ?? {};\n\n // 1. Run registered cleanup functions\n for (const fn of cleanupFns) {\n try {\n fn();\n } catch {\n /* cleanup should not prevent exit */\n }\n }\n\n // 2. Capture error in analytics (if provided)\n if (error) {\n analytics.captureException(error, {\n ...((error instanceof WizardError && error.context) || {}),\n });\n }\n\n // 3. Shutdown analytics\n await analytics.shutdown(error ? 'error' : 'cancelled');\n\n // 4. Display message to user\n getUI().outro(message);\n\n // 5. Exit (fires 'exit' event so TUI cleanup runs)\n return process.exit(exitCode);\n}\n"]}
1
+ {"version":3,"file":"wizard-abort.js","sourceRoot":"","sources":["../../../src/utils/wizard-abort.ts"],"names":[],"mappings":";;;AAgCA,0CAEC;AAED,oCAEC;AAED,kCAmCC;AA3ED;;;;;;;GAOG;AACH,2CAAwC;AACxC,8BAA8B;AAC9B,0DAAkE;AAElE,MAAa,WAAY,SAAQ,KAAK;IAGlB;IAFlB,YACE,OAAe,EACC,OAAiC;QAEjD,KAAK,CAAC,OAAO,CAAC,CAAC;QAFC,YAAO,GAAP,OAAO,CAA0B;QAGjD,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AARD,kCAQC;AAUD,MAAM,UAAU,GAAsB,EAAE,CAAC;AAEzC,SAAgB,eAAe,CAAC,EAAc;IAC5C,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACtB,CAAC;AAED,SAAgB,YAAY;IAC1B,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;AACxB,CAAC;AAEM,KAAK,UAAU,WAAW,CAC/B,OAA4B;IAE5B,MAAM,EACJ,OAAO,GAAG,yBAAyB,EACnC,SAAS,EACT,KAAK,EACL,QAAQ,GAAG,CAAC,GACb,GAAG,OAAO,IAAI,EAAE,CAAC;IAElB,sCAAsC;IACtC,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,EAAE,EAAE,CAAC;QACP,CAAC;QAAC,MAAM,CAAC;YACP,qCAAqC;QACvC,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,IAAI,KAAK,EAAE,CAAC;QACV,qBAAS,CAAC,gBAAgB,CAAC,KAAK,EAAE;YAChC,GAAG,CAAC,CAAC,KAAK,YAAY,WAAW,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;SAC3D,CAAC,CAAC;IACL,CAAC;IAED,wBAAwB;IACxB,MAAM,qBAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAExD,iEAAiE;IACjE,qDAAqD;IACrD,IAAA,UAAK,GAAE,CAAC,UAAU,CAAC,SAAS,IAAI,EAAE,IAAI,EAAE,0BAAS,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAEpE,mDAAmD;IACnD,OAAO,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC","sourcesContent":["/**\n * Single exit point for the wizard. Use instead of process.exit() directly.\n *\n * Sequence: cleanup -> error capture (optional) -> analytics shutdown -> outro -> process.exit\n *\n * WizardError is a data carrier passed to wizardAbort() for analytics context, never thrown.\n * The legacy abort() in setup-utils.ts delegates here.\n */\nimport { analytics } from './analytics';\nimport { getUI } from '../ui';\nimport { OutroKind, type OutroData } from '../lib/wizard-session';\n\nexport class WizardError extends Error {\n constructor(\n message: string,\n public readonly context?: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'WizardError';\n }\n}\n\ninterface WizardAbortOptions {\n message?: string;\n /** Structured error data. Renders via `outroError` instead of `outro`. */\n outroData?: OutroData;\n error?: Error | WizardError;\n exitCode?: number;\n}\n\nconst cleanupFns: Array<() => void> = [];\n\nexport function registerCleanup(fn: () => void): void {\n cleanupFns.push(fn);\n}\n\nexport function clearCleanup(): void {\n cleanupFns.length = 0;\n}\n\nexport async function wizardAbort(\n options?: WizardAbortOptions,\n): Promise<never> {\n const {\n message = 'Wizard setup cancelled.',\n outroData,\n error,\n exitCode = 1,\n } = options ?? {};\n\n // 1. Run registered cleanup functions\n for (const fn of cleanupFns) {\n try {\n fn();\n } catch {\n /* cleanup should not prevent exit */\n }\n }\n\n // 2. Capture error in analytics (if provided)\n if (error) {\n analytics.captureException(error, {\n ...((error instanceof WizardError && error.context) || {}),\n });\n }\n\n // 3. Shutdown analytics\n await analytics.shutdown(error ? 'error' : 'cancelled');\n\n // 4. Render the error outro. Synthesize OutroData from `message`\n // when the caller didn't provide structured data.\n getUI().outroError(outroData ?? { kind: OutroKind.Error, message });\n\n // 5. Exit (fires 'exit' event so TUI cleanup runs)\n return process.exit(exitCode);\n}\n"]}
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@posthog/wizard",
3
- "version": "2.8.0",
3
+ "version": "2.9.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@posthog/wizard",
9
- "version": "2.8.0",
9
+ "version": "2.9.0",
10
10
  "dependencies": {
11
11
  "@anthropic-ai/claude-agent-sdk": "0.2.73",
12
12
  "@inkjs/ui": "^2.0.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@posthog/wizard",
3
- "version": "2.8.0",
3
+ "version": "2.9.0",
4
4
  "homepage": "https://github.com/PostHog/wizard",
5
5
  "repository": "https://github.com/PostHog/wizard",
6
6
  "description": "The PostHog wizard helps you to configure your project",
@@ -1,95 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const run_1 = require("../run");
4
- const agent_runner_1 = require("../lib/agent-runner");
5
- const analytics_1 = require("../utils/analytics");
6
- const constants_1 = require("../lib/constants");
7
- jest.mock('../lib/agent-runner');
8
- jest.mock('../utils/analytics');
9
- jest.mock('../lib/wizard-session', () => ({
10
- buildSession: (args) => ({
11
- debug: false,
12
- forceInstall: false,
13
- installDir: process.cwd(),
14
- ci: false,
15
- signup: false,
16
- localMcp: false,
17
- menu: false,
18
- setupConfirmed: false,
19
- integration: null,
20
- frameworkContext: {},
21
- typescript: false,
22
- credentials: null,
23
- readinessResult: null,
24
- outageDismissed: false,
25
- outroData: null,
26
- frameworkConfig: null,
27
- ...args,
28
- }),
29
- }));
30
- jest.mock('../ui', () => ({
31
- getUI: jest.fn().mockReturnValue({
32
- log: {
33
- info: jest.fn(),
34
- warn: jest.fn(),
35
- error: jest.fn(),
36
- success: jest.fn(),
37
- step: jest.fn(),
38
- },
39
- intro: jest.fn(),
40
- outro: jest.fn(),
41
- cancel: jest.fn(),
42
- note: jest.fn(),
43
- spinner: jest.fn().mockReturnValue({
44
- start: jest.fn(),
45
- stop: jest.fn(),
46
- message: jest.fn(),
47
- }),
48
- setDetectedFramework: jest.fn(),
49
- setCredentials: jest.fn(),
50
- pushStatus: jest.fn(),
51
- syncTodos: jest.fn(),
52
- setLoginUrl: jest.fn(),
53
- showBlockingOutage: jest.fn(),
54
- setReadinessWarnings: jest.fn(),
55
- showSettingsOverride: jest.fn(),
56
- startRun: jest.fn(),
57
- }),
58
- setUI: jest.fn(),
59
- }));
60
- const mockRunAgentWizard = agent_runner_1.runAgentWizard;
61
- const mockAnalytics = analytics_1.analytics;
62
- describe('runWizard error handling', () => {
63
- beforeEach(() => {
64
- jest.clearAllMocks();
65
- mockAnalytics.setTag = jest.fn();
66
- mockAnalytics.captureException = jest.fn();
67
- mockAnalytics.shutdown = jest.fn().mockResolvedValue(undefined);
68
- jest.spyOn(process, 'exit').mockImplementation(() => {
69
- throw new Error('process.exit called');
70
- });
71
- });
72
- afterEach(() => {
73
- jest.restoreAllMocks();
74
- });
75
- it('should capture exception and shutdown analytics on wizard error', async () => {
76
- const testError = new Error('Wizard failed');
77
- const testArgs = {
78
- integration: constants_1.Integration.nextjs,
79
- debug: true,
80
- forceInstall: false,
81
- };
82
- mockRunAgentWizard.mockRejectedValue(testError);
83
- await expect((0, run_1.runWizard)(testArgs)).rejects.toThrow('process.exit called');
84
- expect(mockAnalytics.captureException).toHaveBeenCalledWith(testError, {});
85
- expect(mockAnalytics.shutdown).toHaveBeenCalledWith('error');
86
- });
87
- it('should not call captureException when wizard succeeds', async () => {
88
- const testArgs = { integration: constants_1.Integration.nextjs };
89
- mockRunAgentWizard.mockResolvedValue(undefined);
90
- await (0, run_1.runWizard)(testArgs);
91
- expect(mockAnalytics.captureException).not.toHaveBeenCalled();
92
- expect(mockAnalytics.shutdown).not.toHaveBeenCalled();
93
- });
94
- });
95
- //# sourceMappingURL=run.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"run.test.js","sourceRoot":"","sources":["../../../src/__tests__/run.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { runWizard } from '../run';\nimport { runAgentWizard } from '../lib/agent-runner';\nimport { analytics } from '../utils/analytics';\nimport { Integration } from '../lib/constants';\n\njest.mock('../lib/agent-runner');\njest.mock('../utils/analytics');\njest.mock('../lib/wizard-session', () => ({\n buildSession: (args: Record<string, unknown>) => ({\n debug: false,\n forceInstall: false,\n installDir: process.cwd(),\n ci: false,\n signup: false,\n localMcp: false,\n menu: false,\n setupConfirmed: false,\n integration: null,\n frameworkContext: {},\n typescript: false,\n credentials: null,\n readinessResult: null,\n outageDismissed: false,\n outroData: null,\n frameworkConfig: null,\n ...args,\n }),\n}));\njest.mock('../ui', () => ({\n getUI: jest.fn().mockReturnValue({\n log: {\n info: jest.fn(),\n warn: jest.fn(),\n error: jest.fn(),\n success: jest.fn(),\n step: jest.fn(),\n },\n intro: jest.fn(),\n outro: jest.fn(),\n cancel: jest.fn(),\n note: jest.fn(),\n spinner: jest.fn().mockReturnValue({\n start: jest.fn(),\n stop: jest.fn(),\n message: jest.fn(),\n }),\n setDetectedFramework: jest.fn(),\n setCredentials: jest.fn(),\n pushStatus: jest.fn(),\n syncTodos: jest.fn(),\n setLoginUrl: jest.fn(),\n showBlockingOutage: jest.fn(),\n setReadinessWarnings: jest.fn(),\n showSettingsOverride: jest.fn(),\n startRun: jest.fn(),\n }),\n setUI: jest.fn(),\n}));\n\nconst mockRunAgentWizard = runAgentWizard as jest.MockedFunction<\n typeof runAgentWizard\n>;\nconst mockAnalytics = analytics as jest.Mocked<typeof analytics>;\n\ndescribe('runWizard error handling', () => {\n beforeEach(() => {\n jest.clearAllMocks();\n\n mockAnalytics.setTag = jest.fn();\n mockAnalytics.captureException = jest.fn();\n mockAnalytics.shutdown = jest.fn().mockResolvedValue(undefined);\n\n jest.spyOn(process, 'exit').mockImplementation(() => {\n throw new Error('process.exit called');\n });\n });\n\n afterEach(() => {\n jest.restoreAllMocks();\n });\n\n it('should capture exception and shutdown analytics on wizard error', async () => {\n const testError = new Error('Wizard failed');\n const testArgs = {\n integration: Integration.nextjs,\n debug: true,\n forceInstall: false,\n };\n\n mockRunAgentWizard.mockRejectedValue(testError);\n\n await expect(runWizard(testArgs)).rejects.toThrow('process.exit called');\n\n expect(mockAnalytics.captureException).toHaveBeenCalledWith(testError, {});\n\n expect(mockAnalytics.shutdown).toHaveBeenCalledWith('error');\n });\n\n it('should not call captureException when wizard succeeds', async () => {\n const testArgs = { integration: Integration.nextjs };\n\n mockRunAgentWizard.mockResolvedValue(undefined);\n\n await runWizard(testArgs);\n\n expect(mockAnalytics.captureException).not.toHaveBeenCalled();\n expect(mockAnalytics.shutdown).not.toHaveBeenCalled();\n });\n});\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"package-manager-detection.test.js","sourceRoot":"","sources":["../../../../src/lib/__tests__/package-manager-detection.test.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport {\n detectNodePackageManagers,\n detectPythonPackageManagers,\n composerPackageManager,\n swiftPackageManager,\n gradlePackageManager,\n} from '../package-manager-detection';\n\njest.mock('../../utils/debug');\njest.mock('../../telemetry', () => ({\n traceStep: (_name: string, fn: () => unknown) => fn(),\n}));\njest.mock('../../utils/analytics', () => ({\n analytics: { setTag: jest.fn() },\n}));\n\nfunction makeTmpDir(): string {\n return fs.mkdtempSync(path.join(os.tmpdir(), 'pm-detect-'));\n}\n\nfunction cleanup(dir: string): void {\n fs.rmSync(dir, { recursive: true, force: true });\n}\n\n// ---------------------------------------------------------------------------\n// Node.js detection\n// ---------------------------------------------------------------------------\n\ndescribe('detectNodePackageManagers', () => {\n let tmpDir: string;\n\n beforeEach(() => {\n tmpDir = makeTmpDir();\n });\n afterEach(() => cleanup(tmpDir));\n\n it('returns empty when no lockfile exists', async () => {\n const result = await detectNodePackageManagers(tmpDir);\n expect(result.detected).toHaveLength(0);\n expect(result.primary).toBeNull();\n expect(result.recommendation).toContain('No lockfile found');\n });\n\n it('detects npm via package-lock.json', async () => {\n fs.writeFileSync(path.join(tmpDir, 'package-lock.json'), '{}');\n const result = await detectNodePackageManagers(tmpDir);\n expect(result.detected).toHaveLength(1);\n expect(result.primary?.name).toBe('npm');\n expect(result.primary?.installCommand).toBe('npm add');\n expect(result.recommendation).toContain('npm');\n });\n\n it('detects pnpm via pnpm-lock.yaml', async () => {\n fs.writeFileSync(path.join(tmpDir, 'pnpm-lock.yaml'), '');\n const result = await detectNodePackageManagers(tmpDir);\n expect(result.detected).toHaveLength(1);\n expect(result.primary?.name).toBe('pnpm');\n expect(result.primary?.installCommand).toBe('pnpm add');\n });\n\n it('detects yarn v1 via yarn.lock', async () => {\n fs.writeFileSync(path.join(tmpDir, 'yarn.lock'), '# yarn lockfile v1\\n');\n const result = await detectNodePackageManagers(tmpDir);\n expect(result.detected).toHaveLength(1);\n expect(result.primary?.name).toBe('yarn');\n expect(result.primary?.label).toContain('V1');\n });\n\n it('detects yarn v2+ via yarn.lock with __metadata', async () => {\n fs.writeFileSync(\n path.join(tmpDir, 'yarn.lock'),\n '__metadata:\\n version: 8\\n',\n );\n const result = await detectNodePackageManagers(tmpDir);\n expect(result.detected).toHaveLength(1);\n expect(result.primary?.name).toBe('yarn');\n expect(result.primary?.label).toContain('V2');\n });\n\n it('detects bun via bun.lockb', async () => {\n fs.writeFileSync(path.join(tmpDir, 'bun.lockb'), '');\n const result = await detectNodePackageManagers(tmpDir);\n expect(result.detected).toHaveLength(1);\n expect(result.primary?.name).toBe('bun');\n expect(result.primary?.installCommand).toBe('bun add');\n });\n\n it('detects multiple package managers', async () => {\n fs.writeFileSync(path.join(tmpDir, 'package-lock.json'), '{}');\n fs.writeFileSync(path.join(tmpDir, 'pnpm-lock.yaml'), '');\n const result = await detectNodePackageManagers(tmpDir);\n expect(result.detected.length).toBeGreaterThanOrEqual(2);\n expect(result.recommendation).toContain('Multiple');\n });\n\n it('includes runCommand in detected entries', async () => {\n fs.writeFileSync(path.join(tmpDir, 'package-lock.json'), '{}');\n const result = await detectNodePackageManagers(tmpDir);\n expect(result.primary?.runCommand).toBe('npm run');\n });\n});\n\n// ---------------------------------------------------------------------------\n// Python detection\n// ---------------------------------------------------------------------------\n\ndescribe('detectPythonPackageManagers', () => {\n let tmpDir: string;\n\n beforeEach(() => {\n tmpDir = makeTmpDir();\n });\n afterEach(() => cleanup(tmpDir));\n\n it('detects uv via uv.lock', async () => {\n fs.writeFileSync(path.join(tmpDir, 'uv.lock'), '');\n const result = await detectPythonPackageManagers(tmpDir);\n expect(result.primary?.name).toBe('uv');\n expect(result.primary?.installCommand).toBe('uv add');\n expect(result.primary?.runCommand).toBe('uv run');\n });\n\n it('detects poetry via pyproject.toml [tool.poetry]', async () => {\n fs.writeFileSync(\n path.join(tmpDir, 'pyproject.toml'),\n '[tool.poetry]\\nname = \"test\"\\n',\n );\n const result = await detectPythonPackageManagers(tmpDir);\n expect(result.primary?.name).toBe('poetry');\n expect(result.primary?.installCommand).toBe('poetry add');\n });\n\n it('detects poetry via poetry.lock', async () => {\n fs.writeFileSync(path.join(tmpDir, 'poetry.lock'), '');\n const result = await detectPythonPackageManagers(tmpDir);\n expect(result.primary?.name).toBe('poetry');\n });\n\n it('detects pdm via pyproject.toml [tool.pdm]', async () => {\n fs.writeFileSync(path.join(tmpDir, 'pyproject.toml'), '[tool.pdm]\\n');\n const result = await detectPythonPackageManagers(tmpDir);\n expect(result.primary?.name).toBe('pdm');\n });\n\n it('detects pipenv via Pipfile', async () => {\n fs.writeFileSync(path.join(tmpDir, 'Pipfile'), '');\n const result = await detectPythonPackageManagers(tmpDir);\n expect(result.primary?.name).toBe('pipenv');\n expect(result.primary?.installCommand).toBe('pipenv install');\n });\n\n it('detects conda via environment.yml', async () => {\n fs.writeFileSync(path.join(tmpDir, 'environment.yml'), '');\n const result = await detectPythonPackageManagers(tmpDir);\n expect(result.primary?.name).toBe('conda');\n });\n\n it('detects pip via requirements.txt', async () => {\n fs.writeFileSync(path.join(tmpDir, 'requirements.txt'), 'flask==2.0\\n');\n const result = await detectPythonPackageManagers(tmpDir);\n expect(result.primary?.name).toBe('pip');\n expect(result.primary?.installCommand).toBe('pip install');\n });\n\n it('falls back to unknown when no markers exist', async () => {\n const result = await detectPythonPackageManagers(tmpDir);\n expect(result.primary?.name).toBe('pip');\n expect(result.primary?.label).toContain('default');\n });\n\n it('returns a recommendation string', async () => {\n fs.writeFileSync(path.join(tmpDir, 'uv.lock'), '');\n const result = await detectPythonPackageManagers(tmpDir);\n expect(result.recommendation).toContain('uv');\n expect(result.recommendation).toContain('uv add');\n });\n});\n\n// ---------------------------------------------------------------------------\n// Static helpers\n// ---------------------------------------------------------------------------\n\ndescribe('static package manager helpers', () => {\n it.each([\n { fn: composerPackageManager, name: 'composer' },\n { fn: swiftPackageManager, name: 'spm' },\n { fn: gradlePackageManager, name: 'gradle' },\n ])('$name returns valid PackageManagerInfo', async ({ fn }) => {\n const result = await fn();\n expect(result.detected).toHaveLength(1);\n expect(result.primary).toBe(result.detected[0]);\n expect(result.primary?.name).toBeTruthy();\n expect(result.primary?.installCommand).toBeTruthy();\n expect(result.recommendation).toBeTruthy();\n });\n});\n"]}