@posthog/wizard 2.24.1 → 2.25.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 (64) hide show
  1. package/dist/{AiOptInRequiredScreen-_33FOcVo.js → AiOptInRequiredScreen-C-D9tN6r.js} +20 -16
  2. package/dist/AiOptInRequiredScreen-C-D9tN6r.js.map +1 -0
  3. package/dist/{add-mcp-server-to-clients-CfwEQT_z.js → add-mcp-server-to-clients-t0xe8gn1.js} +4 -4
  4. package/dist/{add-mcp-server-to-clients-CfwEQT_z.js.map → add-mcp-server-to-clients-t0xe8gn1.js.map} +1 -1
  5. package/dist/{agent-interface-D1vtN6Wn.js → agent-interface-BsuUUPle.js} +403 -40
  6. package/dist/agent-interface-BsuUUPle.js.map +1 -0
  7. package/dist/{agent-runner-CBbkS0Ro.js → agent-runner-L_-kJ3y3.js} +624 -17
  8. package/dist/agent-runner-L_-kJ3y3.js.map +1 -0
  9. package/dist/{analytics-CUr82BDl.js → analytics-CDOujOSQ.js} +51 -17
  10. package/dist/analytics-CDOujOSQ.js.map +1 -0
  11. package/dist/{api-CI3Z74NG.js → api-DNS-L-1U.js} +3 -3
  12. package/dist/{api-CI3Z74NG.js.map → api-DNS-L-1U.js.map} +1 -1
  13. package/dist/bin.js +279 -33
  14. package/dist/bin.js.map +1 -1
  15. package/dist/{ci-install-D_kxNmbJ.js → ci-install-_9A7tL36.js} +4 -4
  16. package/dist/{ci-install-D_kxNmbJ.js.map → ci-install-_9A7tL36.js.map} +1 -1
  17. package/dist/{debug-DxA_f5QT.js → debug-BwC7UkGH.js} +16 -8
  18. package/dist/debug-BwC7UkGH.js.map +1 -0
  19. package/dist/{debug-zMvpNYb2.js → debug-CZQcMAJT.js} +1 -1
  20. package/dist/{environment-CyS37cmM.js → environment-DQPoj9sU.js} +3 -3
  21. package/dist/{environment-CyS37cmM.js.map → environment-DQPoj9sU.js.map} +1 -1
  22. package/dist/{interactive-CG6FFqSw.js → interactive-DT5dLd7N.js} +2 -2
  23. package/dist/{interactive-CG6FFqSw.js.map → interactive-DT5dLd7N.js.map} +1 -1
  24. package/dist/{mcp-prompt-streaming-DQz4FSb1.js → mcp-prompt-streaming-CBMr458Q.js} +7 -26
  25. package/dist/mcp-prompt-streaming-CBMr458Q.js.map +1 -0
  26. package/dist/{non-interactive-DWtHX3ZR.js → non-interactive-csP4yGdA.js} +2 -2
  27. package/dist/{non-interactive-DWtHX3ZR.js.map → non-interactive-csP4yGdA.js.map} +1 -1
  28. package/dist/{package-manager-BWUS4CP0.js → package-manager-CB4c2euf.js} +2 -2
  29. package/dist/{package-manager-BWUS4CP0.js.map → package-manager-CB4c2euf.js.map} +1 -1
  30. package/dist/{playground-D7AhMMF5.js → playground-C-lpKoKC.js} +5 -5
  31. package/dist/{playground-D7AhMMF5.js.map → playground-C-lpKoKC.js.map} +1 -1
  32. package/dist/{posthog-integration-DexZ2uHU.js → posthog-integration-BL8-vC0V.js} +11 -11
  33. package/dist/{posthog-integration-DexZ2uHU.js.map → posthog-integration-BL8-vC0V.js.map} +1 -1
  34. package/dist/{provisioning-9c-AQbsa.js → provisioning-DLOiFSM9.js} +3 -3
  35. package/dist/{provisioning-9c-AQbsa.js.map → provisioning-DLOiFSM9.js.map} +1 -1
  36. package/dist/{registry-CO7JVZyE.js → registry-BbRzCV5l.js} +4 -4
  37. package/dist/{registry-CO7JVZyE.js.map → registry-BbRzCV5l.js.map} +1 -1
  38. package/dist/{setup-utils-0U-_Md2G.js → setup-utils-D87CyNkw.js} +8 -8
  39. package/dist/{setup-utils-0U-_Md2G.js.map → setup-utils-D87CyNkw.js.map} +1 -1
  40. package/dist/smoke-test.sh +36 -1
  41. package/dist/{start-tui-WNb3ET14.js → start-tui-DnAG57vY.js} +13 -13
  42. package/dist/{start-tui-WNb3ET14.js.map → start-tui-DnAG57vY.js.map} +1 -1
  43. package/dist/{steps-BAUXDCC4.js → steps-JaxH6u0f.js} +6 -6
  44. package/dist/{steps-BAUXDCC4.js.map → steps-JaxH6u0f.js.map} +1 -1
  45. package/dist/{task-stream-CZawuzlz.js → task-stream-BQNSp0qR.js} +4 -3
  46. package/dist/task-stream-BQNSp0qR.js.map +1 -0
  47. package/dist/{telemetry-ycqCpNPr.js → telemetry-DL28cCwY.js} +3 -3
  48. package/dist/{telemetry-ycqCpNPr.js.map → telemetry-DL28cCwY.js.map} +1 -1
  49. package/dist/{urls-C8aJWvgh.js → urls-vkJ5c0ix.js} +2 -2
  50. package/dist/{urls-C8aJWvgh.js.map → urls-vkJ5c0ix.js.map} +1 -1
  51. package/dist/{wizard-abort-DWXyJdws.js → wizard-abort-BRXKRL4F.js} +1 -1
  52. package/dist/{wizard-abort-C6gRLxUE.js → wizard-abort-CLGgMAEe.js} +3 -3
  53. package/dist/{wizard-abort-C6gRLxUE.js.map → wizard-abort-CLGgMAEe.js.map} +1 -1
  54. package/dist/{wizard-ui-YdGFRyu_.js → wizard-ui-WZ48rUgr.js} +2 -1
  55. package/dist/wizard-ui-WZ48rUgr.js.map +1 -0
  56. package/package.json +1 -1
  57. package/dist/AiOptInRequiredScreen-_33FOcVo.js.map +0 -1
  58. package/dist/agent-interface-D1vtN6Wn.js.map +0 -1
  59. package/dist/agent-runner-CBbkS0Ro.js.map +0 -1
  60. package/dist/analytics-CUr82BDl.js.map +0 -1
  61. package/dist/debug-DxA_f5QT.js.map +0 -1
  62. package/dist/mcp-prompt-streaming-DQz4FSb1.js.map +0 -1
  63. package/dist/task-stream-CZawuzlz.js.map +0 -1
  64. package/dist/wizard-ui-YdGFRyu_.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"api-CI3Z74NG.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\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-DNS-L-1U.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\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,16 +1,16 @@
