@posthog/wizard 2.36.0 → 2.37.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 (63) hide show
  1. package/README.md +6 -3
  2. package/dist/{add-mcp-server-to-clients-D5e3JbUC.js → add-mcp-server-to-clients-CNn9br9l.js} +4 -4
  3. package/dist/{add-mcp-server-to-clients-D5e3JbUC.js.map → add-mcp-server-to-clients-CNn9br9l.js.map} +1 -1
  4. package/dist/{agent-interface-CPn9pZ8j.js → agent-interface-D8jnkEnB.js} +71 -8
  5. package/dist/agent-interface-D8jnkEnB.js.map +1 -0
  6. package/dist/{agent-runner-Cic1uZZ8.js → agent-runner-BxIYcxmA.js} +9 -71
  7. package/dist/agent-runner-BxIYcxmA.js.map +1 -0
  8. package/dist/{analytics-Be_wRgxD.js → analytics-Du8Z_3oX.js} +2 -2
  9. package/dist/{analytics-Be_wRgxD.js.map → analytics-Du8Z_3oX.js.map} +1 -1
  10. package/dist/{api-C_R_ybiA.js → api-BqKMQVhj.js} +3 -3
  11. package/dist/{api-C_R_ybiA.js.map → api-BqKMQVhj.js.map} +1 -1
  12. package/dist/bin.js +54 -40
  13. package/dist/bin.js.map +1 -1
  14. package/dist/{ci-install-B0BHTkGI.js → ci-install-UlWb3u5t.js} +4 -4
  15. package/dist/{ci-install-B0BHTkGI.js.map → ci-install-UlWb3u5t.js.map} +1 -1
  16. package/dist/{debug-DJS2KPGb.js → debug-B4AH8Ahp.js} +1 -1
  17. package/dist/{debug-BpWrz3hX.js → debug-CZwmzyDx.js} +2 -2
  18. package/dist/{debug-BpWrz3hX.js.map → debug-CZwmzyDx.js.map} +1 -1
  19. package/dist/{environment-Dc6VTWyK.js → environment-BRXwshJO.js} +3 -3
  20. package/dist/{environment-Dc6VTWyK.js.map → environment-BRXwshJO.js.map} +1 -1
  21. package/dist/{file-utils-Buj9-umf.js → file-utils-D6CWLaOm.js} +2 -2
  22. package/dist/{file-utils-Buj9-umf.js.map → file-utils-D6CWLaOm.js.map} +1 -1
  23. package/dist/{headless-ui-BplqZRcO.js → headless-ui-DvkogF0b.js} +2 -2
  24. package/dist/{headless-ui-BplqZRcO.js.map → headless-ui-DvkogF0b.js.map} +1 -1
  25. package/dist/{host-resolution-BD6TcZG0.js → host-resolution-DrOzdKdY.js} +3 -3
  26. package/dist/{host-resolution-BD6TcZG0.js.map → host-resolution-DrOzdKdY.js.map} +1 -1
  27. package/dist/{interactive-BspTioP_.js → interactive-CXL8oJwb.js} +2 -2
  28. package/dist/{interactive-BspTioP_.js.map → interactive-CXL8oJwb.js.map} +1 -1
  29. package/dist/{mcp-prompt-streaming-BCNzyL12.js → mcp-prompt-streaming-Dumivcgi.js} +4 -4
  30. package/dist/{mcp-prompt-streaming-BCNzyL12.js.map → mcp-prompt-streaming-Dumivcgi.js.map} +1 -1
  31. package/dist/{non-interactive-CFikUAzO.js → non-interactive-BI5b25U7.js} +2 -2
  32. package/dist/{non-interactive-CFikUAzO.js.map → non-interactive-BI5b25U7.js.map} +1 -1
  33. package/dist/{package-manager-L7gsAbE0.js → package-manager-9nhQBKAy.js} +2 -2
  34. package/dist/{package-manager-L7gsAbE0.js.map → package-manager-9nhQBKAy.js.map} +1 -1
  35. package/dist/{playground-Bl2iPxdt.js → playground-DDYYs2ub.js} +5 -5
  36. package/dist/{playground-Bl2iPxdt.js.map → playground-DDYYs2ub.js.map} +1 -1
  37. package/dist/{posthog-integration-B6pTHVcn.js → posthog-integration-Cx4RvC7E.js} +13 -13
  38. package/dist/{posthog-integration-B6pTHVcn.js.map → posthog-integration-Cx4RvC7E.js.map} +1 -1
  39. package/dist/{provisioning-C9ts56R5.js → provisioning-PosLaOt4.js} +4 -4
  40. package/dist/{provisioning-C9ts56R5.js.map → provisioning-PosLaOt4.js.map} +1 -1
  41. package/dist/{registry-DFazVUSE.js → registry-B43CNAAx.js} +4 -4
  42. package/dist/{registry-DFazVUSE.js.map → registry-B43CNAAx.js.map} +1 -1
  43. package/dist/{setup-utils-BxdW2R0r.js → setup-utils-CR8X8Fmf.js} +19 -11
  44. package/dist/setup-utils-CR8X8Fmf.js.map +1 -0
  45. package/dist/{start-tui-oGWfxdTd.js → start-tui-DeewAqJg.js} +15 -15
  46. package/dist/{start-tui-oGWfxdTd.js.map → start-tui-DeewAqJg.js.map} +1 -1
  47. package/dist/{steps-O0v5UU1G.js → steps-CPvI-2Ms.js} +7 -7
  48. package/dist/{steps-O0v5UU1G.js.map → steps-CPvI-2Ms.js.map} +1 -1
  49. package/dist/{store-Di9OvMql.js → store-0uzey9Am.js} +3 -3
  50. package/dist/{store-Di9OvMql.js.map → store-0uzey9Am.js.map} +1 -1
  51. package/dist/{telemetry-D5WQ4-Ic.js → telemetry-DJNpvkYP.js} +3 -3
  52. package/dist/{telemetry-D5WQ4-Ic.js.map → telemetry-DJNpvkYP.js.map} +1 -1
  53. package/dist/{terminal-Bd-k7pCi.js → terminal-Bd6q58zn.js} +10 -10
  54. package/dist/{terminal-Bd-k7pCi.js.map → terminal-Bd6q58zn.js.map} +1 -1
  55. package/dist/{urls-DpTCPWLD.js → urls-B1a2v93j.js} +2 -2
  56. package/dist/{urls-DpTCPWLD.js.map → urls-B1a2v93j.js.map} +1 -1
  57. package/dist/{wizard-abort-t41wO4Bh.js → wizard-abort-BG8VNOI9.js} +3 -3
  58. package/dist/{wizard-abort-t41wO4Bh.js.map → wizard-abort-BG8VNOI9.js.map} +1 -1
  59. package/dist/{wizard-abort-C1t9M-JN.js → wizard-abort-DyAGpw-u.js} +1 -1
  60. package/package.json +1 -1
  61. package/dist/agent-interface-CPn9pZ8j.js.map +0 -1
  62. package/dist/agent-runner-Cic1uZZ8.js.map +0 -1
  63. package/dist/setup-utils-BxdW2R0r.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"api-C_R_ybiA.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-BqKMQVhj.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,19 +1,19 @@
