@posthog/wizard 2.44.0 → 2.46.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 (121) hide show
  1. package/README.md +5 -1
  2. package/dist/{add-mcp-server-to-clients-D5qsqCkj.js → add-mcp-server-to-clients-Bv2CBSil.js} +53 -6
  3. package/dist/add-mcp-server-to-clients-Bv2CBSil.js.map +1 -0
  4. package/dist/{agent-interface-BvTxWiol.js → agent-interface-B8roB2UP.js} +1122 -157
  5. package/dist/agent-interface-B8roB2UP.js.map +1 -0
  6. package/dist/{agent-runner-BF6_f8Qh.js → agent-runner-CV3qh_2p.js} +298 -610
  7. package/dist/agent-runner-CV3qh_2p.js.map +1 -0
  8. package/dist/analytics-D7vUZgzf.js +2 -0
  9. package/dist/{analytics-DSlQuwOT.js → analytics-k76OWsl0.js} +20 -6
  10. package/dist/analytics-k76OWsl0.js.map +1 -0
  11. package/dist/{api-BXduJZrw.js → api-CmIWcW-U.js} +3 -3
  12. package/dist/{api-BXduJZrw.js.map → api-CmIWcW-U.js.map} +1 -1
  13. package/dist/bin.js +242 -1043
  14. package/dist/bin.js.map +1 -1
  15. package/dist/{ci-install-GirEJqu2.js → ci-install-CNEJxdHf.js} +4 -4
  16. package/dist/{ci-install-GirEJqu2.js.map → ci-install-CNEJxdHf.js.map} +1 -1
  17. package/dist/commandments-DSNrOeOC.js +42 -0
  18. package/dist/commandments-DSNrOeOC.js.map +1 -0
  19. package/dist/commandments-qTW7pwaT.js +2 -0
  20. package/dist/{debug-BOFxiVVs.js → debug-BwIo7nwn.js} +1 -1
  21. package/dist/{debug-DXfQFmcM.js → debug-C9HmIrwx.js} +36 -6
  22. package/dist/debug-C9HmIrwx.js.map +1 -0
  23. package/dist/{defaults-BWLIffh5.js → defaults-CtWMmC8s.js} +1 -1
  24. package/dist/{defaults-BWLIffh5.js.map → defaults-CtWMmC8s.js.map} +1 -1
  25. package/dist/{env-api-key-cjD4yfGT.js → env-api-key-C3LzH8Lr.js} +1 -1
  26. package/dist/{env-api-key-cjD4yfGT.js.map → env-api-key-C3LzH8Lr.js.map} +1 -1
  27. package/dist/{environment-F1yw21dG.js → environment-NJykOp33.js} +3 -3
  28. package/dist/{environment-F1yw21dG.js.map → environment-NJykOp33.js.map} +1 -1
  29. package/dist/{file-utils-D-7YfJ7A.js → file-utils-CLMcNIKi.js} +2 -2
  30. package/dist/{file-utils-D-7YfJ7A.js.map → file-utils-CLMcNIKi.js.map} +1 -1
  31. package/dist/file-watcher-CBDCNQVV.js +123 -0
  32. package/dist/file-watcher-CBDCNQVV.js.map +1 -0
  33. package/dist/{headless-ui-Dni0gPND.js → headless-ui-B3QKxbz8.js} +5 -4
  34. package/dist/headless-ui-B3QKxbz8.js.map +1 -0
  35. package/dist/{interactive-Bmi82rsO.js → interactive-CIJRex02.js} +2 -2
  36. package/dist/{interactive-Bmi82rsO.js.map → interactive-CIJRex02.js.map} +1 -1
  37. package/dist/{mcp-prompt-streaming-AtntLsJ8.js → mcp-prompt-streaming-D6OgW3lC.js} +3 -3
  38. package/dist/{mcp-prompt-streaming-AtntLsJ8.js.map → mcp-prompt-streaming-D6OgW3lC.js.map} +1 -1
  39. package/dist/{mcp-xKRDnrcq.js → mcp-qTjKHqXN.js} +3 -3
  40. package/dist/mcp-qTjKHqXN.js.map +1 -0
  41. package/dist/{non-interactive-BIHqcW8g.js → non-interactive-8Eypq_h-.js} +2 -2
  42. package/dist/{non-interactive-BIHqcW8g.js.map → non-interactive-8Eypq_h-.js.map} +1 -1
  43. package/dist/orchestrator-tools-DVXOV-kz.js +99 -0
  44. package/dist/orchestrator-tools-DVXOV-kz.js.map +1 -0
  45. package/dist/{package-json-CDs1ZVKu.js → package-json-DCuoye-H.js} +1 -1
  46. package/dist/{package-json-CDs1ZVKu.js.map → package-json-DCuoye-H.js.map} +1 -1
  47. package/dist/{package-manager-C6R_zpML.js → package-manager-CAD9Uklp.js} +2 -2
  48. package/dist/{package-manager-C6R_zpML.js.map → package-manager-CAD9Uklp.js.map} +1 -1
  49. package/dist/pi-C9iHv5uG.js +619 -0
  50. package/dist/pi-C9iHv5uG.js.map +1 -0
  51. package/dist/{playground-DwL36I2u.js → playground-C-9Q3ETa.js} +8 -9
  52. package/dist/{playground-DwL36I2u.js.map → playground-C-9Q3ETa.js.map} +1 -1
  53. package/dist/{posthog-DwKlq0HM.js → posthog-DZZbziJ1.js} +1 -1
  54. package/dist/{posthog-DwKlq0HM.js.map → posthog-DZZbziJ1.js.map} +1 -1
  55. package/dist/{posthog-integration-BhLKCFsI.js → posthog-integration-Do997QON.js} +2206 -112
  56. package/dist/posthog-integration-Do997QON.js.map +1 -0
  57. package/dist/{provisioning-jVZm2E-A.js → provisioning-DpqnGk3z.js} +3 -3
  58. package/dist/{provisioning-jVZm2E-A.js.map → provisioning-DpqnGk3z.js.map} +1 -1
  59. package/dist/queue-tools-CTUgbOU8.js +366 -0
  60. package/dist/queue-tools-CTUgbOU8.js.map +1 -0
  61. package/dist/{registry-DcoBCMQR.js → registry-DT58jEYr.js} +96 -18
  62. package/dist/registry-DT58jEYr.js.map +1 -0
  63. package/dist/{security-jxjVsOpd.js → security-CTigdAWm.js} +10 -8
  64. package/dist/security-CTigdAWm.js.map +1 -0
  65. package/dist/{setup-utils-BQCl28D8.js → setup-utils-Cb5uACEO.js} +31 -9
  66. package/dist/setup-utils-Cb5uACEO.js.map +1 -0
  67. package/dist/{start-tui-DgSKFMVh.js → start-tui-Cwc-PFma.js} +37 -92
  68. package/dist/start-tui-Cwc-PFma.js.map +1 -0
  69. package/dist/{steps-erepgD0V.js → steps-DyEKYM4I.js} +7 -7
  70. package/dist/{steps-erepgD0V.js.map → steps-DyEKYM4I.js.map} +1 -1
  71. package/dist/{store-C79GoHCQ.js → store-4sj-vWr5.js} +5 -6
  72. package/dist/store-4sj-vWr5.js.map +1 -0
  73. package/dist/{subagent-aDlD_Ltz.js → subagent-D8_yDgCB.js} +2 -2
  74. package/dist/{subagent-aDlD_Ltz.js.map → subagent-D8_yDgCB.js.map} +1 -1
  75. package/dist/task-D8Y8pkzd.js +304 -0
  76. package/dist/task-D8Y8pkzd.js.map +1 -0
  77. package/dist/{task-stream-0Pk0tPBN.js → task-stream-DQT3vjwS.js} +72 -7
  78. package/dist/task-stream-DQT3vjwS.js.map +1 -0
  79. package/dist/{tasks-ZkrluXCa.js → tasks-D2WKssA5.js} +2 -2
  80. package/dist/{tasks-ZkrluXCa.js.map → tasks-D2WKssA5.js.map} +1 -1
  81. package/dist/{telemetry-DZShaH-y.js → telemetry-CYr4HgS2.js} +3 -3
  82. package/dist/{telemetry-DZShaH-y.js.map → telemetry-CYr4HgS2.js.map} +1 -1
  83. package/dist/{terminal-CEhufbJ4.js → terminal-1RfyHQC2.js} +13 -13
  84. package/dist/{terminal-CEhufbJ4.js.map → terminal-1RfyHQC2.js.map} +1 -1
  85. package/dist/tools-DQCUOQZX.js +199 -0
  86. package/dist/tools-DQCUOQZX.js.map +1 -0
  87. package/dist/{wizard-abort-UCm4Pd5m.js → wizard-abort-D_-v1zvS.js} +1 -1
  88. package/dist/{wizard-abort-C14PzXZ8.js → wizard-abort-FuyIaI_0.js} +4 -4
  89. package/dist/{wizard-abort-C14PzXZ8.js.map → wizard-abort-FuyIaI_0.js.map} +1 -1
  90. package/dist/{wizard-session-C5lZPPEc.js → wizard-session-DWHe83uk.js} +1 -1
  91. package/dist/{wizard-session-BAZql11N.js → wizard-session-tp4Zdbwl.js} +1 -1
  92. package/dist/{wizard-session-BAZql11N.js.map → wizard-session-tp4Zdbwl.js.map} +1 -1
  93. package/dist/yara-hooks-6gNnPFPo.js +2 -0
  94. package/dist/{yara-hooks-CPH8N4yz.js → yara-hooks-DdYRRxfH.js} +82 -21
  95. package/dist/yara-hooks-DdYRRxfH.js.map +1 -0
  96. package/package.json +1 -1
  97. package/dist/add-mcp-server-to-clients-D5qsqCkj.js.map +0 -1
  98. package/dist/agent-interface-BvTxWiol.js.map +0 -1
  99. package/dist/agent-runner-BF6_f8Qh.js.map +0 -1
  100. package/dist/analytics-C7Xx6csw.js +0 -2
  101. package/dist/analytics-DSlQuwOT.js.map +0 -1
  102. package/dist/debug-DXfQFmcM.js.map +0 -1
  103. package/dist/headless-ui-Dni0gPND.js.map +0 -1
  104. package/dist/mcp-xKRDnrcq.js.map +0 -1
  105. package/dist/posthog-integration-BhLKCFsI.js.map +0 -1
  106. package/dist/registry-DcoBCMQR.js.map +0 -1
  107. package/dist/security-jxjVsOpd.js.map +0 -1
  108. package/dist/setup-utils-BQCl28D8.js.map +0 -1
  109. package/dist/start-tui-DgSKFMVh.js.map +0 -1
  110. package/dist/store-C79GoHCQ.js.map +0 -1
  111. package/dist/task-stream-0Pk0tPBN.js.map +0 -1
  112. package/dist/tools-BIPMan6l.js +0 -122
  113. package/dist/tools-BIPMan6l.js.map +0 -1
  114. package/dist/types-y3HkjtSq.js +0 -46
  115. package/dist/types-y3HkjtSq.js.map +0 -1
  116. package/dist/wizard-tools-B7SLjCic.js +0 -1106
  117. package/dist/wizard-tools-B7SLjCic.js.map +0 -1
  118. package/dist/wizard-ui-WZ48rUgr.js +0 -15
  119. package/dist/wizard-ui-WZ48rUgr.js.map +0 -1
  120. package/dist/yara-hooks-CPH8N4yz.js.map +0 -1
  121. package/dist/yara-hooks-VZlj4Lib.js +0 -2
