@posthog/wizard 2.10.4 → 2.12.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 (90) hide show
  1. package/README.md +48 -7
  2. package/dist/{McpScreen-LqnNwEfV.js → AuditChecksViewer-DsfXIO9e.js} +475 -36
  3. package/dist/AuditChecksViewer-DsfXIO9e.js.map +1 -0
  4. package/dist/{add-mcp-server-to-clients-lfUH2pdU.js → add-mcp-server-to-clients-BKoew3aT.js} +157 -125
  5. package/dist/add-mcp-server-to-clients-BKoew3aT.js.map +1 -0
  6. package/dist/{readiness-Cep84RsR.js → agent-interface-D5W9BAB2.js} +329 -464
  7. package/dist/agent-interface-D5W9BAB2.js.map +1 -0
  8. package/dist/{agent-runner-DHtcWn15.js → agent-runner-B8Cx6X6x.js} +22 -31
  9. package/dist/agent-runner-B8Cx6X6x.js.map +1 -0
  10. package/dist/analytics-DmD31Ssc.js +123 -0
  11. package/dist/analytics-DmD31Ssc.js.map +1 -0
  12. package/dist/analytics-JDitS2JI.js +2 -0
  13. package/dist/bin.js +521 -46
  14. package/dist/bin.js.map +1 -1
  15. package/dist/debug-Bkaqv1ab.js +686 -0
  16. package/dist/debug-Bkaqv1ab.js.map +1 -0
  17. package/dist/{debug-CIyf0ZGx.js → debug-I5sRZubJ.js} +1 -1
  18. package/dist/{defaults-DoVkE0gW.js → defaults-GbLPuHxj.js} +8 -8
  19. package/dist/defaults-GbLPuHxj.js.map +1 -0
  20. package/dist/detection-C_RfYYDe.js +206 -0
  21. package/dist/detection-C_RfYYDe.js.map +1 -0
  22. package/dist/{env-api-key-K8TdTDII.js → env-api-key-D5G2PrXW.js} +1 -1
  23. package/dist/{env-api-key-K8TdTDII.js.map → env-api-key-D5G2PrXW.js.map} +1 -1
  24. package/dist/file-8iNrXHkG.js +16 -0
  25. package/dist/file-8iNrXHkG.js.map +1 -0
  26. package/dist/{file-utils-BWneZy6p.js → file-utils-DnTSiTJw.js} +1 -1
  27. package/dist/{file-utils-BWneZy6p.js.map → file-utils-DnTSiTJw.js.map} +1 -1
  28. package/dist/package-json-BzVey4Bd.js +2 -0
  29. package/dist/{package-json-Ctq6LSl8.js → package-json-F_7oktsp.js} +1 -1
  30. package/dist/{package-json-Ctq6LSl8.js.map → package-json-F_7oktsp.js.map} +1 -1
  31. package/dist/{package-manager-CwU26DwX.js → package-manager-qxP2PpM_.js} +2 -2
  32. package/dist/{package-manager-CwU26DwX.js.map → package-manager-qxP2PpM_.js.map} +1 -1
  33. package/dist/paths-DJS47p5x.js +26 -0
  34. package/dist/paths-DJS47p5x.js.map +1 -0
  35. package/dist/{posthog-integration-HBDZrREG.js → posthog-integration-DX77Msto.js} +43 -14
  36. package/dist/posthog-integration-DX77Msto.js.map +1 -0
  37. package/dist/posthog-vm0k9PKS.js +11 -0
  38. package/dist/posthog-vm0k9PKS.js.map +1 -0
  39. package/dist/provisioning-CHfTOEvg.js +2 -0
  40. package/dist/provisioning-DUj285NO.js +166 -0
  41. package/dist/provisioning-DUj285NO.js.map +1 -0
  42. package/dist/{registry-BIV1wRpo.js → registry-CCtIsqb8.js} +5 -6
  43. package/dist/{registry-BIV1wRpo.js.map → registry-CCtIsqb8.js.map} +1 -1
  44. package/dist/{router-CXjdWNh2.js → router-BTfmEDDJ.js} +4 -3
  45. package/dist/router-BTfmEDDJ.js.map +1 -0
  46. package/dist/{setup-utils-CHojnr4N.js → setup-utils-Bv8z6HMb.js} +17 -150
  47. package/dist/setup-utils-Bv8z6HMb.js.map +1 -0
  48. package/dist/setup-utils-CoX-vLgw.js +2 -0
  49. package/dist/{start-playground-D1iLBvqF.js → start-playground-DYNQ8rOz.js} +181 -9
  50. package/dist/start-playground-DYNQ8rOz.js.map +1 -0
  51. package/dist/{start-tui-DkT_H5zx.js → start-tui-DleQG3La.js} +1290 -163
  52. package/dist/start-tui-DleQG3La.js.map +1 -0
  53. package/dist/{steps-zpqG7W08.js → steps-C-syS8if.js} +8 -8
  54. package/dist/steps-C-syS8if.js.map +1 -0
  55. package/dist/task-stream-CX7Uf6EM.js +61 -0
  56. package/dist/task-stream-CX7Uf6EM.js.map +1 -0
  57. package/dist/{telemetry-CPoSyK0a.js → telemetry-DHZfjgqx.js} +2 -2
  58. package/dist/{telemetry-CPoSyK0a.js.map → telemetry-DHZfjgqx.js.map} +1 -1
  59. package/dist/{wizard-abort-BcEPhAxY.js → wizard-abort-DIhFXJ5N.js} +1 -1
  60. package/dist/{wizard-abort-DKctLd33.js → wizard-abort-DfhWuzaw.js} +6 -4
  61. package/dist/{wizard-abort-DKctLd33.js.map → wizard-abort-DfhWuzaw.js.map} +1 -1
  62. package/dist/wizard-session-BQC9vy9Z.js +2 -0
  63. package/dist/{wizard-session-Db6R023m.js → wizard-session-BcNJTl2I.js} +1 -1
  64. package/dist/{wizard-session-Db6R023m.js.map → wizard-session-BcNJTl2I.js.map} +1 -1
  65. package/dist/wizard-ui-YdGFRyu_.js +14 -0
  66. package/dist/wizard-ui-YdGFRyu_.js.map +1 -0
  67. package/npm-shrinkwrap.json +2 -2
  68. package/package.json +1 -1
  69. package/dist/McpScreen-LqnNwEfV.js.map +0 -1
  70. package/dist/add-mcp-server-to-clients-lfUH2pdU.js.map +0 -1
  71. package/dist/agent-runner-DHtcWn15.js.map +0 -1
  72. package/dist/agent-skill-BVjJqol6.js +0 -59
  73. package/dist/agent-skill-BVjJqol6.js.map +0 -1
  74. package/dist/analytics-Cm6i5_gc.js +0 -207
  75. package/dist/analytics-Cm6i5_gc.js.map +0 -1
  76. package/dist/analytics-CviQ_A9M.js +0 -2
  77. package/dist/debug-CyJ_3dTP.js +0 -201
  78. package/dist/debug-CyJ_3dTP.js.map +0 -1
  79. package/dist/defaults-DoVkE0gW.js.map +0 -1
  80. package/dist/detection-gcQwPKPu.js +0 -122
  81. package/dist/detection-gcQwPKPu.js.map +0 -1
  82. package/dist/package-json-BQgl5C3Z.js +0 -2
  83. package/dist/posthog-integration-HBDZrREG.js.map +0 -1
  84. package/dist/readiness-Cep84RsR.js.map +0 -1
  85. package/dist/router-CXjdWNh2.js.map +0 -1
  86. package/dist/setup-utils-CHojnr4N.js.map +0 -1
  87. package/dist/start-playground-D1iLBvqF.js.map +0 -1
  88. package/dist/start-tui-DkT_H5zx.js.map +0 -1
  89. package/dist/steps-zpqG7W08.js.map +0 -1
  90. package/dist/wizard-session-y7nf6aKH.js +0 -2