1
1
  #!/usr/bin/env node
2
- import { $ as getSkillsBaseUrl, I as POSTHOG_DOCS_URL, Z as WIZARD_USER_AGENT, a as getLogFilePath, et as VERSION, h as LoggingUI, j as Integration, m as setUI, p as getUI, r as debug, s as logToFile } from "./debug-BpWrz3hX.js";
3
- import { t as analytics } from "./analytics-Be_wRgxD.js";
4
- import { r as setEntryCommand } from "./telemetry-D5WQ4-Ic.js";
5
- import { n as isUsingTypeScript } from "./setup-utils-BxdW2R0r.js";
6
- import { o as getUiHostFromHost } from "./urls-DpTCPWLD.js";
7
- import { t as HostResolution } from "./host-resolution-BD6TcZG0.js";
8
- import { o as handleApiError } from "./api-C_R_ybiA.js";
2
+ import { $ as getSkillsBaseUrl, I as POSTHOG_DOCS_URL, Z as WIZARD_USER_AGENT, a as getLogFilePath, et as VERSION, h as LoggingUI, j as Integration, m as setUI, p as getUI, r as debug, s as logToFile } from "./debug-CZwmzyDx.js";
3
+ import { t as analytics } from "./analytics-Du8Z_3oX.js";
4
+ import { r as setEntryCommand } from "./telemetry-DJNpvkYP.js";
5
+ import { n as isUsingTypeScript } from "./setup-utils-CR8X8Fmf.js";
6
+ import { o as getUiHostFromHost } from "./urls-B1a2v93j.js";
7
+ import { t as HostResolution } from "./host-resolution-DrOzdKdY.js";
8
+ import { o as handleApiError } from "./api-BqKMQVhj.js";
9
9
  import "./wizard-session-CqihOtk3.js";
