@posthog/wizard 2.54.0 → 2.55.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 (87) hide show
  1. package/dist/{add-mcp-server-to-clients-B3TcwTT5.js → add-mcp-server-to-clients-D6PkSBh4.js} +4 -4
  2. package/dist/{add-mcp-server-to-clients-B3TcwTT5.js.map → add-mcp-server-to-clients-D6PkSBh4.js.map} +1 -1
  3. package/dist/{agent-interface-CLvG6Rk9.js → agent-interface-CpFBADlw.js} +6 -6
  4. package/dist/{agent-interface-CLvG6Rk9.js.map → agent-interface-CpFBADlw.js.map} +1 -1
  5. package/dist/{agent-prompt-loader-Baqm1JMD.js → agent-prompt-loader-puPxllME.js} +5 -5
  6. package/dist/{agent-prompt-loader-Baqm1JMD.js.map → agent-prompt-loader-puPxllME.js.map} +1 -1
  7. package/dist/{agent-runner-D6zGTJqn.js → agent-runner-CpRxcnos.js} +13 -13
  8. package/dist/{agent-runner-D6zGTJqn.js.map → agent-runner-CpRxcnos.js.map} +1 -1
  9. package/dist/analytics-Cy9wgNoD.js +2 -0
  10. package/dist/{analytics-D7hsukY7.js → analytics-DnWQLKT5.js} +2 -2
  11. package/dist/{analytics-D7hsukY7.js.map → analytics-DnWQLKT5.js.map} +1 -1
  12. package/dist/{api-BSq9hLu5.js → api-DMNftHUP.js} +3 -3
  13. package/dist/{api-BSq9hLu5.js.map → api-DMNftHUP.js.map} +1 -1
  14. package/dist/bin.js +175 -71
  15. package/dist/bin.js.map +1 -1
  16. package/dist/{bounded-fs-Cq960M-V.js → bounded-fs-D-VnHUkH.js} +3 -3
  17. package/dist/{bounded-fs-Cq960M-V.js.map → bounded-fs-D-VnHUkH.js.map} +1 -1
  18. package/dist/{ci-install-w-mywB9x.js → ci-install-BuVd4Z5O.js} +4 -4
  19. package/dist/{ci-install-w-mywB9x.js.map → ci-install-BuVd4Z5O.js.map} +1 -1
  20. package/dist/{debug-CX6ZqL9r.js → debug-BRe2lTl9.js} +1 -1
  21. package/dist/{debug-CbgLkSCY.js → debug-Dp9OMl7B.js} +3 -3
  22. package/dist/{debug-CbgLkSCY.js.map → debug-Dp9OMl7B.js.map} +1 -1
  23. package/dist/{environment-BWuaOExh.js → environment-_Htke7Dm.js} +4 -4
  24. package/dist/{environment-BWuaOExh.js.map → environment-_Htke7Dm.js.map} +1 -1
  25. package/dist/{file-watcher-D9tgVBkp.js → file-watcher-DxwhtY-v.js} +2 -2
  26. package/dist/{file-watcher-D9tgVBkp.js.map → file-watcher-DxwhtY-v.js.map} +1 -1
  27. package/dist/{headless-ui-rH97E35y.js → headless-ui-CUJT6bP6.js} +2 -2
  28. package/dist/{headless-ui-rH97E35y.js.map → headless-ui-CUJT6bP6.js.map} +1 -1
  29. package/dist/{interactive-D-MVMdBl.js → interactive-CgjnlcLr.js} +2 -2
  30. package/dist/{interactive-D-MVMdBl.js.map → interactive-CgjnlcLr.js.map} +1 -1
  31. package/dist/{mcp-jKHwa45f.js → mcp-BImh1cSl.js} +2 -2
  32. package/dist/{mcp-jKHwa45f.js.map → mcp-BImh1cSl.js.map} +1 -1
  33. package/dist/{mcp-prompt-streaming-DxDftNHb.js → mcp-prompt-streaming-C0Hd1fW-.js} +3 -3
  34. package/dist/{mcp-prompt-streaming-DxDftNHb.js.map → mcp-prompt-streaming-C0Hd1fW-.js.map} +1 -1
  35. package/dist/{non-interactive-eXT2_WCR.js → non-interactive-C6l4BRQ2.js} +2 -2
  36. package/dist/{non-interactive-eXT2_WCR.js.map → non-interactive-C6l4BRQ2.js.map} +1 -1
  37. package/dist/{orchestrator-tools-CsXrPhsd.js → orchestrator-tools-CC5RnJdr.js} +3 -3
  38. package/dist/{orchestrator-tools-CsXrPhsd.js.map → orchestrator-tools-CC5RnJdr.js.map} +1 -1
  39. package/dist/{package-manager-CASp14jY.js → package-manager-B3wbHpGJ.js} +2 -2
  40. package/dist/{package-manager-CASp14jY.js.map → package-manager-B3wbHpGJ.js.map} +1 -1
  41. package/dist/{pi-CfdqOKDI.js → pi-D1KNd_2R.js} +11 -11
  42. package/dist/{pi-CfdqOKDI.js.map → pi-D1KNd_2R.js.map} +1 -1
  43. package/dist/{playground-DuBvnGkP.js → playground-B_3YPtlb.js} +6 -6
  44. package/dist/{playground-DuBvnGkP.js.map → playground-B_3YPtlb.js.map} +1 -1
  45. package/dist/{posthog-integration-Dy5cNPaa.js → posthog-integration-B22dCMjz.js} +15 -15
  46. package/dist/{posthog-integration-Dy5cNPaa.js.map → posthog-integration-B22dCMjz.js.map} +1 -1
  47. package/dist/{provisioning-CS6fQriR.js → provisioning-CUGRpYeK.js} +122 -25
  48. package/dist/provisioning-CUGRpYeK.js.map +1 -0
  49. package/dist/{queue-tools-ai7gCWyU.js → queue-tools-BYnHqauP.js} +3 -3
  50. package/dist/{queue-tools-ai7gCWyU.js.map → queue-tools-BYnHqauP.js.map} +1 -1
  51. package/dist/{registry-D0hx_-KP.js → registry-BoIdcL-x.js} +5 -5
  52. package/dist/{registry-D0hx_-KP.js.map → registry-BoIdcL-x.js.map} +1 -1
  53. package/dist/{security-BNqgFjYh.js → security-BtifxSc6.js} +4 -4
  54. package/dist/{security-BNqgFjYh.js.map → security-BtifxSc6.js.map} +1 -1
  55. package/dist/{setup-utils-6qyTDNyd.js → setup-utils-Cr9u_GAd.js} +19 -9
  56. package/dist/{setup-utils-6qyTDNyd.js.map → setup-utils-Cr9u_GAd.js.map} +1 -1
  57. package/dist/{start-tui-DNkm-n-4.js → start-tui-p1oiV4Y6.js} +54 -41
  58. package/dist/start-tui-p1oiV4Y6.js.map +1 -0
  59. package/dist/{steps-CqHAVc8R.js → steps-C-QxcbJm.js} +7 -7
  60. package/dist/{steps-CqHAVc8R.js.map → steps-C-QxcbJm.js.map} +1 -1
  61. package/dist/{store-sIaF89XA.js → store-DCoiR5X4.js} +4 -4
  62. package/dist/{store-sIaF89XA.js.map → store-DCoiR5X4.js.map} +1 -1
  63. package/dist/{subagent-CKNbRtfQ.js → subagent-DSLaQg5z.js} +2 -2
  64. package/dist/{subagent-CKNbRtfQ.js.map → subagent-DSLaQg5z.js.map} +1 -1
  65. package/dist/{task-DwzRxORh.js → task-DtHtqm3q.js} +12 -12
  66. package/dist/{task-DwzRxORh.js.map → task-DtHtqm3q.js.map} +1 -1
  67. package/dist/{task-stream-BdJV-usk.js → task-stream-XXeIjdu1.js} +3 -3
  68. package/dist/{task-stream-BdJV-usk.js.map → task-stream-XXeIjdu1.js.map} +1 -1
  69. package/dist/{tasks-yqJVuTvc.js → tasks-CDC1rMTC.js} +2 -2
  70. package/dist/{tasks-yqJVuTvc.js.map → tasks-CDC1rMTC.js.map} +1 -1
  71. package/dist/{telemetry-UBL5MQtw.js → telemetry-L3mGi3gj.js} +3 -3
  72. package/dist/{telemetry-UBL5MQtw.js.map → telemetry-L3mGi3gj.js.map} +1 -1
  73. package/dist/{terminal-vo5Zl7j1.js → terminal-D1G7fSuk.js} +11 -11
  74. package/dist/{terminal-vo5Zl7j1.js.map → terminal-D1G7fSuk.js.map} +1 -1
  75. package/dist/{tools-Br8lP29r.js → tools-BvppPl5C.js} +6 -6
  76. package/dist/{tools-Br8lP29r.js.map → tools-BvppPl5C.js.map} +1 -1
  77. package/dist/{wizard-abort-BRsd7-aB.js → wizard-abort-DFC6tm8V.js} +1 -1
  78. package/dist/{wizard-abort-FIC6lKCs.js → wizard-abort-abTHW4U0.js} +3 -3
  79. package/dist/{wizard-abort-FIC6lKCs.js.map → wizard-abort-abTHW4U0.js.map} +1 -1
  80. package/dist/{yara-hooks-DxpCD72V.js → yara-hooks-CWl6JOv1.js} +4 -4
  81. package/dist/{yara-hooks-DxpCD72V.js.map → yara-hooks-CWl6JOv1.js.map} +1 -1
  82. package/dist/yara-hooks-kLYtFhy7.js +2 -0
  83. package/package.json +1 -1
  84. package/dist/analytics-BBJE4hIu.js +0 -2
  85. package/dist/provisioning-CS6fQriR.js.map +0 -1
  86. package/dist/start-tui-DNkm-n-4.js.map +0 -1
  87. package/dist/yara-hooks--QA2Cwjv.js +0 -2
