@posthog/wizard 2.14.3 → 2.16.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/README.md +43 -1
- package/dist/{TextBlock-DEHERFec.js → TextBlock-DJVhBkr3.js} +4 -4
- package/dist/TextBlock-DJVhBkr3.js.map +1 -0
- package/dist/{add-mcp-server-to-clients-B48J7VVO.js → add-mcp-server-to-clients-9jQjc-CO.js} +5 -5
- package/dist/{add-mcp-server-to-clients-B48J7VVO.js.map → add-mcp-server-to-clients-9jQjc-CO.js.map} +1 -1
- package/dist/{agent-interface-cEdS_bNo.js → agent-interface-pBnqJL8P.js} +106 -21
- package/dist/agent-interface-pBnqJL8P.js.map +1 -0
- package/dist/{agent-runner-CK5r-zQF.js → agent-runner-H1FP6XTc.js} +12 -9
- package/dist/agent-runner-H1FP6XTc.js.map +1 -0
- package/dist/{analytics-DaDpDus8.js → analytics-DZaUgJte.js} +2 -2
- package/dist/{analytics-DaDpDus8.js.map → analytics-DZaUgJte.js.map} +1 -1
- package/dist/analytics-DqeW7XYt.js +2 -0
- package/dist/bin.js +965 -83
- package/dist/bin.js.map +1 -1
- package/dist/{debug-B_PK52GI.js → debug-B6rX6xye.js} +1 -1
- package/dist/{debug-BOogNcWX.js → debug-C4jRuzny.js} +57 -46
- package/dist/debug-C4jRuzny.js.map +1 -0
- package/dist/{defaults-DgKAzsD1.js → defaults-GbLPuHxj.js} +1 -1
- package/dist/{defaults-DgKAzsD1.js.map → defaults-GbLPuHxj.js.map} +1 -1
- package/dist/{detection-OCF8fpfp.js → detection-4eukp9HD.js} +3 -3
- package/dist/{detection-OCF8fpfp.js.map → detection-4eukp9HD.js.map} +1 -1
- package/dist/{env-api-key-D5G2PrXW.js → env-api-key-DU8uIEvo.js} +1 -1
- package/dist/{env-api-key-D5G2PrXW.js.map → env-api-key-DU8uIEvo.js.map} +1 -1
- package/dist/{file-utils-DPmgn9Vm.js → file-utils-DnTSiTJw.js} +1 -1
- package/dist/file-utils-DnTSiTJw.js.map +1 -0
- package/dist/mcp-prompt-streaming-DKiaymMt.js +200 -0
- package/dist/mcp-prompt-streaming-DKiaymMt.js.map +1 -0
- package/dist/package-json-Cttzi3C8.js +2 -0
- package/dist/package-json-v_g2YlN1.js +35 -0
- package/dist/package-json-v_g2YlN1.js.map +1 -0
- package/dist/{package-manager-CmMJAD-V.js → package-manager-DLt75bit.js} +2 -2
- package/dist/package-manager-DLt75bit.js.map +1 -0
- package/dist/posthog-7B92c2Ed.js +120 -0
- package/dist/posthog-7B92c2Ed.js.map +1 -0
- package/dist/{posthog-integration-By5930Gz.js → posthog-integration-CukaeYil.js} +13 -12
- package/dist/{posthog-integration-By5930Gz.js.map → posthog-integration-CukaeYil.js.map} +1 -1
- package/dist/{provisioning-BHa8VWaa.js → provisioning-C_ETLiZE.js} +3 -3
- package/dist/{provisioning-BHa8VWaa.js.map → provisioning-C_ETLiZE.js.map} +1 -1
- package/dist/provisioning-Ch6i8dRV.js +2 -0
- package/dist/{registry-DpROZPnl.js → registry-DqbwO5EL.js} +31 -31
- package/dist/registry-DqbwO5EL.js.map +1 -0
- package/dist/setup-utils-C5uZ9g60.js +2 -0
- package/dist/{setup-utils-Mzpk1vqG.js → setup-utils-DdAdxUTV.js} +170 -60
- package/dist/setup-utils-DdAdxUTV.js.map +1 -0
- package/dist/{slides-BtDXEXdn.js → slides-Dpj4j0w_.js} +580 -27
- package/dist/slides-Dpj4j0w_.js.map +1 -0
- package/dist/smoke-test-ci.sh +5 -2
- package/dist/smoke-test.sh +43 -0
- package/dist/{start-playground-zZL5y9id.js → start-playground-B40O4tye.js} +288 -6
- package/dist/start-playground-B40O4tye.js.map +1 -0
- package/dist/{start-tui-Cz7RZSn_.js → start-tui-CH_ZzQXx.js} +628 -26
- package/dist/start-tui-CH_ZzQXx.js.map +1 -0
- package/dist/{steps-C2XEzN79.js → steps-0d9XqvI6.js} +6 -6
- package/dist/{steps-C2XEzN79.js.map → steps-0d9XqvI6.js.map} +1 -1
- package/dist/task-stream-CoEsidgG.js +195 -0
- package/dist/task-stream-CoEsidgG.js.map +1 -0
- package/dist/{telemetry-BG2bOwCp.js → telemetry-jn2Daxl2.js} +2 -2
- package/dist/{telemetry-BG2bOwCp.js.map → telemetry-jn2Daxl2.js.map} +1 -1
- package/dist/{wizard-abort-BmT-F0Vr.js → wizard-abort-BjLIgu2s.js} +3 -3
- package/dist/{wizard-abort-BmT-F0Vr.js.map → wizard-abort-BjLIgu2s.js.map} +1 -1
- package/dist/{wizard-abort-CYW83OG5.js → wizard-abort-BlYGA1Jk.js} +1 -1
- package/dist/{wizard-session-CsI33S4_.js → wizard-session-Bi95IYca.js} +19 -2
- package/dist/wizard-session-Bi95IYca.js.map +1 -0
- package/dist/wizard-session-DPGTaJ4W.js +2 -0
- package/dist/wizard-ui-YdGFRyu_.js.map +1 -1
- package/package.json +3 -2
- package/dist/TextBlock-DEHERFec.js.map +0 -1
- package/dist/agent-interface-cEdS_bNo.js.map +0 -1
- package/dist/agent-runner-CK5r-zQF.js.map +0 -1
- package/dist/analytics-Bw8E-yhX.js +0 -2
- package/dist/craft-pre-release.sh +0 -10
- package/dist/debug-BOogNcWX.js.map +0 -1
- package/dist/file-BKbKreWF.js +0 -16
- package/dist/file-BKbKreWF.js.map +0 -1
- package/dist/file-utils-DPmgn9Vm.js.map +0 -1
- package/dist/package-json-DZpnf6vU.js +0 -23
- package/dist/package-json-DZpnf6vU.js.map +0 -1
- package/dist/package-json-_4PEss19.js +0 -2
- package/dist/package-manager-CmMJAD-V.js.map +0 -1
- package/dist/paths-DJS47p5x.js +0 -26
- package/dist/paths-DJS47p5x.js.map +0 -1
- package/dist/posthog-BbQf_Hzq.js +0 -11
- package/dist/posthog-BbQf_Hzq.js.map +0 -1
- package/dist/provisioning-gHqu_MXL.js +0 -2
- package/dist/registry-DpROZPnl.js.map +0 -1
- package/dist/setup-utils-Mzpk1vqG.js.map +0 -1
- package/dist/setup-utils-ptemIB6g.js +0 -2
- package/dist/slides-BtDXEXdn.js.map +0 -1
- package/dist/start-playground-zZL5y9id.js.map +0 -1
- package/dist/start-tui-Cz7RZSn_.js.map +0 -1
- package/dist/task-stream-DUpUZmFQ.js +0 -61
- package/dist/task-stream-DUpUZmFQ.js.map +0 -1
- package/dist/wizard-session-CPhhll4P.js +0 -2
- package/dist/wizard-session-CsI33S4_.js.map +0 -1
package/dist/bin.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { t as __exportAll } from "./rolldown-runtime-B_-DWIq7.js";
|
|
3
|
-
import {
|
|
4
|
-
import { n as analytics } from "./analytics-
|
|
5
|
-
import { a as isUsingTypeScript,
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
3
|
+
import { M as POSTHOG_DOCS_URL, W as WIZARD_USER_AGENT, X as VERSION, Y as runtimeEnv, _ as SIGNUP_WIZARD_READINESS_CONFIG, h as LoggingUI, m as setUI, p as getUI, s as logToFile, v as evaluateWizardReadiness, y as getBlockingServiceKeys } from "./debug-C4jRuzny.js";
|
|
4
|
+
import { n as analytics } from "./analytics-DZaUgJte.js";
|
|
5
|
+
import { a as isUsingTypeScript, f as getCloudUrlFromRegion, m as getUiHostFromHost, u as handleApiError } from "./setup-utils-DdAdxUTV.js";
|
|
6
|
+
import "./wizard-session-Bi95IYca.js";
|
|
7
|
+
import { g as AUDIT_REPORT_FILE, h as AUDIT_CHECKS_KEY, m as AUDIT_CHECKS_FILE, t as AgentSignals, u as WIZARD_TOOL_NAMES } from "./agent-interface-pBnqJL8P.js";
|
|
8
|
+
import { i as SPINNER_MESSAGE } from "./registry-DqbwO5EL.js";
|
|
9
|
+
import { c as HEALTH_CHECK_STEP, o as Colors, r as isClearBlock } from "./TextBlock-DJVhBkr3.js";
|
|
10
|
+
import { a as LINE_CHART_BLOCK, i as FUNNEL_BLOCK, n as posthogIntegrationConfig, o as PRODUCT_SUITE_BLOCK, s as StatusPeekTrigger } from "./posthog-integration-CukaeYil.js";
|
|
11
|
+
import { t as IGNORED_DIRS } from "./file-utils-DnTSiTJw.js";
|
|
11
12
|
import { satisfies } from "semver";
|
|
12
13
|
import yargs from "yargs";
|
|
13
14
|
import { hideBin } from "yargs/helpers";
|
|
@@ -34,7 +35,7 @@ function readEnvironment() {
|
|
|
34
35
|
}
|
|
35
36
|
//#endregion
|
|
36
37
|
//#region src/lib/programs/revenue-analytics/detect.ts
|
|
37
|
-
const POSTHOG_SDKS = [
|
|
38
|
+
const POSTHOG_SDKS$1 = [
|
|
38
39
|
"posthog-js",
|
|
39
40
|
"posthog-node",
|
|
40
41
|
"posthog-react-native",
|
|
@@ -79,7 +80,7 @@ function findPackageJsons(installDir, maxDepth = 3) {
|
|
|
79
80
|
if (entry.isFile() && entry.name === "package.json") try {
|
|
80
81
|
const pkg = JSON.parse(readFileSync(fullPath, "utf-8"));
|
|
81
82
|
const depNames = [...Object.keys(pkg.dependencies ?? {}), ...Object.keys(pkg.devDependencies ?? {})];
|
|
82
|
-
const posthogSdks = depNames.filter((d) => POSTHOG_SDKS.includes(d));
|
|
83
|
+
const posthogSdks = depNames.filter((d) => POSTHOG_SDKS$1.includes(d));
|
|
83
84
|
const stripeSdks = depNames.filter((d) => STRIPE_SDKS.includes(d));
|
|
84
85
|
matches.push({
|
|
85
86
|
path: relative(installDir, fullPath) || "package.json",
|
|
@@ -212,7 +213,7 @@ const REVENUE_ANALYTICS_PROGRAM = [
|
|
|
212
213
|
* skill-based program (audit, revenue-analytics, agent-skill, etc.)
|
|
213
214
|
* runs. Skill programs don't need the full PostHog onboarding narrative.
|
|
214
215
|
*/
|
|
215
|
-
const getContentBlocks$
|
|
216
|
+
const getContentBlocks$2 = (store) => {
|
|
216
217
|
return [
|
|
217
218
|
{
|
|
218
219
|
content: "Welcome.",
|
|
@@ -244,7 +245,7 @@ const revenueAnalyticsConfig = {
|
|
|
244
245
|
description: "Set up PostHog revenue analytics (e.g. Stripe integration)",
|
|
245
246
|
id: "revenue-analytics-setup",
|
|
246
247
|
steps: REVENUE_ANALYTICS_PROGRAM,
|
|
247
|
-
getContentBlocks: getContentBlocks$
|
|
248
|
+
getContentBlocks: getContentBlocks$2,
|
|
248
249
|
allowedTools: ["Agent"],
|
|
249
250
|
disallowedTools: [WIZARD_TOOL_NAMES.wizardAsk],
|
|
250
251
|
run: {
|
|
@@ -305,7 +306,7 @@ function createSkillProgram(opts) {
|
|
|
305
306
|
skillId: opts.skillId,
|
|
306
307
|
steps: AGENT_SKILL_STEPS,
|
|
307
308
|
reportFile: opts.reportFile,
|
|
308
|
-
getContentBlocks: getContentBlocks$
|
|
309
|
+
getContentBlocks: getContentBlocks$2,
|
|
309
310
|
run: {
|
|
310
311
|
skillId: opts.skillId,
|
|
311
312
|
integrationLabel: opts.integrationLabel,
|
|
@@ -506,7 +507,7 @@ const EVENTS_AUDIT_PROGRAM = [
|
|
|
506
507
|
//#endregion
|
|
507
508
|
//#region src/lib/programs/events-audit/index.ts
|
|
508
509
|
const SETUP_REPORT_FILE = "posthog-events-audit-report.md";
|
|
509
|
-
const DOCS_URL = "https://posthog.com/docs/product-analytics/best-practices";
|
|
510
|
+
const DOCS_URL$1 = "https://posthog.com/docs/product-analytics/best-practices";
|
|
510
511
|
const eventsAuditConfig = {
|
|
511
512
|
command: "events-audit",
|
|
512
513
|
description: "Audit PostHog event tracking in this project",
|
|
@@ -528,7 +529,7 @@ const eventsAuditConfig = {
|
|
|
528
529
|
successMessage: "Events audit complete! You can view the report at ./posthog-events-audit-report.md",
|
|
529
530
|
estimatedDurationMinutes: 5,
|
|
530
531
|
reportFile: SETUP_REPORT_FILE,
|
|
531
|
-
docsUrl: DOCS_URL,
|
|
532
|
+
docsUrl: DOCS_URL$1,
|
|
532
533
|
errorMessage: "Events audit failed",
|
|
533
534
|
additionalFeatureQueue: session.additionalFeatureQueue,
|
|
534
535
|
customPrompt: (ctx) => `Audit PostHog event capture in this project. Do not modify any project files — produce a read-only report only.
|
|
@@ -546,7 +547,7 @@ Project context:
|
|
|
546
547
|
message: "Your events audit was successful",
|
|
547
548
|
reportFile: SETUP_REPORT_FILE,
|
|
548
549
|
changes: [],
|
|
549
|
-
docsUrl: DOCS_URL,
|
|
550
|
+
docsUrl: DOCS_URL$1,
|
|
550
551
|
continueUrl: sess.signup && cloudUrl ? `${cloudUrl}/products?source=wizard` : void 0,
|
|
551
552
|
dashboardUrl: sess.dashboardUrl ?? (cloudUrl ? `${cloudUrl}/dashboard` : void 0)
|
|
552
553
|
};
|
|
@@ -1188,7 +1189,7 @@ const PRICING_STRUCTURE_BLOCK = {
|
|
|
1188
1189
|
* - posthog.com/docs/feature-flags/common-questions
|
|
1189
1190
|
* - posthog.com/docs/experiments/best-practices
|
|
1190
1191
|
*/
|
|
1191
|
-
const getContentBlocks = (store) => [
|
|
1192
|
+
const getContentBlocks$1 = (store) => [
|
|
1192
1193
|
{
|
|
1193
1194
|
content: "Hello.",
|
|
1194
1195
|
pause: 3e3,
|
|
@@ -1440,7 +1441,7 @@ const migrationConfig = {
|
|
|
1440
1441
|
skillId: PRODUCT_TO_SKILL_ID.statsig,
|
|
1441
1442
|
steps: MIGRATION_PROGRAM,
|
|
1442
1443
|
reportFile: MIGRATION_REPORT_FILE,
|
|
1443
|
-
getContentBlocks,
|
|
1444
|
+
getContentBlocks: getContentBlocks$1,
|
|
1444
1445
|
allowedTools: ["Agent"],
|
|
1445
1446
|
disallowedTools: [WIZARD_TOOL_NAMES.wizardAsk],
|
|
1446
1447
|
cliOptions: { product: {
|
|
@@ -1464,6 +1465,753 @@ const migrationConfig = {
|
|
|
1464
1465
|
requires: ["posthog-integration"]
|
|
1465
1466
|
};
|
|
1466
1467
|
//#endregion
|
|
1468
|
+
//#region src/lib/programs/error-tracking-upload-source-maps/detect.ts
|
|
1469
|
+
const DISPLAY_NAME = {
|
|
1470
|
+
web: "Web (JavaScript)",
|
|
1471
|
+
nextjs: "Next.js",
|
|
1472
|
+
node: "Node.js",
|
|
1473
|
+
react: "React",
|
|
1474
|
+
angular: "Angular",
|
|
1475
|
+
nuxt: "Nuxt",
|
|
1476
|
+
"react-native": "React Native",
|
|
1477
|
+
android: "Android",
|
|
1478
|
+
flutter: "Flutter",
|
|
1479
|
+
ios: "iOS",
|
|
1480
|
+
vite: "Vite",
|
|
1481
|
+
webpack: "Webpack",
|
|
1482
|
+
rollup: "Rollup"
|
|
1483
|
+
};
|
|
1484
|
+
const POSTHOG_SDKS = [
|
|
1485
|
+
"posthog-js",
|
|
1486
|
+
"posthog-node",
|
|
1487
|
+
"posthog-react-native",
|
|
1488
|
+
"posthog-android",
|
|
1489
|
+
"posthog-ios"
|
|
1490
|
+
];
|
|
1491
|
+
/** `[ABORT] <reason>` cases the source maps skill can emit. */
|
|
1492
|
+
const SOURCE_MAPS_ABORT_CASES = [{
|
|
1493
|
+
match: /^no posthog sdk detected$/i,
|
|
1494
|
+
message: "No PostHog SDK detected",
|
|
1495
|
+
body: "The agent could not find a PostHog SDK in your project. Source map upload requires the SDK to already be installed so it can report errors. Run `npx @posthog/wizard` first to install the SDK.",
|
|
1496
|
+
docsUrl: "https://posthog.com/docs/error-tracking"
|
|
1497
|
+
}, {
|
|
1498
|
+
match: /^build command not found$/i,
|
|
1499
|
+
message: "Build command not found",
|
|
1500
|
+
body: "The agent could not identify how to build your project. Source map upload runs as part of the production build. Add a build script to your project and run this wizard again.",
|
|
1501
|
+
docsUrl: "https://posthog.com/docs/error-tracking/upload-source-maps"
|
|
1502
|
+
}];
|
|
1503
|
+
function collectSignals(installDir, maxDepth = 3) {
|
|
1504
|
+
const signals = {
|
|
1505
|
+
packageJsons: [],
|
|
1506
|
+
hasXcodeProject: false,
|
|
1507
|
+
hasPodfile: false,
|
|
1508
|
+
hasSwiftPackage: false,
|
|
1509
|
+
hasGradle: false,
|
|
1510
|
+
hasPubspec: false,
|
|
1511
|
+
scannedFileCount: 0
|
|
1512
|
+
};
|
|
1513
|
+
function scan(dir, depth) {
|
|
1514
|
+
if (depth > maxDepth) return;
|
|
1515
|
+
let entries;
|
|
1516
|
+
try {
|
|
1517
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
1518
|
+
} catch {
|
|
1519
|
+
return;
|
|
1520
|
+
}
|
|
1521
|
+
for (const entry of entries) {
|
|
1522
|
+
if (entry.name.startsWith(".") && entry.name !== ".") continue;
|
|
1523
|
+
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
1524
|
+
const fullPath = join(dir, entry.name);
|
|
1525
|
+
if (entry.isFile()) {
|
|
1526
|
+
signals.scannedFileCount += 1;
|
|
1527
|
+
if (entry.name === "package.json") try {
|
|
1528
|
+
const pkg = JSON.parse(readFileSync(fullPath, "utf-8"));
|
|
1529
|
+
const deps = new Set([...Object.keys(pkg.dependencies ?? {}), ...Object.keys(pkg.devDependencies ?? {})]);
|
|
1530
|
+
signals.packageJsons.push({
|
|
1531
|
+
path: relative(installDir, fullPath) || "package.json",
|
|
1532
|
+
deps
|
|
1533
|
+
});
|
|
1534
|
+
} catch {}
|
|
1535
|
+
else if (entry.name === "Podfile") signals.hasPodfile = true;
|
|
1536
|
+
else if (entry.name === "Package.swift") signals.hasSwiftPackage = true;
|
|
1537
|
+
else if (entry.name === "pubspec.yaml") signals.hasPubspec = true;
|
|
1538
|
+
else if (entry.name === "build.gradle" || entry.name === "build.gradle.kts" || entry.name === "settings.gradle" || entry.name === "settings.gradle.kts") signals.hasGradle = true;
|
|
1539
|
+
} else if (entry.isDirectory()) if (entry.name.endsWith(".xcodeproj")) signals.hasXcodeProject = true;
|
|
1540
|
+
else scan(fullPath, depth + 1);
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
scan(installDir, 0);
|
|
1544
|
+
return signals;
|
|
1545
|
+
}
|
|
1546
|
+
function pickJsVariant(deps) {
|
|
1547
|
+
if (deps.has("react-native")) return "react-native";
|
|
1548
|
+
if (deps.has("nuxt")) return "nuxt";
|
|
1549
|
+
if (deps.has("next")) return "nextjs";
|
|
1550
|
+
if (deps.has("@angular/core")) return "angular";
|
|
1551
|
+
if (deps.has("vite")) return "vite";
|
|
1552
|
+
if (deps.has("webpack")) return "webpack";
|
|
1553
|
+
if (deps.has("rollup")) return "rollup";
|
|
1554
|
+
if (deps.has("react")) return "react";
|
|
1555
|
+
if (deps.has("posthog-node")) return "node";
|
|
1556
|
+
return "web";
|
|
1557
|
+
}
|
|
1558
|
+
function selectVariant(signals) {
|
|
1559
|
+
if (signals.hasPubspec) return "flutter";
|
|
1560
|
+
if (signals.hasXcodeProject || signals.hasPodfile || signals.hasSwiftPackage) return "ios";
|
|
1561
|
+
if (signals.hasGradle) return "android";
|
|
1562
|
+
if (signals.packageJsons.length > 0) {
|
|
1563
|
+
const allDeps = /* @__PURE__ */ new Set();
|
|
1564
|
+
for (const pkg of signals.packageJsons) for (const dep of pkg.deps) allDeps.add(dep);
|
|
1565
|
+
return pickJsVariant(allDeps);
|
|
1566
|
+
}
|
|
1567
|
+
return null;
|
|
1568
|
+
}
|
|
1569
|
+
function hasPostHogSdk(signals) {
|
|
1570
|
+
for (const pkg of signals.packageJsons) for (const sdk of POSTHOG_SDKS) if (pkg.deps.has(sdk)) return true;
|
|
1571
|
+
return signals.hasXcodeProject || signals.hasPodfile || signals.hasSwiftPackage || signals.hasGradle || signals.hasPubspec;
|
|
1572
|
+
}
|
|
1573
|
+
const SOURCE_MAPS_CONTEXT_KEYS = {
|
|
1574
|
+
skillVariant: "sourceMapsSkillVariant",
|
|
1575
|
+
displayName: "sourceMapsDisplayName",
|
|
1576
|
+
packagePaths: "sourceMapsPackagePaths",
|
|
1577
|
+
detectError: "detectError"
|
|
1578
|
+
};
|
|
1579
|
+
/**
|
|
1580
|
+
* Scan `session.installDir` for platform / build-system signals. Writes
|
|
1581
|
+
* detection results into frameworkContext via the callback — either the
|
|
1582
|
+
* picked skill variant + display name, or a `SourceMapsDetectError`.
|
|
1583
|
+
*
|
|
1584
|
+
* The skill install happens later in the agent run, not here. This step
|
|
1585
|
+
* only picks which variant the prompt should ask the agent to load.
|
|
1586
|
+
*/
|
|
1587
|
+
function detectSourceMapsPrerequisites(session, setFrameworkContext) {
|
|
1588
|
+
const fail = (error) => setFrameworkContext(SOURCE_MAPS_CONTEXT_KEYS.detectError, error);
|
|
1589
|
+
const installDir = session.installDir;
|
|
1590
|
+
if (!existsSync(installDir)) {
|
|
1591
|
+
fail({
|
|
1592
|
+
kind: "bad-directory",
|
|
1593
|
+
path: installDir,
|
|
1594
|
+
reason: "missing"
|
|
1595
|
+
});
|
|
1596
|
+
return;
|
|
1597
|
+
}
|
|
1598
|
+
try {
|
|
1599
|
+
if (!statSync(installDir).isDirectory()) {
|
|
1600
|
+
fail({
|
|
1601
|
+
kind: "bad-directory",
|
|
1602
|
+
path: installDir,
|
|
1603
|
+
reason: "not-dir"
|
|
1604
|
+
});
|
|
1605
|
+
return;
|
|
1606
|
+
}
|
|
1607
|
+
} catch {
|
|
1608
|
+
fail({
|
|
1609
|
+
kind: "bad-directory",
|
|
1610
|
+
path: installDir,
|
|
1611
|
+
reason: "unreadable"
|
|
1612
|
+
});
|
|
1613
|
+
return;
|
|
1614
|
+
}
|
|
1615
|
+
const signals = collectSignals(installDir);
|
|
1616
|
+
const variant = selectVariant(signals);
|
|
1617
|
+
if (variant && [
|
|
1618
|
+
"react-native",
|
|
1619
|
+
"flutter",
|
|
1620
|
+
"ios",
|
|
1621
|
+
"android"
|
|
1622
|
+
].includes(variant)) {
|
|
1623
|
+
fail({
|
|
1624
|
+
kind: "unsupported-platform",
|
|
1625
|
+
detected: variant
|
|
1626
|
+
});
|
|
1627
|
+
return;
|
|
1628
|
+
}
|
|
1629
|
+
if (!variant) {
|
|
1630
|
+
if (signals.scannedFileCount === 0) fail({ kind: "no-project-files" });
|
|
1631
|
+
else fail({
|
|
1632
|
+
kind: "unsupported-platform",
|
|
1633
|
+
detected: "unknown"
|
|
1634
|
+
});
|
|
1635
|
+
return;
|
|
1636
|
+
}
|
|
1637
|
+
if (!hasPostHogSdk(signals)) {
|
|
1638
|
+
fail({
|
|
1639
|
+
kind: "no-posthog-sdk",
|
|
1640
|
+
platform: variant
|
|
1641
|
+
});
|
|
1642
|
+
return;
|
|
1643
|
+
}
|
|
1644
|
+
setFrameworkContext(SOURCE_MAPS_CONTEXT_KEYS.skillVariant, variant);
|
|
1645
|
+
setFrameworkContext(SOURCE_MAPS_CONTEXT_KEYS.displayName, DISPLAY_NAME[variant]);
|
|
1646
|
+
setFrameworkContext(SOURCE_MAPS_CONTEXT_KEYS.packagePaths, signals.packageJsons.map((p) => p.path));
|
|
1647
|
+
}
|
|
1648
|
+
//#endregion
|
|
1649
|
+
//#region src/lib/programs/error-tracking-upload-source-maps/steps.ts
|
|
1650
|
+
function healthCheckReady(session) {
|
|
1651
|
+
if (!session.readinessResult) return false;
|
|
1652
|
+
if (session.signup) {
|
|
1653
|
+
const hardBlocking = getBlockingServiceKeys(session.readinessResult.health, SIGNUP_WIZARD_READINESS_CONFIG);
|
|
1654
|
+
const defaultBlocking = getBlockingServiceKeys(session.readinessResult.health);
|
|
1655
|
+
if (hardBlocking.length === 0 && defaultBlocking.length === 0) return true;
|
|
1656
|
+
return session.outageDismissed;
|
|
1657
|
+
}
|
|
1658
|
+
if (session.readinessResult.decision === "no") return session.outageDismissed;
|
|
1659
|
+
return true;
|
|
1660
|
+
}
|
|
1661
|
+
const ERROR_TRACKING_UPLOAD_SOURCE_MAPS_PROGRAM = [
|
|
1662
|
+
{
|
|
1663
|
+
id: "detect",
|
|
1664
|
+
label: "Detecting platform",
|
|
1665
|
+
onReady: (ctx) => detectSourceMapsPrerequisites(ctx.session, ctx.setFrameworkContext)
|
|
1666
|
+
},
|
|
1667
|
+
{
|
|
1668
|
+
id: "intro",
|
|
1669
|
+
label: "Welcome",
|
|
1670
|
+
screenId: "source-maps-intro",
|
|
1671
|
+
gate: (session) => session.setupConfirmed
|
|
1672
|
+
},
|
|
1673
|
+
{
|
|
1674
|
+
id: "health-check",
|
|
1675
|
+
label: "Health check",
|
|
1676
|
+
screenId: "health-check",
|
|
1677
|
+
gate: healthCheckReady,
|
|
1678
|
+
onInit: (ctx) => {
|
|
1679
|
+
evaluateWizardReadiness().then((readiness) => {
|
|
1680
|
+
ctx.setReadinessResult(readiness);
|
|
1681
|
+
}).catch(() => {
|
|
1682
|
+
ctx.setReadinessResult({
|
|
1683
|
+
decision: "yes",
|
|
1684
|
+
health: {},
|
|
1685
|
+
reasons: []
|
|
1686
|
+
});
|
|
1687
|
+
});
|
|
1688
|
+
}
|
|
1689
|
+
},
|
|
1690
|
+
{
|
|
1691
|
+
id: "auth",
|
|
1692
|
+
label: "Authentication",
|
|
1693
|
+
screenId: "auth",
|
|
1694
|
+
isComplete: (session) => session.credentials !== null
|
|
1695
|
+
},
|
|
1696
|
+
{
|
|
1697
|
+
id: "run",
|
|
1698
|
+
label: "Upload source maps",
|
|
1699
|
+
screenId: "run",
|
|
1700
|
+
isComplete: (session) => session.runPhase === "completed" || session.runPhase === "error"
|
|
1701
|
+
},
|
|
1702
|
+
{
|
|
1703
|
+
id: "outro",
|
|
1704
|
+
label: "Done",
|
|
1705
|
+
screenId: "source-maps-outro",
|
|
1706
|
+
isComplete: (session) => session.outroDismissed
|
|
1707
|
+
},
|
|
1708
|
+
{
|
|
1709
|
+
id: "skills",
|
|
1710
|
+
label: "Skills",
|
|
1711
|
+
screenId: "keep-skills"
|
|
1712
|
+
}
|
|
1713
|
+
];
|
|
1714
|
+
//#endregion
|
|
1715
|
+
//#region src/lib/programs/error-tracking-upload-source-maps/prompt.ts
|
|
1716
|
+
const SOURCE_MAPS_DETECTION_FAILED_PROMPT = `Detection did not pick a source maps skill variant for this project.
|
|
1717
|
+
Emit: ${AgentSignals.ABORT} unsupported-platform
|
|
1718
|
+
Then halt.`;
|
|
1719
|
+
function buildSourceMapsUploadPrompt(params) {
|
|
1720
|
+
const { displayName, variant, skillId, projectId, host, settingsUrl, uiHost } = params;
|
|
1721
|
+
const platformLabel = displayName ?? variant;
|
|
1722
|
+
return `You are wiring up PostHog Error Tracking source map upload for this ${platformLabel} project.
|
|
1723
|
+
|
|
1724
|
+
Project context:
|
|
1725
|
+
- PostHog Project ID: ${projectId}
|
|
1726
|
+
- PostHog Host: ${host}
|
|
1727
|
+
- Detected platform: ${platformLabel}
|
|
1728
|
+
- Skill to use: ${skillId}
|
|
1729
|
+
- Personal API keys settings page: ${settingsUrl}
|
|
1730
|
+
|
|
1731
|
+
The skill you install in STEP 2 is the source of truth for the HOW of every
|
|
1732
|
+
step: its "## Steps" section has an overview, tips and per-technology
|
|
1733
|
+
examples for each named step, and its reference files carry the exact
|
|
1734
|
+
per-framework API. The STEPS below give the order, the conditionals, and the
|
|
1735
|
+
wizard-specific mechanics (which MCP tool to call, signals to emit) — read
|
|
1736
|
+
the matching skill step (named in parentheses) before doing the work, and do
|
|
1737
|
+
not invent steps the skill doesn't describe.
|
|
1738
|
+
|
|
1739
|
+
Follow these steps IN ORDER. Do not skip or reorder.
|
|
1740
|
+
|
|
1741
|
+
Before doing any work, create your FULL task list in a single TaskCreate
|
|
1742
|
+
call so the user can follow your progress in the TUI. Use exactly these
|
|
1743
|
+
tasks, in this order — do not collapse, rename, or omit any of them:
|
|
1744
|
+
1. Get personal API key
|
|
1745
|
+
2. Install source maps skill
|
|
1746
|
+
3. Apply build-config changes (per skill)
|
|
1747
|
+
4. Make credentials readable at build time
|
|
1748
|
+
5. Write keys to .env
|
|
1749
|
+
6. Identify build & run commands
|
|
1750
|
+
7. Test the local setup
|
|
1751
|
+
8. Summarise & hand off
|
|
1752
|
+
Drive the list with TaskUpdate — mark a task in_progress when you start it
|
|
1753
|
+
and completed when done. ALWAYS keep task 7 ("Test the local setup") in the
|
|
1754
|
+
list even if the user declines testing in STEP 7: mark it completed rather
|
|
1755
|
+
than deleting it, so the user can see testing was offered.
|
|
1756
|
+
|
|
1757
|
+
STEP 1 — Get a personal API key from the user. (skill: "Get a personal API key")
|
|
1758
|
+
The wizard cannot mint keys — never call the PostHog API or any tool to
|
|
1759
|
+
create one. Ask the user with the wizard_ask MCP tool; you receive the
|
|
1760
|
+
answer as a vaulted secretRef (never the raw value), which you reuse in
|
|
1761
|
+
STEP 5:
|
|
1762
|
+
{
|
|
1763
|
+
id: "api-key",
|
|
1764
|
+
prompt: "Paste your PostHog personal API key below.\\n\\nDon't have one yet? Create one here:\\n${settingsUrl}\\n\\nWhen creating the key, choose the 'Source map upload' preset, then come back and paste it here.",
|
|
1765
|
+
kind: "text",
|
|
1766
|
+
sensitive: true
|
|
1767
|
+
}
|
|
1768
|
+
Keep the \\n line breaks exactly as written — Ink's <Text> renders them
|
|
1769
|
+
as separate lines. The answer is { secretRef: "secret:..." }.
|
|
1770
|
+
If wizard_ask is unavailable (CI / non-interactive), emit
|
|
1771
|
+
${AgentSignals.ABORT} requires-interactive-mode and halt.
|
|
1772
|
+
|
|
1773
|
+
STEP 2 — Install the skill.
|
|
1774
|
+
Call install_skill (wizard-tools MCP server) with skillId "${skillId}".
|
|
1775
|
+
Do NOT run shell commands to install skills. Then read the installed
|
|
1776
|
+
SKILL.md and its reference files — they drive STEPS 3-8.
|
|
1777
|
+
If install fails, emit ${AgentSignals.ERROR_RESOURCE_MISSING} skill ${skillId} could not be installed.
|
|
1778
|
+
|
|
1779
|
+
STEP 3 — Apply build-config changes. (skill: "Apply build-config changes")
|
|
1780
|
+
Make the bundler / build-config changes the skill's step instructs. The
|
|
1781
|
+
skill and its reference are the source of truth for this platform.
|
|
1782
|
+
|
|
1783
|
+
STEP 4 — Make the credentials readable at build time. (skill: "Make credentials available at build time")
|
|
1784
|
+
Follow the skill's step. Wizard-specific: if it calls for a loader (e.g.
|
|
1785
|
+
\`dotenv\`), install it SILENTLY — do NOT ask the user or call wizard_ask.
|
|
1786
|
+
Skip this step entirely if the platform already auto-loads .env.
|
|
1787
|
+
|
|
1788
|
+
STEP 5 — Write the credentials to the env file. (skill: "Write credentials to the env file")
|
|
1789
|
+
Use the wizard-tools MCP server. Reuse the env file the skill tells you to
|
|
1790
|
+
pick — the prerequisite PostHog integration usually already wrote
|
|
1791
|
+
POSTHOG_* vars to one, so seed your keys alongside them.
|
|
1792
|
+
- First call check_env_keys on that file (returns present/absent, never
|
|
1793
|
+
values — don't read the file directly).
|
|
1794
|
+
- Then call set_env_values, passing the STEP 1 secretRef as a value
|
|
1795
|
+
object, not a literal string:
|
|
1796
|
+
values: {
|
|
1797
|
+
"POSTHOG_CLI_API_KEY": { secretRef: "<the ref from STEP 1>" },
|
|
1798
|
+
"POSTHOG_CLI_PROJECT_ID": "${projectId}",
|
|
1799
|
+
"POSTHOG_CLI_HOST": "${host}"
|
|
1800
|
+
}
|
|
1801
|
+
Variable names follow the skill's per-uploader conventions. The wizard
|
|
1802
|
+
resolves the ref locally before writing, so you never see the key value.
|
|
1803
|
+
|
|
1804
|
+
STEP 6 — Identify the build AND run commands. (skill: "Identify the build and run commands")
|
|
1805
|
+
Per the skill, resolve the production BUILD command and the RUN command
|
|
1806
|
+
for THIS project (use detect_package_manager for the package manager). Do
|
|
1807
|
+
NOT run either yourself — the user runs them. If you cannot identify a
|
|
1808
|
+
build command, emit ${AgentSignals.ABORT} build command not found.
|
|
1809
|
+
|
|
1810
|
+
STEP 7 — Offer to test the local setup. (skill: "Test the local setup")
|
|
1811
|
+
Call wizard_ask:
|
|
1812
|
+
{
|
|
1813
|
+
id: "test-affordance",
|
|
1814
|
+
prompt: "Want me to help you test your local setup? I'll add a temporary test button (or route) to your app so you can confirm errors show up in Error Tracking with readable stack traces after your next build. I'll remove it once you've confirmed it works.",
|
|
1815
|
+
kind: "single",
|
|
1816
|
+
options: [
|
|
1817
|
+
{ label: "Yes, help me test it", value: "yes" },
|
|
1818
|
+
{ label: "No, I'll test on my own later", value: "no" }
|
|
1819
|
+
]
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
If "no", skip to STEP 8.
|
|
1823
|
+
|
|
1824
|
+
If "yes", follow the skill's "Test the local setup" step for the
|
|
1825
|
+
platform-appropriate affordance, the captureException shape, the
|
|
1826
|
+
placement, and the read-before-edit / always-revert rules. Then pause for
|
|
1827
|
+
the user with wizard_ask, baking the EXACT build and run commands from
|
|
1828
|
+
STEP 6 (and the exact button label / route) into the prompt as literal,
|
|
1829
|
+
copy-pasteable steps. Separate each numbered step with \\n\\n so the TUI
|
|
1830
|
+
renders them as distinct lines:
|
|
1831
|
+
{
|
|
1832
|
+
id: "test-done",
|
|
1833
|
+
prompt: "1) Run \`<your detected build command>\` to upload source maps and build the app with the test affordance.\\n\\n2) Start the app with \`<your detected run command>\`, then click the \\"<your test button label>\\" button (or hit \`<your test route>\`).\\n\\n3) Open Error Tracking in PostHog (${uiHost}/project/${projectId}/error_tracking) and confirm the test error appears with a source-resolved stack trace pointing at real source files (not minified bundle paths).\\n\\nWhen you're done, select Continue and I'll revert the test code.",
|
|
1834
|
+
kind: "single",
|
|
1835
|
+
options: [{ label: "Continue (revert test code)", value: "continue" }]
|
|
1836
|
+
}
|
|
1837
|
+
After the user continues, revert the test code per the skill's rules and
|
|
1838
|
+
surface any failure in STEP 8.
|
|
1839
|
+
|
|
1840
|
+
STEP 8 — Summarise and hand off. (skill: "Verify and hand off")
|
|
1841
|
+
Follow the skill's "Verify and hand off" step. The Symbol sets page for
|
|
1842
|
+
this project — where the user confirms the upload landed — is:
|
|
1843
|
+
${uiHost}/project/${projectId}/error_tracking/configuration
|
|
1844
|
+
`;
|
|
1845
|
+
}
|
|
1846
|
+
//#endregion
|
|
1847
|
+
//#region src/lib/programs/error-tracking-upload-source-maps/content/index.tsx
|
|
1848
|
+
/**
|
|
1849
|
+
* Source-maps learn-deck — the narrative played in the run screen's left
|
|
1850
|
+
* pane (LearnCard) while the agent wires source-map upload into the build.
|
|
1851
|
+
*
|
|
1852
|
+
* It educates the user on what source maps are and why uploading them
|
|
1853
|
+
* matters, built around a before/after stack-trace contrast: a minified
|
|
1854
|
+
* production trace nobody can read, then the same trace resolved back to
|
|
1855
|
+
* real source. Program-owned; wired onto the program's getContentBlocks.
|
|
1856
|
+
*
|
|
1857
|
+
* Lines stay narrow (~36 cols) because this renders in the left half of a
|
|
1858
|
+
* split pane — see LearnCard's paneWidth math.
|
|
1859
|
+
*/
|
|
1860
|
+
/**
|
|
1861
|
+
* Per-slide dwell multiplier. Each block stays on screen for `pause * SLIDE_PACE`
|
|
1862
|
+
* ms after it finishes animating, before the deck advances. Bump this single
|
|
1863
|
+
* knob to give every slide more reading time. Clear (page-break) blocks are
|
|
1864
|
+
* left untouched so the blank gap between slides stays snappy.
|
|
1865
|
+
*/
|
|
1866
|
+
const SLIDE_PACE = 1.5;
|
|
1867
|
+
const withPace = (block) => {
|
|
1868
|
+
if (typeof block === "string" || isClearBlock(block) || block.pause == null) return block;
|
|
1869
|
+
return {
|
|
1870
|
+
...block,
|
|
1871
|
+
pause: Math.round(block.pause * SLIDE_PACE)
|
|
1872
|
+
};
|
|
1873
|
+
};
|
|
1874
|
+
/** Apply the dwell multiplier to every block in a deck. */
|
|
1875
|
+
const pace = (blocks) => blocks.map(withPace);
|
|
1876
|
+
/** A minified production stack trace — the problem source maps solve. */
|
|
1877
|
+
const MINIFIED_TRACE = {
|
|
1878
|
+
type: "lines",
|
|
1879
|
+
interval: 400,
|
|
1880
|
+
pause: 7e3,
|
|
1881
|
+
lines: [
|
|
1882
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1883
|
+
color: Colors.error,
|
|
1884
|
+
children: "✘ TypeError: cart is undefined"
|
|
1885
|
+
}),
|
|
1886
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1887
|
+
dimColor: true,
|
|
1888
|
+
children: " at t.min.js:1:48213"
|
|
1889
|
+
}),
|
|
1890
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1891
|
+
dimColor: true,
|
|
1892
|
+
children: " at t.min.js:1:9402"
|
|
1893
|
+
}),
|
|
1894
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1895
|
+
dimColor: true,
|
|
1896
|
+
children: " at t.min.js:1:71150"
|
|
1897
|
+
})
|
|
1898
|
+
]
|
|
1899
|
+
};
|
|
1900
|
+
/** The same trace, resolved through uploaded source maps. */
|
|
1901
|
+
const RESOLVED_TRACE = {
|
|
1902
|
+
type: "lines",
|
|
1903
|
+
interval: 400,
|
|
1904
|
+
pause: 8e3,
|
|
1905
|
+
lines: [
|
|
1906
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1907
|
+
color: Colors.success,
|
|
1908
|
+
children: "✔ TypeError: cart is undefined"
|
|
1909
|
+
}),
|
|
1910
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
1911
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1912
|
+
dimColor: true,
|
|
1913
|
+
children: " at "
|
|
1914
|
+
}),
|
|
1915
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1916
|
+
color: "cyan",
|
|
1917
|
+
children: "Cart.tsx:42"
|
|
1918
|
+
}),
|
|
1919
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1920
|
+
dimColor: true,
|
|
1921
|
+
children: " loadCart"
|
|
1922
|
+
})
|
|
1923
|
+
] }),
|
|
1924
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
1925
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1926
|
+
dimColor: true,
|
|
1927
|
+
children: " at "
|
|
1928
|
+
}),
|
|
1929
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1930
|
+
color: "cyan",
|
|
1931
|
+
children: "App.tsx:88"
|
|
1932
|
+
}),
|
|
1933
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1934
|
+
dimColor: true,
|
|
1935
|
+
children: " render"
|
|
1936
|
+
})
|
|
1937
|
+
] }),
|
|
1938
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
1939
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1940
|
+
dimColor: true,
|
|
1941
|
+
children: " at "
|
|
1942
|
+
}),
|
|
1943
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1944
|
+
color: "cyan",
|
|
1945
|
+
children: "index.tsx:5"
|
|
1946
|
+
}),
|
|
1947
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1948
|
+
dimColor: true,
|
|
1949
|
+
children: " main"
|
|
1950
|
+
})
|
|
1951
|
+
] })
|
|
1952
|
+
]
|
|
1953
|
+
};
|
|
1954
|
+
/**
|
|
1955
|
+
* How a bundle is tied to its map: PostHog injects a chunk-ID marker into the
|
|
1956
|
+
* built JS and stamps the matching source map with the same ID.
|
|
1957
|
+
*/
|
|
1958
|
+
const CHUNK_ID_LINK = {
|
|
1959
|
+
type: "lines",
|
|
1960
|
+
interval: 450,
|
|
1961
|
+
pause: 7500,
|
|
1962
|
+
lines: [
|
|
1963
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1964
|
+
dimColor: true,
|
|
1965
|
+
children: "app.min.js"
|
|
1966
|
+
}),
|
|
1967
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1968
|
+
dimColor: true,
|
|
1969
|
+
children: " …minified code…"
|
|
1970
|
+
}),
|
|
1971
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
1972
|
+
color: "cyan",
|
|
1973
|
+
children: " //# chunkId=a1b2c3d4"
|
|
1974
|
+
}), /* @__PURE__ */ jsx(Text, {
|
|
1975
|
+
dimColor: true,
|
|
1976
|
+
children: " ← injected"
|
|
1977
|
+
})] }),
|
|
1978
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1979
|
+
dimColor: true,
|
|
1980
|
+
children: " ↕ matched by id"
|
|
1981
|
+
}),
|
|
1982
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
1983
|
+
dimColor: true,
|
|
1984
|
+
children: "app.min.js.map"
|
|
1985
|
+
}), /* @__PURE__ */ jsx(Text, {
|
|
1986
|
+
dimColor: true,
|
|
1987
|
+
children: " ← uploaded"
|
|
1988
|
+
})] })
|
|
1989
|
+
]
|
|
1990
|
+
};
|
|
1991
|
+
/** Many similar exceptions collapse into a single issue. */
|
|
1992
|
+
const GROUPING = {
|
|
1993
|
+
type: "lines",
|
|
1994
|
+
interval: 450,
|
|
1995
|
+
pause: 7e3,
|
|
1996
|
+
lines: [
|
|
1997
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1998
|
+
dimColor: true,
|
|
1999
|
+
children: "exception ─┐"
|
|
2000
|
+
}),
|
|
2001
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
2002
|
+
dimColor: true,
|
|
2003
|
+
children: "exception ─┼──→ "
|
|
2004
|
+
}), /* @__PURE__ */ jsx(Text, {
|
|
2005
|
+
color: Colors.accent,
|
|
2006
|
+
bold: true,
|
|
2007
|
+
children: "1 issue"
|
|
2008
|
+
})] }),
|
|
2009
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2010
|
+
dimColor: true,
|
|
2011
|
+
children: "exception ─┘"
|
|
2012
|
+
})
|
|
2013
|
+
]
|
|
2014
|
+
};
|
|
2015
|
+
const getContentBlocks = (store) => pace([
|
|
2016
|
+
{
|
|
2017
|
+
content: "Welcome.",
|
|
2018
|
+
pause: 3e3,
|
|
2019
|
+
mode: 0,
|
|
2020
|
+
animationInterval: 160
|
|
2021
|
+
},
|
|
2022
|
+
{
|
|
2023
|
+
content: "I'm wiring PostHog Error Tracking into your build.",
|
|
2024
|
+
pause: 5e3
|
|
2025
|
+
},
|
|
2026
|
+
{
|
|
2027
|
+
type: "clear",
|
|
2028
|
+
pause: 1500
|
|
2029
|
+
},
|
|
2030
|
+
{
|
|
2031
|
+
content: "When you ship to production, your code gets minified.",
|
|
2032
|
+
pause: 5e3
|
|
2033
|
+
},
|
|
2034
|
+
{
|
|
2035
|
+
content: "Thousands of readable lines collapse into one dense bundle.",
|
|
2036
|
+
pause: 5e3
|
|
2037
|
+
},
|
|
2038
|
+
{
|
|
2039
|
+
content: "So a thrown error gives you a stack trace like this:",
|
|
2040
|
+
pause: 2e3
|
|
2041
|
+
},
|
|
2042
|
+
MINIFIED_TRACE,
|
|
2043
|
+
{
|
|
2044
|
+
content: "Just offsets into a file no human can read.",
|
|
2045
|
+
pause: 5e3
|
|
2046
|
+
},
|
|
2047
|
+
{
|
|
2048
|
+
type: "clear",
|
|
2049
|
+
pause: 1500
|
|
2050
|
+
},
|
|
2051
|
+
{
|
|
2052
|
+
content: "Source maps are the key.",
|
|
2053
|
+
pause: 3500
|
|
2054
|
+
},
|
|
2055
|
+
{
|
|
2056
|
+
content: "They map every position in that bundle back to your original source — the real file, line, and function.",
|
|
2057
|
+
pause: 6e3
|
|
2058
|
+
},
|
|
2059
|
+
{
|
|
2060
|
+
content: "Right now I'm hooking source-map generation and upload into your build, tied to each release you ship.",
|
|
2061
|
+
pause: 6e3
|
|
2062
|
+
},
|
|
2063
|
+
{
|
|
2064
|
+
type: "clear",
|
|
2065
|
+
pause: 1500
|
|
2066
|
+
},
|
|
2067
|
+
{
|
|
2068
|
+
content: "But how does PostHog know which map belongs to which build?",
|
|
2069
|
+
pause: 4500
|
|
2070
|
+
},
|
|
2071
|
+
{
|
|
2072
|
+
content: "During the build, it injects a unique chunk ID into each bundle:",
|
|
2073
|
+
pause: 2500
|
|
2074
|
+
},
|
|
2075
|
+
CHUNK_ID_LINK,
|
|
2076
|
+
{
|
|
2077
|
+
content: "The matching source map is stamped with that same ID before it ships to PostHog.",
|
|
2078
|
+
pause: 6e3
|
|
2079
|
+
},
|
|
2080
|
+
{
|
|
2081
|
+
content: "When an error comes in, PostHog reads the chunk ID off the bundle, finds the map with the exact same ID, and uses it to map each frame back to your source — even for a release you shipped weeks ago.",
|
|
2082
|
+
pause: 8e3
|
|
2083
|
+
},
|
|
2084
|
+
{
|
|
2085
|
+
type: "clear",
|
|
2086
|
+
pause: 1500
|
|
2087
|
+
},
|
|
2088
|
+
{
|
|
2089
|
+
content: "So that same error becomes:",
|
|
2090
|
+
pause: 2e3
|
|
2091
|
+
},
|
|
2092
|
+
RESOLVED_TRACE,
|
|
2093
|
+
{
|
|
2094
|
+
content: "Readable stack traces, straight from production.",
|
|
2095
|
+
pause: 5e3
|
|
2096
|
+
},
|
|
2097
|
+
{
|
|
2098
|
+
content: "You debug a live error like it happened on your own machine.",
|
|
2099
|
+
pause: 6e3
|
|
2100
|
+
},
|
|
2101
|
+
{
|
|
2102
|
+
type: "clear",
|
|
2103
|
+
pause: 1500
|
|
2104
|
+
},
|
|
2105
|
+
{
|
|
2106
|
+
content: "Zooming out — this is how Error Tracking works.",
|
|
2107
|
+
pause: 4e3
|
|
2108
|
+
},
|
|
2109
|
+
{
|
|
2110
|
+
content: "Every error your app throws is captured as an exception.",
|
|
2111
|
+
pause: 5e3
|
|
2112
|
+
},
|
|
2113
|
+
{
|
|
2114
|
+
content: "PostHog groups similar exceptions into a single issue:",
|
|
2115
|
+
pause: 2500
|
|
2116
|
+
},
|
|
2117
|
+
GROUPING,
|
|
2118
|
+
{
|
|
2119
|
+
content: "So a bug that fires ten thousand times is one issue to triage — not ten thousand alerts.",
|
|
2120
|
+
pause: 6500
|
|
2121
|
+
},
|
|
2122
|
+
{
|
|
2123
|
+
type: "clear",
|
|
2124
|
+
pause: 1500
|
|
2125
|
+
},
|
|
2126
|
+
{
|
|
2127
|
+
content: "And this is where source maps earn their keep again.",
|
|
2128
|
+
pause: 4500
|
|
2129
|
+
},
|
|
2130
|
+
{
|
|
2131
|
+
content: "Grouping reads the stack trace. Minified frames all look alike — so unrelated crashes get merged, and one real bug scatters across many issues.",
|
|
2132
|
+
pause: 8e3
|
|
2133
|
+
},
|
|
2134
|
+
{
|
|
2135
|
+
content: "With source maps, PostHog groups on your real frames — so each distinct bug lands as one clean issue.",
|
|
2136
|
+
pause: 7e3
|
|
2137
|
+
},
|
|
2138
|
+
{
|
|
2139
|
+
type: "clear",
|
|
2140
|
+
pause: 1500
|
|
2141
|
+
},
|
|
2142
|
+
{
|
|
2143
|
+
pause: 5e3,
|
|
2144
|
+
persist: true,
|
|
2145
|
+
content: /* @__PURE__ */ jsx(StatusPeekTrigger, { store })
|
|
2146
|
+
},
|
|
2147
|
+
{
|
|
2148
|
+
pause: 9e4,
|
|
2149
|
+
content: /* @__PURE__ */ jsxs(Text, { children: [
|
|
2150
|
+
"Press",
|
|
2151
|
+
" ",
|
|
2152
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2153
|
+
color: Colors.accent,
|
|
2154
|
+
bold: true,
|
|
2155
|
+
children: "S"
|
|
2156
|
+
}),
|
|
2157
|
+
" ",
|
|
2158
|
+
"to follow along — or sit tight, I'll let you know when it's done."
|
|
2159
|
+
] })
|
|
2160
|
+
}
|
|
2161
|
+
]);
|
|
2162
|
+
//#endregion
|
|
2163
|
+
//#region src/lib/programs/error-tracking-upload-source-maps/index.ts
|
|
2164
|
+
const REPORT_FILE = "posthog-source-maps-report.md";
|
|
2165
|
+
const DOCS_URL = "https://posthog.com/docs/error-tracking/upload-source-maps";
|
|
2166
|
+
const errorTrackingUploadSourceMapsConfig = {
|
|
2167
|
+
command: "upload-source-maps",
|
|
2168
|
+
description: "Upload source maps to PostHog Error Tracking",
|
|
2169
|
+
id: "error-tracking-upload-source-maps",
|
|
2170
|
+
steps: ERROR_TRACKING_UPLOAD_SOURCE_MAPS_PROGRAM,
|
|
2171
|
+
reportFile: REPORT_FILE,
|
|
2172
|
+
getContentBlocks,
|
|
2173
|
+
requires: ["posthog-integration"],
|
|
2174
|
+
run: (session) => {
|
|
2175
|
+
const variant = session.frameworkContext[SOURCE_MAPS_CONTEXT_KEYS.skillVariant];
|
|
2176
|
+
const displayName = session.frameworkContext[SOURCE_MAPS_CONTEXT_KEYS.displayName];
|
|
2177
|
+
const skillId = variant ? `error-tracking-upload-source-maps-${variant}` : void 0;
|
|
2178
|
+
return Promise.resolve({
|
|
2179
|
+
integrationLabel: "error-tracking-upload-source-maps",
|
|
2180
|
+
successMessage: "Source maps wired up!",
|
|
2181
|
+
reportFile: REPORT_FILE,
|
|
2182
|
+
docsUrl: DOCS_URL,
|
|
2183
|
+
spinnerMessage: "Wiring up source maps...",
|
|
2184
|
+
estimatedDurationMinutes: 3,
|
|
2185
|
+
abortCases: SOURCE_MAPS_ABORT_CASES,
|
|
2186
|
+
customPrompt: (ctx) => {
|
|
2187
|
+
if (!skillId || !variant) return SOURCE_MAPS_DETECTION_FAILED_PROMPT;
|
|
2188
|
+
const uiHost = getUiHostFromHost(ctx.host).replace(/\/$/, "");
|
|
2189
|
+
return buildSourceMapsUploadPrompt({
|
|
2190
|
+
displayName,
|
|
2191
|
+
variant,
|
|
2192
|
+
skillId,
|
|
2193
|
+
projectId: ctx.projectId,
|
|
2194
|
+
host: ctx.host,
|
|
2195
|
+
settingsUrl: `${uiHost}/project/${ctx.projectId}/settings/user-api-keys`,
|
|
2196
|
+
uiHost
|
|
2197
|
+
});
|
|
2198
|
+
},
|
|
2199
|
+
postRun: (sess) => {
|
|
2200
|
+
if (variant) sess.frameworkContext["sourceMapsCompletedVariant"] = variant;
|
|
2201
|
+
return Promise.resolve();
|
|
2202
|
+
},
|
|
2203
|
+
buildOutroData: () => {
|
|
2204
|
+
return {
|
|
2205
|
+
kind: "success",
|
|
2206
|
+
message: "Source maps wired up!",
|
|
2207
|
+
reportFile: REPORT_FILE,
|
|
2208
|
+
docsUrl: DOCS_URL
|
|
2209
|
+
};
|
|
2210
|
+
}
|
|
2211
|
+
});
|
|
2212
|
+
}
|
|
2213
|
+
};
|
|
2214
|
+
//#endregion
|
|
1467
2215
|
//#region src/lib/programs/mcp/index.ts
|
|
1468
2216
|
const mcpAddConfig = {
|
|
1469
2217
|
id: "mcp-add",
|
|
@@ -1473,8 +2221,28 @@ const mcpAddConfig = {
|
|
|
1473
2221
|
label: "Add MCP server",
|
|
1474
2222
|
screenId: "mcp-add",
|
|
1475
2223
|
isComplete: (s) => s.mcpComplete
|
|
2224
|
+
}, {
|
|
2225
|
+
id: "mcp-suggested-prompts",
|
|
2226
|
+
label: "Suggested prompts",
|
|
2227
|
+
screenId: "mcp-suggested-prompts",
|
|
2228
|
+
show: (s) => s.mcpOutcome === "installed",
|
|
2229
|
+
isComplete: (s) => s.mcpSuggestedPromptsDismissed
|
|
1476
2230
|
}]
|
|
1477
2231
|
};
|
|
2232
|
+
/**
|
|
2233
|
+
* `wizard mcp remove` — single-step uninstall flow.
|
|
2234
|
+
*
|
|
2235
|
+
* DO NOT append `mcp-suggested-prompts` (or any other tutorial-shaped
|
|
2236
|
+
* step) here. A user who just removed MCP is opting OUT of the agent
|
|
2237
|
+
* having access to PostHog; immediately pivoting into a tutorial that
|
|
2238
|
+
* asks them to log in and try prompts is wrong on intent and confusing
|
|
2239
|
+
* on UX. The screen also reads `session.mcpInstalledClients` for its
|
|
2240
|
+
* Choose-phase copy ("MCP is installed for X") — that array is empty
|
|
2241
|
+
* post-remove, so the copy would be a lie.
|
|
2242
|
+
*
|
|
2243
|
+
* If you want a "did you mean to keep it?" confirmation, build that as
|
|
2244
|
+
* a screen earlier in this program — don't reuse the tutorial.
|
|
2245
|
+
*/
|
|
1478
2246
|
const mcpRemoveConfig = {
|
|
1479
2247
|
id: "mcp-remove",
|
|
1480
2248
|
description: "Remove PostHog MCP server from supported clients",
|
|
@@ -1485,18 +2253,39 @@ const mcpRemoveConfig = {
|
|
|
1485
2253
|
isComplete: (s) => s.mcpComplete
|
|
1486
2254
|
}]
|
|
1487
2255
|
};
|
|
2256
|
+
/**
|
|
2257
|
+
* Standalone tutorial flow — boots directly into the Choose phase of
|
|
2258
|
+
* McpSuggestedPromptsScreen without going through MCP install first.
|
|
2259
|
+
* Useful for users who already installed MCP and want to revisit the
|
|
2260
|
+
* tutorial, or anyone who just wants to try the agent against PostHog
|
|
2261
|
+
* without touching their IDE config.
|
|
2262
|
+
*
|
|
2263
|
+
* The screen handles its own OAuth (via services.performLogin) so this
|
|
2264
|
+
* program doesn't pre-populate credentials.
|
|
2265
|
+
*/
|
|
2266
|
+
const mcpTutorialConfig = {
|
|
2267
|
+
id: "mcp-tutorial",
|
|
2268
|
+
description: "Try the PostHog MCP with your agent — no install needed",
|
|
2269
|
+
steps: [{
|
|
2270
|
+
id: "mcp-suggested-prompts",
|
|
2271
|
+
label: "MCP tutorial",
|
|
2272
|
+
screenId: "mcp-suggested-prompts",
|
|
2273
|
+
isComplete: (s) => s.mcpSuggestedPromptsDismissed
|
|
2274
|
+
}]
|
|
2275
|
+
};
|
|
1488
2276
|
//#endregion
|
|
1489
2277
|
//#region src/lib/programs/program-registry.ts
|
|
1490
2278
|
const agentSkillConfig = {
|
|
1491
2279
|
id: "agent-skill",
|
|
1492
2280
|
description: "Run an arbitrary context-mill skill",
|
|
1493
2281
|
steps: AGENT_SKILL_STEPS,
|
|
1494
|
-
getContentBlocks: getContentBlocks$
|
|
2282
|
+
getContentBlocks: getContentBlocks$2,
|
|
1495
2283
|
allowedTools: ["Agent"]
|
|
1496
2284
|
};
|
|
1497
2285
|
const PROGRAM_REGISTRY = [
|
|
1498
2286
|
posthogIntegrationConfig,
|
|
1499
2287
|
revenueAnalyticsConfig,
|
|
2288
|
+
errorTrackingUploadSourceMapsConfig,
|
|
1500
2289
|
auditConfig,
|
|
1501
2290
|
eventsAuditConfig,
|
|
1502
2291
|
audit3000Config,
|
|
@@ -1504,7 +2293,8 @@ const PROGRAM_REGISTRY = [
|
|
|
1504
2293
|
migrationConfig,
|
|
1505
2294
|
agentSkillConfig,
|
|
1506
2295
|
mcpAddConfig,
|
|
1507
|
-
mcpRemoveConfig
|
|
2296
|
+
mcpRemoveConfig,
|
|
2297
|
+
mcpTutorialConfig
|
|
1508
2298
|
];
|
|
1509
2299
|
/**
|
|
1510
2300
|
* Typed program names. Values come from each config's `id`, so there's
|
|
@@ -1514,6 +2304,7 @@ const PROGRAM_REGISTRY = [
|
|
|
1514
2304
|
const Program = {
|
|
1515
2305
|
PostHogIntegration: posthogIntegrationConfig.id,
|
|
1516
2306
|
RevenueAnalyticsSetup: revenueAnalyticsConfig.id,
|
|
2307
|
+
ErrorTrackingUploadSourceMaps: errorTrackingUploadSourceMapsConfig.id,
|
|
1517
2308
|
Migration: migrationConfig.id,
|
|
1518
2309
|
Audit: auditConfig.id,
|
|
1519
2310
|
EventsAudit: eventsAuditConfig.id,
|
|
@@ -1521,7 +2312,8 @@ const Program = {
|
|
|
1521
2312
|
PosthogDoctor: posthogDoctorConfig.id,
|
|
1522
2313
|
AgentSkill: agentSkillConfig.id,
|
|
1523
2314
|
McpAdd: mcpAddConfig.id,
|
|
1524
|
-
McpRemove: mcpRemoveConfig.id
|
|
2315
|
+
McpRemove: mcpRemoveConfig.id,
|
|
2316
|
+
McpTutorial: mcpTutorialConfig.id
|
|
1525
2317
|
};
|
|
1526
2318
|
/**
|
|
1527
2319
|
* Look up a program config by its id. `ProgramId` is a union of every
|
|
@@ -1537,12 +2329,12 @@ function getSubcommandPrograms() {
|
|
|
1537
2329
|
}
|
|
1538
2330
|
//#endregion
|
|
1539
2331
|
//#region bin.ts
|
|
1540
|
-
const
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
console.log(`PostHog wizard requires Node.js ${NODE_VERSION_RANGE}. You are using Node.js ${process.version}. Please upgrade your Node.js version.`);
|
|
2332
|
+
const MIN_NODE_VERSION = ">=18.17.0";
|
|
2333
|
+
if (!satisfies(process.version, MIN_NODE_VERSION)) {
|
|
2334
|
+
console.log(`PostHog wizard needs Node.js ${MIN_NODE_VERSION}. Detected ${process.version} — please upgrade Node and re-run.`);
|
|
1544
2335
|
process.exit(1);
|
|
1545
2336
|
}
|
|
2337
|
+
const WIZARD_VERSION = VERSION;
|
|
1546
2338
|
/** Shared yargs options for skill-based program subcommands. */
|
|
1547
2339
|
const skillSubcommandOptions = {
|
|
1548
2340
|
debug: {
|
|
@@ -1597,11 +2389,6 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1597
2389
|
describe: "Use local MCP server at http://localhost:8787/mcp\nenv: POSTHOG_WIZARD_LOCAL_MCP",
|
|
1598
2390
|
type: "boolean"
|
|
1599
2391
|
},
|
|
1600
|
-
ci: {
|
|
1601
|
-
default: false,
|
|
1602
|
-
describe: "Enable CI mode for non-interactive execution\nenv: POSTHOG_WIZARD_CI",
|
|
1603
|
-
type: "boolean"
|
|
1604
|
-
},
|
|
1605
2392
|
"api-key": {
|
|
1606
2393
|
describe: "PostHog personal API key (phx_xxx) for authentication\nenv: POSTHOG_WIZARD_API_KEY",
|
|
1607
2394
|
type: "string"
|
|
@@ -1613,6 +2400,11 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1613
2400
|
email: {
|
|
1614
2401
|
describe: "Email address for signup (used with --signup)\nenv: POSTHOG_WIZARD_EMAIL",
|
|
1615
2402
|
type: "string"
|
|
2403
|
+
},
|
|
2404
|
+
telemetry: {
|
|
2405
|
+
default: true,
|
|
2406
|
+
describe: "Send wizard run state to PostHog (pass --no-telemetry to disable)\nenv: POSTHOG_WIZARD_TELEMETRY",
|
|
2407
|
+
type: "boolean"
|
|
1616
2408
|
}
|
|
1617
2409
|
}).command(["$0"], "Run the PostHog setup wizard", (yargs) => {
|
|
1618
2410
|
return yargs.options({
|
|
@@ -1710,7 +2502,7 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1710
2502
|
setUI(new LoggingUI());
|
|
1711
2503
|
getUI().intro("PostHog Wizard");
|
|
1712
2504
|
try {
|
|
1713
|
-
const { provisionNewAccount } = await import("./provisioning-
|
|
2505
|
+
const { provisionNewAccount } = await import("./provisioning-Ch6i8dRV.js");
|
|
1714
2506
|
const signupRegion = options.region.toUpperCase();
|
|
1715
2507
|
getUI().log.info(`Provisioning new PostHog account for ${String(options.email)} in ${signupRegion}...`);
|
|
1716
2508
|
const result = await provisionNewAccount(options.email, options.name ?? "", signupRegion);
|
|
@@ -1732,11 +2524,11 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1732
2524
|
return;
|
|
1733
2525
|
}
|
|
1734
2526
|
}
|
|
1735
|
-
const { posthogIntegrationConfig } = await import("./posthog-integration-
|
|
1736
|
-
const { FRAMEWORK_REGISTRY } = await import("./registry-
|
|
1737
|
-
const { detectFramework, gatherFrameworkContext } = await import("./detection-
|
|
1738
|
-
const { analytics } = await import("./analytics-
|
|
1739
|
-
const { wizardAbort } = await import("./wizard-abort-
|
|
2527
|
+
const { posthogIntegrationConfig } = await import("./posthog-integration-CukaeYil.js").then((n) => n.r);
|
|
2528
|
+
const { FRAMEWORK_REGISTRY } = await import("./registry-DqbwO5EL.js").then((n) => n.n);
|
|
2529
|
+
const { detectFramework, gatherFrameworkContext } = await import("./detection-4eukp9HD.js").then((n) => n.t);
|
|
2530
|
+
const { analytics } = await import("./analytics-DqeW7XYt.js");
|
|
2531
|
+
const { wizardAbort } = await import("./wizard-abort-BlYGA1Jk.js");
|
|
1740
2532
|
runWizardCI(posthogIntegrationConfig, options, async (session) => {
|
|
1741
2533
|
const integration = session.integration ?? await detectFramework(session.installDir);
|
|
1742
2534
|
if (!integration) {
|
|
@@ -1766,10 +2558,10 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1766
2558
|
});
|
|
1767
2559
|
} else if (isNonInteractiveEnvironment()) {
|
|
1768
2560
|
getUI().intro(`PostHog Wizard`);
|
|
1769
|
-
getUI().log.error("This installer requires an interactive terminal (TTY) to run.\nIt appears you are running in a non-interactive environment.\
|
|
2561
|
+
getUI().log.error("This installer requires an interactive terminal (TTY) to run.\nIt appears you are running in a non-interactive environment.\n\nNon-interactive (CI) mode is not supported in published builds.\n");
|
|
1770
2562
|
process.exit(1);
|
|
1771
2563
|
} else if (options.playground) (async () => {
|
|
1772
|
-
const { startPlayground } = await import("./start-playground-
|
|
2564
|
+
const { startPlayground } = await import("./start-playground-B40O4tye.js");
|
|
1773
2565
|
startPlayground(WIZARD_VERSION);
|
|
1774
2566
|
})();
|
|
1775
2567
|
else if (options.skill) (async () => {
|
|
@@ -1792,7 +2584,7 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1792
2584
|
});
|
|
1793
2585
|
})();
|
|
1794
2586
|
else (async () => {
|
|
1795
|
-
const { posthogIntegrationConfig } = await import("./posthog-integration-
|
|
2587
|
+
const { posthogIntegrationConfig } = await import("./posthog-integration-CukaeYil.js").then((n) => n.r);
|
|
1796
2588
|
runWizard(posthogIntegrationConfig, options);
|
|
1797
2589
|
})();
|
|
1798
2590
|
}).command("mcp <command>", "MCP server management commands", (yargs) => {
|
|
@@ -1816,11 +2608,11 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1816
2608
|
const options = { ...argv };
|
|
1817
2609
|
const mcpFeatures = options.features?.split(",").map((s) => s.trim()).filter(Boolean);
|
|
1818
2610
|
(async () => {
|
|
1819
|
-
const { readApiKeyFromEnv } = await import("./env-api-key-
|
|
2611
|
+
const { readApiKeyFromEnv } = await import("./env-api-key-DU8uIEvo.js");
|
|
1820
2612
|
const apiKey = options.apiKey || readApiKeyFromEnv();
|
|
1821
2613
|
try {
|
|
1822
|
-
const { startTUI } = await import("./start-tui-
|
|
1823
|
-
const { buildSession } = await import("./wizard-session-
|
|
2614
|
+
const { startTUI } = await import("./start-tui-CH_ZzQXx.js");
|
|
2615
|
+
const { buildSession } = await import("./wizard-session-DPGTaJ4W.js");
|
|
1824
2616
|
const tui = startTUI(WIZARD_VERSION, Program.McpAdd);
|
|
1825
2617
|
const session = buildSession({
|
|
1826
2618
|
debug: options.debug,
|
|
@@ -1831,7 +2623,7 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1831
2623
|
tui.store.session = session;
|
|
1832
2624
|
} catch {
|
|
1833
2625
|
setUI(new LoggingUI());
|
|
1834
|
-
const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-
|
|
2626
|
+
const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-9jQjc-CO.js").then((n) => n.r);
|
|
1835
2627
|
await addMCPServerToClientsStep({
|
|
1836
2628
|
local: options.local,
|
|
1837
2629
|
features: mcpFeatures,
|
|
@@ -1849,8 +2641,8 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1849
2641
|
const options = { ...argv };
|
|
1850
2642
|
(async () => {
|
|
1851
2643
|
try {
|
|
1852
|
-
const { startTUI } = await import("./start-tui-
|
|
1853
|
-
const { buildSession } = await import("./wizard-session-
|
|
2644
|
+
const { startTUI } = await import("./start-tui-CH_ZzQXx.js");
|
|
2645
|
+
const { buildSession } = await import("./wizard-session-DPGTaJ4W.js");
|
|
1854
2646
|
const tui = startTUI(WIZARD_VERSION, Program.McpRemove);
|
|
1855
2647
|
const session = buildSession({
|
|
1856
2648
|
debug: options.debug,
|
|
@@ -1859,11 +2651,35 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1859
2651
|
tui.store.session = session;
|
|
1860
2652
|
} catch {
|
|
1861
2653
|
setUI(new LoggingUI());
|
|
1862
|
-
const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-
|
|
2654
|
+
const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-9jQjc-CO.js").then((n) => n.r);
|
|
1863
2655
|
await removeMCPServerFromClientsStep({ local: options.local });
|
|
1864
2656
|
}
|
|
1865
2657
|
})();
|
|
1866
|
-
}).
|
|
2658
|
+
}).command("tutorial", "Try the PostHog MCP with your agent (no install needed)", (yargs) => {
|
|
2659
|
+
return yargs.options({ local: {
|
|
2660
|
+
default: false,
|
|
2661
|
+
describe: "Point the tutorial at the local MCP server (http://localhost:8787)",
|
|
2662
|
+
type: "boolean"
|
|
2663
|
+
} });
|
|
2664
|
+
}, (argv) => {
|
|
2665
|
+
const options = { ...argv };
|
|
2666
|
+
(async () => {
|
|
2667
|
+
try {
|
|
2668
|
+
const { startTUI } = await import("./start-tui-CH_ZzQXx.js");
|
|
2669
|
+
const { buildSession } = await import("./wizard-session-DPGTaJ4W.js");
|
|
2670
|
+
const tui = startTUI(WIZARD_VERSION, Program.McpTutorial);
|
|
2671
|
+
const session = buildSession({
|
|
2672
|
+
debug: options.debug,
|
|
2673
|
+
localMcp: options.local
|
|
2674
|
+
});
|
|
2675
|
+
tui.store.session = session;
|
|
2676
|
+
} catch (err) {
|
|
2677
|
+
setUI(new LoggingUI());
|
|
2678
|
+
getUI().log.error(`The MCP tutorial requires an interactive terminal. ${err instanceof Error ? err.message : String(err)}`);
|
|
2679
|
+
process.exit(1);
|
|
2680
|
+
}
|
|
2681
|
+
})();
|
|
2682
|
+
}).demandCommand(1, "You must specify a subcommand (add, remove, or tutorial)").help();
|
|
1867
2683
|
});
|
|
1868
2684
|
cli.command("provision", "Create a new PostHog account (headless, no TUI)", (yargs) => {
|
|
1869
2685
|
return yargs.options({
|
|
@@ -1895,7 +2711,7 @@ cli.command("provision", "Create a new PostHog account (headless, no TUI)", (yar
|
|
|
1895
2711
|
if (!jsonMode) setUI(new LoggingUI());
|
|
1896
2712
|
(async () => {
|
|
1897
2713
|
try {
|
|
1898
|
-
const { provisionNewAccount } = await import("./provisioning-
|
|
2714
|
+
const { provisionNewAccount } = await import("./provisioning-Ch6i8dRV.js");
|
|
1899
2715
|
if (!jsonMode) getUI().log.info(`Provisioning account for ${email} in ${region}...`);
|
|
1900
2716
|
const result = await provisionNewAccount(email, name, region);
|
|
1901
2717
|
if (jsonMode) process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
@@ -1934,23 +2750,56 @@ for (const programConfig of getSubcommandPrograms()) cli.command(programConfig.c
|
|
|
1934
2750
|
if (options.ci) runWizardCI(programConfig, options);
|
|
1935
2751
|
else runWizard(programConfig, options);
|
|
1936
2752
|
});
|
|
1937
|
-
cli.
|
|
2753
|
+
cli.strictOptions().fail((msg, err) => {
|
|
2754
|
+
throw err || new Error(msg);
|
|
2755
|
+
}).help().alias("help", "h").version().alias("version", "v").wrap(process.stdout.isTTY ? cli.terminalWidth() : 80);
|
|
2756
|
+
{
|
|
2757
|
+
const argvHasCI = process.argv.slice(2).some((a) => a === "--ci" || a === "--no-ci" || a.startsWith("--ci="));
|
|
2758
|
+
const envHasCI = process.env.POSTHOG_WIZARD_CI != null && process.env.POSTHOG_WIZARD_CI !== "";
|
|
2759
|
+
if (argvHasCI || envHasCI) exitWithProductionCIError();
|
|
2760
|
+
}
|
|
2761
|
+
try {
|
|
2762
|
+
cli.parse();
|
|
2763
|
+
} catch (err) {
|
|
2764
|
+
const RED = "\x1B[31m";
|
|
2765
|
+
const BOLD = "\x1B[1m";
|
|
2766
|
+
const RESET = "\x1B[0m";
|
|
2767
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2768
|
+
process.stderr.write(`${RED}${BOLD}✖ ${message}${RESET}\n`);
|
|
2769
|
+
process.stderr.write("Run with --help to see available options.\n");
|
|
2770
|
+
process.exit(1);
|
|
2771
|
+
}
|
|
2772
|
+
function exitWithProductionCIError() {
|
|
2773
|
+
process.stderr.write(`[31m[1m✖ CI mode is not currently supported in published builds.[0m\n`);
|
|
2774
|
+
process.exit(1);
|
|
2775
|
+
}
|
|
2776
|
+
function resolveNoTelemetry(options) {
|
|
2777
|
+
if (options.telemetry === false) return true;
|
|
2778
|
+
const env = process.env.POSTHOG_WIZARD_NO_TELEMETRY;
|
|
2779
|
+
if (env == null || env === "") return false;
|
|
2780
|
+
const norm = env.toLowerCase();
|
|
2781
|
+
return norm !== "0" && norm !== "false";
|
|
2782
|
+
}
|
|
1938
2783
|
/**
|
|
1939
2784
|
* Run a full wizard program in the TUI. Handles the full lifecycle: start TUI,
|
|
1940
2785
|
* build session, run detection, wait for intro gate, execute the
|
|
1941
2786
|
* agent pipeline, wait for outro dismissal, then exit.
|
|
1942
2787
|
*/
|
|
1943
2788
|
function runWizard(config, options) {
|
|
2789
|
+
let tui = null;
|
|
2790
|
+
let taskStream = null;
|
|
2791
|
+
let onSignal = null;
|
|
2792
|
+
let exitInProgress = false;
|
|
1944
2793
|
(async () => {
|
|
1945
2794
|
try {
|
|
1946
2795
|
const installDir = options.installDir || process.cwd();
|
|
1947
|
-
const { startTUI } = await import("./start-tui-
|
|
1948
|
-
const { buildSession } = await import("./wizard-session-
|
|
1949
|
-
const { TaskStreamPush } = await import("./task-stream-
|
|
1950
|
-
const {
|
|
1951
|
-
const {
|
|
1952
|
-
|
|
1953
|
-
const
|
|
2796
|
+
const { startTUI } = await import("./start-tui-CH_ZzQXx.js");
|
|
2797
|
+
const { buildSession, RunPhase } = await import("./wizard-session-DPGTaJ4W.js");
|
|
2798
|
+
const { TaskStreamPush } = await import("./task-stream-CoEsidgG.js");
|
|
2799
|
+
const { PostHogDestination } = await import("./posthog-7B92c2Ed.js");
|
|
2800
|
+
const { logToFile } = await import("./debug-B6rX6xye.js");
|
|
2801
|
+
tui = startTUI(WIZARD_VERSION, config.id);
|
|
2802
|
+
const activeTui = tui;
|
|
1954
2803
|
const session = buildSession({
|
|
1955
2804
|
debug: options.debug,
|
|
1956
2805
|
forceInstall: options.forceInstall,
|
|
@@ -1964,43 +2813,64 @@ function runWizard(config, options) {
|
|
|
1964
2813
|
menu: options.menu,
|
|
1965
2814
|
integration: options.integration,
|
|
1966
2815
|
benchmark: options.benchmark,
|
|
1967
|
-
yaraReport: options.yaraReport
|
|
2816
|
+
yaraReport: options.yaraReport,
|
|
2817
|
+
noTelemetry: resolveNoTelemetry(options)
|
|
1968
2818
|
});
|
|
1969
2819
|
session.programLabel = config.id;
|
|
1970
2820
|
if (options.skillId) session.skillId = options.skillId;
|
|
1971
2821
|
else if (config.skillId) session.skillId = config.skillId;
|
|
1972
|
-
|
|
1973
|
-
const
|
|
1974
|
-
|
|
2822
|
+
activeTui.store.session = session;
|
|
2823
|
+
const taskStreamEnabled = !session.noTelemetry;
|
|
2824
|
+
taskStream = new TaskStreamPush({
|
|
2825
|
+
store: activeTui.store,
|
|
1975
2826
|
programId: config.id,
|
|
1976
|
-
destinations: [new
|
|
2827
|
+
destinations: [new PostHogDestination({
|
|
2828
|
+
getCredentials: () => activeTui.store.session.credentials,
|
|
2829
|
+
onError: (err) => logToFile("[task-stream-push]", err.message)
|
|
2830
|
+
})],
|
|
2831
|
+
enabled: taskStreamEnabled
|
|
1977
2832
|
});
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
2833
|
+
const activeStream = taskStream;
|
|
2834
|
+
activeStream.attach();
|
|
2835
|
+
let signalled = false;
|
|
2836
|
+
onSignal = () => {
|
|
2837
|
+
if (signalled || exitInProgress) return;
|
|
2838
|
+
signalled = true;
|
|
2839
|
+
if (activeTui.store.session.runPhase === RunPhase.Running) activeTui.store.setRunPhase(RunPhase.Error);
|
|
2840
|
+
activeStream.shutdown(2e3).finally(() => {
|
|
2841
|
+
try {
|
|
2842
|
+
activeTui.unmount();
|
|
2843
|
+
} catch {}
|
|
2844
|
+
process.exit(130);
|
|
2845
|
+
});
|
|
2846
|
+
};
|
|
2847
|
+
process.on("SIGINT", onSignal);
|
|
2848
|
+
process.on("SIGTERM", onSignal);
|
|
2849
|
+
await activeTui.store.runReadyHooks();
|
|
2850
|
+
await activeTui.store.getGate("intro");
|
|
2851
|
+
await activeTui.store.getGate("health-check");
|
|
1982
2852
|
const skipAgent = config.run == null;
|
|
1983
2853
|
if (skipAgent) {
|
|
1984
|
-
const { getOrAskForProjectData } = await import("./setup-utils-
|
|
2854
|
+
const { getOrAskForProjectData } = await import("./setup-utils-C5uZ9g60.js");
|
|
1985
2855
|
const { projectApiKey, host, accessToken, projectId } = await getOrAskForProjectData({
|
|
1986
2856
|
signup: session.signup,
|
|
1987
2857
|
ci: session.ci,
|
|
1988
2858
|
apiKey: session.apiKey,
|
|
1989
2859
|
projectId: session.projectId
|
|
1990
2860
|
});
|
|
1991
|
-
|
|
2861
|
+
activeTui.store.setCredentials({
|
|
1992
2862
|
accessToken,
|
|
1993
2863
|
projectApiKey,
|
|
1994
2864
|
host,
|
|
1995
2865
|
projectId
|
|
1996
2866
|
});
|
|
1997
2867
|
} else {
|
|
1998
|
-
const { runAgent } = await import("./agent-runner-
|
|
1999
|
-
await runAgent(config,
|
|
2868
|
+
const { runAgent } = await import("./agent-runner-H1FP6XTc.js");
|
|
2869
|
+
await runAgent(config, activeTui.store.session);
|
|
2000
2870
|
}
|
|
2001
|
-
const isDone = () => skipAgent ?
|
|
2871
|
+
const isDone = () => skipAgent ? activeTui.store.session.outroDismissed : activeTui.store.session.skillsComplete;
|
|
2002
2872
|
await new Promise((resolve) => {
|
|
2003
|
-
const unsub =
|
|
2873
|
+
const unsub = activeTui.store.subscribe(() => {
|
|
2004
2874
|
if (isDone()) {
|
|
2005
2875
|
unsub();
|
|
2006
2876
|
resolve();
|
|
@@ -2011,15 +2881,26 @@ function runWizard(config, options) {
|
|
|
2011
2881
|
resolve();
|
|
2012
2882
|
}
|
|
2013
2883
|
});
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
tui.unmount();
|
|
2884
|
+
exitInProgress = true;
|
|
2885
|
+
await activeStream.shutdown(2e3);
|
|
2886
|
+
process.off("SIGINT", onSignal);
|
|
2887
|
+
process.off("SIGTERM", onSignal);
|
|
2888
|
+
activeTui.unmount();
|
|
2020
2889
|
process.exit(0);
|
|
2021
2890
|
} catch (err) {
|
|
2022
2891
|
if (runtimeEnv("DEBUG") || runtimeEnv("POSTHOG_WIZARD_DEBUG")) console.error("TUI init failed:", err);
|
|
2892
|
+
exitInProgress = true;
|
|
2893
|
+
if (onSignal) {
|
|
2894
|
+
process.off("SIGINT", onSignal);
|
|
2895
|
+
process.off("SIGTERM", onSignal);
|
|
2896
|
+
}
|
|
2897
|
+
if (taskStream) try {
|
|
2898
|
+
await taskStream.shutdown(2e3);
|
|
2899
|
+
} catch {}
|
|
2900
|
+
if (tui) try {
|
|
2901
|
+
tui.unmount();
|
|
2902
|
+
} catch {}
|
|
2903
|
+
process.exit(1);
|
|
2023
2904
|
}
|
|
2024
2905
|
})();
|
|
2025
2906
|
}
|
|
@@ -2046,11 +2927,11 @@ function runWizardCI(config, options, preRun) {
|
|
|
2046
2927
|
}
|
|
2047
2928
|
(async () => {
|
|
2048
2929
|
const path = await import("path");
|
|
2049
|
-
const { buildSession } = await import("./wizard-session-
|
|
2930
|
+
const { buildSession } = await import("./wizard-session-DPGTaJ4W.js");
|
|
2050
2931
|
const { readEnvironment } = await Promise.resolve().then(() => environment_exports);
|
|
2051
|
-
const { readApiKeyFromEnv } = await import("./env-api-key-
|
|
2052
|
-
const { configureLogFileFromEnvironment, logToFile } = await import("./debug-
|
|
2053
|
-
const { wizardAbort, WizardError } = await import("./wizard-abort-
|
|
2932
|
+
const { readApiKeyFromEnv } = await import("./env-api-key-DU8uIEvo.js");
|
|
2933
|
+
const { configureLogFileFromEnvironment, logToFile } = await import("./debug-B6rX6xye.js");
|
|
2934
|
+
const { wizardAbort, WizardError } = await import("./wizard-abort-BlYGA1Jk.js");
|
|
2054
2935
|
configureLogFileFromEnvironment();
|
|
2055
2936
|
const env = readEnvironment();
|
|
2056
2937
|
const apiKey = options.apiKey ?? readApiKeyFromEnv() ?? void 0;
|
|
@@ -2069,6 +2950,7 @@ function runWizardCI(config, options, preRun) {
|
|
|
2069
2950
|
projectId: options.projectId,
|
|
2070
2951
|
benchmark: options.benchmark,
|
|
2071
2952
|
yaraReport: options.yaraReport,
|
|
2953
|
+
noTelemetry: resolveNoTelemetry(options),
|
|
2072
2954
|
...env
|
|
2073
2955
|
});
|
|
2074
2956
|
session.programLabel = config.id;
|
|
@@ -2100,7 +2982,7 @@ function runWizardCI(config, options, preRun) {
|
|
|
2100
2982
|
})
|
|
2101
2983
|
});
|
|
2102
2984
|
}
|
|
2103
|
-
const { runAgent } = await import("./agent-runner-
|
|
2985
|
+
const { runAgent } = await import("./agent-runner-H1FP6XTc.js");
|
|
2104
2986
|
await runAgent(config, session);
|
|
2105
2987
|
} catch (error) {
|
|
2106
2988
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -2118,6 +3000,6 @@ function runWizardCI(config, options, preRun) {
|
|
|
2118
3000
|
});
|
|
2119
3001
|
}
|
|
2120
3002
|
//#endregion
|
|
2121
|
-
export {
|
|
3003
|
+
export { SOURCE_MAPS_CONTEXT_KEYS as a, fetchHealthIssues as c, STRIPE_SDKS as d, DISPLAY_NAME as i, getContentBlocks$2 as l, Program as n, getContentBlocks$1 as o, getProgramConfig as r, getKindMeta as s, PROGRAM_REGISTRY as t, POSTHOG_SDKS$1 as u };
|
|
2122
3004
|
|
|
2123
3005
|
//# sourceMappingURL=bin.js.map
|