@posthog/wizard 2.16.0 → 2.16.1
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/README.md +0 -4
- package/dist/{TextBlock-DJVhBkr3.js → TextBlock-CdeZog_6.js} +2 -2
- package/dist/{TextBlock-DJVhBkr3.js.map → TextBlock-CdeZog_6.js.map} +1 -1
- package/dist/{add-mcp-server-to-clients-9jQjc-CO.js → add-mcp-server-to-clients-BS6Rjcwh.js} +6 -6
- package/dist/{add-mcp-server-to-clients-9jQjc-CO.js.map → add-mcp-server-to-clients-BS6Rjcwh.js.map} +1 -1
- package/dist/{agent-interface-pBnqJL8P.js → agent-interface-B4eUlMso.js} +33 -7
- package/dist/agent-interface-B4eUlMso.js.map +1 -0
- package/dist/{agent-runner-H1FP6XTc.js → agent-runner-BxqiKVEf.js} +16 -21
- package/dist/{agent-runner-H1FP6XTc.js.map → agent-runner-BxqiKVEf.js.map} +1 -1
- package/dist/{analytics-DZaUgJte.js → analytics-DUuUurR3.js} +3 -3
- package/dist/{analytics-DZaUgJte.js.map → analytics-DUuUurR3.js.map} +1 -1
- package/dist/api-B8OR0N1V.js +2 -0
- package/dist/api-CGJ1iGps.js +138 -0
- package/dist/api-CGJ1iGps.js.map +1 -0
- package/dist/bin.js +763 -497
- package/dist/bin.js.map +1 -1
- package/dist/ci-install-DD7WMmIF.js +73 -0
- package/dist/ci-install-DD7WMmIF.js.map +1 -0
- package/dist/{debug-B6rX6xye.js → debug-Cd0hPlZy.js} +1 -1
- package/dist/{debug-C4jRuzny.js → debug-ubpO6102.js} +12 -6
- package/dist/debug-ubpO6102.js.map +1 -0
- package/dist/{defaults-GbLPuHxj.js → defaults-zrYmZ2ID.js} +1 -1
- package/dist/{defaults-GbLPuHxj.js.map → defaults-zrYmZ2ID.js.map} +1 -1
- package/dist/{env-api-key-DU8uIEvo.js → env-api-key-DEl3LJBv.js} +4 -2
- package/dist/{env-api-key-DU8uIEvo.js.map → env-api-key-DEl3LJBv.js.map} +1 -1
- package/dist/environment-BAaC5THg.js +22 -0
- package/dist/environment-BAaC5THg.js.map +1 -0
- package/dist/{file-utils-DnTSiTJw.js → file-utils-DPmgn9Vm.js} +1 -1
- package/dist/{file-utils-DnTSiTJw.js.map → file-utils-DPmgn9Vm.js.map} +1 -1
- package/dist/interactive-BaMAq88Q.js +11 -0
- package/dist/interactive-BaMAq88Q.js.map +1 -0
- package/dist/{mcp-prompt-streaming-DKiaymMt.js → mcp-prompt-streaming-clGsVw8q.js} +2 -2
- package/dist/{mcp-prompt-streaming-DKiaymMt.js.map → mcp-prompt-streaming-clGsVw8q.js.map} +1 -1
- package/dist/non-interactive-l2AKE3jD.js +12 -0
- package/dist/non-interactive-l2AKE3jD.js.map +1 -0
- package/dist/package-json-CumwmZpv.js +2 -0
- package/dist/{package-json-v_g2YlN1.js → package-json-Cynjr9k4.js} +1 -1
- package/dist/{package-json-v_g2YlN1.js.map → package-json-Cynjr9k4.js.map} +1 -1
- package/dist/{package-manager-DLt75bit.js → package-manager-BqsJK3ej.js} +2 -2
- package/dist/{package-manager-DLt75bit.js.map → package-manager-BqsJK3ej.js.map} +1 -1
- package/dist/{start-playground-B40O4tye.js → playground-DlE5RNfE.js} +14 -8
- package/dist/playground-DlE5RNfE.js.map +1 -0
- package/dist/{posthog-7B92c2Ed.js → posthog-DWL8uOcl.js} +1 -1
- package/dist/{posthog-7B92c2Ed.js.map → posthog-DWL8uOcl.js.map} +1 -1
- package/dist/{posthog-integration-CukaeYil.js → posthog-integration-Bf_vtWI9.js} +229 -21
- package/dist/posthog-integration-Bf_vtWI9.js.map +1 -0
- package/dist/provisioning-BlBnlcFd.js +2 -0
- package/dist/{provisioning-C_ETLiZE.js → provisioning-D_hAuxUN.js} +3 -3
- package/dist/{provisioning-C_ETLiZE.js.map → provisioning-D_hAuxUN.js.map} +1 -1
- package/dist/{registry-DqbwO5EL.js → registry-DKgYqROt.js} +5 -5
- package/dist/{registry-DqbwO5EL.js.map → registry-DKgYqROt.js.map} +1 -1
- package/dist/setup-utils-BHZEdkNZ.js +2 -0
- package/dist/{setup-utils-DdAdxUTV.js → setup-utils-D-uTycLX.js} +8 -144
- package/dist/setup-utils-D-uTycLX.js.map +1 -0
- package/dist/skill-CnOQAZXp.js +29 -0
- package/dist/skill-CnOQAZXp.js.map +1 -0
- package/dist/{slides-Dpj4j0w_.js → slides-CL1mv_Kq.js} +154 -50
- package/dist/slides-CL1mv_Kq.js.map +1 -0
- package/dist/{start-tui-CH_ZzQXx.js → start-tui-DXrv6cof.js} +419 -29
- package/dist/start-tui-DXrv6cof.js.map +1 -0
- package/dist/{steps-0d9XqvI6.js → steps-CgScwqso.js} +6 -6
- package/dist/{steps-0d9XqvI6.js.map → steps-CgScwqso.js.map} +1 -1
- package/dist/{task-stream-CoEsidgG.js → task-stream-CF6QMVMv.js} +3 -3
- package/dist/{task-stream-CoEsidgG.js.map → task-stream-CF6QMVMv.js.map} +1 -1
- package/dist/{telemetry-jn2Daxl2.js → telemetry-v6O12Bep.js} +2 -2
- package/dist/{telemetry-jn2Daxl2.js.map → telemetry-v6O12Bep.js.map} +1 -1
- package/dist/{wizard-abort-BlYGA1Jk.js → wizard-abort-BGoBKgvC.js} +1 -1
- package/dist/{wizard-abort-BjLIgu2s.js → wizard-abort-iTaJ8wC8.js} +3 -3
- package/dist/{wizard-abort-BjLIgu2s.js.map → wizard-abort-iTaJ8wC8.js.map} +1 -1
- package/dist/{wizard-session-DPGTaJ4W.js → wizard-session-7tMjgOvP.js} +1 -1
- package/dist/{wizard-session-Bi95IYca.js → wizard-session-gsn8Z3bZ.js} +2 -3
- package/dist/wizard-session-gsn8Z3bZ.js.map +1 -0
- package/dist/wizard-ui-YdGFRyu_.js.map +1 -1
- package/package.json +1 -1
- package/dist/agent-interface-pBnqJL8P.js.map +0 -1
- package/dist/analytics-DqeW7XYt.js +0 -2
- package/dist/debug-C4jRuzny.js.map +0 -1
- package/dist/detection-4eukp9HD.js +0 -206
- package/dist/detection-4eukp9HD.js.map +0 -1
- package/dist/package-json-Cttzi3C8.js +0 -2
- package/dist/posthog-integration-CukaeYil.js.map +0 -1
- package/dist/provisioning-Ch6i8dRV.js +0 -2
- package/dist/setup-utils-C5uZ9g60.js +0 -2
- package/dist/setup-utils-DdAdxUTV.js.map +0 -1
- package/dist/slides-Dpj4j0w_.js.map +0 -1
- package/dist/start-playground-B40O4tye.js.map +0 -1
- package/dist/start-tui-CH_ZzQXx.js.map +0 -1
- package/dist/wizard-session-Bi95IYca.js.map +0 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { A as OAUTH_TIMEOUT_MS, B as WIZARD_OAUTH_SCOPES, D as ISSUES_URL, E as DUMMY_PROJECT_API_KEY, I as POSTHOG_PROXY_CLIENT_ID, P as POSTHOG_OAUTH_URL, W as WIZARD_USER_AGENT, k as OAUTH_PORTS, p as getUI, s as logToFile, w as DEFAULT_HOST_URL } from "./debug-
|
|
2
|
-
import {
|
|
3
|
-
import { t as withProgress } from "./telemetry-
|
|
4
|
-
import { t as provisionNewAccount } from "./provisioning-
|
|
5
|
-
import {
|
|
1
|
+
import { A as OAUTH_TIMEOUT_MS, B as WIZARD_OAUTH_SCOPES, D as ISSUES_URL, E as DUMMY_PROJECT_API_KEY, I as POSTHOG_PROXY_CLIENT_ID, P as POSTHOG_OAUTH_URL, W as WIZARD_USER_AGENT, k as OAUTH_PORTS, p as getUI, s as logToFile, w as DEFAULT_HOST_URL } from "./debug-ubpO6102.js";
|
|
2
|
+
import { t as analytics } from "./analytics-DUuUurR3.js";
|
|
3
|
+
import { t as withProgress } from "./telemetry-v6O12Bep.js";
|
|
4
|
+
import { t as provisionNewAccount } from "./provisioning-D_hAuxUN.js";
|
|
5
|
+
import { a as fetchProjectData, o as fetchUserData } from "./api-CGJ1iGps.js";
|
|
6
|
+
import { r as wizardAbort } from "./wizard-abort-iTaJ8wC8.js";
|
|
6
7
|
import { major, minVersion } from "semver";
|
|
7
8
|
import * as childProcess from "node:child_process";
|
|
8
9
|
import { execSync } from "node:child_process";
|
|
@@ -63,7 +64,6 @@ const packageManagers = [
|
|
|
63
64
|
buildCommand: "bun run build",
|
|
64
65
|
runScriptCommand: "bun run",
|
|
65
66
|
flags: "",
|
|
66
|
-
forceInstallFlag: "--force",
|
|
67
67
|
detect: ({ installDir }) => hasLockfile(installDir, "bun.lockb") || hasLockfile(installDir, "bun.lock"),
|
|
68
68
|
addOverride: (pkgName, pkgVersion, opts) => writeOverride("npm", pkgName, pkgVersion, opts)
|
|
69
69
|
},
|
|
@@ -74,7 +74,6 @@ const packageManagers = [
|
|
|
74
74
|
buildCommand: "yarn build",
|
|
75
75
|
runScriptCommand: "yarn",
|
|
76
76
|
flags: "--ignore-workspace-root-check",
|
|
77
|
-
forceInstallFlag: "--force",
|
|
78
77
|
detect: ({ installDir }) => lockfileHeaderContains(installDir, "yarn.lock", "yarn lockfile v1"),
|
|
79
78
|
addOverride: (pkgName, pkgVersion, opts) => writeOverride("yarn", pkgName, pkgVersion, opts)
|
|
80
79
|
},
|
|
@@ -85,7 +84,6 @@ const packageManagers = [
|
|
|
85
84
|
buildCommand: "yarn build",
|
|
86
85
|
runScriptCommand: "yarn",
|
|
87
86
|
flags: "",
|
|
88
|
-
forceInstallFlag: "--force",
|
|
89
87
|
detect: ({ installDir }) => lockfileHeaderContains(installDir, "yarn.lock", "__metadata"),
|
|
90
88
|
addOverride: (pkgName, pkgVersion, opts) => writeOverride("yarn", pkgName, pkgVersion, opts)
|
|
91
89
|
},
|
|
@@ -96,7 +94,6 @@ const packageManagers = [
|
|
|
96
94
|
buildCommand: "pnpm build",
|
|
97
95
|
runScriptCommand: "pnpm",
|
|
98
96
|
flags: "--ignore-workspace-root-check",
|
|
99
|
-
forceInstallFlag: "--force",
|
|
100
97
|
detect: ({ installDir }) => hasLockfile(installDir, "pnpm-lock.yaml"),
|
|
101
98
|
addOverride: (pkgName, pkgVersion, opts) => writeOverride("pnpm", pkgName, pkgVersion, opts)
|
|
102
99
|
},
|
|
@@ -107,7 +104,6 @@ const packageManagers = [
|
|
|
107
104
|
buildCommand: "npm run build",
|
|
108
105
|
runScriptCommand: "npm run",
|
|
109
106
|
flags: "",
|
|
110
|
-
forceInstallFlag: "--force",
|
|
111
107
|
detect: ({ installDir }) => hasLockfile(installDir, "package-lock.json"),
|
|
112
108
|
addOverride: (pkgName, pkgVersion, opts) => writeOverride("npm", pkgName, pkgVersion, opts)
|
|
113
109
|
},
|
|
@@ -118,7 +114,6 @@ const packageManagers = [
|
|
|
118
114
|
buildCommand: "npx expo build",
|
|
119
115
|
runScriptCommand: "npx expo run",
|
|
120
116
|
flags: "",
|
|
121
|
-
forceInstallFlag: "--force",
|
|
122
117
|
detect: () => false,
|
|
123
118
|
addOverride: (pkgName, pkgVersion, opts) => writeOverride("npm", pkgName, pkgVersion, opts)
|
|
124
119
|
}
|
|
@@ -444,137 +439,6 @@ async function performOAuthFlow(config) {
|
|
|
444
439
|
throw new Error("OAuth port retry loop exited unexpectedly");
|
|
445
440
|
}
|
|
446
441
|
//#endregion
|
|
447
|
-
//#region src/lib/api.ts
|
|
448
|
-
/**
|
|
449
|
-
* User payload from `/api/users/@me/`. Schema typed for the fields the
|
|
450
|
-
* wizard actually reads + passthrough on everything else so the full
|
|
451
|
-
* upstream response rides through to the session for downstream features
|
|
452
|
-
* (account-aware copy, plan-gated flows, org/team metadata, etc.).
|
|
453
|
-
*
|
|
454
|
-
* Top-level uses `.passthrough()` so unknown fields aren't stripped;
|
|
455
|
-
* the few nested objects we care about (team, organization,
|
|
456
|
-
* organizations[]) do the same so their additional fields survive too.
|
|
457
|
-
*
|
|
458
|
-
* Keep `distinct_id` required — analytics depends on it. Everything
|
|
459
|
-
* else added here is nullish so partial responses don't fail parsing.
|
|
460
|
-
*/
|
|
461
|
-
const ApiUserSchema = z.object({
|
|
462
|
-
distinct_id: z.string(),
|
|
463
|
-
uuid: z.string().nullish(),
|
|
464
|
-
id: z.number().nullish(),
|
|
465
|
-
email: z.string().nullish(),
|
|
466
|
-
first_name: z.string().nullish(),
|
|
467
|
-
last_name: z.string().nullish(),
|
|
468
|
-
date_joined: z.string().nullish(),
|
|
469
|
-
is_email_verified: z.boolean().nullish(),
|
|
470
|
-
is_2fa_enabled: z.boolean().nullish(),
|
|
471
|
-
is_staff: z.boolean().nullish(),
|
|
472
|
-
theme_mode: z.string().nullish(),
|
|
473
|
-
toolbar_mode: z.string().nullish(),
|
|
474
|
-
hide_mcp_hints: z.boolean().nullish(),
|
|
475
|
-
role_at_organization: z.string().nullish(),
|
|
476
|
-
team: z.object({
|
|
477
|
-
id: z.number(),
|
|
478
|
-
uuid: z.string().nullish(),
|
|
479
|
-
organization: z.string().uuid(),
|
|
480
|
-
api_token: z.string().nullish(),
|
|
481
|
-
project_id: z.number().nullish(),
|
|
482
|
-
name: z.string().nullish(),
|
|
483
|
-
timezone: z.string().nullish()
|
|
484
|
-
}).passthrough(),
|
|
485
|
-
organization: z.object({
|
|
486
|
-
id: z.string().uuid(),
|
|
487
|
-
name: z.string().nullish(),
|
|
488
|
-
slug: z.string().nullish(),
|
|
489
|
-
membership_level: z.number().nullish(),
|
|
490
|
-
customer_id: z.string().nullish()
|
|
491
|
-
}).passthrough(),
|
|
492
|
-
organizations: z.array(z.object({
|
|
493
|
-
id: z.string().uuid(),
|
|
494
|
-
name: z.string().nullish(),
|
|
495
|
-
membership_level: z.number().nullish()
|
|
496
|
-
}).passthrough())
|
|
497
|
-
}).passthrough();
|
|
498
|
-
/**
|
|
499
|
-
* Single activity log entry the wizard cares about. The PostHog endpoint
|
|
500
|
-
* returns much more — schema kept minimal so changes upstream don't break us.
|
|
501
|
-
*
|
|
502
|
-
* @unused — no current caller after the Phase 6 streaming-agent pivot
|
|
503
|
-
* dropped activity_log polling. Deliberately retained: this is a thin,
|
|
504
|
-
* well-typed wrapper around a stable PostHog endpoint, and we're likely
|
|
505
|
-
* to want it again for a future feature (e.g. "what changed in your
|
|
506
|
-
* project recently"). Re-deriving the schema is more work than letting
|
|
507
|
-
* it sit dormant.
|
|
508
|
-
*/
|
|
509
|
-
const ActivityLogEntrySchema = z.object({
|
|
510
|
-
scope: z.string().nullish(),
|
|
511
|
-
activity: z.string().nullish(),
|
|
512
|
-
created_at: z.string().nullish()
|
|
513
|
-
}).passthrough();
|
|
514
|
-
z.object({ results: z.array(ActivityLogEntrySchema) });
|
|
515
|
-
const ApiProjectSchema = z.object({
|
|
516
|
-
id: z.number(),
|
|
517
|
-
uuid: z.string().uuid(),
|
|
518
|
-
organization: z.string().uuid(),
|
|
519
|
-
api_token: z.string(),
|
|
520
|
-
name: z.string()
|
|
521
|
-
});
|
|
522
|
-
var ApiError = class extends Error {
|
|
523
|
-
constructor(message, statusCode, endpoint) {
|
|
524
|
-
super(message);
|
|
525
|
-
this.statusCode = statusCode;
|
|
526
|
-
this.endpoint = endpoint;
|
|
527
|
-
this.name = "ApiError";
|
|
528
|
-
}
|
|
529
|
-
};
|
|
530
|
-
async function fetchUserData(accessToken, baseUrl) {
|
|
531
|
-
try {
|
|
532
|
-
const response = await axios.get(`${baseUrl}/api/users/@me/`, { headers: {
|
|
533
|
-
Authorization: `Bearer ${accessToken}`,
|
|
534
|
-
"User-Agent": WIZARD_USER_AGENT
|
|
535
|
-
} });
|
|
536
|
-
return ApiUserSchema.parse(response.data);
|
|
537
|
-
} catch (error) {
|
|
538
|
-
const apiError = handleApiError(error, "fetch user data");
|
|
539
|
-
analytics.captureException(apiError, {
|
|
540
|
-
endpoint: "/api/users/@me/",
|
|
541
|
-
baseUrl
|
|
542
|
-
});
|
|
543
|
-
throw apiError;
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
async function fetchProjectData(accessToken, projectId, baseUrl) {
|
|
547
|
-
try {
|
|
548
|
-
const response = await axios.get(`${baseUrl}/api/projects/${projectId}/`, { headers: {
|
|
549
|
-
Authorization: `Bearer ${accessToken}`,
|
|
550
|
-
"User-Agent": WIZARD_USER_AGENT
|
|
551
|
-
} });
|
|
552
|
-
return ApiProjectSchema.parse(response.data);
|
|
553
|
-
} catch (error) {
|
|
554
|
-
const apiError = handleApiError(error, "fetch project data");
|
|
555
|
-
analytics.captureException(apiError, {
|
|
556
|
-
endpoint: `/api/projects/${projectId}/`,
|
|
557
|
-
baseUrl,
|
|
558
|
-
projectId
|
|
559
|
-
});
|
|
560
|
-
throw apiError;
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
function handleApiError(error, operation) {
|
|
564
|
-
if (axios.isAxiosError(error)) {
|
|
565
|
-
const axiosError = error;
|
|
566
|
-
const status = axiosError.response?.status;
|
|
567
|
-
const detail = axiosError.response?.data?.detail;
|
|
568
|
-
const endpoint = axiosError.config?.url;
|
|
569
|
-
if (status === 401) return new ApiError(`Authentication failed while trying to ${operation}`, status, endpoint);
|
|
570
|
-
if (status === 403) return new ApiError(`Access denied while trying to ${operation}`, status, endpoint);
|
|
571
|
-
if (status === 404) return new ApiError(`Resource not found while trying to ${operation}`, status, endpoint);
|
|
572
|
-
return new ApiError(detail || `Failed to ${operation}`, status, endpoint);
|
|
573
|
-
}
|
|
574
|
-
if (error instanceof z.ZodError) return new ApiError(`Invalid response format while trying to ${operation}`);
|
|
575
|
-
return new ApiError(`Unexpected error while trying to ${operation}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
576
|
-
}
|
|
577
|
-
//#endregion
|
|
578
442
|
//#region src/utils/semver.ts
|
|
579
443
|
/**
|
|
580
444
|
* Version strings from package.json that are not semver ranges.
|
|
@@ -870,6 +734,6 @@ async function askForProvisioningSignup(email, region) {
|
|
|
870
734
|
}
|
|
871
735
|
}
|
|
872
736
|
//#endregion
|
|
873
|
-
export { isUsingTypeScript as a, createVersionBucket as c,
|
|
737
|
+
export { isUsingTypeScript as a, createVersionBucket as c, getLlmGatewayUrlFromHost as d, getUiHostFromHost as f, getPackageDotJson as i, extractOAuthCode as l, detectOrgAndProject as n, tryGetPackageJson as o, detectAllPackageManagers as p, getOrAskForProjectData as r, updatePackageDotJson as s, abort as t, getCloudUrlFromRegion as u };
|
|
874
738
|
|
|
875
|
-
//# sourceMappingURL=setup-utils-
|
|
739
|
+
//# sourceMappingURL=setup-utils-D-uTycLX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-utils-D-uTycLX.js","names":["fs","path","fs"],"sources":["../src/utils/package-manager.ts","../src/utils/urls.ts","../src/utils/oauth.ts","../src/utils/semver.ts","../src/utils/setup-utils.ts"],"sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport { withProgress } from '../telemetry';\nimport { getPackageDotJson, updatePackageDotJson } from './setup-utils';\nimport type { PackageJson } from './package-json';\nimport { analytics } from './analytics';\nimport type { WizardRunOptions } from './types';\n\ntype InstallDirOpt = Pick<WizardRunOptions, 'installDir'>;\n\nexport interface PackageManager {\n name: string;\n label: string;\n installCommand: string;\n buildCommand: string;\n /** Command the manager uses to execute a `package.json` script. */\n runScriptCommand: string;\n flags: string;\n detect: (opts: InstallDirOpt) => boolean;\n addOverride: (\n pkgName: string,\n pkgVersion: string,\n opts: InstallDirOpt,\n ) => Promise<void>;\n}\n\nfunction hasLockfile(installDir: string, file: string): boolean {\n return fs.existsSync(path.join(installDir, file));\n}\n\nfunction lockfileHeaderContains(\n installDir: string,\n file: string,\n needle: string,\n): boolean {\n try {\n const head = fs\n .readFileSync(path.join(installDir, file), 'utf-8')\n .slice(0, 500);\n return head.includes(needle);\n } catch {\n return false;\n }\n}\n\ntype OverrideSlot = 'npm' | 'yarn' | 'pnpm';\n\nasync function writeOverride(\n slot: OverrideSlot,\n pkgName: string,\n pkgVersion: string,\n { installDir }: InstallDirOpt,\n): Promise<void> {\n const pkg = await getPackageDotJson({ installDir });\n let next: PackageJson;\n if (slot === 'yarn') {\n next = {\n ...pkg,\n resolutions: { ...(pkg.resolutions ?? {}), [pkgName]: pkgVersion },\n };\n } else if (slot === 'pnpm') {\n next = {\n ...pkg,\n pnpm: {\n ...(pkg.pnpm ?? {}),\n overrides: { ...(pkg.pnpm?.overrides ?? {}), [pkgName]: pkgVersion },\n },\n };\n } else {\n next = {\n ...pkg,\n overrides: { ...(pkg.overrides ?? {}), [pkgName]: pkgVersion },\n };\n }\n await updatePackageDotJson(next, { installDir });\n}\n\nexport const BUN: PackageManager = {\n name: 'bun',\n label: 'Bun',\n installCommand: 'bun add',\n buildCommand: 'bun run build',\n runScriptCommand: 'bun run',\n flags: '',\n detect: ({ installDir }) =>\n hasLockfile(installDir, 'bun.lockb') || hasLockfile(installDir, 'bun.lock'),\n addOverride: (pkgName, pkgVersion, opts) =>\n writeOverride('npm', pkgName, pkgVersion, opts),\n};\n\nexport const YARN_V1: PackageManager = {\n name: 'yarn',\n label: 'Yarn V1',\n installCommand: 'yarn add',\n buildCommand: 'yarn build',\n runScriptCommand: 'yarn',\n flags: '--ignore-workspace-root-check',\n detect: ({ installDir }) =>\n lockfileHeaderContains(installDir, 'yarn.lock', 'yarn lockfile v1'),\n addOverride: (pkgName, pkgVersion, opts) =>\n writeOverride('yarn', pkgName, pkgVersion, opts),\n};\n\n/** YARN V2/3/4 */\nexport const YARN_V2: PackageManager = {\n name: 'yarn',\n label: 'Yarn V2/3/4',\n installCommand: 'yarn add',\n buildCommand: 'yarn build',\n runScriptCommand: 'yarn',\n flags: '',\n detect: ({ installDir }) =>\n lockfileHeaderContains(installDir, 'yarn.lock', '__metadata'),\n addOverride: (pkgName, pkgVersion, opts) =>\n writeOverride('yarn', pkgName, pkgVersion, opts),\n};\n\nexport const PNPM: PackageManager = {\n name: 'pnpm',\n label: 'pnpm',\n installCommand: 'pnpm add',\n buildCommand: 'pnpm build',\n runScriptCommand: 'pnpm',\n flags: '--ignore-workspace-root-check',\n detect: ({ installDir }) => hasLockfile(installDir, 'pnpm-lock.yaml'),\n addOverride: (pkgName, pkgVersion, opts) =>\n writeOverride('pnpm', pkgName, pkgVersion, opts),\n};\n\nexport const NPM: PackageManager = {\n name: 'npm',\n label: 'npm',\n installCommand: 'npm add',\n buildCommand: 'npm run build',\n runScriptCommand: 'npm run',\n flags: '',\n detect: ({ installDir }) => hasLockfile(installDir, 'package-lock.json'),\n addOverride: (pkgName, pkgVersion, opts) =>\n writeOverride('npm', pkgName, pkgVersion, opts),\n};\n\n// Expo is selected by upstream config (app.json / app.config.*) rather than\n// a lockfile, so its detect always returns false here.\nexport const EXPO: PackageManager = {\n name: 'expo',\n label: 'Expo',\n installCommand: 'npx expo install',\n buildCommand: 'npx expo build',\n runScriptCommand: 'npx expo run',\n flags: '',\n detect: () => false,\n addOverride: (pkgName, pkgVersion, opts) =>\n writeOverride('npm', pkgName, pkgVersion, opts),\n};\n\nexport const packageManagers: PackageManager[] = [\n BUN,\n YARN_V1,\n YARN_V2,\n PNPM,\n NPM,\n EXPO,\n];\n\nexport function detectAllPackageManagers({\n installDir,\n}: InstallDirOpt): PackageManager[] {\n return withProgress('detect-package-manager', () => {\n const matches = packageManagers.filter((pm) => pm.detect({ installDir }));\n if (matches.length === 0) {\n analytics.setTag('package-manager', 'not-detected');\n }\n return matches;\n });\n}\n","import axios from 'axios';\nimport { IS_DEV, WIZARD_USER_AGENT } from '@lib/constants';\nimport type { CloudRegion } from './types';\n\nexport const getAssetHostFromHost = (host: string) => {\n if (host.includes('us.i.posthog.com')) {\n return 'https://us-assets.i.posthog.com';\n }\n\n if (host.includes('eu.i.posthog.com')) {\n return 'https://eu-assets.i.posthog.com';\n }\n\n return host;\n};\n\nexport const getUiHostFromHost = (host: string) => {\n if (host.includes('us.i.posthog.com')) {\n return 'https://us.posthog.com';\n }\n\n if (host.includes('eu.i.posthog.com')) {\n return 'https://eu.posthog.com';\n }\n\n return host;\n};\n\nexport const getHostFromRegion = (region: CloudRegion) => {\n if (IS_DEV) {\n return 'http://localhost:8010';\n }\n\n if (region === 'eu') {\n return 'https://eu.i.posthog.com';\n }\n\n return 'https://us.i.posthog.com';\n};\n\nexport const getCloudUrlFromRegion = (region: CloudRegion) => {\n if (IS_DEV) {\n return 'http://localhost:8010';\n }\n\n if (region === 'eu') {\n return 'https://eu.posthog.com';\n }\n\n return 'https://us.posthog.com';\n};\n\nexport async function detectRegionFromToken(\n accessToken: string,\n): Promise<CloudRegion> {\n if (IS_DEV) {\n return 'us';\n }\n\n const headers = {\n Authorization: `Bearer ${accessToken}`,\n 'User-Agent': WIZARD_USER_AGENT,\n };\n\n const [usResult, euResult] = await Promise.allSettled([\n axios.get('https://us.posthog.com/api/users/@me/', { headers }),\n axios.get('https://eu.posthog.com/api/users/@me/', { headers }),\n ]);\n\n if (usResult.status === 'fulfilled') return 'us';\n if (euResult.status === 'fulfilled') return 'eu';\n\n throw new Error(\n 'Could not determine cloud region from access token. Please check your PostHog account.',\n );\n}\n\nexport const getLlmGatewayUrlFromHost = (host: string) => {\n if (host.includes('localhost')) {\n return 'http://localhost:3308/wizard';\n }\n\n if (host.includes('eu.posthog.com') || host.includes('eu.i.posthog.com')) {\n return 'https://gateway.eu.posthog.com/wizard';\n }\n\n return 'https://gateway.us.posthog.com/wizard';\n};\n","import * as crypto from 'node:crypto';\nimport * as http from 'node:http';\nimport { execSync } from 'node:child_process';\nimport axios from 'axios';\nimport { logToFile } from './debug';\nimport opn from 'opn';\nimport { z } from 'zod';\nimport { getUI } from '@ui';\nimport {\n IS_DEV,\n ISSUES_URL,\n OAUTH_PORTS,\n OAUTH_TIMEOUT_MS,\n POSTHOG_DEV_CLIENT_ID,\n POSTHOG_OAUTH_URL,\n POSTHOG_PROXY_CLIENT_ID,\n WIZARD_USER_AGENT,\n} from '@lib/constants';\nimport { NODE_ENV } from '@env';\nimport { abort } from './setup-utils';\nimport { analytics } from './analytics';\n\nconst OAUTH_CALLBACK_STYLES = `\n <style>\n * {\n font-family: monospace;\n background-color: #1b0a00;\n color: #F7A502;\n font-weight: medium;\n font-size: 24px;\n margin: .25rem;\n }\n\n .blink {\n animation: blink-animation 1s steps(2, start) infinite;\n }\n\n @keyframes blink-animation {\n to {\n opacity: 0;\n }\n }\n </style>\n`;\n\nconst OAuthTokenResponseSchema = z.object({\n access_token: z.string(),\n expires_in: z.number(),\n token_type: z.string(),\n scope: z.string(),\n refresh_token: z.string().optional(),\n scoped_teams: z.array(z.number()).optional(),\n scoped_organizations: z.array(z.string()).optional(),\n});\n\nexport type OAuthTokenResponse = z.infer<typeof OAuthTokenResponseSchema>;\n\ninterface OAuthConfig {\n scopes: string[];\n signup?: boolean;\n}\n\nfunction getLocalOAuthOrigin(port: number): string {\n return `http://localhost:${port}`;\n}\n\nfunction getCallbackUrl(port: number): string {\n return `${getLocalOAuthOrigin(port)}/callback`;\n}\n\nfunction getLocalLoginUrl(port: number): string {\n return `${getLocalOAuthOrigin(port)}/authorize`;\n}\n\nfunction getLocalSignupUrl(port: number): string {\n return `${getLocalLoginUrl(port)}?signup=true`;\n}\n\n/**\n * Extract an OAuth authorization code from raw user input. Accepts either the\n * bare code, the full callback URL the browser was redirected to\n * (`http://localhost:8239/callback?code=abc123&...`), or just the query\n * string. Returns null when no code can be found.\n *\n * This backs the manual-entry fallback: in headless/remote environments the\n * browser can't reach the wizard's local callback server, so the user copies\n * the failed callback URL (or the code from it) back into the terminal.\n */\nexport function extractOAuthCode(input: string): string | null {\n const trimmed = input.trim();\n if (!trimmed) return null;\n\n // Full URL — pull the `code` query param.\n let looksLikeUrl = false;\n try {\n const url = new URL(trimmed);\n looksLikeUrl = true;\n const code = url.searchParams.get('code');\n if (code) return code;\n } catch {\n // Not a parseable URL — fall through to the looser checks below.\n }\n\n // A pasted query string or `code=...` fragment.\n const match = trimmed.match(/[?&]?code=([^&\\s]+)/);\n if (match) return decodeURIComponent(match[1]);\n\n // A URL with no code is invalid — don't mistake the whole URL for a code.\n if (looksLikeUrl) return null;\n\n // Otherwise treat the whole input as the bare code (no embedded whitespace).\n if (!/\\s/.test(trimmed)) return trimmed;\n\n return null;\n}\n\nfunction generateCodeVerifier(): string {\n return crypto.randomBytes(32).toString('base64url');\n}\n\nfunction generateCodeChallenge(verifier: string): string {\n return crypto.createHash('sha256').update(verifier).digest('base64url');\n}\n\nasync function startCallbackServer(\n authUrl: string,\n signupUrl: string,\n port: number,\n): Promise<{\n port: number;\n server: http.Server;\n waitForCallback: () => Promise<string>;\n}> {\n return new Promise((resolve, reject) => {\n let callbackResolve: (code: string) => void;\n let callbackReject: (error: Error) => void;\n\n const waitForCallback = () =>\n new Promise<string>((res, rej) => {\n callbackResolve = res;\n callbackReject = rej;\n });\n\n const server = http.createServer((req, res) => {\n if (!req.url) {\n res.writeHead(400);\n res.end();\n return;\n }\n const url = new URL(req.url, getLocalOAuthOrigin(port));\n\n if (url.pathname === '/authorize') {\n const isSignup = url.searchParams.get('signup') === 'true';\n const redirectUrl = isSignup ? signupUrl : authUrl;\n res.writeHead(302, { Location: redirectUrl });\n res.end();\n return;\n }\n\n const code = url.searchParams.get('code');\n const error = url.searchParams.get('error');\n\n if (error) {\n const isAccessDenied = error === 'access_denied';\n res.writeHead(isAccessDenied ? 200 : 400, {\n 'Content-Type': 'text/html; charset=utf-8',\n });\n res.end(`\n <html>\n <head>\n <meta charset=\"UTF-8\">\n <title>PostHog wizard - Authorization ${\n isAccessDenied ? 'cancelled' : 'failed'\n }</title>\n ${OAUTH_CALLBACK_STYLES}\n </head>\n <body>\n <p>${\n isAccessDenied\n ? 'Authorization cancelled.'\n : `Authorization failed.`\n }</p>\n <p>Return to your terminal. This window will close automatically.</p>\n <script>window.close();</script>\n </body>\n </html>\n `);\n callbackReject(new Error(`OAuth error: ${error}`));\n return;\n }\n\n if (code) {\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });\n res.end(`\n <html>\n <head>\n <meta charset=\"UTF-8\">\n <title>PostHog wizard is ready</title>\n ${OAUTH_CALLBACK_STYLES}\n </head>\n <body>\n <p>PostHog login complete!</p>\n <p>Return to your terminal: the wizard is hard at work on your project<span class=\"blink\">█</span></p>\n <script>window.close();</script>\n </body>\n </html>\n `);\n callbackResolve(code);\n } else {\n res.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });\n res.end(`\n <html>\n <head>\n <meta charset=\"UTF-8\">\n <title>PostHog wizard - Invalid request</title>\n ${OAUTH_CALLBACK_STYLES}\n </head>\n <body>\n <p>Invalid request - no authorization code received.</p>\n <p>You can close this window.</p>\n </body>\n </html>\n `);\n }\n });\n\n server.listen(port, () => {\n resolve({ port, server, waitForCallback });\n });\n\n server.on('error', reject);\n });\n}\n\nfunction getPortProcessInfo(port: number): {\n command: string;\n pid: string;\n port: number;\n user: string;\n} {\n try {\n const output = execSync(`lsof -i :${port} -sTCP:LISTEN 2>/dev/null`, {\n encoding: 'utf-8',\n timeout: 3000,\n }).trim();\n const lines = output.split('\\n');\n // First line is header, second is the process\n if (lines.length < 2)\n return { command: 'unknown', pid: 'unknown', port, user: 'unknown' };\n const fields = lines[1].split(/\\s+/);\n // lsof columns: COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME\n const command = fields[0] ?? 'unknown';\n const pid = fields[1] ?? 'unknown';\n const user = fields[2] ?? 'unknown';\n return { command, pid, port, user };\n } catch {\n return { command: 'unknown', pid: 'unknown', port, user: 'unknown' };\n }\n}\n\nfunction isPortInUseError(error: unknown): boolean {\n return (\n error instanceof Error &&\n 'code' in error &&\n (error as NodeJS.ErrnoException).code === 'EADDRINUSE'\n );\n}\n\nasync function exchangeCodeForToken(\n code: string,\n codeVerifier: string,\n callbackUrl: string,\n): Promise<OAuthTokenResponse> {\n const clientId = IS_DEV ? POSTHOG_DEV_CLIENT_ID : POSTHOG_PROXY_CLIENT_ID;\n\n const response = await axios.post(\n `${POSTHOG_OAUTH_URL}/oauth/token`,\n {\n grant_type: 'authorization_code',\n code,\n redirect_uri: callbackUrl,\n client_id: clientId,\n code_verifier: codeVerifier,\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': WIZARD_USER_AGENT,\n },\n },\n );\n\n return OAuthTokenResponseSchema.parse(response.data);\n}\n\nexport async function performOAuthFlow(\n config: OAuthConfig,\n): Promise<OAuthTokenResponse> {\n const clientId = IS_DEV ? POSTHOG_DEV_CLIENT_ID : POSTHOG_PROXY_CLIENT_ID;\n const codeVerifier = generateCodeVerifier();\n const codeChallenge = generateCodeChallenge(codeVerifier);\n let shouldRetry = false;\n\n do {\n shouldRetry = false;\n let lastProcessInfo: {\n command: string;\n pid: string;\n port: number;\n user: string;\n } | null = null;\n\n for (const port of OAUTH_PORTS) {\n const callbackUrl = getCallbackUrl(port);\n const authUrl = new URL(`${POSTHOG_OAUTH_URL}/oauth/authorize`);\n authUrl.searchParams.set('client_id', clientId);\n authUrl.searchParams.set('redirect_uri', callbackUrl);\n authUrl.searchParams.set('response_type', 'code');\n authUrl.searchParams.set('code_challenge', codeChallenge);\n authUrl.searchParams.set('code_challenge_method', 'S256');\n authUrl.searchParams.set('scope', config.scopes.join(' '));\n authUrl.searchParams.set('required_access_level', 'project');\n\n const signupUrl = new URL(\n `${POSTHOG_OAUTH_URL}/signup?next=${encodeURIComponent(\n authUrl.toString(),\n )}`,\n );\n const localSignupUrl = getLocalSignupUrl(port);\n const localLoginUrl = getLocalLoginUrl(port);\n const urlToOpen = config.signup ? localSignupUrl : localLoginUrl;\n\n logToFile(`[oauth] attempting callback server on port ${port}`);\n\n let server: http.Server;\n let waitForCallback: () => Promise<string>;\n try {\n ({ server, waitForCallback } = await startCallbackServer(\n authUrl.toString(),\n signupUrl.toString(),\n port,\n ));\n } catch (e) {\n if (!isPortInUseError(e)) throw e;\n lastProcessInfo = getPortProcessInfo(port);\n continue;\n }\n\n logToFile('[oauth] callback server ready, showing login URL');\n\n getUI().setLoginUrl(urlToOpen);\n // The localhost proxy above only works on this machine. Surface the\n // direct PostHog authorize URL too, for the manual-paste modal — on a\n // remote/headless box the user opens it from another machine, where\n // localhost:<port> is unreachable.\n getUI().setAuthorizeUrl(\n config.signup ? signupUrl.toString() : authUrl.toString(),\n );\n\n if (NODE_ENV !== 'test') {\n opn(urlToOpen, { wait: false }).catch(() => {\n // opn throws in environments without a browser\n });\n }\n\n const loginSpinner = getUI().spinner();\n loginSpinner.start('Waiting for authorization...');\n\n try {\n // Race the local callback server against a manually-pasted code. The\n // manual path is the fallback for headless/remote shells where the\n // browser can't reach localhost — the user opens the auth screen's\n // paste modal and submits the callback URL or code by hand.\n const code = await Promise.race([\n waitForCallback(),\n getUI().waitForManualAuthCode(),\n new Promise<never>((_, reject) =>\n setTimeout(\n () => reject(new Error('Authorization timed out')),\n OAUTH_TIMEOUT_MS,\n ),\n ),\n ]);\n\n const token = await exchangeCodeForToken(\n code,\n codeVerifier,\n callbackUrl,\n );\n\n server.close();\n getUI().setLoginUrl(null);\n getUI().setAuthorizeUrl(null);\n loginSpinner.stop('Authorization complete!');\n\n return token;\n } catch (e) {\n loginSpinner.stop('Authorization failed.');\n server.close();\n\n const error = e instanceof Error ? e : new Error('Unknown error');\n\n if (error.message.includes('timeout')) {\n getUI().log.error('Authorization timed out. Please try again.');\n } else if (error.message.includes('access_denied')) {\n getUI().log.info(\n `Authorization was cancelled.\\n\\nYou denied access to PostHog. To use the wizard, you need to authorize access to your PostHog account.\\n\\nYou can try again by re-running the wizard.`,\n );\n } else {\n getUI().log.error(\n `Authorization failed:\\n\\n${error.message}\\n\\nIf you think this is a bug in the PostHog wizard, please create an issue:\\n${ISSUES_URL}`,\n );\n }\n\n const oauthErrorCode = error.message.startsWith('OAuth error: ')\n ? error.message.slice('OAuth error: '.length)\n : error.message.includes('timeout')\n ? 'timeout'\n : 'unknown';\n\n analytics.captureException(error, {\n step: 'oauth_flow',\n oauth_error_code: oauthErrorCode,\n client_id: clientId,\n requested_scopes: config.scopes.join(' '),\n // Collapse OAuth callback failures of the same kind into one issue\n // instead of fragmenting by each user's install path in the stack trace.\n $exception_fingerprint: `wizard_oauth_${oauthErrorCode}`,\n });\n\n await abort();\n throw error;\n }\n }\n\n if (!lastProcessInfo) {\n throw new Error('No OAuth callback ports configured');\n }\n\n await getUI().showPortConflict(lastProcessInfo);\n shouldRetry = true;\n } while (shouldRetry);\n\n throw new Error('OAuth port retry loop exited unexpectedly');\n}\n","import {\n major,\n minVersion,\n satisfies,\n subset,\n valid,\n validRange,\n} from 'semver';\n\n/**\n * Version strings from package.json that are not semver ranges.\n * URLs, git refs, dist-tags, local paths, workspace protocol, npm aliases, etc.\n * These should be rejected early — we can't determine a clear version from them.\n */\nfunction isNonSemverVersion(version: string): boolean {\n const v = version.trim();\n return (\n v === '' ||\n v.startsWith('http://') ||\n v.startsWith('https://') ||\n v.startsWith('git+') ||\n v.startsWith('git://') ||\n v.startsWith('file:') ||\n v.startsWith('npm:') ||\n v.startsWith('workspace:') ||\n v.startsWith('/') ||\n v.includes('/') // user/repo shorthand\n );\n}\n\nexport function versionSatisfiesRange({\n version,\n acceptableVersions,\n canBeLatest,\n}: {\n version: string;\n acceptableVersions: string;\n canBeLatest: boolean;\n}): boolean {\n if (version === 'latest') return canBeLatest;\n if (isNonSemverVersion(version)) return false;\n\n const concrete = valid(version);\n if (concrete !== null) {\n return satisfies(concrete, acceptableVersions);\n }\n\n const userRange = validRange(version);\n if (userRange === null) return false;\n return subset(userRange, acceptableVersions);\n}\n\n/**\n * Creates a version bucket function for analytics.\n * Converts versions like \"1.2.3\" to \"1.x\" for grouping in analytics.\n *\n * @param minMajorVersion - Optional minimum major version threshold.\n * Versions below this will be bucketed as \"<{min}.0.0\"\n *\n * @example\n * const getVersionBucket = createVersionBucket(); // no minimum\n * getVersionBucket(\"1.2.3\") // \"1.x\"\n *\n * const getVersionBucket = createVersionBucket(11);\n * getVersionBucket(\"15.3.0\") // \"15.x\"\n * getVersionBucket(\"10.0.0\") // \"<11.0.0\"\n */\nexport function createVersionBucket(minMajorVersion?: number) {\n return (version: string | undefined): string => {\n if (!version) {\n return 'none';\n }\n\n if (isNonSemverVersion(version)) {\n return 'unknown';\n }\n\n try {\n const minVer = minVersion(version);\n if (!minVer) {\n return 'invalid';\n }\n const majorVersion = major(minVer);\n if (minMajorVersion !== undefined && majorVersion < minMajorVersion) {\n return `<${minMajorVersion}.0.0`;\n }\n return `${majorVersion}.x`;\n } catch {\n return 'unknown';\n }\n };\n}\n","import * as childProcess from 'node:child_process';\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport { basename, isAbsolute, join, relative } from 'node:path';\nimport { promisify } from 'node:util';\n\nimport { withProgress } from '../telemetry';\nimport { debug } from './debug';\nimport type { PackageJson } from './package-json';\nimport {\n type PackageManager,\n detectAllPackageManagers,\n NPM as npm,\n} from './package-manager';\nimport type { CloudRegion, WizardRunOptions } from './types';\nimport { getDeclaredVersion } from './package-json';\nimport {\n DEFAULT_HOST_URL,\n DUMMY_PROJECT_API_KEY,\n ISSUES_URL,\n WIZARD_OAUTH_SCOPES,\n} from '@lib/constants';\nimport { analytics } from './analytics';\nimport { getUI } from '@ui';\nimport {\n getCloudUrlFromRegion,\n getHostFromRegion,\n detectRegionFromToken,\n} from './urls';\nimport { performOAuthFlow } from './oauth';\nimport { provisionNewAccount } from './provisioning';\nimport { fetchUserData, fetchProjectData, type ApiUser } from '@lib/api';\nimport { versionSatisfiesRange } from './semver';\nimport { wizardAbort } from './wizard-abort';\n\ninterface ProjectData {\n projectApiKey: string;\n accessToken: string;\n host: string;\n distinctId: string;\n projectId: number;\n /**\n * Optional `role_at_organization` from `/api/users/@me/`. Drives the\n * role-tailored prompt suggestions on the McpSuggestedPromptsScreen. Null\n * for signup flows (no role picked yet) and older accounts.\n */\n roleAtOrganization?: string | null;\n /**\n * Full user payload from `/api/users/@me/`. Carried through so\n * `getOrAskForProjectData` can forward it to the session as\n * `session.apiUser`. Null when the request failed or the CI key\n * lacked permissions.\n */\n user?: ApiUser | null;\n}\n\nexport interface CliSetupConfig {\n filename: string;\n name: string;\n gitignore: boolean;\n\n likelyAlreadyHasAuthToken(contents: string): boolean;\n tokenContent(authToken: string): string;\n\n likelyAlreadyHasOrgAndProject(contents: string): boolean;\n orgAndProjContent(org: string, project: string): string;\n\n likelyAlreadyHasUrl?(contents: string): boolean;\n urlContent?(url: string): string;\n}\n\nexport interface CliSetupConfigContent {\n authToken: string;\n org?: string;\n project?: string;\n url?: string;\n}\n\n/** @deprecated Use wizardAbort() directly for new code. */\nexport async function abort(message?: string, status?: number): Promise<never> {\n return wizardAbort({ message, exitCode: status });\n}\n\nexport function isInGitRepo(): boolean {\n try {\n childProcess.execSync('git rev-parse --show-toplevel', {\n stdio: 'ignore',\n });\n } catch {\n return false;\n }\n return true;\n}\n\nconst FREEMAIL_DOMAINS = new Set([\n 'gmail.com',\n 'googlemail.com',\n 'hotmail.com',\n 'outlook.com',\n 'yahoo.com',\n 'icloud.com',\n 'me.com',\n 'mail.com',\n 'protonmail.com',\n 'proton.me',\n 'live.com',\n 'aol.com',\n 'yandex.com',\n 'zoho.com',\n 'gmx.com',\n 'fastmail.com',\n]);\n\nfunction parseGitRemote(): { org: string; repo: string } | null {\n try {\n const url = childProcess\n .execSync('git remote get-url origin', {\n stdio: ['ignore', 'pipe', 'ignore'],\n })\n .toString()\n .trim();\n // git@github.com:acme-corp/my-app.git or https://github.com/acme-corp/my-app.git\n const match = url.match(/[/:]([\\w.-]+)\\/([\\w.-]+?)(?:\\.git)?$/);\n if (match) return { org: match[1], repo: match[2] };\n } catch {\n // not in a git repo or no remote\n }\n return null;\n}\n\nexport function detectOrgAndProject(email: string): {\n orgName: string | undefined;\n projectName: string | undefined;\n} {\n const remote = parseGitRemote();\n\n // Project name: git repo name > directory name\n const projectName = remote?.repo || basename(process.cwd()) || undefined;\n\n // Org name: git remote org > email domain (skip freemail)\n let orgName: string | undefined;\n if (remote?.org) {\n orgName = remote.org;\n } else {\n const domain = email.split('@')[1]?.toLowerCase();\n if (domain && !FREEMAIL_DOMAINS.has(domain)) {\n orgName = domain.split('.')[0];\n }\n }\n\n return { orgName, projectName };\n}\n\nexport function getUncommittedOrUntrackedFiles(): string[] {\n let gitStatus: string;\n try {\n gitStatus = childProcess\n .execSync('git status --porcelain=v1', {\n // we only care about stdout\n stdio: ['ignore', 'pipe', 'ignore'],\n })\n .toString();\n } catch {\n return [];\n }\n\n const result: string[] = [];\n for (const rawLine of gitStatus.split(os.EOL)) {\n const line = rawLine.trim();\n if (!line) continue;\n const match = /^\\S+\\s+(\\S+)/.exec(line);\n result.push(`- ${match?.[1]}`);\n }\n return result;\n}\n\nexport async function isReact19Installed({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n try {\n const packageJson = await tryGetPackageJson({ installDir });\n if (!packageJson) return false;\n const reactVersion = getDeclaredVersion('react', packageJson);\n\n if (!reactVersion) {\n return false;\n }\n\n return versionSatisfiesRange({\n version: reactVersion,\n acceptableVersions: '>=19.0.0',\n canBeLatest: true,\n });\n } catch {\n return false;\n }\n}\n\n/**\n * Installs or updates a package with the user's package manager.\n *\n * IMPORTANT: This function modifies the `package.json`! Be sure to re-read\n * it if you make additional modifications to it after calling this function!\n */\nexport async function installPackage({\n packageName,\n alreadyInstalled,\n packageNameDisplayLabel,\n packageManager,\n integration,\n installDir,\n}: {\n packageName: string;\n alreadyInstalled: boolean;\n packageNameDisplayLabel?: string;\n packageManager?: PackageManager;\n integration?: string;\n installDir: string;\n}): Promise<{ packageManager?: PackageManager }> {\n return withProgress('install-package', async () => {\n const sdkInstallSpinner = getUI().spinner();\n\n const pkgManager =\n packageManager || (await getPackageManager({ installDir }));\n\n const isReact19 = await isReact19Installed({ installDir });\n const legacyPeerDepsFlag =\n isReact19 && pkgManager.name === 'npm' ? '--legacy-peer-deps' : '';\n\n sdkInstallSpinner.start(\n `${alreadyInstalled ? 'Updating' : 'Installing'} ${\n packageNameDisplayLabel ?? packageName\n } with ${pkgManager.label}.`,\n );\n\n const execAsync = promisify(childProcess.exec);\n const installCommand =\n `${pkgManager.installCommand} ${packageName} ${pkgManager.flags} ${legacyPeerDepsFlag}`.trim();\n\n try {\n await execAsync(installCommand, { cwd: installDir });\n } catch (e) {\n const { stdout = '', stderr = '' } = (e ?? {}) as {\n stdout?: string;\n stderr?: string;\n };\n fs.writeFileSync(\n join(\n process.cwd(),\n `posthog-wizard-installation-error-${Date.now()}.log`,\n ),\n JSON.stringify({ stdout, stderr }),\n { encoding: 'utf8' },\n );\n sdkInstallSpinner.stop('Installation failed.');\n getUI().log.error(\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n `Encountered the following error during installation:\\n\\n${e}\\n\\nThe wizard has created a \\`posthog-wizard-installation-error-*.log\\` file. If you think this issue is caused by the PostHog wizard, create an issue on GitHub and include the log file's content:\\n${ISSUES_URL}`,\n );\n await abort();\n }\n\n sdkInstallSpinner.stop(\n `${alreadyInstalled ? 'Updated' : 'Installed'} ${\n packageNameDisplayLabel ?? packageName\n } with ${pkgManager.label}.`,\n );\n\n analytics.wizardCapture('package installed', {\n package_name: packageName,\n package_manager: pkgManager.name,\n integration,\n });\n\n return { packageManager: pkgManager };\n });\n}\n\n/**\n * Get package.json or abort the wizard if not found.\n * Only use where package.json is required (e.g., package install, overrides).\n * For detection/version-checks, use tryGetPackageJson() instead.\n */\nexport async function getPackageDotJson({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<PackageJson> {\n const pkgPath = join(installDir, 'package.json');\n\n let raw: string;\n try {\n raw = await fs.promises.readFile(pkgPath, 'utf8');\n } catch {\n getUI().log.error(\n 'Could not find package.json. Make sure to run the wizard in the root of your app!',\n );\n await abort();\n return {};\n }\n\n try {\n const parsed = JSON.parse(raw) as PackageJson | null;\n return parsed ?? {};\n } catch {\n getUI().log.error(\n `Unable to parse your package.json. Make sure it has a valid format!`,\n );\n await abort();\n return {};\n }\n}\n\n/**\n * Try to get package.json, returning null if it doesn't exist.\n * Use this for detection purposes where missing package.json is expected (e.g., Python projects).\n */\nexport async function tryGetPackageJson({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<PackageJson | null> {\n try {\n const packageJsonFileContents = await fs.promises.readFile(\n join(installDir, 'package.json'),\n 'utf8',\n );\n return JSON.parse(packageJsonFileContents) as PackageJson;\n } catch {\n return null;\n }\n}\n\nexport async function updatePackageDotJson(\n packageDotJson: PackageJson,\n { installDir }: Pick<WizardRunOptions, 'installDir'>,\n): Promise<void> {\n const pkgPath = join(installDir, 'package.json');\n const serialized = JSON.stringify(packageDotJson, null, 2);\n\n try {\n await fs.promises.writeFile(pkgPath, serialized, {\n encoding: 'utf8',\n flag: 'w',\n });\n return;\n } catch {\n getUI().log.error(`Unable to update your package.json.`);\n await abort();\n }\n}\n\n/**\n * Detect and return the package manager. Pure — no prompts.\n * Falls back to first detected or npm if ambiguous.\n */\n// eslint-disable-next-line @typescript-eslint/require-await\nexport async function getPackageManager(\n options: Pick<WizardRunOptions, 'installDir'> & { ci?: boolean },\n): Promise<PackageManager> {\n const detectedPackageManagers = detectAllPackageManagers({\n installDir: options.installDir,\n });\n\n if (detectedPackageManagers.length >= 1) {\n const selected = detectedPackageManagers[0];\n analytics.setTag('package-manager', selected.name);\n return selected;\n }\n\n // No package manager detected — default to npm\n analytics.setTag('package-manager', npm.name);\n return npm;\n}\n\nexport function isUsingTypeScript({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): boolean {\n try {\n fs.accessSync(join(installDir, 'tsconfig.json'));\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get project data for the wizard via OAuth or CI API key.\n */\nexport async function getOrAskForProjectData(\n _options: Pick<WizardRunOptions, 'signup' | 'ci' | 'apiKey' | 'projectId'> & {\n email?: string;\n region?: CloudRegion;\n },\n): Promise<{\n host: string;\n projectApiKey: string;\n accessToken: string;\n projectId: number;\n cloudRegion: CloudRegion;\n roleAtOrganization: string | null;\n user: ApiUser | null;\n}> {\n // CI mode: bypass OAuth, use personal API key for LLM gateway\n if (_options.ci && _options.apiKey) {\n getUI().log.info('Using provided API key (CI mode - OAuth bypassed)');\n\n const cloudRegion = await detectRegionFromToken(_options.apiKey);\n const host = getHostFromRegion(cloudRegion);\n const cloudUrl = getCloudUrlFromRegion(cloudRegion);\n\n const projectData =\n _options.projectId != null\n ? await fetchProjectDataById(\n _options.apiKey,\n _options.projectId,\n cloudUrl,\n )\n : await fetchProjectDataWithApiKey(_options.apiKey, cloudUrl);\n\n // Best-effort user fetch — CI flows may run with project-scoped keys\n // that 403 on /api/users/@me/, so swallow errors and continue with\n // a null user (and null role).\n let user: ApiUser | null = null;\n let roleAtOrganization: string | null = null;\n try {\n user = await fetchUserData(_options.apiKey, cloudUrl);\n roleAtOrganization = user.role_at_organization ?? null;\n } catch {\n // best-effort\n }\n\n return {\n host,\n projectApiKey: projectData.api_token,\n accessToken: _options.apiKey,\n projectId: projectData.id,\n cloudRegion,\n roleAtOrganization,\n user,\n };\n }\n\n const {\n host,\n projectApiKey,\n accessToken,\n projectId,\n cloudRegion,\n roleAtOrganization,\n user,\n } = await withProgress('login', () =>\n askForWizardLogin({\n signup: _options.signup,\n email: _options.email,\n region: _options.region,\n }),\n );\n\n if (!projectApiKey) {\n const cloudUrl = getCloudUrlFromRegion(cloudRegion);\n getUI().log.error(`Didn't receive a project token. This shouldn't happen :(\n\nPlease let us know if you think this is a bug in the wizard:\n${ISSUES_URL}`);\n\n getUI().log\n .info(`In the meantime, we'll add a dummy project token (\"${DUMMY_PROJECT_API_KEY}\") for you to replace later.\nYou can find your project token here:\n${cloudUrl}/settings/project#variables`);\n }\n\n return {\n accessToken,\n host: host || DEFAULT_HOST_URL,\n projectApiKey: projectApiKey || DUMMY_PROJECT_API_KEY,\n projectId,\n cloudRegion,\n roleAtOrganization: roleAtOrganization ?? null,\n user: user ?? null,\n };\n}\n\nasync function fetchProjectDataWithApiKey(\n apiKey: string,\n cloudUrl: string,\n): Promise<{ api_token: string; id: number }> {\n const userData = await fetchUserData(apiKey, cloudUrl);\n const projectId = userData.team?.id;\n\n if (!projectId) {\n throw new Error(\n 'Could not determine project ID from API key. Please ensure your API key has access to a project in this cloud region.',\n );\n }\n\n const projectData = await fetchProjectData(apiKey, projectId, cloudUrl);\n return {\n api_token: projectData.api_token,\n id: projectId,\n };\n}\n\nasync function fetchProjectDataById(\n apiKey: string,\n projectId: number,\n cloudUrl: string,\n): Promise<{ api_token: string; id: number }> {\n const projectData = await fetchProjectData(apiKey, projectId, cloudUrl);\n return {\n api_token: projectData.api_token,\n id: projectId,\n };\n}\n\nasync function askForWizardLogin(options: {\n signup: boolean;\n email?: string;\n region?: CloudRegion;\n}): Promise<ProjectData & { cloudRegion: CloudRegion }> {\n if (options.signup) {\n return askForProvisioningSignup(options.email, options.region);\n }\n\n const tokenResponse = await performOAuthFlow({\n scopes: [...WIZARD_OAUTH_SCOPES],\n signup: false,\n });\n\n const projectId = tokenResponse.scoped_teams?.[0];\n\n if (projectId === undefined) {\n const error = new Error(\n 'No project access granted. Please authorize with project-level access.',\n );\n analytics.captureException(error, {\n step: 'wizard_login',\n has_scoped_teams: !!tokenResponse.scoped_teams,\n });\n getUI().log.error(error.message);\n await abort();\n }\n\n const cloudRegion = await detectRegionFromToken(tokenResponse.access_token);\n const cloudUrl = getCloudUrlFromRegion(cloudRegion);\n const host = getHostFromRegion(cloudRegion);\n\n const projectData = await fetchProjectData(\n tokenResponse.access_token,\n projectId!,\n cloudUrl,\n );\n const userData = await fetchUserData(tokenResponse.access_token, cloudUrl);\n\n const data = {\n accessToken: tokenResponse.access_token,\n projectApiKey: projectData.api_token,\n host,\n distinctId: userData.distinct_id,\n projectId: projectId!,\n cloudRegion,\n roleAtOrganization: userData.role_at_organization ?? null,\n user: userData,\n };\n\n getUI().log.success('Login complete.');\n analytics.setTag('opened-wizard-link', true);\n analytics.setDistinctId(data.distinctId);\n\n return data;\n}\n\nasync function askForProvisioningSignup(\n email?: string,\n region?: CloudRegion,\n): Promise<ProjectData & { cloudRegion: CloudRegion }> {\n if (!email || !email.includes('@')) {\n getUI().log.error(\n 'Email is required for signup. Use --email your@email.com with --signup.',\n );\n await abort();\n throw new Error('unreachable');\n }\n\n const spinner = getUI().spinner();\n spinner.start('Creating your PostHog account...');\n\n try {\n const provisionRegion = (region ?? 'us').toUpperCase() as 'US' | 'EU';\n const { orgName, projectName } = detectOrgAndProject(email);\n const result = await provisionNewAccount(email, '', provisionRegion, {\n orgName,\n projectName,\n });\n\n spinner.stop('Account created!');\n getUI().log.success('Welcome to PostHog!');\n\n const host = result.host;\n const cloudRegion: CloudRegion = host.includes('eu.') ? 'eu' : 'us';\n\n analytics.setTag('provisioning-signup', true);\n\n return {\n accessToken: result.accessToken,\n projectApiKey: result.projectApiKey,\n host,\n distinctId: email,\n projectId: parseInt(result.projectId, 10) || 0,\n cloudRegion,\n };\n } catch (error) {\n spinner.stop('Account creation failed.');\n const message = error instanceof Error ? error.message : 'Unknown error';\n\n if (message.includes('already associated')) {\n getUI().log.info(\n 'This email already has a PostHog account. Switching to login flow...',\n );\n return askForWizardLogin({ signup: false });\n }\n\n getUI().log.error(`Failed to create account: ${message}`);\n analytics.captureException(\n error instanceof Error ? error : new Error(message),\n { step: 'provisioning_signup' },\n );\n await abort();\n throw error;\n }\n}\n\n/**\n * Creates a new config file with the given filepath and codeSnippet.\n */\nexport async function createNewConfigFile(\n filepath: string,\n codeSnippet: string,\n { installDir }: Pick<WizardRunOptions, 'installDir'>,\n moreInformation?: string,\n): Promise<boolean> {\n if (!isAbsolute(filepath)) {\n debug(`createNewConfigFile: filepath is not absolute: ${filepath}`);\n return false;\n }\n\n const prettyFilename = relative(installDir, filepath);\n\n try {\n await fs.promises.writeFile(filepath, codeSnippet);\n\n getUI().log.success(`Added new ${prettyFilename} file.`);\n\n if (moreInformation) {\n getUI().log.info(moreInformation);\n }\n\n return true;\n } catch (e) {\n debug(e);\n getUI().log.warn(\n `Could not create a new ${prettyFilename} file. Please create one manually and follow the instructions below.`,\n );\n }\n\n return false;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { M as POSTHOG_DOCS_URL } from "./debug-ubpO6102.js";
|
|
2
|
+
import { d as createSkillProgram, n as runWizard, t as runWizardCI } from "./bin.js";
|
|
3
|
+
//#region src/commands/basic-integration/skill.ts
|
|
4
|
+
/** Run an arbitrary context-mill skill by id (`--skill <id>`, headless with `--ci`). */
|
|
5
|
+
function runSkillMode(argv) {
|
|
6
|
+
const skillId = argv.skill;
|
|
7
|
+
const config = createSkillProgram({
|
|
8
|
+
skillId,
|
|
9
|
+
command: "skill",
|
|
10
|
+
id: "agent-skill",
|
|
11
|
+
description: `Run skill: ${skillId}`,
|
|
12
|
+
integrationLabel: skillId,
|
|
13
|
+
successMessage: `${skillId} completed!`,
|
|
14
|
+
reportFile: `posthog-${skillId}-report.md`,
|
|
15
|
+
docsUrl: POSTHOG_DOCS_URL,
|
|
16
|
+
spinnerMessage: `Running ${skillId}...`,
|
|
17
|
+
estimatedDurationMinutes: 5
|
|
18
|
+
});
|
|
19
|
+
const options = {
|
|
20
|
+
...argv,
|
|
21
|
+
skillId
|
|
22
|
+
};
|
|
23
|
+
if (argv.ci) runWizardCI(config, options);
|
|
24
|
+
else runWizard(config, options);
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { runSkillMode };
|
|
28
|
+
|
|
29
|
+
//# sourceMappingURL=skill-CnOQAZXp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-CnOQAZXp.js","names":[],"sources":["../src/commands/basic-integration/skill.ts"],"sourcesContent":["import type { Arguments } from 'yargs';\nimport { POSTHOG_DOCS_URL } from '@lib/constants';\nimport { runWizard, runWizardCI } from '@lib/runners';\nimport { createSkillProgram } from '@lib/programs/agent-skill/index';\n\n/** Run an arbitrary context-mill skill by id (`--skill <id>`, headless with `--ci`). */\nexport function runSkillMode(argv: Arguments): void {\n const skillId = argv.skill as string;\n const config = createSkillProgram({\n skillId,\n command: 'skill',\n id: 'agent-skill',\n description: `Run skill: ${skillId}`,\n integrationLabel: skillId,\n successMessage: `${skillId} completed!`,\n reportFile: `posthog-${skillId}-report.md`,\n docsUrl: POSTHOG_DOCS_URL,\n spinnerMessage: `Running ${skillId}...`,\n estimatedDurationMinutes: 5,\n });\n const options = { ...argv, skillId };\n if (argv.ci) {\n runWizardCI(config, options);\n } else {\n runWizard(config, options);\n }\n}\n"],"mappings":";;;;AAMA,SAAgB,aAAa,MAAuB;CAClD,MAAM,UAAU,KAAK;CACrB,MAAM,SAAS,mBAAmB;EAChC;EACA,SAAS;EACT,IAAI;EACJ,aAAa,cAAc;EAC3B,kBAAkB;EAClB,gBAAgB,GAAG,QAAQ;EAC3B,YAAY,WAAW,QAAQ;EAC/B,SAAS;EACT,gBAAgB,WAAW,QAAQ;EACnC,0BAA0B;EAC3B,CAAC;CACF,MAAM,UAAU;EAAE,GAAG;EAAM;EAAS;AACpC,KAAI,KAAK,GACP,aAAY,QAAQ,QAAQ;KAE5B,WAAU,QAAQ,QAAQ"}
|