package/dist/bin.js CHANGED
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env node
2
- import { Ct as regionOption, L as Integration, St as isHeadless, U as POSTHOG_DOCS_URL, a as getLogFilePath, f as getUI, ft as WIZARD_USER_AGENT, ht as VERSION, m as LoggingUI, p as setUI, pt as getSkillsBaseUrl, r as debug, s as logToFile, xt as headlessOption } from "./debug-CbgLkSCY.js";
3
- import { n as analytics } from "./analytics-D7hsukY7.js";
4
- import { r as setEntryCommand } from "./telemetry-UBL5MQtw.js";
5
- import { a as walkProjectFiles, i as safeReadFile } from "./bounded-fs-Cq960M-V.js";
6
- import { n as isUsingTypeScript } from "./setup-utils-6qyTDNyd.js";
7
- import { o as handleApiError } from "./api-BSq9hLu5.js";
2
+ import { Ct as regionOption, L as Integration, St as isHeadless, U as POSTHOG_DOCS_URL, a as getLogFilePath, f as getUI, ft as WIZARD_USER_AGENT, ht as VERSION, m as LoggingUI, p as setUI, pt as getSkillsBaseUrl, r as debug, s as logToFile, xt as headlessOption } from "./debug-Dp9OMl7B.js";
3
+ import { n as analytics } from "./analytics-DnWQLKT5.js";
4
+ import { r as setEntryCommand } from "./telemetry-L3mGi3gj.js";
5
+ import { a as walkProjectFiles, i as safeReadFile } from "./bounded-fs-D-VnHUkH.js";
6
+ import { n as isUsingTypeScript } from "./setup-utils-Cr9u_GAd.js";
7
+ import { o as handleApiError } from "./api-DMNftHUP.js";
8
8
  import "./wizard-session-CwgR5y3-.js";