1
1
  #!/usr/bin/env node
2
- import { $ as VERSION, P as POSTHOG_DOCS_URL, Q as getSkillsBaseUrl, Y as WIZARD_USER_AGENT, _ as SIGNUP_WIZARD_READINESS_CONFIG, a as getLogFilePath, h as LoggingUI, m as setUI, p as getUI, s as logToFile, v as evaluateWizardReadiness, y as getBlockingServiceKeys } from "./debug-DxA_f5QT.js";
3
- import { t as analytics } from "./analytics-CUr82BDl.js";
4
- import { r as setEntryCommand } from "./telemetry-ycqCpNPr.js";
5
- import { n as isUsingTypeScript } from "./setup-utils-0U-_Md2G.js";
6
- import { a as getUiHostFromHost, n as getCloudUrlFromRegion } from "./urls-C8aJWvgh.js";
7
- import { o as handleApiError } from "./api-CI3Z74NG.js";
2
+ import { $ as getSkillsBaseUrl, P as POSTHOG_DOCS_URL, X as WIZARD_USER_AGENT, _ as SIGNUP_WIZARD_READINESS_CONFIG, a as getLogFilePath, et as VERSION, h as LoggingUI, m as setUI, p as getUI, r as debug, s as logToFile, v as evaluateWizardReadiness, y as getBlockingServiceKeys } from "./debug-BwC7UkGH.js";
3
+ import { t as analytics } from "./analytics-CDOujOSQ.js";
4
+ import { r as setEntryCommand } from "./telemetry-DL28cCwY.js";
5
+ import { n as isUsingTypeScript } from "./setup-utils-D87CyNkw.js";
6
+ import { a as getUiHostFromHost, n as getCloudUrlFromRegion } from "./urls-vkJ5c0ix.js";
7
+ import { o as handleApiError } from "./api-DNS-L-1U.js";
8
8
  import "./wizard-session-G3VWD6hv.js";
