@posthog/wizard 2.16.1 → 2.18.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 (83) hide show
  1. package/dist/{add-mcp-server-to-clients-BS6Rjcwh.js → add-mcp-server-to-clients-DnPwZl1P.js} +38 -5
  2. package/dist/add-mcp-server-to-clients-DnPwZl1P.js.map +1 -0
  3. package/dist/{agent-interface-B4eUlMso.js → agent-interface-C2VEF-BD.js} +110 -54
  4. package/dist/agent-interface-C2VEF-BD.js.map +1 -0
  5. package/dist/{agent-runner-BxqiKVEf.js → agent-runner-Dw8cjZoN.js} +11 -8
  6. package/dist/{agent-runner-BxqiKVEf.js.map → agent-runner-Dw8cjZoN.js.map} +1 -1
  7. package/dist/{analytics-DUuUurR3.js → analytics-C-zcTO6g.js} +26 -4
  8. package/dist/analytics-C-zcTO6g.js.map +1 -0
  9. package/dist/{api-CGJ1iGps.js → api-B3MWP3vm.js} +14 -4
  10. package/dist/{api-CGJ1iGps.js.map → api-B3MWP3vm.js.map} +1 -1
  11. package/dist/bin.js +238 -82
  12. package/dist/bin.js.map +1 -1
  13. package/dist/{ci-install-DD7WMmIF.js → ci-install-DLuSmSq6.js} +4 -4
  14. package/dist/{ci-install-DD7WMmIF.js.map → ci-install-DLuSmSq6.js.map} +1 -1
  15. package/dist/{debug-Cd0hPlZy.js → debug--gQGudnY.js} +1 -1
  16. package/dist/{debug-ubpO6102.js → debug-BorYMfpE.js} +2 -2
  17. package/dist/{debug-ubpO6102.js.map → debug-BorYMfpE.js.map} +1 -1
  18. package/dist/{defaults-zrYmZ2ID.js → defaults-DA3-9dHT.js} +1 -1
  19. package/dist/{defaults-zrYmZ2ID.js.map → defaults-DA3-9dHT.js.map} +1 -1
  20. package/dist/{env-api-key-DEl3LJBv.js → env-api-key-MlzJYAvt.js} +1 -1
  21. package/dist/{env-api-key-DEl3LJBv.js.map → env-api-key-MlzJYAvt.js.map} +1 -1
  22. package/dist/{environment-BAaC5THg.js → environment-DIOtLqTQ.js} +3 -3
  23. package/dist/{environment-BAaC5THg.js.map → environment-DIOtLqTQ.js.map} +1 -1
  24. package/dist/{file-utils-DPmgn9Vm.js → file-utils-VAXoyXVA.js} +1 -1
  25. package/dist/{file-utils-DPmgn9Vm.js.map → file-utils-VAXoyXVA.js.map} +1 -1
  26. package/dist/{interactive-BaMAq88Q.js → interactive-DjGjlvY3.js} +2 -2
  27. package/dist/{interactive-BaMAq88Q.js.map → interactive-DjGjlvY3.js.map} +1 -1
  28. package/dist/{mcp-prompt-streaming-clGsVw8q.js → mcp-prompt-streaming-Dm47tmiy.js} +62 -12
  29. package/dist/mcp-prompt-streaming-Dm47tmiy.js.map +1 -0
  30. package/dist/{non-interactive-l2AKE3jD.js → non-interactive-C2f3Gwva.js} +2 -2
  31. package/dist/{non-interactive-l2AKE3jD.js.map → non-interactive-C2f3Gwva.js.map} +1 -1
  32. package/dist/{package-json-Cynjr9k4.js → package-json-DCuoye-H.js} +8 -2
  33. package/dist/{package-json-Cynjr9k4.js.map → package-json-DCuoye-H.js.map} +1 -1
  34. package/dist/{package-manager-BqsJK3ej.js → package-manager-Bl2KOUFK.js} +2 -2
  35. package/dist/{package-manager-BqsJK3ej.js.map → package-manager-Bl2KOUFK.js.map} +1 -1
  36. package/dist/{playground-DlE5RNfE.js → playground-ZLG68cvx.js} +21 -10
  37. package/dist/playground-ZLG68cvx.js.map +1 -0
  38. package/dist/{posthog-DWL8uOcl.js → posthog-Cr37rnla.js} +1 -1
  39. package/dist/{posthog-DWL8uOcl.js.map → posthog-Cr37rnla.js.map} +1 -1
  40. package/dist/{posthog-integration-Bf_vtWI9.js → posthog-integration-B_DLodqr.js} +282 -14
  41. package/dist/posthog-integration-B_DLodqr.js.map +1 -0
  42. package/dist/{provisioning-D_hAuxUN.js → provisioning-Bk4E6VYn.js} +9 -4
  43. package/dist/{provisioning-D_hAuxUN.js.map → provisioning-Bk4E6VYn.js.map} +1 -1
  44. package/dist/{registry-DKgYqROt.js → registry-DMM3UmZD.js} +5 -5
  45. package/dist/{registry-DKgYqROt.js.map → registry-DMM3UmZD.js.map} +1 -1
  46. package/dist/{setup-utils-D-uTycLX.js → setup-utils-Df9ezAjZ.js} +86 -38
  47. package/dist/setup-utils-Df9ezAjZ.js.map +1 -0
  48. package/dist/{slides-CL1mv_Kq.js → slides-DwvXZ8iS.js} +1583 -322
  49. package/dist/slides-DwvXZ8iS.js.map +1 -0
  50. package/dist/{start-tui-DXrv6cof.js → start-tui-P9aMwBzt.js} +28 -18
  51. package/dist/start-tui-P9aMwBzt.js.map +1 -0
  52. package/dist/{steps-CgScwqso.js → steps-RCRZbLjZ.js} +6 -6
  53. package/dist/{steps-CgScwqso.js.map → steps-RCRZbLjZ.js.map} +1 -1
  54. package/dist/{task-stream-CF6QMVMv.js → task-stream-CZRj6auI.js} +3 -3
  55. package/dist/{task-stream-CF6QMVMv.js.map → task-stream-CZRj6auI.js.map} +1 -1
  56. package/dist/{telemetry-v6O12Bep.js → telemetry-CMbVbpaY.js} +2 -2
  57. package/dist/{telemetry-v6O12Bep.js.map → telemetry-CMbVbpaY.js.map} +1 -1
  58. package/dist/urls-BzG_Jtw9.js +35 -0
  59. package/dist/urls-BzG_Jtw9.js.map +1 -0
  60. package/dist/{wizard-abort-BGoBKgvC.js → wizard-abort-Dl8WJQgJ.js} +1 -1
  61. package/dist/{wizard-abort-iTaJ8wC8.js → wizard-abort-QuKm_B5z.js} +3 -3
  62. package/dist/{wizard-abort-iTaJ8wC8.js.map → wizard-abort-QuKm_B5z.js.map} +1 -1
  63. package/dist/{wizard-session-gsn8Z3bZ.js → wizard-session-d27JGRGi.js} +1 -1
  64. package/dist/{wizard-session-gsn8Z3bZ.js.map → wizard-session-d27JGRGi.js.map} +1 -1
  65. package/dist/{wizard-session-7tMjgOvP.js → wizard-session-y304gEEI.js} +1 -1
  66. package/package.json +1 -1
  67. package/dist/TextBlock-CdeZog_6.js +0 -275
  68. package/dist/TextBlock-CdeZog_6.js.map +0 -1
  69. package/dist/add-mcp-server-to-clients-BS6Rjcwh.js.map +0 -1
  70. package/dist/agent-interface-B4eUlMso.js.map +0 -1
  71. package/dist/analytics-DUuUurR3.js.map +0 -1
  72. package/dist/api-B8OR0N1V.js +0 -2
  73. package/dist/mcp-prompt-streaming-clGsVw8q.js.map +0 -1
  74. package/dist/package-json-CumwmZpv.js +0 -2
  75. package/dist/playground-DlE5RNfE.js.map +0 -1
  76. package/dist/posthog-integration-Bf_vtWI9.js.map +0 -1
  77. package/dist/provisioning-BlBnlcFd.js +0 -2
  78. package/dist/setup-utils-BHZEdkNZ.js +0 -2
  79. package/dist/setup-utils-D-uTycLX.js.map +0 -1
  80. package/dist/skill-CnOQAZXp.js +0 -29
  81. package/dist/skill-CnOQAZXp.js.map +0 -1
  82. package/dist/slides-CL1mv_Kq.js.map +0 -1
  83. package/dist/start-tui-DXrv6cof.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"api-CGJ1iGps.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 })\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});\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\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-B3MWP3vm.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 })\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});\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\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,16 +1,16 @@