9
- import { r as runCleanups } from "./wizard-abort-FIC6lKCs.js";
10
- import { n as isNonInteractiveEnvironment } from "./environment-BWuaOExh.js";
11
- import { n as runAgent, o as authenticate } from "./agent-runner-D6zGTJqn.js";
12
- import { l as recoverOrphanedSettingsBackups, p as AgentSignals, v as WIZARD_TOOL_NAMES, x as fetchSkillMenu } from "./agent-interface-CLvG6Rk9.js";
13
- import { S as SETUP_REPORT_FILE, _ as AUDIT_CHECKS_KEY, g as AUDIT_CHECKS_FILE, v as AUDIT_REPORT_FILE } from "./yara-hooks-DxpCD72V.js";
14
- import { i as SPINNER_MESSAGE } from "./registry-D0hx_-KP.js";
15
- import { C as gatherFrameworkContext, S as resolveProjectDir, _ as WAREHOUSE_ABORT_CASES, a as LINE_CHART_BLOCK, b as detectIntegrationProjects, d as isClearBlock, g as HEALTH_CHECK_STEP, h as Icons, i as FUNNEL_BLOCK, m as Colors, n as integrationRunStep, o as PRODUCT_SUITE_BLOCK, r as posthogIntegrationConfig, s as StatusPeekTrigger, u as wordWrap, v as detectWarehousePrerequisites, y as getDetectedWarehouseSources } from "./posthog-integration-Dy5cNPaa.js";
9
+ import { r as runCleanups } from "./wizard-abort-abTHW4U0.js";
10
+ import { n as isNonInteractiveEnvironment } from "./environment-_Htke7Dm.js";
11
+ import { n as runAgent, o as authenticate } from "./agent-runner-CpRxcnos.js";
12
+ import { l as recoverOrphanedSettingsBackups, p as AgentSignals, v as WIZARD_TOOL_NAMES, x as fetchSkillMenu } from "./agent-interface-CpFBADlw.js";
13
+ import { S as SETUP_REPORT_FILE, _ as AUDIT_CHECKS_KEY, g as AUDIT_CHECKS_FILE, v as AUDIT_REPORT_FILE } from "./yara-hooks-CWl6JOv1.js";
14
+ import { i as SPINNER_MESSAGE } from "./registry-BoIdcL-x.js";
15
+ import { C as resolveProjectDir, _ as WAREHOUSE_ABORT_CASES, a as LINE_CHART_BLOCK, b as detectWarehouseSources, d as isClearBlock, g as HEALTH_CHECK_STEP, h as Icons, i as FUNNEL_BLOCK, m as Colors, n as integrationRunStep, o as PRODUCT_SUITE_BLOCK, r as posthogIntegrationConfig, s as StatusPeekTrigger, u as wordWrap, v as detectWarehousePrerequisites, w as gatherFrameworkContext, x as detectIntegrationProjects, y as getDetectedWarehouseSources } from "./posthog-integration-B22dCMjz.js";
16
16
  import { n as readApiKeyFromEnv } from "./env-api-key-cjD4yfGT.js";
17
17
  import { satisfies } from "semver";
18
18
  import yargs from "yargs";
@@ -200,7 +200,7 @@ function runProvision(argv) {
200
200
  }