package/dist/bin.js CHANGED
@@ -1,16 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
  import { t as __exportAll } from "./rolldown-runtime-B_-DWIq7.js";
3
- import { c as getUI, f as runtimeEnv, l as setUI, p as red, u as LoggingUI } from "./debug-CyJ_3dTP.js";
4
- import { T as VERSION } from "./analytics-Cm6i5_gc.js";
5
- import "./setup-utils-CHojnr4N.js";
6
- import { t as posthogIntegrationConfig } from "./posthog-integration-HBDZrREG.js";
7
- import { t as IGNORED_DIRS } from "./file-utils-BWneZy6p.js";
3
+ import { D as POSTHOG_DOCS_URL, G as VERSION, K as red, W as runtimeEnv, c as getUI, l as setUI, s as logToFile, u as LoggingUI, z as WIZARD_USER_AGENT } from "./debug-Bkaqv1ab.js";
4
+ import { n as analytics } from "./analytics-DmD31Ssc.js";
5
+ import { u as handleApiError } from "./setup-utils-Bv8z6HMb.js";
6
+ import { h as AUDIT_REPORT_FILE, m as AUDIT_CHECKS_KEY, p as AUDIT_CHECKS_FILE } from "./agent-interface-D5W9BAB2.js";
7
+ import { n as posthogIntegrationConfig } from "./posthog-integration-DX77Msto.js";
8
+ import { t as IGNORED_DIRS } from "./file-utils-DnTSiTJw.js";
8
9
  import { satisfies } from "semver";
9
10
  import yargs from "yargs";
10
11
  import { hideBin } from "yargs/helpers";
11
12
  import readEnvModule from "read-env";
12
- import { existsSync, readFileSync, readdirSync, statSync } from "fs";
13
- import { join, relative } from "path";
13
+ import fs, { existsSync, readFileSync, readdirSync, statSync } from "fs";
14
+ import path, { join, relative } from "path";
15
+ import axios from "axios";
16
+ import { z } from "zod";
14
17
  import "fast-glob";
15
18
  //#region src/utils/environment.ts