package/dist/bin.js CHANGED
@@ -1,28 +1,27 @@
1
1
  #!/usr/bin/env node
2
- import { L as Integration, U as POSTHOG_DOCS_URL, a as getLogFilePath, bt as isHeadless, dt as WIZARD_USER_AGENT, f as getUI, ht as VERSION, m as LoggingUI, p as setUI, pt as getSkillsBaseUrl, r as debug, s as logToFile, yt as headlessOption } from "./debug-DXfQFmcM.js";
3
- import { n as analytics } from "./analytics-DSlQuwOT.js";
4
- import { r as setEntryCommand } from "./telemetry-DZShaH-y.js";
5
- import { n as isUsingTypeScript } from "./setup-utils-BQCl28D8.js";
6
- import { o as handleApiError } from "./api-BXduJZrw.js";
7
- import "./wizard-session-BAZql11N.js";
8
- import { r as runCleanups } from "./wizard-abort-C14PzXZ8.js";
9
- import { n as isNonInteractiveEnvironment } from "./environment-F1yw21dG.js";
10
- import { n as runAgent, o as authenticate } from "./agent-runner-BF6_f8Qh.js";
11
- import { l as recoverOrphanedSettingsBackups, p as AgentSignals } from "./agent-interface-BvTxWiol.js";
12
- import { i as fetchSkillMenu, t as WIZARD_TOOL_NAMES } from "./wizard-tools-B7SLjCic.js";
13
- import { n as AUDIT_CHECKS_KEY, r as AUDIT_REPORT_FILE, t as AUDIT_CHECKS_FILE } from "./types-y3HkjtSq.js";
14
- import { h as SETUP_REPORT_FILE } from "./yara-hooks-CPH8N4yz.js";
15
- import { i as SPINNER_MESSAGE, t as FRAMEWORK_REGISTRY } from "./registry-DcoBCMQR.js";
16
- import { _ as gatherFrameworkContext, a as LINE_CHART_BLOCK, b as parseRequirementsTxt, g as detectProjectsWithAgent, h as HEALTH_CHECK_STEP, i as FUNNEL_BLOCK, m as Icons, n as integrationRunStep, o as PRODUCT_SUITE_BLOCK, p as Colors, r as posthogIntegrationConfig, s as StatusPeekTrigger, u as isClearBlock, v as parsePipfile, y as parsePyprojectToml } from "./posthog-integration-BhLKCFsI.js";
17
- import { n as safeReadFile, r as walkProjectFiles, t as IGNORED_DIRS } from "./file-utils-D-7YfJ7A.js";
18
- import { n as readApiKeyFromEnv } from "./env-api-key-cjD4yfGT.js";
2
+ import { B as Integration, Et as regionOption, K as POSTHOG_DOCS_URL, Tt as isHeadless, a as getLogFilePath, bt as VERSION, f as getUI, gt as WIZARD_USER_AGENT, m as LoggingUI, p as setUI, r as debug, s as logToFile, vt as getSkillsBaseUrl, wt as headlessOption } from "./debug-C9HmIrwx.js";
3
+ import { n as analytics } from "./analytics-k76OWsl0.js";
4
+ import { r as setEntryCommand } from "./telemetry-CYr4HgS2.js";
5
+ import { n as isUsingTypeScript } from "./setup-utils-Cb5uACEO.js";
6
+ import { o as handleApiError } from "./api-CmIWcW-U.js";
7
+ import "./wizard-session-tp4Zdbwl.js";
8
+ import { r as runCleanups } from "./wizard-abort-FuyIaI_0.js";
9
+ import { n as isNonInteractiveEnvironment } from "./environment-NJykOp33.js";
10
+ import { n as runAgent, o as authenticate } from "./agent-runner-CV3qh_2p.js";
11
+ import { l as recoverOrphanedSettingsBackups, p as AgentSignals, v as WIZARD_TOOL_NAMES, x as fetchSkillMenu } from "./agent-interface-B8roB2UP.js";
12
+ import { _ as AUDIT_CHECKS_FILE, h as SETUP_REPORT_FILE, v as AUDIT_CHECKS_KEY, y as AUDIT_REPORT_FILE } from "./yara-hooks-DdYRRxfH.js";
13
+ import { i as SPINNER_MESSAGE } from "./registry-DT58jEYr.js";
14
+ import { S as gatherFrameworkContext, _ as detectWarehousePrerequisites, a as LINE_CHART_BLOCK, g as WAREHOUSE_ABORT_CASES, h as HEALTH_CHECK_STEP, i as FUNNEL_BLOCK, m as Icons, n as integrationRunStep, o as PRODUCT_SUITE_BLOCK, p as Colors, r as posthogIntegrationConfig, s as StatusPeekTrigger, u as isClearBlock, v as getDetectedWarehouseSources, x as resolveProjectDir, y as detectIntegrationProjects } from "./posthog-integration-Do997QON.js";
15
+ import { t as IGNORED_DIRS } from "./file-utils-CLMcNIKi.js";
16
+ import { n as readApiKeyFromEnv } from "./env-api-key-C3LzH8Lr.js";
19
17
  import { satisfies } from "semver";
20
18
  import yargs from "yargs";
21
19
  import { hideBin } from "yargs/helpers";
22
20
  import fs, { existsSync, readFileSync, readdirSync, statSync } from "fs";
23
- import path, { join, relative, resolve, sep } from "path";
21
+ import path, { join, relative } from "path";
24
22
  import * as os from "node:os";
25
23
  import * as path$1 from "node:path";
24
+ import { join as join$1 } from "node:path";
26
25
  import { spawnSync } from "node:child_process";
27
26
  import * as fs$1 from "node:fs";
28
27
  import axios from "axios";
@@ -74,11 +73,6 @@ const GLOBAL_OPTIONS = {
74
73
  describe: "Enable verbose logging\nenv: POSTHOG_WIZARD_DEBUG",
75
74
  type: "boolean"
76
75
  },
