@posthog/wizard 2.69.0 → 2.70.1

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 (100) hide show
  1. package/dist/{add-mcp-server-to-clients-Cl2HBuxp.js → add-mcp-server-to-clients-BCnjUqnW.js} +4 -4
  2. package/dist/{add-mcp-server-to-clients-Cl2HBuxp.js.map → add-mcp-server-to-clients-BCnjUqnW.js.map} +1 -1
  3. package/dist/{agent-interface-CI89BrWE.js → agent-interface-Lu7tnLr0.js} +8 -8
  4. package/dist/{agent-interface-CI89BrWE.js.map → agent-interface-Lu7tnLr0.js.map} +1 -1
  5. package/dist/{agent-prompt-loader-Dc1g5Oub.js → agent-prompt-loader-y5GxgEkc.js} +5 -5
  6. package/dist/{agent-prompt-loader-Dc1g5Oub.js.map → agent-prompt-loader-y5GxgEkc.js.map} +1 -1
  7. package/dist/{agent-runner-D5dhuE4z.js → agent-runner-vKtpgqVI.js} +21 -16
  8. package/dist/agent-runner-vKtpgqVI.js.map +1 -0
  9. package/dist/analytics-D-bMEYjD.js +2 -0
  10. package/dist/{analytics-D90QbLf5.js → analytics-DTyJClPr.js} +13 -3
  11. package/dist/analytics-DTyJClPr.js.map +1 -0
  12. package/dist/{api-BHhrT6wb.js → api-j-OfJ8Dz.js} +3 -3
  13. package/dist/{api-BHhrT6wb.js.map → api-j-OfJ8Dz.js.map} +1 -1
  14. package/dist/bin.js +61 -56
  15. package/dist/bin.js.map +1 -1
  16. package/dist/{bounded-fs-BhlVkP1r.js → bounded-fs-BWX25ixc.js} +3 -3
  17. package/dist/{bounded-fs-BhlVkP1r.js.map → bounded-fs-BWX25ixc.js.map} +1 -1
  18. package/dist/{ci-install-94wC3a4K.js → ci-install-zNWgp1TL.js} +4 -4
  19. package/dist/{ci-install-94wC3a4K.js.map → ci-install-zNWgp1TL.js.map} +1 -1
  20. package/dist/{debug-CifTS9lQ.js → debug-BM0fZaGl.js} +3 -3
  21. package/dist/{debug-CifTS9lQ.js.map → debug-BM0fZaGl.js.map} +1 -1
  22. package/dist/{debug-DtixqVEY.js → debug-xr2Pq5VA.js} +1 -1
  23. package/dist/{env-api-key-CwhtZrik.js → env-api-key-DlxCZWU0.js} +2 -2
  24. package/dist/{env-api-key-CwhtZrik.js.map → env-api-key-DlxCZWU0.js.map} +1 -1
  25. package/dist/{environment-DhacWZf7.js → environment-o-bTOuzK.js} +4 -4
  26. package/dist/{environment-DhacWZf7.js.map → environment-o-bTOuzK.js.map} +1 -1
  27. package/dist/{file-watcher-L28OpUV2.js → file-watcher-D7G4f5sP.js} +2 -2
  28. package/dist/{file-watcher-L28OpUV2.js.map → file-watcher-D7G4f5sP.js.map} +1 -1
  29. package/dist/{headless-ui-DNcOVJxU.js → headless-ui-C46DctKG.js} +2 -2
  30. package/dist/{headless-ui-DNcOVJxU.js.map → headless-ui-C46DctKG.js.map} +1 -1
  31. package/dist/{interactive-DlNrV77o.js → interactive-B5zy3Gxk.js} +2 -2
  32. package/dist/{interactive-DlNrV77o.js.map → interactive-B5zy3Gxk.js.map} +1 -1
  33. package/dist/{mcp-CJEem9qs.js → mcp-lJRwE-YW.js} +2 -2
  34. package/dist/{mcp-CJEem9qs.js.map → mcp-lJRwE-YW.js.map} +1 -1
  35. package/dist/{mcp-prompt-streaming-DER7MG3q.js → mcp-prompt-streaming-Dsos09hT.js} +4 -4
  36. package/dist/{mcp-prompt-streaming-DER7MG3q.js.map → mcp-prompt-streaming-Dsos09hT.js.map} +1 -1
  37. package/dist/{non-interactive-CbvniKHm.js → non-interactive-qcCCtiYQ.js} +2 -2
  38. package/dist/{non-interactive-CbvniKHm.js.map → non-interactive-qcCCtiYQ.js.map} +1 -1
  39. package/dist/{orchestrator-tools-Czf3Wo_y.js → orchestrator-tools-ezFTbAIp.js} +3 -3
  40. package/dist/{orchestrator-tools-Czf3Wo_y.js.map → orchestrator-tools-ezFTbAIp.js.map} +1 -1
  41. package/dist/{package-json-GEU2VZlS.js → package-json-xt3eeyBI.js} +1 -1
  42. package/dist/{package-json-GEU2VZlS.js.map → package-json-xt3eeyBI.js.map} +1 -1
  43. package/dist/{package-manager-CNNlFA2q.js → package-manager-CGfN9UhH.js} +2 -2
  44. package/dist/{package-manager-CNNlFA2q.js.map → package-manager-CGfN9UhH.js.map} +1 -1
  45. package/dist/{pi-kpN-bO9z.js → pi-DzQLHIcQ.js} +11 -11
  46. package/dist/{pi-kpN-bO9z.js.map → pi-DzQLHIcQ.js.map} +1 -1
  47. package/dist/{playground-ZYaQmfBa.js → playground-DLN31BPV.js} +7 -7
  48. package/dist/{playground-ZYaQmfBa.js.map → playground-DLN31BPV.js.map} +1 -1
  49. package/dist/{posthog-D1zHPgYJ.js → posthog-Dxr8XK4x.js} +2 -2
  50. package/dist/{posthog-D1zHPgYJ.js.map → posthog-Dxr8XK4x.js.map} +1 -1
  51. package/dist/{posthog-integration-DdeIUkYw.js → posthog-integration-MDfRO911.js} +93 -29
  52. package/dist/posthog-integration-MDfRO911.js.map +1 -0
  53. package/dist/{provisioning-e3roaLgp.js → provisioning-Di5GNV9k.js} +3 -3
  54. package/dist/{provisioning-e3roaLgp.js.map → provisioning-Di5GNV9k.js.map} +1 -1
  55. package/dist/{queue-tools-zrqCiy6q.js → queue-tools-KosDptd6.js} +3 -3
  56. package/dist/{queue-tools-zrqCiy6q.js.map → queue-tools-KosDptd6.js.map} +1 -1
  57. package/dist/{registry-C1t8v5tE.js → registry-BBdaIFWq.js} +6 -6
  58. package/dist/{registry-C1t8v5tE.js.map → registry-BBdaIFWq.js.map} +1 -1
  59. package/dist/{security-CIfhIscL.js → security-BwOvjMaq.js} +5 -5
  60. package/dist/{security-CIfhIscL.js.map → security-BwOvjMaq.js.map} +1 -1
  61. package/dist/{setup-utils-B_06xag2.js → setup-utils-Bo3WZt3a.js} +9 -9
  62. package/dist/{setup-utils-B_06xag2.js.map → setup-utils-Bo3WZt3a.js.map} +1 -1
  63. package/dist/{start-tui-BafJXVNT.js → start-tui-B1LrB7k1.js} +288 -133
  64. package/dist/start-tui-B1LrB7k1.js.map +1 -0
  65. package/dist/{steps-DR-Yo_IT.js → steps-BMrQJpQh.js} +7 -7
  66. package/dist/{steps-DR-Yo_IT.js.map → steps-BMrQJpQh.js.map} +1 -1
  67. package/dist/{store-DSUCWMRO.js → store-DhNTBWQR.js} +40 -6
  68. package/dist/store-DhNTBWQR.js.map +1 -0
  69. package/dist/{subagent-DjZM3G7y.js → subagent-q6M-mBHo.js} +2 -2
  70. package/dist/{subagent-DjZM3G7y.js.map → subagent-q6M-mBHo.js.map} +1 -1
  71. package/dist/{task-Czzz3tzt.js → task-CgAOxod7.js} +12 -12
  72. package/dist/{task-Czzz3tzt.js.map → task-CgAOxod7.js.map} +1 -1
  73. package/dist/{task-stream-uxG6wJfj.js → task-stream-rxR1IsdJ.js} +5 -5
  74. package/dist/{task-stream-uxG6wJfj.js.map → task-stream-rxR1IsdJ.js.map} +1 -1
  75. package/dist/{tasks-CVmG8qFw.js → tasks-lzvWF__k.js} +2 -2
  76. package/dist/{tasks-CVmG8qFw.js.map → tasks-lzvWF__k.js.map} +1 -1
  77. package/dist/{telemetry-B1VEXHpL.js → telemetry-CickTk_7.js} +3 -3
  78. package/dist/{telemetry-B1VEXHpL.js.map → telemetry-CickTk_7.js.map} +1 -1
  79. package/dist/{terminal-Czuo0x8i.js → terminal-BjUFxn_x.js} +12 -12
  80. package/dist/{terminal-Czuo0x8i.js.map → terminal-BjUFxn_x.js.map} +1 -1
  81. package/dist/{tools-DOZg9n3A.js → tools-MKXGXFSk.js} +6 -6
  82. package/dist/{tools-DOZg9n3A.js.map → tools-MKXGXFSk.js.map} +1 -1
  83. package/dist/{wizard-abort-BZOeapsf.js → wizard-abort-CW_C2EXr.js} +1 -1
  84. package/dist/{wizard-abort-CFMdj6sZ.js → wizard-abort-CooWEh9N.js} +4 -4
  85. package/dist/{wizard-abort-CFMdj6sZ.js.map → wizard-abort-CooWEh9N.js.map} +1 -1
  86. package/dist/{wizard-session-C_7r3-rO.js → wizard-session-Bki7dQhv.js} +12 -2
  87. package/dist/wizard-session-Bki7dQhv.js.map +1 -0
  88. package/dist/{wizard-session-D1KQqUml.js → wizard-session-gbYCXdBf.js} +1 -1
  89. package/dist/{yara-hooks-CmQT-oBy.js → yara-hooks-BpngckdZ.js} +4 -4
  90. package/dist/{yara-hooks-CmQT-oBy.js.map → yara-hooks-BpngckdZ.js.map} +1 -1
  91. package/dist/yara-hooks-C-qG6EJt.js +2 -0
  92. package/package.json +1 -1
  93. package/dist/agent-runner-D5dhuE4z.js.map +0 -1
  94. package/dist/analytics-D90QbLf5.js.map +0 -1
  95. package/dist/analytics-Dmf_Jm3K.js +0 -2
  96. package/dist/posthog-integration-DdeIUkYw.js.map +0 -1
  97. package/dist/start-tui-BafJXVNT.js.map +0 -1
  98. package/dist/store-DSUCWMRO.js.map +0 -1
  99. package/dist/wizard-session-C_7r3-rO.js.map +0 -1
  100. package/dist/yara-hooks-BhNAWw7W.js +0 -2
