@posthog/wizard 2.7.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 (233) hide show
  1. package/README.md +11 -0
  2. package/dist/bin.js +289 -162
  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 +20 -7
  107. package/dist/src/lib/wizard-session.js +4 -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/__tests__/provisioning.test.d.ts +1 -0
  199. package/dist/src/utils/__tests__/provisioning.test.js +192 -0
  200. package/dist/src/utils/__tests__/provisioning.test.js.map +1 -0
  201. package/dist/src/utils/file-utils.d.ts +8 -0
  202. package/dist/src/utils/file-utils.js +32 -0
  203. package/dist/src/utils/file-utils.js.map +1 -1
  204. package/dist/src/utils/provisioning.d.ts +25 -0
  205. package/dist/src/utils/provisioning.js +191 -0
  206. package/dist/src/utils/provisioning.js.map +1 -0
  207. package/dist/src/utils/setup-utils.d.ts +4 -1
  208. package/dist/src/utils/setup-utils.js +46 -2
  209. package/dist/src/utils/setup-utils.js.map +1 -1
  210. package/dist/src/utils/types.d.ts +4 -0
  211. package/dist/src/utils/types.js.map +1 -1
  212. package/dist/src/utils/wizard-abort.d.ts +3 -0
  213. package/dist/src/utils/wizard-abort.js +5 -3
  214. package/dist/src/utils/wizard-abort.js.map +1 -1
  215. package/npm-shrinkwrap.json +2 -2
  216. package/package.json +1 -1
  217. package/dist/src/__tests__/run.test.js +0 -95
  218. package/dist/src/__tests__/run.test.js.map +0 -1
  219. package/dist/src/lib/__tests__/package-manager-detection.test.js.map +0 -1
  220. package/dist/src/lib/agent-interface.js.map +0 -1
  221. package/dist/src/lib/agent-runner.d.ts +0 -9
  222. package/dist/src/lib/agent-runner.js +0 -383
  223. package/dist/src/lib/agent-runner.js.map +0 -1
  224. package/dist/src/lib/commandments.js.map +0 -1
  225. package/dist/src/lib/package-manager-detection.js.map +0 -1
  226. package/dist/src/run.d.ts +0 -22
  227. package/dist/src/run.js +0 -152
  228. package/dist/src/run.js.map +0 -1
  229. /package/dist/src/{__tests__/run.test.d.ts → lib/agent/__tests__/agent-prompt.test.d.ts} +0 -0
  230. /package/dist/src/lib/{commandments.d.ts → agent/commandments.d.ts} +0 -0
  231. /package/dist/src/lib/{commandments.js → agent/commandments.js} +0 -0
  232. /package/dist/src/lib/{__tests__/package-manager-detection.test.d.ts → detection/__tests__/context.test.d.ts} +0 -0
  233. /package/dist/src/lib/{package-manager-detection.d.ts → detection/package-manager.d.ts} +0 -0
package/README.md CHANGED
@@ -33,6 +33,17 @@ npx @posthog/wizard mcp add
33
33
  npx @posthog/wizard mcp remove