77
- region: {
78
- describe: "PostHog cloud region\nenv: POSTHOG_WIZARD_REGION",
79
- choices: ["us", "eu"],
80
- type: "string"
81
- },
82
76
  signup: {
83
77
  default: false,
84
78
  describe: "Create a new PostHog account during setup\nenv: POSTHOG_WIZARD_SIGNUP",
@@ -206,7 +200,7 @@ function runProvision(argv) {
206
200
  }
207
201
  async function provision({ email, region, name, baseUrl, jsonMode }) {
208
202
  try {
209
- const { provisionNewAccount } = await import("./provisioning-jVZm2E-A.js").then((n) => n.n);
203
+ const { provisionNewAccount } = await import("./provisioning-DpqnGk3z.js").then((n) => n.n);
210
204
  if (!jsonMode) getUI().log.info(`Provisioning account for ${email} in ${region}...`);
211
205
  emitResult(await provisionNewAccount(email, name, region, { baseUrl }), jsonMode);
212
206
  process.exit(0);
@@ -262,7 +256,8 @@ const basicIntegrationCommand = {
262
256
  type: "boolean",
263
257
  hidden: true
264
258
  },
265
- ...headlessOption
259
+ ...headlessOption,
260
+ ...regionOption
266
261
  },
267
262
  check: (argv) => {
268
263
  if (argv.playground && (argv.ci || isHeadless(argv))) throw new Error("--playground cannot be combined with a headless run.");
@@ -272,22 +267,22 @@ const basicIntegrationCommand = {
272
267
  setEntryCommand("integrate");
273
268
  (async () => {
274
269
  if (isHeadless(argv)) {
275
- const { runHeadlessInstall } = await import("./ci-install-GirEJqu2.js");
270
+ const { runHeadlessInstall } = await import("./ci-install-CNEJxdHf.js");
276
271
  return runHeadlessInstall(argv);
277
272
  }
278
273
  if (argv.ci) {
279
- const { runCIInstall } = await import("./ci-install-GirEJqu2.js");
274
+ const { runCIInstall } = await import("./ci-install-CNEJxdHf.js");
280
275
  return runCIInstall(argv);
281
276
  }
282
277
  if (isNonInteractiveEnvironment()) {
283
- const { failNonInteractive } = await import("./non-interactive-BIHqcW8g.js");
278
+ const { failNonInteractive } = await import("./non-interactive-8Eypq_h-.js");
284
279
  return failNonInteractive();
285
280
  }
286
281
  if (argv.playground) {
287
- const { runPlayground } = await import("./playground-DwL36I2u.js");
282
+ const { runPlayground } = await import("./playground-C-9Q3ETa.js");
288
283
  return runPlayground();
289
284
  }
290
- const { runInteractive } = await import("./interactive-Bmi82rsO.js");
285
+ const { runInteractive } = await import("./interactive-CIJRex02.js");
291
286
  runInteractive(argv);
292
287
  })();
293
288
  }
@@ -530,809 +525,6 @@ const revenueAnalyticsConfig = {
530
525
  requires: ["posthog-integration"]
531
526
  };
532
527
  //#endregion
533
- //#region src/lib/warehouse-sources/registry.ts
534
- const SOURCE_DETECTORS = [
535
- {
536
- kind: "Postgres",
537
- label: "PostgreSQL",
538
- mode: "in-cli",
539
- signals: {
540
- npm: [
541
- "pg",
542
- "postgres",
543
- "postgres.js",
544
- "knex",
545
- "sequelize"
546
- ],
547
- python: [
548
- "psycopg",
549
- "psycopg2",
550
- "psycopg2-binary",
551
- "asyncpg"
552
- ],
553
- ruby: ["pg"],
554
- envKeys: [
555
- /^DATABASE_URL$/,
556
- /^POSTGRES_/,
557
- /^PG(HOST|DATABASE|USER|PORT)$/
558
- ]
559
- }
560
- },
561
- {
562
- kind: "MySQL",
563
- label: "MySQL",
564
- mode: "in-cli",
565
- signals: {
566
- npm: ["mysql", "mysql2"],
567
- python: [
568
- "pymysql",
569
- "mysqlclient",
570
- "mysql-connector-python"
571
- ],
572
- ruby: ["mysql2"],
573
- envKeys: [/^MYSQL_/]
574
- }
575
- },
576
- {
577
- kind: "MongoDB",
578
- label: "MongoDB",
579
- mode: "in-cli",
580
- signals: {
581
- npm: ["mongodb", "mongoose"],
582
- python: ["pymongo", "motor"],
583
- ruby: ["mongo", "mongoid"],
584
- envKeys: [/^MONGO(DB)?_/]
585
- }
586
- },
587
- {
588
- kind: "Snowflake",
589
- label: "Snowflake",
590
- mode: "in-cli",
591
- signals: {
592
- npm: ["snowflake-sdk"],
593
- python: ["snowflake-connector-python", "snowflake-sqlalchemy"],
594
- envKeys: [/^SNOWFLAKE_/]
595
- }
596
- },
597
- {
598
- kind: "BigQuery",
599
- label: "BigQuery",
600
- mode: "in-cli",
601
- signals: {
602
- npm: ["@google-cloud/bigquery"],
603
- python: ["google-cloud-bigquery"],
604
- envKeys: [/^BIGQUERY_/]
605
- }
606
- },
607
- {
608
- kind: "Redshift",
609
- label: "Redshift",
610
- mode: "in-cli",
611
- signals: {
612
- npm: ["node-redshift"],
613
- python: ["redshift-connector"],
614
- envKeys: [/^REDSHIFT_/]
615
- }
616
- },
617
- {
618
- kind: "MSSQL",
619
- label: "SQL Server",
620
- mode: "in-cli",
621
- signals: {
622
- npm: ["mssql", "tedious"],
623
- python: ["pyodbc", "pymssql"],
624
- envKeys: [/^MSSQL_/]
625
- }
626
- },
627
- {
628
- kind: "Supabase",
629
- label: "Supabase",
630
- mode: "in-cli",
631
- signals: {
632
- npm: ["@supabase/supabase-js"],
633
- python: ["supabase"],
634
- envKeys: [/^SUPABASE_/]
635
- }
636
- },
637
- {
638
- kind: "ClickHouse",
639
- label: "ClickHouse",
640
- mode: "in-cli",
641
- signals: {
642
- npm: ["@clickhouse/client"],
643
- python: ["clickhouse-connect", "clickhouse-driver"],
644
- envKeys: [/^CLICKHOUSE_/]
645
- }
646
- },
647
- {
648
- kind: "Convex",
649
- label: "Convex",
650
- mode: "in-cli",
651
- signals: {
652
- npm: ["convex"],
653
- python: ["convex"],
654
- envKeys: [/^CONVEX_/, /^NEXT_PUBLIC_CONVEX_URL$/]
655
- }
656
- },
657
- {
658
- kind: "Stripe",
659
- label: "Stripe",
660
- mode: "in-cli",
661
- signals: {
662
- npm: [
663
- "stripe",
664
- "@stripe/stripe-js",
665
- "@stripe/react-stripe-js"
666
- ],
667
- python: ["stripe"],
668
- ruby: ["stripe"],
669
- envKeys: [/^STRIPE_(SECRET|API)_KEY$/]
670
- }
671
- },
672
- {
673
- kind: "Clerk",
674
- label: "Clerk",
675
- mode: "in-cli",
676
- signals: {
677
- npm: [
678
- "@clerk/nextjs",
679
- "@clerk/clerk-react",
680
- "@clerk/backend",
681
- "@clerk/express",
682
- "@clerk/fastify",
683
- "@clerk/remix"
684
- ],
685
- envKeys: [/^CLERK_SECRET_KEY$/, /^NEXT_PUBLIC_CLERK_/]
686
- }
687
- },
688
- {
689
- kind: "Resend",
690
- label: "Resend",
691
- mode: "in-cli",
692
- signals: {
693
- npm: ["resend"],
694
- python: ["resend"],
695
- envKeys: [/^RESEND_API_KEY$/]
696
- }
697
- },
698
- {
699
- kind: "Shopify",
700
- label: "Shopify",
701
- mode: "in-cli",
702
- signals: {
703
- npm: ["@shopify/shopify-api", "shopify-api-node"],
704
- python: ["shopifyapi"],
705
- envKeys: [/^SHOPIFY_/]
706
- }
707
- },
708
- {
709
- kind: "Klaviyo",
710
- label: "Klaviyo",
711
- mode: "in-cli",
712
- signals: {
713
- npm: ["klaviyo-api"],
714
- python: ["klaviyo-api"],
715
- envKeys: [/^KLAVIYO_/]
716
- }
717
- },
718
- {
719
- kind: "Chargebee",
720
- label: "Chargebee",
721
- mode: "in-cli",
722
- signals: {
723
- npm: ["chargebee"],
724
- python: ["chargebee"],
725
- envKeys: [/^CHARGEBEE_/]
726
- }
727
- },
728
- {
729
- kind: "Paddle",
730
- label: "Paddle",
731
- mode: "in-cli",
732
- signals: {
733
- npm: ["@paddle/paddle-node-sdk", "@paddle/paddle-js"],
734
- envKeys: [/^PADDLE_/]
735
- }
736
- },
737
- {
738
- kind: "Polar",
739
- label: "Polar",
740
- mode: "in-cli",
741
- signals: {
742
- npm: ["@polar-sh/sdk", "@polar-sh/nextjs"],
743
- envKeys: [/^POLAR_/]
744
- }
745
- },
746
- {
747
- kind: "Mailchimp",
748
- label: "Mailchimp",
749
- mode: "in-cli",
750
- signals: {
751
- npm: ["@mailchimp/mailchimp_marketing"],
752
- python: ["mailchimp-marketing"],
753
- envKeys: [/^MAILCHIMP_/]
754
- }
755
- },
756
- {
757
- kind: "CustomerIO",
758
- label: "Customer.io",
759
- mode: "in-cli",
760
- signals: {
761
- npm: ["customerio-node"],
762
- python: ["customerio"],
763
- envKeys: [/^CUSTOMER_?IO_/]
764
- }
765
- },
766
- {
767
- kind: "Typeform",
768
- label: "Typeform",
769
- mode: "in-cli",
770
- signals: {
771
- npm: ["@typeform/api-client"],
772
- envKeys: [/^TYPEFORM_/]
773
- }
774
- },
775
- {
776
- kind: "Sentry",
777
- label: "Sentry",
778
- mode: "in-cli",
779
- signals: {
780
- npm: [
781
- "@sentry/node",
782
- "@sentry/browser",
783
- "@sentry/react",
784
- "@sentry/nextjs"
785
- ],
786
- python: ["sentry-sdk"],
787
- ruby: ["sentry-ruby"]
788
- }
789
- },
790
- {
791
- kind: "Plaid",
792
- label: "Plaid",
793
- mode: "in-cli",
794
- signals: {
795
- npm: ["plaid"],
796
- python: ["plaid-python", "plaid"],
797
- ruby: ["plaid"],
798
- envKeys: [/^PLAID_/]
799
- }
800
- },
801
- {
802
- kind: "Braintree",
803
- label: "Braintree",
804
- mode: "in-cli",
805
- signals: {
806
- npm: ["braintree"],
807
- python: ["braintree"],
808
- ruby: ["braintree"],
809
- envKeys: [/^BRAINTREE_/]
810
- }
811
- },
812
- {
813
- kind: "Square",
814
- label: "Square",
815
- mode: "in-cli",
816
- signals: {
817
- npm: ["square"],
818
- python: ["squareup"],
819
- ruby: ["square"],
820
- envKeys: [/^SQUARE_/]
821
- }
822
- },
823
- {
824
- kind: "GoCardless",
825
- label: "GoCardless",
826
- mode: "in-cli",
827
- signals: {
828
- npm: ["gocardless-nodejs"],
829
- python: ["gocardless-pro"],
830
- ruby: ["gocardless_pro"],
831
- envKeys: [/^GOCARDLESS_/]
832
- }
833
- },
834
- {
835
- kind: "Mollie",
836
- label: "Mollie",
837
- mode: "in-cli",
838
- signals: {
839
- npm: ["@mollie/api-client"],
840
- python: ["mollie-api-python"],
841
- envKeys: [/^MOLLIE_/]
842
- }
843
- },
844
- {
845
- kind: "CheckoutCom",
846
- label: "Checkout.com",
847
- mode: "in-cli",
848
- signals: {
849
- npm: ["checkout-sdk-node"],
850
- python: ["checkout-sdk"],
851
- envKeys: [/^CKO_/, /^CHECKOUT_COM_/]
852
- }
853
- },
854
- {
855
- kind: "Recurly",
856
- label: "Recurly",
857
- mode: "in-cli",
858
- signals: {
859
- npm: ["recurly"],
860
- python: ["recurly"],
861
- ruby: ["recurly"],
862
- envKeys: [/^RECURLY_/]
863
- }
864
- },
865
- {
866
- kind: "RevenueCat",
867
- label: "RevenueCat",
868
- mode: "in-cli",
869
- signals: {
870
- npm: [
871
- "@revenuecat/purchases-js",
872
- "react-native-purchases",
873
- "@revenuecat/purchases-capacitor"
874
- ],
875
- envKeys: [/^REVENUE_?CAT_/]
876
- }
877
- },
878
- {
879
- kind: "Twilio",
880
- label: "Twilio",
881
- mode: "in-cli",
882
- signals: {
883
- npm: ["twilio"],
884
- python: ["twilio"],
885
- ruby: ["twilio-ruby"],
886
- envKeys: [/^TWILIO_/]
887
- }
888
- },
889
- {
890
- kind: "SendGrid",
891
- label: "SendGrid",
892
- mode: "in-cli",
893
- signals: {
894
- npm: ["@sendgrid/mail", "@sendgrid/client"],
895
- python: ["sendgrid"],
896
- ruby: ["sendgrid-ruby"],
897
- envKeys: [/^SENDGRID_/]
898
- }
899
- },
900
- {
901
- kind: "Mailgun",
902
- label: "Mailgun",
903
- mode: "in-cli",
904
- signals: {
905
- npm: ["mailgun.js", "mailgun-js"],
906
- python: ["mailgun"],
907
- ruby: ["mailgun-ruby"],
908
- envKeys: [/^MAILGUN_/]
909
- }
910
- },
911
- {
912
- kind: "Postmark",
913
- label: "Postmark",
914
- mode: "in-cli",
915
- signals: {
916
- npm: ["postmark"],
917
- python: ["postmarker"],
918
- ruby: ["postmark"],
919
- envKeys: [/^POSTMARK_/]
920
- }
921
- },
922
- {
923
- kind: "Brevo",
924
- label: "Brevo",
925
- mode: "in-cli",
926
- signals: {
927
- npm: ["@getbrevo/brevo", "sib-api-v3-sdk"],
928
- python: ["sib-api-v3-sdk"],
929
- envKeys: [/^BREVO_/]
930
- }
931
- },
932
- {
933
- kind: "MailerLite",
934
- label: "MailerLite",
935
- mode: "in-cli",
936
- signals: {
937
- npm: ["@mailerlite/mailerlite-nodejs"],
938
- python: ["mailerlite"],
939
- envKeys: [/^MAILERLITE_/]
940
- }
941
- },
942
- {
943
- kind: "Mailjet",
944
- label: "Mailjet",
945
- mode: "in-cli",
946
- signals: {
947
- npm: ["node-mailjet"],
948
- python: ["mailjet-rest"],
949
- envKeys: [/^MAILJET_/, /^MJ_APIKEY_/]
950
- }
951
- },
952
- {
953
- kind: "LaunchDarkly",
954
- label: "LaunchDarkly",
955
- mode: "in-cli",
956
- signals: {
957
- npm: [
958
- "launchdarkly-node-server-sdk",
959
- "@launchdarkly/node-server-sdk",
960
- "launchdarkly-js-client-sdk",
961
- "launchdarkly-react-client-sdk"
962
- ],
963
- python: ["launchdarkly-server-sdk"],
964
- ruby: ["launchdarkly-server-sdk"],
965
- envKeys: [/^LAUNCHDARKLY_/, /^LD_SDK_KEY$/]
966
- }
967
- },
968
- {
969
- kind: "Optimizely",
970
- label: "Optimizely",
971
- mode: "in-cli",
972
- signals: {
973
- npm: ["@optimizely/optimizely-sdk"],
974
- python: ["optimizely-sdk"],
975
- envKeys: [/^OPTIMIZELY_/]
976
- }
977
- },
978
- {
979
- kind: "Braze",
980
- label: "Braze",
981
- mode: "in-cli",
982
- signals: {
983
- npm: ["@braze/web-sdk", "@braze/react-native-sdk"],
984
- python: ["braze-client"],
985
- envKeys: [/^BRAZE_/]
986
- }
987
- },
988
- {
989
- kind: "Rollbar",
990
- label: "Rollbar",
991
- mode: "in-cli",
992
- signals: {
993
- npm: ["rollbar"],
994
- python: ["rollbar", "pyrollbar"],
995
- ruby: ["rollbar"],
996
- envKeys: [/^ROLLBAR_/]
997
- }
998
- },
999
- {
1000
- kind: "Okta",
1001
- label: "Okta",
1002
- mode: "in-cli",
1003
- signals: {
1004
- npm: [
1005
- "@okta/okta-sdk-nodejs",
1006
- "@okta/okta-auth-js",
1007
- "@okta/okta-react"
1008
- ],
1009
- python: ["okta"],
1010
- envKeys: [/^OKTA_/]
1011
- }
1012
- },
1013
- {
1014
- kind: "WorkOS",
1015
- label: "WorkOS",
1016
- mode: "in-cli",
1017
- signals: {
1018
- npm: ["@workos-inc/node"],
1019
- python: ["workos"],
1020
- envKeys: [/^WORKOS_/]
1021
- }
1022
- },
1023
- {
1024
- kind: "Notion",
1025
- label: "Notion",
1026
- mode: "in-cli",
1027
- signals: {
1028
- npm: ["@notionhq/client"],
1029
- python: ["notion-client"],
1030
- envKeys: [/^NOTION_/]
1031
- }
1032
- },
1033
- {
1034
- kind: "FullStory",
1035
- label: "FullStory",
1036
- mode: "in-cli",
1037
- signals: {
1038
- npm: ["@fullstory/browser", "@fullstory/react-native"],
1039
- envKeys: [/^FULLSTORY_/]
1040
- }
1041
- },
1042
- {
1043
- kind: "Amplitude",
1044
- label: "Amplitude",
1045
- mode: "in-cli",
1046
- signals: {
1047
- npm: [
1048
- "@amplitude/analytics-browser",
1049
- "@amplitude/analytics-node",
1050
- "@amplitude/analytics-react-native",
1051
- "amplitude-js"
1052
- ],
1053
- python: ["amplitude-analytics"],
1054
- envKeys: [/^AMPLITUDE_/]
1055
- }
1056
- },
1057
- {
1058
- kind: "Mixpanel",
1059
- label: "Mixpanel",
1060
- mode: "in-cli",
1061
- signals: {
1062
- npm: ["mixpanel", "mixpanel-browser"],
1063
- python: ["mixpanel"],
1064
- ruby: ["mixpanel-ruby"],
1065
- envKeys: [/^MIXPANEL_/]
1066
- }
1067
- },
1068
- {
1069
- kind: "Pendo",
1070
- label: "Pendo",
1071
- mode: "in-cli",
1072
- signals: {
1073
- npm: ["@pendo/agent"],
1074
- envKeys: [/^PENDO_/]
1075
- }
1076
- },
1077
- {
1078
- kind: "Salesforce",
1079
- label: "Salesforce",
1080
- mode: "deep-link",
1081
- signals: {
1082
- npm: ["jsforce"],
1083
- python: ["simple-salesforce"],
1084
- envKeys: [/^SALESFORCE_/]
1085
- }
1086
- },
1087
- {
1088
- kind: "Hubspot",
1089
- label: "HubSpot",
1090
- mode: "deep-link",
1091
- signals: {
1092
- npm: ["@hubspot/api-client"],
1093
- python: ["hubspot-api-client"],
1094
- envKeys: [/^HUBSPOT_/]
1095
- }
1096
- },
1097
- {
1098
- kind: "Zendesk",
1099
- label: "Zendesk",
1100
- mode: "deep-link",
1101
- signals: {
1102
- npm: ["node-zendesk"],
1103
- python: ["zenpy"],
1104
- envKeys: [/^ZENDESK_/]
1105
- }
1106
- },
1107
- {
1108
- kind: "Intercom",
1109
- label: "Intercom",
1110
- mode: "deep-link",
1111
- signals: {
1112
- npm: ["intercom-client", "@intercom/messenger-js-sdk"],
1113
- python: ["python-intercom"],
1114
- envKeys: [/^INTERCOM_/]
1115
- }
1116
- },
1117
- {
1118
- kind: "Linear",
1119
- label: "Linear",
1120
- mode: "deep-link",
1121
- signals: {
1122
- npm: ["@linear/sdk"],
1123
- envKeys: [/^LINEAR_API_KEY$/]
1124
- }
1125
- },
1126
- {
1127
- kind: "Slack",
1128
- label: "Slack",
1129
- mode: "deep-link",
1130
- signals: {
1131
- npm: ["@slack/web-api", "@slack/bolt"],
1132
- python: ["slack-sdk", "slack-bolt"],
1133
- envKeys: [/^SLACK_(BOT|APP|SIGNING|CLIENT)_/]
1134
- }
1135
- },
1136
- {
1137
- kind: "Github",
1138
- label: "GitHub",
1139
- mode: "deep-link",
1140
- signals: {
1141
- npm: [
1142
- "@octokit/rest",
1143
- "@octokit/core",
1144
- "@octokit/graphql",
1145
- "octokit"
1146
- ],
1147
- python: ["pygithub"],
1148
- ruby: ["octokit"]
1149
- }
1150
- }
1151
- ];
1152
- //#endregion
1153
- //#region src/lib/warehouse-sources/detect.ts
1154
- /**
1155
- * Data warehouse source detection.
1156
- *
1157
- * Scans a project for codebase signals (npm/python/ruby deps, `.env` key
1158
- * names) and matches them against the `SOURCE_DETECTORS` registry. Pure
1159
- * function: no store mutations, no UI calls. Reads files locally — only the
1160
- * wizard process does this; the agent never sees secret values.
1161
- *
1162
- * Note we only read `.env` KEY NAMES, never values.
1163
- */
1164
- const MAX_DEPTH = 3;
1165
- /**
1166
- * Detect which warehouse sources the project at `installDir` appears to use.
1167
- * Returns one `DetectedSource` per matched registry entry (kinds are unique,
1168
- * so the result is naturally deduped).
1169
- */
1170
- function detectWarehouseSources(installDir) {
1171
- const signals = collectSignals(installDir);
1172
- const detected = [];
1173
- for (const detector of SOURCE_DETECTORS) {
1174
- const match = matchDetector(detector, signals);
1175
- if (match) detected.push({
1176
- kind: detector.kind,
1177
- label: detector.label,
1178
- mode: detector.mode,
1179
- matchedSignal: match
1180
- });
1181
- }
1182
- return detected;
1183
- }
1184
- /** Returns a human-readable description of the first matching signal, or null. */
1185
- function matchDetector(detector, signals) {
1186
- const { npm, python, ruby, envKeys } = detector.signals;
1187
- const npmHit = npm?.find((dep) => signals.npm.has(dep));
1188
- if (npmHit) return `found \`${npmHit}\` in package.json`;
1189
- const pyHit = python?.find((dep) => signals.python.has(dep));
1190
- if (pyHit) return `found \`${pyHit}\` in Python dependencies`;
1191
- const rubyHit = ruby?.find((gem) => signals.ruby.has(gem));
1192
- if (rubyHit) return `found \`${rubyHit}\` in Gemfile`;
1193
- if (envKeys) {
1194
- for (const key of signals.envKeys) if (envKeys.some((re) => re.test(key))) return `found \`${key}\` in .env`;
1195
- }
1196
- return null;
1197
- }
1198
- function collectSignals(installDir) {
1199
- const signals = {
1200
- npm: /* @__PURE__ */ new Set(),
1201
- python: /* @__PURE__ */ new Set(),
1202
- ruby: /* @__PURE__ */ new Set(),
1203
- envKeys: /* @__PURE__ */ new Set()
1204
- };
1205
- walkProjectFiles(installDir, (name, fullPath) => ingestFile(name, fullPath, signals), MAX_DEPTH);
1206
- return signals;
1207
- }
1208
- /**
1209
- * Route a file to the right parser BY NAME, reading its contents only when the
1210
- * name matches one of the ~6 manifests we care about. Checking the name first
1211
- * avoids slurping every file in the tree (lockfiles, binaries, assets) into
1212
- * memory just to discard it.
1213
- */
1214
- function ingestFile(name, fullPath, signals) {
1215
- const ingest = ingestorFor(name);
1216
- if (!ingest) return;
1217
- const content = safeReadFile(fullPath);
1218
- if (content === null) return;
1219
- ingest(content, signals);
1220
- }
1221
- /** Pick the parser for a manifest filename, or null if it's not one we read. */
1222
- function ingestorFor(name) {
1223
- if (name === "package.json") return addNpmDeps;
1224
- if (name === "requirements.txt") return (c, s) => parseRequirementsTxt(c).forEach((d) => s.python.add(d));
1225
- if (name === "pyproject.toml") return (c, s) => parsePyprojectToml(c).forEach((d) => s.python.add(d));
1226
- if (name === "Pipfile") return (c, s) => parsePipfile(c).forEach((d) => s.python.add(d));
1227
- if (name === "Gemfile") return (c, s) => parseGemfile(c).forEach((g) => s.ruby.add(g));
1228
- if (name.startsWith(".env")) return (c, s) => parseEnvKeys(c).forEach((k) => s.envKeys.add(k));
1229
- return null;
1230
- }
1231
- function addNpmDeps(content, signals) {
1232
- try {
1233
- const pkg = JSON.parse(content);
1234
- for (const dep of Object.keys({
1235
- ...pkg.dependencies,
1236
- ...pkg.devDependencies
1237
- })) signals.npm.add(dep);
1238
- } catch (error) {
1239
- analytics.captureException(error instanceof Error ? error : new Error(String(error)), { step: "detectWarehouseSources.parsePackageJson" });
1240
- }
1241
- }
1242
- /** Extract gem names from `gem 'name'` declarations. */
1243
- function parseGemfile(content) {
1244
- const gems = [];
1245
- for (const match of content.matchAll(/^\s*gem\s+['"]([^'"]+)['"]/gm)) gems.push(match[1]);
1246
- return gems;
1247
- }
1248
- /** Extract KEY NAMES from a dotenv file. Values are intentionally discarded. */
1249
- function parseEnvKeys(content) {
1250
- const keys = [];
1251
- for (const line of content.split("\n")) {
1252
- const trimmed = line.trim();
1253
- if (!trimmed || trimmed.startsWith("#")) continue;
1254
- const match = trimmed.match(/^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/);
1255
- if (match) keys.push(match[1]);
1256
- }
1257
- return keys;
1258
- }
1259
- //#endregion
1260
- //#region src/lib/programs/warehouse-source/detect.ts
1261
- /**
1262
- * Warehouse-source program detection step.
1263
- *
1264
- * Thin adapter over `detectWarehouseSources` that writes results into
1265
- * frameworkContext for the intro screen, plus the `[ABORT]` cases the
1266
- * data-warehouse-source-setup skill can emit.
1267
- */
1268
- /** frameworkContext key holding the detected sources (set on success). */
1269
- const DETECTED_WAREHOUSE_SOURCES_KEY = "detectedWarehouseSources";
1270
- /**
1271
- * Read the detected sources out of frameworkContext. Single accessor shared by
1272
- * the intro screen and the prompt builder so the key + cast live in one place.
1273
- */
1274
- function getDetectedWarehouseSources(session) {
1275
- return session.frameworkContext["detectedWarehouseSources"] ?? [];
1276
- }
1277
- /** `[ABORT] <reason>` cases the skill can emit. */
1278
- const WAREHOUSE_ABORT_CASES = [{
1279
- match: /^no data sources? detected\.?$/i,
1280
- message: "No data source detected",
1281
- body: "The agent could not confirm a data warehouse source to connect. Run this command from a project that uses a supported source (a database, Stripe, etc.).",
1282
- docsUrl: "https://posthog.com/docs/data-warehouse"
1283
- }, {
1284
- match: /^source creation failed\.?$/i,
1285
- message: "Source creation failed",
1286
- body: "PostHog could not create the data warehouse source with the credentials provided. Double-check the connection details and try again, or set the source up directly in the PostHog app.",
1287
- docsUrl: "https://posthog.com/docs/data-warehouse"
1288
- }];
1289
- /**
1290
- * Scan `session.installDir` for warehouse-source signals. Writes the detected
1291
- * sources (or a `detectError`) into frameworkContext for the intro screen.
1292
- */
1293
- function detectWarehousePrerequisites(session, setFrameworkContext) {
1294
- const fail = (error) => setFrameworkContext("detectError", error);
1295
- const installDir = session.installDir;
1296
- if (!existsSync(installDir)) {
1297
- fail({
1298
- kind: "bad-directory",
1299
- path: installDir,
1300
- reason: "missing"
1301
- });
1302
- return;
1303
- }
1304
- try {
1305
- if (!statSync(installDir).isDirectory()) {
1306
- fail({
1307
- kind: "bad-directory",
1308
- path: installDir,
1309
- reason: "not-dir"
1310
- });
1311
- return;
1312
- }
1313
- } catch (error) {
1314
- analytics.captureException(error instanceof Error ? error : new Error(String(error)), {
1315
- step: "detectWarehousePrerequisites.stat",
1316
- path: installDir
1317
- });
1318
- fail({
1319
- kind: "bad-directory",
1320
- path: installDir,
1321
- reason: "unreadable"
1322
- });
1323
- return;
1324
- }
1325
- const sources = detectWarehouseSources(installDir);
1326
- if (sources.length === 0) {
1327
- fail({ kind: "no-sources" });
1328
- return;
1329
- }
1330
- analytics.setTag("warehouse_source_kinds", sources.map((s) => s.kind).join(","));
1331
- analytics.setTag("warehouse_source_modes", sources.map((s) => `${s.kind}:${s.mode}`).join(","));
1332
- analytics.setTag("warehouse_source_count", sources.length);
1333
- setFrameworkContext(DETECTED_WAREHOUSE_SOURCES_KEY, sources);
1334
- }
1335
- //#endregion
1336
528
  //#region src/lib/programs/warehouse-source/steps.ts
1337
529
  const WAREHOUSE_SOURCE_PROGRAM = [
1338
530
  {
@@ -1636,7 +828,10 @@ const auditConfig = {
1636
828
  run: auditRun,
1637
829
  allowedTools: ["Agent"],
1638
830
  disallowedTools: [WIZARD_TOOL_NAMES.wizardAsk],
1639
- cliOptions: { ...headlessOption }
831
+ cliOptions: {
832
+ ...headlessOption,
833
+ ...regionOption
834
+ }
1640
835
  };
1641
836
  //#endregion
1642
837
  //#region src/lib/programs/events-audit/steps.ts
@@ -2603,10 +1798,12 @@ const DISPLAY_NAME = {
2603
1798
  };
2604
1799
  /**
2605
1800
  * Variants the wizard can wire up source-map upload for automatically. The
2606
- * native variants (react-native, android, flutter, ios) are recognised but not
2607
- * yet automatable, so the agentic picker treats them as non-instrumentable.
1801
+ * native variants (react-native, flutter) are recognised but not yet
1802
+ * automatable, so the agentic picker treats them as non-instrumentable.
2608
1803
  */
2609
1804
  const AUTOMATABLE_VARIANTS = [
1805
+ "android",
1806
+ "ios",
2610
1807
  "web",
2611
1808
  "nextjs",
2612
1809
  "node",
@@ -2617,6 +1814,11 @@ const AUTOMATABLE_VARIANTS = [
2617
1814
  "webpack",
2618
1815
  "rollup"
2619
1816
  ];
1817
+ /**
1818
+ * Variants the wizard pre-installs a machine-global `posthog-cli` for — their
1819
+ * build shells out to it with no npx / local-dep fallback. JS variants stay out.
1820
+ */
1821
+ const VARIANTS_REQUIRING_POSTHOG_CLI = new Set(["ios", "android"]);
2620
1822
  /** `[ABORT] <reason>` cases the source maps skill can emit. */
2621
1823
  const SOURCE_MAPS_ABORT_CASES = [{
2622
1824
  match: /^no posthog sdk detected$/i,
@@ -2690,6 +1892,28 @@ function buildSourceMapsUploadPrompt(params) {
2690
1892
  const { displayName, variant, skillId, projectPath, projectId, host, settingsUrl, uiHost } = params;
2691
1893
  const platformLabel = displayName ?? variant;
2692
1894
  const inSubproject = projectPath != null && projectPath !== ".";
1895
+ const projectLine = inSubproject ? `- Project directory (relative to the wizard's working directory): ${projectPath}` : "- Project directory: the wizard's working directory (even when it sits inside a larger git repo, this directory is the project root)";
1896
+ const credentialSteps = `STEP 4 — Make the credentials readable at build time. (skill: "Make credentials available at build time")
1897
+ Follow the skill's step. Wizard-specific: if it calls for a loader (e.g.
1898
+ \`dotenv\`), install it SILENTLY — do NOT ask the user or call wizard_ask.
1899
+ Skip this step entirely if the platform already auto-loads .env.
1900
+
1901
+ STEP 5 — Write the credentials to the env file. (skill: "Write credentials to the env file")
1902
+ Use the wizard-tools MCP server. Reuse the env file the skill tells you to
1903
+ pick — the prerequisite PostHog integration usually already wrote
1904
+ POSTHOG_* vars to one, so seed your keys alongside them.
1905
+ - First call check_env_keys on that file (returns present/absent, never
1906
+ values — don't read the file directly).
1907
+ - Env tool path rule: ${inSubproject ? `Tool filePaths are relative to the wizard's working directory, not the selected project directory. Treat the skill's env path as relative to the selected project and prefix it with \`${projectPath}/\` when calling the tools: for example, pass \`${projectPath}/.env\`, not \`.env\` (which would target the wizard's working directory).` : `Tool filePaths are relative to the wizard's working directory. For an env file at this project root, pass \`.env\`; never prefix it with this directory's path inside an ancestor repository.`}
1908
+ - Then call set_env_values, passing the STEP 1 secretRef as a value
1909
+ object, not a literal string:
1910
+ values: {
1911
+ "POSTHOG_CLI_API_KEY": { secretRef: "<the ref from STEP 1>" },
1912
+ "POSTHOG_CLI_PROJECT_ID": "${projectId}",
1913
+ "POSTHOG_CLI_HOST": "${uiHost}"
1914
+ }
1915
+ Variable names follow the skill's per-uploader conventions. The wizard
1916
+ resolves the ref locally before writing, so you never see the key value.`;
2693
1917
  return `You are wiring up PostHog Error Tracking source map upload for this ${platformLabel} project.
2694
1918
 
2695
1919
  Project context:
@@ -2697,7 +1921,7 @@ Project context:
2697
1921
  - PostHog Host: ${host}
2698
1922
  - Detected platform: ${platformLabel}
2699
1923
  - Skill to use: ${skillId}
2700
- ${inSubproject ? `- Project directory (relative to repo root): ${projectPath}` : "- Project directory: the repo root"}
1924
+ ${projectLine}
2701
1925
  - Personal API keys settings page: ${settingsUrl}
2702
1926
 
2703
1927
  All file changes, build/run commands, and config edits target the project directory above${inSubproject ? ` — this is a monorepo, so scope your work to \`${projectPath}\` and do not touch other packages` : ""}.
@@ -2765,26 +1989,7 @@ STEP 3 — Apply build-config changes. (skill: "Apply build-config changes")
2765
1989
  Make the bundler / build-config changes the skill's step instructs. The
2766
1990
  skill and its reference are the source of truth for this platform.
2767
1991
 
2768
- STEP 4 — Make the credentials readable at build time. (skill: "Make credentials available at build time")
2769
- Follow the skill's step. Wizard-specific: if it calls for a loader (e.g.
2770
- \`dotenv\`), install it SILENTLY — do NOT ask the user or call wizard_ask.
2771
- Skip this step entirely if the platform already auto-loads .env.
2772
-
2773
- STEP 5 — Write the credentials to the env file. (skill: "Write credentials to the env file")
2774
- Use the wizard-tools MCP server. Reuse the env file the skill tells you to
2775
- pick — the prerequisite PostHog integration usually already wrote
2776
- POSTHOG_* vars to one, so seed your keys alongside them.
2777
- - First call check_env_keys on that file (returns present/absent, never
2778
- values — don't read the file directly).
2779
- - Then call set_env_values, passing the STEP 1 secretRef as a value
2780
- object, not a literal string:
2781
- values: {
2782
- "POSTHOG_CLI_API_KEY": { secretRef: "<the ref from STEP 1>" },
2783
- "POSTHOG_CLI_PROJECT_ID": "${projectId}",
2784
- "POSTHOG_CLI_HOST": "${host}"
2785
- }
2786
- Variable names follow the skill's per-uploader conventions. The wizard
2787
- resolves the ref locally before writing, so you never see the key value.
1992
+ ${credentialSteps}
2788
1993
 
2789
1994
  STEP 6 — Identify the build AND run commands. (skill: "Identify the build and run commands")
2790
1995
  Per the skill, resolve the production BUILD command and the RUN command
@@ -2822,13 +2027,24 @@ STEP 8 — Offer to test the local setup. (skill: "Test the local setup")
2822
2027
  If "yes", follow the skill's "Test the local setup" step for the
2823
2028
  platform-appropriate affordance, the captureException shape, the
2824
2029
  placement, and the read-before-edit / always-revert rules. Then pause for
2825
- the user with wizard_ask, baking the EXACT build and run commands from
2826
- STEP 6 (and the exact button label / route) into the prompt as literal,
2827
- copy-pasteable steps. Separate each numbered step with \\n\\n so the TUI
2828
- renders them as distinct lines:
2030
+ the user with wizard_ask, baking the build-and-run flow (and the exact
2031
+ button label / route) into the prompt as literal, copy-pasteable
2032
+ numbered steps:
2033
+ - Steps 1-2: the production build, then launching the app and
2034
+ triggering the test affordance. Source them from STEP 6 and the
2035
+ skill's "Test the local setup" step — when the skill gives the
2036
+ platform's test flow as verbatim steps (IDE-driven platforms like
2037
+ Xcode do), use its wording and do NOT invent CLI build commands,
2038
+ debugger steps, or relaunch steps it doesn't state. Quote CLI
2039
+ commands verbatim. When build and run are one action (an IDE Run),
2040
+ fold them into step 1 and make step 2 just triggering the affordance.
2041
+ - The last step is always the Error Tracking check, exactly as in the
2042
+ template.
2043
+ Separate each numbered step with \\n\\n so the TUI renders them as
2044
+ distinct lines:
2829
2045
  {
2830
2046
  id: "test-done",
2831
- prompt: "1) Run \`<your detected build command>\` to upload source maps and build the app with the test affordance.\\n\\n2) Start the app with \`<your detected run command>\`, then click the \\"<your test button label>\\" button (or hit \`<your test route>\`).\\n\\n3) Open Error Tracking in PostHog (${uiHost}/project/${projectId}/error_tracking) and confirm the test error appears with a source-resolved stack trace pointing at real source files (not minified bundle paths).\\n\\nWhen you're done, select Continue and I'll revert the test code.",
2047
+ prompt: "1) <production build step — it uploads source maps and builds the app with the test affordance>\\n\\n2) <run step>, then click the \\"<your test button label>\\" button (or hit \`<your test route>\`).\\n\\n3) Open Error Tracking in PostHog (${uiHost}/project/${projectId}/error_tracking) and confirm the test error appears with a source-resolved stack trace pointing at real source files (not minified bundle paths).\\n\\nWhen you're done, select Continue and I'll revert the test code.",
2832
2048
  kind: "single",
2833
2049
  options: [{ label: "Continue (revert test code)", value: "continue" }]
2834
2050
  }
@@ -3170,9 +2386,135 @@ const getContentBlocks$1 = (store) => pace([
3170
2386
  }
3171
2387
  ]);
3172
2388
  //#endregion
2389
+ //#region src/steps/install-cli-steering/index.ts
2390
+ const dirExists = (...segments) => {
2391
+ try {
2392
+ return fs$1.existsSync(path$1.join(os.homedir(), ...segments));
2393
+ } catch {
2394
+ return false;
2395
+ }
2396
+ };
2397
+ const CLI_STEERING_TARGETS = [
2398
+ {
2399
+ id: "claude-code",
2400
+ name: "Claude Code",
2401
+ instructionsPath: () => path$1.join(os.homedir(), ".claude", "CLAUDE.md"),
2402
+ isDetected: () => dirExists(".claude")
2403
+ },
2404
+ {
2405
+ id: "codex",
2406
+ name: "Codex",
2407
+ instructionsPath: () => path$1.join(os.homedir(), ".codex", "AGENTS.md"),
2408
+ isDetected: () => dirExists(".codex")
2409
+ },
2410
+ {
2411
+ id: "gemini",
2412
+ name: "Gemini CLI",
2413
+ instructionsPath: () => path$1.join(os.homedir(), ".gemini", "GEMINI.md"),
2414
+ isDetected: () => dirExists(".gemini")
2415
+ }
2416
+ ];
2417
+ function findTarget(id) {
2418
+ return CLI_STEERING_TARGETS.find((target) => target.id === id);
2419
+ }
2420
+ function detectTargets() {
2421
+ return CLI_STEERING_TARGETS.filter((target) => target.isDetected());
2422
+ }
2423
+ const spawnOptions = {
2424
+ encoding: "utf-8",
2425
+ shell: process.platform === "win32"
2426
+ };
2427
+ /**
2428
+ * Install or update the PostHog CLI in the user's environment. `npm install
2429
+ * --global @posthog/cli@latest` covers both first-time installs and upgrades
2430
+ * for existing npm-installed CLIs.
2431
+ */
2432
+ function installOrUpdatePostHogCli() {
2433
+ const args = [
2434
+ "install",
2435
+ "--global",
2436
+ "@posthog/cli@latest"
2437
+ ];
2438
+ debug(`Running npm ${args.join(" ")}`);
2439
+ const result = spawnSync("npm", args, spawnOptions);
2440
+ if (result.error) return {
2441
+ success: false,
2442
+ error: `Failed to run npm: ${result.error.message}. Is Node.js installed?`,
2443
+ errorObject: result.error
2444
+ };
2445
+ if (result.status !== 0) {
2446
+ const message = (result.stderr || result.stdout || "").trim() || `npm install --global @posthog/cli@latest exited with status ${result.status ?? "unknown"}`;
2447
+ return {
2448
+ success: false,
2449
+ error: message,
2450
+ errorObject: new Error(message)
2451
+ };
2452
+ }
2453
+ return { success: true };
2454
+ }
2455
+ /**
2456
+ * Delegate the actual write to the installed `posthog-cli api agents-md
2457
+ * install`. The steering snippet lives in the CLI (its single source of truth),
2458
+ * so the command should run only after `installOrUpdatePostHogCli` refreshes
2459
+ * the CLI to the latest release.
2460
+ */
2461
+ function installSteeringSnippet(filePath) {
2462
+ const args = [
2463
+ "api",
2464
+ "agents-md",
2465
+ "install",
2466
+ "--path",
2467
+ filePath
2468
+ ];
2469
+ debug(`Running posthog-cli ${args.join(" ")}`);
2470
+ const result = spawnSync("posthog-cli", args, {
2471
+ ...spawnOptions,
2472
+ env: {
2473
+ ...process.env,
2474
+ POSTHOG_CLI_EXPERIMENTAL_API: "1"
2475
+ }
2476
+ });
2477
+ if (result.error) return {
2478
+ success: false,
2479
+ filePath,
2480
+ error: `Failed to run posthog-cli: ${result.error.message}. Make sure npm's global bin directory is on your PATH.`
2481
+ };
2482
+ if (result.status !== 0) return {
2483
+ success: false,
2484
+ filePath,
2485
+ error: (result.stderr || result.stdout || "").trim() || `posthog-cli exited with status ${result.status ?? "unknown"}`
2486
+ };
2487
+ return {
2488
+ success: true,
2489
+ filePath
2490
+ };
2491
+ }
2492
+ //#endregion
3173
2493
  //#region src/lib/programs/error-tracking-upload-source-maps/index.ts
3174
2494
  const REPORT_FILE$1 = "posthog-source-maps-report.md";
3175
2495
  const DOCS_URL$1 = "https://posthog.com/docs/error-tracking/upload-source-maps";
2496
+ let postHogCliInstallAttempted = false;
2497
+ /**
2498
+ * Pre-install posthog-cli for variants that need a machine-global copy
2499
+ * (`VARIANTS_REQUIRING_POSTHOG_CLI`). The agent can't — warlock blocks
2500
+ * `npm install -g` — so the wizard does it in-process. Warn, don't fail.
2501
+ */
2502
+ function ensurePostHogCli(variant) {
2503
+ if (postHogCliInstallAttempted) return;
2504
+ postHogCliInstallAttempted = true;
2505
+ const result = installOrUpdatePostHogCli();
2506
+ if (!result.success) {
2507
+ analytics.wizardCapture("source maps posthog-cli preinstall failed", {
2508
+ variant,
2509
+ error: String(result.error).slice(0, 500)
2510
+ });
2511
+ analytics.captureException(result.errorObject ?? /* @__PURE__ */ new Error(`posthog-cli pre-install failed: ${result.error}`), {
2512
+ source: "source_maps_cli_preinstall",
2513
+ variant
2514
+ });
2515
+ getUI().log.warn(`Could not pre-install posthog-cli (${result.error}). Your release build will fail to upload debug symbols until it's installed: npm install -g @posthog/cli@latest`);
2516
+ }
2517
+ }
3176
2518
  const errorTrackingUploadSourceMapsConfig = {
3177
2519
  command: "upload-source-maps",
3178
2520
  description: "Upload source maps to PostHog Error Tracking",
@@ -3204,6 +2546,7 @@ const errorTrackingUploadSourceMapsConfig = {
3204
2546
  customPrompt: (ctx) => {
3205
2547
  const { variant, displayName, projectPath, skillId } = readSelection();
3206
2548
  if (!skillId || !variant) return SOURCE_MAPS_DETECTION_FAILED_PROMPT;
2549
+ if (VARIANTS_REQUIRING_POSTHOG_CLI.has(variant)) ensurePostHogCli(variant);
3207
2550
  const uiHost = ctx.host.appHost.replace(/\/$/, "");
3208
2551
  return buildSourceMapsUploadPrompt({
3209
2552
  displayName,
@@ -3444,23 +2787,6 @@ function detectSelfDrivingPrerequisites(session, setFrameworkContext) {
3444
2787
  }
3445
2788
  //#endregion
3446
2789
  //#region src/lib/programs/self-driving/detect-agentic.ts
3447
- /**
3448
- * Agentic (Haiku) detection for self-driving's integration phase.
3449
- *
3450
- * Mirrors source-maps: the integration-detect screen runs `detectSelfDriving-
3451
- * IntegrationProjects` (the shared Haiku detector with the integration framework
3452
- * targets), shows a project map, and the user picks one. This file supplies the
3453
- * targets, maps the result back to `Integration`s, and classifies each project
3454
- * as instrumentable (a framework the wizard supports that doesn't already have
3455
- * PostHog). The screen writes the choice to the session; `prepSelfDriving-
3456
- * Integration` then gathers the chosen project's framework context before the
3457
- * integration agent runs (the runner scopes the install dir).
3458
- */
3459
- /** Integration framework targets for the agentic detector (id → display name). */
3460
- const INTEGRATION_TARGETS = Object.entries(FRAMEWORK_REGISTRY).map(([id, config]) => ({
3461
- id,
3462
- name: config.metadata.name
3463
- }));
3464
2790
  const INTEGRATION_IDS = new Set(Object.values(Integration));
3465
2791
  function classify(integration, hasPostHog) {
3466
2792
  if (integration == null) return {
@@ -3492,11 +2818,7 @@ function toIntegrationReport(report) {
3492
2818
  }
3493
2819
  /** Run the Haiku detector over the repo and classify projects for integration. */
3494
2820
  async function detectSelfDrivingIntegrationProjects(session, onEvent) {
3495
- return toIntegrationReport(await detectProjectsWithAgent(session, {
3496
- targets: INTEGRATION_TARGETS,
3497
- purpose: "set up a PostHog SDK integration",
3498
- onEvent
3499
- }));
2821
+ return toIntegrationReport(await detectIntegrationProjects(session, { onEvent }));
3500
2822
  }
3501
2823
  /**
3502
2824
  * Prepare the integration phase after the user picked a project on the
@@ -3523,36 +2845,10 @@ async function prepSelfDrivingIntegration(session) {
3523
2845
  }
3524
2846
  //#endregion
3525
2847
  //#region src/lib/programs/self-driving/steps.ts
3526
- /**
3527
- * Self-driving program step list.
3528
- *
3529
- * detect → intro → integration-check → health-check → auth → integrate-detect →
3530
- * integrate-run → self-driving-handoff → run → outro. A deterministic check in
3531
- * `detect` decides whether PostHog is already in the project: found → the
3532
- * integration screens are skipped and the integrate-run phase never shows; not
3533
- * found → integration-check reports it and the only action sets up PostHog.
3534
- * After auth, `integrate-detect` runs the Haiku detector and has the user pick
3535
- * which project to set PostHog up in (a monorepo can have several);
3536
- * `integrate-run` then runs the real integration program's agent (its own task
3537
- * list) in that project. `self-driving-handoff` then bridges to Self-driving
3538
- * ("PostHog is installed — now set up Self-driving") before the Self-driving
3539
- * run. No keep-skills step: the setup skill is transient, so postRun removes it.
3540
- */
3541
2848
  /** True once detection found PostHog already present in the project. */
3542
2849
  const postHogPresent = (session) => session.frameworkContext[POSTHOG_PRESENT_KEY] === true;
3543
- /**
3544
- * Absolute dir to integrate into: the picked sub-app, else the repo root.
3545
- * The picked path originates from LLM output; if it resolves outside the
3546
- * repo (defense-in-depth on top of the coerce-layer clamp), fall back to
3547
- * the root rather than run the agent elsewhere.
3548
- */
3549
- const integrationDir = (session) => {
3550
- const rel = session.frameworkContext[SELF_DRIVING_INTEGRATE_PATH_KEY];
3551
- if (typeof rel !== "string" || rel === ".") return session.installDir;
3552
- const root = resolve(session.installDir);
3553
- const dir = resolve(root, rel);
3554
- return dir === root || dir.startsWith(root + sep) ? dir : root;
3555
- };
2850
+ /** Absolute dir to integrate into: the picked sub-app (LLM output — the shared resolver clamps escapes), else the repo root. */
2851
+ const integrationDir = (session) => resolveProjectDir(session.installDir, session.frameworkContext[SELF_DRIVING_INTEGRATE_PATH_KEY]);
3556
2852
  const SELF_DRIVING_PROGRAM = [
3557
2853
  {
3558
2854
  id: "detect",
@@ -4433,13 +3729,13 @@ const mcpAddCommand = {
4433
3729
  function runMcpAdd(argv) {
4434
3730
  const features = parseFeatures(argv.features);
4435
3731
  (async () => {
4436
- const { readApiKeyFromEnv } = await import("./env-api-key-cjD4yfGT.js").then((n) => n.t);
3732
+ const { readApiKeyFromEnv } = await import("./env-api-key-C3LzH8Lr.js").then((n) => n.t);
4437
3733
  const apiKey = argv.apiKey || readApiKeyFromEnv();
4438
3734
  const debug = argv.debug;
4439
3735
  const localMcp = argv.local;
4440
3736
  try {
4441
- const { startTUI } = await import("./start-tui-DgSKFMVh.js");
4442
- const { buildSession } = await import("./wizard-session-C5lZPPEc.js");
3737
+ const { startTUI } = await import("./start-tui-Cwc-PFma.js");
3738
+ const { buildSession } = await import("./wizard-session-DWHe83uk.js");
4443
3739
  const tui = startTUI(VERSION, Program.McpAdd);
4444
3740
  tui.store.session = buildSession({
4445
3741
  debug,
@@ -4451,7 +3747,7 @@ function runMcpAdd(argv) {
4451
3747
  } catch (error) {
4452
3748
  if (!isTUIUnavailable(error)) throw error;
4453
3749
  setUI(new LoggingUI());
4454
- const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-D5qsqCkj.js").then((n) => n.r);
3750
+ const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-Bv2CBSil.js").then((n) => n.r);
4455
3751
  await addMCPServerToClientsStep({
4456
3752
  local: localMcp,
4457
3753
  features,
@@ -4490,8 +3786,8 @@ function runMcpRemove(argv) {
4490
3786
  const debug = argv.debug;
4491
3787
  const localMcp = argv.local;
4492
3788
  try {
4493
- const { startTUI } = await import("./start-tui-DgSKFMVh.js");
4494
- const { buildSession } = await import("./wizard-session-C5lZPPEc.js");
3789
+ const { startTUI } = await import("./start-tui-Cwc-PFma.js");
3790
+ const { buildSession } = await import("./wizard-session-DWHe83uk.js");
4495
3791
  const tui = startTUI(VERSION, Program.McpRemove);
4496
3792
  tui.store.session = buildSession({
4497
3793
  debug,
@@ -4500,7 +3796,7 @@ function runMcpRemove(argv) {
4500
3796
  });
4501
3797
  } catch {
4502
3798
  setUI(new LoggingUI());
4503
- const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-D5qsqCkj.js").then((n) => n.r);
3799
+ const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-Bv2CBSil.js").then((n) => n.r);
4504
3800
  await removeMCPServerFromClientsStep({ local: localMcp });
4505
3801
  }
4506
3802
  })();
@@ -4522,8 +3818,8 @@ function runMcpTutorial(argv) {
4522
3818
  const debug = argv.debug;
4523
3819
  const localMcp = argv.local;
4524
3820
  try {
4525
- const { startTUI } = await import("./start-tui-DgSKFMVh.js");
4526
- const { buildSession } = await import("./wizard-session-C5lZPPEc.js");
3821
+ const { startTUI } = await import("./start-tui-Cwc-PFma.js");
3822
+ const { buildSession } = await import("./wizard-session-DWHe83uk.js");
4527
3823
  const tui = startTUI(VERSION, Program.McpTutorial);
4528
3824
  tui.store.session = buildSession({
4529
3825
  debug,
@@ -4603,10 +3899,10 @@ function runWizard(config, options) {
4603
3899
  (async () => {
4604
3900
  try {
4605
3901
  const installDir = options.installDir || process.cwd();
4606
- const { startTUI } = await import("./start-tui-DgSKFMVh.js");
4607
- const { buildSession, RunPhase } = await import("./wizard-session-C5lZPPEc.js");
4608
- const { TaskStreamPush } = await import("./task-stream-0Pk0tPBN.js");
4609
- const { PostHogDestination } = await import("./posthog-DwKlq0HM.js");
3902
+ const { startTUI } = await import("./start-tui-Cwc-PFma.js");
3903
+ const { buildSession, RunPhase } = await import("./wizard-session-DWHe83uk.js");
3904
+ const { TaskStreamPush } = await import("./task-stream-DQT3vjwS.js");
3905
+ const { PostHogDestination } = await import("./posthog-DZZbziJ1.js");
4610
3906
  tui = startTUI(WIZARD_VERSION, config.id);
4611
3907
  const activeTui = tui;
4612
3908
  const session = buildSession({
@@ -4639,6 +3935,7 @@ function runWizard(config, options) {
4639
3935
  getCredentials: () => activeTui.store.session.credentials,
4640
3936
  onError: (err) => logToFile("[task-stream-push]", err.message)
4641
3937
  })],
3938
+ eventPlanPath: config.eventPlanFile ? join$1(session.installDir, config.eventPlanFile) : void 0,
4642
3939
  enabled: taskStreamEnabled
4643
3940
  });
4644
3941
  const activeStream = taskStream;
@@ -4670,7 +3967,7 @@ function runWizard(config, options) {
4670
3967
  if (shown(step)) await advanceStep(step, activeTui.store, config);
4671
3968
  }
4672
3969
  else if (skipAgent) {
4673
- const { getOrAskForProjectData } = await import("./setup-utils-BQCl28D8.js").then((n) => n.r);
3970
+ const { getOrAskForProjectData } = await import("./setup-utils-Cb5uACEO.js").then((n) => n.r);
4674
3971
  const { projectApiKey, host, accessToken, projectId } = await getOrAskForProjectData({
4675
3972
  signup: session.signup,
4676
3973
  ci: session.ci,
@@ -4732,15 +4029,14 @@ function modeLabel(mode) {
4732
4029
  return mode === "headless" ? "Headless" : "CI";
4733
4030
  }
4734
4031
  /**
4735
- * The single non-interactive validation layer: defaults region and requires
4736
- * api-key and install-dir. Every non-interactive entry point routes through
4032
+ * The single non-interactive validation layer: requires api-key and
4033
+ * install-dir. Every non-interactive entry point routes through
4737
4034
  * `runNonInteractive`, so this is the one place these checks live. UI must be
4738
4035
  * initialized before calling.
4739
4036
  */
4740
4037
  function validateNonInteractiveOptions(options, mode) {
4741
4038
  const label = modeLabel(mode);
4742
4039
  const keyHint = mode === "headless" ? "personal API key phx_xxx or pha_ OAuth access token" : "personal API key phx_xxx";
4743
- if (!options.region) options.region = "us";
4744
4040
  if (!options.apiKey) {
4745
4041
  getUI().intro("PostHog Wizard");
4746
4042
  getUI().log.error(`${label} mode requires --api-key (${keyHint})`);
@@ -4772,11 +4068,11 @@ function runNonInteractive(config, options, mode) {
4772
4068
  analytics.setTag("build", mode);
4773
4069
  (async () => {
4774
4070
  const path = await import("path");
4775
- const { buildSession, RunPhase, OutroKind } = await import("./wizard-session-C5lZPPEc.js");
4776
- const { readEnvironment } = await import("./environment-F1yw21dG.js").then((n) => n.t);
4777
- const { readApiKeyFromEnv } = await import("./env-api-key-cjD4yfGT.js").then((n) => n.t);
4778
- const { configureLogFileFromEnvironment, logToFile } = await import("./debug-BOFxiVVs.js");
4779
- const { wizardAbort, WizardError } = await import("./wizard-abort-UCm4Pd5m.js");
4071
+ const { buildSession, RunPhase, OutroKind } = await import("./wizard-session-DWHe83uk.js");
4072
+ const { readEnvironment } = await import("./environment-NJykOp33.js").then((n) => n.t);
4073
+ const { readApiKeyFromEnv } = await import("./env-api-key-C3LzH8Lr.js").then((n) => n.t);
4074
+ const { configureLogFileFromEnvironment, logToFile } = await import("./debug-BwIo7nwn.js");
4075
+ const { wizardAbort, WizardError } = await import("./wizard-abort-D_-v1zvS.js");
4780
4076
  configureLogFileFromEnvironment();
4781
4077
  const env = readEnvironment();
4782
4078
  const apiKey = options.apiKey ?? readApiKeyFromEnv() ?? void 0;
@@ -4797,7 +4093,8 @@ function runNonInteractive(config, options, mode) {
4797
4093
  harness: options.harness,
4798
4094
  sequence: options.sequence,
4799
4095
  model: options.model,
4800
- ...env
4096
+ ...env,
4097
+ region: options.region ?? env.region
4801
4098
  });
4802
4099
  session.programLabel = config.id;
4803
4100
  if (config.skillId) session.skillId = config.skillId;
@@ -4807,9 +4104,9 @@ function runNonInteractive(config, options, mode) {
4807
4104
  let store = null;
4808
4105
  let taskStream = null;
4809
4106
  if (mode === "headless") {
4810
- const { WizardStore } = await import("./store-C79GoHCQ.js").then((n) => n.n);
4811
- const { HeadlessUI } = await import("./headless-ui-Dni0gPND.js");
4812
- const { TaskStreamPush, PostHogDestination } = await import("./task-stream-0Pk0tPBN.js");
4107
+ const { WizardStore } = await import("./store-4sj-vWr5.js").then((n) => n.n);
4108
+ const { HeadlessUI } = await import("./headless-ui-B3QKxbz8.js");
4109
+ const { TaskStreamPush, PostHogDestination } = await import("./task-stream-DQT3vjwS.js");
4813
4110
  store = new WizardStore(config.id);
4814
4111
  store.session = session;
4815
4112
  setUI(new HeadlessUI(store));
@@ -4820,6 +4117,7 @@ function runNonInteractive(config, options, mode) {
4820
4117
  getCredentials: () => session.credentials,
4821
4118
  onError: (e) => logToFile("[headless task-stream]", e.message)
4822
4119
  })],
4120
+ eventPlanPath: config.eventPlanFile ? join$1(session.installDir, config.eventPlanFile) : void 0,
4823
4121
  enabled: !session.noTelemetry
4824
4122
  });
4825
4123
  taskStream.attach();
@@ -4864,7 +4162,7 @@ function runNonInteractive(config, options, mode) {
4864
4162
  });
4865
4163
  }
4866
4164
  }
4867
- const { runAgent } = await import("./agent-runner-BF6_f8Qh.js").then((n) => n.t);
4165
+ const { runAgent } = await import("./agent-runner-CV3qh_2p.js").then((n) => n.t);
4868
4166
  await runAgent(config, session);
4869
4167
  await settleStream(RunPhase.Completed);
4870
4168
  } catch (error) {
@@ -5793,7 +5091,7 @@ async function runDoctorCI(options) {
5793
5091
  getUI().intro("Welcome to the PostHog setup wizard");
5794
5092
  getUI().log.info("Running posthog-doctor in CI mode");
5795
5093
  try {
5796
- const { getOrAskForProjectData } = await import("./setup-utils-BQCl28D8.js").then((n) => n.r);
5094
+ const { getOrAskForProjectData } = await import("./setup-utils-Cb5uACEO.js").then((n) => n.r);
5797
5095
  const { host, accessToken, projectId } = await getOrAskForProjectData({
5798
5096
  signup: false,
5799
5097
  ci: true,
@@ -5811,7 +5109,7 @@ async function runDoctorCI(options) {
5811
5109
  for (const issue of sorted) getUI().log.info(` • [${issue.severity}] ${getKindMeta(issue.kind).title}`);
5812
5110
  process.exit(1);
5813
5111
  } catch (error) {
5814
- const { ApiError } = await import("./api-BXduJZrw.js").then((n) => n.n);
5112
+ const { ApiError } = await import("./api-CmIWcW-U.js").then((n) => n.n);
5815
5113
  const message = error instanceof ApiError && error.statusCode === 401 ? "Your PostHog API key is invalid or expired." : error instanceof Error ? error.message : String(error);
5816
5114
  getUI().log.error(`Doctor failed: ${message}`);
5817
5115
  process.exit(1);
@@ -5893,8 +5191,8 @@ function runSlackConnect(argv) {
5893
5191
  (async () => {
5894
5192
  const debug = argv.debug;
5895
5193
  try {
5896
- const { startTUI } = await import("./start-tui-DgSKFMVh.js");
5897
- const { buildSession } = await import("./wizard-session-C5lZPPEc.js");
5194
+ const { startTUI } = await import("./start-tui-Cwc-PFma.js");
5195
+ const { buildSession } = await import("./wizard-session-DWHe83uk.js");
5898
5196
  const tui = startTUI(VERSION, Program.SlackConnect);
5899
5197
  tui.store.session = buildSession({
5900
5198
  debug,
@@ -6017,105 +5315,6 @@ const skillCommand = {
6017
5315
  }
6018
5316
  };
6019
5317
  //#endregion
6020
- //#region src/steps/install-cli-steering/index.ts
6021
- const dirExists = (...segments) => {
6022
- try {
6023
- return fs$1.existsSync(path$1.join(os.homedir(), ...segments));
6024
- } catch {
6025
- return false;
6026
- }
6027
- };
6028
- const CLI_STEERING_TARGETS = [
6029
- {
6030
- id: "claude-code",
6031
- name: "Claude Code",
6032
- instructionsPath: () => path$1.join(os.homedir(), ".claude", "CLAUDE.md"),
6033
- isDetected: () => dirExists(".claude")
6034
- },
6035
- {
6036
- id: "codex",
6037
- name: "Codex",
6038
- instructionsPath: () => path$1.join(os.homedir(), ".codex", "AGENTS.md"),
6039
- isDetected: () => dirExists(".codex")
6040
- },
6041
- {
6042
- id: "gemini",
6043
- name: "Gemini CLI",
6044
- instructionsPath: () => path$1.join(os.homedir(), ".gemini", "GEMINI.md"),
6045
- isDetected: () => dirExists(".gemini")
6046
- }
6047
- ];
6048
- function findTarget(id) {
6049
- return CLI_STEERING_TARGETS.find((target) => target.id === id);
6050
- }
6051
- function detectTargets() {
6052
- return CLI_STEERING_TARGETS.filter((target) => target.isDetected());
6053
- }
6054
- const spawnOptions = {
6055
- encoding: "utf-8",
6056
- shell: process.platform === "win32"
6057
- };
6058
- /**
6059
- * Install or update the PostHog CLI in the user's environment. `npm install
6060
- * --global @posthog/cli@latest` covers both first-time installs and upgrades
6061
- * for existing npm-installed CLIs.
6062
- */
6063
- function installOrUpdatePostHogCli() {
6064
- const args = [
6065
- "install",
6066
- "--global",
6067
- "@posthog/cli@latest"
6068
- ];
6069
- debug(`Running npm ${args.join(" ")}`);
6070
- const result = spawnSync("npm", args, spawnOptions);
6071
- if (result.error) return {
6072
- success: false,
6073
- error: `Failed to run npm: ${result.error.message}. Is Node.js installed?`
6074
- };
6075
- if (result.status !== 0) return {
6076
- success: false,
6077
- error: (result.stderr || result.stdout || "").trim() || `npm install --global @posthog/cli@latest exited with status ${result.status ?? "unknown"}`
6078
- };
6079
- return { success: true };
6080
- }
6081
- /**
6082
- * Delegate the actual write to the installed `posthog-cli api agents-md
6083
- * install`. The steering snippet lives in the CLI (its single source of truth),
6084
- * so the command should run only after `installOrUpdatePostHogCli` refreshes
6085
- * the CLI to the latest release.
6086
- */
6087
- function installSteeringSnippet(filePath) {
6088
- const args = [
6089
- "api",
6090
- "agents-md",
6091
- "install",
6092
- "--path",
6093
- filePath
6094
- ];
6095
- debug(`Running posthog-cli ${args.join(" ")}`);
6096
- const result = spawnSync("posthog-cli", args, {
6097
- ...spawnOptions,
6098
- env: {
6099
- ...process.env,
6100
- POSTHOG_CLI_EXPERIMENTAL_API: "1"
6101
- }
6102
- });
6103
- if (result.error) return {
6104
- success: false,
6105
- filePath,
6106
- error: `Failed to run posthog-cli: ${result.error.message}. Make sure npm's global bin directory is on your PATH.`
6107
- };
6108
- if (result.status !== 0) return {
6109
- success: false,
6110
- filePath,
6111
- error: (result.stderr || result.stdout || "").trim() || `posthog-cli exited with status ${result.status ?? "unknown"}`
6112
- };
6113
- return {
6114
- success: true,
6115
- filePath
6116
- };
6117
- }
6118
- //#endregion
6119
5318
  //#region src/commands/cli/add.ts
6120
5319
  const cliAddCommand = {
6121
5320
  name: "add",
@@ -6275,6 +5474,6 @@ function resolveInstallDir() {
6275
5474
  }
6276
5475
  Wizard.use(basicIntegrationCommand).use(mcpCommand).use(mcpAnalyticsCommand).use(cliCommand).use(auditCommand).use(doctorCommand).use(migrateCommand).use(revenueCommand).use(warehouseCommand).use(selfDrivingCommand).use(slackCommand).use(uploadSourcemapsCommand).use(skillCommand).init();
6277
5476
  //#endregion
6278
- export { STRIPE_SDKS as C, POSTHOG_SDKS as S, SOURCE_MAPS_CONTEXT_KEYS as _, ConfirmButton as a, getDetectedWarehouseSources as b, runWizardCI as c, Program as d, getProgramConfig as f, DISPLAY_NAME as g, AUTOMATABLE_VARIANTS as h, useKeyboardHintsContext as i, runWizard as l, SELF_DRIVING_INTEGRATE_PATH_KEY as m, useKeyBindings as n, PromptLabel as o, detectSelfDrivingIntegrationProjects as p, KeyboardHintsProvider as r, runWizardHeadless as s, PickerMenu as t, PROGRAM_REGISTRY as u, getKindMeta as v, getContentBlocks$3 as x, fetchHealthIssues as y };
5477
+ export { STRIPE_SDKS as S, SOURCE_MAPS_CONTEXT_KEYS as _, ConfirmButton as a, getContentBlocks$3 as b, runWizardCI as c, Program as d, getProgramConfig as f, DISPLAY_NAME as g, AUTOMATABLE_VARIANTS as h, useKeyboardHintsContext as i, runWizard as l, SELF_DRIVING_INTEGRATE_PATH_KEY as m, useKeyBindings as n, PromptLabel as o, detectSelfDrivingIntegrationProjects as p, KeyboardHintsProvider as r, runWizardHeadless as s, PickerMenu as t, PROGRAM_REGISTRY as u, getKindMeta as v, POSTHOG_SDKS as x, fetchHealthIssues as y };
6279
5478
 
6280
5479
  //# sourceMappingURL=bin.js.map