10
- import { r as runCleanups } from "./wizard-abort-t41wO4Bh.js";
11
- import { n as isNonInteractiveEnvironment } from "./environment-Dc6VTWyK.js";
12
- import { D as AUDIT_CHECKS_KEY, E as AUDIT_CHECKS_FILE, O as AUDIT_REPORT_FILE, f as AgentSignals, l as recoverOrphanedSettingsBackups, v as SETUP_REPORT_FILE, x as fetchSkillMenu, y as WIZARD_TOOL_NAMES } from "./agent-interface-CPn9pZ8j.js";
13
- import { n as runAgent, r as authenticate } from "./agent-runner-Cic1uZZ8.js";
14
- import { i as SPINNER_MESSAGE, t as FRAMEWORK_REGISTRY } from "./registry-DFazVUSE.js";
15
- import { _ as gatherFrameworkContext, a as LINE_CHART_BLOCK, b as parseRequirementsTxt, g as detectProjectsWithAgent, h as HEALTH_CHECK_STEP, i as FUNNEL_BLOCK, m as Icons, n as integrationRunStep, o as PRODUCT_SUITE_BLOCK, p as Colors, r as posthogIntegrationConfig, s as StatusPeekTrigger, u as isClearBlock, v as parsePipfile, y as parsePyprojectToml } from "./posthog-integration-B6pTHVcn.js";
16
- import { n as safeReadFile, r as walkProjectFiles, t as IGNORED_DIRS } from "./file-utils-Buj9-umf.js";
10
+ import { r as runCleanups } from "./wizard-abort-BG8VNOI9.js";
11
+ import { n as isNonInteractiveEnvironment } from "./environment-BRXwshJO.js";
12
+ import { D as AUDIT_CHECKS_FILE, O as AUDIT_CHECKS_KEY, f as AgentSignals, k as AUDIT_REPORT_FILE, l as recoverOrphanedSettingsBackups, v as SETUP_REPORT_FILE, x as fetchSkillMenu, y as WIZARD_TOOL_NAMES } from "./agent-interface-D8jnkEnB.js";
13
+ import { n as runAgent, r as authenticate } from "./agent-runner-BxIYcxmA.js";
14
+ import { i as SPINNER_MESSAGE, t as FRAMEWORK_REGISTRY } from "./registry-B43CNAAx.js";
15
+ import { _ as gatherFrameworkContext, a as LINE_CHART_BLOCK, b as parseRequirementsTxt, g as detectProjectsWithAgent, h as HEALTH_CHECK_STEP, i as FUNNEL_BLOCK, m as Icons, n as integrationRunStep, o as PRODUCT_SUITE_BLOCK, p as Colors, r as posthogIntegrationConfig, s as StatusPeekTrigger, u as isClearBlock, v as parsePipfile, y as parsePyprojectToml } from "./posthog-integration-Cx4RvC7E.js";
16
+ import { n as safeReadFile, r as walkProjectFiles, t as IGNORED_DIRS } from "./file-utils-D6CWLaOm.js";
17
17
  import { n as readApiKeyFromEnv } from "./env-api-key-Db-mNPK2.js";
18
18
  import { satisfies } from "semver";
19
19
  import yargs from "yargs";
@@ -235,7 +235,7 @@ function runProvision(argv) {
235
235
  }