34
34
  ```
35
35
 
36
+ ## Revenue Analytics
37
+
38
+ Wire up an existing PostHog + Stripe project for revenue analytics:
39
+
40
+ ```bash
41
+ npx @posthog/wizard revenue
42
+ ```
43
+
44
+ Requires PostHog and Stripe SDKs already installed. Supports `--ci` with the
45
+ same flags as the main wizard.
46
+
36
47
  # Options
37
48
 
38
49
  The following CLI arguments are available:
package/dist/bin.js CHANGED
@@ -17,10 +17,10 @@ if (!(0, semver_1.satisfies)(process.version, NODE_VERSION_RANGE)) {
17
17
  (0, logging_1.red)(`PostHog wizard requires Node.js ${NODE_VERSION_RANGE}. You are using Node.js ${process.version}. Please upgrade your Node.js version.`);
18
18
  process.exit(1);
19
19
  }
20
- const run_1 = require("./src/run");
21
20
  const environment_1 = require("./src/utils/environment");
22
21
  const ui_1 = require("./src/ui");
23
22
  const logging_ui_1 = require("./src/ui/logging-ui");
23
+ const workflow_registry_1 = require("./src/lib/workflows/workflow-registry");
24
24
  if (process.env.NODE_ENV === 'test') {
25
25
  void (async () => {
26
26
  try {
@@ -34,7 +34,35 @@ if (process.env.NODE_ENV === 'test') {
34
34
  }
35
35
  })();
36
36
  }
37
- (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
37
+ /** Shared yargs options for skill-based workflow subcommands. */
38
+ const skillSubcommandOptions = {
39
+ debug: {
40
+ default: false,
41
+ describe: 'Enable verbose logging',
42
+ type: 'boolean',
43
+ },
44
+ 'install-dir': {
45
+ describe: 'Directory to install in',
46
+ type: 'string',
47
+ },
48
+ 'local-mcp': {
49
+ default: false,
50
+ describe: 'Use local MCP server',
51
+ type: 'boolean',
52
+ },
53
+ benchmark: {
54
+ default: false,
55
+ describe: 'Run in benchmark mode',
56
+ type: 'boolean',
57
+ },
58
+ 'yara-report': {
59
+ default: false,
60
+ describe: 'Print YARA scanner summary',
61
+ type: 'boolean',
62
+ hidden: true,
63
+ },
64
+ };
65
+ const cli = (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
38
66
  .env('POSTHOG_WIZARD')
39
67
  // global options
40
68
  .options({
@@ -122,28 +150,71 @@ if (process.env.NODE_ENV === 'test') {
122
150
  type: 'boolean',
123
151
  hidden: true,
124
152
  },
153
+ skill: {
154
+ describe: 'Run a specific context-mill skill by ID\nenv: POSTHOG_WIZARD_SKILL',
155
+ type: 'string',
156
+ },
125
157
  });
126
158
  }, (argv) => {
127
159
  const options = { ...argv };
128
160
  // CI mode validation and TTY check
129
161
  if (options.ci) {
130
- // Use LoggingUI for CI mode (no dependencies, no prompts)
131
- (0, ui_1.setUI)(new logging_ui_1.LoggingUI());
132
- // Default region to 'us' if not specified
133
- if (!options.region) {
162
+ if (!options.region)
134
163
  options.region = 'us';
135
- }
136
164
  if (!options.apiKey) {
137
- (0, ui_1.getUI)().intro(`PostHog Wizard`);
165
+ (0, ui_1.setUI)(new logging_ui_1.LoggingUI());
166
+ (0, ui_1.getUI)().intro('PostHog Wizard');
138
167
  (0, ui_1.getUI)().log.error('CI mode requires --api-key (personal API key phx_xxx)');
139
168
  process.exit(1);
169
+ return;
140
170
  }
141
171
  if (!options.installDir) {
142
- (0, ui_1.getUI)().intro(`PostHog Wizard`);
143
- (0, ui_1.getUI)().log.error('CI mode requires --install-dir (directory to install PostHog in)');
172
+ (0, ui_1.setUI)(new logging_ui_1.LoggingUI());
173
+ (0, ui_1.getUI)().intro('PostHog Wizard');
174
+ (0, ui_1.getUI)().log.error('CI mode requires --install-dir (directory to install in)');
144
175
  process.exit(1);
176
+ return;
145
177
  }
146
- void (0, run_1.runWizard)(options);
178
+ void (async () => {
179
+ const { posthogIntegrationConfig } = await import('./src/lib/workflows/posthog-integration/index.js');
180
+ const { FRAMEWORK_REGISTRY } = await import('./src/lib/registry.js');
181
+ const { detectFramework, gatherFrameworkContext } = await import('./src/lib/detection/index.js');
182
+ const { analytics } = await import('./src/utils/analytics.js');
183
+ const { wizardAbort } = await import('./src/utils/wizard-abort.js');
184
+ // preRun: honor --integration, else auto-detect, then gather
185
+ // framework context. Bypasses onReady hooks by design.
186
+ runWizardCI(posthogIntegrationConfig, options, async (session) => {
187
+ const integration = session.integration ??
188
+ (await detectFramework(session.installDir));
189
+ if (!integration) {
190
+ await wizardAbort({
191
+ message: 'Could not auto-detect your framework. Please specify --integration on the command line.',
192
+ });
193
+ return;
194
+ }
195
+ session.integration = integration;
196
+ analytics.setTag('integration', integration);
197
+ const frameworkConfig = FRAMEWORK_REGISTRY[integration];
198
+ session.frameworkConfig = frameworkConfig;
199
+ const context = await gatherFrameworkContext(frameworkConfig, {
200
+ installDir: session.installDir,
201
+ debug: session.debug,
202
+ forceInstall: session.forceInstall,
203
+ default: false,
204
+ signup: session.signup,
205
+ localMcp: session.localMcp,
206
+ ci: true,
207
+ menu: session.menu,
208
+ benchmark: session.benchmark,
209
+ yaraReport: session.yaraReport,
210
+ });
211
+ for (const [key, value] of Object.entries(context)) {
212
+ if (!(key in session.frameworkContext)) {
213
+ session.frameworkContext[key] = value;
214
+ }
215
+ }
216
+ });
217
+ })();
147
218
  }
148
219
  else if ((0, environment_1.isNonInteractiveEnvironment)()) {
149
220
  // Non-interactive non-CI: error out
@@ -162,158 +233,32 @@ if (process.env.NODE_ENV === 'test') {
162
233
  startPlayground(WIZARD_VERSION);
163
234
  })();
164
235
  }
236
+ else if (options.skill) {
237
+ // Run a specific skill by ID
238
+ void (async () => {
239
+ const { createSkillWorkflow } = await import('./src/lib/workflows/agent-skill/index.js');
240
+ const skillId = options.skill;
241
+ const config = createSkillWorkflow({
242
+ skillId,
243
+ command: 'skill',
244
+ flowKey: 'agent-skill',
245
+ description: `Run skill: ${skillId}`,
246
+ integrationLabel: skillId,
247
+ successMessage: `${skillId} completed!`,
248
+ reportFile: `posthog-${skillId}-report.md`,
249
+ docsUrl: 'https://posthog.com/docs',
250
+ spinnerMessage: `Running ${skillId}...`,
251
+ estimatedDurationMinutes: 5,
252
+ });
253
+ runWizard(config, options);
254
+ })();
255
+ }
165
256
  else {
166
- // Interactive TTY: launch the Ink TUI
257
+ // Interactive TTY: run core-integration through the unified workflow path.
258
+ // Same codepath as `npx @posthog/wizard integrate`.
167
259
  void (async () => {
168
- try {
169
- const { startTUI } = await import('./src/ui/tui/start-tui.js');
170
- const { buildSession } = await import('./src/lib/wizard-session.js');
171
- const tui = startTUI(WIZARD_VERSION);
172
- // Build session from CLI args and attach to store
173
- const session = buildSession({
174
- debug: options.debug,
175
- forceInstall: options.forceInstall,
176
- installDir: options.installDir,
177
- ci: false,
178
- signup: options.signup,
179
- localMcp: options.localMcp,
180
- apiKey: options.apiKey,
181
- menu: options.menu,
182
- integration: options.integration,
183
- benchmark: options.benchmark,
184
- yaraReport: options.yaraReport,
185
- projectId: options.projectId,
186
- });
187
- tui.store.session = session;
188
- // Detect framework while IntroScreen shows its spinner.
189
- // Runs concurrently — IntroScreen reacts when detection completes.
190
- const { FRAMEWORK_REGISTRY } = (await import('./src/lib/registry.js'));
191
- const { detectIntegration } = (await import('./src/run.js'));
192
- const installDir = session.installDir ?? process.cwd();
193
- const { DETECTION_TIMEOUT_MS } = (await import('./src/lib/constants.js'));
194
- const detectedIntegration = await Promise.race([
195
- detectIntegration(installDir),
196
- new Promise((resolve) => setTimeout(() => resolve(undefined), DETECTION_TIMEOUT_MS)),
197
- ]);
198
- if (detectedIntegration) {
199
- const config = FRAMEWORK_REGISTRY[detectedIntegration];
200
- // Run gatherContext for the friendly variant label
201
- if (config.metadata.gatherContext) {
202
- try {
203
- const context = await Promise.race([
204
- config.metadata.gatherContext({
205
- installDir,
206
- debug: session.debug,
207
- forceInstall: session.forceInstall,
208
- default: false,
209
- signup: session.signup,
210
- localMcp: session.localMcp,
211
- ci: session.ci,
212
- menu: session.menu,
213
- benchmark: session.benchmark,
214
- yaraReport: session.yaraReport,
215
- }),
216
- new Promise((resolve) => setTimeout(() => resolve({}), DETECTION_TIMEOUT_MS)),
217
- ]);
218
- for (const [key, value] of Object.entries(context)) {
219
- if (!(key in session.frameworkContext)) {
220
- tui.store.setFrameworkContext(key, value);
221
- }
222
- }
223
- }
224
- catch {
225
- // Detection failed — will show generic name
226
- }
227
- }
228
- tui.store.setFrameworkConfig(detectedIntegration, config);
229
- if (!session.detectedFrameworkLabel) {
230
- tui.store.setDetectedFramework(config.metadata.name);
231
- }
232
- // Early version check — surface on IntroScreen before user proceeds
233
- if (config.detection.minimumVersion &&
234
- config.detection.getInstalledVersion) {
235
- const semver = await import('semver');
236
- const version = await config.detection.getInstalledVersion({
237
- installDir,
238
- debug: session.debug,
239
- forceInstall: session.forceInstall,
240
- default: false,
241
- signup: session.signup,
242
- localMcp: session.localMcp,
243
- ci: session.ci,
244
- menu: session.menu,
245
- benchmark: session.benchmark,
246
- yaraReport: session.yaraReport,
247
- });
248
- if (version) {
249
- const coerced = semver.coerce(version);
250
- if (coerced &&
251
- semver.lt(coerced, config.detection.minimumVersion)) {
252
- tui.store.setUnsupportedVersion({
253
- current: version,
254
- minimum: config.detection.minimumVersion,
255
- docsUrl: config.metadata.unsupportedVersionDocsUrl ??
256
- config.metadata.docsUrl,
257
- });
258
- }
259
- }
260
- }
261
- }
262
- // Feature discovery — deterministic scan of package.json deps
263
- try {
264
- const { readFileSync } = await import('fs');
265
- const pkgPath = require('path').join(installDir, 'package.json');
266
- const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
267
- const allDeps = {
268
- ...pkg.dependencies,
269
- ...pkg.devDependencies,
270
- };
271
- const depNames = Object.keys(allDeps);
272
- const { DiscoveredFeature } = await import('./src/lib/wizard-session.js');
273
- if (depNames.some((d) => ['stripe', '@stripe/stripe-js'].includes(d))) {
274
- tui.store.addDiscoveredFeature(DiscoveredFeature.Stripe);
275
- }
276
- // LLM SDK detection — sourced from PostHog LLM analytics skill
277
- const LLM_PACKAGES = [
278
- 'openai',
279
- '@anthropic-ai/sdk',
280
- 'ai',
281
- '@ai-sdk/openai',
282
- 'langchain',
283
- '@langchain/openai',
284
- '@langchain/langgraph',
285
- '@google/generative-ai',
286
- '@google/genai',
287
- '@instructor-ai/instructor',
288
- '@mastra/core',
289
- 'portkey-ai',
290
- ];
291
- if (depNames.some((d) => LLM_PACKAGES.includes(d))) {
292
- tui.store.addDiscoveredFeature(DiscoveredFeature.LLM);
293
- }
294
- }
295
- catch {
296
- // No package.json or parse error — skip feature discovery
297
- }
298
- // Signal detection is done — IntroScreen shows picker or results
299
- tui.store.setDetectionComplete();
300
- // Wait for IntroScreen confirmation
301
- await tui.waitForSetup();
302
- // Ensure health check has completed before starting the wizard.
303
- // The flow gate on Intro (readinessResult !== null) keeps the
304
- // TUI on IntroScreen until this resolves. If blocking, the
305
- // outage overlay was already pushed in the .then() callback.
306
- await tui.store.healthGateComplete;
307
- await (0, run_1.runWizard)(options, tui.store.session);
308
- // Keep the outro screen visible — let process.exit() handle cleanup
309
- }
310
- catch (err) {
311
- // TUI unavailable (e.g., in test environment) — continue with default UI
312
- if (process.env.DEBUG || process.env.POSTHOG_WIZARD_DEBUG) {
313
- console.error('TUI init failed:', err); // eslint-disable-line no-console
314
- }
315
- await (0, run_1.runWizard)(options);
316
- }
260
+ const { posthogIntegrationConfig } = await import('./src/lib/workflows/posthog-integration/index.js');
261
+ runWizard(posthogIntegrationConfig, options);
317
262
  })();
318
263
  }
319
264
  })
@@ -403,10 +348,192 @@ if (process.env.NODE_ENV === 'test') {
403
348
  })
404
349
  .demandCommand(1, 'You must specify a subcommand (add or remove)')
405
350
  .help();
406
- })
351
+ });
352
+ // ── Skill-based workflow subcommands (derived from registry) ─────────
353
+ for (const wfConfig of (0, workflow_registry_1.getSubcommandWorkflows)()) {
354
+ cli.command(wfConfig.command, wfConfig.description, (y) => y.options(skillSubcommandOptions), (argv) => {
355
+ const options = { ...argv };
356
+ if (options.ci) {
357
+ runWizardCI(wfConfig, options);
358
+ }
359
+ else {
360
+ runWizard(wfConfig, options);
361
+ }
362
+ });
363
+ }
364
+ cli
407
365
  .help()
408
366
  .alias('help', 'h')
409
367
  .version()
410
368
  .alias('version', 'v')
411
369
  .wrap(process.stdout.isTTY ? yargs_1.default.terminalWidth() : 80).argv;
370
+ /**
371
+ * Run a full wizard workflow in the TUI. Handles the full lifecycle: start TUI,
372
+ * build session, run detection, wait for intro gate, execute the
373
+ * agent pipeline, wait for outro dismissal, then exit.
374
+ */
375
+ function runWizard(config, options) {
376
+ void (async () => {
377
+ try {
378
+ const installDir = options.installDir || process.cwd();
379
+ const { startTUI } = await import('./src/ui/tui/start-tui.js');
380
+ const { buildSession } = await import('./src/lib/wizard-session.js');
381
+ // flowKey values match Flow enum values by convention
382
+ const tui = startTUI(WIZARD_VERSION, config.flowKey);
383
+ const session = buildSession({
384
+ debug: options.debug,
385
+ forceInstall: options.forceInstall,
386
+ localMcp: options.localMcp,
387
+ installDir,
388
+ ci: false,
389
+ signup: options.signup,
390
+ apiKey: options.apiKey,
391
+ projectId: options.projectId,
392
+ menu: options.menu,
393
+ integration: options.integration,
394
+ benchmark: options.benchmark,
395
+ yaraReport: options.yaraReport,
396
+ });
397
+ // Set workflow metadata for TUI display
398
+ session.workflowLabel = config.flowKey;
399
+ const runDef = typeof config.run === 'object' ? config.run : null;
400
+ session.skillId = runDef?.skillId ?? null;
401
+ tui.store.session = session;
402
+ await tui.store.runReadyHooks();
403
+ await tui.store.getGate('intro');
404
+ const { runAgent } = await import('./src/lib/agent/agent-runner.js');
405
+ await runAgent(config, tui.store.session);
406
+ tui.store.onEnterScreen('outro', () => {
407
+ // Screen is already outro — listen for dismissal
408
+ });
409
+ await new Promise((resolve) => {
410
+ const unsub = tui.store.subscribe(() => {
411
+ if (tui.store.session.outroDismissed) {
412
+ unsub();
413
+ resolve();
414
+ }
415
+ });
416
+ if (tui.store.session.outroDismissed) {
417
+ unsub();
418
+ resolve();
419
+ }
420
+ });
421
+ process.exit(0);
422
+ }
423
+ catch (err) {
424
+ if (process.env.DEBUG || process.env.POSTHOG_WIZARD_DEBUG) {
425
+ console.error('TUI init failed:', err); // eslint-disable-line no-console
426
+ }
427
+ }
428
+ })();
429
+ }
430
+ /**
431
+ * CI-mode pipeline shared by every non-interactive entry point.
432
+ *
433
+ * Validates flags, builds a `ci:true` session, runs `preRun` (or the
434
+ * workflow's `onReady` hooks by default), executes `runAgent`, and
435
+ * routes any failure through `wizardAbort`. `wizardAbort` owns all
436
+ * exits — never add a raw `process.exit` here.
437
+ */
438
+ function runWizardCI(config, options, preRun) {
439
+ (0, ui_1.setUI)(new logging_ui_1.LoggingUI());
440
+ if (!options.region)
441
+ options.region = 'us';
442
+ if (!options.apiKey) {
443
+ (0, ui_1.getUI)().intro('PostHog Wizard');
444
+ (0, ui_1.getUI)().log.error('CI mode requires --api-key (personal API key phx_xxx)');
445
+ process.exit(1);
446
+ }
447
+ if (!options.installDir) {
448
+ (0, ui_1.getUI)().intro('PostHog Wizard');
449
+ (0, ui_1.getUI)().log.error('CI mode requires --install-dir (directory to install in)');
450
+ process.exit(1);
451
+ }
452
+ void (async () => {
453
+ const path = await import('path');
454
+ const { buildSession } = await import('./src/lib/wizard-session.js');
455
+ const { readEnvironment } = await import('./src/utils/environment.js');
456
+ const { readApiKeyFromEnv } = await import('./src/utils/env-api-key.js');
457
+ const { configureLogFileFromEnvironment, logToFile } = await import('./src/utils/debug.js');
458
+ const { wizardAbort, WizardError } = await import('./src/utils/wizard-abort.js');
459
+ configureLogFileFromEnvironment();
460
+ const env = readEnvironment();
461
+ const apiKey = options.apiKey ?? readApiKeyFromEnv() ?? undefined;
462
+ const installDir = path.isAbsolute(options.installDir)
463
+ ? options.installDir
464
+ : path.join(process.cwd(), options.installDir);
465
+ const session = buildSession({
466
+ debug: options.debug,
467
+ forceInstall: options.forceInstall,
468
+ installDir,
469
+ ci: true,
470
+ signup: options.signup,
471
+ localMcp: options.localMcp,
472
+ apiKey,
473
+ menu: options.menu,
474
+ integration: options.integration, // eslint-disable-line @typescript-eslint/no-explicit-any
475
+ projectId: options.projectId,
476
+ benchmark: options.benchmark,
477
+ yaraReport: options.yaraReport,
478
+ ...env,
479
+ });
480
+ session.workflowLabel = config.flowKey;
481
+ const runDef = typeof config.run === 'object' ? config.run : null;
482
+ session.skillId = runDef?.skillId ?? null;
483
+ (0, ui_1.getUI)().intro('Welcome to the PostHog setup wizard');
484
+ (0, ui_1.getUI)().log.info(`Running ${config.flowKey} in CI mode`);
485
+ try {
486
+ if (preRun) {
487
+ await preRun(session);
488
+ }
489
+ else {
490
+ // Run onReady hooks against a minimal store-less context.
491
+ const readyCtx = {
492
+ session,
493
+ setFrameworkContext: (key, value) => {
494
+ session.frameworkContext[key] = value;
495
+ },
496
+ setFrameworkConfig: () => undefined,
497
+ setDetectedFramework: () => undefined,
498
+ setUnsupportedVersion: () => undefined,
499
+ addDiscoveredFeature: () => undefined,
500
+ setDetectionComplete: () => undefined,
501
+ };
502
+ for (const step of config.steps) {
503
+ if (step.onReady) {
504
+ await step.onReady(readyCtx);
505
+ }
506
+ }
507
+ // Surface detectError written by the workflow's detect hook.
508
+ const detectError = session.frameworkContext.detectError;
509
+ if (detectError) {
510
+ await wizardAbort({
511
+ message: `Prerequisites not met: ${detectError.kind}\n\nSee ${runDef?.docsUrl ?? 'https://posthog.com/docs'}`,
512
+ error: new WizardError(`${config.flowKey} prerequisites failed`, {
513
+ integration: config.flowKey,
514
+ detect_error_kind: detectError.kind,
515
+ }),
516
+ });
517
+ }
518
+ }
519
+ const { runAgent } = await import('./src/lib/agent/agent-runner.js');
520
+ await runAgent(config, session);
521
+ }
522
+ catch (error) {
523
+ const errorMessage = error instanceof Error ? error.message : String(error);
524
+ const errorStack = error instanceof Error && error.stack ? error.stack : undefined;
525
+ logToFile(`[bin.ts CI] ERROR: ${errorMessage}`);
526
+ if (errorStack)
527
+ logToFile(`[bin.ts CI] STACK: ${errorStack}`);
528
+ const debugInfo = session.debug && errorStack ? `\n\n${errorStack}` : '';
529
+ const docsUrl = session.frameworkConfig?.metadata.docsUrl ??
530
+ runDef?.docsUrl ??
531
+ 'https://posthog.com/docs';
532
+ await wizardAbort({
533
+ message: `Something went wrong: ${errorMessage}\n\nYou can read the documentation at ${docsUrl} to set up manually.${debugInfo}`,
534
+ error: error,
535
+ });
536
+ }
537
+ })();
538
+ }
412
539
  //# sourceMappingURL=bin.js.map