201
201
  async function provision({ email, region, name, baseUrl, jsonMode }) {
202
202
  try {
203
- const { provisionNewAccount } = await import("./provisioning-CS6fQriR.js").then((n) => n.n);
203
+ const { provisionNewAccount } = await import("./provisioning-CUGRpYeK.js").then((n) => n.r);
204
204
  if (!jsonMode) getUI().log.info(`Provisioning account for ${email} in ${region}...`);
205
205
  emitResult(await provisionNewAccount(email, name, region, { baseUrl }), jsonMode);
206
206
  process.exit(0);
@@ -267,22 +267,22 @@ const basicIntegrationCommand = {
267
267
  setEntryCommand("integrate");
268
268
  (async () => {
269
269
  if (isHeadless(argv)) {
270
- const { runHeadlessInstall } = await import("./ci-install-w-mywB9x.js");
270
+ const { runHeadlessInstall } = await import("./ci-install-BuVd4Z5O.js");
271
271
  return runHeadlessInstall(argv);
272
272
  }
273
273
  if (argv.ci) {
274
- const { runCIInstall } = await import("./ci-install-w-mywB9x.js");
274
+ const { runCIInstall } = await import("./ci-install-BuVd4Z5O.js");
275
275
  return runCIInstall(argv);
276
276
  }
277
277
  if (isNonInteractiveEnvironment()) {
278
- const { failNonInteractive } = await import("./non-interactive-eXT2_WCR.js");
278
+ const { failNonInteractive } = await import("./non-interactive-C6l4BRQ2.js");
279
279
  return failNonInteractive();
280
280
  }
281
281
  if (argv.playground) {
282
- const { runPlayground } = await import("./playground-DuBvnGkP.js");
282
+ const { runPlayground } = await import("./playground-B_3YPtlb.js");
283
283
  return runPlayground();
284
284
  }
285
- const { runInteractive } = await import("./interactive-D-MVMdBl.js");
285
+ const { runInteractive } = await import("./interactive-CgjnlcLr.js");
286
286
  runInteractive(argv);
287
287
  })();
288
288
  }
@@ -1788,13 +1788,12 @@ const DISPLAY_NAME = {
1788
1788
  rollup: "Rollup"
1789
1789
  };
1790
1790
  /**
1791
- * Variants the wizard can wire up source-map upload for automatically. React
1792
- * Native is recognised but not yet automatable, so the agentic picker treats
1793
- * it as non-instrumentable.
1791
+ * Variants the wizard can wire up source-map upload for automatically.
1794
1792
  */
1795
1793
  const AUTOMATABLE_VARIANTS = [
1796
1794
  "android",
1797
1795
  "ios",
1796
+ "react-native",
1798
1797
  "flutter",
1799
1798
  "web",
1800
1799
  "nextjs",
@@ -1808,28 +1807,39 @@ const AUTOMATABLE_VARIANTS = [
1808
1807
  ];
1809
1808
  /**
1810
1809
  * Variants the wizard pre-installs a machine-global `posthog-cli` for — their
1811
- * build shells out to it with no npx / local-dep fallback. JS variants stay
1812
- * out. Flutter counts here despite emitting plain `.js.map` files: a Flutter
1813
- * project has no `package.json`, so there is no npx or local dependency to
1814
- * fall back to when the post-build step invokes the CLI.
1810
+ * build shells out to it with no npx / local-dep fallback. Web JS variants stay
1811
+ * out. React Native counts as native here — its Xcode build phases and Gradle
1812
+ * tasks invoke the global CLI. Flutter counts too despite emitting plain
1813
+ * `.js.map` files: a Flutter project has no `package.json`, so there is no npx
1814
+ * or local dependency to fall back to when the post-build step invokes the CLI.
1815
1815
  */
1816
1816
  const VARIANTS_REQUIRING_POSTHOG_CLI = new Set([
1817
1817
  "ios",
1818
1818
  "android",
1819
+ "react-native",
1819
1820
  "flutter"
1820
1821
  ]);
1821
1822
  /** `[ABORT] <reason>` cases the source maps skill can emit. */
1822
- const SOURCE_MAPS_ABORT_CASES = [{
1823
- match: /^no posthog sdk detected$/i,
1824
- message: "No PostHog SDK detected",
1825
- body: "The agent could not find a PostHog SDK in your project. Source map upload requires the SDK to already be installed so it can report errors. Run `npx @posthog/wizard` first to install the SDK.",
1826
- docsUrl: "https://posthog.com/docs/error-tracking"
1827
- }, {
1828
- match: /^build command not found$/i,
1829
- message: "Build command not found",
1830
- body: "The agent could not identify how to build your project. Source map upload runs as part of the production build. Add a build script to your project and run this wizard again.",
1831
- docsUrl: "https://posthog.com/docs/error-tracking/upload-source-maps"
1832
- }];
1823
+ const SOURCE_MAPS_ABORT_CASES = [
1824
+ {
1825
+ match: /^no posthog sdk detected$/i,
1826
+ message: "No PostHog SDK detected",
1827
+ body: "The agent could not find a PostHog SDK in your project. Source map upload requires the SDK to already be installed so it can report errors. Run `npx @posthog/wizard` first to install the SDK.",
1828
+ docsUrl: "https://posthog.com/docs/error-tracking"
1829
+ },
1830
+ {
1831
+ match: /^build command not found$/i,
1832
+ message: "Build command not found",
1833
+ body: "The agent could not identify how to build your project. Source map upload runs as part of the production build. Add a build script to your project and run this wizard again.",
1834
+ docsUrl: "https://posthog.com/docs/error-tracking/upload-source-maps"
1835
+ },
1836
+ {
1837
+ match: /^bare react native not supported$/i,
1838
+ message: "Bare React Native is not supported",
1839
+ body: "Source-map upload for React Native requires Expo, and this project has no `expo` package. Bare React Native builds cannot inject the chunk IDs PostHog needs to resolve stack traces.",
1840
+ docsUrl: "https://posthog.com/docs/error-tracking/upload-source-maps/react-native"
1841
+ }
1842
+ ];
1833
1843
  const SOURCE_MAPS_CONTEXT_KEYS = {
1834
1844
  skillVariant: "sourceMapsSkillVariant",
1835
1845
  displayName: "sourceMapsDisplayName",
@@ -1888,7 +1898,7 @@ const SOURCE_MAPS_DETECTION_FAILED_PROMPT = `Detection did not pick a source map
1888
1898
  Emit: ${AgentSignals.ABORT} unsupported-platform
1889
1899
  Then halt.`;
1890
1900
  function buildSourceMapsUploadPrompt(params) {
1891
- const { displayName, variant, skillId, projectPath, projectId, host, settingsUrl, uiHost } = params;
1901
+ const { displayName, variant, skillId, projectPath, projectId, host, settingsUrl, uiHost, reportFile } = params;
1892
1902
  const platformLabel = displayName ?? variant;
1893
1903
  const inSubproject = projectPath != null && projectPath !== ".";
1894
1904
  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)";
@@ -2051,8 +2061,16 @@ STEP 8 — Offer to test the local setup. (skill: "Test the local setup")
2051
2061
  surface any failure in STEP 9.
2052
2062
 
2053
2063
  STEP 9 — Summarise and hand off. (skill: "Verify and hand off")
2054
- Follow the skill's "Verify and hand off" step. The Symbol sets page for
2055
- this project — where the user confirms the upload landed — is:
2064
+ Follow the skill's "Verify and hand off" step. Write the hand-off to
2065
+ \`${reportFile}\` at the WIZARD'S WORKING DIRECTORY — pass exactly
2066
+ \`${reportFile}\` as the file path, never prefixed with the selected
2067
+ project directory; this file is the one exception to the project-scope
2068
+ rule above. Cover: the files you changed (paths only), the exact build
2069
+ and upload commands, every CI secret the user still has to create, and
2070
+ how to verify the upload — then give the same summary in chat. Never
2071
+ write secret values into the report, only variable names. The success
2072
+ screen points the user at this file, so do not skip it. The Symbol sets page for this project — where the user
2073
+ confirms the upload landed — is:
2056
2074
  ${uiHost}/project/${projectId}/error_tracking/configuration
2057
2075
  `;
2058
2076
  }
@@ -2555,7 +2573,8 @@ const errorTrackingUploadSourceMapsConfig = {
2555
2573
  projectId: ctx.projectId,
2556
2574
  host: ctx.host.apiHost,
2557
2575
  settingsUrl: `${uiHost}/project/${ctx.projectId}/settings/user-api-keys`,
2558
- uiHost
2576
+ uiHost,
2577
+ reportFile: REPORT_FILE$1
2559
2578
  });
2560
2579
  },
2561
2580
  postRun: () => {
@@ -2605,6 +2624,12 @@ const POSTHOG_PRESENT_KEY = "postHogPresent";
2605
2624
  * into the chosen sub-app, not the root.
2606
2625
  */
2607
2626
  const SELF_DRIVING_INTEGRATE_PATH_KEY = "selfDrivingIntegratePath";
2627
+ /** Self-driving's own detected-tools key — not the warehouse one, which the integration program reads. */
2628
+ const SELF_DRIVING_DETECTED_TOOLS_KEY = "selfDrivingDetectedTools";
2629
+ /** Read the detected tools out of frameworkContext. */
2630
+ function getSelfDrivingDetectedTools(session) {
2631
+ return session.frameworkContext["selfDrivingDetectedTools"] ?? [];
2632
+ }
2608
2633
  const POSTHOG_PACKAGE_RE = /(^|["'\s/=:.@])posthog/im;
2609
2634
  const POSTHOG_MANIFESTS = [
2610
2635
  "package.json",
@@ -2790,6 +2815,44 @@ function detectSelfDrivingPrerequisites(session, setFrameworkContext) {
2790
2815
  return;
2791
2816
  }
2792
2817
  setFrameworkContext(POSTHOG_PRESENT_KEY, detectPostHogPresent(installDir));
2818
+ detectConnectedTools(installDir, setFrameworkContext);
2819
+ }
2820
+ /** Step 5's ask options intersected with `SOURCE_DETECTORS` — reconcile when the skill's catalog grows. */
2821
+ const SELF_DRIVING_TOOL_KINDS = new Set([
2822
+ "Github",
2823
+ "GitLab",
2824
+ "Gitea",
2825
+ "Linear",
2826
+ "Jira",
2827
+ "Shortcut",
2828
+ "Sentry",
2829
+ "Rollbar",
2830
+ "Bugsnag",
2831
+ "Honeybadger",
2832
+ "Raygun",
2833
+ "Zendesk",
2834
+ "Freshdesk",
2835
+ "Front",
2836
+ "Gorgias",
2837
+ "Kustomer",
2838
+ "Plain",
2839
+ "Snyk",
2840
+ "Canny",
2841
+ "Productboard",
2842
+ "GoogleSearchConsole"
2843
+ ]);
2844
+ /** Scan for inbox-connectable tools so STEP 5 can surface them first. Best-effort — never blocks detection. */
2845
+ function detectConnectedTools(installDir, setFrameworkContext) {
2846
+ try {
2847
+ const tools = detectWarehouseSources(installDir).filter((s) => SELF_DRIVING_TOOL_KINDS.has(s.kind));
2848
+ analytics.setTag("connected_tools_detected_count", tools.length);
2849
+ if (tools.length === 0) return;
2850
+ analytics.setTag("connected_tools_detected", tools.map((s) => s.kind).join(","));
2851
+ setFrameworkContext(SELF_DRIVING_DETECTED_TOOLS_KEY, tools);
2852
+ } catch (error) {
2853
+ analytics.setTag("connected_tools_detected_count", -1);
2854
+ analytics.captureException(error instanceof Error ? error : new Error(String(error)), { step: "detectConnectedTools" });
2855
+ }
2793
2856
  }
2794
2857
  //#endregion
2795
2858
  //#region src/lib/programs/self-driving/detect-agentic.ts
@@ -2920,17 +2983,38 @@ const SELF_DRIVING_PROGRAM = [
2920
2983
  //#endregion
2921
2984
  //#region src/lib/programs/self-driving/prompt.ts
2922
2985
  /**
2986
+ * Render the deterministic codebase-tool scan for the prompt. STEP 4 and
2987
+ * STEP 5 read this instead of the agent doing its own flaky "light scan":
2988
+ * enable the matching signal sources, and surface detected tools first in the
2989
+ * connected-tools ask rather than dumping the full ~500-source catalog. When
2990
+ * nothing is detected we still say so explicitly, so the agent falls back to
2991
+ * the skill's default ordering instead of inventing a scan.
2992
+ */
2993
+ function renderDetectedTools(sources) {
2994
+ if (sources.length === 0) return `Tools detected in this codebase: none found by the dependency + env scan. Use the skill's default ordering for STEP 5.`;
2995
+ return [
2996
+ "Tools detected in this codebase (deterministic dependency + env-key scan — this is evidence, not a guess):",
2997
+ ...sources.map((s) => `- ${s.label} (source_type: ${s.kind}) — ${s.matchedSignal}`),
2998
+ "",
2999
+ "Use this list in STEP 4 (enable the matching signal sources) and STEP 5 (surface these detected tools first in the connected-tools ask, ahead of the SaaS basics and the \"others\" option), exactly as the skill describes. Never enable or pre-select a tool the user has not confirmed."
3000
+ ].join("\n");
3001
+ }
3002
+ /**
2923
3003
  * Build the self-driving run prompt. The installed
2924
3004
  * `self-driving-setup` skill is the source of truth for the HOW of
2925
3005
  * every step (which MCP tools to call, which sources/scouts apply, how
2926
3006
  * to verify); this prompt carries the order, the wizard-specific
2927
3007
  * mechanics (wizard_ask, abort signals), and the project URLs.
2928
3008
  *
3009
+ * `detectedSources` is the deterministic codebase scan (from the detect step);
3010
+ * it drives STEP 4/STEP 5 tool prioritisation. Empty is fine — the block then
3011
+ * tells the agent to use the skill's default ordering.
3012
+ *
2929
3013
  * Integration (when the project has no PostHog yet) runs as a separate phase
2930
3014
  * before this — the real integration program, with its own screens and task
2931
3015
  * list — so this prompt only covers the Self-driving steps.
2932
3016
  */
2933
- function buildSelfDrivingPrompt(ctx) {
3017
+ function buildSelfDrivingPrompt(ctx, detectedSources = []) {
2934
3018
  const uiHost = ctx.host.appHost.replace(/\/$/, "");
2935
3019
  const projectBase = `${uiHost}/project/${ctx.projectId}`;
2936
3020
  const integrationsSettingsUrl = `${projectBase}/settings/environment-integrations`;
@@ -2955,6 +3039,8 @@ snippet, so repo evidence may rule a product IN but never OUT):
2955
3039
  - Exception autocapture (error tracking): ${optIn(optIns?.exceptionAutocapture)}
2956
3040
  - Surveys: ${optIn(optIns?.surveys)}
2957
3041
 
3042
+ ${renderDetectedTools(detectedSources)}
3043
+
2958
3044
  The installed skill is the source of truth for the HOW of every step:
2959
3045
  which MCP tools to call, which sources and scouts apply to this product,
2960
3046
  and how to verify each change. The STEPS below give the order and the
@@ -3040,7 +3126,10 @@ STEP 4 — Enable signal sources. (skill: "Enable sources")
3040
3126
 
3041
3127
  STEP 5 — Offer issue-tracker integrations. (skill: "Connected tools")
3042
3128
  One batched multi-select wizard_ask for the external tools the skill
3043
- lists. The run auto-connects the ones it can (GitHub Issues, and
3129
+ lists. Order it per the skill: the tools from the "Tools detected in
3130
+ this codebase" list above come first, then the SaaS basics, then an
3131
+ "others" option for the long tail — never dump the whole catalog.
3132
+ The run auto-connects the ones it can (GitHub Issues, and
3044
3133
  Linear via a one-click OAuth link), verifying each with a single
3045
3134
  silent check — never nudge. For GitHub Issues: when the GitHub
3046
3135
  integration has exactly one repository connected, use that repo by
@@ -3053,9 +3142,11 @@ STEP 5 — Offer issue-tracker integrations. (skill: "Connected tools")
3053
3142
 
3054
3143
  STEP 6 — Configure the scout troop. (skill: "Scouts")
3055
3144
  Materialize the troop, read the project's enforced scout-run budget
3056
- (24 runs a day by default), then enable only a small set — the
3057
- "general" scout plus the two or three specialists for the products
3058
- this project uses most — and disable the rest, per the skill.
3145
+ (100 runs a day by default), then enable a selective set — the
3146
+ "general" scout plus the three to five specialists for the products
3147
+ this project uses most — and disable the rest, per the skill. The
3148
+ whole troop, including step 6b's custom scouts, stays at or under
3149
+ ten enabled scouts.
3059
3150
 
3060
3151
  STEP 6b — Design custom scouts for this product. (skill: "Custom scouts")
3061
3152
  You are the only actor that has read this repo — turn that into
@@ -3091,7 +3182,7 @@ const SELF_DRIVING_TIPS = [
3091
3182
  {
3092
3183
  id: "scout",
3093
3184
  title: "Scout",
3094
- description: "An agent on a schedule, watching your sources for anomalies and patterns. Your project gets up to 24 scout runs a day by default."
3185
+ description: "An agent on a schedule, watching your sources for anomalies and patterns. Your project gets up to 100 scout runs a day by default."
3095
3186
  },
3096
3187
  {
3097
3188
  id: "signal-report",
@@ -3451,10 +3542,10 @@ async function removeInstalledSkill(installDir) {
3451
3542
  force: true
3452
3543
  }).catch(() => void 0);
3453
3544
  }
3454
- const run = {
3545
+ const buildRun = (session) => Promise.resolve({
3455
3546
  skillId: SELF_DRIVING_SKILL_ID,
3456
3547
  integrationLabel: SELF_DRIVING_SKILL_ID,
3457
- customPrompt: buildSelfDrivingPrompt,
3548
+ customPrompt: (ctx) => buildSelfDrivingPrompt(ctx, getSelfDrivingDetectedTools(session)),
3458
3549
  successMessage: SUCCESS_MESSAGE,
3459
3550
  reportFile: REPORT_FILE,
3460
3551
  docsUrl: DOCS_URL,
@@ -3489,7 +3580,7 @@ const run = {
3489
3580
  reportFile: REPORT_FILE
3490
3581
  };
3491
3582
  }
3492
- };
3583
+ });
3493
3584
  const selfDrivingConfig = {
3494
3585
  ...createSkillProgram({
3495
3586
  skillId: SELF_DRIVING_SKILL_ID,
@@ -3506,7 +3597,7 @@ const selfDrivingConfig = {
3506
3597
  abortCases: SELF_DRIVING_ABORT_CASES
3507
3598
  }),
3508
3599
  steps: SELF_DRIVING_PROGRAM,
3509
- run,
3600
+ run: buildRun,
3510
3601
  getTips,
3511
3602
  getContentBlocks
3512
3603
  };
@@ -3798,7 +3889,7 @@ function runMcpAdd(argv) {
3798
3889
  const debug = argv.debug;
3799
3890
  const localMcp = argv.local;
3800
3891
  try {
3801
- const { startTUI } = await import("./start-tui-DNkm-n-4.js");
3892
+ const { startTUI } = await import("./start-tui-p1oiV4Y6.js");
3802
3893
  const { buildSession } = await import("./wizard-session-DsK16SGs.js");
3803
3894
  const tui = startTUI(VERSION, Program.McpAdd);
3804
3895
  tui.store.session = buildSession({
@@ -3811,7 +3902,7 @@ function runMcpAdd(argv) {
3811
3902
  } catch (error) {
3812
3903
  if (!isTUIUnavailable(error)) throw error;
3813
3904
  setUI(new LoggingUI());
3814
- const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-B3TcwTT5.js").then((n) => n.r);
3905
+ const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-D6PkSBh4.js").then((n) => n.r);
3815
3906
  await addMCPServerToClientsStep({
3816
3907
  local: localMcp,
3817
3908
  features,
@@ -3850,7 +3941,7 @@ function runMcpRemove(argv) {
3850
3941
  const debug = argv.debug;
3851
3942
  const localMcp = argv.local;
3852
3943
  try {
3853
- const { startTUI } = await import("./start-tui-DNkm-n-4.js");
3944
+ const { startTUI } = await import("./start-tui-p1oiV4Y6.js");
3854
3945
  const { buildSession } = await import("./wizard-session-DsK16SGs.js");
3855
3946
  const tui = startTUI(VERSION, Program.McpRemove);
3856
3947
  tui.store.session = buildSession({
@@ -3860,7 +3951,7 @@ function runMcpRemove(argv) {
3860
3951
  });
3861
3952
  } catch {
3862
3953
  setUI(new LoggingUI());
3863
- const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-B3TcwTT5.js").then((n) => n.r);
3954
+ const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-D6PkSBh4.js").then((n) => n.r);
3864
3955
  await removeMCPServerFromClientsStep({ local: localMcp });
3865
3956
  }
3866
3957
  })();
@@ -3882,7 +3973,7 @@ function runMcpTutorial(argv) {
3882
3973
  const debug = argv.debug;
3883
3974
  const localMcp = argv.local;
3884
3975
  try {
3885
- const { startTUI } = await import("./start-tui-DNkm-n-4.js");
3976
+ const { startTUI } = await import("./start-tui-p1oiV4Y6.js");
3886
3977
  const { buildSession } = await import("./wizard-session-DsK16SGs.js");
3887
3978
  const tui = startTUI(VERSION, Program.McpTutorial);
3888
3979
  tui.store.session = buildSession({
@@ -3927,7 +4018,8 @@ function resolveNoTelemetry(options) {
3927
4018
  const WIZARD_VERSION = VERSION;
3928
4019
  /** The session a run step's agent runs in: scoped to the step's target dir
3929
4020
  * (e.g. a monorepo sub-app) with its own framework context, after any prep.
3930
- * A step without `targetDir` runs in the live session, unchanged. */
4021
+ * A step without `targetDir` runs in the live session, unchanged.
4022
+ * The frameworkContext copy is shallow and unfiltered — name keys per owning program. */
3931
4023
  async function prepareRunSession(step, live) {
3932
4024
  const session = step.targetDir ? {
3933
4025
  ...live,
@@ -3963,9 +4055,9 @@ function runWizard(config, options) {
3963
4055
  (async () => {
3964
4056
  try {
3965
4057
  const installDir = options.installDir || process.cwd();
3966
- const { startTUI } = await import("./start-tui-DNkm-n-4.js");
4058
+ const { startTUI } = await import("./start-tui-p1oiV4Y6.js");
3967
4059
  const { buildSession, RunPhase } = await import("./wizard-session-DsK16SGs.js");
3968
- const { TaskStreamPush } = await import("./task-stream-BdJV-usk.js");
4060
+ const { TaskStreamPush } = await import("./task-stream-XXeIjdu1.js");
3969
4061
  const { PostHogDestination } = await import("./posthog-DDLIrku0.js");
3970
4062
  tui = startTUI(WIZARD_VERSION, config.id);
3971
4063
  const activeTui = tui;
@@ -4032,7 +4124,7 @@ function runWizard(config, options) {
4032
4124
  if (shown(step)) await advanceStep(step, activeTui.store, config);
4033
4125
  }
4034
4126
  else if (skipAgent) {
4035
- const { getOrAskForProjectData } = await import("./setup-utils-6qyTDNyd.js").then((n) => n.r);
4127
+ const { getOrAskForProjectData } = await import("./setup-utils-Cr9u_GAd.js").then((n) => n.r);
4036
4128
  const { projectApiKey, host, accessToken, projectId } = await getOrAskForProjectData({
4037
4129
  signup: session.signup,
4038
4130
  ci: session.ci,
@@ -4134,10 +4226,10 @@ function runNonInteractive(config, options, mode) {
4134
4226
  (async () => {
4135
4227
  const path = await import("path");
4136
4228
  const { buildSession, RunPhase, OutroKind } = await import("./wizard-session-DsK16SGs.js");
4137
- const { readEnvironment } = await import("./environment-BWuaOExh.js").then((n) => n.t);
4229
+ const { readEnvironment } = await import("./environment-_Htke7Dm.js").then((n) => n.t);
4138
4230
  const { readApiKeyFromEnv } = await import("./env-api-key-cjD4yfGT.js").then((n) => n.t);
4139
- const { configureLogFileFromEnvironment, logToFile } = await import("./debug-CX6ZqL9r.js");
4140
- const { wizardAbort, WizardError } = await import("./wizard-abort-BRsd7-aB.js");
4231
+ const { configureLogFileFromEnvironment, logToFile } = await import("./debug-BRe2lTl9.js");
4232
+ const { wizardAbort, WizardError } = await import("./wizard-abort-DFC6tm8V.js");
4141
4233
  configureLogFileFromEnvironment();
4142
4234
  const env = readEnvironment();
4143
4235
  const apiKey = options.apiKey ?? readApiKeyFromEnv() ?? void 0;
@@ -4170,9 +4262,9 @@ function runNonInteractive(config, options, mode) {
4170
4262
  let store = null;
4171
4263
  let taskStream = null;
4172
4264
  if (mode === "headless") {
4173
- const { WizardStore } = await import("./store-sIaF89XA.js").then((n) => n.n);
4174
- const { HeadlessUI } = await import("./headless-ui-rH97E35y.js");
4175
- const { TaskStreamPush, PostHogDestination } = await import("./task-stream-BdJV-usk.js");
4265
+ const { WizardStore } = await import("./store-DCoiR5X4.js").then((n) => n.n);
4266
+ const { HeadlessUI } = await import("./headless-ui-CUJT6bP6.js");
4267
+ const { TaskStreamPush, PostHogDestination } = await import("./task-stream-XXeIjdu1.js");
4176
4268
  store = new WizardStore(config.id);
4177
4269
  store.session = session;
4178
4270
  setUI(new HeadlessUI(store));
@@ -4228,7 +4320,7 @@ function runNonInteractive(config, options, mode) {
4228
4320
  });
4229
4321
  }
4230
4322
  }
4231
- const { runAgent } = await import("./agent-runner-D6zGTJqn.js").then((n) => n.t);
4323
+ const { runAgent } = await import("./agent-runner-CpRxcnos.js").then((n) => n.t);
4232
4324
  await runAgent(config, session);
4233
4325
  await settleStream(RunPhase.Completed);
4234
4326
  } catch (error) {
@@ -5308,7 +5400,7 @@ async function runDoctorCI(options) {
5308
5400
  getUI().intro("Welcome to the PostHog setup wizard");
5309
5401
  getUI().log.info("Running posthog-doctor in CI mode");
5310
5402
  try {
5311
- const { getOrAskForProjectData } = await import("./setup-utils-6qyTDNyd.js").then((n) => n.r);
5403
+ const { getOrAskForProjectData } = await import("./setup-utils-Cr9u_GAd.js").then((n) => n.r);
5312
5404
  const { host, accessToken, projectId } = await getOrAskForProjectData({
5313
5405
  signup: false,
5314
5406
  ci: true,
@@ -5326,7 +5418,7 @@ async function runDoctorCI(options) {
5326
5418
  for (const issue of sorted) getUI().log.info(` • [${issue.severity}] ${getKindMeta(issue.kind).title}`);
5327
5419
  process.exit(1);
5328
5420
  } catch (error) {
5329
- const { ApiError } = await import("./api-BSq9hLu5.js").then((n) => n.n);
5421
+ const { ApiError } = await import("./api-DMNftHUP.js").then((n) => n.n);
5330
5422
  const message = error instanceof ApiError && error.statusCode === 401 ? "Your PostHog API key is invalid or expired." : error instanceof Error ? error.message : String(error);
5331
5423
  getUI().log.error(`Doctor failed: ${message}`);
5332
5424
  process.exit(1);
@@ -5408,7 +5500,7 @@ function runSlackConnect(argv) {
5408
5500
  (async () => {
5409
5501
  const debug = argv.debug;
5410
5502
  try {
5411
- const { startTUI } = await import("./start-tui-DNkm-n-4.js");
5503
+ const { startTUI } = await import("./start-tui-p1oiV4Y6.js");
5412
5504
  const { buildSession } = await import("./wizard-session-DsK16SGs.js");
5413
5505
  const tui = startTUI(VERSION, Program.SlackConnect);
5414
5506
  tui.store.session = buildSession({
@@ -5677,7 +5769,19 @@ const cliCommand = {
5677
5769
  //#region bin.ts
5678
5770
  const NODE_VERSION_RANGE = ">=22.22.0";
5679
5771
  if (!satisfies(process.version, NODE_VERSION_RANGE)) {
5680
- console.log(`PostHog wizard requires Node.js ${NODE_VERSION_RANGE}. You are using Node.js ${process.version}. Please upgrade your Node.js version.`);
5772
+ console.log([
5773
+ `The PostHog wizard needs a newer version of Node.js to run.`,
5774
+ ``,
5775
+ ` You have: ${process.version}`,
5776
+ ` You need: v${NODE_VERSION_RANGE.replace(">=", "")} or later`,
5777
+ ``,
5778
+ `To update Node.js:`,
5779
+ ``,
5780
+ ` Download the latest version from https://nodejs.org/en/download`,
5781
+ ` Or, if you use nvm, run: nvm install 22 && nvm use 22`,
5782
+ ``,
5783
+ `Then run the wizard again. Stuck? Email wizard@posthog.com and we'll help.`
5784
+ ].join("\n"));
5681
5785
  process.exit(1);
5682
5786
  }
5683
5787
  recoverOrphanedSettingsBackups(resolveInstallDir());