@@ -0,0 +1,2 @@
1
+ import { n as analytics } from "./analytics-DTyJClPr.js";
2
+ export { analytics };
@@ -1,4 +1,5 @@
1
- import { C as ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY, S as ANALYTICS_HOST_URL, bt as TASK_RUN_ID, gt as VERSION, it as WIZARD_FLAG_KEYS, r as debug, s as logToFile, vt as RUN_SURFACE, w as ANALYTICS_TEAM_TAG, yt as TASK_ID } from "./debug-CifTS9lQ.js";
1
+ import { C as ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY, S as ANALYTICS_HOST_URL, bt as TASK_RUN_ID, gt as VERSION, it as WIZARD_FLAG_KEYS, r as debug, s as logToFile, vt as RUN_SURFACE, w as ANALYTICS_TEAM_TAG, yt as TASK_ID } from "./debug-BM0fZaGl.js";
2
+ import { s as reportableDiscoveredFeatures } from "./wizard-session-Bki7dQhv.js";
2
3
  import { PostHog } from "posthog-node";
3
4
  import { v4 } from "uuid";
4
5
  //#region src/utils/ci-flag-overrides.ts
@@ -37,12 +38,14 @@ function invocationProperties() {
37
38
  * Used by store-level analytics and available for ad-hoc captures.
38
39
  */
39
40
  function sessionProperties(session) {
41
+ const discoveredFeatures = reportableDiscoveredFeatures(session);
40
42
  return {
41
43
  integration: session.integration,
42
44
  detected_framework: session.detectedFrameworkLabel,
43
45
  typescript: session.typescript,
44
46
  project_id: session.credentials?.projectId,
45
- discovered_features: session.discoveredFeatures,
47
+ ...discoveredFeatures !== void 0 ? { discovered_features: discoveredFeatures } : {},
48
+ scan_consent: session.scanConsent,
46
49
  additional_features: session.additionalFeatureQueue,
47
50
  run_phase: session.runPhase
48
51
  };
@@ -192,6 +195,13 @@ var Analytics = class {
192
195
  }
193
196
  });
194
197
  }