9
- import { r as runCleanups } from "./wizard-abort-C6gRLxUE.js";
10
- import { n as isNonInteractiveEnvironment } from "./environment-CyS37cmM.js";
11
- import { _ as AUDIT_CHECKS_KEY, f as WIZARD_TOOL_NAMES, g as AUDIT_CHECKS_FILE, l as AgentSignals, m as fetchSkillMenu, s as recoverOrphanedSettingsBackups, v as AUDIT_REPORT_FILE } from "./agent-interface-D1vtN6Wn.js";
12
- import { i as SPINNER_MESSAGE } from "./registry-CO7JVZyE.js";
13
- 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, p as Icons, r as FUNNEL_BLOCK } from "./posthog-integration-DexZ2uHU.js";
9
+ import { r as runCleanups } from "./wizard-abort-CLGgMAEe.js";
10
+ import { n as isNonInteractiveEnvironment } from "./environment-DQPoj9sU.js";
11
+ import { S as AUDIT_REPORT_FILE, b as AUDIT_CHECKS_FILE, c as recoverOrphanedSettingsBackups, h as fetchSkillMenu, p as WIZARD_TOOL_NAMES, u as AgentSignals, x as AUDIT_CHECKS_KEY } from "./agent-interface-BsuUUPle.js";
12
+ import { i as SPINNER_MESSAGE } from "./registry-BbRzCV5l.js";
13
+ 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, p as Icons, r as FUNNEL_BLOCK } from "./posthog-integration-BL8-vC0V.js";
14
14
  import { t as IGNORED_DIRS } from "./file-utils-VAXoyXVA.js";
15
15
  import { n as readApiKeyFromEnv } from "./env-api-key-MlzJYAvt.js";
16
16
  import { satisfies } from "semver";
@@ -18,11 +18,16 @@ import yargs from "yargs";
18
18
  import { hideBin } from "yargs/helpers";
19
19
  import fs, { existsSync, readFileSync, readdirSync, statSync } from "fs";
20
20
  import path, { join, relative } from "path";
21
+ import * as os from "node:os";
22
+ import * as path$1 from "node:path";
23
+ import { spawnSync } from "node:child_process";
24
+ import * as fs$1 from "node:fs";
21
25
  import axios from "axios";
22
26
  import { z } from "zod";
23
27
  import { Box, Text, render, useInput } from "ink";
24
28
  import { createContext, createElement, useCallback, useContext, useEffect, useRef, useState } from "react";
25
29
  import { jsx, jsxs } from "react/jsx-runtime";
30
+ import * as readline from "node:readline/promises";
26
31
  //#region src/commands/command.ts
27
32
  /** Extract the bare command word(s) from a yargs name spec, dropping positionals and aliases' arg syntax. */