1
1
  #!/usr/bin/env node
2
- import { J as VERSION, M as POSTHOG_DOCS_URL, W as WIZARD_USER_AGENT, X as runtimeEnv, _ as SIGNUP_WIZARD_READINESS_CONFIG, h as LoggingUI, m as setUI, p as getUI, s as logToFile, v as evaluateWizardReadiness, y as getBlockingServiceKeys } from "./debug-ubpO6102.js";
3
- import { t as analytics } from "./analytics-DUuUurR3.js";
4
- import { a as isUsingTypeScript, f as getUiHostFromHost, u as getCloudUrlFromRegion } from "./setup-utils-D-uTycLX.js";
5
- import { s as handleApiError } from "./api-CGJ1iGps.js";
6
- import "./wizard-session-gsn8Z3bZ.js";
7
- import { n as isNonInteractiveEnvironment } from "./environment-BAaC5THg.js";
8
- import { g as AUDIT_REPORT_FILE, h as AUDIT_CHECKS_KEY, m as AUDIT_CHECKS_FILE, t as AgentSignals, u as WIZARD_TOOL_NAMES } from "./agent-interface-B4eUlMso.js";
9
- import { i as SPINNER_MESSAGE } from "./registry-DKgYqROt.js";
10
- import { a as PRODUCT_SUITE_BLOCK, i as LINE_CHART_BLOCK, n as posthogIntegrationConfig, o as StatusPeekTrigger, r as FUNNEL_BLOCK } from "./posthog-integration-Bf_vtWI9.js";
11
- import { c as HEALTH_CHECK_STEP, o as Colors, r as isClearBlock } from "./TextBlock-CdeZog_6.js";
12
- import { t as IGNORED_DIRS } from "./file-utils-DPmgn9Vm.js";
13
- import { n as readApiKeyFromEnv } from "./env-api-key-DEl3LJBv.js";
2
+ import { J as VERSION, M as POSTHOG_DOCS_URL, W as WIZARD_USER_AGENT, X as runtimeEnv, _ as SIGNUP_WIZARD_READINESS_CONFIG, h as LoggingUI, m as setUI, p as getUI, s as logToFile, v as evaluateWizardReadiness, y as getBlockingServiceKeys } from "./debug-BorYMfpE.js";
3
+ import { t as analytics } from "./analytics-C-zcTO6g.js";
4
+ import { n as isUsingTypeScript } from "./setup-utils-Df9ezAjZ.js";
5
+ import { a as getUiHostFromHost, n as getCloudUrlFromRegion } from "./urls-BzG_Jtw9.js";
6
+ import { a as handleApiError } from "./api-B3MWP3vm.js";
7
+ import "./wizard-session-d27JGRGi.js";
8
+ import { n as isNonInteractiveEnvironment } from "./environment-DIOtLqTQ.js";
9
+ import { _ as AUDIT_REPORT_FILE, c as AgentSignals, d as WIZARD_TOOL_NAMES, g as AUDIT_CHECKS_KEY, h as AUDIT_CHECKS_FILE } from "./agent-interface-C2VEF-BD.js";
10
+ import { i as SPINNER_MESSAGE } from "./registry-DMM3UmZD.js";
11
+ import { a as PRODUCT_SUITE_BLOCK, f as Colors, i as LINE_CHART_BLOCK, l as isClearBlock, m as HEALTH_CHECK_STEP, n as posthogIntegrationConfig, o as StatusPeekTrigger, r as FUNNEL_BLOCK } from "./posthog-integration-B_DLodqr.js";
12
+ import { t as IGNORED_DIRS } from "./file-utils-VAXoyXVA.js";
13
+ import { n as readApiKeyFromEnv } from "./env-api-key-MlzJYAvt.js";
14
14
  import { satisfies } from "semver";