236
236
  async function provision({ email, region, name, baseUrl, jsonMode }) {
237
237
  try {
238
- const { provisionNewAccount } = await import("./provisioning-C9ts56R5.js").then((n) => n.n);
238
+ const { provisionNewAccount } = await import("./provisioning-PosLaOt4.js").then((n) => n.n);
239
239
  if (!jsonMode) getUI().log.info(`Provisioning account for ${email} in ${region}...`);
240
240
  emitResult(await provisionNewAccount(email, name, region, { baseUrl }), jsonMode);
241
241
  process.exit(0);
@@ -300,22 +300,22 @@ const basicIntegrationCommand = {
300
300
  setEntryCommand("integrate");
301
301
  (async () => {
302
302
  if (isHeadless(argv)) {
303
- const { runHeadlessInstall } = await import("./ci-install-B0BHTkGI.js");
303
+ const { runHeadlessInstall } = await import("./ci-install-UlWb3u5t.js");
304
304
  return runHeadlessInstall(argv);
305
305
  }
306
306
  if (argv.ci) {
307
- const { runCIInstall } = await import("./ci-install-B0BHTkGI.js");
307
+ const { runCIInstall } = await import("./ci-install-UlWb3u5t.js");
308
308
  return runCIInstall(argv);
309
309
  }
310
310
  if (isNonInteractiveEnvironment()) {
311
- const { failNonInteractive } = await import("./non-interactive-CFikUAzO.js");
311
+ const { failNonInteractive } = await import("./non-interactive-BI5b25U7.js");
312
312
  return failNonInteractive();
313
313
  }
314
314
  if (argv.playground) {
315
- const { runPlayground } = await import("./playground-Bl2iPxdt.js");
315
+ const { runPlayground } = await import("./playground-DDYYs2ub.js");
316
316
  return runPlayground();
317
317
  }
318
- const { runInteractive } = await import("./interactive-BspTioP_.js");
318
+ const { runInteractive } = await import("./interactive-CXL8oJwb.js");
319
319
  runInteractive(argv);
320
320
  })();
321
321
  }
@@ -3596,11 +3596,12 @@ tasks, in this order:
3596
3596
  1. Check Self-driving access
3597
3597
  2. Read project and current Self-driving state
3598
3598
  3. Connect GitHub (required)
3599
+ 3b. Enable products (replay, error tracking, support)
3599
3600
  4. Enable signal sources
3600
3601
  5. Offer issue-tracker integrations
3601
3602
  6. Configure the scout troop
3602
- 7. Design custom scouts
3603
- 8. Write report and hand off
3603
+ 6b. Design custom scouts
3604
+ 7. Write report and hand off
3604
3605
  Drive the list with TaskUpdate — mark a task in_progress when you start
3605
3606
  it and completed when done. If a step turns out to be a no-op (e.g.
3606
3607
  GitHub is already connected), still mark its task completed.
@@ -3648,6 +3649,19 @@ STEP 3 — Connect GitHub. REQUIRED. (skill: "Connect GitHub")
3648
3649
  ${AgentSignals.ABORT} github connection declined
3649
3650
  and halt — never finish setup without GitHub.
3650
3651
 
3652
+ STEP 3b — Enable products. (skill: "Enable products")
3653
+ Turn ON the PostHog products Signals reads from — Session Replay,
3654
+ Error Tracking, and Support — so the sources you enable next have data
3655
+ to read. These are server-side enables with conservative defaults
3656
+ (owned by the server, not you). The project-state block above covers
3657
+ only Session Replay and Error Tracking, so you can skip those if they
3658
+ are already ON; it does not show Support, but every enable is idempotent
3659
+ so enabling any of them again is safe regardless. For a web app, also
3660
+ make sure this repo's posthog-js
3661
+ init doesn't disable them; for a pure backend or mobile app the server
3662
+ flip is inert, so just record that for the report and move on. The skill
3663
+ names the exact tool and the per-platform detail.
3664
+
3651
3665
  STEP 4 — Enable signal sources. (skill: "Enable sources")
3652
3666
  Enable the sources that match what this product actually uses, per
3653
3667
  the skill. Never enable a source for a tool the user hasn't
@@ -3667,7 +3681,7 @@ STEP 6 — Configure the scout troop. (skill: "Scouts")
3667
3681
  scout plus the one or two specialists for the products this project
3668
3682
  uses most — and disable the rest, per the skill.
3669
3683
 
3670
- STEP 7 — Design custom scouts for this product. (skill: "Custom scouts")
3684
+ STEP 6b — Design custom scouts for this product. (skill: "Custom scouts")
3671
3685
  You are the only actor that has read this repo — turn that into
3672
3686
  coverage per the skill: a real gap analysis of the project's
3673
3687
  watchable surfaces against what the built-in troop already covers,
@@ -3681,7 +3695,7 @@ STEP 7 — Design custom scouts for this product. (skill: "Custom scouts")
3681
3695
  no gap at all) is a valid outcome, not an abort. Mark the task
3682
3696
  completed either way.
3683
3697
 
3684
- STEP 8 — Write the report and hand off. (skill: "Report")
3698
+ STEP 7 — Write the report and hand off. (skill: "Report")
3685
3699
  Write the report per the skill, including follow-ups for anything
3686
3700
  deferred. Tell the user findings will start appearing in their inbox
3687
3701
  at ${inboxUrl} within about 30 minutes.`;
@@ -4026,7 +4040,7 @@ function runMcpAdd(argv) {
4026
4040
  const debug = argv.debug;
4027
4041
  const localMcp = argv.local;
4028
4042
  try {
4029
- const { startTUI } = await import("./start-tui-oGWfxdTd.js");
4043
+ const { startTUI } = await import("./start-tui-DeewAqJg.js");
4030
4044
  const { buildSession } = await import("./wizard-session-xzqycI7i.js");
4031
4045
  const tui = startTUI(VERSION, Program.McpAdd);
4032
4046
  tui.store.session = buildSession({
@@ -4039,7 +4053,7 @@ function runMcpAdd(argv) {
4039
4053
  } catch (error) {
4040
4054
  if (!isTUIUnavailable(error)) throw error;
4041
4055
  setUI(new LoggingUI());
4042
- const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-D5e3JbUC.js").then((n) => n.r);
4056
+ const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-CNn9br9l.js").then((n) => n.r);
4043
4057
  await addMCPServerToClientsStep({
4044
4058
  local: localMcp,
4045
4059
  features,
@@ -4078,7 +4092,7 @@ function runMcpRemove(argv) {
4078
4092
  const debug = argv.debug;
4079
4093
  const localMcp = argv.local;
4080
4094
  try {
4081
- const { startTUI } = await import("./start-tui-oGWfxdTd.js");
4095
+ const { startTUI } = await import("./start-tui-DeewAqJg.js");
4082
4096
  const { buildSession } = await import("./wizard-session-xzqycI7i.js");
4083
4097
  const tui = startTUI(VERSION, Program.McpRemove);
4084
4098
  tui.store.session = buildSession({
@@ -4088,7 +4102,7 @@ function runMcpRemove(argv) {
4088
4102
  });
4089
4103
  } catch {
4090
4104
  setUI(new LoggingUI());
4091
- const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-D5e3JbUC.js").then((n) => n.r);
4105
+ const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-CNn9br9l.js").then((n) => n.r);
4092
4106
  await removeMCPServerFromClientsStep({ local: localMcp });
4093
4107
  }
4094
4108
  })();
@@ -4110,7 +4124,7 @@ function runMcpTutorial(argv) {
4110
4124
  const debug = argv.debug;
4111
4125
  const localMcp = argv.local;
4112
4126
  try {
4113
- const { startTUI } = await import("./start-tui-oGWfxdTd.js");
4127
+ const { startTUI } = await import("./start-tui-DeewAqJg.js");
4114
4128
  const { buildSession } = await import("./wizard-session-xzqycI7i.js");
4115
4129
  const tui = startTUI(VERSION, Program.McpTutorial);
4116
4130
  tui.store.session = buildSession({
@@ -4191,7 +4205,7 @@ function runWizard(config, options) {
4191
4205
  (async () => {
4192
4206
  try {
4193
4207
  const installDir = options.installDir || process.cwd();
4194
- const { startTUI } = await import("./start-tui-oGWfxdTd.js");
4208
+ const { startTUI } = await import("./start-tui-DeewAqJg.js");
4195
4209
  const { buildSession, RunPhase } = await import("./wizard-session-xzqycI7i.js");
4196
4210
  const { TaskStreamPush } = await import("./task-stream-DkbGqxZv.js");
4197
4211
  const { PostHogDestination } = await import("./posthog-BrLFkaji.js");
@@ -4255,7 +4269,7 @@ function runWizard(config, options) {
4255
4269
  if (shown(step)) await advanceStep(step, activeTui.store, config);
4256
4270
  }
4257
4271
  else if (skipAgent) {
4258
- const { getOrAskForProjectData } = await import("./setup-utils-BxdW2R0r.js").then((n) => n.r);
4272
+ const { getOrAskForProjectData } = await import("./setup-utils-CR8X8Fmf.js").then((n) => n.r);
4259
4273
  const { projectApiKey, host, accessToken, projectId } = await getOrAskForProjectData({
4260
4274
  signup: session.signup,
4261
4275
  ci: session.ci,
@@ -4358,10 +4372,10 @@ function runNonInteractive(config, options, mode) {
4358
4372
  (async () => {
4359
4373
  const path = await import("path");
4360
4374
  const { buildSession, RunPhase, OutroKind } = await import("./wizard-session-xzqycI7i.js");
4361
- const { readEnvironment } = await import("./environment-Dc6VTWyK.js").then((n) => n.t);
4375
+ const { readEnvironment } = await import("./environment-BRXwshJO.js").then((n) => n.t);
4362
4376
  const { readApiKeyFromEnv } = await import("./env-api-key-Db-mNPK2.js").then((n) => n.t);
4363
- const { configureLogFileFromEnvironment, logToFile } = await import("./debug-DJS2KPGb.js");
4364
- const { wizardAbort, WizardError } = await import("./wizard-abort-C1t9M-JN.js");
4377
+ const { configureLogFileFromEnvironment, logToFile } = await import("./debug-B4AH8Ahp.js");
4378
+ const { wizardAbort, WizardError } = await import("./wizard-abort-DyAGpw-u.js");
4365
4379
  configureLogFileFromEnvironment();
4366
4380
  const env = readEnvironment();
4367
4381
  const apiKey = options.apiKey ?? readApiKeyFromEnv() ?? void 0;
@@ -4389,8 +4403,8 @@ function runNonInteractive(config, options, mode) {
4389
4403
  let store = null;
4390
4404
  let taskStream = null;
4391
4405
  if (mode === "headless") {
4392
- const { WizardStore } = await import("./store-Di9OvMql.js").then((n) => n.n);
4393
- const { HeadlessUI } = await import("./headless-ui-BplqZRcO.js");
4406
+ const { WizardStore } = await import("./store-0uzey9Am.js").then((n) => n.n);
4407
+ const { HeadlessUI } = await import("./headless-ui-DvkogF0b.js");
4394
4408
  const { TaskStreamPush, PostHogDestination } = await import("./task-stream-DkbGqxZv.js");
4395
4409
  store = new WizardStore(config.id);
4396
4410
  store.session = session;
@@ -4446,7 +4460,7 @@ function runNonInteractive(config, options, mode) {
4446
4460
  });
4447
4461
  }
4448
4462
  }
4449
- const { runAgent } = await import("./agent-runner-Cic1uZZ8.js").then((n) => n.t);
4463
+ const { runAgent } = await import("./agent-runner-BxIYcxmA.js").then((n) => n.t);
4450
4464
  await runAgent(config, session);
4451
4465
  await settleStream(RunPhase.Completed);
4452
4466
  } catch (error) {
@@ -5373,7 +5387,7 @@ async function runDoctorCI(options) {
5373
5387
  getUI().intro("Welcome to the PostHog setup wizard");
5374
5388
  getUI().log.info("Running posthog-doctor in CI mode");
5375
5389
  try {
5376
- const { getOrAskForProjectData } = await import("./setup-utils-BxdW2R0r.js").then((n) => n.r);
5390
+ const { getOrAskForProjectData } = await import("./setup-utils-CR8X8Fmf.js").then((n) => n.r);
5377
5391
  const { host, accessToken, projectId } = await getOrAskForProjectData({
5378
5392
  signup: false,
5379
5393
  ci: true,
@@ -5391,7 +5405,7 @@ async function runDoctorCI(options) {
5391
5405
  for (const issue of sorted) getUI().log.info(` • [${issue.severity}] ${getKindMeta(issue.kind).title}`);
5392
5406
  process.exit(1);
5393
5407
  } catch (error) {
5394
- const { ApiError } = await import("./api-C_R_ybiA.js").then((n) => n.n);
5408
+ const { ApiError } = await import("./api-BqKMQVhj.js").then((n) => n.n);
5395
5409
  const message = error instanceof ApiError && error.statusCode === 401 ? "Your PostHog API key is invalid or expired." : error instanceof Error ? error.message : String(error);
5396
5410
  getUI().log.error(`Doctor failed: ${message}`);
5397
5411
  process.exit(1);
@@ -5473,7 +5487,7 @@ function runSlackConnect(argv) {
5473
5487
  (async () => {
5474
5488
  const debug = argv.debug;
5475
5489
  try {
5476
- const { startTUI } = await import("./start-tui-oGWfxdTd.js");
5490
+ const { startTUI } = await import("./start-tui-DeewAqJg.js");
5477
5491
  const { buildSession } = await import("./wizard-session-xzqycI7i.js");
5478
5492
  const tui = startTUI(VERSION, Program.SlackConnect);
5479
5493
  tui.store.session = buildSession({