16
19
  var environment_exports = /* @__PURE__ */ __exportAll({
@@ -160,8 +163,8 @@ function detectRevenuePrerequisites(session, setFrameworkContext) {
160
163
  setFrameworkContext("detectedPackagePaths", matches.filter((m) => m.posthogSdks.length > 0 || m.stripeSdks.length > 0).map((m) => m.path));
161
164
  }
162
165
  //#endregion
163
- //#region src/lib/workflows/workflow-registry.ts
164
- const WORKFLOW_REGISTRY = [posthogIntegrationConfig, {
166
+ //#region src/lib/workflows/revenue-analytics/index.ts
167
+ const revenueAnalyticsConfig = {
165
168
  command: "revenue",
166
169
  description: "Set up PostHog revenue analytics (e.g. Stripe integration)",
167
170
  flowKey: "revenue-analytics-setup",
@@ -213,7 +216,348 @@ const WORKFLOW_REGISTRY = [posthogIntegrationConfig, {
213
216
  abortCases: REVENUE_ABORT_CASES
214
217
  },
215
218
  requires: ["posthog-integration"]
219
+ };
220
+ //#endregion
221
+ //#region src/lib/workflows/agent-skill/steps.ts
222
+ const AGENT_SKILL_STEPS = [
223
+ {
224
+ id: "intro",
225
+ label: "Welcome",
226
+ screen: "agent-skill-intro",
227
+ gate: (session) => session.setupConfirmed
228
+ },
229
+ {
230
+ id: "auth",
231
+ label: "Authentication",
232
+ screen: "auth",
233
+ isComplete: (session) => session.credentials !== null
234
+ },
235
+ {
236
+ id: "run",
237
+ label: "Running",
238
+ screen: "run",
239
+ isComplete: (session) => session.runPhase === "completed" || session.runPhase === "error"
240
+ },
241
+ {
242
+ id: "outro",
243
+ label: "Done",
244
+ screen: "outro",
245
+ isComplete: (session) => session.outroDismissed
246
+ },
247
+ {
248
+ id: "skills",
249
+ label: "Skills",
250
+ screen: "keep-skills"
251
+ }
252
+ ];
253
+ //#endregion
254
+ //#region src/lib/workflows/agent-skill/index.ts
255
+ var agent_skill_exports = /* @__PURE__ */ __exportAll({ createSkillWorkflow: () => createSkillWorkflow });
256
+ function createSkillWorkflow(opts) {
257
+ return {
258
+ command: opts.command,
259
+ description: opts.description,
260
+ flowKey: opts.flowKey,
261
+ steps: AGENT_SKILL_STEPS,
262
+ run: {
263
+ skillId: opts.skillId,
264
+ integrationLabel: opts.integrationLabel,
265
+ customPrompt: opts.customPrompt ? () => opts.customPrompt : void 0,
266
+ successMessage: opts.successMessage,
267
+ reportFile: opts.reportFile,
268
+ docsUrl: opts.docsUrl,
269
+ spinnerMessage: opts.spinnerMessage,
270
+ estimatedDurationMinutes: opts.estimatedDurationMinutes,
271
+ buildOutroData: opts.buildOutroData,
272
+ abortCases: opts.abortCases
273
+ },
274
+ requires: opts.requires
275
+ };
276
+ }
277
+ //#endregion
278
+ //#region src/lib/workflows/audit/detect.ts
279
+ /** `[ABORT] <reason>` cases the audit skill can emit. Reason strings are
280
+ * defined in the skill's `Abort statuses` section. */
281
+ const AUDIT_ABORT_CASES = [{
282
+ match: /^no posthog sdk found$/i,
283
+ message: "No PostHog SDK found",
284
+ body: "The audit needs an existing PostHog integration to review. No PostHog SDK appears in this project’s dependency manifests. Run the basic integration workflow to install PostHog first, then re-run the audit.",
285
+ docsUrl: "https://posthog.com/docs/getting-started/install"
216
286
  }];
287
+ //#endregion
288
+ //#region src/lib/workflows/audit/seed.ts
289
+ /** The 10 data-integrity checks the audit runs. */
290
+ const AUDIT_SEED_CHECKS = [
291
+ {
292
+ id: "sdk-installed",
293
+ area: "Installation",
294
+ label: "PostHog SDK installed",
295
+ status: "pending"
296
+ },
297
+ {
298
+ id: "sdk-up-to-date",
299
+ area: "Installation",
300
+ label: "SDK version up to date",
301
+ status: "pending"
302
+ },
303
+ {
304
+ id: "init-correct",
305
+ area: "Installation",
306
+ label: "Initialization is correct",
307
+ status: "pending"
308
+ },
309
+ {
310
+ id: "identify-stable-distinct-id",
311
+ area: "Identification",
312
+ label: "Stable distinct_id (not session UUID)",
313
+ status: "pending"
314
+ },
315
+ {
316
+ id: "identify-not-late",
317
+ area: "Identification",
318
+ label: "identify() called before captures / flag evals",
319
+ status: "pending"
320
+ },
321
+ {
322
+ id: "cross-runtime-distinct-id",
323
+ area: "Identification",
324
+ label: "Same distinct_id across client and server",
325
+ status: "pending"
326
+ },
327
+ {
328
+ id: "identify-reset-on-logout",
329
+ area: "Identification",
330
+ label: "reset() called on logout / account switch",
331
+ status: "pending"
332
+ },
333
+ {
334
+ id: "capture-event-names-static",
335
+ area: "Event Capture",
336
+ label: "Event names are static and consistent",
337
+ status: "pending"
338
+ },
339
+ {
340
+ id: "capture-uses-proxy",
341
+ area: "Event Capture",
342
+ label: "Captures route through a reverse proxy",
343
+ status: "pending"
344
+ },
345
+ {
346
+ id: "capture-growth-events",
347
+ area: "Event Capture",
348
+ label: "Key activation events captured",
349
+ status: "pending"
350
+ }
351
+ ];
352
+ /** Atomically write the seeded ledger to the project's audit checks file. */
353
+ function seedAuditLedger(installDir) {
354
+ const target = path.join(installDir, AUDIT_CHECKS_FILE);
355
+ const tmp = `${target}.tmp`;
356
+ fs.writeFileSync(tmp, JSON.stringify(AUDIT_SEED_CHECKS, null, 2), "utf8");
357
+ fs.renameSync(tmp, target);
358
+ logToFile(`seedAuditLedger: wrote ${AUDIT_SEED_CHECKS.length} entries to ${target}`);
359
+ }
360
+ //#endregion
361
+ //#region src/lib/workflows/audit/index.ts
362
+ /** Audit-specific screens for the shared agent-skill pipeline. */
363
+ const AUDIT_SCREEN_BY_STEP = {
364
+ intro: "audit-intro",
365
+ run: "audit-run",
366
+ outro: "audit-outro"
367
+ };
368
+ const seedBeforeAuditRun = (session) => {
369
+ seedAuditLedger(session.installDir);
370
+ session.frameworkContext[AUDIT_CHECKS_KEY] = AUDIT_SEED_CHECKS;
371
+ };
372
+ const withAuditScreens = (steps) => steps.map((step) => {
373
+ const override = AUDIT_SCREEN_BY_STEP[step.id];
374
+ return override ? {
375
+ ...step,
376
+ screen: override
377
+ } : step;
378
+ });
379
+ const auditSteps = withAuditScreens(AGENT_SKILL_STEPS);
380
+ const baseConfig = createSkillWorkflow({
381
+ skillId: "audit",
382
+ command: "audit",
383
+ flowKey: "audit",
384
+ description: "Audit an existing PostHog integration for correctness and best practices",
385
+ integrationLabel: "audit",
386
+ customPrompt: "Run a comprehensive audit of the existing PostHog integration. Follow the skill workflow steps in order. Do not modify any project files — only create the final audit report.",
387
+ successMessage: "Audit complete! You can view the audit report at ./posthog-audit-report.md",
388
+ reportFile: AUDIT_REPORT_FILE,
389
+ docsUrl: "https://posthog.com/docs/product-analytics/best-practices",
390
+ spinnerMessage: "Auditing PostHog integration...",
391
+ estimatedDurationMinutes: 5,
392
+ requires: ["posthog-integration"],
393
+ abortCases: AUDIT_ABORT_CASES
394
+ });
395
+ const auditRun = async (session) => {
396
+ seedBeforeAuditRun(session);
397
+ if (!baseConfig.run) throw new Error("Audit workflow has no run configuration.");
398
+ return typeof baseConfig.run === "function" ? baseConfig.run(session) : baseConfig.run;
399
+ };
400
+ const auditConfig = {
401
+ ...baseConfig,
402
+ steps: auditSteps,
403
+ run: auditRun
404
+ };
405
+ //#endregion
406
+ //#region src/lib/workflows/posthog-doctor/steps.ts
407
+ const POSTHOG_DOCTOR_WORKFLOW = [
408
+ {
409
+ id: "intro",
410
+ label: "Welcome",
411
+ screen: "doctor-intro",
412
+ gate: (session) => session.setupConfirmed
413
+ },
414
+ {
415
+ id: "auth",
416
+ label: "Authentication",
417
+ screen: "auth",
418
+ isComplete: (session) => session.credentials !== null
419
+ },
420
+ {
421
+ id: "report",
422
+ label: "Doctor report",
423
+ screen: "doctor-report",
424
+ isComplete: (session) => session.outroData !== null
425
+ },
426
+ {
427
+ id: "outro",
428
+ label: "Done",
429
+ screen: "outro",
430
+ isComplete: (session) => session.outroDismissed
431
+ }
432
+ ];
433
+ //#endregion
434
+ //#region src/lib/workflows/posthog-doctor/types.ts
435
+ const HealthIssueSeveritySchema = z.enum([
436
+ "critical",
437
+ "warning",
438
+ "info"
439
+ ]);
440
+ const HealthIssueStatusSchema = z.enum(["active", "resolved"]);
441
+ const HealthIssueSchema = z.object({
442
+ id: z.string(),
443
+ kind: z.string(),
444
+ severity: HealthIssueSeveritySchema,
445
+ status: HealthIssueStatusSchema,
446
+ dismissed: z.boolean(),
447
+ created_at: z.string(),
448
+ updated_at: z.string(),
449
+ resolved_at: z.string().nullable().optional()
450
+ });
451
+ const HealthIssueListResponseSchema = z.object({
452
+ results: z.array(HealthIssueSchema),
453
+ count: z.number().optional(),
454
+ next: z.string().nullable().optional(),
455
+ previous: z.string().nullable().optional()
456
+ });
457
+ //#endregion
458
+ //#region src/lib/workflows/posthog-doctor/fetch.ts
459
+ async function fetchHealthIssues(accessToken, baseUrl, projectId) {
460
+ const endpoint = `/api/environments/${projectId}/health_issues/`;
461
+ const url = `${baseUrl}${endpoint}?status=active&dismissed=false&limit=250`;
462
+ try {
463
+ const response = await axios.get(url, { headers: {
464
+ Authorization: `Bearer ${accessToken}`,
465
+ "User-Agent": WIZARD_USER_AGENT
466
+ } });
467
+ return HealthIssueListResponseSchema.parse(response.data).results;
468
+ } catch (error) {
469
+ const apiError = handleApiError(error, "fetch health issues");
470
+ analytics.captureException(apiError, {
471
+ endpoint,
472
+ baseUrl,
473
+ projectId
474
+ });
475
+ throw apiError;
476
+ }
477
+ }
478
+ //#endregion
479
+ //#region src/lib/workflows/posthog-doctor/kind-metadata.ts
480
+ const KIND_METADATA = {
481
+ ingestion_lag: {
482
+ title: "Ingestion is delayed",
483
+ description: "Events are being received but are taking longer than usual to appear.",
484
+ docsUrl: `${POSTHOG_DOCS_URL}/support/troubleshooting`
485
+ },
486
+ ingestion_warning: {
487
+ title: "Ingestion warnings on recent events",
488
+ description: "Some recent events were rejected or flagged by the ingestion pipeline.",
489
+ docsUrl: `${POSTHOG_DOCS_URL}/support/troubleshooting`
490
+ },
491
+ sdk_outdated: {
492
+ title: "SDK version is out of date",
493
+ description: "One or more SDKs are running an old version. Upgrade to get the latest fixes.",
494
+ docsUrl: `${POSTHOG_DOCS_URL}/libraries`
495
+ },
496
+ no_live_events: {
497
+ title: "No $pageview or $screen events in the last 30 days",
498
+ description: "PostHog is not receiving page or screen events from this project.",
499
+ docsUrl: `${POSTHOG_DOCS_URL}/getting-started/install`
500
+ },
501
+ no_pageleave_events: {
502
+ title: "$pageleave events not being sent",
503
+ description: "Enable pageleave tracking to power bounce rate and session duration.",
504
+ docsUrl: `${POSTHOG_DOCS_URL}/libraries/js#config`
505
+ },
506
+ scroll_depth: {
507
+ title: "Scroll depth tracking disabled",
508
+ description: "Turn on scroll depth to capture how far users read each page.",
509
+ docsUrl: `${POSTHOG_DOCS_URL}/libraries/js#config`
510
+ },
511
+ authorized_urls: {
512
+ title: "No authorized URLs configured",
513
+ description: "Some web analytics filters require at least one authorized URL to work.",
514
+ docsUrl: `${POSTHOG_DOCS_URL}/web-analytics/faq`
515
+ },
516
+ reverse_proxy: {
517
+ title: "No reverse proxy detected",
518
+ description: "A reverse proxy reduces data loss from ad blockers.",
519
+ docsUrl: `${POSTHOG_DOCS_URL}/advanced/proxy`
520
+ },
521
+ web_vitals: {
522
+ title: "Web Vitals tracking disabled",
523
+ description: "Enable Web Vitals to capture LCP, CLS and other performance metrics.",
524
+ docsUrl: `${POSTHOG_DOCS_URL}/web-analytics/web-vitals`
525
+ },
526
+ materialized_view_failure: {
527
+ title: "A materialized view is failing",
528
+ description: "A data modeling pipeline failed its most recent run.",
529
+ docsUrl: `${POSTHOG_DOCS_URL}/data-warehouse`
530
+ },
531
+ external_data_failure: {
532
+ title: "External data source is failing",
533
+ description: "An external data source sync failed and data may be stale.",
534
+ docsUrl: `${POSTHOG_DOCS_URL}/data-warehouse/sources`
535
+ }
536
+ };
537
+ const UNKNOWN_KIND_META = {
538
+ title: "Unknown issue",
539
+ description: "PostHog reported an issue kind the wizard does not yet recognize.",
540
+ docsUrl: POSTHOG_DOCS_URL
541
+ };
542
+ function getKindMeta(kind) {
543
+ return KIND_METADATA[kind] ?? {
544
+ ...UNKNOWN_KIND_META,
545
+ title: kind
546
+ };
547
+ }
548
+ //#endregion
549
+ //#region src/lib/workflows/workflow-registry.ts
550
+ const WORKFLOW_REGISTRY = [
551
+ posthogIntegrationConfig,
552
+ revenueAnalyticsConfig,
553
+ auditConfig,
554
+ {
555
+ command: "doctor",
556
+ description: "Diagnose your PostHog project for configuration issues and setup warnings",
557
+ flowKey: "posthog-doctor",
558
+ steps: POSTHOG_DOCTOR_WORKFLOW
559
+ }
560
+ ];
217
561
  /** All workflow configs that are exposed as CLI subcommands. */
218
562
  function getSubcommandWorkflows() {
219
563
  return WORKFLOW_REGISTRY.filter((c) => c.command != null);
@@ -345,32 +689,69 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
345
689
  skill: {
346
690
  describe: "Run a specific context-mill skill by ID\nenv: POSTHOG_WIZARD_SKILL",
347
691
  type: "string"
692
+ },
693
+ name: {
694
+ describe: "Name for account creation with --ci --signup\nenv: POSTHOG_WIZARD_NAME",
695
+ type: "string"
348
696
  }
349
697
  });
350
698
  }, (argv) => {
351
699
  const options = { ...argv };
352
700
  if (options.ci) {
353
701
  if (!options.region) options.region = "us";
354
- if (!options.apiKey) {
702
+ if (!options.installDir) {
355
703
  setUI(new LoggingUI());
356
704
  getUI().intro("PostHog Wizard");
357
- getUI().log.error("CI mode requires --api-key (personal API key phx_xxx)");
705
+ getUI().log.error("CI mode requires --install-dir (directory to install in)");
358
706
  process.exit(1);
359
707
  return;
360
708
  }
361
- if (!options.installDir) {
709
+ if (!options.apiKey && !options.signup) {
362
710
  setUI(new LoggingUI());
363
711
  getUI().intro("PostHog Wizard");
364
- getUI().log.error("CI mode requires --install-dir (directory to install in)");
712
+ getUI().log.error("CI mode requires --api-key (personal API key phx_xxx). To create a new account instead, use --signup --email you@example.com.");
713
+ process.exit(1);
714
+ return;
715
+ }
716
+ if (!options.apiKey && options.signup && !options.email) {
717
+ setUI(new LoggingUI());
718
+ getUI().intro("PostHog Wizard");
719
+ getUI().log.error("CI --signup requires --email to create a new account.");
365
720
  process.exit(1);
366
721
  return;
367
722
  }
368
723
  (async () => {
369
- const { posthogIntegrationConfig } = await import("./posthog-integration-HBDZrREG.js").then((n) => n.n);
370
- const { FRAMEWORK_REGISTRY } = await import("./registry-BIV1wRpo.js").then((n) => n.n);
371
- const { detectFramework, gatherFrameworkContext } = await import("./detection-gcQwPKPu.js").then((n) => n.t);
372
- const { analytics } = await import("./analytics-CviQ_A9M.js");
373
- const { wizardAbort } = await import("./wizard-abort-BcEPhAxY.js");
724
+ if (!options.apiKey && options.signup) {
725
+ setUI(new LoggingUI());
726
+ getUI().intro("PostHog Wizard");
727
+ try {
728
+ const { provisionNewAccount } = await import("./provisioning-CHfTOEvg.js");
729
+ const signupRegion = options.region.toUpperCase();
730
+ getUI().log.info(`Provisioning new PostHog account for ${String(options.email)} in ${signupRegion}...`);
731
+ const result = await provisionNewAccount(options.email, options.name ?? "", signupRegion);
732
+ if (!result.personalApiKey) {
733
+ getUI().log.error("Provisioning succeeded but no personal API key was returned — cannot continue install.");
734
+ process.exit(1);
735
+ return;
736
+ }
737
+ getUI().log.success("Account ready.");
738
+ getUI().log.info(` Project API Key: ${result.projectApiKey}`);
739
+ getUI().log.info(` Personal API Key: ${result.personalApiKey}`);
740
+ getUI().log.info(` Host: ${result.host}`);
741
+ options.apiKey = result.personalApiKey;
742
+ if (options.projectId == null) options.projectId = result.projectId;
743
+ } catch (error) {
744
+ const msg = error instanceof Error ? error.message : String(error);
745
+ getUI().log.error(`Provisioning failed: ${msg}`);
746
+ process.exit(1);
747
+ return;
748
+ }
749
+ }
750
+ const { posthogIntegrationConfig } = await import("./posthog-integration-DX77Msto.js").then((n) => n.r);
751
+ const { FRAMEWORK_REGISTRY } = await import("./registry-CCtIsqb8.js").then((n) => n.n);
752
+ const { detectFramework, gatherFrameworkContext } = await import("./detection-C_RfYYDe.js").then((n) => n.t);
753
+ const { analytics } = await import("./analytics-JDitS2JI.js");
754
+ const { wizardAbort } = await import("./wizard-abort-DIhFXJ5N.js");
374
755
  runWizardCI(posthogIntegrationConfig, options, async (session) => {
375
756
  const integration = session.integration ?? await detectFramework(session.installDir);
376
757
  if (!integration) {
@@ -403,11 +784,11 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
403
784
  getUI().log.error("This installer requires an interactive terminal (TTY) to run.\nIt appears you are running in a non-interactive environment.\nPlease run the wizard in an interactive terminal.\n\nFor CI/CD environments, use --ci mode:\n npx @posthog/wizard --ci --region us --api-key phx_xxx");
404
785
  process.exit(1);
405
786
  } else if (options.playground) (async () => {
406
- const { startPlayground } = await import("./start-playground-D1iLBvqF.js");
787
+ const { startPlayground } = await import("./start-playground-DYNQ8rOz.js");
407
788
  startPlayground(WIZARD_VERSION);
408
789
  })();
409
790
  else if (options.skill) (async () => {
410
- const { createSkillWorkflow } = await import("./agent-skill-BVjJqol6.js").then((n) => n.t);
791
+ const { createSkillWorkflow } = await Promise.resolve().then(() => agent_skill_exports);
411
792
  const skillId = options.skill;
412
793
  runWizard(createSkillWorkflow({
413
794
  skillId,
@@ -417,13 +798,16 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
417
798
  integrationLabel: skillId,
418
799
  successMessage: `${skillId} completed!`,
419
800
  reportFile: `posthog-${skillId}-report.md`,
420
- docsUrl: "https://posthog.com/docs",
801
+ docsUrl: POSTHOG_DOCS_URL,
421
802
  spinnerMessage: `Running ${skillId}...`,
422
803
  estimatedDurationMinutes: 5
423
- }), options);
804
+ }), {
805
+ ...options,
806
+ skillId
807
+ });
424
808
  })();
425
809
  else (async () => {
426
- const { posthogIntegrationConfig } = await import("./posthog-integration-HBDZrREG.js").then((n) => n.n);
810
+ const { posthogIntegrationConfig } = await import("./posthog-integration-DX77Msto.js").then((n) => n.r);
427
811
  runWizard(posthogIntegrationConfig, options);
428
812
  })();
429
813
  }).command("mcp <command>", "MCP server management commands", (yargs) => {
@@ -447,12 +831,12 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
447
831
  const options = { ...argv };
448
832
  const mcpFeatures = options.features?.split(",").map((s) => s.trim()).filter(Boolean);
449
833
  (async () => {
450
- const { readApiKeyFromEnv } = await import("./env-api-key-K8TdTDII.js");
834
+ const { readApiKeyFromEnv } = await import("./env-api-key-D5G2PrXW.js");
451
835
  const apiKey = options.apiKey || readApiKeyFromEnv();
452
836
  try {
453
- const { startTUI } = await import("./start-tui-DkT_H5zx.js");
454
- const { buildSession } = await import("./wizard-session-y7nf6aKH.js");
455
- const { Flow } = await import("./router-CXjdWNh2.js").then((n) => n.n);
837
+ const { startTUI } = await import("./start-tui-DleQG3La.js");
838
+ const { buildSession } = await import("./wizard-session-BQC9vy9Z.js");
839
+ const { Flow } = await import("./router-BTfmEDDJ.js").then((n) => n.n);
456
840
  const tui = startTUI(WIZARD_VERSION, Flow.McpAdd);
457
841
  const session = buildSession({
458
842
  debug: options.debug,
@@ -463,7 +847,7 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
463
847
  tui.store.session = session;
464
848
  } catch {
465
849
  setUI(new LoggingUI());
466
- const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-lfUH2pdU.js").then((n) => n.r);
850
+ const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-BKoew3aT.js").then((n) => n.r);
467
851
  await addMCPServerToClientsStep({
468
852
  local: options.local,
469
853
  features: mcpFeatures,
@@ -481,9 +865,9 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
481
865
  const options = { ...argv };
482
866
  (async () => {
483
867
  try {
484
- const { startTUI } = await import("./start-tui-DkT_H5zx.js");
485
- const { buildSession } = await import("./wizard-session-y7nf6aKH.js");
486
- const { Flow } = await import("./router-CXjdWNh2.js").then((n) => n.n);
868
+ const { startTUI } = await import("./start-tui-DleQG3La.js");
869
+ const { buildSession } = await import("./wizard-session-BQC9vy9Z.js");
870
+ const { Flow } = await import("./router-BTfmEDDJ.js").then((n) => n.n);
487
871
  const tui = startTUI(WIZARD_VERSION, Flow.McpRemove);
488
872
  const session = buildSession({
489
873
  debug: options.debug,
@@ -492,12 +876,69 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
492
876
  tui.store.session = session;
493
877
  } catch {
494
878
  setUI(new LoggingUI());
495
- const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-lfUH2pdU.js").then((n) => n.r);
879
+ const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-BKoew3aT.js").then((n) => n.r);
496
880
  await removeMCPServerFromClientsStep({ local: options.local });
497
881
  }
498
882
  })();
499
883
  }).demandCommand(1, "You must specify a subcommand (add or remove)").help();
500
884
  });
885
+ cli.command("provision", "Create a new PostHog account (headless, no TUI)", (yargs) => {
886
+ return yargs.options({
887
+ email: {
888
+ describe: "Email address for the new account",
889
+ type: "string",
890
+ demandOption: true
891
+ },
892
+ region: {
893
+ describe: "Cloud region (us or eu)",
894
+ choices: ["us", "eu"],
895
+ default: "us"
896
+ },
897
+ name: {
898
+ describe: "Name for the new account",
899
+ type: "string",
900
+ default: ""
901
+ },
902
+ json: {
903
+ describe: "Emit JSON result to stdout (defaults to true when stdout is not a TTY)",
904
+ type: "boolean"
905
+ }
906
+ }).example("wizard provision --email matt+test@posthog.com --region us", "").example("wizard provision --email user@example.com --region eu --json", "");
907
+ }, (argv) => {
908
+ const email = argv.email;
909
+ const region = argv.region.toUpperCase();
910
+ const name = argv.name ?? "";
911
+ const jsonMode = argv.json === void 0 ? !process.stdout.isTTY : argv.json;
912
+ if (!jsonMode) setUI(new LoggingUI());
913
+ (async () => {
914
+ try {
915
+ const { provisionNewAccount } = await import("./provisioning-CHfTOEvg.js");
916
+ if (!jsonMode) getUI().log.info(`Provisioning account for ${email} in ${region}...`);
917
+ const result = await provisionNewAccount(email, name, region);
918
+ if (jsonMode) process.stdout.write(`${JSON.stringify(result)}\n`);
919
+ else {
920
+ getUI().log.success("Account provisioned successfully:");
921
+ getUI().log.info(` API Key: ${result.projectApiKey}`);
922
+ getUI().log.info(` Host: ${result.host}`);
923
+ getUI().log.info(` Project ID: ${result.projectId}`);
924
+ getUI().log.info(` Account ID: ${result.accountId}`);
925
+ getUI().log.info(` Access Token: ${result.accessToken}`);
926
+ getUI().log.info(` Refresh Token: ${result.refreshToken}`);
927
+ if (result.personalApiKey) getUI().log.info(` Personal API Key: ${result.personalApiKey}`);
928
+ }
929
+ process.exit(0);
930
+ } catch (error) {
931
+ const msg = error instanceof Error ? error.message : String(error);
932
+ const code = msg.includes("already associated") ? "email_exists" : "provisioning_failed";
933
+ if (jsonMode) process.stderr.write(`${JSON.stringify({
934
+ error: msg,
935
+ code
936
+ })}\n`);
937
+ else getUI().log.error(`Provisioning failed: ${msg}`);
938
+ process.exit(1);
939
+ }
940
+ })();
941
+ });
501
942
  for (const wfConfig of getSubcommandWorkflows()) cli.command(wfConfig.command, wfConfig.description, (y) => y.options(skillSubcommandOptions), (argv) => {
502
943
  const options = { ...argv };
503
944
  if (options.ci) runWizardCI(wfConfig, options);
@@ -513,8 +954,12 @@ function runWizard(config, options) {
513
954
  (async () => {
514
955
  try {
515
956
  const installDir = options.installDir || process.cwd();
516
- const { startTUI } = await import("./start-tui-DkT_H5zx.js");
517
- const { buildSession } = await import("./wizard-session-y7nf6aKH.js");
957
+ const { startTUI } = await import("./start-tui-DleQG3La.js");
958
+ const { buildSession } = await import("./wizard-session-BQC9vy9Z.js");
959
+ const { TaskStreamPush } = await import("./task-stream-CX7Uf6EM.js");
960
+ const { FileDestination } = await import("./file-8iNrXHkG.js");
961
+ const { PostHogDestination } = await import("./posthog-vm0k9PKS.js");
962
+ const { analytics } = await import("./analytics-JDitS2JI.js");
518
963
  const tui = startTUI(WIZARD_VERSION, config.flowKey);
519
964
  const session = buildSession({
520
965
  debug: options.debug,
@@ -532,24 +977,55 @@ function runWizard(config, options) {
532
977
  yaraReport: options.yaraReport
533
978
  });
534
979
  session.workflowLabel = config.flowKey;
535
- session.skillId = (typeof config.run === "object" ? config.run : null)?.skillId ?? null;
980
+ if (options.skillId) session.skillId = options.skillId;
536
981
  tui.store.session = session;
982
+ const taskStream = new TaskStreamPush({
983
+ store: tui.store,
984
+ workflowId: config.flowKey,
985
+ destinations: [new FileDestination(), new PostHogDestination()]
986
+ });
987
+ tui.store.onTasksChanged = () => void taskStream.push();
537
988
  await tui.store.runReadyHooks();
538
989
  await tui.store.getGate("intro");
539
- const { runAgent } = await import("./agent-runner-DHtcWn15.js");
540
- await runAgent(config, tui.store.session);
990
+ await tui.store.getGate("health-check");
991
+ const skipAgent = config.run == null;
992
+ if (skipAgent) {
993
+ const { getOrAskForProjectData } = await import("./setup-utils-CoX-vLgw.js");
994
+ const { projectApiKey, host, accessToken, projectId } = await getOrAskForProjectData({
995
+ signup: session.signup,
996
+ ci: session.ci,
997
+ apiKey: session.apiKey,
998
+ projectId: session.projectId
999
+ });
1000
+ tui.store.setCredentials({
1001
+ accessToken,
1002
+ projectApiKey,
1003
+ host,
1004
+ projectId
1005
+ });
1006
+ } else {
1007
+ const { runAgent } = await import("./agent-runner-B8Cx6X6x.js");
1008
+ await runAgent(config, tui.store.session);
1009
+ }
1010
+ const isDone = () => skipAgent ? tui.store.session.outroDismissed : tui.store.session.skillsComplete;
541
1011
  await new Promise((resolve) => {
542
1012
  const unsub = tui.store.subscribe(() => {
543
- if (tui.store.session.skillsComplete) {
1013
+ if (isDone()) {
544
1014
  unsub();
545
1015
  resolve();
546
1016
  }
547
1017
  });
548
- if (tui.store.session.skillsComplete) {
1018
+ if (isDone()) {
549
1019
  unsub();
550
1020
  resolve();
551
1021
  }
552
1022
  });
1023
+ try {
1024
+ await taskStream.dispose();
1025
+ } catch (error) {
1026
+ analytics.captureException(error);
1027
+ }
1028
+ tui.unmount();
553
1029
  process.exit(0);
554
1030
  } catch (err) {
555
1031
  if (runtimeEnv("DEBUG") || runtimeEnv("POSTHOG_WIZARD_DEBUG")) console.error("TUI init failed:", err);
@@ -579,11 +1055,11 @@ function runWizardCI(config, options, preRun) {
579
1055
  }
580
1056
  (async () => {
581
1057
  const path = await import("path");
582
- const { buildSession } = await import("./wizard-session-y7nf6aKH.js");
1058
+ const { buildSession } = await import("./wizard-session-BQC9vy9Z.js");
583
1059
  const { readEnvironment } = await Promise.resolve().then(() => environment_exports);
584
- const { readApiKeyFromEnv } = await import("./env-api-key-K8TdTDII.js");
585
- const { configureLogFileFromEnvironment, logToFile } = await import("./debug-CIyf0ZGx.js");
586
- const { wizardAbort, WizardError } = await import("./wizard-abort-BcEPhAxY.js");
1060
+ const { readApiKeyFromEnv } = await import("./env-api-key-D5G2PrXW.js");
1061
+ const { configureLogFileFromEnvironment, logToFile } = await import("./debug-I5sRZubJ.js");
1062
+ const { wizardAbort, WizardError } = await import("./wizard-abort-DIhFXJ5N.js");
587
1063
  configureLogFileFromEnvironment();
588
1064
  const env = readEnvironment();
589
1065
  const apiKey = options.apiKey ?? readApiKeyFromEnv() ?? void 0;
@@ -606,7 +1082,6 @@ function runWizardCI(config, options, preRun) {
606
1082
  });
607
1083
  session.workflowLabel = config.flowKey;
608
1084
  const runDef = typeof config.run === "object" ? config.run : null;
609
- session.skillId = runDef?.skillId ?? null;
610
1085
  getUI().intro("Welcome to the PostHog setup wizard");
611
1086
  getUI().log.info(`Running ${config.flowKey} in CI mode`);
612
1087
  try {
@@ -633,7 +1108,7 @@ function runWizardCI(config, options, preRun) {
633
1108
  })
634
1109
  });
635
1110
  }
636
- const { runAgent } = await import("./agent-runner-DHtcWn15.js");
1111
+ const { runAgent } = await import("./agent-runner-B8Cx6X6x.js");
637
1112
  await runAgent(config, session);
638
1113
  } catch (error) {
639
1114
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -651,6 +1126,6 @@ function runWizardCI(config, options, preRun) {
651
1126
  });
652
1127
  }
653
1128
  //#endregion
654
- export { POSTHOG_SDKS as n, STRIPE_SDKS as r, WORKFLOW_REGISTRY as t };
1129
+ export { POSTHOG_SDKS as a, AGENT_SKILL_STEPS as i, getKindMeta as n, STRIPE_SDKS as o, fetchHealthIssues as r, WORKFLOW_REGISTRY as t };
655
1130
 
656
1131
  //# sourceMappingURL=bin.js.map