15
15
  import yargs from "yargs";
16
16
  import { hideBin } from "yargs/helpers";
@@ -160,7 +160,7 @@ function runProvision(argv) {
160
160
  }
161
161
  async function provision({ email, region, name, jsonMode }) {
162
162
  try {
163
- const { provisionNewAccount } = await import("./provisioning-BlBnlcFd.js");
163
+ const { provisionNewAccount } = await import("./provisioning-Bk4E6VYn.js").then((n) => n.n);
164
164
  if (!jsonMode) getUI().log.info(`Provisioning account for ${email} in ${region}...`);
165
165
  emitResult(await provisionNewAccount(email, name, region), jsonMode);
166
166
  process.exit(0);
@@ -222,49 +222,36 @@ const basicIntegrationCommand = {
222
222
  type: "boolean",
223
223
  hidden: true
224
224
  },
225
- skill: {
226
- describe: "Run a specific context-mill skill by ID\nenv: POSTHOG_WIZARD_SKILL",
227
- type: "string"
228
- },
229
225
  name: {
230
226
  describe: "Name for account creation with --ci --signup\nenv: POSTHOG_WIZARD_NAME",
231
227
  type: "string"
232
228
  }
233
229
  },
234
230
  check: (argv) => {
235
- if (argv.playground && (argv.ci || argv.skill)) throw new Error("--playground cannot be combined with --ci or --skill.");
236
- if (typeof argv.skill === "string" && argv.skill.trim() === "") throw new Error("--skill needs a skill ID, e.g. --skill=\"foo\"");
231
+ if (argv.playground && argv.ci) throw new Error("--playground cannot be combined with --ci.");
237
232
  return true;
238
233
  },
239
234
  handler: (argv) => {
240
235
  (async () => {
241
- if (argv.ci && argv.skill) {
242
- const { runSkillMode } = await import("./skill-CnOQAZXp.js");
243
- return runSkillMode(argv);
244
- }
245
236
  if (argv.ci) {
246
- const { runCIInstall } = await import("./ci-install-DD7WMmIF.js");
237
+ const { runCIInstall } = await import("./ci-install-DLuSmSq6.js");
247
238
  return runCIInstall(argv);
248
239
  }
249
240
  if (isNonInteractiveEnvironment()) {
250
- const { failNonInteractive } = await import("./non-interactive-l2AKE3jD.js");
241
+ const { failNonInteractive } = await import("./non-interactive-C2f3Gwva.js");
251
242
  return failNonInteractive();
252
243
  }
253
244
  if (argv.playground) {
254
- const { runPlayground } = await import("./playground-DlE5RNfE.js");
245
+ const { runPlayground } = await import("./playground-ZLG68cvx.js");
255
246
  return runPlayground();
256
247
  }
257
- if (argv.skill) {
258
- const { runSkillMode } = await import("./skill-CnOQAZXp.js");
259
- return runSkillMode(argv);
260
- }
261
- const { runInteractive } = await import("./interactive-BaMAq88Q.js");
248
+ const { runInteractive } = await import("./interactive-DjGjlvY3.js");
262
249
  runInteractive(argv);
263
250
  })();
264
251
  }
265
252
  };
266
253
  //#endregion