28
33
  function commandKeys(name) {
@@ -184,7 +189,7 @@ function runProvision(argv) {
184
189
  }
185
190
  async function provision({ email, region, name, jsonMode }) {
186
191
  try {
187
- const { provisionNewAccount } = await import("./provisioning-9c-AQbsa.js").then((n) => n.n);
192
+ const { provisionNewAccount } = await import("./provisioning-DLOiFSM9.js").then((n) => n.n);
188
193
  if (!jsonMode) getUI().log.info(`Provisioning account for ${email} in ${region}...`);
189
194
  emitResult(await provisionNewAccount(email, name, region), jsonMode);
190
195
  process.exit(0);
@@ -249,18 +254,18 @@ const basicIntegrationCommand = {
249
254
  setEntryCommand("integrate");
250
255
  (async () => {
251
256
  if (argv.ci) {
252
- const { runCIInstall } = await import("./ci-install-D_kxNmbJ.js");
257
+ const { runCIInstall } = await import("./ci-install-_9A7tL36.js");
253
258
  return runCIInstall(argv);
254
259
  }
255
260
  if (isNonInteractiveEnvironment()) {
256
- const { failNonInteractive } = await import("./non-interactive-DWtHX3ZR.js");
261
+ const { failNonInteractive } = await import("./non-interactive-csP4yGdA.js");
257
262
  return failNonInteractive();
258
263
  }
259
264
  if (argv.playground) {
260
- const { runPlayground } = await import("./playground-D7AhMMF5.js");
265
+ const { runPlayground } = await import("./playground-C-lpKoKC.js");
261
266
  return runPlayground();
262
267
  }
263
- const { runInteractive } = await import("./interactive-CG6FFqSw.js");
268
+ const { runInteractive } = await import("./interactive-DT5dLd7N.js");
264
269
  runInteractive(argv);
265
270
  })();
266
271
  }
@@ -2648,7 +2653,7 @@ function runMcpAdd(argv) {
2648
2653
  const debug = argv.debug;
2649
2654
  const localMcp = argv.local;
2650
2655
  try {
2651
- const { startTUI } = await import("./start-tui-WNb3ET14.js");
2656
+ const { startTUI } = await import("./start-tui-DnAG57vY.js");
2652
2657
  const { buildSession } = await import("./wizard-session-wPJtNl4c.js");
2653
2658
  const tui = startTUI(VERSION, Program.McpAdd);
2654
2659
  tui.store.session = buildSession({
@@ -2660,7 +2665,7 @@ function runMcpAdd(argv) {
2660
2665
  } catch (error) {
2661
2666
  if (!isTUIUnavailable(error)) throw error;
2662
2667
  setUI(new LoggingUI());
2663
- const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-CfwEQT_z.js").then((n) => n.r);
2668
+ const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-t0xe8gn1.js").then((n) => n.r);
2664
2669
  await addMCPServerToClientsStep({
2665
2670
  local: localMcp,
2666
2671
  features,
@@ -2699,7 +2704,7 @@ function runMcpRemove(argv) {
2699
2704
  const debug = argv.debug;
2700
2705
  const localMcp = argv.local;
2701
2706
  try {
2702
- const { startTUI } = await import("./start-tui-WNb3ET14.js");
2707
+ const { startTUI } = await import("./start-tui-DnAG57vY.js");
2703
2708
  const { buildSession } = await import("./wizard-session-wPJtNl4c.js");
2704
2709
  const tui = startTUI(VERSION, Program.McpRemove);
2705
2710
  tui.store.session = buildSession({
@@ -2708,7 +2713,7 @@ function runMcpRemove(argv) {
2708
2713
  });
2709
2714
  } catch {
2710
2715
  setUI(new LoggingUI());
2711
- const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-CfwEQT_z.js").then((n) => n.r);
2716
+ const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-t0xe8gn1.js").then((n) => n.r);
2712
2717
  await removeMCPServerFromClientsStep({ local: localMcp });
2713
2718
  }
2714
2719
  })();
@@ -2730,7 +2735,7 @@ function runMcpTutorial(argv) {
2730
2735
  const debug = argv.debug;
2731
2736
  const localMcp = argv.local;
2732
2737
  try {
2733
- const { startTUI } = await import("./start-tui-WNb3ET14.js");
2738
+ const { startTUI } = await import("./start-tui-DnAG57vY.js");
2734
2739
  const { buildSession } = await import("./wizard-session-wPJtNl4c.js");
2735
2740
  const tui = startTUI(VERSION, Program.McpTutorial);
2736
2741
  tui.store.session = buildSession({
@@ -2785,9 +2790,9 @@ function runWizard(config, options) {
2785
2790
  (async () => {
2786
2791
  try {
2787
2792
  const installDir = options.installDir || process.cwd();
2788
- const { startTUI } = await import("./start-tui-WNb3ET14.js");
2793
+ const { startTUI } = await import("./start-tui-DnAG57vY.js");
2789
2794
  const { buildSession, RunPhase } = await import("./wizard-session-wPJtNl4c.js");
2790
- const { TaskStreamPush } = await import("./task-stream-CZawuzlz.js");
2795
+ const { TaskStreamPush } = await import("./task-stream-BQNSp0qR.js");
2791
2796
  const { PostHogDestination } = await import("./posthog-Cr37rnla.js");
2792
2797
  tui = startTUI(WIZARD_VERSION, config.id);
2793
2798
  const activeTui = tui;
@@ -2841,7 +2846,7 @@ function runWizard(config, options) {
2841
2846
  await activeTui.store.getGate("health-check");
2842
2847
  const skipAgent = config.run == null;
2843
2848
  if (skipAgent) {
2844
- const { getOrAskForProjectData } = await import("./setup-utils-0U-_Md2G.js").then((n) => n.r);
2849
+ const { getOrAskForProjectData } = await import("./setup-utils-D87CyNkw.js").then((n) => n.r);
2845
2850
  const { projectApiKey, host, accessToken, projectId } = await getOrAskForProjectData({
2846
2851
  signup: session.signup,
2847
2852
  ci: session.ci,
@@ -2856,7 +2861,7 @@ function runWizard(config, options) {
2856
2861
  projectId
2857
2862
  });
2858
2863
  } else {
2859
- const { runAgent } = await import("./agent-runner-CBbkS0Ro.js");
2864
+ const { runAgent } = await import("./agent-runner-L_-kJ3y3.js");
2860
2865
  await runAgent(config, activeTui.store.session);
2861
2866
  }
2862
2867
  const isDone = () => skipAgent ? activeTui.store.session.outroDismissed : activeTui.store.session.skillsComplete;
@@ -2933,10 +2938,10 @@ function runWizardCI(config, options) {
2933
2938
  (async () => {
2934
2939
  const path = await import("path");
2935
2940
  const { buildSession } = await import("./wizard-session-wPJtNl4c.js");
2936
- const { readEnvironment } = await import("./environment-CyS37cmM.js").then((n) => n.t);
2941
+ const { readEnvironment } = await import("./environment-DQPoj9sU.js").then((n) => n.t);
2937
2942
  const { readApiKeyFromEnv } = await import("./env-api-key-MlzJYAvt.js").then((n) => n.t);
2938
- const { configureLogFileFromEnvironment, logToFile } = await import("./debug-zMvpNYb2.js");
2939
- const { wizardAbort, WizardError } = await import("./wizard-abort-DWXyJdws.js");
2943
+ const { configureLogFileFromEnvironment, logToFile } = await import("./debug-CZQcMAJT.js");
2944
+ const { wizardAbort, WizardError } = await import("./wizard-abort-BRXKRL4F.js");
2940
2945
  configureLogFileFromEnvironment();
2941
2946
  const env = readEnvironment();
2942
2947
  const apiKey = options.apiKey ?? readApiKeyFromEnv() ?? void 0;
@@ -2987,7 +2992,7 @@ function runWizardCI(config, options) {
2987
2992
  })
2988
2993
  });
2989
2994
  }
2990
- const { runAgent } = await import("./agent-runner-CBbkS0Ro.js");
2995
+ const { runAgent } = await import("./agent-runner-L_-kJ3y3.js");
2991
2996
  await runAgent(config, session);
2992
2997
  } catch (error) {
2993
2998
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -3766,7 +3771,7 @@ async function runDoctorCI(options) {
3766
3771
  getUI().intro("Welcome to the PostHog setup wizard");
3767
3772
  getUI().log.info("Running posthog-doctor in CI mode");
3768
3773
  try {
3769
- const { getOrAskForProjectData } = await import("./setup-utils-0U-_Md2G.js").then((n) => n.r);
3774
+ const { getOrAskForProjectData } = await import("./setup-utils-D87CyNkw.js").then((n) => n.r);
3770
3775
  const { host, accessToken, projectId } = await getOrAskForProjectData({
3771
3776
  signup: false,
3772
3777
  ci: true,
@@ -3783,7 +3788,7 @@ async function runDoctorCI(options) {
3783
3788
  for (const issue of sorted) getUI().log.info(` • [${issue.severity}] ${getKindMeta(issue.kind).title}`);
3784
3789
  process.exit(1);
3785
3790
  } catch (error) {
3786
- const { ApiError } = await import("./api-CI3Z74NG.js").then((n) => n.n);
3791
+ const { ApiError } = await import("./api-DNS-L-1U.js").then((n) => n.n);
3787
3792
  const message = error instanceof ApiError && error.statusCode === 401 ? "Your PostHog API key is invalid or expired." : error instanceof Error ? error.message : String(error);
3788
3793
  getUI().log.error(`Doctor failed: ${message}`);
3789
3794
  process.exit(1);
@@ -3846,7 +3851,7 @@ function runSlackConnect(argv) {
3846
3851
  (async () => {
3847
3852
  const debug = argv.debug;
3848
3853
  try {
3849
- const { startTUI } = await import("./start-tui-WNb3ET14.js");
3854
+ const { startTUI } = await import("./start-tui-DnAG57vY.js");
3850
3855
  const { buildSession } = await import("./wizard-session-wPJtNl4c.js");
3851
3856
  const tui = startTUI(VERSION, Program.SlackConnect);
3852
3857
  tui.store.session = buildSession({ debug });
@@ -3967,6 +3972,247 @@ const skillCommand = {
3967
3972
  }
3968
3973
  };
3969
3974
  //#endregion
3975
+ //#region src/steps/install-cli-steering/index.ts
3976
+ const dirExists = (...segments) => {
3977
+ try {
3978
+ return fs$1.existsSync(path$1.join(os.homedir(), ...segments));
3979
+ } catch {
3980
+ return false;
3981
+ }
3982
+ };
3983
+ const CLI_STEERING_TARGETS = [
3984
+ {
3985
+ id: "claude-code",
3986
+ name: "Claude Code",
3987
+ instructionsPath: () => path$1.join(os.homedir(), ".claude", "CLAUDE.md"),
3988
+ isDetected: () => dirExists(".claude")
3989
+ },
3990
+ {
3991
+ id: "codex",
3992
+ name: "Codex",
3993
+ instructionsPath: () => path$1.join(os.homedir(), ".codex", "AGENTS.md"),
3994
+ isDetected: () => dirExists(".codex")
3995
+ },
3996
+ {
3997
+ id: "gemini",
3998
+ name: "Gemini CLI",
3999
+ instructionsPath: () => path$1.join(os.homedir(), ".gemini", "GEMINI.md"),
4000
+ isDetected: () => dirExists(".gemini")
4001
+ }
4002
+ ];
4003
+ function findTarget(id) {
4004
+ return CLI_STEERING_TARGETS.find((target) => target.id === id);
4005
+ }
4006
+ function detectTargets() {
4007
+ return CLI_STEERING_TARGETS.filter((target) => target.isDetected());
4008
+ }
4009
+ const spawnOptions = {
4010
+ encoding: "utf-8",
4011
+ shell: process.platform === "win32"
4012
+ };
4013
+ /**
4014
+ * Install or update the PostHog CLI in the user's environment. `npm install
4015
+ * --global @posthog/cli@latest` covers both first-time installs and upgrades
4016
+ * for existing npm-installed CLIs.
4017
+ */
4018
+ function installOrUpdatePostHogCli() {
4019
+ const args = [
4020
+ "install",
4021
+ "--global",
4022
+ "@posthog/cli@latest"
4023
+ ];
4024
+ debug(`Running npm ${args.join(" ")}`);
4025
+ const result = spawnSync("npm", args, spawnOptions);
4026
+ if (result.error) return {
4027
+ success: false,
4028
+ error: `Failed to run npm: ${result.error.message}. Is Node.js installed?`
4029
+ };
4030
+ if (result.status !== 0) return {
4031
+ success: false,
4032
+ error: (result.stderr || result.stdout || "").trim() || `npm install --global @posthog/cli@latest exited with status ${result.status ?? "unknown"}`
4033
+ };
4034
+ return { success: true };
4035
+ }
4036
+ /**
4037
+ * Delegate the actual write to the installed `posthog-cli api agents-md
4038
+ * install`. The steering snippet lives in the CLI (its single source of truth),
4039
+ * so the command should run only after `installOrUpdatePostHogCli` refreshes
4040
+ * the CLI to the latest release.
4041
+ */
4042
+ function installSteeringSnippet(filePath) {
4043
+ const args = [
4044
+ "api",
4045
+ "agents-md",
4046
+ "install",
4047
+ "--path",
4048
+ filePath
4049
+ ];
4050
+ debug(`Running posthog-cli ${args.join(" ")}`);
4051
+ const result = spawnSync("posthog-cli", args, {
4052
+ ...spawnOptions,
4053
+ env: {
4054
+ ...process.env,
4055
+ POSTHOG_CLI_EXPERIMENTAL_API: "1"
4056
+ }
4057
+ });
4058
+ if (result.error) return {
4059
+ success: false,
4060
+ filePath,
4061
+ error: `Failed to run posthog-cli: ${result.error.message}. Make sure npm's global bin directory is on your PATH.`
4062
+ };
4063
+ if (result.status !== 0) return {
4064
+ success: false,
4065
+ filePath,
4066
+ error: (result.stderr || result.stdout || "").trim() || `posthog-cli exited with status ${result.status ?? "unknown"}`
4067
+ };
4068
+ return {
4069
+ success: true,
4070
+ filePath
4071
+ };
4072
+ }
4073
+ //#endregion
4074
+ //#region src/commands/cli/add.ts
4075
+ const cliAddCommand = {
4076
+ name: "add",
4077
+ description: "Install or update PostHog CLI and add steering instructions to your coding agent's global instructions file",
4078
+ options: {
4079
+ agent: {
4080
+ describe: "Agent to install the instructions for",
4081
+ choices: CLI_STEERING_TARGETS.map((target) => target.id),
4082
+ type: "string"
4083
+ },
4084
+ path: {
4085
+ describe: "Write to an explicit instructions file instead of a detected agent",
4086
+ type: "string"
4087
+ },
4088
+ all: {
4089
+ default: false,
4090
+ describe: "Install for every detected agent without prompting",
4091
+ type: "boolean"
4092
+ }
4093
+ },
4094
+ examples: [
4095
+ ["wizard cli add", "Detect your coding agents and pick one"],
4096
+ ["wizard cli add --agent claude-code", "Install for Claude Code (~/.claude/CLAUDE.md)"],
4097
+ ["wizard cli add --all", "Install for every detected agent"],
4098
+ ["wizard cli add --path ./AGENTS.md", "Install into a specific instructions file"]
4099
+ ],
4100
+ check: (argv) => {
4101
+ if (argv.all && (argv.agent || argv.path)) throw new Error("--all cannot be combined with --agent or --path");
4102
+ return true;
4103
+ },
4104
+ handler: (argv) => {
4105
+ runCliAdd(argv);
4106
+ }
4107
+ };
4108
+ async function runCliAdd(argv) {
4109
+ setUI(new LoggingUI());
4110
+ const ui = getUI();
4111
+ ui.intro("PostHog CLI setup");
4112
+ const files = await resolveTargetFiles(argv);
4113
+ if (files.length === 0) {
4114
+ process.exit(1);
4115
+ return;
4116
+ }
4117
+ ui.log.info("Installing or updating PostHog CLI...");
4118
+ const cliInstallResult = installOrUpdatePostHogCli();
4119
+ if (!cliInstallResult.success) {
4120
+ ui.log.error(`Failed to install or update PostHog CLI: ${cliInstallResult.error ?? ""}`);
4121
+ analytics.wizardCapture("cli steering installed", {
4122
+ files: files.length,
4123
+ failures: files.length,
4124
+ cli_install_failed: true,
4125
+ agent: typeof argv.agent === "string" ? argv.agent : void 0
4126
+ });
4127
+ process.exit(1);
4128
+ return;
4129
+ }
4130
+ ui.log.success("Installed or updated PostHog CLI.");
4131
+ let failures = 0;
4132
+ for (const file of files) {
4133
+ const result = installSteeringSnippet(file);
4134
+ if (result.success) ui.log.success(`Installed PostHog steering instructions in ${file}`);
4135
+ else {
4136
+ failures += 1;
4137
+ ui.log.error(`Failed to update ${file}: ${result.error ?? ""}`);
4138
+ }
4139
+ }
4140
+ analytics.wizardCapture("cli steering installed", {
4141
+ files: files.length,
4142
+ failures,
4143
+ agent: typeof argv.agent === "string" ? argv.agent : void 0
4144
+ });
4145
+ if (failures > 0) {
4146
+ process.exit(1);
4147
+ return;
4148
+ }
4149
+ ui.outro("Done. PostHog CLI is installed and your agent will now use `posthog-cli api` for PostHog tasks.");
4150
+ process.exit(0);
4151
+ }
4152
+ /** Resolve which instruction files to write, from flags, detection, or a prompt. */
4153
+ async function resolveTargetFiles(argv) {
4154
+ const ui = getUI();
4155
+ if (typeof argv.path === "string" && argv.path.trim()) return [path$1.resolve(argv.path.trim())];
4156
+ if (typeof argv.agent === "string") {
4157
+ const target = findTarget(argv.agent);
4158
+ if (!target) {
4159
+ ui.log.error(`Unsupported agent: ${argv.agent}`);
4160
+ return [];
4161
+ }
4162
+ return [target.instructionsPath()];
4163
+ }
4164
+ const detected = detectTargets();
4165
+ if (detected.length === 0) {
4166
+ ui.log.error("No supported coding agents detected. Pass --agent <id> or --path <file> to choose a target.");
4167
+ ui.log.info(`Supported agents: ${CLI_STEERING_TARGETS.map((t) => t.id).join(", ")}`);
4168
+ return [];
4169
+ }
4170
+ if (argv.all === true) {
4171
+ ui.log.info(`Installing for all detected agents: ${detected.map((t) => t.name).join(", ")}`);
4172
+ return detected.map((target) => target.instructionsPath());
4173
+ }
4174
+ if (detected.length === 1) {
4175
+ ui.log.info(`Detected ${detected[0].name} (${detected[0].instructionsPath()})`);
4176
+ return [detected[0].instructionsPath()];
4177
+ }
4178
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
4179
+ ui.log.info(`Installing for all detected agents: ${detected.map((t) => t.name).join(", ")}`);
4180
+ return detected.map((target) => target.instructionsPath());
4181
+ }
4182
+ return (await promptForTargets(detected)).map((target) => target.instructionsPath());
4183
+ }
4184
+ /** Minimal numbered selection — this command is intentionally not a TUI flow. */
4185
+ async function promptForTargets(detected) {
4186
+ const ui = getUI();
4187
+ ui.log.info("Which coding agent are you using?");
4188
+ detected.forEach((target, index) => {
4189
+ ui.log.info(` ${index + 1}) ${target.name} (${target.instructionsPath()})`);
4190
+ });
4191
+ ui.log.info(` ${detected.length + 1}) All of the above`);
4192
+ const rl = readline.createInterface({
4193
+ input: process.stdin,
4194
+ output: process.stdout
4195
+ });
4196
+ try {
4197
+ for (;;) {
4198
+ const answer = (await rl.question(`Select 1-${detected.length + 1}: `)).trim();
4199
+ const choice = Number(answer);
4200
+ if (Number.isInteger(choice) && choice >= 1 && choice <= detected.length) return [detected[choice - 1]];
4201
+ if (choice === detected.length + 1) return detected;
4202
+ ui.log.warn(`Enter a number between 1 and ${detected.length + 1}.`);
4203
+ }
4204
+ } finally {
4205
+ rl.close();
4206
+ }
4207
+ }
4208
+ //#endregion
4209
+ //#region src/commands/cli/index.ts
4210
+ const cliCommand = {
4211
+ name: "cli",
4212
+ description: "PostHog CLI agent integration commands",
4213
+ children: [cliAddCommand]
4214
+ };
4215
+ //#endregion
3970
4216
  //#region bin.ts
3971
4217
  const NODE_VERSION_RANGE = ">=18.17.0";
3972
4218
  if (!satisfies(process.version, NODE_VERSION_RANGE)) {
@@ -3982,7 +4228,7 @@ function resolveInstallDir() {
3982
4228
  if (inline) return inline.slice(14);
3983
4229
  return process.env.POSTHOG_WIZARD_INSTALL_DIR ?? process.cwd();
3984
4230
  }
3985
- Wizard.use(basicIntegrationCommand).use(mcpCommand).use(auditCommand).use(doctorCommand).use(migrateCommand).use(revenueCommand).use(slackCommand).use(uploadSourcemapsCommand).use(skillCommand).init();
4231
+ Wizard.use(basicIntegrationCommand).use(mcpCommand).use(cliCommand).use(auditCommand).use(doctorCommand).use(migrateCommand).use(revenueCommand).use(slackCommand).use(uploadSourcemapsCommand).use(skillCommand).init();
3986
4232
  //#endregion
3987
4233
  export { POSTHOG_SDKS$1 as _, PromptLabel as a, PROGRAM_REGISTRY as c, DISPLAY_NAME as d, SOURCE_MAPS_CONTEXT_KEYS as f, getContentBlocks$2 as g, fetchHealthIssues as h, useKeyboardHintsContext as i, Program as l, getKindMeta as m, useKeyBindings as n, runWizardCI as o, getContentBlocks$1 as p, KeyboardHintsProvider as r, runWizard as s, PickerMenu as t, getProgramConfig as u, STRIPE_SDKS as v };
3988
4234