@posthog/wizard 2.45.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 (112) hide show
  1. package/README.md +5 -1
  2. package/dist/{add-mcp-server-to-clients-CNzZMSat.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-CF7GsdFf.js → agent-interface-B8roB2UP.js} +833 -8
  5. package/dist/agent-interface-B8roB2UP.js.map +1 -0
  6. package/dist/{agent-runner-B0LTVFfw.js → agent-runner-CV3qh_2p.js} +204 -48
  7. package/dist/agent-runner-CV3qh_2p.js.map +1 -0
  8. package/dist/analytics-D7vUZgzf.js +2 -0
  9. package/dist/{analytics-DQEuL6qS.js → analytics-k76OWsl0.js} +20 -6
  10. package/dist/analytics-k76OWsl0.js.map +1 -0
  11. package/dist/{api-uCMvDII5.js → api-CmIWcW-U.js} +3 -3
  12. package/dist/{api-uCMvDII5.js.map → api-CmIWcW-U.js.map} +1 -1
  13. package/dist/bin.js +228 -985
  14. package/dist/bin.js.map +1 -1
  15. package/dist/{ci-install-Bow8-f0j.js → ci-install-CNEJxdHf.js} +4 -4
  16. package/dist/{ci-install-Bow8-f0j.js.map → ci-install-CNEJxdHf.js.map} +1 -1
  17. package/dist/{commandments-CyB7Icr1.js → commandments-DSNrOeOC.js} +1 -1
  18. package/dist/{commandments-CyB7Icr1.js.map → commandments-DSNrOeOC.js.map} +1 -1
  19. package/dist/commandments-qTW7pwaT.js +2 -0
  20. package/dist/{debug-BixHZmHv.js → debug-BwIo7nwn.js} +1 -1
  21. package/dist/{debug-DBmxx59Q.js → debug-C9HmIrwx.js} +19 -5
  22. package/dist/debug-C9HmIrwx.js.map +1 -0
  23. package/dist/{defaults-8zjNjGGi.js → defaults-CtWMmC8s.js} +1 -1
  24. package/dist/{defaults-8zjNjGGi.js.map → defaults-CtWMmC8s.js.map} +1 -1
  25. package/dist/{env-api-key-AcC_tz8G.js → env-api-key-C3LzH8Lr.js} +1 -1
  26. package/dist/{env-api-key-AcC_tz8G.js.map → env-api-key-C3LzH8Lr.js.map} +1 -1
  27. package/dist/{environment-kZtkp7eG.js → environment-NJykOp33.js} +3 -3
  28. package/dist/{environment-kZtkp7eG.js.map → environment-NJykOp33.js.map} +1 -1
  29. package/dist/{file-utils-BAhYy5vC.js → file-utils-CLMcNIKi.js} +2 -2
  30. package/dist/{file-utils-BAhYy5vC.js.map → file-utils-CLMcNIKi.js.map} +1 -1
  31. package/dist/{file-watcher-BL-IRbR7.js → file-watcher-CBDCNQVV.js} +2 -2
  32. package/dist/{file-watcher-BL-IRbR7.js.map → file-watcher-CBDCNQVV.js.map} +1 -1
  33. package/dist/{headless-ui-DWmMyhaP.js → headless-ui-B3QKxbz8.js} +2 -2
  34. package/dist/{headless-ui-DWmMyhaP.js.map → headless-ui-B3QKxbz8.js.map} +1 -1
  35. package/dist/{interactive-Cyic0bGL.js → interactive-CIJRex02.js} +2 -2
  36. package/dist/{interactive-Cyic0bGL.js.map → interactive-CIJRex02.js.map} +1 -1
  37. package/dist/{mcp-prompt-streaming-C227vG1X.js → mcp-prompt-streaming-D6OgW3lC.js} +3 -3
  38. package/dist/{mcp-prompt-streaming-C227vG1X.js.map → mcp-prompt-streaming-D6OgW3lC.js.map} +1 -1
  39. package/dist/{mcp-BSGmEWjt.js → mcp-qTjKHqXN.js} +2 -2
  40. package/dist/{mcp-BSGmEWjt.js.map → mcp-qTjKHqXN.js.map} +1 -1
  41. package/dist/{non-interactive-DQA9vn9f.js → non-interactive-8Eypq_h-.js} +2 -2
  42. package/dist/{non-interactive-DQA9vn9f.js.map → non-interactive-8Eypq_h-.js.map} +1 -1
  43. package/dist/{orchestrator-tools-NuWONNkF.js → orchestrator-tools-DVXOV-kz.js} +3 -3
  44. package/dist/{orchestrator-tools-NuWONNkF.js.map → orchestrator-tools-DVXOV-kz.js.map} +1 -1
  45. package/dist/{package-manager-DKtR3xzM.js → package-manager-CAD9Uklp.js} +2 -2
  46. package/dist/{package-manager-DKtR3xzM.js.map → package-manager-CAD9Uklp.js.map} +1 -1
  47. package/dist/{pi-DJCln9jJ.js → pi-C9iHv5uG.js} +48 -32
  48. package/dist/pi-C9iHv5uG.js.map +1 -0
  49. package/dist/{playground-CbEndzc8.js → playground-C-9Q3ETa.js} +7 -7
  50. package/dist/{playground-CbEndzc8.js.map → playground-C-9Q3ETa.js.map} +1 -1
  51. package/dist/{posthog-DFyux4Vw.js → posthog-DZZbziJ1.js} +1 -1
  52. package/dist/{posthog-DFyux4Vw.js.map → posthog-DZZbziJ1.js.map} +1 -1
  53. package/dist/{posthog-integration-dmWJZ8mj.js → posthog-integration-Do997QON.js} +2006 -17
  54. package/dist/posthog-integration-Do997QON.js.map +1 -0
  55. package/dist/{provisioning-CcxCry5p.js → provisioning-DpqnGk3z.js} +3 -3
  56. package/dist/{provisioning-CcxCry5p.js.map → provisioning-DpqnGk3z.js.map} +1 -1
  57. package/dist/{queue-tools-Bw-AANLM.js → queue-tools-CTUgbOU8.js} +2 -2
  58. package/dist/{queue-tools-Bw-AANLM.js.map → queue-tools-CTUgbOU8.js.map} +1 -1
  59. package/dist/{registry-D2V88NoC.js → registry-DT58jEYr.js} +4 -4
  60. package/dist/{registry-D2V88NoC.js.map → registry-DT58jEYr.js.map} +1 -1
  61. package/dist/{security-DOtBCBvx.js → security-CTigdAWm.js} +10 -8
  62. package/dist/security-CTigdAWm.js.map +1 -0
  63. package/dist/{setup-utils-Qp-u6BZk.js → setup-utils-Cb5uACEO.js} +31 -9
  64. package/dist/setup-utils-Cb5uACEO.js.map +1 -0
  65. package/dist/{start-tui-DHa_9aiB.js → start-tui-Cwc-PFma.js} +36 -30
  66. package/dist/start-tui-Cwc-PFma.js.map +1 -0
  67. package/dist/{steps-D07HUQyE.js → steps-DyEKYM4I.js} +7 -7
  68. package/dist/{steps-D07HUQyE.js.map → steps-DyEKYM4I.js.map} +1 -1
  69. package/dist/{store-DSwsITKX.js → store-4sj-vWr5.js} +4 -4
  70. package/dist/{store-DSwsITKX.js.map → store-4sj-vWr5.js.map} +1 -1
  71. package/dist/{subagent-Dk4K5MDa.js → subagent-D8_yDgCB.js} +2 -2
  72. package/dist/{subagent-Dk4K5MDa.js.map → subagent-D8_yDgCB.js.map} +1 -1
  73. package/dist/{task-CQnV9Qd2.js → task-D8Y8pkzd.js} +12 -13
  74. package/dist/task-D8Y8pkzd.js.map +1 -0
  75. package/dist/{task-stream-B7qia9eW.js → task-stream-DQT3vjwS.js} +4 -4
  76. package/dist/{task-stream-B7qia9eW.js.map → task-stream-DQT3vjwS.js.map} +1 -1
  77. package/dist/{tasks-C7BQp659.js → tasks-D2WKssA5.js} +2 -2
  78. package/dist/{tasks-C7BQp659.js.map → tasks-D2WKssA5.js.map} +1 -1
  79. package/dist/{telemetry-DgahJGSx.js → telemetry-CYr4HgS2.js} +3 -3
  80. package/dist/{telemetry-DgahJGSx.js.map → telemetry-CYr4HgS2.js.map} +1 -1
  81. package/dist/{terminal-Bb6tZkf-.js → terminal-1RfyHQC2.js} +12 -12
  82. package/dist/{terminal-Bb6tZkf-.js.map → terminal-1RfyHQC2.js.map} +1 -1
  83. package/dist/tools-DQCUOQZX.js +199 -0
  84. package/dist/tools-DQCUOQZX.js.map +1 -0
  85. package/dist/{wizard-abort-DpDmuCfA.js → wizard-abort-D_-v1zvS.js} +1 -1
  86. package/dist/{wizard-abort-BxtdkgI-.js → wizard-abort-FuyIaI_0.js} +3 -3
  87. package/dist/{wizard-abort-BxtdkgI-.js.map → wizard-abort-FuyIaI_0.js.map} +1 -1
  88. package/dist/yara-hooks-6gNnPFPo.js +2 -0
  89. package/dist/{yara-hooks-pw86rZ8y.js → yara-hooks-DdYRRxfH.js} +82 -21
  90. package/dist/yara-hooks-DdYRRxfH.js.map +1 -0
  91. package/package.json +1 -1
  92. package/dist/add-mcp-server-to-clients-CNzZMSat.js.map +0 -1
  93. package/dist/agent-interface-CF7GsdFf.js.map +0 -1
  94. package/dist/agent-runner-B0LTVFfw.js.map +0 -1
  95. package/dist/analytics-DQEuL6qS.js.map +0 -1
  96. package/dist/analytics-YD3D38z2.js +0 -2
  97. package/dist/commandments-DguPfCX8.js +0 -2
  98. package/dist/debug-DBmxx59Q.js.map +0 -1
  99. package/dist/pi-DJCln9jJ.js.map +0 -1
  100. package/dist/posthog-integration-dmWJZ8mj.js.map +0 -1
  101. package/dist/security-DOtBCBvx.js.map +0 -1
  102. package/dist/setup-utils-Qp-u6BZk.js.map +0 -1
  103. package/dist/start-tui-DHa_9aiB.js.map +0 -1
  104. package/dist/task-CQnV9Qd2.js.map +0 -1
  105. package/dist/tools-BJEvSUWN.js +0 -122
  106. package/dist/tools-BJEvSUWN.js.map +0 -1
  107. package/dist/types-BRe_EzTW.js +0 -46
  108. package/dist/types-BRe_EzTW.js.map +0 -1
  109. package/dist/wizard-tools-Dg8o2lcH.js +0 -783
  110. package/dist/wizard-tools-Dg8o2lcH.js.map +0 -1
  111. package/dist/yara-hooks-CncaWRuC.js +0 -2
  112. package/dist/yara-hooks-pw86rZ8y.js.map +0 -1
