@posthog/wizard 2.41.0 → 2.43.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-Bvv6Vh5y.js → add-mcp-server-to-clients-BiZmRLE6.js} +5 -5
- package/dist/{add-mcp-server-to-clients-Bvv6Vh5y.js.map → add-mcp-server-to-clients-BiZmRLE6.js.map} +1 -1
- package/dist/{agent-interface-CFeI8jzW.js → agent-interface-CUaNjvqq.js} +8 -9
- package/dist/agent-interface-CUaNjvqq.js.map +1 -0
- package/dist/{agent-runner-B0pWHl5j.js → agent-runner-BuH7W62W.js} +143 -64
- package/dist/agent-runner-BuH7W62W.js.map +1 -0
- package/dist/{analytics-C1qxjbYZ.js → analytics-C_9Kh6J1.js} +5 -2
- package/dist/analytics-C_9Kh6J1.js.map +1 -0
- package/dist/analytics-o-WJHD8Z.js +2 -0
- package/dist/{api-CEMR_Aa6.js → api-Kgk7BFqo.js} +3 -3
- package/dist/{api-CEMR_Aa6.js.map → api-Kgk7BFqo.js.map} +1 -1
- package/dist/bin.js +87 -68
- package/dist/bin.js.map +1 -1
- package/dist/{ci-install-BBZscv3z.js → ci-install-DoARcA-j.js} +4 -4
- package/dist/{ci-install-BBZscv3z.js.map → ci-install-DoARcA-j.js.map} +1 -1
- package/dist/{debug-DBrsvcym.js → debug-CI0PLD6X.js} +1 -1
- package/dist/{debug-BMkCmZdo.js → debug-DNEQR5DL.js} +9 -5
- package/dist/debug-DNEQR5DL.js.map +1 -0
- package/dist/{defaults-BxiMLkQY.js → defaults-CeNThA-1.js} +1 -1
- package/dist/{defaults-BxiMLkQY.js.map → defaults-CeNThA-1.js.map} +1 -1
- package/dist/{env-api-key-DDVkPQmo.js → env-api-key-cjD4yfGT.js} +1 -1
- package/dist/{env-api-key-DDVkPQmo.js.map → env-api-key-cjD4yfGT.js.map} +1 -1
- package/dist/{environment-B7DmpnXD.js → environment-D44UP2Nu.js} +3 -3
- package/dist/{environment-B7DmpnXD.js.map → environment-D44UP2Nu.js.map} +1 -1
- package/dist/{file-utils-BCxAu-vq.js → file-utils-C2PNKLhr.js} +2 -2
- package/dist/{file-utils-BCxAu-vq.js.map → file-utils-C2PNKLhr.js.map} +1 -1
- package/dist/{headless-ui-NFf-5XOW.js → headless-ui-C3C0wWUi.js} +2 -2
- package/dist/{headless-ui-NFf-5XOW.js.map → headless-ui-C3C0wWUi.js.map} +1 -1
- package/dist/{interactive-CBrzEFly.js → interactive-k4xQiftO.js} +2 -2
- package/dist/{interactive-CBrzEFly.js.map → interactive-k4xQiftO.js.map} +1 -1
- package/dist/{mcp-C7dn0DIC.js → mcp-CJn_ryMN.js} +15 -19
- package/dist/mcp-CJn_ryMN.js.map +1 -0
- package/dist/{mcp-prompt-streaming-uXF2xskx.js → mcp-prompt-streaming-BB5nO--L.js} +8 -10
- package/dist/mcp-prompt-streaming-BB5nO--L.js.map +1 -0
- package/dist/{non-interactive-CDYGf19o.js → non-interactive-0x0Due8h.js} +2 -2
- package/dist/{non-interactive-CDYGf19o.js.map → non-interactive-0x0Due8h.js.map} +1 -1
- package/dist/{package-manager-BHAvpGav.js → package-manager-CBRR4_i4.js} +2 -2
- package/dist/{package-manager-BHAvpGav.js.map → package-manager-CBRR4_i4.js.map} +1 -1
- package/dist/{playground-B8OhYzyc.js → playground-CK617U6k.js} +26 -21
- package/dist/playground-CK617U6k.js.map +1 -0
- package/dist/{posthog-BHbtnNQE.js → posthog-DwKlq0HM.js} +2 -2
- package/dist/posthog-DwKlq0HM.js.map +1 -0
- package/dist/{posthog-integration-G839iLK6.js → posthog-integration-qRjKkLcu.js} +25 -25
- package/dist/posthog-integration-qRjKkLcu.js.map +1 -0
- package/dist/{provisioning-BOhuDX6i.js → provisioning-BMXR8fS1.js} +67 -6
- package/dist/provisioning-BMXR8fS1.js.map +1 -0
- package/dist/{registry-CC26CjWO.js → registry-CsUUdVCd.js} +4 -4
- package/dist/{registry-CC26CjWO.js.map → registry-CsUUdVCd.js.map} +1 -1
- package/dist/{security-wlqqLk44.js → security-CIP3lpp6.js} +4 -4
- package/dist/{security-wlqqLk44.js.map → security-CIP3lpp6.js.map} +1 -1
- package/dist/{setup-utils-NwB2Qj6N.js → setup-utils-DkyEOBDx.js} +137 -32
- package/dist/setup-utils-DkyEOBDx.js.map +1 -0
- package/dist/{start-tui-DQndpyTU.js → start-tui-CJlIgYjf.js} +36 -30
- package/dist/start-tui-CJlIgYjf.js.map +1 -0
- package/dist/{steps-CC_Ge4sR.js → steps-CuNjxYsA.js} +7 -7
- package/dist/{steps-CC_Ge4sR.js.map → steps-CuNjxYsA.js.map} +1 -1
- package/dist/{store-1-pQpHlY.js → store-UKAJftq6.js} +5 -5
- package/dist/{store-1-pQpHlY.js.map → store-UKAJftq6.js.map} +1 -1
- package/dist/{subagent-FMDybA8X.js → subagent-_syej145.js} +2 -2
- package/dist/{subagent-FMDybA8X.js.map → subagent-_syej145.js.map} +1 -1
- package/dist/{task-stream-d-R9J0g4.js → task-stream-Ne-9ZOnf.js} +3 -3
- package/dist/{task-stream-d-R9J0g4.js.map → task-stream-Ne-9ZOnf.js.map} +1 -1
- package/dist/{tasks-BfDJpHgK.js → tasks-CUvCA1OY.js} +2 -2
- package/dist/{tasks-BfDJpHgK.js.map → tasks-CUvCA1OY.js.map} +1 -1
- package/dist/{telemetry-CcysC4ji.js → telemetry-DFYgJHH-.js} +3 -3
- package/dist/{telemetry-CcysC4ji.js.map → telemetry-DFYgJHH-.js.map} +1 -1
- package/dist/{terminal-CWpmzTgT.js → terminal-DLFgIxhg.js} +49 -25
- package/dist/terminal-DLFgIxhg.js.map +1 -0
- package/dist/{tools-BsOywKLp.js → tools-CNyhLqlK.js} +4 -4
- package/dist/{tools-BsOywKLp.js.map → tools-CNyhLqlK.js.map} +1 -1
- package/dist/{types-evL_rPob.js → types-y3HkjtSq.js} +1 -1
- package/dist/{types-evL_rPob.js.map → types-y3HkjtSq.js.map} +1 -1
- package/dist/{wizard-abort-56bo4Zhs.js → wizard-abort-BM3pISoR.js} +4 -4
- package/dist/{wizard-abort-56bo4Zhs.js.map → wizard-abort-BM3pISoR.js.map} +1 -1
- package/dist/{wizard-abort-7oUXxutu.js → wizard-abort-DCv08-op.js} +1 -1
- package/dist/{wizard-session-BoXAZEOf.js → wizard-session-BudcixsA.js} +1 -2
- package/dist/wizard-session-BudcixsA.js.map +1 -0
- package/dist/{wizard-session-C8W_6X0j.js → wizard-session-DXivb7kv.js} +1 -1
- package/dist/{wizard-tools-BXd4PCO3.js → wizard-tools-BcuRxp1A.js} +6 -4
- package/dist/wizard-tools-BcuRxp1A.js.map +1 -0
- package/dist/wizard-ui-WZ48rUgr.js.map +1 -1
- package/dist/yara-hooks-DKbfESYf.js +2 -0
- package/dist/{yara-hooks-BZmYgr9V.js → yara-hooks-GIs-R_g1.js} +4 -4
- package/dist/{yara-hooks-BZmYgr9V.js.map → yara-hooks-GIs-R_g1.js.map} +1 -1
- package/package.json +1 -1
- package/dist/agent-interface-CFeI8jzW.js.map +0 -1
- package/dist/agent-runner-B0pWHl5j.js.map +0 -1
- package/dist/analytics-C1qxjbYZ.js.map +0 -1
- package/dist/analytics-_8xKpUAa.js +0 -2
- package/dist/debug-BMkCmZdo.js.map +0 -1
- package/dist/host-resolution-UZELMVTQ.js +0 -115
- package/dist/host-resolution-UZELMVTQ.js.map +0 -1
- package/dist/mcp-C7dn0DIC.js.map +0 -1
- package/dist/mcp-prompt-streaming-uXF2xskx.js.map +0 -1
- package/dist/playground-B8OhYzyc.js.map +0 -1
- package/dist/posthog-BHbtnNQE.js.map +0 -1
- package/dist/posthog-integration-G839iLK6.js.map +0 -1
- package/dist/provisioning-BOhuDX6i.js.map +0 -1
- package/dist/setup-utils-NwB2Qj6N.js.map +0 -1
- package/dist/start-tui-DQndpyTU.js.map +0 -1
- package/dist/terminal-CWpmzTgT.js.map +0 -1
- package/dist/urls-PfZ1TYOf.js +0 -67
- package/dist/urls-PfZ1TYOf.js.map +0 -1
- package/dist/wizard-session-BoXAZEOf.js.map +0 -1
- package/dist/wizard-tools-BXd4PCO3.js.map +0 -1
- package/dist/yara-hooks-D0h7Vu7A.js +0 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY,
|
|
1
|
+
import { b as ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY, ht as RUN_SURFACE, r as debug, s as logToFile, x as ANALYTICS_TEAM_TAG, y as ANALYTICS_HOST_URL } from "./debug-DNEQR5DL.js";
|
|
2
2
|
import { PostHog } from "posthog-node";
|
|
3
3
|
import { v4 } from "uuid";
|
|
4
4
|
//#region src/utils/ci-flag-overrides.ts
|
|
@@ -54,6 +54,7 @@ var Analytics = class {
|
|
|
54
54
|
activeFlags = null;
|
|
55
55
|
groups = {};
|
|
56
56
|
personProperties = {};
|
|
57
|
+
terminalEventSent = false;
|
|
57
58
|
constructor() {
|
|
58
59
|
this.client = new PostHog(ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY, {
|
|
59
60
|
host: ANALYTICS_HOST_URL,
|
|
@@ -212,6 +213,8 @@ var Analytics = class {
|
|
|
212
213
|
}
|
|
213
214
|
async shutdown(status) {
|
|
214
215
|
if (Object.keys(this.tags).length === 0) return;
|
|
216
|
+
if (this.terminalEventSent) return;
|
|
217
|
+
this.terminalEventSent = true;
|
|
215
218
|
this.client.capture({
|
|
216
219
|
distinctId: this.distinctId ?? this.anonymousId,
|
|
217
220
|
event: "setup wizard finished",
|
|
@@ -230,4 +233,4 @@ const analytics = new Analytics();
|
|
|
230
233
|
//#endregion
|
|
231
234
|
export { ciExcludedTaskTypes as a, sessionProperties as i, analytics as n, groupsFromUser as r, Analytics as t };
|
|
232
235
|
|
|
233
|
-
//# sourceMappingURL=analytics-
|
|
236
|
+
//# sourceMappingURL=analytics-C_9Kh6J1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics-C_9Kh6J1.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, RUN_SURFACE } 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 private terminalEventSent = false;\n\n constructor() {\n this.client = new PostHog(ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY, {\n host: ANALYTICS_HOST_URL,\n flushAt: 1,\n flushInterval: 0,\n enableExceptionAutocapture: true,\n before_send: (event) => {\n if (!event) return event;\n if (Object.keys(this.groups).length > 0) {\n event.groups = { ...this.groups, ...event.groups };\n }\n // Autocaptured exceptions arrive with a random uuid and\n // `$process_person_profile: false` — reattach the run's identity\n // and tags so they land on the same person as everything else.\n if (event.event === '$exception') {\n event.distinctId = this.distinctId ?? this.anonymousId;\n const { $process_person_profile, ...properties } =\n event.properties ?? {};\n void $process_person_profile;\n event.properties = { ...this.tags, ...properties };\n }\n return event;\n },\n });\n\n this.tags = { $app_name: this.appName };\n // Tag every run with its build type so prod / dev / ci / headless segment\n // cleanly in analytics. tsdown inlines IS_PRODUCTION_BUILD to `true` in\n // published builds and `false` for dev/tsx/test runs. Non-interactive runs\n // upgrade this in runWizardCI: dev `--ci` runs to 'ci', published headless\n // runs to 'headless'.\n this.tags.build = IS_PRODUCTION_BUILD ? 'prod' : 'dev';\n\n this.tags.run_surface = RUN_SURFACE;\n\n 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 // First status wins. The interrupt fallback in start-tui fires\n // shutdown('cancelled') on every TUI teardown; without this guard a run\n // that already reported 'success' would emit a second, contradicting\n // terminal event when the user dismisses the outro.\n if (this.terminalEventSent) {\n return;\n }\n this.terminalEventSent = true;\n\n this.client.capture({\n distinctId: this.distinctId ?? this.anonymousId,\n event: 'setup wizard finished',\n properties: {\n // Flat for filtering; the nested `tags` snapshot stays for back-compat.\n ...this.tags,\n run_id: this._runId,\n ...(this.sessionId ? { $session_id: this.sessionId } : {}),\n status,\n tags: this.tags,\n },\n });\n\n await this.client.shutdown();\n }\n}\n\nexport const analytics = new Analytics();\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-B_-DWIq7.js";
|
|
2
|
-
import {
|
|
3
|
-
import { n as analytics } from "./analytics-
|
|
2
|
+
import { ut as WIZARD_USER_AGENT } from "./debug-DNEQR5DL.js";
|
|
3
|
+
import { n as analytics } from "./analytics-C_9Kh6J1.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-Kgk7BFqo.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-CEMR_Aa6.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-Kgk7BFqo.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,23 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { n as analytics } from "./analytics-
|
|
4
|
-
import { r as setEntryCommand } from "./telemetry-
|
|
5
|
-
import { n as isUsingTypeScript } from "./setup-utils-
|
|
6
|
-
import { o as
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
import "./
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import { h as
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import { n as safeReadFile, r as walkProjectFiles, t as IGNORED_DIRS } from "./file-utils-BCxAu-vq.js";
|
|
20
|
-
import { n as readApiKeyFromEnv } from "./env-api-key-DDVkPQmo.js";
|
|
2
|
+
import { L as Integration, U as POSTHOG_DOCS_URL, _t as HEADLESS_FLAG, a as getLogFilePath, f as getUI, ft as getSkillsBaseUrl, m as LoggingUI, p as setUI, pt as VERSION, r as debug, s as logToFile, ut as WIZARD_USER_AGENT, vt as isHeadless } from "./debug-DNEQR5DL.js";
|
|
3
|
+
import { n as analytics } from "./analytics-C_9Kh6J1.js";
|
|
4
|
+
import { r as setEntryCommand } from "./telemetry-DFYgJHH-.js";
|
|
5
|
+
import { n as isUsingTypeScript } from "./setup-utils-DkyEOBDx.js";
|
|
6
|
+
import { o as handleApiError } from "./api-Kgk7BFqo.js";
|
|
7
|
+
import "./wizard-session-BudcixsA.js";
|
|
8
|
+
import { r as runCleanups } from "./wizard-abort-BM3pISoR.js";
|
|
9
|
+
import { n as isNonInteractiveEnvironment } from "./environment-D44UP2Nu.js";
|
|
10
|
+
import { n as runAgent, o as authenticate } from "./agent-runner-BuH7W62W.js";
|
|
11
|
+
import { l as recoverOrphanedSettingsBackups, p as AgentSignals } from "./agent-interface-CUaNjvqq.js";
|
|
12
|
+
import { i as fetchSkillMenu, t as WIZARD_TOOL_NAMES } from "./wizard-tools-BcuRxp1A.js";
|
|
13
|
+
import { n as AUDIT_CHECKS_KEY, r as AUDIT_REPORT_FILE, t as AUDIT_CHECKS_FILE } from "./types-y3HkjtSq.js";
|
|
14
|
+
import { h as SETUP_REPORT_FILE } from "./yara-hooks-GIs-R_g1.js";
|
|
15
|
+
import { i as SPINNER_MESSAGE, t as FRAMEWORK_REGISTRY } from "./registry-CsUUdVCd.js";
|
|
16
|
+
import { _ as gatherFrameworkContext, a as LINE_CHART_BLOCK, b as parseRequirementsTxt, g as detectProjectsWithAgent, h as HEALTH_CHECK_STEP, i as FUNNEL_BLOCK, m as Icons, n as integrationRunStep, o as PRODUCT_SUITE_BLOCK, p as Colors, r as posthogIntegrationConfig, s as StatusPeekTrigger, u as isClearBlock, v as parsePipfile, y as parsePyprojectToml } from "./posthog-integration-qRjKkLcu.js";
|
|
17
|
+
import { n as safeReadFile, r as walkProjectFiles, t as IGNORED_DIRS } from "./file-utils-C2PNKLhr.js";
|
|
18
|
+
import { n as readApiKeyFromEnv } from "./env-api-key-cjD4yfGT.js";
|
|
21
19
|
import { satisfies } from "semver";
|
|
22
20
|
import yargs from "yargs";
|
|
23
21
|
import { hideBin } from "yargs/helpers";
|
|
@@ -214,7 +212,7 @@ function runProvision(argv) {
|
|
|
214
212
|
}
|
|
215
213
|
async function provision({ email, region, name, baseUrl, jsonMode }) {
|
|
216
214
|
try {
|
|
217
|
-
const { provisionNewAccount } = await import("./provisioning-
|
|
215
|
+
const { provisionNewAccount } = await import("./provisioning-BMXR8fS1.js").then((n) => n.n);
|
|
218
216
|
if (!jsonMode) getUI().log.info(`Provisioning account for ${email} in ${region}...`);
|
|
219
217
|
emitResult(await provisionNewAccount(email, name, region, { baseUrl }), jsonMode);
|
|
220
218
|
process.exit(0);
|
|
@@ -279,22 +277,22 @@ const basicIntegrationCommand = {
|
|
|
279
277
|
setEntryCommand("integrate");
|
|
280
278
|
(async () => {
|
|
281
279
|
if (isHeadless(argv)) {
|
|
282
|
-
const { runHeadlessInstall } = await import("./ci-install-
|
|
280
|
+
const { runHeadlessInstall } = await import("./ci-install-DoARcA-j.js");
|
|
283
281
|
return runHeadlessInstall(argv);
|
|
284
282
|
}
|
|
285
283
|
if (argv.ci) {
|
|
286
|
-
const { runCIInstall } = await import("./ci-install-
|
|
284
|
+
const { runCIInstall } = await import("./ci-install-DoARcA-j.js");
|
|
287
285
|
return runCIInstall(argv);
|
|
288
286
|
}
|
|
289
287
|
if (isNonInteractiveEnvironment()) {
|
|
290
|
-
const { failNonInteractive } = await import("./non-interactive-
|
|
288
|
+
const { failNonInteractive } = await import("./non-interactive-0x0Due8h.js");
|
|
291
289
|
return failNonInteractive();
|
|
292
290
|
}
|
|
293
291
|
if (argv.playground) {
|
|
294
|
-
const { runPlayground } = await import("./playground-
|
|
292
|
+
const { runPlayground } = await import("./playground-CK617U6k.js");
|
|
295
293
|
return runPlayground();
|
|
296
294
|
}
|
|
297
|
-
const { runInteractive } = await import("./interactive-
|
|
295
|
+
const { runInteractive } = await import("./interactive-k4xQiftO.js");
|
|
298
296
|
runInteractive(argv);
|
|
299
297
|
})();
|
|
300
298
|
}
|
|
@@ -1334,6 +1332,9 @@ function detectWarehousePrerequisites(session, setFrameworkContext) {
|
|
|
1334
1332
|
fail({ kind: "no-sources" });
|
|
1335
1333
|
return;
|
|
1336
1334
|
}
|
|
1335
|
+
analytics.setTag("warehouse_source_kinds", sources.map((s) => s.kind).join(","));
|
|
1336
|
+
analytics.setTag("warehouse_source_modes", sources.map((s) => `${s.kind}:${s.mode}`).join(","));
|
|
1337
|
+
analytics.setTag("warehouse_source_count", sources.length);
|
|
1337
1338
|
setFrameworkContext(DETECTED_WAREHOUSE_SOURCES_KEY, sources);
|
|
1338
1339
|
}
|
|
1339
1340
|
//#endregion
|
|
@@ -1619,9 +1620,9 @@ const auditRun = async (session) => {
|
|
|
1619
1620
|
const baseRun = typeof baseConfig.run === "function" ? await baseConfig.run(session) : baseConfig.run;
|
|
1620
1621
|
return {
|
|
1621
1622
|
...baseRun,
|
|
1622
|
-
buildOutroData: (
|
|
1623
|
-
const cloudUrl =
|
|
1624
|
-
const continueUrl =
|
|
1623
|
+
buildOutroData: (sess, credentials) => {
|
|
1624
|
+
const cloudUrl = credentials.host.appHost;
|
|
1625
|
+
const continueUrl = sess.signup ? `${cloudUrl}/products?source=wizard` : void 0;
|
|
1625
1626
|
return {
|
|
1626
1627
|
kind: "success",
|
|
1627
1628
|
message: baseRun.successMessage,
|
|
@@ -1782,17 +1783,17 @@ Project context:
|
|
|
1782
1783
|
- PostHog Project ID: ${ctx.projectId}
|
|
1783
1784
|
- TypeScript: ${typeScriptDetected ? "Yes" : "No"}
|
|
1784
1785
|
- PostHog public token: ${ctx.projectApiKey}
|
|
1785
|
-
- PostHog Host: ${ctx.host}
|
|
1786
|
+
- PostHog Host: ${ctx.host.apiHost}
|
|
1786
1787
|
`,
|
|
1787
|
-
buildOutroData: (sess,
|
|
1788
|
-
const cloudUrl =
|
|
1788
|
+
buildOutroData: (sess, credentials) => {
|
|
1789
|
+
const cloudUrl = credentials.host.appHost;
|
|
1789
1790
|
return {
|
|
1790
1791
|
kind: "success",
|
|
1791
1792
|
message: "Your events audit was successful",
|
|
1792
1793
|
reportFile: SETUP_REPORT_FILE,
|
|
1793
1794
|
changes: [],
|
|
1794
1795
|
docsUrl: DOCS_URL$3,
|
|
1795
|
-
continueUrl: sess.signup
|
|
1796
|
+
continueUrl: sess.signup ? `${cloudUrl}/products?source=wizard` : void 0,
|
|
1796
1797
|
dashboardUrl: sess.dashboardUrl ?? (cloudUrl ? `${cloudUrl}/dashboard` : void 0),
|
|
1797
1798
|
notebookUrl: sess.notebookUrl ?? void 0
|
|
1798
1799
|
};
|
|
@@ -3207,14 +3208,14 @@ const errorTrackingUploadSourceMapsConfig = {
|
|
|
3207
3208
|
customPrompt: (ctx) => {
|
|
3208
3209
|
const { variant, displayName, projectPath, skillId } = readSelection();
|
|
3209
3210
|
if (!skillId || !variant) return SOURCE_MAPS_DETECTION_FAILED_PROMPT;
|
|
3210
|
-
const uiHost =
|
|
3211
|
+
const uiHost = ctx.host.appHost.replace(/\/$/, "");
|
|
3211
3212
|
return buildSourceMapsUploadPrompt({
|
|
3212
3213
|
displayName,
|
|
3213
3214
|
variant,
|
|
3214
3215
|
skillId,
|
|
3215
3216
|
projectPath,
|
|
3216
3217
|
projectId: ctx.projectId,
|
|
3217
|
-
host: ctx.host,
|
|
3218
|
+
host: ctx.host.apiHost,
|
|
3218
3219
|
settingsUrl: `${uiHost}/project/${ctx.projectId}/settings/user-api-keys`,
|
|
3219
3220
|
uiHost
|
|
3220
3221
|
});
|
|
@@ -3632,7 +3633,7 @@ const SELF_DRIVING_PROGRAM = [
|
|
|
3632
3633
|
* list — so this prompt only covers the Self-driving steps.
|
|
3633
3634
|
*/
|
|
3634
3635
|
function buildSelfDrivingPrompt(ctx) {
|
|
3635
|
-
const uiHost =
|
|
3636
|
+
const uiHost = ctx.host.appHost.replace(/\/$/, "");
|
|
3636
3637
|
const projectBase = `${uiHost}/project/${ctx.projectId}`;
|
|
3637
3638
|
const integrationsSettingsUrl = `${projectBase}/settings/environment-integrations`;
|
|
3638
3639
|
const orgAiSettingsUrl = `${uiHost}/settings/organization#organization-ai-consent`;
|
|
@@ -3743,7 +3744,11 @@ STEP 5 — Offer issue-tracker integrations. (skill: "Connected tools")
|
|
|
3743
3744
|
One batched multi-select wizard_ask for the external tools the skill
|
|
3744
3745
|
lists. The run auto-connects the ones it can (GitHub Issues, and
|
|
3745
3746
|
Linear via a one-click OAuth link), verifying each with a single
|
|
3746
|
-
silent check — never nudge.
|
|
3747
|
+
silent check — never nudge. For GitHub Issues: when the GitHub
|
|
3748
|
+
integration has exactly one repository connected, use that repo by
|
|
3749
|
+
default and skip repo research entirely — research which repo
|
|
3750
|
+
matches this project only when several are connected. It arms the
|
|
3751
|
+
rest as dormant responders to
|
|
3747
3752
|
finish later: for tools it can't auto-connect (Zendesk, pganalyze) it
|
|
3748
3753
|
never sends the user to paste credentials and never re-prompts. Enable
|
|
3749
3754
|
a source only for a tool the user picked.
|
|
@@ -3757,7 +3762,11 @@ STEP 6b — Design custom scouts for this product. (skill: "Custom scouts")
|
|
|
3757
3762
|
You are the only actor that has read this repo — turn that into
|
|
3758
3763
|
coverage per the skill: a real gap analysis of the project's
|
|
3759
3764
|
watchable surfaces against what the built-in troop already covers,
|
|
3760
|
-
then custom scouts for the uncovered ones.
|
|
3765
|
+
then custom scouts for the uncovered ones. Start the gap analysis
|
|
3766
|
+
from the repo's for-agents context when present (AGENTS.md,
|
|
3767
|
+
CLAUDE.md, ARCHITECTURE.md, .cursor/rules, agent-facing docs) — it
|
|
3768
|
+
is a maintained map of the product's surfaces and vocabulary, so
|
|
3769
|
+
read it before scanning source. Keep scout bodies
|
|
3761
3770
|
high-level: describe the behavior and signal conditions to watch,
|
|
3762
3771
|
referencing repo evidence by file/function name — never paste raw
|
|
3763
3772
|
source, secrets, env values, or customer data into a scout body.
|
|
@@ -3795,6 +3804,11 @@ const SELF_DRIVING_TIPS = [
|
|
|
3795
3804
|
title: "The loop",
|
|
3796
3805
|
description: "After a fix ships, PostHog measures the result. If the pattern persists, a new signal reopens the work."
|
|
3797
3806
|
},
|
|
3807
|
+
{
|
|
3808
|
+
id: "pricing",
|
|
3809
|
+
title: "What it costs",
|
|
3810
|
+
description: "Watching is free. You pay a flat $15 only when a report ships a PR."
|
|
3811
|
+
},
|
|
3798
3812
|
{
|
|
3799
3813
|
id: "work-anywhere",
|
|
3800
3814
|
title: "Work anywhere",
|
|
@@ -4031,6 +4045,10 @@ const getContentBlocks = (store) => {
|
|
|
4031
4045
|
content: "Investigate with the agent, tag teammates, or kick off a PR.",
|
|
4032
4046
|
pause: 6e3
|
|
4033
4047
|
},
|
|
4048
|
+
{
|
|
4049
|
+
content: "That PR is the only thing you pay for: a flat $15 per report that ships a PR. Watching is free.",
|
|
4050
|
+
pause: 6e3
|
|
4051
|
+
},
|
|
4034
4052
|
CLEAR,
|
|
4035
4053
|
{
|
|
4036
4054
|
content: "And after the PR ships, PostHog measures the result.",
|
|
@@ -4157,17 +4175,18 @@ const run = {
|
|
|
4157
4175
|
message: SUCCESS_MESSAGE,
|
|
4158
4176
|
primaryLink: {
|
|
4159
4177
|
label: "Your Self-driving inbox",
|
|
4160
|
-
url: `${
|
|
4178
|
+
url: `${credentials.host.appHost.replace(/\/$/, "")}/project/${credentials.projectId}/inbox`
|
|
4161
4179
|
},
|
|
4162
4180
|
nextSteps: {
|
|
4163
4181
|
heading: "In your inbox you can:",
|
|
4164
4182
|
items: [
|
|
4165
4183
|
"Investigate reports with the agent",
|
|
4166
4184
|
"Tag teammates to loop them in",
|
|
4167
|
-
"Kick off a PR when you like the proposed fix",
|
|
4185
|
+
"Kick off a PR when you like the proposed fix ($15 flat)",
|
|
4168
4186
|
"Or work from Slack (tag @PostHog) and MCP"
|
|
4169
4187
|
]
|
|
4170
4188
|
},
|
|
4189
|
+
body: "Pricing: scouts, signals, and reports are free. You pay a flat $15 only when a report ships a PR.",
|
|
4171
4190
|
reportFile: REPORT_FILE
|
|
4172
4191
|
};
|
|
4173
4192
|
}
|
|
@@ -4418,13 +4437,13 @@ const mcpAddCommand = {
|
|
|
4418
4437
|
function runMcpAdd(argv) {
|
|
4419
4438
|
const features = parseFeatures(argv.features);
|
|
4420
4439
|
(async () => {
|
|
4421
|
-
const { readApiKeyFromEnv } = await import("./env-api-key-
|
|
4440
|
+
const { readApiKeyFromEnv } = await import("./env-api-key-cjD4yfGT.js").then((n) => n.t);
|
|
4422
4441
|
const apiKey = argv.apiKey || readApiKeyFromEnv();
|
|
4423
4442
|
const debug = argv.debug;
|
|
4424
4443
|
const localMcp = argv.local;
|
|
4425
4444
|
try {
|
|
4426
|
-
const { startTUI } = await import("./start-tui-
|
|
4427
|
-
const { buildSession } = await import("./wizard-session-
|
|
4445
|
+
const { startTUI } = await import("./start-tui-CJlIgYjf.js");
|
|
4446
|
+
const { buildSession } = await import("./wizard-session-DXivb7kv.js");
|
|
4428
4447
|
const tui = startTUI(VERSION, Program.McpAdd);
|
|
4429
4448
|
tui.store.session = buildSession({
|
|
4430
4449
|
debug,
|
|
@@ -4436,7 +4455,7 @@ function runMcpAdd(argv) {
|
|
|
4436
4455
|
} catch (error) {
|
|
4437
4456
|
if (!isTUIUnavailable(error)) throw error;
|
|
4438
4457
|
setUI(new LoggingUI());
|
|
4439
|
-
const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-
|
|
4458
|
+
const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-BiZmRLE6.js").then((n) => n.r);
|
|
4440
4459
|
await addMCPServerToClientsStep({
|
|
4441
4460
|
local: localMcp,
|
|
4442
4461
|
features,
|
|
@@ -4475,8 +4494,8 @@ function runMcpRemove(argv) {
|
|
|
4475
4494
|
const debug = argv.debug;
|
|
4476
4495
|
const localMcp = argv.local;
|
|
4477
4496
|
try {
|
|
4478
|
-
const { startTUI } = await import("./start-tui-
|
|
4479
|
-
const { buildSession } = await import("./wizard-session-
|
|
4497
|
+
const { startTUI } = await import("./start-tui-CJlIgYjf.js");
|
|
4498
|
+
const { buildSession } = await import("./wizard-session-DXivb7kv.js");
|
|
4480
4499
|
const tui = startTUI(VERSION, Program.McpRemove);
|
|
4481
4500
|
tui.store.session = buildSession({
|
|
4482
4501
|
debug,
|
|
@@ -4485,7 +4504,7 @@ function runMcpRemove(argv) {
|
|
|
4485
4504
|
});
|
|
4486
4505
|
} catch {
|
|
4487
4506
|
setUI(new LoggingUI());
|
|
4488
|
-
const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-
|
|
4507
|
+
const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-BiZmRLE6.js").then((n) => n.r);
|
|
4489
4508
|
await removeMCPServerFromClientsStep({ local: localMcp });
|
|
4490
4509
|
}
|
|
4491
4510
|
})();
|
|
@@ -4507,8 +4526,8 @@ function runMcpTutorial(argv) {
|
|
|
4507
4526
|
const debug = argv.debug;
|
|
4508
4527
|
const localMcp = argv.local;
|
|
4509
4528
|
try {
|
|
4510
|
-
const { startTUI } = await import("./start-tui-
|
|
4511
|
-
const { buildSession } = await import("./wizard-session-
|
|
4529
|
+
const { startTUI } = await import("./start-tui-CJlIgYjf.js");
|
|
4530
|
+
const { buildSession } = await import("./wizard-session-DXivb7kv.js");
|
|
4512
4531
|
const tui = startTUI(VERSION, Program.McpTutorial);
|
|
4513
4532
|
tui.store.session = buildSession({
|
|
4514
4533
|
debug,
|
|
@@ -4588,10 +4607,10 @@ function runWizard(config, options) {
|
|
|
4588
4607
|
(async () => {
|
|
4589
4608
|
try {
|
|
4590
4609
|
const installDir = options.installDir || process.cwd();
|
|
4591
|
-
const { startTUI } = await import("./start-tui-
|
|
4592
|
-
const { buildSession, RunPhase } = await import("./wizard-session-
|
|
4593
|
-
const { TaskStreamPush } = await import("./task-stream-
|
|
4594
|
-
const { PostHogDestination } = await import("./posthog-
|
|
4610
|
+
const { startTUI } = await import("./start-tui-CJlIgYjf.js");
|
|
4611
|
+
const { buildSession, RunPhase } = await import("./wizard-session-DXivb7kv.js");
|
|
4612
|
+
const { TaskStreamPush } = await import("./task-stream-Ne-9ZOnf.js");
|
|
4613
|
+
const { PostHogDestination } = await import("./posthog-DwKlq0HM.js");
|
|
4595
4614
|
tui = startTUI(WIZARD_VERSION, config.id);
|
|
4596
4615
|
const activeTui = tui;
|
|
4597
4616
|
const session = buildSession({
|
|
@@ -4655,7 +4674,7 @@ function runWizard(config, options) {
|
|
|
4655
4674
|
if (shown(step)) await advanceStep(step, activeTui.store, config);
|
|
4656
4675
|
}
|
|
4657
4676
|
else if (skipAgent) {
|
|
4658
|
-
const { getOrAskForProjectData } = await import("./setup-utils-
|
|
4677
|
+
const { getOrAskForProjectData } = await import("./setup-utils-DkyEOBDx.js").then((n) => n.r);
|
|
4659
4678
|
const { projectApiKey, host, accessToken, projectId } = await getOrAskForProjectData({
|
|
4660
4679
|
signup: session.signup,
|
|
4661
4680
|
ci: session.ci,
|
|
@@ -4757,11 +4776,11 @@ function runNonInteractive(config, options, mode) {
|
|
|
4757
4776
|
analytics.setTag("build", mode);
|
|
4758
4777
|
(async () => {
|
|
4759
4778
|
const path = await import("path");
|
|
4760
|
-
const { buildSession, RunPhase, OutroKind } = await import("./wizard-session-
|
|
4761
|
-
const { readEnvironment } = await import("./environment-
|
|
4762
|
-
const { readApiKeyFromEnv } = await import("./env-api-key-
|
|
4763
|
-
const { configureLogFileFromEnvironment, logToFile } = await import("./debug-
|
|
4764
|
-
const { wizardAbort, WizardError } = await import("./wizard-abort-
|
|
4779
|
+
const { buildSession, RunPhase, OutroKind } = await import("./wizard-session-DXivb7kv.js");
|
|
4780
|
+
const { readEnvironment } = await import("./environment-D44UP2Nu.js").then((n) => n.t);
|
|
4781
|
+
const { readApiKeyFromEnv } = await import("./env-api-key-cjD4yfGT.js").then((n) => n.t);
|
|
4782
|
+
const { configureLogFileFromEnvironment, logToFile } = await import("./debug-CI0PLD6X.js");
|
|
4783
|
+
const { wizardAbort, WizardError } = await import("./wizard-abort-DCv08-op.js");
|
|
4765
4784
|
configureLogFileFromEnvironment();
|
|
4766
4785
|
const env = readEnvironment();
|
|
4767
4786
|
const apiKey = options.apiKey ?? readApiKeyFromEnv() ?? void 0;
|
|
@@ -4792,9 +4811,9 @@ function runNonInteractive(config, options, mode) {
|
|
|
4792
4811
|
let store = null;
|
|
4793
4812
|
let taskStream = null;
|
|
4794
4813
|
if (mode === "headless") {
|
|
4795
|
-
const { WizardStore } = await import("./store-
|
|
4796
|
-
const { HeadlessUI } = await import("./headless-ui-
|
|
4797
|
-
const { TaskStreamPush, PostHogDestination } = await import("./task-stream-
|
|
4814
|
+
const { WizardStore } = await import("./store-UKAJftq6.js").then((n) => n.n);
|
|
4815
|
+
const { HeadlessUI } = await import("./headless-ui-C3C0wWUi.js");
|
|
4816
|
+
const { TaskStreamPush, PostHogDestination } = await import("./task-stream-Ne-9ZOnf.js");
|
|
4798
4817
|
store = new WizardStore(config.id);
|
|
4799
4818
|
store.session = session;
|
|
4800
4819
|
setUI(new HeadlessUI(store));
|
|
@@ -4849,7 +4868,7 @@ function runNonInteractive(config, options, mode) {
|
|
|
4849
4868
|
});
|
|
4850
4869
|
}
|
|
4851
4870
|
}
|
|
4852
|
-
const { runAgent } = await import("./agent-runner-
|
|
4871
|
+
const { runAgent } = await import("./agent-runner-BuH7W62W.js").then((n) => n.t);
|
|
4853
4872
|
await runAgent(config, session);
|
|
4854
4873
|
await settleStream(RunPhase.Completed);
|
|
4855
4874
|
} catch (error) {
|
|
@@ -5777,7 +5796,7 @@ async function runDoctorCI(options) {
|
|
|
5777
5796
|
getUI().intro("Welcome to the PostHog setup wizard");
|
|
5778
5797
|
getUI().log.info("Running posthog-doctor in CI mode");
|
|
5779
5798
|
try {
|
|
5780
|
-
const { getOrAskForProjectData } = await import("./setup-utils-
|
|
5799
|
+
const { getOrAskForProjectData } = await import("./setup-utils-DkyEOBDx.js").then((n) => n.r);
|
|
5781
5800
|
const { host, accessToken, projectId } = await getOrAskForProjectData({
|
|
5782
5801
|
signup: false,
|
|
5783
5802
|
ci: true,
|
|
@@ -5785,7 +5804,7 @@ async function runDoctorCI(options) {
|
|
|
5785
5804
|
projectId: options.projectId ? Number(options.projectId) : void 0,
|
|
5786
5805
|
baseUrl: options.baseUrl
|
|
5787
5806
|
});
|
|
5788
|
-
const issues = await fetchHealthIssues(accessToken, host, projectId);
|
|
5807
|
+
const issues = await fetchHealthIssues(accessToken, host.apiHost, projectId);
|
|
5789
5808
|
if (issues.length === 0) {
|
|
5790
5809
|
getUI().log.success("No active issues — your project looks healthy.");
|
|
5791
5810
|
process.exit(0);
|
|
@@ -5795,7 +5814,7 @@ async function runDoctorCI(options) {
|
|
|
5795
5814
|
for (const issue of sorted) getUI().log.info(` • [${issue.severity}] ${getKindMeta(issue.kind).title}`);
|
|
5796
5815
|
process.exit(1);
|
|
5797
5816
|
} catch (error) {
|
|
5798
|
-
const { ApiError } = await import("./api-
|
|
5817
|
+
const { ApiError } = await import("./api-Kgk7BFqo.js").then((n) => n.n);
|
|
5799
5818
|
const message = error instanceof ApiError && error.statusCode === 401 ? "Your PostHog API key is invalid or expired." : error instanceof Error ? error.message : String(error);
|
|
5800
5819
|
getUI().log.error(`Doctor failed: ${message}`);
|
|
5801
5820
|
process.exit(1);
|
|
@@ -5877,8 +5896,8 @@ function runSlackConnect(argv) {
|
|
|
5877
5896
|
(async () => {
|
|
5878
5897
|
const debug = argv.debug;
|
|
5879
5898
|
try {
|
|
5880
|
-
const { startTUI } = await import("./start-tui-
|
|
5881
|
-
const { buildSession } = await import("./wizard-session-
|
|
5899
|
+
const { startTUI } = await import("./start-tui-CJlIgYjf.js");
|
|
5900
|
+
const { buildSession } = await import("./wizard-session-DXivb7kv.js");
|
|
5882
5901
|
const tui = startTUI(VERSION, Program.SlackConnect);
|
|
5883
5902
|
tui.store.session = buildSession({
|
|
5884
5903
|
debug,
|
|
@@ -6243,7 +6262,7 @@ const cliCommand = {
|
|
|
6243
6262
|
};
|
|
6244
6263
|
//#endregion
|
|
6245
6264
|
//#region bin.ts
|
|
6246
|
-
const NODE_VERSION_RANGE = ">=
|
|
6265
|
+
const NODE_VERSION_RANGE = ">=22.22.0";
|
|
6247
6266
|
if (!satisfies(process.version, NODE_VERSION_RANGE)) {
|
|
6248
6267
|
console.log(`PostHog wizard requires Node.js ${NODE_VERSION_RANGE}. You are using Node.js ${process.version}. Please upgrade your Node.js version.`);
|
|
6249
6268
|
process.exit(1);
|