@posthog/wizard 2.32.0 → 2.33.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.
- package/dist/{add-mcp-server-to-clients-Dc0yssCM.js → add-mcp-server-to-clients-Dhq75Hda.js} +5 -5
- package/dist/{add-mcp-server-to-clients-Dc0yssCM.js.map → add-mcp-server-to-clients-Dhq75Hda.js.map} +1 -1
- package/dist/{agent-interface-c7B2JZEd.js → agent-interface-DCeQ5Oiw.js} +6 -6
- package/dist/{agent-interface-c7B2JZEd.js.map → agent-interface-DCeQ5Oiw.js.map} +1 -1
- package/dist/{agent-runner-Am34bBUT.js → agent-runner-BRajaO84.js} +10 -9
- package/dist/{agent-runner-Am34bBUT.js.map → agent-runner-BRajaO84.js.map} +1 -1
- package/dist/{analytics-CBIKy9PZ.js → analytics-CU4o3eF8.js} +3 -3
- package/dist/analytics-CU4o3eF8.js.map +1 -0
- package/dist/{api-Blg3nvvZ.js → api-BBRfHEZ-.js} +3 -3
- package/dist/{api-Blg3nvvZ.js.map → api-BBRfHEZ-.js.map} +1 -1
- package/dist/bin.js +203 -75
- package/dist/bin.js.map +1 -1
- package/dist/ci-install-D-otkGW6.js +113 -0
- package/dist/ci-install-D-otkGW6.js.map +1 -0
- package/dist/{debug-AdvgwKEw.js → debug-BGMe1wP6.js} +2 -2
- package/dist/{debug-AdvgwKEw.js.map → debug-BGMe1wP6.js.map} +1 -1
- package/dist/{debug-cy_jyRb4.js → debug-BewTLNNr.js} +1 -1
- package/dist/{defaults-BNWIWzjc.js → defaults-DII5CAog.js} +1 -1
- package/dist/{defaults-BNWIWzjc.js.map → defaults-DII5CAog.js.map} +1 -1
- package/dist/{environment-B6TW5v9d.js → environment-G41UFzou.js} +3 -3
- package/dist/{environment-B6TW5v9d.js.map → environment-G41UFzou.js.map} +1 -1
- package/dist/{file-utils-8tUk_eEX.js → file-utils-D9InAvZd.js} +2 -2
- package/dist/{file-utils-8tUk_eEX.js.map → file-utils-D9InAvZd.js.map} +1 -1
- package/dist/headless-ui-xjHVVUqe.js +24 -0
- package/dist/headless-ui-xjHVVUqe.js.map +1 -0
- package/dist/{interactive-CApktTrj.js → interactive-D2CKikzz.js} +3 -3
- package/dist/{interactive-CApktTrj.js.map → interactive-D2CKikzz.js.map} +1 -1
- package/dist/{mcp-prompt-streaming-BKcU9yuz.js → mcp-prompt-streaming-FrArGwfv.js} +4 -4
- package/dist/{mcp-prompt-streaming-BKcU9yuz.js.map → mcp-prompt-streaming-FrArGwfv.js.map} +1 -1
- package/dist/{non-interactive-DejTdRTW.js → non-interactive-BXx6Q-D0.js} +2 -2
- package/dist/{non-interactive-DejTdRTW.js.map → non-interactive-BXx6Q-D0.js.map} +1 -1
- package/dist/{package-manager-DBfgSXNn.js → package-manager-D9ojA4jO.js} +2 -2
- package/dist/{package-manager-DBfgSXNn.js.map → package-manager-D9ojA4jO.js.map} +1 -1
- package/dist/{playground-BOg2U1AT.js → playground-Bgtxrusl.js} +7 -5
- package/dist/{playground-BOg2U1AT.js.map → playground-Bgtxrusl.js.map} +1 -1
- package/dist/{posthog-Cr37rnla.js → posthog-DU6JXG00.js} +1 -1
- package/dist/{posthog-Cr37rnla.js.map → posthog-DU6JXG00.js.map} +1 -1
- package/dist/{posthog-integration-gLhOUdPJ.js → posthog-integration-gnC9v4kg.js} +13 -13
- package/dist/{posthog-integration-gLhOUdPJ.js.map → posthog-integration-gnC9v4kg.js.map} +1 -1
- package/dist/{provisioning-DuzclqPB.js → provisioning-C3qglLdc.js} +3 -3
- package/dist/{provisioning-DuzclqPB.js.map → provisioning-C3qglLdc.js.map} +1 -1
- package/dist/{registry-Dbl-5SnO.js → registry-BVrvFTZ0.js} +4 -4
- package/dist/{registry-Dbl-5SnO.js.map → registry-BVrvFTZ0.js.map} +1 -1
- package/dist/{setup-utils-B6wbp3s0.js → setup-utils-CanVlGbX.js} +8 -8
- package/dist/{setup-utils-B6wbp3s0.js.map → setup-utils-CanVlGbX.js.map} +1 -1
- package/dist/smoke-test.sh +25 -0
- package/dist/{start-tui-IoQh-Nhj.js → start-tui-YE7bybIr.js} +17 -16
- package/dist/{start-tui-IoQh-Nhj.js.map → start-tui-YE7bybIr.js.map} +1 -1
- package/dist/{steps-CJrqlHbo.js → steps-N20e4IoE.js} +7 -7
- package/dist/{steps-CJrqlHbo.js.map → steps-N20e4IoE.js.map} +1 -1
- package/dist/store-D15C9YSW.js +763 -0
- package/dist/store-D15C9YSW.js.map +1 -0
- package/dist/{task-stream-BQNSp0qR.js → task-stream-CPjpHFhI.js} +4 -4
- package/dist/{task-stream-BQNSp0qR.js.map → task-stream-CPjpHFhI.js.map} +1 -1
- package/dist/{telemetry-1m0CyTry.js → telemetry-DknCDWP6.js} +3 -3
- package/dist/{telemetry-1m0CyTry.js.map → telemetry-DknCDWP6.js.map} +1 -1
- package/dist/{terminal-BKI4i72f.js → terminal-Cvv0a-7Q.js} +14 -764
- package/dist/terminal-Cvv0a-7Q.js.map +1 -0
- package/dist/{urls-B3JumpLT.js → urls-DrR6F_A3.js} +2 -2
- package/dist/{urls-B3JumpLT.js.map → urls-DrR6F_A3.js.map} +1 -1
- package/dist/{wizard-abort-PqLMKSh1.js → wizard-abort-Cw818xPr.js} +4 -3
- package/dist/{wizard-abort-PqLMKSh1.js.map → wizard-abort-Cw818xPr.js.map} +1 -1
- package/dist/{wizard-abort-D7SzKUgE.js → wizard-abort-DMvS0YXD.js} +1 -1
- package/dist/wizard-session-BKEdX9mO.js +2 -0
- package/dist/{wizard-session-G3VWD6hv.js → wizard-session-CN55LYyZ.js} +9 -2
- package/dist/{wizard-session-G3VWD6hv.js.map → wizard-session-CN55LYyZ.js.map} +1 -1
- package/package.json +1 -1
- package/dist/analytics-CBIKy9PZ.js.map +0 -1
- package/dist/ci-install-51ntd9x5.js +0 -73
- package/dist/ci-install-51ntd9x5.js.map +0 -1
- package/dist/terminal-BKI4i72f.js.map +0 -1
- package/dist/wizard-session-wPJtNl4c.js +0 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as ANALYTICS_TEAM_TAG, b as ANALYTICS_HOST_URL, r as debug, s as logToFile, x as ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY } from "./debug-
|
|
1
|
+
import { S as ANALYTICS_TEAM_TAG, b as ANALYTICS_HOST_URL, r as debug, s as logToFile, x as ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY } from "./debug-BGMe1wP6.js";
|
|
2
2
|
import { PostHog } from "posthog-node";
|
|
3
3
|
import { v4 } from "uuid";
|
|
4
4
|
//#region src/utils/ci-flag-overrides.ts
|
|
@@ -88,7 +88,7 @@ var Analytics = class {
|
|
|
88
88
|
get runId() {
|
|
89
89
|
return this._runId;
|
|
90
90
|
}
|
|
91
|
-
/** Build type for this run ('prod' | 'dev' | 'ci') — the same value tagged on every analytics event. */
|
|
91
|
+
/** Build type for this run ('prod' | 'dev' | 'ci' | 'headless') — the same value tagged on every analytics event. */
|
|
92
92
|
get build() {
|
|
93
93
|
return String(this.tags.build ?? "dev");
|
|
94
94
|
}
|
|
@@ -228,4 +228,4 @@ const analytics = new Analytics();
|
|
|
228
228
|
//#endregion
|
|
229
229
|
export { ciExcludedTaskTypes as i, groupsFromUser as n, sessionProperties as r, analytics as t };
|
|
230
230
|
|
|
231
|
-
//# sourceMappingURL=analytics-
|
|
231
|
+
//# sourceMappingURL=analytics-CU4o3eF8.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics-CU4o3eF8.js","names":["uuidv4"],"sources":["../src/utils/ci-flag-overrides.ts","../src/utils/analytics.ts"],"sourcesContent":["/**\n * CI-only feature-flag overrides.\n *\n * CI must route deterministically: a run that tests the orchestrator arm says\n * so explicitly instead of depending on a live feature flag someone can edit\n * mid-week. The override env var (see the allowlist in `env.ts`) is a JSON\n * object of flag key → value, merged over whatever PostHog returned.\n *\n * The override path exists only in CI builds (`pnpm build:ci`). Published\n * builds inline NODE_ENV as the literal \"production\", the guards collapse,\n * and tsdown strips the rest from the bundle — and the smoke test asserts the\n * env var names are physically absent from production output (which is also\n * why no comment in this file may spell them out), so this can never quietly\n * become a production surface.\n */\nimport { runtimeEnv } from '@env';\nimport { logToFile } from './debug';\n\nexport function applyCiFlagOverrides(\n flags: Record<string, string>,\n): Record<string, string> {\n // Compared inline (not via env.ts's IS_PRODUCTION_BUILD) so tsdown replaces\n // it with a literal right here and the bundler can prove the rest of this\n // function unreachable in production builds. The smoke test enforces that.\n if (process.env.NODE_ENV === 'production') return flags;\n\n const raw = runtimeEnv('WIZARD_CI_FLAG_OVERRIDES');\n if (!raw) return flags;\n\n let overrides: Record<string, unknown>;\n try {\n overrides = JSON.parse(raw) as Record<string, unknown>;\n } catch {\n // A malformed override is a CI misconfiguration. Fail the run loudly\n // rather than silently testing whatever the live flags happen to say.\n throw new Error(\n 'The CI flag-override env var is not valid JSON (expected {\"flag-key\": value, ...}).',\n );\n }\n\n const merged = { ...flags };\n for (const [key, value] of Object.entries(overrides)) {\n merged[key] = String(value);\n }\n logToFile('[flags] CI overrides applied', overrides);\n return merged;\n}\n\n/**\n * Task types excluded from this run. The exclusion env var (see the allowlist\n * in `env.ts`) is a comma-separated list (e.g. `dashboard`), set by the CI\n * harness that owns the policy — the wizard and the served content stay\n * run-mode agnostic. CI-build only, same as the flag overrides: published\n * builds strip this path.\n */\nexport function ciExcludedTaskTypes(): readonly string[] {\n if (process.env.NODE_ENV === 'production') return [];\n\n const raw = runtimeEnv('WIZARD_CI_EXCLUDE_TASKS');\n if (!raw) return [];\n const types = raw\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean);\n if (types.length > 0) logToFile('[flags] CI task exclusions', types);\n return types;\n}\n","import { PostHog } from 'posthog-node';\nimport {\n ANALYTICS_HOST_URL,\n ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY,\n ANALYTICS_TEAM_TAG,\n} from '@lib/constants';\nimport type { WizardSession } from '@lib/wizard-session';\nimport type { ApiUser } from '@lib/api';\nimport { v4 as uuidv4 } from 'uuid';\nimport { IS_PRODUCTION_BUILD } from '@env';\nimport { debug, logToFile } from './debug';\nimport { applyCiFlagOverrides } from './ci-flag-overrides';\n\n/**\n * Extract a standard property bag from the current session.\n * Used by store-level analytics and available for ad-hoc captures.\n */\nexport function sessionProperties(\n session: WizardSession,\n): Record<string, unknown> {\n return {\n integration: session.integration,\n detected_framework: session.detectedFrameworkLabel,\n typescript: session.typescript,\n project_id: session.credentials?.projectId,\n discovered_features: session.discoveredFeatures,\n additional_features: session.additionalFeatureQueue,\n run_phase: session.runPhase,\n };\n}\n\nexport function groupsFromUser(\n user: ApiUser | null,\n host: string,\n): Record<string, string> {\n const groups: Record<string, string> = { instance: host };\n if (!user) return groups;\n\n const organizationId = user.organization?.id;\n if (organizationId) groups.organization = organizationId;\n\n const customerId = user.organization?.customer_id;\n if (customerId) groups.customer = customerId;\n\n const projectUuid = user.team?.uuid;\n if (projectUuid) groups.project = projectUuid;\n\n return groups;\n}\n\nexport class Analytics {\n private client: PostHog;\n private tags: Record<string, string | boolean | number | null | undefined> =\n {};\n private distinctId?: string;\n private anonymousId: string;\n private _runId: string;\n private sessionId: string | null = null;\n private appName = 'wizard';\n private activeFlags: Record<string, string> | null = null;\n private groups: Record<string, string> = {};\n private personProperties: Record<string, string> = {};\n\n constructor() {\n this.client = new PostHog(ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY, {\n host: ANALYTICS_HOST_URL,\n flushAt: 1,\n flushInterval: 0,\n enableExceptionAutocapture: true,\n before_send: (event) => {\n if (!event) return event;\n if (Object.keys(this.groups).length > 0) {\n event.groups = { ...this.groups, ...event.groups };\n }\n // Autocaptured exceptions arrive with a random uuid and\n // `$process_person_profile: false` — reattach the run's identity\n // and tags so they land on the same person as everything else.\n if (event.event === '$exception') {\n event.distinctId = this.distinctId ?? this.anonymousId;\n const { $process_person_profile, ...properties } =\n event.properties ?? {};\n void $process_person_profile;\n event.properties = { ...this.tags, ...properties };\n }\n return event;\n },\n });\n\n this.tags = { $app_name: this.appName };\n // Tag every run with its build type so prod / dev / ci / headless segment\n // cleanly in analytics. tsdown inlines IS_PRODUCTION_BUILD to `true` in\n // published builds and `false` for dev/tsx/test runs. Non-interactive runs\n // upgrade this in runWizardCI: dev `--ci` runs to 'ci', published headless\n // runs to 'headless'.\n this.tags.build = IS_PRODUCTION_BUILD ? 'prod' : 'dev';\n\n this.anonymousId = uuidv4();\n\n // One id per process = one id per wizard run, registered in the tag bag\n // so it rides on every capture, exception, and autocaptured exception\n // (all of which merge `this.tags`). Lets you separate two runs by the\n // same logged-in user, who otherwise share one distinct id. Distinct\n // from `anonymousId`, the pre-login *person* id that gets aliased onto\n // the real user at login. `$session_id` is intentionally not set here —\n // it stays null until OAuth completes (see identifyUser).\n this._runId = uuidv4();\n this.tags.run_id = this._runId;\n\n this.distinctId = undefined;\n }\n\n /** Per-process run id, tagged on every event and gateway trace. */\n get runId(): string {\n return this._runId;\n }\n\n /** Build type for this run ('prod' | 'dev' | 'ci' | 'headless') — the same value tagged on every analytics event. */\n get build(): string {\n return String(this.tags.build ?? 'dev');\n }\n\n /**\n * Associate the run with the logged-in user, once per id. Identifies them\n * (email, name) and records those person properties so events carry them and\n * feature flags can target the individual user — without the email here the\n * wizard only sends `$app_name`, so email-targeted flags never match. Opens\n * the analytics session on first login, then aliases the run's anonymous id\n * onto the identified person so pre-login events merge in.\n */\n identifyUser(user: ApiUser) {\n const distinctId = user.distinct_id;\n if (this.distinctId === distinctId || distinctId === this.anonymousId) {\n return;\n }\n this.distinctId = distinctId;\n // Open the analytics session on first login. Null until here, so\n // pre-OAuth events carry only `run_id`; from now on every event also\n // carries `$session_id` and PostHog groups the authenticated run into a\n // native Session. Stored in the tag bag so it rides on every subsequent\n // capture and exception.\n if (!this.sessionId) {\n this.sessionId = uuidv4();\n this.tags.$session_id = this.sessionId;\n }\n const props: Record<string, string> = {};\n if (user.email) props.email = user.email;\n const name = [user.first_name, user.last_name]\n .filter(Boolean)\n .join(' ')\n .trim();\n if (name) props.name = name;\n this.personProperties = props;\n this.client.identify({ distinctId, properties: { $set: props } });\n this.client.alias({\n distinctId,\n alias: this.anonymousId,\n });\n // The flag snapshot is per identity. Anything evaluated before login (the\n // intro screen reads the tools-menu flag) was anonymous — drop it so the\n // next read re-evaluates as this user.\n this.activeFlags = null;\n }\n\n /** Person properties sent with flag evaluation: app name plus the user's. */\n private flagPersonProperties(): Record<string, string> {\n return { $app_name: this.appName, ...this.personProperties };\n }\n\n setTag(key: string, value: string | boolean | number | null | undefined) {\n this.tags[key] = value;\n }\n\n setGroups(groups: Record<string, string>) {\n this.groups = groups;\n }\n\n captureException(error: Error, properties: Record<string, unknown> = {}) {\n this.client.captureException(error, this.distinctId ?? this.anonymousId, {\n team: ANALYTICS_TEAM_TAG,\n ...this.tags,\n ...properties,\n });\n }\n\n capture(eventName: string, properties?: Record<string, unknown>) {\n this.client.capture({\n distinctId: this.distinctId ?? this.anonymousId,\n event: eventName,\n properties: {\n ...this.tags,\n ...properties,\n },\n });\n }\n\n /**\n * Capture a wizard-specific event. Automatically prepends \"wizard: \" to the event name.\n * All new wizard analytics should use this method instead of capture() directly.\n */\n wizardCapture(eventName: string, properties?: Record<string, unknown>): void {\n this.capture(`wizard: ${eventName}`, properties);\n }\n\n /**\n * Flush pending events without firing the \"setup wizard finished\" terminal\n * event. Use this from CLI error paths that exit before any wizard run\n * starts — `shutdown()` would inflate the run count with a \"finished\" event\n * for a parse error that never actually ran the wizard.\n */\n async flush(): Promise<void> {\n await this.client.shutdown();\n }\n\n async getFeatureFlag(flagKey: string): Promise<string | boolean | undefined> {\n try {\n const distinctId = this.distinctId ?? this.anonymousId;\n return await this.client.getFeatureFlag(flagKey, distinctId, {\n sendFeatureFlagEvents: true,\n personProperties: this.flagPersonProperties(),\n });\n } catch (error) {\n debug('Failed to get feature flag:', flagKey, error);\n return undefined;\n }\n }\n\n /**\n * Evaluate all feature flags for the current user at the start of a run.\n * Result is cached; subsequent calls in the same run return the same map.\n * Returns flag key -> string value (booleans become 'true'/'false').\n */\n async getAllFlagsForWizard(): Promise<Record<string, string>> {\n if (this.activeFlags !== null) {\n return this.activeFlags;\n }\n const out: Record<string, string> = {};\n try {\n const distinctId = this.distinctId ?? this.anonymousId;\n logToFile('[flags] evaluating as', {\n distinctId,\n identified: this.distinctId !== undefined,\n personProperties: this.flagPersonProperties(),\n });\n const result = await this.client.getAllFlagsAndPayloads(distinctId, {\n personProperties: this.flagPersonProperties(),\n });\n const flags = result.featureFlags ?? {};\n for (const [key, value] of Object.entries(flags)) {\n if (value === undefined) continue;\n out[key] = typeof value === 'boolean' ? String(value) : String(value);\n }\n } catch (error) {\n debug('Failed to get all feature flags:', error);\n this.captureException(\n error instanceof Error ? error : new Error(String(error)),\n { step: 'get_all_flags' },\n );\n }\n // Outside the fetch guard on purpose: a malformed CI override must fail\n // the run loudly, and a valid one applies even when the fetch failed —\n // CI routing stays deterministic either way.\n this.activeFlags = applyCiFlagOverrides(out);\n logToFile('[flags] evaluated', this.activeFlags);\n return this.activeFlags;\n }\n\n async shutdown(status: 'success' | 'error' | 'cancelled') {\n if (Object.keys(this.tags).length === 0) {\n return;\n }\n\n this.client.capture({\n distinctId: this.distinctId ?? this.anonymousId,\n event: 'setup wizard finished',\n properties: {\n // Hoisted out of `tags` so the run's terminal event is filterable by\n // run, and joins the session when one was opened (post-OAuth runs).\n run_id: this._runId,\n ...(this.sessionId ? { $session_id: this.sessionId } : {}),\n status,\n tags: this.tags,\n },\n });\n\n await this.client.shutdown();\n }\n}\n\nexport const analytics = new Analytics();\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-B_-DWIq7.js";
|
|
2
|
-
import { Q as WIZARD_USER_AGENT } from "./debug-
|
|
3
|
-
import { t as analytics } from "./analytics-
|
|
2
|
+
import { Q as WIZARD_USER_AGENT } from "./debug-BGMe1wP6.js";
|
|
3
|
+
import { t as analytics } from "./analytics-CU4o3eF8.js";
|
|
4
4
|
import axios from "axios";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
//#region src/lib/api.ts
|
|
@@ -170,4 +170,4 @@ function handleApiError(error, operation) {
|
|
|
170
170
|
//#endregion
|
|
171
171
|
export { fetchUserData as a, fetchSlackConnected as i, api_exports as n, handleApiError as o, fetchProjectData as r, ApiError as t };
|
|
172
172
|
|
|
173
|
-
//# sourceMappingURL=api-
|
|
173
|
+
//# sourceMappingURL=api-BBRfHEZ-.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-Blg3nvvZ.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-BBRfHEZ-.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,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { I as POSTHOG_DOCS_URL, Q as WIZARD_USER_AGENT, a as getLogFilePath, et as getSkillsBaseUrl, h as LoggingUI, m as setUI, p as getUI, r as debug, s as logToFile, tt as VERSION } from "./debug-
|
|
3
|
-
import { t as analytics } from "./analytics-
|
|
4
|
-
import { r as setEntryCommand } from "./telemetry-
|
|
5
|
-
import { n as isUsingTypeScript } from "./setup-utils-
|
|
6
|
-
import { a as getUiHostFromHost, n as getCloudUrlFromRegion } from "./urls-
|
|
7
|
-
import { o as handleApiError } from "./api-
|
|
8
|
-
import "./wizard-session-
|
|
9
|
-
import { r as runCleanups } from "./wizard-abort-
|
|
10
|
-
import { n as isNonInteractiveEnvironment } from "./environment-
|
|
11
|
-
import { C as AUDIT_CHECKS_FILE, T as AUDIT_REPORT_FILE, c as recoverOrphanedSettingsBackups, g as WIZARD_TOOL_NAMES, h as SETUP_REPORT_FILE, u as AgentSignals, v as fetchSkillMenu, w as AUDIT_CHECKS_KEY } from "./agent-interface-
|
|
12
|
-
import { i as SPINNER_MESSAGE } from "./registry-
|
|
13
|
-
import { _ as parseRequirementsTxt, a as StatusPeekTrigger, c as isClearBlock, d as Colors, f as Icons, g as parsePyprojectToml, h as parsePipfile, i as PRODUCT_SUITE_BLOCK, n as FUNNEL_BLOCK, p as HEALTH_CHECK_STEP, r as LINE_CHART_BLOCK, t as posthogIntegrationConfig } from "./posthog-integration-
|
|
14
|
-
import { n as safeReadFile, r as walkProjectFiles, t as IGNORED_DIRS } from "./file-utils-
|
|
2
|
+
import { I as POSTHOG_DOCS_URL, Q as WIZARD_USER_AGENT, a as getLogFilePath, et as getSkillsBaseUrl, h as LoggingUI, m as setUI, p as getUI, r as debug, s as logToFile, tt as VERSION } from "./debug-BGMe1wP6.js";
|
|
3
|
+
import { t as analytics } from "./analytics-CU4o3eF8.js";
|
|
4
|
+
import { r as setEntryCommand } from "./telemetry-DknCDWP6.js";
|
|
5
|
+
import { n as isUsingTypeScript } from "./setup-utils-CanVlGbX.js";
|
|
6
|
+
import { a as getUiHostFromHost, n as getCloudUrlFromRegion } from "./urls-DrR6F_A3.js";
|
|
7
|
+
import { o as handleApiError } from "./api-BBRfHEZ-.js";
|
|
8
|
+
import "./wizard-session-CN55LYyZ.js";
|
|
9
|
+
import { r as runCleanups } from "./wizard-abort-Cw818xPr.js";
|
|
10
|
+
import { n as isNonInteractiveEnvironment } from "./environment-G41UFzou.js";
|
|
11
|
+
import { C as AUDIT_CHECKS_FILE, T as AUDIT_REPORT_FILE, c as recoverOrphanedSettingsBackups, g as WIZARD_TOOL_NAMES, h as SETUP_REPORT_FILE, u as AgentSignals, v as fetchSkillMenu, w as AUDIT_CHECKS_KEY } from "./agent-interface-DCeQ5Oiw.js";
|
|
12
|
+
import { i as SPINNER_MESSAGE } from "./registry-BVrvFTZ0.js";
|
|
13
|
+
import { _ as parseRequirementsTxt, a as StatusPeekTrigger, c as isClearBlock, d as Colors, f as Icons, g as parsePyprojectToml, h as parsePipfile, i as PRODUCT_SUITE_BLOCK, n as FUNNEL_BLOCK, p as HEALTH_CHECK_STEP, r as LINE_CHART_BLOCK, t as posthogIntegrationConfig } from "./posthog-integration-gnC9v4kg.js";
|
|
14
|
+
import { n as safeReadFile, r as walkProjectFiles, t as IGNORED_DIRS } from "./file-utils-D9InAvZd.js";
|
|
15
15
|
import { n as readApiKeyFromEnv } from "./env-api-key-MlzJYAvt.js";
|
|
16
16
|
import { satisfies } from "semver";
|
|
17
17
|
import yargs from "yargs";
|
|
@@ -29,6 +29,37 @@ import { createContext, createElement, useCallback, useContext, useEffect, useRe
|
|
|
29
29
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
30
30
|
import { access, rm } from "node:fs/promises";
|
|
31
31
|
import * as readline from "node:readline/promises";
|
|
32
|
+
//#region src/lib/headless-mode.ts
|
|
33
|
+
/**
|
|
34
|
+
* Headless mode — the published-build, non-interactive run path.
|
|
35
|
+
*
|
|
36
|
+
* The headless flag and `--ci` both drive a non-interactive install
|
|
37
|
+
* (session.ci === true), but through dedicated entry points so they can
|
|
38
|
+
* diverge: runHeadlessInstall → runWizardHeadless for headless,
|
|
39
|
+
* runCIInstall → runWizardCI for `--ci`. Both delegate to one shared pipeline
|
|
40
|
+
* (runNonInteractive) today; the only forks are the api-key prefixes accepted
|
|
41
|
+
* (ci-install) and the analytics build tag (the mode passed to the runner).
|
|
42
|
+
*
|
|
43
|
+
* The flag is deliberately named `--headless-DONOTUSE-EXPERIMENTAL` and hidden
|
|
44
|
+
* from `--help`: the contract is still unstable and subject to breaking
|
|
45
|
+
* changes, so it must not be advertised or relied on by external callers. This
|
|
46
|
+
* module is the single source of truth for the flag's name and detection — keep
|
|
47
|
+
* the scary name out of every other file so a future rename is one edit here.
|
|
48
|
+
*/
|
|
49
|
+
/**
|
|
50
|
+
* The on-CLI flag name. Intentionally ugly + undocumented; do not surface it in
|
|
51
|
+
* `--help`, the README, or user-facing error messages.
|
|
52
|
+
*/
|
|
53
|
+
const HEADLESS_FLAG = "headless-DONOTUSE-EXPERIMENTAL";
|
|
54
|
+
/**
|
|
55
|
+
* Read the headless signal off a parsed argv / options bag. yargs always sets
|
|
56
|
+
* the value under the declared key (`HEADLESS_FLAG`), so reading that key is
|
|
57
|
+
* reliable regardless of camel-case expansion.
|
|
58
|
+
*/
|
|
59
|
+
function isHeadless(options) {
|
|
60
|
+
return options[HEADLESS_FLAG] === true;
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
32
63
|
//#region src/commands/command.ts
|
|
33
64
|
/** Extract the bare command word(s) from a yargs name spec, dropping positionals and aliases' arg syntax. */
|
|
34
65
|
function commandKeys(name) {
|
|
@@ -98,6 +129,12 @@ const GLOBAL_OPTIONS = {
|
|
|
98
129
|
describe: "Email address for signup (used with --signup)\nenv: POSTHOG_WIZARD_EMAIL",
|
|
99
130
|
type: "string"
|
|
100
131
|
},
|
|
132
|
+
[HEADLESS_FLAG]: {
|
|
133
|
+
default: false,
|
|
134
|
+
describe: "EXPERIMENTAL — do not use. Unstable, subject to breaking changes.",
|
|
135
|
+
type: "boolean",
|
|
136
|
+
hidden: true
|
|
137
|
+
},
|
|
101
138
|
"local-mcp": {
|
|
102
139
|
default: false,
|
|
103
140
|
describe: "Use local MCP server at http://localhost:8787/mcp\nenv: POSTHOG_WIZARD_LOCAL_MCP",
|
|
@@ -190,7 +227,7 @@ function runProvision(argv) {
|
|
|
190
227
|
}
|
|
191
228
|
async function provision({ email, region, name, jsonMode }) {
|
|
192
229
|
try {
|
|
193
|
-
const { provisionNewAccount } = await import("./provisioning-
|
|
230
|
+
const { provisionNewAccount } = await import("./provisioning-C3qglLdc.js").then((n) => n.n);
|
|
194
231
|
if (!jsonMode) getUI().log.info(`Provisioning account for ${email} in ${region}...`);
|
|
195
232
|
emitResult(await provisionNewAccount(email, name, region), jsonMode);
|
|
196
233
|
process.exit(0);
|
|
@@ -248,25 +285,29 @@ const basicIntegrationCommand = {
|
|
|
248
285
|
}
|
|
249
286
|
},
|
|
250
287
|
check: (argv) => {
|
|
251
|
-
if (argv.playground && argv.ci) throw new Error("--playground cannot be combined with
|
|
288
|
+
if (argv.playground && (argv.ci || isHeadless(argv))) throw new Error("--playground cannot be combined with a headless run.");
|
|
252
289
|
return true;
|
|
253
290
|
},
|
|
254
291
|
handler: (argv) => {
|
|
255
292
|
setEntryCommand("integrate");
|
|
256
293
|
(async () => {
|
|
294
|
+
if (isHeadless(argv)) {
|
|
295
|
+
const { runHeadlessInstall } = await import("./ci-install-D-otkGW6.js");
|
|
296
|
+
return runHeadlessInstall(argv);
|
|
297
|
+
}
|
|
257
298
|
if (argv.ci) {
|
|
258
|
-
const { runCIInstall } = await import("./ci-install-
|
|
299
|
+
const { runCIInstall } = await import("./ci-install-D-otkGW6.js");
|
|
259
300
|
return runCIInstall(argv);
|
|
260
301
|
}
|
|
261
302
|
if (isNonInteractiveEnvironment()) {
|
|
262
|
-
const { failNonInteractive } = await import("./non-interactive-
|
|
303
|
+
const { failNonInteractive } = await import("./non-interactive-BXx6Q-D0.js");
|
|
263
304
|
return failNonInteractive();
|
|
264
305
|
}
|
|
265
306
|
if (argv.playground) {
|
|
266
|
-
const { runPlayground } = await import("./playground-
|
|
307
|
+
const { runPlayground } = await import("./playground-Bgtxrusl.js");
|
|
267
308
|
return runPlayground();
|
|
268
309
|
}
|
|
269
|
-
const { runInteractive } = await import("./interactive-
|
|
310
|
+
const { runInteractive } = await import("./interactive-D2CKikzz.js");
|
|
270
311
|
runInteractive(argv);
|
|
271
312
|
})();
|
|
272
313
|
}
|
|
@@ -3216,13 +3257,18 @@ const errorTrackingUploadSourceMapsConfig = {
|
|
|
3216
3257
|
* `session.installDir` is a real, readable directory. We deliberately do
|
|
3217
3258
|
* NOT require the base posthog-integration report to be present — it is a
|
|
3218
3259
|
* report many users never commit, and `requires: ['posthog-integration']`
|
|
3219
|
-
* is metadata, not a hard runtime gate.
|
|
3220
|
-
*
|
|
3221
|
-
*
|
|
3222
|
-
*
|
|
3223
|
-
* the
|
|
3224
|
-
*
|
|
3225
|
-
*
|
|
3260
|
+
* is metadata, not a hard runtime gate.
|
|
3261
|
+
*
|
|
3262
|
+
* Self-driving is now in OPEN beta — available to every team — so STEP 1
|
|
3263
|
+
* no longer probes the Signals API as an access gate; it completes
|
|
3264
|
+
* instantly so the run opens with a fast first checkmark. The
|
|
3265
|
+
* `self-driving is not available for this project` abort below is kept
|
|
3266
|
+
* only as a safety net: if the Signals API genuinely can't be reached
|
|
3267
|
+
* during the run (a hard error that is unexpected in open beta), the skill
|
|
3268
|
+
* emits it and the wizard renders a friendly "try again" screen — now with
|
|
3269
|
+
* open-beta wording, not the old closed, per-team "join the beta" copy. The
|
|
3270
|
+
* PostHog-side flags (`product-autonomy`, `signals-scout`) are unchanged by
|
|
3271
|
+
* the wizard-side "self-driving" rename.
|
|
3226
3272
|
*/
|
|
3227
3273
|
/**
|
|
3228
3274
|
* `[ABORT] <reason>` cases the self-driving skill can emit. The
|
|
@@ -3233,7 +3279,7 @@ const SELF_DRIVING_ABORT_CASES = [
|
|
|
3233
3279
|
{
|
|
3234
3280
|
match: /^self-driving is not available for this project$/i,
|
|
3235
3281
|
message: "PostHog Self-driving is not available for this project",
|
|
3236
|
-
body: "Self-driving is in beta and
|
|
3282
|
+
body: "Self-driving is in open beta and available to every team, so this is unexpected — the PostHog Signals API could not be reached for this project. Nothing was changed. Try again in a moment, and if it keeps happening reach out to wizard@posthog.com."
|
|
3237
3283
|
},
|
|
3238
3284
|
{
|
|
3239
3285
|
match: /^github connection declined$/i,
|
|
@@ -3389,8 +3435,13 @@ Wizard mechanics:
|
|
|
3389
3435
|
Follow these steps IN ORDER. Do not skip or reorder.
|
|
3390
3436
|
|
|
3391
3437
|
STEP 1 — Check Self-driving access. (skill: "Check access")
|
|
3392
|
-
|
|
3393
|
-
|
|
3438
|
+
Self-driving is in open beta and available to every team, so there is
|
|
3439
|
+
no access gate to probe. Do NOT call any MCP tool here — mark this task
|
|
3440
|
+
in_progress and then completed right away and emit the
|
|
3441
|
+
${AgentSignals.STATUS} line, so the user sees an immediate first step.
|
|
3442
|
+
Only if the Signals API later turns out to be genuinely unreachable for
|
|
3443
|
+
this project (a hard error on every Signals call, unexpected in open
|
|
3444
|
+
beta) should you emit
|
|
3394
3445
|
${AgentSignals.ABORT} self-driving is not available for this project
|
|
3395
3446
|
and halt.
|
|
3396
3447
|
|
|
@@ -3790,8 +3841,8 @@ function runMcpAdd(argv) {
|
|
|
3790
3841
|
const debug = argv.debug;
|
|
3791
3842
|
const localMcp = argv.local;
|
|
3792
3843
|
try {
|
|
3793
|
-
const { startTUI } = await import("./start-tui-
|
|
3794
|
-
const { buildSession } = await import("./wizard-session-
|
|
3844
|
+
const { startTUI } = await import("./start-tui-YE7bybIr.js");
|
|
3845
|
+
const { buildSession } = await import("./wizard-session-BKEdX9mO.js");
|
|
3795
3846
|
const tui = startTUI(VERSION, Program.McpAdd);
|
|
3796
3847
|
tui.store.session = buildSession({
|
|
3797
3848
|
debug,
|
|
@@ -3802,7 +3853,7 @@ function runMcpAdd(argv) {
|
|
|
3802
3853
|
} catch (error) {
|
|
3803
3854
|
if (!isTUIUnavailable(error)) throw error;
|
|
3804
3855
|
setUI(new LoggingUI());
|
|
3805
|
-
const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-
|
|
3856
|
+
const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-Dhq75Hda.js").then((n) => n.r);
|
|
3806
3857
|
await addMCPServerToClientsStep({
|
|
3807
3858
|
local: localMcp,
|
|
3808
3859
|
features,
|
|
@@ -3841,8 +3892,8 @@ function runMcpRemove(argv) {
|
|
|
3841
3892
|
const debug = argv.debug;
|
|
3842
3893
|
const localMcp = argv.local;
|
|
3843
3894
|
try {
|
|
3844
|
-
const { startTUI } = await import("./start-tui-
|
|
3845
|
-
const { buildSession } = await import("./wizard-session-
|
|
3895
|
+
const { startTUI } = await import("./start-tui-YE7bybIr.js");
|
|
3896
|
+
const { buildSession } = await import("./wizard-session-BKEdX9mO.js");
|
|
3846
3897
|
const tui = startTUI(VERSION, Program.McpRemove);
|
|
3847
3898
|
tui.store.session = buildSession({
|
|
3848
3899
|
debug,
|
|
@@ -3850,7 +3901,7 @@ function runMcpRemove(argv) {
|
|
|
3850
3901
|
});
|
|
3851
3902
|
} catch {
|
|
3852
3903
|
setUI(new LoggingUI());
|
|
3853
|
-
const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-
|
|
3904
|
+
const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-Dhq75Hda.js").then((n) => n.r);
|
|
3854
3905
|
await removeMCPServerFromClientsStep({ local: localMcp });
|
|
3855
3906
|
}
|
|
3856
3907
|
})();
|
|
@@ -3872,8 +3923,8 @@ function runMcpTutorial(argv) {
|
|
|
3872
3923
|
const debug = argv.debug;
|
|
3873
3924
|
const localMcp = argv.local;
|
|
3874
3925
|
try {
|
|
3875
|
-
const { startTUI } = await import("./start-tui-
|
|
3876
|
-
const { buildSession } = await import("./wizard-session-
|
|
3926
|
+
const { startTUI } = await import("./start-tui-YE7bybIr.js");
|
|
3927
|
+
const { buildSession } = await import("./wizard-session-BKEdX9mO.js");
|
|
3877
3928
|
const tui = startTUI(VERSION, Program.McpTutorial);
|
|
3878
3929
|
tui.store.session = buildSession({
|
|
3879
3930
|
debug,
|
|
@@ -3927,10 +3978,10 @@ function runWizard(config, options) {
|
|
|
3927
3978
|
(async () => {
|
|
3928
3979
|
try {
|
|
3929
3980
|
const installDir = options.installDir || process.cwd();
|
|
3930
|
-
const { startTUI } = await import("./start-tui-
|
|
3931
|
-
const { buildSession, RunPhase } = await import("./wizard-session-
|
|
3932
|
-
const { TaskStreamPush } = await import("./task-stream-
|
|
3933
|
-
const { PostHogDestination } = await import("./posthog-
|
|
3981
|
+
const { startTUI } = await import("./start-tui-YE7bybIr.js");
|
|
3982
|
+
const { buildSession, RunPhase } = await import("./wizard-session-BKEdX9mO.js");
|
|
3983
|
+
const { TaskStreamPush } = await import("./task-stream-CPjpHFhI.js");
|
|
3984
|
+
const { PostHogDestination } = await import("./posthog-DU6JXG00.js");
|
|
3934
3985
|
tui = startTUI(WIZARD_VERSION, config.id);
|
|
3935
3986
|
const activeTui = tui;
|
|
3936
3987
|
const session = buildSession({
|
|
@@ -3983,7 +4034,7 @@ function runWizard(config, options) {
|
|
|
3983
4034
|
await activeTui.store.getGate("health-check");
|
|
3984
4035
|
const skipAgent = config.run == null;
|
|
3985
4036
|
if (skipAgent) {
|
|
3986
|
-
const { getOrAskForProjectData } = await import("./setup-utils-
|
|
4037
|
+
const { getOrAskForProjectData } = await import("./setup-utils-CanVlGbX.js").then((n) => n.r);
|
|
3987
4038
|
const { projectApiKey, host, accessToken, projectId } = await getOrAskForProjectData({
|
|
3988
4039
|
signup: session.signup,
|
|
3989
4040
|
ci: session.ci,
|
|
@@ -3998,7 +4049,7 @@ function runWizard(config, options) {
|
|
|
3998
4049
|
projectId
|
|
3999
4050
|
});
|
|
4000
4051
|
} else {
|
|
4001
|
-
const { runAgent } = await import("./agent-runner-
|
|
4052
|
+
const { runAgent } = await import("./agent-runner-BRajaO84.js");
|
|
4002
4053
|
await runAgent(config, activeTui.store.session);
|
|
4003
4054
|
}
|
|
4004
4055
|
const isDone = () => skipAgent ? activeTui.store.session.outroDismissed : activeTui.store.session.skillsComplete;
|
|
@@ -4041,44 +4092,57 @@ function runWizard(config, options) {
|
|
|
4041
4092
|
})();
|
|
4042
4093
|
}
|
|
4043
4094
|
//#endregion
|
|
4044
|
-
//#region src/lib/runners/run-
|
|
4095
|
+
//#region src/lib/runners/run-non-interactive.ts
|
|
4096
|
+
/** User-facing label for a non-interactive mode. */
|
|
4097
|
+
function modeLabel(mode) {
|
|
4098
|
+
return mode === "headless" ? "Headless" : "CI";
|
|
4099
|
+
}
|
|
4045
4100
|
/**
|
|
4046
|
-
* The single
|
|
4047
|
-
* install-dir. Every
|
|
4048
|
-
* the one place these checks live. UI must be
|
|
4101
|
+
* The single non-interactive validation layer: defaults region and requires
|
|
4102
|
+
* api-key and install-dir. Every non-interactive entry point routes through
|
|
4103
|
+
* `runNonInteractive`, so this is the one place these checks live. UI must be
|
|
4104
|
+
* initialized before calling.
|
|
4049
4105
|
*/
|
|
4050
|
-
function
|
|
4106
|
+
function validateNonInteractiveOptions(options, mode) {
|
|
4107
|
+
const label = modeLabel(mode);
|
|
4108
|
+
const keyHint = mode === "headless" ? "personal API key phx_xxx or pha_ OAuth access token" : "personal API key phx_xxx";
|
|
4051
4109
|
if (!options.region) options.region = "us";
|
|
4052
4110
|
if (!options.apiKey) {
|
|
4053
4111
|
getUI().intro("PostHog Wizard");
|
|
4054
|
-
getUI().log.error(
|
|
4112
|
+
getUI().log.error(`${label} mode requires --api-key (${keyHint})`);
|
|
4055
4113
|
process.exit(1);
|
|
4056
4114
|
}
|
|
4057
4115
|
if (!options.installDir) {
|
|
4058
4116
|
getUI().intro("PostHog Wizard");
|
|
4059
|
-
getUI().log.error(
|
|
4117
|
+
getUI().log.error(`${label} mode requires --install-dir (directory to install in)`);
|
|
4060
4118
|
process.exit(1);
|
|
4061
4119
|
}
|
|
4062
4120
|
}
|
|
4063
4121
|
/**
|
|
4064
|
-
*
|
|
4122
|
+
* Non-interactive pipeline shared by CI (`runWizardCI`) and headless
|
|
4123
|
+
* (`runWizardHeadless`) runs.
|
|
4065
4124
|
*
|
|
4066
4125
|
* Validates flags, builds a `ci:true` session, runs `config.ciPreRun` (or the
|
|
4067
4126
|
* program's `onReady` hooks by default), executes `runAgent`, and routes any
|
|
4068
4127
|
* failure through `wizardAbort`. `wizardAbort` owns all exits — never add a
|
|
4069
4128
|
* raw `process.exit` here.
|
|
4129
|
+
*
|
|
4130
|
+
* `mode` is the only difference between the two callers today (it sets the
|
|
4131
|
+
* analytics build tag and the user-facing label). Keeping it a parameter is
|
|
4132
|
+
* what lets CI and headless share this body now and diverge later — branch on
|
|
4133
|
+
* `mode` here, or stop sharing this function entirely.
|
|
4070
4134
|
*/
|
|
4071
|
-
function
|
|
4135
|
+
function runNonInteractive(config, options, mode) {
|
|
4072
4136
|
setUI(new LoggingUI());
|
|
4073
|
-
|
|
4074
|
-
analytics.setTag("build",
|
|
4137
|
+
validateNonInteractiveOptions(options, mode);
|
|
4138
|
+
analytics.setTag("build", mode);
|
|
4075
4139
|
(async () => {
|
|
4076
4140
|
const path = await import("path");
|
|
4077
|
-
const { buildSession } = await import("./wizard-session-
|
|
4078
|
-
const { readEnvironment } = await import("./environment-
|
|
4141
|
+
const { buildSession, RunPhase, OutroKind } = await import("./wizard-session-BKEdX9mO.js");
|
|
4142
|
+
const { readEnvironment } = await import("./environment-G41UFzou.js").then((n) => n.t);
|
|
4079
4143
|
const { readApiKeyFromEnv } = await import("./env-api-key-MlzJYAvt.js").then((n) => n.t);
|
|
4080
|
-
const { configureLogFileFromEnvironment, logToFile } = await import("./debug-
|
|
4081
|
-
const { wizardAbort, WizardError } = await import("./wizard-abort-
|
|
4144
|
+
const { configureLogFileFromEnvironment, logToFile } = await import("./debug-BewTLNNr.js");
|
|
4145
|
+
const { wizardAbort, WizardError } = await import("./wizard-abort-DMvS0YXD.js");
|
|
4082
4146
|
configureLogFileFromEnvironment();
|
|
4083
4147
|
const env = readEnvironment();
|
|
4084
4148
|
const apiKey = options.apiKey ?? readApiKeyFromEnv() ?? void 0;
|
|
@@ -4101,7 +4165,34 @@ function runWizardCI(config, options) {
|
|
|
4101
4165
|
if (config.skillId) session.skillId = config.skillId;
|
|
4102
4166
|
const runDef = typeof config.run === "object" ? config.run : null;
|
|
4103
4167
|
getUI().intro("Welcome to the PostHog setup wizard");
|
|
4104
|
-
getUI().log.info(`Running ${config.id} in
|
|
4168
|
+
getUI().log.info(`Running ${config.id} in ${modeLabel(mode)} mode`);
|
|
4169
|
+
let store = null;
|
|
4170
|
+
let taskStream = null;
|
|
4171
|
+
if (mode === "headless") {
|
|
4172
|
+
const { WizardStore } = await import("./store-D15C9YSW.js").then((n) => n.n);
|
|
4173
|
+
const { HeadlessUI } = await import("./headless-ui-xjHVVUqe.js");
|
|
4174
|
+
const { TaskStreamPush, PostHogDestination } = await import("./task-stream-CPjpHFhI.js");
|
|
4175
|
+
store = new WizardStore(config.id);
|
|
4176
|
+
store.session = session;
|
|
4177
|
+
setUI(new HeadlessUI(store));
|
|
4178
|
+
taskStream = new TaskStreamPush({
|
|
4179
|
+
store,
|
|
4180
|
+
programId: config.id,
|
|
4181
|
+
destinations: [new PostHogDestination({
|
|
4182
|
+
getCredentials: () => session.credentials,
|
|
4183
|
+
onError: (e) => logToFile("[headless task-stream]", e.message)
|
|
4184
|
+
})],
|
|
4185
|
+
enabled: !session.noTelemetry
|
|
4186
|
+
});
|
|
4187
|
+
taskStream.attach();
|
|
4188
|
+
store.setRunPhase(RunPhase.Running);
|
|
4189
|
+
}
|
|
4190
|
+
const settleStream = async (phase, outroData) => {
|
|
4191
|
+
if (!store || !taskStream) return;
|
|
4192
|
+
if (outroData) store.setOutroData(outroData);
|
|
4193
|
+
store.setRunPhase(phase);
|
|
4194
|
+
await taskStream.shutdown(2e3);
|
|
4195
|
+
};
|
|
4105
4196
|
try {
|
|
4106
4197
|
if (config.ciPreRun) await config.ciPreRun(session);
|
|
4107
4198
|
else {
|
|
@@ -4121,24 +4212,36 @@ function runWizardCI(config, options) {
|
|
|
4121
4212
|
};
|
|
4122
4213
|
for (const step of config.steps) if (step.onReady) await step.onReady(readyCtx);
|
|
4123
4214
|
const detectError = session.frameworkContext.detectError;
|
|
4124
|
-
if (detectError)
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4215
|
+
if (detectError) {
|
|
4216
|
+
await settleStream(RunPhase.Error, {
|
|
4217
|
+
kind: OutroKind.Error,
|
|
4218
|
+
message: `Prerequisites not met: ${detectError.kind}`
|
|
4219
|
+
});
|
|
4220
|
+
await wizardAbort({
|
|
4221
|
+
message: `Prerequisites not met: ${detectError.kind}\n\nSee ${runDef?.docsUrl ?? "https://posthog.com/docs"}`,
|
|
4222
|
+
error: new WizardError(`${config.id} prerequisites failed`, {
|
|
4223
|
+
integration: config.id,
|
|
4224
|
+
detect_error_kind: detectError.kind
|
|
4225
|
+
})
|
|
4226
|
+
});
|
|
4227
|
+
}
|
|
4131
4228
|
}
|
|
4132
|
-
const { runAgent } = await import("./agent-runner-
|
|
4229
|
+
const { runAgent } = await import("./agent-runner-BRajaO84.js");
|
|
4133
4230
|
await runAgent(config, session);
|
|
4231
|
+
await settleStream(RunPhase.Completed);
|
|
4134
4232
|
} catch (error) {
|
|
4135
4233
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
4136
4234
|
const errorStack = error instanceof Error && error.stack ? error.stack : void 0;
|
|
4137
|
-
logToFile(`[
|
|
4138
|
-
if (errorStack) logToFile(`[
|
|
4235
|
+
logToFile(`[${mode}] ERROR: ${errorMessage}`);
|
|
4236
|
+
if (errorStack) logToFile(`[${mode}] STACK: ${errorStack}`);
|
|
4139
4237
|
const debugInfo = session.debug && errorStack ? `\n\n${errorStack}` : "";
|
|
4238
|
+
const docsUrl = session.frameworkConfig?.metadata.docsUrl ?? runDef?.docsUrl ?? "https://posthog.com/docs";
|
|
4239
|
+
await settleStream(RunPhase.Error, {
|
|
4240
|
+
kind: OutroKind.Error,
|
|
4241
|
+
message: errorMessage
|
|
4242
|
+
});
|
|
4140
4243
|
await wizardAbort({
|
|
4141
|
-
message: `Something went wrong: ${errorMessage}\n\nYou can read the documentation at ${
|
|
4244
|
+
message: `Something went wrong: ${errorMessage}\n\nYou can read the documentation at ${docsUrl} to set up manually.${debugInfo}`,
|
|
4142
4245
|
error
|
|
4143
4246
|
});
|
|
4144
4247
|
}
|
|
@@ -4147,6 +4250,31 @@ function runWizardCI(config, options) {
|
|
|
4147
4250
|
});
|
|
4148
4251
|
}
|
|
4149
4252
|
//#endregion
|
|
4253
|
+
//#region src/lib/runners/run-wizard-ci.ts
|
|
4254
|
+
/**
|
|
4255
|
+
* CI-mode entry point (`--ci`, dev/test builds). A thin shell over the shared
|
|
4256
|
+
* non-interactive pipeline — see `runNonInteractive`. Kept as its own function
|
|
4257
|
+
* so CI and headless (`runWizardHeadless`) can diverge without re-threading the
|
|
4258
|
+
* many callers that route here.
|
|
4259
|
+
*/
|
|
4260
|
+
function runWizardCI(config, options) {
|
|
4261
|
+
runNonInteractive(config, options, "ci");
|
|
4262
|
+
}
|
|
4263
|
+
//#endregion
|
|
4264
|
+
//#region src/lib/runners/run-wizard-headless.ts
|
|
4265
|
+
/**
|
|
4266
|
+
* Headless entry point (the experimental published-build, non-interactive run
|
|
4267
|
+
* path; see @lib/headless-mode). A thin shell over the shared non-interactive
|
|
4268
|
+
* pipeline — see `runNonInteractive`. Today it behaves exactly like
|
|
4269
|
+
* `runWizardCI`; it exists as a separate function so headless can diverge later
|
|
4270
|
+
* (its own auth handling, telemetry, prompts, …) without touching CI or its
|
|
4271
|
+
* callers. Diverge by branching on the mode inside `runNonInteractive`, or by
|
|
4272
|
+
* giving this function its own body.
|
|
4273
|
+
*/
|
|
4274
|
+
function runWizardHeadless(config, options) {
|
|
4275
|
+
runNonInteractive(config, options, "headless");
|
|
4276
|
+
}
|
|
4277
|
+
//#endregion
|
|
4150
4278
|
//#region src/commands/skill-program-options.ts
|
|
4151
4279
|
/**
|
|
4152
4280
|
* Per-command options shared by every skill-based program command
|
|
@@ -5025,7 +5153,7 @@ async function runDoctorCI(options) {
|
|
|
5025
5153
|
getUI().intro("Welcome to the PostHog setup wizard");
|
|
5026
5154
|
getUI().log.info("Running posthog-doctor in CI mode");
|
|
5027
5155
|
try {
|
|
5028
|
-
const { getOrAskForProjectData } = await import("./setup-utils-
|
|
5156
|
+
const { getOrAskForProjectData } = await import("./setup-utils-CanVlGbX.js").then((n) => n.r);
|
|
5029
5157
|
const { host, accessToken, projectId } = await getOrAskForProjectData({
|
|
5030
5158
|
signup: false,
|
|
5031
5159
|
ci: true,
|
|
@@ -5042,7 +5170,7 @@ async function runDoctorCI(options) {
|
|
|
5042
5170
|
for (const issue of sorted) getUI().log.info(` • [${issue.severity}] ${getKindMeta(issue.kind).title}`);
|
|
5043
5171
|
process.exit(1);
|
|
5044
5172
|
} catch (error) {
|
|
5045
|
-
const { ApiError } = await import("./api-
|
|
5173
|
+
const { ApiError } = await import("./api-BBRfHEZ-.js").then((n) => n.n);
|
|
5046
5174
|
const message = error instanceof ApiError && error.statusCode === 401 ? "Your PostHog API key is invalid or expired." : error instanceof Error ? error.message : String(error);
|
|
5047
5175
|
getUI().log.error(`Doctor failed: ${message}`);
|
|
5048
5176
|
process.exit(1);
|
|
@@ -5119,8 +5247,8 @@ function runSlackConnect(argv) {
|
|
|
5119
5247
|
(async () => {
|
|
5120
5248
|
const debug = argv.debug;
|
|
5121
5249
|
try {
|
|
5122
|
-
const { startTUI } = await import("./start-tui-
|
|
5123
|
-
const { buildSession } = await import("./wizard-session-
|
|
5250
|
+
const { startTUI } = await import("./start-tui-YE7bybIr.js");
|
|
5251
|
+
const { buildSession } = await import("./wizard-session-BKEdX9mO.js");
|
|
5124
5252
|
const tui = startTUI(VERSION, Program.SlackConnect);
|
|
5125
5253
|
tui.store.session = buildSession({ debug });
|
|
5126
5254
|
} catch (err) {
|
|
@@ -5498,6 +5626,6 @@ function resolveInstallDir() {
|
|
|
5498
5626
|
}
|
|
5499
5627
|
Wizard.use(basicIntegrationCommand).use(mcpCommand).use(mcpAnalyticsCommand).use(cliCommand).use(auditCommand).use(doctorCommand).use(migrateCommand).use(revenueCommand).use(warehouseCommand).use(selfDrivingCommand).use(slackCommand).use(uploadSourcemapsCommand).use(skillCommand).init();
|
|
5500
5628
|
//#endregion
|
|
5501
|
-
export {
|
|
5629
|
+
export { fetchHealthIssues as _, ConfirmButton as a, POSTHOG_SDKS as b, runWizardCI as c, Program as d, getProgramConfig as f, getKindMeta as g, SOURCE_MAPS_CONTEXT_KEYS as h, useKeyboardHintsContext as i, runWizard as l, DISPLAY_NAME as m, useKeyBindings as n, PromptLabel as o, AUTOMATABLE_VARIANTS as p, KeyboardHintsProvider as r, runWizardHeadless as s, PickerMenu as t, PROGRAM_REGISTRY as u, getDetectedWarehouseSources as v, STRIPE_SDKS as x, getContentBlocks$2 as y };
|
|
5502
5630
|
|
|
5503
5631
|
//# sourceMappingURL=bin.js.map
|