package/dist/bin.js CHANGED
@@ -1,21 +1,19 @@
1
1
  #!/usr/bin/env node
2
- import { B as Integration, Ct as headlessOption, K as POSTHOG_DOCS_URL, _t as getSkillsBaseUrl, a as getLogFilePath, f as getUI, ht as WIZARD_USER_AGENT, m as LoggingUI, p as setUI, r as debug, s as logToFile, wt as isHeadless, yt as VERSION } from "./debug-DBmxx59Q.js";
3
- import { n as analytics } from "./analytics-DQEuL6qS.js";
4
- import { r as setEntryCommand } from "./telemetry-DgahJGSx.js";
5
- import { n as isUsingTypeScript } from "./setup-utils-Qp-u6BZk.js";
6
- import { o as handleApiError } from "./api-uCMvDII5.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
7
  import "./wizard-session-tp4Zdbwl.js";
8
- import { r as runCleanups } from "./wizard-abort-BxtdkgI-.js";
9
- import { n as isNonInteractiveEnvironment } from "./environment-kZtkp7eG.js";
10
- import { n as runAgent, o as authenticate } from "./agent-runner-B0LTVFfw.js";
11
- import { l as recoverOrphanedSettingsBackups, p as AgentSignals } from "./agent-interface-CF7GsdFf.js";
12
- import { n as AUDIT_CHECKS_KEY, r as AUDIT_REPORT_FILE, t as AUDIT_CHECKS_FILE } from "./types-BRe_EzTW.js";
13
- import { i as fetchSkillMenu, t as WIZARD_TOOL_NAMES } from "./wizard-tools-Dg8o2lcH.js";
14
- import { h as SETUP_REPORT_FILE } from "./yara-hooks-pw86rZ8y.js";
15
- import { i as SPINNER_MESSAGE } from "./registry-D2V88NoC.js";
16
- import { S as parseRequirementsTxt, a as LINE_CHART_BLOCK, b as parsePipfile, g as detectIntegrationProjects, 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 resolveProjectDir, x as parsePyprojectToml, y as gatherFrameworkContext } from "./posthog-integration-dmWJZ8mj.js";
17
- import { n as safeReadFile, r as walkProjectFiles, t as IGNORED_DIRS } from "./file-utils-BAhYy5vC.js";
18
- import { n as readApiKeyFromEnv } from "./env-api-key-AcC_tz8G.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";
@@ -75,11 +73,6 @@ const GLOBAL_OPTIONS = {
75
73
  describe: "Enable verbose logging\nenv: POSTHOG_WIZARD_DEBUG",
76
74
  type: "boolean"
77
75
  },