198
+ groupIdentify(groupType, groupKey, properties) {
199
+ this.client.groupIdentify({
200
+ groupType,
201
+ groupKey,
202
+ properties
203
+ });
204
+ }
195
205
  wizardFlagFeatureProperties() {
196
206
  if (this.activeFlags === null) return {};
197
207
  const props = {};
@@ -281,4 +291,4 @@ const analytics = new Analytics();
281
291
  //#endregion
282
292
  export { ciExcludedTaskTypes as a, sessionProperties as i, analytics as n, groupsFromUser as r, Analytics as t };
283
293
 
284
- //# sourceMappingURL=analytics-D90QbLf5.js.map
294
+ //# sourceMappingURL=analytics-DTyJClPr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics-DTyJClPr.js","names":["uuidv4"],"sources":["../src/utils/ci-flag-overrides.ts","../src/utils/analytics.ts"],"sourcesContent":["/**\n * CI-only feature-flag overrides.\n *\n * CI must route deterministically: a run that tests the orchestrator arm says\n * so explicitly instead of depending on a live feature flag someone can edit\n * mid-week. The override env var (see the allowlist in `env.ts`) is a JSON\n * object of flag key → value, merged over whatever PostHog returned.\n *\n * The override path exists only in CI builds (`pnpm build:ci`). Published\n * builds inline NODE_ENV as the literal \"production\", the guards collapse,\n * and tsdown strips the rest from the bundle — and the smoke test asserts the\n * env var names are physically absent from production output (which is also\n * why no comment in this file may spell them out), so this can never quietly\n * become a production surface.\n */\nimport { runtimeEnv } from '@env';\nimport { logToFile } from './debug';\n\nexport function applyCiFlagOverrides(\n flags: Record<string, string>,\n payloads: Record<string, unknown> = {},\n): { flags: Record<string, string>; payloads: Record<string, unknown> } {\n // Compared inline (not via env.ts's IS_PRODUCTION_BUILD) so tsdown replaces\n // it with a literal right here and the bundler can prove the rest of this\n // function unreachable in production builds. The smoke test enforces that.\n if (process.env.NODE_ENV === 'production') return { flags, payloads };\n\n const raw = runtimeEnv('WIZARD_CI_FLAG_OVERRIDES');\n if (!raw) return { flags, payloads };\n\n let overrides: Record<string, unknown>;\n try {\n overrides = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n // A malformed override is a CI misconfiguration. Fail the run loudly\n // rather than silently testing whatever the live flags happen to say.\n throw new Error(\n 'The CI flag-override env var is not valid JSON (expected {\"flag-key\": value, ...}).',\n );\n }\n\n const mergedFlags = { ...flags };\n const mergedPayloads = { ...payloads };\n for (const [key, value] of Object.entries(overrides)) {\n // An object/array override is a flag payload: the flag reads 'true' and\n // the value rides the payload channel, matching a payload-carrying flag.\n if (typeof value === 'object' && value !== null) {\n mergedFlags[key] = 'true';\n mergedPayloads[key] = value;\n } else {\n mergedFlags[key] = String(value);\n }\n }\n logToFile('[flags] CI overrides applied', overrides);\n return { flags: mergedFlags, payloads: mergedPayloads };\n}\n\n/**\n * Task types excluded from this run. The exclusion env var (see the allowlist\n * in `env.ts`) is a comma-separated list (e.g. `dashboard`), set by the CI\n * harness that owns the policy — the wizard and the served content stay\n * run-mode agnostic. CI-build only, same as the flag overrides: published\n * builds strip this path.\n */\nexport function ciExcludedTaskTypes(): readonly string[] {\n if (process.env.NODE_ENV === 'production') return [];\n\n const raw = runtimeEnv('WIZARD_CI_EXCLUDE_TASKS');\n if (!raw) return [];\n const types = raw\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean);\n if (types.length > 0) logToFile('[flags] CI task exclusions', types);\n return types;\n}\n","import { PostHog } from 'posthog-node';\nimport {\n ANALYTICS_HOST_URL,\n ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY,\n ANALYTICS_TEAM_TAG,\n WIZARD_FLAG_KEYS,\n} from '@lib/constants';\nimport {\n reportableDiscoveredFeatures,\n type WizardSession,\n} from '@lib/wizard-session';\nimport type { ApiUser } from '@lib/api';\nimport { v4 as uuidv4 } from 'uuid';\nimport { IS_PRODUCTION_BUILD, RUN_SURFACE, TASK_ID, TASK_RUN_ID } from '@env';\nimport { VERSION } from '@lib/version';\nimport { debug, logToFile } from './debug';\nimport { applyCiFlagOverrides } from './ci-flag-overrides';\n\n/**\n * The invocation, reduced to flag-safe strings: the command word (first\n * positional, 'default' for the bare flow) and the sorted option NAMES.\n * Option values never leave the machine — they carry paths, emails, keys.\n */\nfunction invocationProperties(): { command: string; cli_flags: string } {\n const args = process.argv.slice(2);\n const command = args.find((a) => !a.startsWith('-')) ?? 'default';\n const flags = [\n ...new Set(\n args\n .filter((a) => a.startsWith('--'))\n .map((a) => a.slice(2).split('=')[0]),\n ),\n ].sort();\n return { command, cli_flags: flags.join(',') };\n}\n\n/**\n * Extract a standard property bag from the current session.\n * Used by store-level analytics and available for ad-hoc captures.\n */\nexport function sessionProperties(\n session: WizardSession,\n): Record<string, unknown> {\n // reportableDiscoveredFeatures() owns the consent decision; this file\n // never needs to know what `scanConsent` means, only that the result\n // might be absent. An absent key is unambiguous, while an empty array\n // would read as \"we looked and found nothing\" instead of \"not reported\".\n const discoveredFeatures = reportableDiscoveredFeatures(session);\n\n return {\n integration: session.integration,\n detected_framework: session.detectedFrameworkLabel,\n typescript: session.typescript,\n project_id: session.credentials?.projectId,\n ...(discoveredFeatures !== undefined\n ? { discovered_features: discoveredFeatures }\n : {}),\n scan_consent: session.scanConsent,\n additional_features: session.additionalFeatureQueue,\n run_phase: session.runPhase,\n };\n}\n\nexport function groupsFromUser(\n user: ApiUser | null,\n host: string,\n): Record<string, string> {\n const groups: Record<string, string> = { instance: host };\n if (!user) return groups;\n\n const organizationId = user.organization?.id;\n if (organizationId) groups.organization = organizationId;\n\n const customerId = user.organization?.customer_id;\n if (customerId) groups.customer = customerId;\n\n const projectUuid = user.team?.uuid;\n if (projectUuid) groups.project = projectUuid;\n\n return groups;\n}\n\nconst WIZARD_FLAGS: ReadonlySet<string> = new Set(WIZARD_FLAG_KEYS);\n\n// Widen back to the SDK's shape — a filter on `true` never matches `'true'`.\nfunction flagResponseValue(value: string): string | boolean {\n if (value === 'true') return true;\n if (value === 'false') return false;\n return value;\n}\n\nexport class Analytics {\n private client: PostHog;\n private tags: Record<string, string | boolean | number | null | undefined> =\n {};\n private distinctId?: string;\n private anonymousId: string;\n private _runId: string;\n private sessionId: string | null = null;\n private appName = 'wizard';\n private activeFlags: Record<string, string> | null = null;\n private activeFlagPayloads: Record<string, unknown> = {};\n private groups: Record<string, string> = {};\n private personProperties: Record<string, string> = {};\n private terminalEventSent = false;\n\n constructor() {\n this.client = new PostHog(ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY, {\n host: ANALYTICS_HOST_URL,\n flushAt: 1,\n flushInterval: 0,\n enableExceptionAutocapture: true,\n before_send: (event) => {\n if (!event) return event;\n if (Object.keys(this.groups).length > 0) {\n event.groups = { ...this.groups, ...event.groups };\n }\n // Autocaptured exceptions arrive with a random uuid and\n // `$process_person_profile: false` — reattach the run's identity\n // and tags so they land on the same person as everything else.\n if (event.event === '$exception') {\n event.distinctId = this.distinctId ?? this.anonymousId;\n const { $process_person_profile, ...properties } =\n event.properties ?? {};\n void $process_person_profile;\n event.properties = { ...this.tags, ...properties };\n }\n // The SDK captures this one itself, bypassing capture(), so tags merge here.\n if (event.event === '$feature_flag_called') {\n event.properties = { ...this.tags, ...(event.properties ?? {}) };\n }\n return event;\n },\n });\n\n this.tags = { $app_name: this.appName };\n // Tag every run with its build type so prod / dev / ci / headless segment\n // cleanly in analytics. tsdown inlines IS_PRODUCTION_BUILD to `true` in\n // published builds and `false` for dev/tsx/test runs. Non-interactive runs\n // upgrade this in runWizardCI: dev `--ci` runs to 'ci', published headless\n // runs to 'headless'.\n this.tags.build = IS_PRODUCTION_BUILD ? 'prod' : 'dev';\n\n this.tags.run_surface = RUN_SURFACE;\n\n // The build this run came from. Already sent as a flag-evaluation person\n // property; tagging it makes every event attributable to a release, so a\n // regression can be bounded to the versions that carry it.\n this.tags.version = VERSION;\n\n // Cloud runs only: the task run that owns the sandbox. Without these the\n // wizard's events and the run that launched it are two unrelated streams,\n // since run_id above is minted per process and never leaves the wizard.\n // Left unset for local runs so the properties stay absent rather than null.\n if (TASK_RUN_ID) this.tags.task_run_id = TASK_RUN_ID;\n if (TASK_ID) this.tags.task_id = TASK_ID;\n\n this.anonymousId = uuidv4();\n\n // One id per process = one id per wizard run, registered in the tag bag\n // so it rides on every capture, exception, and autocaptured exception\n // (all of which merge `this.tags`). Lets you separate two runs by the\n // same logged-in user, who otherwise share one distinct id. Distinct\n // from `anonymousId`, the pre-login *person* id that gets aliased onto\n // the real user at login. `$session_id` is intentionally not set here —\n // it stays null until OAuth completes (see identifyUser).\n this._runId = uuidv4();\n this.tags.run_id = this._runId;\n\n this.distinctId = undefined;\n }\n\n /** Per-process run id, tagged on every event and gateway trace. */\n get runId(): string {\n return this._runId;\n }\n\n /** Build type for this run ('prod' | 'dev' | 'ci' | 'headless') — the same value tagged on every analytics event. */\n get build(): string {\n return String(this.tags.build ?? 'dev');\n }\n\n /**\n * Associate the run with the logged-in user, once per id. Identifies them\n * (email, name) and records those person properties so events carry them and\n * feature flags can target the individual user — without the email here the\n * wizard only sends `$app_name`, so email-targeted flags never match. Opens\n * the analytics session on first login, then aliases the run's anonymous id\n * onto the identified person so pre-login events merge in.\n */\n identifyUser(user: ApiUser) {\n const distinctId = user.distinct_id;\n if (this.distinctId === distinctId || distinctId === this.anonymousId) {\n return;\n }\n this.distinctId = distinctId;\n // Open the analytics session on first login. Null until here, so\n // pre-OAuth events carry only `run_id`; from now on every event also\n // carries `$session_id` and PostHog groups the authenticated run into a\n // native Session. Stored in the tag bag so it rides on every subsequent\n // capture and exception.\n if (!this.sessionId) {\n this.sessionId = uuidv4();\n this.tags.$session_id = this.sessionId;\n }\n const props: Record<string, string> = {};\n if (user.email) props.email = user.email;\n const name = [user.first_name, user.last_name]\n .filter(Boolean)\n .join(' ')\n .trim();\n if (name) props.name = name;\n this.personProperties = props;\n this.client.identify({ distinctId, properties: { $set: props } });\n this.client.alias({\n distinctId,\n alias: this.anonymousId,\n });\n // The flag snapshot is per identity. Anything evaluated before login (the\n // intro screen reads the tools-menu flag) was anonymous — drop it so the\n // next read re-evaluates as this user.\n this.activeFlags = null;\n this.activeFlagPayloads = {};\n }\n\n /** Person properties sent with flag evaluation: app name plus the user's. */\n private flagPersonProperties(): Record<string, string> {\n // Environment facts flag conditions can scope on — evaluation-time only,\n // never persisted onto the person. `version` gates an experiment to\n // releases that implement it (a condition on a property older builds\n // don't send silently never matches them); `run_surface`/`build` scope\n // by invocation surface; `command`/`cli_flags` by subcommand; `os`/\n // `node_major` by platform.\n return {\n $app_name: this.appName,\n version: VERSION,\n run_surface: RUN_SURFACE,\n build: String(this.tags.build ?? 'dev'),\n os: process.platform,\n node_major: process.versions.node.split('.')[0],\n ...invocationProperties(),\n ...this.personProperties,\n };\n }\n\n setTag(key: string, value: string | boolean | number | null | undefined) {\n this.tags[key] = value;\n }\n\n setGroups(groups: Record<string, string>) {\n this.groups = groups;\n }\n\n captureException(error: Error, properties: Record<string, unknown> = {}) {\n this.client.captureException(error, this.distinctId ?? this.anonymousId, {\n team: ANALYTICS_TEAM_TAG,\n ...this.tags,\n ...properties,\n });\n }\n\n capture(eventName: string, properties?: Record<string, unknown>) {\n this.client.capture({\n distinctId: this.distinctId ?? this.anonymousId,\n event: eventName,\n properties: {\n ...this.tags,\n ...this.wizardFlagFeatureProperties(),\n ...properties,\n },\n });\n }\n\n groupIdentify(\n groupType: string,\n groupKey: string,\n properties: Record<string, unknown>,\n ) {\n this.client.groupIdentify({ groupType, groupKey, properties });\n }\n\n // Built from the resolved map, not the SDK snapshot: a CI-forced variant must own its events.\n private wizardFlagFeatureProperties(): Record<string, unknown> {\n if (this.activeFlags === null) return {};\n const props: Record<string, unknown> = {};\n const active: string[] = [];\n for (const [key, value] of Object.entries(this.activeFlags)) {\n if (!WIZARD_FLAGS.has(key)) continue;\n const resolved = flagResponseValue(value);\n props[`$feature/${key}`] = resolved;\n if (resolved !== false) active.push(key);\n }\n if (active.length > 0) props.$active_feature_flags = active.sort();\n return props;\n }\n\n /**\n * Capture a wizard-specific event. Automatically prepends \"wizard: \" to the event name.\n * All new wizard analytics should use this method instead of capture() directly.\n */\n wizardCapture(eventName: string, properties?: Record<string, unknown>): void {\n this.capture(`wizard: ${eventName}`, properties);\n }\n\n /**\n * Flush pending events without firing the \"setup wizard finished\" terminal\n * event. Use this from CLI error paths that exit before any wizard run\n * starts — `shutdown()` would inflate the run count with a \"finished\" event\n * for a parse error that never actually ran the wizard.\n */\n async flush(): Promise<void> {\n await this.client.shutdown();\n }\n\n /**\n * Evaluate all feature flags for the current user at the start of a run.\n * Result is cached; subsequent calls in the same run return the same map.\n * Returns flag key -> string value (booleans become 'true'/'false').\n */\n // Only a getFlag read records an exposure; the bulk response records none.\n async getAllFlagsForWizard(): Promise<Record<string, string>> {\n if (this.activeFlags !== null) {\n return this.activeFlags;\n }\n const out: Record<string, string> = {};\n const payloads: Record<string, unknown> = {};\n try {\n const distinctId = this.distinctId ?? this.anonymousId;\n logToFile('[flags] evaluating as', {\n distinctId,\n identified: this.distinctId !== undefined,\n personProperties: this.flagPersonProperties(),\n });\n const evaluation = await this.client.evaluateFlags(distinctId, {\n personProperties: this.flagPersonProperties(),\n });\n for (const key of WIZARD_FLAG_KEYS) {\n const value = evaluation.getFlag(key);\n if (value === undefined) continue;\n out[key] = String(value);\n const payload = evaluation.getFlagPayload(key);\n if (payload !== undefined) payloads[key] = payload;\n }\n } catch (error) {\n debug('Failed to get all feature flags:', error);\n this.captureException(\n error instanceof Error ? error : new Error(String(error)),\n { step: 'get_all_flags' },\n );\n }\n // Outside the fetch guard on purpose: a malformed CI override must fail\n // the run loudly, and a valid one applies even when the fetch failed —\n // CI routing stays deterministic either way.\n const merged = applyCiFlagOverrides(out, payloads);\n this.activeFlags = merged.flags;\n this.activeFlagPayloads = merged.payloads;\n logToFile('[flags] evaluated', this.activeFlags);\n return this.activeFlags;\n }\n\n /** Flag payloads from the same snapshot; empty until the flags are fetched. */\n getWizardFlagPayloads(): Record<string, unknown> {\n return this.activeFlagPayloads;\n }\n\n async shutdown(status: 'success' | 'error' | 'cancelled') {\n if (Object.keys(this.tags).length === 0) {\n return;\n }\n\n // First status wins. The interrupt fallback in start-tui fires\n // shutdown('cancelled') on every TUI teardown; without this guard a run\n // that already reported 'success' would emit a second, contradicting\n // terminal event when the user dismisses the outro.\n if (this.terminalEventSent) {\n return;\n }\n this.terminalEventSent = true;\n\n this.client.capture({\n distinctId: this.distinctId ?? this.anonymousId,\n event: 'setup wizard finished',\n properties: {\n // Flat for filtering; the nested `tags` snapshot stays for back-compat.\n ...this.tags,\n run_id: this._runId,\n ...(this.sessionId ? { $session_id: this.sessionId } : {}),\n status,\n tags: this.tags,\n },\n });\n\n await this.client.shutdown();\n }\n}\n\nexport const analytics = new Analytics();\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-B_-DWIq7.js";
2
- import { pt as WIZARD_USER_AGENT } from "./debug-CifTS9lQ.js";
3
- import { n as analytics } from "./analytics-D90QbLf5.js";
2
+ import { pt as WIZARD_USER_AGENT } from "./debug-BM0fZaGl.js";
3
+ import { n as analytics } from "./analytics-DTyJClPr.js";
4
4
  import axios from "axios";
5
5
  import { z } from "zod";
6
6
  //#region src/lib/api.ts
@@ -170,4 +170,4 @@ function handleApiError(error, operation) {
170
170
  //#endregion
171
171
  export { fetchUserData as a, fetchSlackConnected as i, api_exports as n, handleApiError as o, fetchProjectData as r, ApiError as t };
172
172
 
173
- //# sourceMappingURL=api-BHhrT6wb.js.map
173
+ //# sourceMappingURL=api-j-OfJ8Dz.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"api-BHhrT6wb.js","names":[],"sources":["../src/lib/api.ts"],"sourcesContent":["import axios, { AxiosError } from 'axios';\nimport { z } from 'zod';\nimport { analytics } from '@utils/analytics';\nimport { WIZARD_USER_AGENT } from './constants';\n\n/**\n * User payload from `/api/users/@me/`. Schema typed for the fields the\n * wizard actually reads + passthrough on everything else so the full\n * upstream response rides through to the session for downstream features\n * (account-aware copy, plan-gated flows, org/team metadata, etc.).\n *\n * Top-level uses `.passthrough()` so unknown fields aren't stripped;\n * the few nested objects we care about (team, organization,\n * organizations[]) do the same so their additional fields survive too.\n *\n * Keep `distinct_id` required — analytics depends on it. Everything\n * else added here is nullish so partial responses don't fail parsing.\n */\nexport const ApiUserSchema = z\n .object({\n // Identifiers\n distinct_id: z.string(),\n uuid: z.string().nullish(),\n id: z.number().nullish(),\n\n // Profile\n email: z.string().nullish(),\n first_name: z.string().nullish(),\n last_name: z.string().nullish(),\n date_joined: z.string().nullish(),\n is_email_verified: z.boolean().nullish(),\n is_2fa_enabled: z.boolean().nullish(),\n is_staff: z.boolean().nullish(),\n\n // Preferences\n theme_mode: z.string().nullish(),\n toolbar_mode: z.string().nullish(),\n hide_mcp_hints: z.boolean().nullish(),\n\n // Optional / nullable on the backend — pre-onboarding signup paths\n // return null and older accounts may not have it set. Treat as a\n // hint, never a guarantee.\n role_at_organization: z.string().nullish(),\n\n // Current team + organization (objects from the API, kept typed on\n // the fields the wizard uses; passthrough preserves the rest).\n team: z\n .object({\n id: z.number(),\n uuid: z.string().nullish(),\n organization: z.string().uuid(),\n api_token: z.string().nullish(),\n project_id: z.number().nullish(),\n name: z.string().nullish(),\n timezone: z.string().nullish(),\n })\n .passthrough(),\n organization: z\n .object({\n id: z.string().uuid(),\n name: z.string().nullish(),\n slug: z.string().nullish(),\n membership_level: z.number().nullish(),\n customer_id: z.string().nullish(),\n // Org-level AI consent gate. Signals drops all findings while\n // this is not true. Null on older orgs (pre-2026-05 default\n // flip) — treat null as \"unknown\", not \"off\".\n is_ai_data_processing_approved: z.boolean().nullish(),\n })\n .passthrough(),\n organizations: z.array(\n z\n .object({\n id: z.string().uuid(),\n name: z.string().nullish(),\n membership_level: z.number().nullish(),\n })\n .passthrough(),\n ),\n })\n .passthrough();\n\n/**\n * Single activity log entry the wizard cares about. The PostHog endpoint\n * returns much more — schema kept minimal so changes upstream don't break us.\n *\n * @unused — no current caller after the Phase 6 streaming-agent pivot\n * dropped activity_log polling. Deliberately retained: this is a thin,\n * well-typed wrapper around a stable PostHog endpoint, and we're likely\n * to want it again for a future feature (e.g. \"what changed in your\n * project recently\"). Re-deriving the schema is more work than letting\n * it sit dormant.\n */\nexport const ActivityLogEntrySchema = z\n .object({\n scope: z.string().nullish(),\n activity: z.string().nullish(),\n created_at: z.string().nullish(),\n })\n .passthrough();\n\n/** @unused — see ActivityLogEntrySchema. */\nexport const ActivityLogResponseSchema = z.object({\n results: z.array(ActivityLogEntrySchema),\n});\n\n/** @unused — see ActivityLogEntrySchema. */\nexport type ActivityLogEntry = z.infer<typeof ActivityLogEntrySchema>;\n\nexport const ApiProjectSchema = z.object({\n id: z.number(),\n uuid: z.string().uuid(),\n organization: z.string().uuid(),\n api_token: z.string(),\n name: z.string(),\n // Product opt-ins (TeamSerializer-compat fields on /api/projects/:id).\n // Project-level truth for \"is this product enabled\" — a product can be\n // instrumented from another repo or the snippet, so these settings\n // override repo-local evidence. Null/absent = unknown. Only the\n // opt-ins a signals decision consumes: replay + exception autocapture\n // feed signal-source choices; surveys feeds the surveys-scout tuning.\n session_recording_opt_in: z.boolean().nullish(),\n autocapture_exceptions_opt_in: z.boolean().nullish(),\n surveys_opt_in: z.boolean().nullish(),\n});\n\nexport type ApiUser = z.infer<typeof ApiUserSchema>;\nexport type ApiProject = z.infer<typeof ApiProjectSchema>;\n\nexport class ApiError extends Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n public readonly endpoint?: string,\n ) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\nexport async function fetchUserData(\n accessToken: string,\n baseUrl: string,\n): Promise<ApiUser> {\n try {\n const response = await axios.get(`${baseUrl}/api/users/@me/`, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n });\n\n return ApiUserSchema.parse(response.data);\n } catch (error) {\n const apiError = handleApiError(error, 'fetch user data');\n analytics.captureException(apiError, {\n endpoint: '/api/users/@me/',\n baseUrl,\n });\n throw apiError;\n }\n}\n\n/**\n * Best-effort fetch of recent activity log entries. Returns [] on any error\n * so callers can treat absence of results as \"haven't detected anything yet\"\n * rather than a hard failure.\n *\n * @unused — no current caller after the Phase 6 streaming-agent pivot\n * dropped activity_log polling from McpSuggestedPromptsScreen.\n * Deliberately retained for future features that want a soft signal of\n * recent project changes (e.g. dashboards, audit summaries). See the\n * ActivityLogEntrySchema doc comment for the keep-vs-delete rationale.\n */\nexport async function fetchRecentActivity(\n accessToken: string,\n projectId: number,\n baseUrl: string,\n since: Date,\n): Promise<ActivityLogEntry[]> {\n try {\n const response = await axios.get(\n `${baseUrl}/api/projects/${projectId}/activity_log/`,\n {\n params: { limit: 10 },\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n // Short timeout — best-effort probe, not a critical path.\n timeout: 4000,\n },\n );\n const parsed = ActivityLogResponseSchema.safeParse(response.data);\n if (!parsed.success) return [];\n const sinceMs = since.getTime();\n return parsed.data.results.filter((entry) => {\n if (!entry.created_at) return false;\n const t = Date.parse(entry.created_at);\n return Number.isFinite(t) && t >= sinceMs;\n });\n } catch {\n return [];\n }\n}\n\nexport async function fetchProjectData(\n accessToken: string,\n projectId: number,\n baseUrl: string,\n): Promise<ApiProject> {\n try {\n const response = await axios.get(`${baseUrl}/api/projects/${projectId}/`, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n });\n\n return ApiProjectSchema.parse(response.data);\n } catch (error) {\n const apiError = handleApiError(error, 'fetch project data');\n analytics.captureException(apiError, {\n endpoint: `/api/projects/${projectId}/`,\n baseUrl,\n projectId,\n });\n throw apiError;\n }\n}\n\n/** Minimal shape of `/api/projects/:id/integrations/` — we only read `kind`. */\nconst IntegrationsResponseSchema = z.object({\n results: z.array(z.object({ kind: z.string().nullish() }).passthrough()),\n});\n\n/**\n * Check whether the project already has a Slack integration connected.\n * Requires the `integration:read` scope. Throws on failure — callers\n * (including the SlackConnectScreen poll) decide how to degrade and\n * are responsible for capturing the error exactly once.\n */\nexport async function fetchSlackConnected(\n accessToken: string,\n projectId: number,\n baseUrl: string,\n signal?: AbortSignal,\n): Promise<boolean> {\n const response = await axios.get(\n `${baseUrl}/api/projects/${projectId}/integrations/`,\n {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n signal,\n },\n );\n const parsed = IntegrationsResponseSchema.safeParse(response.data);\n if (!parsed.success) return false;\n return parsed.data.results.some((i) => i.kind === 'slack');\n}\n\nexport function handleApiError(error: unknown, operation: string): ApiError {\n if (axios.isAxiosError(error)) {\n const axiosError = error as AxiosError<{ detail?: string }>;\n const status = axiosError.response?.status;\n const detail = axiosError.response?.data?.detail;\n const endpoint = axiosError.config?.url;\n\n if (status === 401) {\n return new ApiError(\n `Authentication failed while trying to ${operation}`,\n status,\n endpoint,\n );\n }\n\n if (status === 403) {\n return new ApiError(\n `Access denied while trying to ${operation}`,\n status,\n endpoint,\n );\n }\n\n if (status === 404) {\n return new ApiError(\n `Resource not found while trying to ${operation}`,\n status,\n endpoint,\n );\n }\n\n const message = detail || `Failed to ${operation}`;\n return new ApiError(message, status, endpoint);\n }\n\n if (error instanceof z.ZodError) {\n return new ApiError(`Invalid response format while trying to ${operation}`);\n }\n\n return new ApiError(\n `Unexpected error while trying to ${operation}: ${\n error instanceof Error ? error.message : 'Unknown error'\n }`,\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"api-j-OfJ8Dz.js","names":[],"sources":["../src/lib/api.ts"],"sourcesContent":["import axios, { AxiosError } from 'axios';\nimport { z } from 'zod';\nimport { analytics } from '@utils/analytics';\nimport { WIZARD_USER_AGENT } from './constants';\n\n/**\n * User payload from `/api/users/@me/`. Schema typed for the fields the\n * wizard actually reads + passthrough on everything else so the full\n * upstream response rides through to the session for downstream features\n * (account-aware copy, plan-gated flows, org/team metadata, etc.).\n *\n * Top-level uses `.passthrough()` so unknown fields aren't stripped;\n * the few nested objects we care about (team, organization,\n * organizations[]) do the same so their additional fields survive too.\n *\n * Keep `distinct_id` required — analytics depends on it. Everything\n * else added here is nullish so partial responses don't fail parsing.\n */\nexport const ApiUserSchema = z\n .object({\n // Identifiers\n distinct_id: z.string(),\n uuid: z.string().nullish(),\n id: z.number().nullish(),\n\n // Profile\n email: z.string().nullish(),\n first_name: z.string().nullish(),\n last_name: z.string().nullish(),\n date_joined: z.string().nullish(),\n is_email_verified: z.boolean().nullish(),\n is_2fa_enabled: z.boolean().nullish(),\n is_staff: z.boolean().nullish(),\n\n // Preferences\n theme_mode: z.string().nullish(),\n toolbar_mode: z.string().nullish(),\n hide_mcp_hints: z.boolean().nullish(),\n\n // Optional / nullable on the backend — pre-onboarding signup paths\n // return null and older accounts may not have it set. Treat as a\n // hint, never a guarantee.\n role_at_organization: z.string().nullish(),\n\n // Current team + organization (objects from the API, kept typed on\n // the fields the wizard uses; passthrough preserves the rest).\n team: z\n .object({\n id: z.number(),\n uuid: z.string().nullish(),\n organization: z.string().uuid(),\n api_token: z.string().nullish(),\n project_id: z.number().nullish(),\n name: z.string().nullish(),\n timezone: z.string().nullish(),\n })\n .passthrough(),\n organization: z\n .object({\n id: z.string().uuid(),\n name: z.string().nullish(),\n slug: z.string().nullish(),\n membership_level: z.number().nullish(),\n customer_id: z.string().nullish(),\n // Org-level AI consent gate. Signals drops all findings while\n // this is not true. Null on older orgs (pre-2026-05 default\n // flip) — treat null as \"unknown\", not \"off\".\n is_ai_data_processing_approved: z.boolean().nullish(),\n })\n .passthrough(),\n organizations: z.array(\n z\n .object({\n id: z.string().uuid(),\n name: z.string().nullish(),\n membership_level: z.number().nullish(),\n })\n .passthrough(),\n ),\n })\n .passthrough();\n\n/**\n * Single activity log entry the wizard cares about. The PostHog endpoint\n * returns much more — schema kept minimal so changes upstream don't break us.\n *\n * @unused — no current caller after the Phase 6 streaming-agent pivot\n * dropped activity_log polling. Deliberately retained: this is a thin,\n * well-typed wrapper around a stable PostHog endpoint, and we're likely\n * to want it again for a future feature (e.g. \"what changed in your\n * project recently\"). Re-deriving the schema is more work than letting\n * it sit dormant.\n */\nexport const ActivityLogEntrySchema = z\n .object({\n scope: z.string().nullish(),\n activity: z.string().nullish(),\n created_at: z.string().nullish(),\n })\n .passthrough();\n\n/** @unused — see ActivityLogEntrySchema. */\nexport const ActivityLogResponseSchema = z.object({\n results: z.array(ActivityLogEntrySchema),\n});\n\n/** @unused — see ActivityLogEntrySchema. */\nexport type ActivityLogEntry = z.infer<typeof ActivityLogEntrySchema>;\n\nexport const ApiProjectSchema = z.object({\n id: z.number(),\n uuid: z.string().uuid(),\n organization: z.string().uuid(),\n api_token: z.string(),\n name: z.string(),\n // Product opt-ins (TeamSerializer-compat fields on /api/projects/:id).\n // Project-level truth for \"is this product enabled\" — a product can be\n // instrumented from another repo or the snippet, so these settings\n // override repo-local evidence. Null/absent = unknown. Only the\n // opt-ins a signals decision consumes: replay + exception autocapture\n // feed signal-source choices; surveys feeds the surveys-scout tuning.\n session_recording_opt_in: z.boolean().nullish(),\n autocapture_exceptions_opt_in: z.boolean().nullish(),\n surveys_opt_in: z.boolean().nullish(),\n});\n\nexport type ApiUser = z.infer<typeof ApiUserSchema>;\nexport type ApiProject = z.infer<typeof ApiProjectSchema>;\n\nexport class ApiError extends Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n public readonly endpoint?: string,\n ) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\nexport async function fetchUserData(\n accessToken: string,\n baseUrl: string,\n): Promise<ApiUser> {\n try {\n const response = await axios.get(`${baseUrl}/api/users/@me/`, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n });\n\n return ApiUserSchema.parse(response.data);\n } catch (error) {\n const apiError = handleApiError(error, 'fetch user data');\n analytics.captureException(apiError, {\n endpoint: '/api/users/@me/',\n baseUrl,\n });\n throw apiError;\n }\n}\n\n/**\n * Best-effort fetch of recent activity log entries. Returns [] on any error\n * so callers can treat absence of results as \"haven't detected anything yet\"\n * rather than a hard failure.\n *\n * @unused — no current caller after the Phase 6 streaming-agent pivot\n * dropped activity_log polling from McpSuggestedPromptsScreen.\n * Deliberately retained for future features that want a soft signal of\n * recent project changes (e.g. dashboards, audit summaries). See the\n * ActivityLogEntrySchema doc comment for the keep-vs-delete rationale.\n */\nexport async function fetchRecentActivity(\n accessToken: string,\n projectId: number,\n baseUrl: string,\n since: Date,\n): Promise<ActivityLogEntry[]> {\n try {\n const response = await axios.get(\n `${baseUrl}/api/projects/${projectId}/activity_log/`,\n {\n params: { limit: 10 },\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n // Short timeout — best-effort probe, not a critical path.\n timeout: 4000,\n },\n );\n const parsed = ActivityLogResponseSchema.safeParse(response.data);\n if (!parsed.success) return [];\n const sinceMs = since.getTime();\n return parsed.data.results.filter((entry) => {\n if (!entry.created_at) return false;\n const t = Date.parse(entry.created_at);\n return Number.isFinite(t) && t >= sinceMs;\n });\n } catch {\n return [];\n }\n}\n\nexport async function fetchProjectData(\n accessToken: string,\n projectId: number,\n baseUrl: string,\n): Promise<ApiProject> {\n try {\n const response = await axios.get(`${baseUrl}/api/projects/${projectId}/`, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n });\n\n return ApiProjectSchema.parse(response.data);\n } catch (error) {\n const apiError = handleApiError(error, 'fetch project data');\n analytics.captureException(apiError, {\n endpoint: `/api/projects/${projectId}/`,\n baseUrl,\n projectId,\n });\n throw apiError;\n }\n}\n\n/** Minimal shape of `/api/projects/:id/integrations/` — we only read `kind`. */\nconst IntegrationsResponseSchema = z.object({\n results: z.array(z.object({ kind: z.string().nullish() }).passthrough()),\n});\n\n/**\n * Check whether the project already has a Slack integration connected.\n * Requires the `integration:read` scope. Throws on failure — callers\n * (including the SlackConnectScreen poll) decide how to degrade and\n * are responsible for capturing the error exactly once.\n */\nexport async function fetchSlackConnected(\n accessToken: string,\n projectId: number,\n baseUrl: string,\n signal?: AbortSignal,\n): Promise<boolean> {\n const response = await axios.get(\n `${baseUrl}/api/projects/${projectId}/integrations/`,\n {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n signal,\n },\n );\n const parsed = IntegrationsResponseSchema.safeParse(response.data);\n if (!parsed.success) return false;\n return parsed.data.results.some((i) => i.kind === 'slack');\n}\n\nexport function handleApiError(error: unknown, operation: string): ApiError {\n if (axios.isAxiosError(error)) {\n const axiosError = error as AxiosError<{ detail?: string }>;\n const status = axiosError.response?.status;\n const detail = axiosError.response?.data?.detail;\n const endpoint = axiosError.config?.url;\n\n if (status === 401) {\n return new ApiError(\n `Authentication failed while trying to ${operation}`,\n status,\n endpoint,\n );\n }\n\n if (status === 403) {\n return new ApiError(\n `Access denied while trying to ${operation}`,\n status,\n endpoint,\n );\n }\n\n if (status === 404) {\n return new ApiError(\n `Resource not found while trying to ${operation}`,\n status,\n endpoint,\n );\n }\n\n const message = detail || `Failed to ${operation}`;\n return new ApiError(message, status, endpoint);\n }\n\n if (error instanceof z.ZodError) {\n return new ApiError(`Invalid response format while trying to ${operation}`);\n }\n\n return new ApiError(\n `Unexpected error while trying to ${operation}: ${\n error instanceof Error ? error.message : 'Unknown error'\n }`,\n );\n}\n"],"mappings":"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"}
package/dist/bin.js CHANGED
@@ -1,22 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as AgentSignals, c as emitWizardError, l as ErrorCodes, r as detectErrorCode } from "./errors-BSdz2lsl.js";
3
- import { Ct as isHeadless, L as Integration, St as headlessOption, U as POSTHOG_DOCS_URL, a as getLogFilePath, f as getUI, gt as VERSION, m as LoggingUI, mt as getSkillsBaseUrl, p as setUI, pt as WIZARD_USER_AGENT, r as debug, s as logToFile, wt as regionOption } from "./debug-CifTS9lQ.js";
3
+ import { Ct as isHeadless, L as Integration, St as headlessOption, U as POSTHOG_DOCS_URL, a as getLogFilePath, f as getUI, gt as VERSION, m as LoggingUI, mt as getSkillsBaseUrl, p as setUI, pt as WIZARD_USER_AGENT, r as debug, s as logToFile, wt as regionOption } from "./debug-BM0fZaGl.js";
4
4
  import { a as getLocalDev, i as checkLocalServices, o as initLocalDev, r as POSTHOG_LOCAL_URL, s as localMcpSkillsNotice } from "./local-dev-DPZiIPCK.js";
5
- import { n as analytics } from "./analytics-D90QbLf5.js";
6
- import { r as setEntryCommand } from "./telemetry-B1VEXHpL.js";
7
- import { a as safeReadFile, o as walkProjectFiles } from "./bounded-fs-BhlVkP1r.js";
8
- import { n as isUsingTypeScript } from "./setup-utils-B_06xag2.js";
9
- import { o as handleApiError } from "./api-BHhrT6wb.js";
10
- import "./wizard-session-C_7r3-rO.js";
11
- import { i as wizardAbort, r as runCleanups } from "./wizard-abort-CFMdj6sZ.js";
12
- import { n as isNonInteractiveEnvironment } from "./environment-DhacWZf7.js";
13
- import { n as runAgent, s as authenticate } from "./agent-runner-D5dhuE4z.js";
14
- import { T as WIZARD_TOOL_NAMES, k as fetchSkillMenu, l as recoverOrphanedSettingsBackups } from "./agent-interface-CI89BrWE.js";
15
- import { m as writeJsonAtomic } from "./queue-tools-zrqCiy6q.js";
16
- import { S as SETUP_REPORT_FILE, _ as AUDIT_CHECKS_KEY, g as AUDIT_CHECKS_FILE, v as AUDIT_REPORT_FILE } from "./yara-hooks-CmQT-oBy.js";
17
- import { i as SPINNER_MESSAGE, t as FRAMEWORK_REGISTRY } from "./registry-C1t8v5tE.js";
18
- import { C as scopeInstallDirToProject, D as detectFramework, E as gatherFrameworkContext, S as detectIntegrationProjects, T as resolveProjectDir, _ as HEALTH_CHECK_STEP, a as LINE_CHART_BLOCK, b as getDetectedWarehouseSources, d as isClearBlock, g as detectPostHogIntegration, 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 WAREHOUSE_ABORT_CASES, x as detectWarehouseSources, y as detectWarehousePrerequisites } from "./posthog-integration-DdeIUkYw.js";
19
- import { n as readApiKeyFromEnv } from "./env-api-key-CwhtZrik.js";
5
+ import "./wizard-session-Bki7dQhv.js";
6
+ import { n as analytics } from "./analytics-DTyJClPr.js";
7
+ import { r as setEntryCommand } from "./telemetry-CickTk_7.js";
8
+ import { a as safeReadFile, o as walkProjectFiles } from "./bounded-fs-BWX25ixc.js";
9
+ import { n as isUsingTypeScript } from "./setup-utils-Bo3WZt3a.js";
10
+ import { o as handleApiError } from "./api-j-OfJ8Dz.js";
11
+ import { i as wizardAbort, r as runCleanups } from "./wizard-abort-CooWEh9N.js";
12
+ import { n as isNonInteractiveEnvironment } from "./environment-o-bTOuzK.js";
13
+ import { n as runAgent, s as authenticate } from "./agent-runner-vKtpgqVI.js";
14
+ import { T as WIZARD_TOOL_NAMES, k as fetchSkillMenu, l as recoverOrphanedSettingsBackups } from "./agent-interface-Lu7tnLr0.js";
15
+ import { m as writeJsonAtomic } from "./queue-tools-KosDptd6.js";
16
+ import { S as SETUP_REPORT_FILE, _ as AUDIT_CHECKS_KEY, g as AUDIT_CHECKS_FILE, v as AUDIT_REPORT_FILE } from "./yara-hooks-BpngckdZ.js";
17
+ import { i as SPINNER_MESSAGE, t as FRAMEWORK_REGISTRY } from "./registry-BBdaIFWq.js";
18
+ import { C as detectIntegrationProjects, D as gatherFrameworkContext, E as resolveProjectDir, O as detectFramework, S as detectWarehouseSources, a as LINE_CHART_BLOCK, b as detectWarehousePrerequisites, d as isClearBlock, g as detectPostHogIntegration, 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 HEALTH_CHECK_STEP, w as scopeInstallDirToProject, x as getDetectedWarehouseSources, y as WAREHOUSE_ABORT_CASES } from "./posthog-integration-MDfRO911.js";
19
+ import { n as readApiKeyFromEnv } from "./env-api-key-DlxCZWU0.js";
20
20
  import { satisfies } from "semver";
21
21
  import yargs from "yargs";
22
22
  import { hideBin } from "yargs/helpers";
@@ -242,7 +242,7 @@ function runProvision(argv) {
242
242
  }
243
243
  async function provision({ email, region, name, baseUrl, jsonMode }) {
244
244
  try {
245
- const { provisionNewAccount } = await import("./provisioning-e3roaLgp.js").then((n) => n.r);
245
+ const { provisionNewAccount } = await import("./provisioning-Di5GNV9k.js").then((n) => n.r);
246
246
  if (!jsonMode) getUI().log.info(`Provisioning account for ${email} in ${region}...`);
247
247
  emitResult(await provisionNewAccount(email, name, region, { baseUrl }), jsonMode);
248
248
  process.exit(0);
@@ -309,22 +309,22 @@ const basicIntegrationCommand = {
309
309
  setEntryCommand("integrate");
310
310
  (async () => {
311
311
  if (isHeadless(argv)) {
312
- const { runHeadlessInstall } = await import("./ci-install-94wC3a4K.js");
312
+ const { runHeadlessInstall } = await import("./ci-install-zNWgp1TL.js");
313
313
  return runHeadlessInstall(argv);
314
314
  }
315
315
  if (argv.ci) {
316
- const { runCIInstall } = await import("./ci-install-94wC3a4K.js");
316
+ const { runCIInstall } = await import("./ci-install-zNWgp1TL.js");
317
317
  return runCIInstall(argv);
318
318
  }
319
319
  if (isNonInteractiveEnvironment()) {
320
- const { failNonInteractive } = await import("./non-interactive-CbvniKHm.js");
320
+ const { failNonInteractive } = await import("./non-interactive-qcCCtiYQ.js");
321
321
  return failNonInteractive();
322
322
  }
323
323
  if (argv.playground) {
324
- const { runPlayground } = await import("./playground-ZYaQmfBa.js");
324
+ const { runPlayground } = await import("./playground-DLN31BPV.js");
325
325
  return runPlayground();
326
326
  }
327
- const { runInteractive } = await import("./interactive-DlNrV77o.js");
327
+ const { runInteractive } = await import("./interactive-B5zy3Gxk.js");
328
328
  runInteractive(argv);
329
329
  })();
330
330
  }
@@ -2009,14 +2009,19 @@ STEP 5 — Write the credentials to the env file. (skill: "Write credentials to
2009
2009
  because a template documents a key rather than setting it.
2010
2010
  - 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).${variant === "rust" ? ` Cargo workspace exception: when the skill places the env file at the workspace root instead, pass the path of the ROOT manifest's directory relative to the wizard's working directory (e.g. \`rust/.env\` for a workspace root at \`rust/\`, or plain \`.env\` when the workspace root IS the working directory) — not the member path.` : ""}` : `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.`}
2011
2011
  - Then call set_env_values, passing the STEP 1 secretRef as a value
2012
- object, not a literal string:
2012
+ object, not a literal string. Take the three variable NAMES from the
2013
+ skill's per-uploader list in "Write credentials to the env file" — they
2014
+ differ by uploader, and only the shape below is fixed:
2013
2015
  values: {
2014
- "POSTHOG_CLI_API_KEY": { secretRef: "<the ref from STEP 1>" },
2015
- "POSTHOG_CLI_PROJECT_ID": "${projectId}",
2016
- "POSTHOG_CLI_HOST": "${uiHost}"
2016
+ "<key var for the uploader you wired>": { secretRef: "<the ref from STEP 1>" },
2017
+ "<project id var>": "${projectId}",
2018
+ "<host var>": "${uiHost}"
2017
2019
  }
2018
- Variable names follow the skill's per-uploader conventions. The wizard
2019
- resolves the ref locally before writing, so you never see the key value.`;
2020
+ Write that one set only. Do not also write another uploader's variables
2021
+ as a fallback — a credential nothing reads is an unused secret sitting
2022
+ in the user's env file.
2023
+ The wizard resolves the ref locally before writing, so you never see the
2024
+ key value.`;
2020
2025
  return `You are wiring up PostHog Error Tracking source map upload for this ${platformLabel} project.
2021
2026
 
2022
2027
  Project context:
@@ -4325,7 +4330,7 @@ const mcpAddCommand = {
4325
4330
  function runMcpAdd(argv) {
4326
4331
  const features = parseFeatures(argv.features);
4327
4332
  (async () => {
4328
- const { readApiKeyFromEnv } = await import("./env-api-key-CwhtZrik.js").then((n) => n.t);
4333
+ const { readApiKeyFromEnv } = await import("./env-api-key-DlxCZWU0.js").then((n) => n.t);
4329
4334
  const apiKey = argv.apiKey || readApiKeyFromEnv();
4330
4335
  const debug = argv.debug;
4331
4336
  const localMcp = argv.local;
@@ -4339,8 +4344,8 @@ function runMcpAdd(argv) {
4339
4344
  return;
4340
4345
  }
4341
4346
  try {
4342
- const { startTUI } = await import("./start-tui-BafJXVNT.js");
4343
- const { buildSession } = await import("./wizard-session-D1KQqUml.js");
4347
+ const { startTUI } = await import("./start-tui-B1LrB7k1.js");
4348
+ const { buildSession } = await import("./wizard-session-gbYCXdBf.js");
4344
4349
  const tui = startTUI(VERSION, Program.McpAdd);
4345
4350
  tui.store.session = buildSession({
4346
4351
  debug,
@@ -4357,7 +4362,7 @@ function runMcpAdd(argv) {
4357
4362
  }
4358
4363
  async function runHeadlessAdd(args) {
4359
4364
  setUI(new LoggingUI());
4360
- const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-Cl2HBuxp.js").then((n) => n.r);
4365
+ const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-BCnjUqnW.js").then((n) => n.r);
4361
4366
  const { installed, failed } = await addMCPServerToClientsStep(args);
4362
4367
  if (failed.length > 0 || installed.length === 0) process.exitCode = 1;
4363
4368
  }
@@ -4389,8 +4394,8 @@ function runMcpRemove(argv) {
4389
4394
  return;
4390
4395
  }
4391
4396
  try {
4392
- const { startTUI } = await import("./start-tui-BafJXVNT.js");
4393
- const { buildSession } = await import("./wizard-session-D1KQqUml.js");
4397
+ const { startTUI } = await import("./start-tui-B1LrB7k1.js");
4398
+ const { buildSession } = await import("./wizard-session-gbYCXdBf.js");
4394
4399
  const tui = startTUI(VERSION, Program.McpRemove);
4395
4400
  tui.store.session = buildSession({
4396
4401
  debug,
@@ -4406,7 +4411,7 @@ function runMcpRemove(argv) {
4406
4411
  /** No exit code on an empty result: nothing to remove is the requested end state. */
4407
4412
  async function runHeadlessRemove(local) {
4408
4413
  setUI(new LoggingUI());
4409
- const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-Cl2HBuxp.js").then((n) => n.r);
4414
+ const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-BCnjUqnW.js").then((n) => n.r);
4410
4415
  await removeMCPServerFromClientsStep({ local });
4411
4416
  }
4412
4417
  //#endregion
@@ -4426,8 +4431,8 @@ function runMcpTutorial(argv) {
4426
4431
  const debug = argv.debug;
4427
4432
  const localMcp = argv.local;
4428
4433
  try {
4429
- const { startTUI } = await import("./start-tui-BafJXVNT.js");
4430
- const { buildSession } = await import("./wizard-session-D1KQqUml.js");
4434
+ const { startTUI } = await import("./start-tui-B1LrB7k1.js");
4435
+ const { buildSession } = await import("./wizard-session-gbYCXdBf.js");
4431
4436
  const tui = startTUI(VERSION, Program.McpTutorial);
4432
4437
  tui.store.session = buildSession({
4433
4438
  debug,
@@ -4512,17 +4517,17 @@ function runWizard(config, options) {
4512
4517
  (async () => {
4513
4518
  try {
4514
4519
  const installDir = options.installDir || process.cwd();
4515
- const { startTUI } = await import("./start-tui-BafJXVNT.js");
4516
- const { buildSession, RunPhase } = await import("./wizard-session-D1KQqUml.js");
4517
- const { TaskStreamPush } = await import("./task-stream-uxG6wJfj.js");
4518
- const { PostHogDestination } = await import("./posthog-D1zHPgYJ.js");
4520
+ const { startTUI } = await import("./start-tui-B1LrB7k1.js");
4521
+ const { buildSession, RunPhase } = await import("./wizard-session-gbYCXdBf.js");
4522
+ const { TaskStreamPush } = await import("./task-stream-rxR1IsdJ.js");
4523
+ const { PostHogDestination } = await import("./posthog-Dxr8XK4x.js");
4519
4524
  const local = getLocalDev();
4520
4525
  const localServicesError = await checkLocalServices({
4521
4526
  ...local,
4522
4527
  localPosthog: local.localPosthog && !options.baseUrl
4523
4528
  });
4524
4529
  if (localServicesError) {
4525
- const { wizardAbort } = await import("./wizard-abort-BZOeapsf.js");
4530
+ const { wizardAbort } = await import("./wizard-abort-CW_C2EXr.js");
4526
4531
  await wizardAbort({ message: localServicesError });
4527
4532
  return;
4528
4533
  }
@@ -4593,7 +4598,7 @@ function runWizard(config, options) {
4593
4598
  if (shown(step)) await advanceStep(step, activeTui.store, config);
4594
4599
  }
4595
4600
  else if (skipAgent) {
4596
- const { getOrAskForProjectData } = await import("./setup-utils-B_06xag2.js").then((n) => n.r);
4601
+ const { getOrAskForProjectData } = await import("./setup-utils-Bo3WZt3a.js").then((n) => n.r);
4597
4602
  const { projectApiKey, host, accessToken, projectId } = await getOrAskForProjectData({
4598
4603
  signup: session.signup,
4599
4604
  ci: session.ci,
@@ -4706,11 +4711,11 @@ function runNonInteractive(config, options, mode) {
4706
4711
  analytics.setTag("build", mode);
4707
4712
  (async () => {
4708
4713
  const path = await import("path");
4709
- const { buildSession, RunPhase, OutroKind } = await import("./wizard-session-D1KQqUml.js");
4710
- const { readEnvironment } = await import("./environment-DhacWZf7.js").then((n) => n.t);
4711
- const { readApiKeyFromEnv } = await import("./env-api-key-CwhtZrik.js").then((n) => n.t);
4712
- const { configureLogFileFromEnvironment, logToFile } = await import("./debug-DtixqVEY.js");
4713
- const { wizardAbort, WizardError } = await import("./wizard-abort-BZOeapsf.js");
4714
+ const { buildSession, RunPhase, OutroKind } = await import("./wizard-session-gbYCXdBf.js");
4715
+ const { readEnvironment } = await import("./environment-o-bTOuzK.js").then((n) => n.t);
4716
+ const { readApiKeyFromEnv } = await import("./env-api-key-DlxCZWU0.js").then((n) => n.t);
4717
+ const { configureLogFileFromEnvironment, logToFile } = await import("./debug-xr2Pq5VA.js");
4718
+ const { wizardAbort, WizardError } = await import("./wizard-abort-CW_C2EXr.js");
4714
4719
  configureLogFileFromEnvironment();
4715
4720
  const env = readEnvironment();
4716
4721
  const apiKey = options.apiKey ?? readApiKeyFromEnv() ?? void 0;
@@ -4757,9 +4762,9 @@ function runNonInteractive(config, options, mode) {
4757
4762
  let store = null;
4758
4763
  let taskStream = null;
4759
4764
  if (mode === "headless") {
4760
- const { WizardStore } = await import("./store-DSUCWMRO.js").then((n) => n.n);
4761
- const { HeadlessUI } = await import("./headless-ui-DNcOVJxU.js");
4762
- const { TaskStreamPush, PostHogDestination } = await import("./task-stream-uxG6wJfj.js");
4765
+ const { WizardStore } = await import("./store-DhNTBWQR.js").then((n) => n.n);
4766
+ const { HeadlessUI } = await import("./headless-ui-C46DctKG.js");
4767
+ const { TaskStreamPush, PostHogDestination } = await import("./task-stream-rxR1IsdJ.js");
4763
4768
  store = new WizardStore(config.id);
4764
4769
  store.session = session;
4765
4770
  setUI(new HeadlessUI(store));
@@ -4842,7 +4847,7 @@ function runNonInteractive(config, options, mode) {
4842
4847
  });
4843
4848
  }
4844
4849
  }
4845
- const { runAgent } = await import("./agent-runner-D5dhuE4z.js").then((n) => n.t);
4850
+ const { runAgent } = await import("./agent-runner-vKtpgqVI.js").then((n) => n.t);
4846
4851
  await runAgent(config, session);
4847
4852
  await settleStream(RunPhase.Completed);
4848
4853
  } catch (error) {
@@ -6089,7 +6094,7 @@ async function runDoctorCI(options) {
6089
6094
  getUI().intro("Welcome to the PostHog setup wizard");
6090
6095
  getUI().log.info("Running posthog-doctor in CI mode");
6091
6096
  try {
6092
- const { getOrAskForProjectData } = await import("./setup-utils-B_06xag2.js").then((n) => n.r);
6097
+ const { getOrAskForProjectData } = await import("./setup-utils-Bo3WZt3a.js").then((n) => n.r);
6093
6098
  const { host, accessToken, projectId } = await getOrAskForProjectData({
6094
6099
  signup: false,
6095
6100
  ci: true,
@@ -6107,7 +6112,7 @@ async function runDoctorCI(options) {
6107
6112
  for (const issue of sorted) getUI().log.info(` • [${issue.severity}] ${getKindMeta(issue.kind).title}`);
6108
6113
  process.exit(1);
6109
6114
  } catch (error) {
6110
- const { ApiError } = await import("./api-BHhrT6wb.js").then((n) => n.n);
6115
+ const { ApiError } = await import("./api-j-OfJ8Dz.js").then((n) => n.n);
6111
6116
  const message = error instanceof ApiError && error.statusCode === 401 ? "Your PostHog API key is invalid or expired." : error instanceof Error ? error.message : String(error);
6112
6117
  getUI().log.error(`Doctor failed: ${message}`);
6113
6118
  emitWizardError({
@@ -6193,8 +6198,8 @@ function runSlackConnect(argv) {
6193
6198
  (async () => {
6194
6199
  const debug = argv.debug;
6195
6200
  try {
6196
- const { startTUI } = await import("./start-tui-BafJXVNT.js");
6197
- const { buildSession } = await import("./wizard-session-D1KQqUml.js");
6201
+ const { startTUI } = await import("./start-tui-B1LrB7k1.js");
6202
+ const { buildSession } = await import("./wizard-session-gbYCXdBf.js");
6198
6203
  const tui = startTUI(VERSION, Program.SlackConnect);
6199
6204
  tui.store.session = buildSession({
6200
6205
  debug,