267
- //#region src/lib/programs/revenue-analytics/detect.ts
254
+ //#region src/lib/programs/shared/package-scanning.ts
268
255
  const POSTHOG_SDKS$1 = [
269
256
  "posthog-js",
270
257
  "posthog-node",
@@ -277,18 +264,6 @@ const STRIPE_SDKS = [
277
264
  "@stripe/stripe-js",
278
265
  "@stripe/react-stripe-js"
279
266
  ];
280
- /** `[ABORT] <reason>` cases the revenue analytics skill can emit. */
281
- const REVENUE_ABORT_CASES = [{
282
- match: /^could not find a posthog distinct_id$/i,
283
- message: "Could not find a PostHog distinct_id",
284
- body: "The agent could not find PostHog distinct_id usage in your codebase. Your users must be identified in PostHog before they can be tagged in Stripe. Please identify your users and try again.",
285
- docsUrl: "https://posthog.com/docs/product-analytics/identify"
286
- }, {
287
- match: /^could not find a stripe integration$/i,
288
- message: "Could not find a Stripe integration",
289
- body: "The Wizard could not find an existing Stripe customer, charge, subscription, or other Stripe operations. Please run the Revenue Analytics Wizard on a project with an existing Stripe integration.",
290
- docsUrl: "https://posthog.com/docs/revenue-analytics"
291
- }];
292
267
  /**
293
268
  * Recursively find all package.json files under installDir (max depth 3),
294
269
  * skipping common ignored directories. Returns matches with detected SDKs.
@@ -324,6 +299,26 @@ function findPackageJsons(installDir, maxDepth = 3) {
324
299
  scan(installDir, 0);
325
300
  return matches;
326
301
  }
302
+ //#endregion
303
+ //#region src/lib/programs/revenue-analytics/detect.ts
304
+ /**
305
+ * Revenue analytics prerequisite detection.
306
+ *
307
+ * Scans the project for PostHog + Stripe SDKs and writes results
308
+ * into frameworkContext for the intro screen to render.
309
+ */
310
+ /** `[ABORT] <reason>` cases the revenue analytics skill can emit. */
311
+ const REVENUE_ABORT_CASES = [{
312
+ match: /^could not find a posthog distinct_id$/i,
313
+ message: "Could not find a PostHog distinct_id",
314
+ body: "The agent could not find PostHog distinct_id usage in your codebase. Your users must be identified in PostHog before they can be tagged in Stripe. Please identify your users and try again.",
315
+ docsUrl: "https://posthog.com/docs/product-analytics/identify"
316
+ }, {
317
+ match: /^could not find a stripe integration$/i,
318
+ message: "Could not find a Stripe integration",
319
+ body: "The Wizard could not find an existing Stripe customer, charge, subscription, or other Stripe operations. Please run the Revenue Analytics Wizard on a project with an existing Stripe integration.",
320
+ docsUrl: "https://posthog.com/docs/revenue-analytics"
321
+ }];
327
322
  /**
328
323
  * Scan `session.installDir` for PostHog + Stripe SDKs. Writes detection
329
324
  * results into frameworkContext via the callback — either the detected
@@ -830,7 +825,7 @@ const EVENTS_AUDIT_SEED_CHECKS = [
830
825
  //#endregion
831
826
  //#region src/lib/programs/events-audit/index.ts
832
827
  const SETUP_REPORT_FILE = "posthog-events-audit-report.md";
833
- const DOCS_URL$1 = "https://posthog.com/docs/product-analytics/best-practices";
828
+ const DOCS_URL$2 = "https://posthog.com/docs/product-analytics/best-practices";
834
829
  const eventsAuditConfig = {
835
830
  command: "events-audit",
836
831
  description: "Audit PostHog event tracking in this project",
@@ -852,7 +847,7 @@ const eventsAuditConfig = {
852
847
  successMessage: "Events audit complete! You can view the report at ./posthog-events-audit-report.md",
853
848
  estimatedDurationMinutes: 5,
854
849
  reportFile: SETUP_REPORT_FILE,
855
- docsUrl: DOCS_URL$1,
850
+ docsUrl: DOCS_URL$2,
856
851
  errorMessage: "Events audit failed",
857
852
  additionalFeatureQueue: session.additionalFeatureQueue,
858
853
  customPrompt: (ctx) => `Audit PostHog event capture in this project. Do not modify any project files — produce a read-only report only.
@@ -870,7 +865,7 @@ Project context:
870
865
  message: "Your events audit was successful",
871
866
  reportFile: SETUP_REPORT_FILE,
872
867
  changes: [],
873
- docsUrl: DOCS_URL$1,
868
+ docsUrl: DOCS_URL$2,
874
869
  continueUrl: sess.signup && cloudUrl ? `${cloudUrl}/products?source=wizard` : void 0,
875
870
  dashboardUrl: sess.dashboardUrl ?? (cloudUrl ? `${cloudUrl}/dashboard` : void 0),
876
871
  notebookUrl: sess.notebookUrl ?? void 0
@@ -1235,6 +1230,97 @@ const posthogDoctorConfig = {
1235
1230
  disallowedTools: [WIZARD_TOOL_NAMES.wizardAsk]
1236
1231
  };
1237
1232
  //#endregion
1233
+ //#region src/lib/programs/web-analytics-doctor/detect.ts
1234
+ const WEB_ANALYTICS_ABORT_CASES = [
1235
+ {
1236
+ match: /^no web analytics events$/i,
1237
+ message: "No web analytics events",
1238
+ body: "The doctor found no $pageview events in the last 30 days, so there is nothing to audit yet. Make sure PostHog is initialized and capturing pageviews, then run the doctor again.",
1239
+ docsUrl: "https://posthog.com/docs/web-analytics/getting-started"
1240
+ },
1241
+ {
1242
+ match: /^insufficient permissions$/i,
1243
+ message: "Insufficient permissions",
1244
+ body: "The doctor could not query your project — the authenticated token is missing query access. Re-run the wizard to sign in again, or use a key with read access to your events.",
1245
+ docsUrl: "https://posthog.com/docs/web-analytics"
1246
+ },
1247
+ {
1248
+ match: /^posthog sdk not installed$/i,
1249
+ message: "PostHog SDK not installed",
1250
+ body: "The doctor could not find a PostHog SDK in this project. Install and configure PostHog first (run `npx @posthog/wizard`), then run the doctor to check your web analytics setup.",
1251
+ docsUrl: "https://posthog.com/docs/libraries/js"
1252
+ }
1253
+ ];
1254
+ function detectWebAnalyticsPrerequisites(session, setFrameworkContext) {
1255
+ const fail = (error) => setFrameworkContext("detectError", error);
1256
+ const installDir = session.installDir;
1257
+ if (!existsSync(installDir)) {
1258
+ fail({
1259
+ kind: "bad-directory",
1260
+ path: installDir,
1261
+ reason: "missing"
1262
+ });
1263
+ return;
1264
+ }
1265
+ try {
1266
+ if (!statSync(installDir).isDirectory()) {
1267
+ fail({
1268
+ kind: "bad-directory",
1269
+ path: installDir,
1270
+ reason: "not-dir"
1271
+ });
1272
+ return;
1273
+ }
1274
+ } catch {
1275
+ fail({
1276
+ kind: "bad-directory",
1277
+ path: installDir,
1278
+ reason: "unreadable"
1279
+ });
1280
+ return;
1281
+ }
1282
+ const matches = findPackageJsons(installDir);
1283
+ if (matches.length === 0) {
1284
+ fail({ kind: "no-package-json" });
1285
+ return;
1286
+ }
1287
+ const sdks = [...new Set(matches.flatMap((m) => m.posthogSdks))];
1288
+ if (sdks.length === 0) {
1289
+ fail({
1290
+ kind: "no-posthog",
1291
+ scannedCount: matches.length
1292
+ });
1293
+ return;
1294
+ }
1295
+ setFrameworkContext("detectedPosthogSdks", sdks);
1296
+ }
1297
+ //#endregion
1298
+ //#region src/lib/programs/web-analytics-doctor/steps.ts
1299
+ const WEB_ANALYTICS_DOCTOR_PROGRAM = [{
1300
+ id: "detect",
1301
+ label: "Detecting prerequisites",
1302
+ onReady: (ctx) => detectWebAnalyticsPrerequisites(ctx.session, ctx.setFrameworkContext)
1303
+ }, ...AGENT_SKILL_STEPS];
1304
+ const webAnalyticsDoctorConfig = {
1305
+ ...createSkillProgram({
1306
+ skillId: "web-analytics-doctor",
1307
+ command: "web-analytics",
1308
+ id: "web-analytics-doctor",
1309
+ description: "Audit and fix your PostHog web analytics setup",
1310
+ integrationLabel: "web-analytics-doctor",
1311
+ customPrompt: "Run the web-analytics-doctor skill to check this project's PostHog web analytics setup. Audit read-only first, then present the findings to the user with a single wizard_ask multi-select and apply only the fixes they choose — editing project code and/or PostHog project settings via the MCP — before writing the report.",
1312
+ successMessage: "Web analytics check complete! You can view the report at ./posthog-web-analytics-report.md",
1313
+ reportFile: "posthog-web-analytics-report.md",
1314
+ docsUrl: "https://posthog.com/docs/web-analytics",
1315
+ spinnerMessage: "Checking your web analytics setup...",
1316
+ estimatedDurationMinutes: 5,
1317
+ requires: ["posthog-integration"],
1318
+ abortCases: WEB_ANALYTICS_ABORT_CASES
1319
+ }),
1320
+ steps: WEB_ANALYTICS_DOCTOR_PROGRAM,
1321
+ parentCommand: "audit"
1322
+ };
1323
+ //#endregion
1238
1324
  //#region src/lib/programs/migration/steps.ts
1239
1325
  const MIGRATION_PROGRAM = [
1240
1326
  {
@@ -2626,6 +2712,7 @@ const PROGRAM_REGISTRY = [
2626
2712
  eventsAuditConfig,
2627
2713
  audit3000Config,
2628
2714
  posthogDoctorConfig,
2715
+ webAnalyticsDoctorConfig,
2629
2716
  migrationConfig,
2630
2717
  agentSkillConfig,
2631
2718
  mcpAddConfig,
@@ -2646,6 +2733,7 @@ const Program = {
2646
2733
  EventsAudit: eventsAuditConfig.id,
2647
2734
  Audit3000: audit3000Config.id,
2648
2735
  PosthogDoctor: posthogDoctorConfig.id,
2736
+ WebAnalyticsDoctor: webAnalyticsDoctorConfig.id,
2649
2737
  AgentSkill: agentSkillConfig.id,
2650
2738
  McpAdd: mcpAddConfig.id,
2651
2739
  McpRemove: mcpRemoveConfig.id,
@@ -2684,13 +2772,13 @@ const mcpAddCommand = {
2684
2772
  function runMcpAdd(argv) {
2685
2773
  const features = parseFeatures(argv.features);
2686
2774
  (async () => {
2687
- const { readApiKeyFromEnv } = await import("./env-api-key-DEl3LJBv.js").then((n) => n.t);
2775
+ const { readApiKeyFromEnv } = await import("./env-api-key-MlzJYAvt.js").then((n) => n.t);
2688
2776
  const apiKey = argv.apiKey || readApiKeyFromEnv();
2689
2777
  const debug = argv.debug;
2690
2778
  const localMcp = argv.local;
2691
2779
  try {
2692
- const { startTUI } = await import("./start-tui-DXrv6cof.js");
2693
- const { buildSession } = await import("./wizard-session-7tMjgOvP.js");
2780
+ const { startTUI } = await import("./start-tui-P9aMwBzt.js");
2781
+ const { buildSession } = await import("./wizard-session-y304gEEI.js");
2694
2782
  const tui = startTUI(VERSION, Program.McpAdd);
2695
2783
  tui.store.session = buildSession({
2696
2784
  debug,
@@ -2701,7 +2789,7 @@ function runMcpAdd(argv) {
2701
2789
  } catch (error) {
2702
2790
  if (!isTUIUnavailable(error)) throw error;
2703
2791
  setUI(new LoggingUI());
2704
- const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-BS6Rjcwh.js").then((n) => n.r);
2792
+ const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-DnPwZl1P.js").then((n) => n.r);
2705
2793
  await addMCPServerToClientsStep({
2706
2794
  local: localMcp,
2707
2795
  features,
@@ -2740,8 +2828,8 @@ function runMcpRemove(argv) {
2740
2828
  const debug = argv.debug;
2741
2829
  const localMcp = argv.local;
2742
2830
  try {
2743
- const { startTUI } = await import("./start-tui-DXrv6cof.js");
2744
- const { buildSession } = await import("./wizard-session-7tMjgOvP.js");
2831
+ const { startTUI } = await import("./start-tui-P9aMwBzt.js");
2832
+ const { buildSession } = await import("./wizard-session-y304gEEI.js");
2745
2833
  const tui = startTUI(VERSION, Program.McpRemove);
2746
2834
  tui.store.session = buildSession({
2747
2835
  debug,
@@ -2749,7 +2837,7 @@ function runMcpRemove(argv) {
2749
2837
  });
2750
2838
  } catch {
2751
2839
  setUI(new LoggingUI());
2752
- const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-BS6Rjcwh.js").then((n) => n.r);
2840
+ const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-DnPwZl1P.js").then((n) => n.r);
2753
2841
  await removeMCPServerFromClientsStep({ local: localMcp });
2754
2842
  }
2755
2843
  })();
@@ -2771,8 +2859,8 @@ function runMcpTutorial(argv) {
2771
2859
  const debug = argv.debug;
2772
2860
  const localMcp = argv.local;
2773
2861
  try {
2774
- const { startTUI } = await import("./start-tui-DXrv6cof.js");
2775
- const { buildSession } = await import("./wizard-session-7tMjgOvP.js");
2862
+ const { startTUI } = await import("./start-tui-P9aMwBzt.js");
2863
+ const { buildSession } = await import("./wizard-session-y304gEEI.js");
2776
2864
  const tui = startTUI(VERSION, Program.McpTutorial);
2777
2865
  tui.store.session = buildSession({
2778
2866
  debug,
@@ -2826,11 +2914,11 @@ function runWizard(config, options) {
2826
2914
  (async () => {
2827
2915
  try {
2828
2916
  const installDir = options.installDir || process.cwd();
2829
- const { startTUI } = await import("./start-tui-DXrv6cof.js");
2830
- const { buildSession, RunPhase } = await import("./wizard-session-7tMjgOvP.js");
2831
- const { TaskStreamPush } = await import("./task-stream-CF6QMVMv.js");
2832
- const { PostHogDestination } = await import("./posthog-DWL8uOcl.js");
2833
- const { logToFile } = await import("./debug-Cd0hPlZy.js");
2917
+ const { startTUI } = await import("./start-tui-P9aMwBzt.js");
2918
+ const { buildSession, RunPhase } = await import("./wizard-session-y304gEEI.js");
2919
+ const { TaskStreamPush } = await import("./task-stream-CZRj6auI.js");
2920
+ const { PostHogDestination } = await import("./posthog-Cr37rnla.js");
2921
+ const { logToFile } = await import("./debug--gQGudnY.js");
2834
2922
  tui = startTUI(WIZARD_VERSION, config.id);
2835
2923
  const activeTui = tui;
2836
2924
  const session = buildSession({
@@ -2881,12 +2969,13 @@ function runWizard(config, options) {
2881
2969
  await activeTui.store.getGate("health-check");
2882
2970
  const skipAgent = config.run == null;
2883
2971
  if (skipAgent) {
2884
- const { getOrAskForProjectData } = await import("./setup-utils-BHZEdkNZ.js");
2972
+ const { getOrAskForProjectData } = await import("./setup-utils-Df9ezAjZ.js").then((n) => n.r);
2885
2973
  const { projectApiKey, host, accessToken, projectId } = await getOrAskForProjectData({
2886
2974
  signup: session.signup,
2887
2975
  ci: session.ci,
2888
2976
  apiKey: session.apiKey,
2889
- projectId: session.projectId
2977
+ projectId: session.projectId,
2978
+ programId: config.id
2890
2979
  });
2891
2980
  activeTui.store.setCredentials({
2892
2981
  accessToken,
@@ -2895,7 +2984,7 @@ function runWizard(config, options) {
2895
2984
  projectId
2896
2985
  });
2897
2986
  } else {
2898
- const { runAgent } = await import("./agent-runner-BxqiKVEf.js");
2987
+ const { runAgent } = await import("./agent-runner-Dw8cjZoN.js");
2899
2988
  await runAgent(config, activeTui.store.session);
2900
2989
  }
2901
2990
  const isDone = () => skipAgent ? activeTui.store.session.outroDismissed : activeTui.store.session.skillsComplete;
@@ -2967,11 +3056,11 @@ function runWizardCI(config, options) {
2967
3056
  validateCiOptions(options);
2968
3057
  (async () => {
2969
3058
  const path = await import("path");
2970
- const { buildSession } = await import("./wizard-session-7tMjgOvP.js");
2971
- const { readEnvironment } = await import("./environment-BAaC5THg.js").then((n) => n.t);
2972
- const { readApiKeyFromEnv } = await import("./env-api-key-DEl3LJBv.js").then((n) => n.t);
2973
- const { configureLogFileFromEnvironment, logToFile } = await import("./debug-Cd0hPlZy.js");
2974
- const { wizardAbort, WizardError } = await import("./wizard-abort-BGoBKgvC.js");
3059
+ const { buildSession } = await import("./wizard-session-y304gEEI.js");
3060
+ const { readEnvironment } = await import("./environment-DIOtLqTQ.js").then((n) => n.t);
3061
+ const { readApiKeyFromEnv } = await import("./env-api-key-MlzJYAvt.js").then((n) => n.t);
3062
+ const { configureLogFileFromEnvironment, logToFile } = await import("./debug--gQGudnY.js");
3063
+ const { wizardAbort, WizardError } = await import("./wizard-abort-Dl8WJQgJ.js");
2975
3064
  configureLogFileFromEnvironment();
2976
3065
  const env = readEnvironment();
2977
3066
  const apiKey = options.apiKey ?? readApiKeyFromEnv() ?? void 0;
@@ -3019,7 +3108,7 @@ function runWizardCI(config, options) {
3019
3108
  })
3020
3109
  });
3021
3110
  }
3022
- const { runAgent } = await import("./agent-runner-BxqiKVEf.js");
3111
+ const { runAgent } = await import("./agent-runner-Dw8cjZoN.js");
3023
3112
  await runAgent(config, session);
3024
3113
  } catch (error) {
3025
3114
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -3087,21 +3176,36 @@ const integrateCommand = {
3087
3176
  };
3088
3177
  //#endregion
3089
3178
  //#region src/commands/audit.ts
3179
+ const dispatchProgram = (config, argv) => {
3180
+ const extras = config.mapCliOptions?.(argv) ?? {};
3181
+ const options = {
3182
+ ...argv,
3183
+ ...extras
3184
+ };
3185
+ if (options.ci) runWizardCI(config, options);
3186
+ else runWizard(config, options);
3187
+ };
3188
+ const webAnalyticsCommand = {
3189
+ name: webAnalyticsDoctorConfig.command,
3190
+ description: webAnalyticsDoctorConfig.description,
3191
+ options: {
3192
+ ...skillProgramOptions,
3193
+ ...webAnalyticsDoctorConfig.cliOptions ?? {}
3194
+ },
3195
+ handler: (argv) => {
3196
+ dispatchProgram(webAnalyticsDoctorConfig, argv);
3197
+ }
3198
+ };
3090
3199
  const auditCommand = {
3091
3200
  name: "audit",
3092
3201
  description: auditConfig.description,
3202
+ children: [webAnalyticsCommand],
3093
3203
  options: {
3094
3204
  ...skillProgramOptions,
3095
3205
  ...auditConfig.cliOptions ?? {}
3096
3206
  },
3097
3207
  handler: (argv) => {
3098
- const extras = auditConfig.mapCliOptions?.(argv) ?? {};
3099
- const options = {
3100
- ...argv,
3101
- ...extras
3102
- };
3103
- if (options.ci) runWizardCI(auditConfig, options);
3104
- else runWizard(auditConfig, options);
3208
+ dispatchProgram(auditConfig, argv);
3105
3209
  }
3106
3210
  };
3107
3211
  //#endregion
@@ -3158,7 +3262,7 @@ async function runDoctorCI(options) {
3158
3262
  getUI().intro("Welcome to the PostHog setup wizard");
3159
3263
  getUI().log.info("Running posthog-doctor in CI mode");
3160
3264
  try {
3161
- const { getOrAskForProjectData } = await import("./setup-utils-BHZEdkNZ.js");
3265
+ const { getOrAskForProjectData } = await import("./setup-utils-Df9ezAjZ.js").then((n) => n.r);
3162
3266
  const { host, accessToken, projectId } = await getOrAskForProjectData({
3163
3267
  signup: false,
3164
3268
  ci: true,
@@ -3175,7 +3279,7 @@ async function runDoctorCI(options) {
3175
3279
  for (const issue of sorted) getUI().log.info(` • [${issue.severity}] ${getKindMeta(issue.kind).title}`);
3176
3280
  process.exit(1);
3177
3281
  } catch (error) {
3178
- const { ApiError } = await import("./api-B8OR0N1V.js");
3282
+ const { ApiError } = await import("./api-B3MWP3vm.js").then((n) => n.n);
3179
3283
  const message = error instanceof ApiError && error.statusCode === 401 ? "Your PostHog API key is invalid or expired." : error instanceof Error ? error.message : String(error);
3180
3284
  getUI().log.error(`Doctor failed: ${message}`);
3181
3285
  process.exit(1);
@@ -3241,7 +3345,7 @@ const revenueCommand = {
3241
3345
  //#endregion
3242
3346
  //#region src/commands/upload-sourcemaps.ts
3243
3347
  const uploadSourcemapsCommand = {
3244
- name: "upload-sourcemaps",
3348
+ name: [errorTrackingUploadSourceMapsConfig.command, "upload-sourcemaps"],
3245
3349
  description: errorTrackingUploadSourceMapsConfig.description,
3246
3350
  options: {
3247
3351
  ...skillProgramOptions,
@@ -3258,14 +3362,66 @@ const uploadSourcemapsCommand = {
3258
3362
  }
3259
3363
  };
3260
3364
  //#endregion
3365
+ //#region src/commands/basic-integration/skill.ts
3366
+ /** Run an arbitrary context-mill skill by id (`wizard skill <id>`, headless with `--ci`). */
3367
+ function runSkillMode(argv) {
3368
+ const skillId = argv.skill;
3369
+ const config = createSkillProgram({
3370
+ skillId,
3371
+ command: "skill",
3372
+ id: "agent-skill",
3373
+ description: `Run skill: ${skillId}`,
3374
+ integrationLabel: skillId,
3375
+ successMessage: `${skillId} completed!`,
3376
+ reportFile: `posthog-${skillId}-report.md`,
3377
+ docsUrl: POSTHOG_DOCS_URL,
3378
+ spinnerMessage: `Running ${skillId}...`,
3379
+ estimatedDurationMinutes: 5
3380
+ });
3381
+ const options = {
3382
+ ...argv,
3383
+ skillId
3384
+ };
3385
+ if (argv.ci) runWizardCI(config, options);
3386
+ else runWizard(config, options);
3387
+ }
3388
+ //#endregion
3389
+ //#region src/commands/skill.ts
3390
+ /** Read the `<skill-name>` positional (yargs camelCases the hyphenated key). */
3391
+ function readSkillName(argv) {
3392
+ return String(argv.skillName ?? argv["skill-name"] ?? "").trim();
3393
+ }
3394
+ /**
3395
+ * `wizard skill <skill-name>` — run a single context-mill skill by id.
3396
+ *
3397
+ * Replaces the old `--skill=<id>` flag on the default command. The skill id
3398
+ * is fetched from context-mill's release at runtime (same mechanism the flag
3399
+ * used), so any published skill id works. Pass `--ci` to run headlessly.
3400
+ */
3401
+ const skillCommand = {
3402
+ name: "skill <skill-name>",
3403
+ description: "Run a specific context-mill skill by name",
3404
+ options: { ...skillProgramOptions },
3405
+ check: (argv) => {
3406
+ if (!readSkillName(argv)) throw new Error("skill needs a skill name, e.g. `wizard skill audit-events`");
3407
+ return true;
3408
+ },
3409
+ handler: (argv) => {
3410
+ runSkillMode({
3411
+ ...argv,
3412
+ skill: readSkillName(argv)
3413
+ });
3414
+ }
3415
+ };
3416
+ //#endregion
3261
3417
  //#region bin.ts
3262
3418
  const NODE_VERSION_RANGE = ">=18.17.0";
3263
3419
  if (!satisfies(process.version, NODE_VERSION_RANGE)) {
3264
3420
  console.log(`PostHog wizard requires Node.js ${NODE_VERSION_RANGE}. You are using Node.js ${process.version}. Please upgrade your Node.js version.`);
3265
3421
  process.exit(1);
3266
3422
  }
3267
- Wizard.use(basicIntegrationCommand).use(mcpCommand).use(integrateCommand).use(auditCommand).use(audit3000Command).use(doctorCommand).use(migrateCommand).use(eventsAuditCommand).use(revenueCommand).use(uploadSourcemapsCommand).init();
3423
+ Wizard.use(basicIntegrationCommand).use(mcpCommand).use(integrateCommand).use(auditCommand).use(audit3000Command).use(doctorCommand).use(migrateCommand).use(eventsAuditCommand).use(revenueCommand).use(uploadSourcemapsCommand).use(skillCommand).init();
3268
3424
  //#endregion
3269
- export { getProgramConfig as a, getContentBlocks$1 as c, createSkillProgram as d, getContentBlocks$2 as f, Program as i, getKindMeta as l, STRIPE_SDKS as m, runWizard as n, DISPLAY_NAME as o, POSTHOG_SDKS$1 as p, PROGRAM_REGISTRY as r, SOURCE_MAPS_CONTEXT_KEYS as s, runWizardCI as t, fetchHealthIssues as u };
3425
+ export { getProgramConfig as a, getContentBlocks$1 as c, getContentBlocks$2 as d, POSTHOG_SDKS$1 as f, Program as i, getKindMeta as l, runWizard as n, DISPLAY_NAME as o, STRIPE_SDKS as p, PROGRAM_REGISTRY as r, SOURCE_MAPS_CONTEXT_KEYS as s, runWizardCI as t, fetchHealthIssues as u };
3270
3426
 
3271
3427
  //# sourceMappingURL=bin.js.map