78
- region: {
79
- describe: "PostHog cloud region\nenv: POSTHOG_WIZARD_REGION",
80
- choices: ["us", "eu"],
81
- type: "string"
82
- },
83
76
  signup: {
84
77
  default: false,
85
78
  describe: "Create a new PostHog account during setup\nenv: POSTHOG_WIZARD_SIGNUP",
@@ -207,7 +200,7 @@ function runProvision(argv) {
207
200
  }
208
201
  async function provision({ email, region, name, baseUrl, jsonMode }) {
209
202
  try {
210
- const { provisionNewAccount } = await import("./provisioning-CcxCry5p.js").then((n) => n.n);
203
+ const { provisionNewAccount } = await import("./provisioning-DpqnGk3z.js").then((n) => n.n);
211
204
  if (!jsonMode) getUI().log.info(`Provisioning account for ${email} in ${region}...`);
212
205
  emitResult(await provisionNewAccount(email, name, region, { baseUrl }), jsonMode);
213
206
  process.exit(0);
@@ -263,7 +256,8 @@ const basicIntegrationCommand = {
263
256
  type: "boolean",
264
257
  hidden: true
265
258
  },
266
- ...headlessOption
259
+ ...headlessOption,
260
+ ...regionOption
267
261
  },
268
262
  check: (argv) => {
269
263
  if (argv.playground && (argv.ci || isHeadless(argv))) throw new Error("--playground cannot be combined with a headless run.");
@@ -273,22 +267,22 @@ const basicIntegrationCommand = {
273
267
  setEntryCommand("integrate");
274
268
  (async () => {
275
269
  if (isHeadless(argv)) {
276
- const { runHeadlessInstall } = await import("./ci-install-Bow8-f0j.js");
270
+ const { runHeadlessInstall } = await import("./ci-install-CNEJxdHf.js");
277
271
  return runHeadlessInstall(argv);
278
272
  }
279
273
  if (argv.ci) {
280
- const { runCIInstall } = await import("./ci-install-Bow8-f0j.js");
274
+ const { runCIInstall } = await import("./ci-install-CNEJxdHf.js");
281
275
  return runCIInstall(argv);
282
276
  }
283
277
  if (isNonInteractiveEnvironment()) {
284
- const { failNonInteractive } = await import("./non-interactive-DQA9vn9f.js");
278
+ const { failNonInteractive } = await import("./non-interactive-8Eypq_h-.js");
285
279
  return failNonInteractive();
286
280
  }
287
281
  if (argv.playground) {
288
- const { runPlayground } = await import("./playground-CbEndzc8.js");
282
+ const { runPlayground } = await import("./playground-C-9Q3ETa.js");
289
283
  return runPlayground();
290
284
  }
291
- const { runInteractive } = await import("./interactive-Cyic0bGL.js");
285
+ const { runInteractive } = await import("./interactive-CIJRex02.js");
292
286
  runInteractive(argv);
293
287
  })();
294
288
  }
@@ -531,809 +525,6 @@ const revenueAnalyticsConfig = {
531
525
  requires: ["posthog-integration"]
532
526
  };
533
527
  //#endregion
534
- //#region src/lib/warehouse-sources/registry.ts
535
- const SOURCE_DETECTORS = [
536
- {
537
- kind: "Postgres",
538
- label: "PostgreSQL",
539
- mode: "in-cli",
540
- signals: {
541
- npm: [
542
- "pg",
543
- "postgres",
544
- "postgres.js",
545
- "knex",
546
- "sequelize"
547
- ],
548
- python: [
549
- "psycopg",
550
- "psycopg2",
551
- "psycopg2-binary",
552
- "asyncpg"
553
- ],
554
- ruby: ["pg"],
555
- envKeys: [
556
- /^DATABASE_URL$/,
557
- /^POSTGRES_/,
558
- /^PG(HOST|DATABASE|USER|PORT)$/
559
- ]
560
- }
561
- },
562
- {
563
- kind: "MySQL",
564
- label: "MySQL",
565
- mode: "in-cli",
566
- signals: {
567
- npm: ["mysql", "mysql2"],
568
- python: [
569
- "pymysql",
570
- "mysqlclient",
571
- "mysql-connector-python"
572
- ],
573
- ruby: ["mysql2"],
574
- envKeys: [/^MYSQL_/]
575
- }
576
- },
577
- {
578
- kind: "MongoDB",
579
- label: "MongoDB",
580
- mode: "in-cli",
581
- signals: {
582
- npm: ["mongodb", "mongoose"],
583
- python: ["pymongo", "motor"],
584
- ruby: ["mongo", "mongoid"],
585
- envKeys: [/^MONGO(DB)?_/]
586
- }
587
- },
588
- {
589
- kind: "Snowflake",
590
- label: "Snowflake",
591
- mode: "in-cli",
592
- signals: {
593
- npm: ["snowflake-sdk"],
594
- python: ["snowflake-connector-python", "snowflake-sqlalchemy"],
595
- envKeys: [/^SNOWFLAKE_/]
596
- }
597
- },
598
- {
599
- kind: "BigQuery",
600
- label: "BigQuery",
601
- mode: "in-cli",
602
- signals: {
603
- npm: ["@google-cloud/bigquery"],
604
- python: ["google-cloud-bigquery"],
605
- envKeys: [/^BIGQUERY_/]
606
- }
607
- },
608
- {
609
- kind: "Redshift",
610
- label: "Redshift",
611
- mode: "in-cli",
612
- signals: {
613
- npm: ["node-redshift"],
614
- python: ["redshift-connector"],
615
- envKeys: [/^REDSHIFT_/]
616
- }
617
- },
618
- {
619
- kind: "MSSQL",
620
- label: "SQL Server",
621
- mode: "in-cli",
622
- signals: {
623
- npm: ["mssql", "tedious"],
624
- python: ["pyodbc", "pymssql"],
625
- envKeys: [/^MSSQL_/]
626
- }
627
- },
628
- {
629
- kind: "Supabase",
630
- label: "Supabase",
631
- mode: "in-cli",
632
- signals: {
633
- npm: ["@supabase/supabase-js"],
634
- python: ["supabase"],
635
- envKeys: [/^SUPABASE_/]
636
- }
637
- },
638
- {
639
- kind: "ClickHouse",
640
- label: "ClickHouse",
641
- mode: "in-cli",
642
- signals: {
643
- npm: ["@clickhouse/client"],
644
- python: ["clickhouse-connect", "clickhouse-driver"],
645
- envKeys: [/^CLICKHOUSE_/]
646
- }
647
- },
648
- {
649
- kind: "Convex",
650
- label: "Convex",
651
- mode: "in-cli",
652
- signals: {
653
- npm: ["convex"],
654
- python: ["convex"],
655
- envKeys: [/^CONVEX_/, /^NEXT_PUBLIC_CONVEX_URL$/]
656
- }
657
- },
658
- {
659
- kind: "Stripe",
660
- label: "Stripe",
661
- mode: "in-cli",
662
- signals: {
663
- npm: [
664
- "stripe",
665
- "@stripe/stripe-js",
666
- "@stripe/react-stripe-js"
667
- ],
668
- python: ["stripe"],
669
- ruby: ["stripe"],
670
- envKeys: [/^STRIPE_(SECRET|API)_KEY$/]
671
- }
672
- },
673
- {
674
- kind: "Clerk",
675
- label: "Clerk",
676
- mode: "in-cli",
677
- signals: {
678
- npm: [
679
- "@clerk/nextjs",
680
- "@clerk/clerk-react",
681
- "@clerk/backend",
682
- "@clerk/express",
683
- "@clerk/fastify",
684
- "@clerk/remix"
685
- ],
686
- envKeys: [/^CLERK_SECRET_KEY$/, /^NEXT_PUBLIC_CLERK_/]
687
- }
688
- },
689
- {
690
- kind: "Resend",
691
- label: "Resend",
692
- mode: "in-cli",
693
- signals: {
694
- npm: ["resend"],
695
- python: ["resend"],
696
- envKeys: [/^RESEND_API_KEY$/]
697
- }
698
- },
699
- {
700
- kind: "Shopify",
701
- label: "Shopify",
702
- mode: "in-cli",
703
- signals: {
704
- npm: ["@shopify/shopify-api", "shopify-api-node"],
705
- python: ["shopifyapi"],
706
- envKeys: [/^SHOPIFY_/]
707
- }
708
- },
709
- {
710
- kind: "Klaviyo",
711
- label: "Klaviyo",
712
- mode: "in-cli",
713
- signals: {
714
- npm: ["klaviyo-api"],
715
- python: ["klaviyo-api"],
716
- envKeys: [/^KLAVIYO_/]
717
- }
718
- },
719
- {
720
- kind: "Chargebee",
721
- label: "Chargebee",
722
- mode: "in-cli",
723
- signals: {
724
- npm: ["chargebee"],
725
- python: ["chargebee"],
726
- envKeys: [/^CHARGEBEE_/]
727
- }
728
- },
729
- {
730
- kind: "Paddle",
731
- label: "Paddle",
732
- mode: "in-cli",
733
- signals: {
734
- npm: ["@paddle/paddle-node-sdk", "@paddle/paddle-js"],
735
- envKeys: [/^PADDLE_/]
736
- }
737
- },
738
- {
739
- kind: "Polar",
740
- label: "Polar",
741
- mode: "in-cli",
742
- signals: {
743
- npm: ["@polar-sh/sdk", "@polar-sh/nextjs"],
744
- envKeys: [/^POLAR_/]
745
- }
746
- },
747
- {
748
- kind: "Mailchimp",
749
- label: "Mailchimp",
750
- mode: "in-cli",
751
- signals: {
752
- npm: ["@mailchimp/mailchimp_marketing"],
753
- python: ["mailchimp-marketing"],
754
- envKeys: [/^MAILCHIMP_/]
755
- }
756
- },
757
- {
758
- kind: "CustomerIO",
759
- label: "Customer.io",
760
- mode: "in-cli",
761
- signals: {
762
- npm: ["customerio-node"],
763
- python: ["customerio"],
764
- envKeys: [/^CUSTOMER_?IO_/]
765
- }
766
- },
767
- {
768
- kind: "Typeform",
769
- label: "Typeform",
770
- mode: "in-cli",
771
- signals: {
772
- npm: ["@typeform/api-client"],
773
- envKeys: [/^TYPEFORM_/]
774
- }
775
- },
776
- {
777
- kind: "Sentry",
778
- label: "Sentry",
779
- mode: "in-cli",
780
- signals: {
781
- npm: [
782
- "@sentry/node",
783
- "@sentry/browser",
784
- "@sentry/react",
785
- "@sentry/nextjs"
786
- ],
787
- python: ["sentry-sdk"],
788
- ruby: ["sentry-ruby"]
789
- }
790
- },
791
- {
792
- kind: "Plaid",
793
- label: "Plaid",
794
- mode: "in-cli",
795
- signals: {
796
- npm: ["plaid"],
797
- python: ["plaid-python", "plaid"],
798
- ruby: ["plaid"],
799
- envKeys: [/^PLAID_/]
800
- }
801
- },
802
- {
803
- kind: "Braintree",
804
- label: "Braintree",
805
- mode: "in-cli",
806
- signals: {
807
- npm: ["braintree"],
808
- python: ["braintree"],
809
- ruby: ["braintree"],
810
- envKeys: [/^BRAINTREE_/]
811
- }
812
- },
813
- {
814
- kind: "Square",
815
- label: "Square",
816
- mode: "in-cli",
817
- signals: {
818
- npm: ["square"],
819
- python: ["squareup"],
820
- ruby: ["square"],
821
- envKeys: [/^SQUARE_/]
822
- }
823
- },
824
- {
825
- kind: "GoCardless",
826
- label: "GoCardless",
827
- mode: "in-cli",
828
- signals: {
829
- npm: ["gocardless-nodejs"],
830
- python: ["gocardless-pro"],
831
- ruby: ["gocardless_pro"],
832
- envKeys: [/^GOCARDLESS_/]
833
- }
834
- },
835
- {
836
- kind: "Mollie",
837
- label: "Mollie",
838
- mode: "in-cli",
839
- signals: {
840
- npm: ["@mollie/api-client"],
841
- python: ["mollie-api-python"],
842
- envKeys: [/^MOLLIE_/]
843
- }
844
- },
845
- {
846
- kind: "CheckoutCom",
847
- label: "Checkout.com",
848
- mode: "in-cli",
849
- signals: {
850
- npm: ["checkout-sdk-node"],
851
- python: ["checkout-sdk"],
852
- envKeys: [/^CKO_/, /^CHECKOUT_COM_/]
853
- }
854
- },
855
- {
856
- kind: "Recurly",
857
- label: "Recurly",
858
- mode: "in-cli",
859
- signals: {
860
- npm: ["recurly"],
861
- python: ["recurly"],
862
- ruby: ["recurly"],
863
- envKeys: [/^RECURLY_/]
864
- }
865
- },
866
- {
867
- kind: "RevenueCat",
868
- label: "RevenueCat",
869
- mode: "in-cli",
870
- signals: {
871
- npm: [
872
- "@revenuecat/purchases-js",
873
- "react-native-purchases",
874
- "@revenuecat/purchases-capacitor"
875
- ],
876
- envKeys: [/^REVENUE_?CAT_/]
877
- }
878
- },
879
- {
880
- kind: "Twilio",
881
- label: "Twilio",
882
- mode: "in-cli",
883
- signals: {
884
- npm: ["twilio"],
885
- python: ["twilio"],
886
- ruby: ["twilio-ruby"],
887
- envKeys: [/^TWILIO_/]
888
- }
889
- },
890
- {
891
- kind: "SendGrid",
892
- label: "SendGrid",
893
- mode: "in-cli",
894
- signals: {
895
- npm: ["@sendgrid/mail", "@sendgrid/client"],
896
- python: ["sendgrid"],
897
- ruby: ["sendgrid-ruby"],
898
- envKeys: [/^SENDGRID_/]
899
- }
900
- },
901
- {
902
- kind: "Mailgun",
903
- label: "Mailgun",
904
- mode: "in-cli",
905
- signals: {
906
- npm: ["mailgun.js", "mailgun-js"],
907
- python: ["mailgun"],
908
- ruby: ["mailgun-ruby"],
909
- envKeys: [/^MAILGUN_/]
910
- }
911
- },
912
- {
913
- kind: "Postmark",
914
- label: "Postmark",
915
- mode: "in-cli",
916
- signals: {
917
- npm: ["postmark"],
918
- python: ["postmarker"],
919
- ruby: ["postmark"],
920
- envKeys: [/^POSTMARK_/]
921
- }
922
- },
923
- {
924
- kind: "Brevo",
925
- label: "Brevo",
926
- mode: "in-cli",
927
- signals: {
928
- npm: ["@getbrevo/brevo", "sib-api-v3-sdk"],
929
- python: ["sib-api-v3-sdk"],
930
- envKeys: [/^BREVO_/]
931
- }
932
- },
933
- {
934
- kind: "MailerLite",
935
- label: "MailerLite",
936
- mode: "in-cli",
937
- signals: {
938
- npm: ["@mailerlite/mailerlite-nodejs"],
939
- python: ["mailerlite"],
940
- envKeys: [/^MAILERLITE_/]
941
- }
942
- },
943
- {
944
- kind: "Mailjet",
945
- label: "Mailjet",
946
- mode: "in-cli",
947
- signals: {
948
- npm: ["node-mailjet"],
949
- python: ["mailjet-rest"],
950
- envKeys: [/^MAILJET_/, /^MJ_APIKEY_/]
951
- }
952
- },
953
- {
954
- kind: "LaunchDarkly",
955
- label: "LaunchDarkly",
956
- mode: "in-cli",
957
- signals: {
958
- npm: [
959
- "launchdarkly-node-server-sdk",
960
- "@launchdarkly/node-server-sdk",
961
- "launchdarkly-js-client-sdk",
962
- "launchdarkly-react-client-sdk"
963
- ],
964
- python: ["launchdarkly-server-sdk"],
965
- ruby: ["launchdarkly-server-sdk"],
966
- envKeys: [/^LAUNCHDARKLY_/, /^LD_SDK_KEY$/]
967
- }
968
- },
969
- {
970
- kind: "Optimizely",
971
- label: "Optimizely",
972
- mode: "in-cli",
973
- signals: {
974
- npm: ["@optimizely/optimizely-sdk"],
975
- python: ["optimizely-sdk"],
976
- envKeys: [/^OPTIMIZELY_/]
977
- }
978
- },
979
- {
980
- kind: "Braze",
981
- label: "Braze",
982
- mode: "in-cli",
983
- signals: {
984
- npm: ["@braze/web-sdk", "@braze/react-native-sdk"],
985
- python: ["braze-client"],
986
- envKeys: [/^BRAZE_/]
987
- }
988
- },
989
- {
990
- kind: "Rollbar",
991
- label: "Rollbar",
992
- mode: "in-cli",
993
- signals: {
994
- npm: ["rollbar"],
995
- python: ["rollbar", "pyrollbar"],
996
- ruby: ["rollbar"],
997
- envKeys: [/^ROLLBAR_/]
998
- }
999
- },
1000
- {
1001
- kind: "Okta",
1002
- label: "Okta",
1003
- mode: "in-cli",
1004
- signals: {
1005
- npm: [
1006
- "@okta/okta-sdk-nodejs",
1007
- "@okta/okta-auth-js",
1008
- "@okta/okta-react"
1009
- ],
1010
- python: ["okta"],
1011
- envKeys: [/^OKTA_/]
1012
- }
1013
- },
1014
- {
1015
- kind: "WorkOS",
1016
- label: "WorkOS",
1017
- mode: "in-cli",
1018
- signals: {
1019
- npm: ["@workos-inc/node"],
1020
- python: ["workos"],
1021
- envKeys: [/^WORKOS_/]
1022
- }
1023
- },
1024
- {
1025
- kind: "Notion",
1026
- label: "Notion",
1027
- mode: "in-cli",
1028
- signals: {
1029
- npm: ["@notionhq/client"],
1030
- python: ["notion-client"],
1031
- envKeys: [/^NOTION_/]
1032
- }
1033
- },
1034
- {
1035
- kind: "FullStory",
1036
- label: "FullStory",
1037
- mode: "in-cli",
1038
- signals: {
1039
- npm: ["@fullstory/browser", "@fullstory/react-native"],
1040
- envKeys: [/^FULLSTORY_/]
1041
- }
1042
- },
1043
- {
1044
- kind: "Amplitude",
1045
- label: "Amplitude",
1046
- mode: "in-cli",
1047
- signals: {
1048
- npm: [
1049
- "@amplitude/analytics-browser",
1050
- "@amplitude/analytics-node",
1051
- "@amplitude/analytics-react-native",
1052
- "amplitude-js"
1053
- ],
1054
- python: ["amplitude-analytics"],
1055
- envKeys: [/^AMPLITUDE_/]
1056
- }
1057
- },
1058
- {
1059
- kind: "Mixpanel",
1060
- label: "Mixpanel",
1061
- mode: "in-cli",
1062
- signals: {
1063
- npm: ["mixpanel", "mixpanel-browser"],
1064
- python: ["mixpanel"],
1065
- ruby: ["mixpanel-ruby"],
1066
- envKeys: [/^MIXPANEL_/]
1067
- }
1068
- },
1069
- {
1070
- kind: "Pendo",
1071
- label: "Pendo",
1072
- mode: "in-cli",
1073
- signals: {
1074
- npm: ["@pendo/agent"],
1075
- envKeys: [/^PENDO_/]
1076
- }
1077
- },
1078
- {
1079
- kind: "Salesforce",
1080
- label: "Salesforce",
1081
- mode: "deep-link",
1082
- signals: {
1083
- npm: ["jsforce"],
1084
- python: ["simple-salesforce"],
1085
- envKeys: [/^SALESFORCE_/]
1086
- }
1087
- },
1088
- {
1089
- kind: "Hubspot",
1090
- label: "HubSpot",
1091
- mode: "deep-link",
1092
- signals: {
1093
- npm: ["@hubspot/api-client"],
1094
- python: ["hubspot-api-client"],
1095
- envKeys: [/^HUBSPOT_/]
1096
- }
1097
- },
1098
- {
1099
- kind: "Zendesk",
1100
- label: "Zendesk",
1101
- mode: "deep-link",
1102
- signals: {
1103
- npm: ["node-zendesk"],
1104
- python: ["zenpy"],
1105
- envKeys: [/^ZENDESK_/]
1106
- }
1107
- },
1108
- {
1109
- kind: "Intercom",
1110
- label: "Intercom",
1111
- mode: "deep-link",
1112
- signals: {
1113
- npm: ["intercom-client", "@intercom/messenger-js-sdk"],
1114
- python: ["python-intercom"],
1115
- envKeys: [/^INTERCOM_/]
1116
- }
1117
- },
1118
- {
1119
- kind: "Linear",
1120
- label: "Linear",
1121
- mode: "deep-link",
1122
- signals: {
1123
- npm: ["@linear/sdk"],
1124
- envKeys: [/^LINEAR_API_KEY$/]
1125
- }
1126
- },
1127
- {
1128
- kind: "Slack",
1129
- label: "Slack",
1130
- mode: "deep-link",
1131
- signals: {
1132
- npm: ["@slack/web-api", "@slack/bolt"],
1133
- python: ["slack-sdk", "slack-bolt"],
1134
- envKeys: [/^SLACK_(BOT|APP|SIGNING|CLIENT)_/]
1135
- }
1136
- },
1137
- {
1138
- kind: "Github",
1139
- label: "GitHub",
1140
- mode: "deep-link",
1141
- signals: {
1142
- npm: [
1143
- "@octokit/rest",
1144
- "@octokit/core",
1145
- "@octokit/graphql",
1146
- "octokit"
1147
- ],
1148
- python: ["pygithub"],
1149
- ruby: ["octokit"]
1150
- }
1151
- }
1152
- ];
1153
- //#endregion
1154
- //#region src/lib/warehouse-sources/detect.ts
1155
- /**
1156
- * Data warehouse source detection.
1157
- *
1158
- * Scans a project for codebase signals (npm/python/ruby deps, `.env` key
1159
- * names) and matches them against the `SOURCE_DETECTORS` registry. Pure
1160
- * function: no store mutations, no UI calls. Reads files locally — only the
1161
- * wizard process does this; the agent never sees secret values.
1162
- *
1163
- * Note we only read `.env` KEY NAMES, never values.
1164
- */
1165
- const MAX_DEPTH = 3;
1166
- /**
1167
- * Detect which warehouse sources the project at `installDir` appears to use.
1168
- * Returns one `DetectedSource` per matched registry entry (kinds are unique,
1169
- * so the result is naturally deduped).
1170
- */
1171
- function detectWarehouseSources(installDir) {
1172
- const signals = collectSignals(installDir);
1173
- const detected = [];
1174
- for (const detector of SOURCE_DETECTORS) {
1175
- const match = matchDetector(detector, signals);
1176
- if (match) detected.push({
1177
- kind: detector.kind,
1178
- label: detector.label,
1179
- mode: detector.mode,
1180
- matchedSignal: match
1181
- });
1182
- }
1183
- return detected;
1184
- }
1185
- /** Returns a human-readable description of the first matching signal, or null. */
1186
- function matchDetector(detector, signals) {
1187
- const { npm, python, ruby, envKeys } = detector.signals;
1188
- const npmHit = npm?.find((dep) => signals.npm.has(dep));
1189
- if (npmHit) return `found \`${npmHit}\` in package.json`;
1190
- const pyHit = python?.find((dep) => signals.python.has(dep));
1191
- if (pyHit) return `found \`${pyHit}\` in Python dependencies`;
1192
- const rubyHit = ruby?.find((gem) => signals.ruby.has(gem));
1193
- if (rubyHit) return `found \`${rubyHit}\` in Gemfile`;
1194
- if (envKeys) {
1195
- for (const key of signals.envKeys) if (envKeys.some((re) => re.test(key))) return `found \`${key}\` in .env`;
1196
- }
1197
- return null;
1198
- }
1199
- function collectSignals(installDir) {
1200
- const signals = {
1201
- npm: /* @__PURE__ */ new Set(),
1202
- python: /* @__PURE__ */ new Set(),
1203
- ruby: /* @__PURE__ */ new Set(),
1204
- envKeys: /* @__PURE__ */ new Set()
1205
- };
1206
- walkProjectFiles(installDir, (name, fullPath) => ingestFile(name, fullPath, signals), MAX_DEPTH);
1207
- return signals;
1208
- }
1209
- /**
1210
- * Route a file to the right parser BY NAME, reading its contents only when the
1211
- * name matches one of the ~6 manifests we care about. Checking the name first
1212
- * avoids slurping every file in the tree (lockfiles, binaries, assets) into
1213
- * memory just to discard it.
1214
- */
1215
- function ingestFile(name, fullPath, signals) {
1216
- const ingest = ingestorFor(name);
1217
- if (!ingest) return;
1218
- const content = safeReadFile(fullPath);
1219
- if (content === null) return;
1220
- ingest(content, signals);
1221
- }
1222
- /** Pick the parser for a manifest filename, or null if it's not one we read. */
1223
- function ingestorFor(name) {
1224
- if (name === "package.json") return addNpmDeps;
1225
- if (name === "requirements.txt") return (c, s) => parseRequirementsTxt(c).forEach((d) => s.python.add(d));
1226
- if (name === "pyproject.toml") return (c, s) => parsePyprojectToml(c).forEach((d) => s.python.add(d));
1227
- if (name === "Pipfile") return (c, s) => parsePipfile(c).forEach((d) => s.python.add(d));
1228
- if (name === "Gemfile") return (c, s) => parseGemfile(c).forEach((g) => s.ruby.add(g));
1229
- if (name.startsWith(".env")) return (c, s) => parseEnvKeys(c).forEach((k) => s.envKeys.add(k));
1230
- return null;
1231
- }
1232
- function addNpmDeps(content, signals) {
1233
- try {
1234
- const pkg = JSON.parse(content);
1235
- for (const dep of Object.keys({
1236
- ...pkg.dependencies,
1237
- ...pkg.devDependencies
1238
- })) signals.npm.add(dep);
1239
- } catch (error) {
1240
- analytics.captureException(error instanceof Error ? error : new Error(String(error)), { step: "detectWarehouseSources.parsePackageJson" });
1241
- }
1242
- }
1243
- /** Extract gem names from `gem 'name'` declarations. */
1244
- function parseGemfile(content) {
1245
- const gems = [];
1246
- for (const match of content.matchAll(/^\s*gem\s+['"]([^'"]+)['"]/gm)) gems.push(match[1]);
1247
- return gems;
1248
- }
1249
- /** Extract KEY NAMES from a dotenv file. Values are intentionally discarded. */
1250
- function parseEnvKeys(content) {
1251
- const keys = [];
1252
- for (const line of content.split("\n")) {
1253
- const trimmed = line.trim();
1254
- if (!trimmed || trimmed.startsWith("#")) continue;
1255
- const match = trimmed.match(/^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/);
1256
- if (match) keys.push(match[1]);
1257
- }
1258
- return keys;
1259
- }
1260
- //#endregion
1261
- //#region src/lib/programs/warehouse-source/detect.ts
1262
- /**
1263
- * Warehouse-source program detection step.
1264
- *
1265
- * Thin adapter over `detectWarehouseSources` that writes results into
1266
- * frameworkContext for the intro screen, plus the `[ABORT]` cases the
1267
- * data-warehouse-source-setup skill can emit.
1268
- */
1269
- /** frameworkContext key holding the detected sources (set on success). */
1270
- const DETECTED_WAREHOUSE_SOURCES_KEY = "detectedWarehouseSources";
1271
- /**
1272
- * Read the detected sources out of frameworkContext. Single accessor shared by
1273
- * the intro screen and the prompt builder so the key + cast live in one place.
1274
- */
1275
- function getDetectedWarehouseSources(session) {
1276
- return session.frameworkContext["detectedWarehouseSources"] ?? [];
1277
- }
1278
- /** `[ABORT] <reason>` cases the skill can emit. */
1279
- const WAREHOUSE_ABORT_CASES = [{
1280
- match: /^no data sources? detected\.?$/i,
1281
- message: "No data source detected",
1282
- 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.).",
1283
- docsUrl: "https://posthog.com/docs/data-warehouse"
1284
- }, {
1285
- match: /^source creation failed\.?$/i,
1286
- message: "Source creation failed",
1287
- 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.",
1288
- docsUrl: "https://posthog.com/docs/data-warehouse"
1289
- }];
1290
- /**
1291
- * Scan `session.installDir` for warehouse-source signals. Writes the detected
1292
- * sources (or a `detectError`) into frameworkContext for the intro screen.
1293
- */
1294
- function detectWarehousePrerequisites(session, setFrameworkContext) {
1295
- const fail = (error) => setFrameworkContext("detectError", error);
1296
- const installDir = session.installDir;
1297
- if (!existsSync(installDir)) {
1298
- fail({
1299
- kind: "bad-directory",
1300
- path: installDir,
1301
- reason: "missing"
1302
- });
1303
- return;
1304
- }
1305
- try {
1306
- if (!statSync(installDir).isDirectory()) {
1307
- fail({
1308
- kind: "bad-directory",
1309
- path: installDir,
1310
- reason: "not-dir"
1311
- });
1312
- return;
1313
- }
1314
- } catch (error) {
1315
- analytics.captureException(error instanceof Error ? error : new Error(String(error)), {
1316
- step: "detectWarehousePrerequisites.stat",
1317
- path: installDir
1318
- });
1319
- fail({
1320
- kind: "bad-directory",
1321
- path: installDir,
1322
- reason: "unreadable"
1323
- });
1324
- return;
1325
- }
1326
- const sources = detectWarehouseSources(installDir);
1327
- if (sources.length === 0) {
1328
- fail({ kind: "no-sources" });
1329
- return;
1330
- }
1331
- analytics.setTag("warehouse_source_kinds", sources.map((s) => s.kind).join(","));
1332
- analytics.setTag("warehouse_source_modes", sources.map((s) => `${s.kind}:${s.mode}`).join(","));
1333
- analytics.setTag("warehouse_source_count", sources.length);
1334
- setFrameworkContext(DETECTED_WAREHOUSE_SOURCES_KEY, sources);
1335
- }
1336
- //#endregion
1337
528
  //#region src/lib/programs/warehouse-source/steps.ts
1338
529
  const WAREHOUSE_SOURCE_PROGRAM = [
1339
530
  {
@@ -1637,7 +828,10 @@ const auditConfig = {
1637
828
  run: auditRun,
1638
829
  allowedTools: ["Agent"],
1639
830
  disallowedTools: [WIZARD_TOOL_NAMES.wizardAsk],
1640
- cliOptions: { ...headlessOption }
831
+ cliOptions: {
832
+ ...headlessOption,
833
+ ...regionOption
834
+ }
1641
835
  };
1642
836
  //#endregion
1643
837
  //#region src/lib/programs/events-audit/steps.ts
@@ -2604,10 +1798,12 @@ const DISPLAY_NAME = {
2604
1798
  };
2605
1799
  /**
2606
1800
  * Variants the wizard can wire up source-map upload for automatically. The
2607
- * native variants (react-native, android, flutter, ios) are recognised but not
2608
- * 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.
2609
1803
  */
2610
1804
  const AUTOMATABLE_VARIANTS = [
1805
+ "android",
1806
+ "ios",
2611
1807
  "web",
2612
1808
  "nextjs",
2613
1809
  "node",
@@ -2618,6 +1814,11 @@ const AUTOMATABLE_VARIANTS = [
2618
1814
  "webpack",
2619
1815
  "rollup"
2620
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"]);
2621
1822
  /** `[ABORT] <reason>` cases the source maps skill can emit. */
2622
1823
  const SOURCE_MAPS_ABORT_CASES = [{
2623
1824
  match: /^no posthog sdk detected$/i,
@@ -2691,6 +1892,28 @@ function buildSourceMapsUploadPrompt(params) {
2691
1892
  const { displayName, variant, skillId, projectPath, projectId, host, settingsUrl, uiHost } = params;
2692
1893
  const platformLabel = displayName ?? variant;
2693
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.`;
2694
1917
  return `You are wiring up PostHog Error Tracking source map upload for this ${platformLabel} project.
2695
1918
 
2696
1919
  Project context:
@@ -2698,7 +1921,7 @@ Project context:
2698
1921
  - PostHog Host: ${host}
2699
1922
  - Detected platform: ${platformLabel}
2700
1923
  - Skill to use: ${skillId}
2701
- ${inSubproject ? `- Project directory (relative to repo root): ${projectPath}` : "- Project directory: the repo root"}
1924
+ ${projectLine}
2702
1925
  - Personal API keys settings page: ${settingsUrl}
2703
1926
 
2704
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` : ""}.
@@ -2766,26 +1989,7 @@ STEP 3 — Apply build-config changes. (skill: "Apply build-config changes")
2766
1989
  Make the bundler / build-config changes the skill's step instructs. The
2767
1990
  skill and its reference are the source of truth for this platform.
2768
1991
 
2769
- STEP 4 — Make the credentials readable at build time. (skill: "Make credentials available at build time")
2770
- Follow the skill's step. Wizard-specific: if it calls for a loader (e.g.
2771
- \`dotenv\`), install it SILENTLY — do NOT ask the user or call wizard_ask.
2772
- Skip this step entirely if the platform already auto-loads .env.
2773
-
2774
- STEP 5 — Write the credentials to the env file. (skill: "Write credentials to the env file")
2775
- Use the wizard-tools MCP server. Reuse the env file the skill tells you to
2776
- pick — the prerequisite PostHog integration usually already wrote
2777
- POSTHOG_* vars to one, so seed your keys alongside them.
2778
- - First call check_env_keys on that file (returns present/absent, never
2779
- values — don't read the file directly).
2780
- - Then call set_env_values, passing the STEP 1 secretRef as a value
2781
- object, not a literal string:
2782
- values: {
2783
- "POSTHOG_CLI_API_KEY": { secretRef: "<the ref from STEP 1>" },
2784
- "POSTHOG_CLI_PROJECT_ID": "${projectId}",
2785
- "POSTHOG_CLI_HOST": "${host}"
2786
- }
2787
- Variable names follow the skill's per-uploader conventions. The wizard
2788
- resolves the ref locally before writing, so you never see the key value.
1992
+ ${credentialSteps}
2789
1993
 
2790
1994
  STEP 6 — Identify the build AND run commands. (skill: "Identify the build and run commands")
2791
1995
  Per the skill, resolve the production BUILD command and the RUN command
@@ -2823,13 +2027,24 @@ STEP 8 — Offer to test the local setup. (skill: "Test the local setup")
2823
2027
  If "yes", follow the skill's "Test the local setup" step for the
2824
2028
  platform-appropriate affordance, the captureException shape, the
2825
2029
  placement, and the read-before-edit / always-revert rules. Then pause for
2826
- the user with wizard_ask, baking the EXACT build and run commands from
2827
- STEP 6 (and the exact button label / route) into the prompt as literal,
2828
- copy-pasteable steps. Separate each numbered step with \\n\\n so the TUI
2829
- 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:
2830
2045
  {
2831
2046
  id: "test-done",
2832
- 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.",
2833
2048
  kind: "single",
2834
2049
  options: [{ label: "Continue (revert test code)", value: "continue" }]
2835
2050
  }
@@ -3171,9 +2386,135 @@ const getContentBlocks$1 = (store) => pace([
3171
2386
  }
3172
2387
  ]);
3173
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
3174
2493
  //#region src/lib/programs/error-tracking-upload-source-maps/index.ts
3175
2494
  const REPORT_FILE$1 = "posthog-source-maps-report.md";
3176
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
+ }
3177
2518
  const errorTrackingUploadSourceMapsConfig = {
3178
2519
  command: "upload-source-maps",
3179
2520
  description: "Upload source maps to PostHog Error Tracking",
@@ -3205,6 +2546,7 @@ const errorTrackingUploadSourceMapsConfig = {
3205
2546
  customPrompt: (ctx) => {
3206
2547
  const { variant, displayName, projectPath, skillId } = readSelection();
3207
2548
  if (!skillId || !variant) return SOURCE_MAPS_DETECTION_FAILED_PROMPT;
2549
+ if (VARIANTS_REQUIRING_POSTHOG_CLI.has(variant)) ensurePostHogCli(variant);
3208
2550
  const uiHost = ctx.host.appHost.replace(/\/$/, "");
3209
2551
  return buildSourceMapsUploadPrompt({
3210
2552
  displayName,
@@ -4387,12 +3729,12 @@ const mcpAddCommand = {
4387
3729
  function runMcpAdd(argv) {
4388
3730
  const features = parseFeatures(argv.features);
4389
3731
  (async () => {
4390
- const { readApiKeyFromEnv } = await import("./env-api-key-AcC_tz8G.js").then((n) => n.t);
3732
+ const { readApiKeyFromEnv } = await import("./env-api-key-C3LzH8Lr.js").then((n) => n.t);
4391
3733
  const apiKey = argv.apiKey || readApiKeyFromEnv();
4392
3734
  const debug = argv.debug;
4393
3735
  const localMcp = argv.local;
4394
3736
  try {
4395
- const { startTUI } = await import("./start-tui-DHa_9aiB.js");
3737
+ const { startTUI } = await import("./start-tui-Cwc-PFma.js");
4396
3738
  const { buildSession } = await import("./wizard-session-DWHe83uk.js");
4397
3739
  const tui = startTUI(VERSION, Program.McpAdd);
4398
3740
  tui.store.session = buildSession({
@@ -4405,7 +3747,7 @@ function runMcpAdd(argv) {
4405
3747
  } catch (error) {
4406
3748
  if (!isTUIUnavailable(error)) throw error;
4407
3749
  setUI(new LoggingUI());
4408
- const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-CNzZMSat.js").then((n) => n.r);
3750
+ const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-Bv2CBSil.js").then((n) => n.r);
4409
3751
  await addMCPServerToClientsStep({
4410
3752
  local: localMcp,
4411
3753
  features,
@@ -4444,7 +3786,7 @@ function runMcpRemove(argv) {
4444
3786
  const debug = argv.debug;
4445
3787
  const localMcp = argv.local;
4446
3788
  try {
4447
- const { startTUI } = await import("./start-tui-DHa_9aiB.js");
3789
+ const { startTUI } = await import("./start-tui-Cwc-PFma.js");
4448
3790
  const { buildSession } = await import("./wizard-session-DWHe83uk.js");
4449
3791
  const tui = startTUI(VERSION, Program.McpRemove);
4450
3792
  tui.store.session = buildSession({
@@ -4454,7 +3796,7 @@ function runMcpRemove(argv) {
4454
3796
  });
4455
3797
  } catch {
4456
3798
  setUI(new LoggingUI());
4457
- const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-CNzZMSat.js").then((n) => n.r);
3799
+ const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-Bv2CBSil.js").then((n) => n.r);
4458
3800
  await removeMCPServerFromClientsStep({ local: localMcp });
4459
3801
  }
4460
3802
  })();
@@ -4476,7 +3818,7 @@ function runMcpTutorial(argv) {
4476
3818
  const debug = argv.debug;
4477
3819
  const localMcp = argv.local;
4478
3820
  try {
4479
- const { startTUI } = await import("./start-tui-DHa_9aiB.js");
3821
+ const { startTUI } = await import("./start-tui-Cwc-PFma.js");
4480
3822
  const { buildSession } = await import("./wizard-session-DWHe83uk.js");
4481
3823
  const tui = startTUI(VERSION, Program.McpTutorial);
4482
3824
  tui.store.session = buildSession({
@@ -4557,10 +3899,10 @@ function runWizard(config, options) {
4557
3899
  (async () => {
4558
3900
  try {
4559
3901
  const installDir = options.installDir || process.cwd();
4560
- const { startTUI } = await import("./start-tui-DHa_9aiB.js");
3902
+ const { startTUI } = await import("./start-tui-Cwc-PFma.js");
4561
3903
  const { buildSession, RunPhase } = await import("./wizard-session-DWHe83uk.js");
4562
- const { TaskStreamPush } = await import("./task-stream-B7qia9eW.js");
4563
- const { PostHogDestination } = await import("./posthog-DFyux4Vw.js");
3904
+ const { TaskStreamPush } = await import("./task-stream-DQT3vjwS.js");
3905
+ const { PostHogDestination } = await import("./posthog-DZZbziJ1.js");
4564
3906
  tui = startTUI(WIZARD_VERSION, config.id);
4565
3907
  const activeTui = tui;
4566
3908
  const session = buildSession({
@@ -4625,7 +3967,7 @@ function runWizard(config, options) {
4625
3967
  if (shown(step)) await advanceStep(step, activeTui.store, config);
4626
3968
  }
4627
3969
  else if (skipAgent) {
4628
- const { getOrAskForProjectData } = await import("./setup-utils-Qp-u6BZk.js").then((n) => n.r);
3970
+ const { getOrAskForProjectData } = await import("./setup-utils-Cb5uACEO.js").then((n) => n.r);
4629
3971
  const { projectApiKey, host, accessToken, projectId } = await getOrAskForProjectData({
4630
3972
  signup: session.signup,
4631
3973
  ci: session.ci,
@@ -4687,15 +4029,14 @@ function modeLabel(mode) {
4687
4029
  return mode === "headless" ? "Headless" : "CI";
4688
4030
  }
4689
4031
  /**
4690
- * The single non-interactive validation layer: defaults region and requires
4691
- * 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
4692
4034
  * `runNonInteractive`, so this is the one place these checks live. UI must be
4693
4035
  * initialized before calling.
4694
4036
  */
4695
4037
  function validateNonInteractiveOptions(options, mode) {
4696
4038
  const label = modeLabel(mode);
4697
4039
  const keyHint = mode === "headless" ? "personal API key phx_xxx or pha_ OAuth access token" : "personal API key phx_xxx";
4698
- if (!options.region) options.region = "us";
4699
4040
  if (!options.apiKey) {
4700
4041
  getUI().intro("PostHog Wizard");
4701
4042
  getUI().log.error(`${label} mode requires --api-key (${keyHint})`);
@@ -4728,10 +4069,10 @@ function runNonInteractive(config, options, mode) {
4728
4069
  (async () => {
4729
4070
  const path = await import("path");
4730
4071
  const { buildSession, RunPhase, OutroKind } = await import("./wizard-session-DWHe83uk.js");
4731
- const { readEnvironment } = await import("./environment-kZtkp7eG.js").then((n) => n.t);
4732
- const { readApiKeyFromEnv } = await import("./env-api-key-AcC_tz8G.js").then((n) => n.t);
4733
- const { configureLogFileFromEnvironment, logToFile } = await import("./debug-BixHZmHv.js");
4734
- const { wizardAbort, WizardError } = await import("./wizard-abort-DpDmuCfA.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");
4735
4076
  configureLogFileFromEnvironment();
4736
4077
  const env = readEnvironment();
4737
4078
  const apiKey = options.apiKey ?? readApiKeyFromEnv() ?? void 0;
@@ -4752,7 +4093,8 @@ function runNonInteractive(config, options, mode) {
4752
4093
  harness: options.harness,
4753
4094
  sequence: options.sequence,
4754
4095
  model: options.model,
4755
- ...env
4096
+ ...env,
4097
+ region: options.region ?? env.region
4756
4098
  });
4757
4099
  session.programLabel = config.id;
4758
4100
  if (config.skillId) session.skillId = config.skillId;
@@ -4762,9 +4104,9 @@ function runNonInteractive(config, options, mode) {
4762
4104
  let store = null;
4763
4105
  let taskStream = null;
4764
4106
  if (mode === "headless") {
4765
- const { WizardStore } = await import("./store-DSwsITKX.js").then((n) => n.n);
4766
- const { HeadlessUI } = await import("./headless-ui-DWmMyhaP.js");
4767
- const { TaskStreamPush, PostHogDestination } = await import("./task-stream-B7qia9eW.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");
4768
4110
  store = new WizardStore(config.id);
4769
4111
  store.session = session;
4770
4112
  setUI(new HeadlessUI(store));
@@ -4820,7 +4162,7 @@ function runNonInteractive(config, options, mode) {
4820
4162
  });
4821
4163
  }
4822
4164
  }
4823
- const { runAgent } = await import("./agent-runner-B0LTVFfw.js").then((n) => n.t);
4165
+ const { runAgent } = await import("./agent-runner-CV3qh_2p.js").then((n) => n.t);
4824
4166
  await runAgent(config, session);
4825
4167
  await settleStream(RunPhase.Completed);
4826
4168
  } catch (error) {
@@ -5749,7 +5091,7 @@ async function runDoctorCI(options) {
5749
5091
  getUI().intro("Welcome to the PostHog setup wizard");
5750
5092
  getUI().log.info("Running posthog-doctor in CI mode");
5751
5093
  try {
5752
- const { getOrAskForProjectData } = await import("./setup-utils-Qp-u6BZk.js").then((n) => n.r);
5094
+ const { getOrAskForProjectData } = await import("./setup-utils-Cb5uACEO.js").then((n) => n.r);
5753
5095
  const { host, accessToken, projectId } = await getOrAskForProjectData({
5754
5096
  signup: false,
5755
5097
  ci: true,
@@ -5767,7 +5109,7 @@ async function runDoctorCI(options) {
5767
5109
  for (const issue of sorted) getUI().log.info(` • [${issue.severity}] ${getKindMeta(issue.kind).title}`);
5768
5110
  process.exit(1);
5769
5111
  } catch (error) {
5770
- const { ApiError } = await import("./api-uCMvDII5.js").then((n) => n.n);
5112
+ const { ApiError } = await import("./api-CmIWcW-U.js").then((n) => n.n);
5771
5113
  const message = error instanceof ApiError && error.statusCode === 401 ? "Your PostHog API key is invalid or expired." : error instanceof Error ? error.message : String(error);
5772
5114
  getUI().log.error(`Doctor failed: ${message}`);
5773
5115
  process.exit(1);
@@ -5849,7 +5191,7 @@ function runSlackConnect(argv) {
5849
5191
  (async () => {
5850
5192
  const debug = argv.debug;
5851
5193
  try {
5852
- const { startTUI } = await import("./start-tui-DHa_9aiB.js");
5194
+ const { startTUI } = await import("./start-tui-Cwc-PFma.js");
5853
5195
  const { buildSession } = await import("./wizard-session-DWHe83uk.js");
5854
5196
  const tui = startTUI(VERSION, Program.SlackConnect);
5855
5197
  tui.store.session = buildSession({
@@ -5973,105 +5315,6 @@ const skillCommand = {
5973
5315
  }
5974
5316
  };
5975
5317
  //#endregion
5976
- //#region src/steps/install-cli-steering/index.ts
5977
- const dirExists = (...segments) => {
5978
- try {
5979
- return fs$1.existsSync(path$1.join(os.homedir(), ...segments));
5980
- } catch {
5981
- return false;
5982
- }
5983
- };
5984
- const CLI_STEERING_TARGETS = [
5985
- {
5986
- id: "claude-code",
5987
- name: "Claude Code",
5988
- instructionsPath: () => path$1.join(os.homedir(), ".claude", "CLAUDE.md"),
5989
- isDetected: () => dirExists(".claude")
5990
- },
5991
- {
5992
- id: "codex",
5993
- name: "Codex",
5994
- instructionsPath: () => path$1.join(os.homedir(), ".codex", "AGENTS.md"),
5995
- isDetected: () => dirExists(".codex")
5996
- },
5997
- {
5998
- id: "gemini",
5999
- name: "Gemini CLI",
6000
- instructionsPath: () => path$1.join(os.homedir(), ".gemini", "GEMINI.md"),
6001
- isDetected: () => dirExists(".gemini")
6002
- }
6003
- ];
6004
- function findTarget(id) {
6005
- return CLI_STEERING_TARGETS.find((target) => target.id === id);
6006
- }
6007
- function detectTargets() {
6008
- return CLI_STEERING_TARGETS.filter((target) => target.isDetected());
6009
- }
6010
- const spawnOptions = {
6011
- encoding: "utf-8",
6012
- shell: process.platform === "win32"
6013
- };
6014
- /**
6015
- * Install or update the PostHog CLI in the user's environment. `npm install
6016
- * --global @posthog/cli@latest` covers both first-time installs and upgrades
6017
- * for existing npm-installed CLIs.
6018
- */
6019
- function installOrUpdatePostHogCli() {
6020
- const args = [
6021
- "install",
6022
- "--global",
6023
- "@posthog/cli@latest"
6024
- ];
6025
- debug(`Running npm ${args.join(" ")}`);
6026
- const result = spawnSync("npm", args, spawnOptions);
6027
- if (result.error) return {
6028
- success: false,
6029
- error: `Failed to run npm: ${result.error.message}. Is Node.js installed?`
6030
- };
6031
- if (result.status !== 0) return {
6032
- success: false,
6033
- error: (result.stderr || result.stdout || "").trim() || `npm install --global @posthog/cli@latest exited with status ${result.status ?? "unknown"}`
6034
- };
6035
- return { success: true };
6036
- }
6037
- /**
6038
- * Delegate the actual write to the installed `posthog-cli api agents-md
6039
- * install`. The steering snippet lives in the CLI (its single source of truth),
6040
- * so the command should run only after `installOrUpdatePostHogCli` refreshes
6041
- * the CLI to the latest release.
6042
- */
6043
- function installSteeringSnippet(filePath) {
6044
- const args = [
6045
- "api",
6046
- "agents-md",
6047
- "install",
6048
- "--path",
6049
- filePath
6050
- ];
6051
- debug(`Running posthog-cli ${args.join(" ")}`);
6052
- const result = spawnSync("posthog-cli", args, {
6053
- ...spawnOptions,
6054
- env: {
6055
- ...process.env,
6056
- POSTHOG_CLI_EXPERIMENTAL_API: "1"
6057
- }
6058
- });
6059
- if (result.error) return {
6060
- success: false,
6061
- filePath,
6062
- error: `Failed to run posthog-cli: ${result.error.message}. Make sure npm's global bin directory is on your PATH.`
6063
- };
6064
- if (result.status !== 0) return {
6065
- success: false,
6066
- filePath,
6067
- error: (result.stderr || result.stdout || "").trim() || `posthog-cli exited with status ${result.status ?? "unknown"}`
6068
- };
6069
- return {
6070
- success: true,
6071
- filePath
6072
- };
6073
- }
6074
- //#endregion
6075
5318
  //#region src/commands/cli/add.ts
6076
5319
  const cliAddCommand = {
6077
5320
  name: "add",
@@ -6231,6 +5474,6 @@ function resolveInstallDir() {
6231
5474
  }
6232
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();
6233
5476
  //#endregion
6234
- 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 };
6235
5478
 
6236
5479
  //# sourceMappingURL=bin.js.map