@posthog/wizard 2.14.2 → 2.15.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-B3cm43YY.js → TextBlock-B_8bXLLs.js} +33 -2
- package/dist/TextBlock-B_8bXLLs.js.map +1 -0
- package/dist/{add-mcp-server-to-clients-BL0trzId.js → add-mcp-server-to-clients-Dq0n2yzq.js} +5 -5
- package/dist/add-mcp-server-to-clients-Dq0n2yzq.js.map +1 -0
- package/dist/{agent-interface-HBWLfIDs.js → agent-interface-yB_27jG8.js} +106 -21
- package/dist/agent-interface-yB_27jG8.js.map +1 -0
- package/dist/{agent-runner-PUFQDL4S.js → agent-runner-C9sSudE0.js} +7 -8
- package/dist/agent-runner-C9sSudE0.js.map +1 -0
- package/dist/analytics-BnR9904x.js +2 -0
- package/dist/{analytics-D1-WXmxH.js → analytics-Da4QHjMw.js} +2 -2
- package/dist/analytics-Da4QHjMw.js.map +1 -0
- package/dist/bin.js +901 -108
- package/dist/bin.js.map +1 -1
- package/dist/{debug-BuBfx2GP.js → debug-D5kt4fxB.js} +1 -1
- package/dist/{debug-Dmx2Q7HM.js → debug-DRKLej5r.js} +55 -46
- package/dist/debug-DRKLej5r.js.map +1 -0
- package/dist/{defaults-DgKAzsD1.js → defaults-CPH6eWhN.js} +1 -1
- package/dist/{defaults-DgKAzsD1.js.map → defaults-CPH6eWhN.js.map} +1 -1
- package/dist/{detection-CM90aZAk.js → detection-0Pz2NncX.js} +3 -3
- package/dist/detection-0Pz2NncX.js.map +1 -0
- package/dist/{env-api-key-D5G2PrXW.js → env-api-key-HFqv1l-z.js} +1 -1
- package/dist/{env-api-key-D5G2PrXW.js.map → env-api-key-HFqv1l-z.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/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-D6MvXiGG.js → package-manager-DlTISyej.js} +2 -2
- package/dist/package-manager-DlTISyej.js.map +1 -0
- package/dist/posthog-B1G0raJU.js +120 -0
- package/dist/posthog-B1G0raJU.js.map +1 -0
- package/dist/{posthog-integration-C4yP5ZMX.js → posthog-integration-D-DyEJvz.js} +14 -40
- package/dist/posthog-integration-D-DyEJvz.js.map +1 -0
- package/dist/provisioning-COeHnCVG.js +2 -0
- package/dist/{provisioning-Buru4Hui.js → provisioning-DmN8ZDbE.js} +3 -3
- package/dist/provisioning-DmN8ZDbE.js.map +1 -0
- package/dist/{registry-C9-54_aB.js → registry-CofBzIdU.js} +31 -31
- package/dist/registry-CofBzIdU.js.map +1 -0
- package/dist/setup-utils-C5iSJ3eg.js +2 -0
- package/dist/{setup-utils-Cra9hsR5.js → setup-utils-_P-or31U.js} +91 -51
- package/dist/setup-utils-_P-or31U.js.map +1 -0
- package/dist/{slides-DtXq03Cd.js → slides-D3I6JzlG.js} +41 -8
- package/dist/slides-D3I6JzlG.js.map +1 -0
- package/dist/smoke-test-ci.sh +5 -2
- package/dist/smoke-test.sh +43 -0
- package/dist/{start-playground-BZUi05v7.js → start-playground-Bxd2KG2L.js} +5 -6
- package/dist/start-playground-Bxd2KG2L.js.map +1 -0
- package/dist/{start-tui-BFtVjPvL.js → start-tui-Bl8fCbp_.js} +576 -23
- package/dist/start-tui-Bl8fCbp_.js.map +1 -0
- package/dist/{steps-PV5CP6fe.js → steps-B-vmvb2V.js} +6 -6
- package/dist/steps-B-vmvb2V.js.map +1 -0
- package/dist/task-stream-z6QFZtpC.js +195 -0
- package/dist/task-stream-z6QFZtpC.js.map +1 -0
- package/dist/{telemetry-CeitxLMv.js → telemetry-XO0SlTFs.js} +2 -2
- package/dist/telemetry-XO0SlTFs.js.map +1 -0
- package/dist/{wizard-abort-DwlDCXy5.js → wizard-abort-CuaS1eXn.js} +1 -1
- package/dist/{wizard-abort-gatjLP05.js → wizard-abort-uolun8Q3.js} +3 -3
- package/dist/wizard-abort-uolun8Q3.js.map +1 -0
- package/dist/{wizard-session-CsI33S4_.js → wizard-session-BlgiX-5d.js} +16 -2
- package/dist/wizard-session-BlgiX-5d.js.map +1 -0
- package/dist/wizard-session-DxU5ZMBN.js +2 -0
- package/dist/wizard-ui-YdGFRyu_.js.map +1 -1
- package/package.json +5 -2
- package/dist/TextBlock-B3cm43YY.js.map +0 -1
- package/dist/add-mcp-server-to-clients-BL0trzId.js.map +0 -1
- package/dist/agent-interface-HBWLfIDs.js.map +0 -1
- package/dist/agent-runner-PUFQDL4S.js.map +0 -1
- package/dist/analytics-D1-WXmxH.js.map +0 -1
- package/dist/analytics-DVT_xa3O.js +0 -2
- package/dist/craft-pre-release.sh +0 -10
- package/dist/debug-Dmx2Q7HM.js.map +0 -1
- package/dist/detection-CM90aZAk.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-D6MvXiGG.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/posthog-integration-C4yP5ZMX.js.map +0 -1
- package/dist/provisioning-BbpTbU7J.js +0 -2
- package/dist/provisioning-Buru4Hui.js.map +0 -1
- package/dist/registry-C9-54_aB.js.map +0 -1
- package/dist/setup-utils-BAQfaP4a.js +0 -2
- package/dist/setup-utils-Cra9hsR5.js.map +0 -1
- package/dist/slides-DtXq03Cd.js.map +0 -1
- package/dist/start-playground-BZUi05v7.js.map +0 -1
- package/dist/start-tui-BFtVjPvL.js.map +0 -1
- package/dist/steps-PV5CP6fe.js.map +0 -1
- package/dist/task-stream-DUpUZmFQ.js +0 -61
- package/dist/task-stream-DUpUZmFQ.js.map +0 -1
- package/dist/telemetry-CeitxLMv.js.map +0 -1
- package/dist/wizard-abort-gatjLP05.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 { o as Colors } from "./TextBlock-
|
|
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-DRKLej5r.js";
|
|
4
|
+
import { n as analytics } from "./analytics-Da4QHjMw.js";
|
|
5
|
+
import { a as isUsingTypeScript, f as getCloudUrlFromRegion, m as getUiHostFromHost, u as handleApiError } from "./setup-utils-_P-or31U.js";
|
|
6
|
+
import "./wizard-session-BlgiX-5d.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-yB_27jG8.js";
|
|
8
|
+
import { i as SPINNER_MESSAGE } from "./registry-CofBzIdU.js";
|
|
9
|
+
import { c as HEALTH_CHECK_STEP, o as Colors, r as isClearBlock } from "./TextBlock-B_8bXLLs.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-D-DyEJvz.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",
|
|
@@ -180,6 +181,7 @@ const REVENUE_ANALYTICS_PROGRAM = [
|
|
|
180
181
|
screenId: "revenue-intro",
|
|
181
182
|
gate: (session) => session.setupConfirmed
|
|
182
183
|
},
|
|
184
|
+
HEALTH_CHECK_STEP,
|
|
183
185
|
{
|
|
184
186
|
id: "auth",
|
|
185
187
|
label: "Authentication",
|
|
@@ -211,7 +213,7 @@ const REVENUE_ANALYTICS_PROGRAM = [
|
|
|
211
213
|
* skill-based program (audit, revenue-analytics, agent-skill, etc.)
|
|
212
214
|
* runs. Skill programs don't need the full PostHog onboarding narrative.
|
|
213
215
|
*/
|
|
214
|
-
const getContentBlocks$
|
|
216
|
+
const getContentBlocks$2 = (store) => {
|
|
215
217
|
return [
|
|
216
218
|
{
|
|
217
219
|
content: "Welcome.",
|
|
@@ -243,7 +245,7 @@ const revenueAnalyticsConfig = {
|
|
|
243
245
|
description: "Set up PostHog revenue analytics (e.g. Stripe integration)",
|
|
244
246
|
id: "revenue-analytics-setup",
|
|
245
247
|
steps: REVENUE_ANALYTICS_PROGRAM,
|
|
246
|
-
getContentBlocks: getContentBlocks$
|
|
248
|
+
getContentBlocks: getContentBlocks$2,
|
|
247
249
|
allowedTools: ["Agent"],
|
|
248
250
|
disallowedTools: [WIZARD_TOOL_NAMES.wizardAsk],
|
|
249
251
|
run: {
|
|
@@ -268,6 +270,7 @@ const AGENT_SKILL_STEPS = [
|
|
|
268
270
|
screenId: "agent-skill-intro",
|
|
269
271
|
gate: (session) => session.setupConfirmed
|
|
270
272
|
},
|
|
273
|
+
HEALTH_CHECK_STEP,
|
|
271
274
|
{
|
|
272
275
|
id: "auth",
|
|
273
276
|
label: "Authentication",
|
|
@@ -303,7 +306,7 @@ function createSkillProgram(opts) {
|
|
|
303
306
|
skillId: opts.skillId,
|
|
304
307
|
steps: AGENT_SKILL_STEPS,
|
|
305
308
|
reportFile: opts.reportFile,
|
|
306
|
-
getContentBlocks: getContentBlocks$
|
|
309
|
+
getContentBlocks: getContentBlocks$2,
|
|
307
310
|
run: {
|
|
308
311
|
skillId: opts.skillId,
|
|
309
312
|
integrationLabel: opts.integrationLabel,
|
|
@@ -456,17 +459,6 @@ function needsSetup(session) {
|
|
|
456
459
|
if (!config?.metadata.setup?.questions) return false;
|
|
457
460
|
return config.metadata.setup.questions.some((q) => !(q.key in session.frameworkContext));
|
|
458
461
|
}
|
|
459
|
-
function healthCheckReady(session) {
|
|
460
|
-
if (!session.readinessResult) return false;
|
|
461
|
-
if (session.signup) {
|
|
462
|
-
const hardBlocking = getBlockingServiceKeys(session.readinessResult.health, SIGNUP_WIZARD_READINESS_CONFIG);
|
|
463
|
-
const defaultBlocking = getBlockingServiceKeys(session.readinessResult.health);
|
|
464
|
-
if (hardBlocking.length === 0 && defaultBlocking.length === 0) return true;
|
|
465
|
-
return session.outageDismissed;
|
|
466
|
-
}
|
|
467
|
-
if (session.readinessResult.decision === "no") return session.outageDismissed;
|
|
468
|
-
return true;
|
|
469
|
-
}
|
|
470
462
|
const EVENTS_AUDIT_PROGRAM = [
|
|
471
463
|
{
|
|
472
464
|
id: "intro",
|
|
@@ -474,23 +466,7 @@ const EVENTS_AUDIT_PROGRAM = [
|
|
|
474
466
|
screenId: "audit-intro",
|
|
475
467
|
gate: (session) => session.setupConfirmed
|
|
476
468
|
},
|
|
477
|
-
|
|
478
|
-
id: "health-check",
|
|
479
|
-
label: "Health check",
|
|
480
|
-
screenId: "health-check",
|
|
481
|
-
gate: healthCheckReady,
|
|
482
|
-
onInit: (ctx) => {
|
|
483
|
-
evaluateWizardReadiness().then((readiness) => {
|
|
484
|
-
ctx.setReadinessResult(readiness);
|
|
485
|
-
}).catch(() => {
|
|
486
|
-
ctx.setReadinessResult({
|
|
487
|
-
decision: "yes",
|
|
488
|
-
health: {},
|
|
489
|
-
reasons: []
|
|
490
|
-
});
|
|
491
|
-
});
|
|
492
|
-
}
|
|
493
|
-
},
|
|
469
|
+
HEALTH_CHECK_STEP,
|
|
494
470
|
{
|
|
495
471
|
id: "setup",
|
|
496
472
|
label: "Setup",
|
|
@@ -531,7 +507,7 @@ const EVENTS_AUDIT_PROGRAM = [
|
|
|
531
507
|
//#endregion
|
|
532
508
|
//#region src/lib/programs/events-audit/index.ts
|
|
533
509
|
const SETUP_REPORT_FILE = "posthog-events-audit-report.md";
|
|
534
|
-
const DOCS_URL = "https://posthog.com/docs/product-analytics/best-practices";
|
|
510
|
+
const DOCS_URL$1 = "https://posthog.com/docs/product-analytics/best-practices";
|
|
535
511
|
const eventsAuditConfig = {
|
|
536
512
|
command: "events-audit",
|
|
537
513
|
description: "Audit PostHog event tracking in this project",
|
|
@@ -553,7 +529,7 @@ const eventsAuditConfig = {
|
|
|
553
529
|
successMessage: "Events audit complete! You can view the report at ./posthog-events-audit-report.md",
|
|
554
530
|
estimatedDurationMinutes: 5,
|
|
555
531
|
reportFile: SETUP_REPORT_FILE,
|
|
556
|
-
docsUrl: DOCS_URL,
|
|
532
|
+
docsUrl: DOCS_URL$1,
|
|
557
533
|
errorMessage: "Events audit failed",
|
|
558
534
|
additionalFeatureQueue: session.additionalFeatureQueue,
|
|
559
535
|
customPrompt: (ctx) => `Audit PostHog event capture in this project. Do not modify any project files — produce a read-only report only.
|
|
@@ -571,7 +547,7 @@ Project context:
|
|
|
571
547
|
message: "Your events audit was successful",
|
|
572
548
|
reportFile: SETUP_REPORT_FILE,
|
|
573
549
|
changes: [],
|
|
574
|
-
docsUrl: DOCS_URL,
|
|
550
|
+
docsUrl: DOCS_URL$1,
|
|
575
551
|
continueUrl: sess.signup && cloudUrl ? `${cloudUrl}/products?source=wizard` : void 0,
|
|
576
552
|
dashboardUrl: sess.dashboardUrl ?? (cloudUrl ? `${cloudUrl}/dashboard` : void 0)
|
|
577
553
|
};
|
|
@@ -789,6 +765,7 @@ const POSTHOG_DOCTOR_PROGRAM = [
|
|
|
789
765
|
screenId: "doctor-intro",
|
|
790
766
|
gate: (session) => session.setupConfirmed
|
|
791
767
|
},
|
|
768
|
+
HEALTH_CHECK_STEP,
|
|
792
769
|
{
|
|
793
770
|
id: "auth",
|
|
794
771
|
label: "Authentication",
|
|
@@ -942,6 +919,7 @@ const MIGRATION_PROGRAM = [
|
|
|
942
919
|
screenId: "migration-intro",
|
|
943
920
|
gate: (session) => session.setupConfirmed
|
|
944
921
|
},
|
|
922
|
+
HEALTH_CHECK_STEP,
|
|
945
923
|
{
|
|
946
924
|
id: "auth",
|
|
947
925
|
label: "Authentication",
|
|
@@ -1211,7 +1189,7 @@ const PRICING_STRUCTURE_BLOCK = {
|
|
|
1211
1189
|
* - posthog.com/docs/feature-flags/common-questions
|
|
1212
1190
|
* - posthog.com/docs/experiments/best-practices
|
|
1213
1191
|
*/
|
|
1214
|
-
const getContentBlocks = (store) => [
|
|
1192
|
+
const getContentBlocks$1 = (store) => [
|
|
1215
1193
|
{
|
|
1216
1194
|
content: "Hello.",
|
|
1217
1195
|
pause: 3e3,
|
|
@@ -1463,7 +1441,7 @@ const migrationConfig = {
|
|
|
1463
1441
|
skillId: PRODUCT_TO_SKILL_ID.statsig,
|
|
1464
1442
|
steps: MIGRATION_PROGRAM,
|
|
1465
1443
|
reportFile: MIGRATION_REPORT_FILE,
|
|
1466
|
-
getContentBlocks,
|
|
1444
|
+
getContentBlocks: getContentBlocks$1,
|
|
1467
1445
|
allowedTools: ["Agent"],
|
|
1468
1446
|
disallowedTools: [WIZARD_TOOL_NAMES.wizardAsk],
|
|
1469
1447
|
cliOptions: { product: {
|
|
@@ -1487,6 +1465,753 @@ const migrationConfig = {
|
|
|
1487
1465
|
requires: ["posthog-integration"]
|
|
1488
1466
|
};
|
|
1489
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-sourcemaps",
|
|
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
|
|
1490
2215
|
//#region src/lib/programs/mcp/index.ts
|
|
1491
2216
|
const mcpAddConfig = {
|
|
1492
2217
|
id: "mcp-add",
|
|
@@ -1514,12 +2239,13 @@ const agentSkillConfig = {
|
|
|
1514
2239
|
id: "agent-skill",
|
|
1515
2240
|
description: "Run an arbitrary context-mill skill",
|
|
1516
2241
|
steps: AGENT_SKILL_STEPS,
|
|
1517
|
-
getContentBlocks: getContentBlocks$
|
|
2242
|
+
getContentBlocks: getContentBlocks$2,
|
|
1518
2243
|
allowedTools: ["Agent"]
|
|
1519
2244
|
};
|
|
1520
2245
|
const PROGRAM_REGISTRY = [
|
|
1521
2246
|
posthogIntegrationConfig,
|
|
1522
2247
|
revenueAnalyticsConfig,
|
|
2248
|
+
errorTrackingUploadSourceMapsConfig,
|
|
1523
2249
|
auditConfig,
|
|
1524
2250
|
eventsAuditConfig,
|
|
1525
2251
|
audit3000Config,
|
|
@@ -1537,6 +2263,7 @@ const PROGRAM_REGISTRY = [
|
|
|
1537
2263
|
const Program = {
|
|
1538
2264
|
PostHogIntegration: posthogIntegrationConfig.id,
|
|
1539
2265
|
RevenueAnalyticsSetup: revenueAnalyticsConfig.id,
|
|
2266
|
+
ErrorTrackingUploadSourceMaps: errorTrackingUploadSourceMapsConfig.id,
|
|
1540
2267
|
Migration: migrationConfig.id,
|
|
1541
2268
|
Audit: auditConfig.id,
|
|
1542
2269
|
EventsAudit: eventsAuditConfig.id,
|
|
@@ -1560,12 +2287,12 @@ function getSubcommandPrograms() {
|
|
|
1560
2287
|
}
|
|
1561
2288
|
//#endregion
|
|
1562
2289
|
//#region bin.ts
|
|
1563
|
-
const
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
console.log(`PostHog wizard requires Node.js ${NODE_VERSION_RANGE}. You are using Node.js ${process.version}. Please upgrade your Node.js version.`);
|
|
2290
|
+
const MIN_NODE_VERSION = ">=18.17.0";
|
|
2291
|
+
if (!satisfies(process.version, MIN_NODE_VERSION)) {
|
|
2292
|
+
console.log(`PostHog wizard needs Node.js ${MIN_NODE_VERSION}. Detected ${process.version} — please upgrade Node and re-run.`);
|
|
1567
2293
|
process.exit(1);
|
|
1568
2294
|
}
|
|
2295
|
+
const WIZARD_VERSION = VERSION;
|
|
1569
2296
|
/** Shared yargs options for skill-based program subcommands. */
|
|
1570
2297
|
const skillSubcommandOptions = {
|
|
1571
2298
|
debug: {
|
|
@@ -1620,11 +2347,6 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1620
2347
|
describe: "Use local MCP server at http://localhost:8787/mcp\nenv: POSTHOG_WIZARD_LOCAL_MCP",
|
|
1621
2348
|
type: "boolean"
|
|
1622
2349
|
},
|
|
1623
|
-
ci: {
|
|
1624
|
-
default: false,
|
|
1625
|
-
describe: "Enable CI mode for non-interactive execution\nenv: POSTHOG_WIZARD_CI",
|
|
1626
|
-
type: "boolean"
|
|
1627
|
-
},
|
|
1628
2350
|
"api-key": {
|
|
1629
2351
|
describe: "PostHog personal API key (phx_xxx) for authentication\nenv: POSTHOG_WIZARD_API_KEY",
|
|
1630
2352
|
type: "string"
|
|
@@ -1636,6 +2358,11 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1636
2358
|
email: {
|
|
1637
2359
|
describe: "Email address for signup (used with --signup)\nenv: POSTHOG_WIZARD_EMAIL",
|
|
1638
2360
|
type: "string"
|
|
2361
|
+
},
|
|
2362
|
+
telemetry: {
|
|
2363
|
+
default: true,
|
|
2364
|
+
describe: "Send wizard run state to PostHog (pass --no-telemetry to disable)\nenv: POSTHOG_WIZARD_TELEMETRY",
|
|
2365
|
+
type: "boolean"
|
|
1639
2366
|
}
|
|
1640
2367
|
}).command(["$0"], "Run the PostHog setup wizard", (yargs) => {
|
|
1641
2368
|
return yargs.options({
|
|
@@ -1733,7 +2460,7 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1733
2460
|
setUI(new LoggingUI());
|
|
1734
2461
|
getUI().intro("PostHog Wizard");
|
|
1735
2462
|
try {
|
|
1736
|
-
const { provisionNewAccount } = await import("./provisioning-
|
|
2463
|
+
const { provisionNewAccount } = await import("./provisioning-COeHnCVG.js");
|
|
1737
2464
|
const signupRegion = options.region.toUpperCase();
|
|
1738
2465
|
getUI().log.info(`Provisioning new PostHog account for ${String(options.email)} in ${signupRegion}...`);
|
|
1739
2466
|
const result = await provisionNewAccount(options.email, options.name ?? "", signupRegion);
|
|
@@ -1755,11 +2482,11 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1755
2482
|
return;
|
|
1756
2483
|
}
|
|
1757
2484
|
}
|
|
1758
|
-
const { posthogIntegrationConfig } = await import("./posthog-integration-
|
|
1759
|
-
const { FRAMEWORK_REGISTRY } = await import("./registry-
|
|
1760
|
-
const { detectFramework, gatherFrameworkContext } = await import("./detection-
|
|
1761
|
-
const { analytics } = await import("./analytics-
|
|
1762
|
-
const { wizardAbort } = await import("./wizard-abort-
|
|
2485
|
+
const { posthogIntegrationConfig } = await import("./posthog-integration-D-DyEJvz.js").then((n) => n.r);
|
|
2486
|
+
const { FRAMEWORK_REGISTRY } = await import("./registry-CofBzIdU.js").then((n) => n.n);
|
|
2487
|
+
const { detectFramework, gatherFrameworkContext } = await import("./detection-0Pz2NncX.js").then((n) => n.t);
|
|
2488
|
+
const { analytics } = await import("./analytics-BnR9904x.js");
|
|
2489
|
+
const { wizardAbort } = await import("./wizard-abort-CuaS1eXn.js");
|
|
1763
2490
|
runWizardCI(posthogIntegrationConfig, options, async (session) => {
|
|
1764
2491
|
const integration = session.integration ?? await detectFramework(session.installDir);
|
|
1765
2492
|
if (!integration) {
|
|
@@ -1789,10 +2516,10 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1789
2516
|
});
|
|
1790
2517
|
} else if (isNonInteractiveEnvironment()) {
|
|
1791
2518
|
getUI().intro(`PostHog Wizard`);
|
|
1792
|
-
getUI().log.error("This installer requires an interactive terminal (TTY) to run.\nIt appears you are running in a non-interactive environment.\
|
|
2519
|
+
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");
|
|
1793
2520
|
process.exit(1);
|
|
1794
2521
|
} else if (options.playground) (async () => {
|
|
1795
|
-
const { startPlayground } = await import("./start-playground-
|
|
2522
|
+
const { startPlayground } = await import("./start-playground-Bxd2KG2L.js");
|
|
1796
2523
|
startPlayground(WIZARD_VERSION);
|
|
1797
2524
|
})();
|
|
1798
2525
|
else if (options.skill) (async () => {
|
|
@@ -1815,7 +2542,7 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1815
2542
|
});
|
|
1816
2543
|
})();
|
|
1817
2544
|
else (async () => {
|
|
1818
|
-
const { posthogIntegrationConfig } = await import("./posthog-integration-
|
|
2545
|
+
const { posthogIntegrationConfig } = await import("./posthog-integration-D-DyEJvz.js").then((n) => n.r);
|
|
1819
2546
|
runWizard(posthogIntegrationConfig, options);
|
|
1820
2547
|
})();
|
|
1821
2548
|
}).command("mcp <command>", "MCP server management commands", (yargs) => {
|
|
@@ -1839,11 +2566,11 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1839
2566
|
const options = { ...argv };
|
|
1840
2567
|
const mcpFeatures = options.features?.split(",").map((s) => s.trim()).filter(Boolean);
|
|
1841
2568
|
(async () => {
|
|
1842
|
-
const { readApiKeyFromEnv } = await import("./env-api-key-
|
|
2569
|
+
const { readApiKeyFromEnv } = await import("./env-api-key-HFqv1l-z.js");
|
|
1843
2570
|
const apiKey = options.apiKey || readApiKeyFromEnv();
|
|
1844
2571
|
try {
|
|
1845
|
-
const { startTUI } = await import("./start-tui-
|
|
1846
|
-
const { buildSession } = await import("./wizard-session-
|
|
2572
|
+
const { startTUI } = await import("./start-tui-Bl8fCbp_.js");
|
|
2573
|
+
const { buildSession } = await import("./wizard-session-DxU5ZMBN.js");
|
|
1847
2574
|
const tui = startTUI(WIZARD_VERSION, Program.McpAdd);
|
|
1848
2575
|
const session = buildSession({
|
|
1849
2576
|
debug: options.debug,
|
|
@@ -1854,7 +2581,7 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1854
2581
|
tui.store.session = session;
|
|
1855
2582
|
} catch {
|
|
1856
2583
|
setUI(new LoggingUI());
|
|
1857
|
-
const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-
|
|
2584
|
+
const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-Dq0n2yzq.js").then((n) => n.r);
|
|
1858
2585
|
await addMCPServerToClientsStep({
|
|
1859
2586
|
local: options.local,
|
|
1860
2587
|
features: mcpFeatures,
|
|
@@ -1872,8 +2599,8 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1872
2599
|
const options = { ...argv };
|
|
1873
2600
|
(async () => {
|
|
1874
2601
|
try {
|
|
1875
|
-
const { startTUI } = await import("./start-tui-
|
|
1876
|
-
const { buildSession } = await import("./wizard-session-
|
|
2602
|
+
const { startTUI } = await import("./start-tui-Bl8fCbp_.js");
|
|
2603
|
+
const { buildSession } = await import("./wizard-session-DxU5ZMBN.js");
|
|
1877
2604
|
const tui = startTUI(WIZARD_VERSION, Program.McpRemove);
|
|
1878
2605
|
const session = buildSession({
|
|
1879
2606
|
debug: options.debug,
|
|
@@ -1882,7 +2609,7 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1882
2609
|
tui.store.session = session;
|
|
1883
2610
|
} catch {
|
|
1884
2611
|
setUI(new LoggingUI());
|
|
1885
|
-
const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-
|
|
2612
|
+
const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-Dq0n2yzq.js").then((n) => n.r);
|
|
1886
2613
|
await removeMCPServerFromClientsStep({ local: options.local });
|
|
1887
2614
|
}
|
|
1888
2615
|
})();
|
|
@@ -1918,7 +2645,7 @@ cli.command("provision", "Create a new PostHog account (headless, no TUI)", (yar
|
|
|
1918
2645
|
if (!jsonMode) setUI(new LoggingUI());
|
|
1919
2646
|
(async () => {
|
|
1920
2647
|
try {
|
|
1921
|
-
const { provisionNewAccount } = await import("./provisioning-
|
|
2648
|
+
const { provisionNewAccount } = await import("./provisioning-COeHnCVG.js");
|
|
1922
2649
|
if (!jsonMode) getUI().log.info(`Provisioning account for ${email} in ${region}...`);
|
|
1923
2650
|
const result = await provisionNewAccount(email, name, region);
|
|
1924
2651
|
if (jsonMode) process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
@@ -1957,23 +2684,56 @@ for (const programConfig of getSubcommandPrograms()) cli.command(programConfig.c
|
|
|
1957
2684
|
if (options.ci) runWizardCI(programConfig, options);
|
|
1958
2685
|
else runWizard(programConfig, options);
|
|
1959
2686
|
});
|
|
1960
|
-
cli.
|
|
2687
|
+
cli.strictOptions().fail((msg, err) => {
|
|
2688
|
+
throw err || new Error(msg);
|
|
2689
|
+
}).help().alias("help", "h").version().alias("version", "v").wrap(process.stdout.isTTY ? cli.terminalWidth() : 80);
|
|
2690
|
+
{
|
|
2691
|
+
const argvHasCI = process.argv.slice(2).some((a) => a === "--ci" || a === "--no-ci" || a.startsWith("--ci="));
|
|
2692
|
+
const envHasCI = process.env.POSTHOG_WIZARD_CI != null && process.env.POSTHOG_WIZARD_CI !== "";
|
|
2693
|
+
if (argvHasCI || envHasCI) exitWithProductionCIError();
|
|
2694
|
+
}
|
|
2695
|
+
try {
|
|
2696
|
+
cli.parse();
|
|
2697
|
+
} catch (err) {
|
|
2698
|
+
const RED = "\x1B[31m";
|
|
2699
|
+
const BOLD = "\x1B[1m";
|
|
2700
|
+
const RESET = "\x1B[0m";
|
|
2701
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2702
|
+
process.stderr.write(`${RED}${BOLD}✖ ${message}${RESET}\n`);
|
|
2703
|
+
process.stderr.write("Run with --help to see available options.\n");
|
|
2704
|
+
process.exit(1);
|
|
2705
|
+
}
|
|
2706
|
+
function exitWithProductionCIError() {
|
|
2707
|
+
process.stderr.write(`[31m[1m✖ CI mode is not currently supported in published builds.[0m\n`);
|
|
2708
|
+
process.exit(1);
|
|
2709
|
+
}
|
|
2710
|
+
function resolveNoTelemetry(options) {
|
|
2711
|
+
if (options.telemetry === false) return true;
|
|
2712
|
+
const env = process.env.POSTHOG_WIZARD_NO_TELEMETRY;
|
|
2713
|
+
if (env == null || env === "") return false;
|
|
2714
|
+
const norm = env.toLowerCase();
|
|
2715
|
+
return norm !== "0" && norm !== "false";
|
|
2716
|
+
}
|
|
1961
2717
|
/**
|
|
1962
2718
|
* Run a full wizard program in the TUI. Handles the full lifecycle: start TUI,
|
|
1963
2719
|
* build session, run detection, wait for intro gate, execute the
|
|
1964
2720
|
* agent pipeline, wait for outro dismissal, then exit.
|
|
1965
2721
|
*/
|
|
1966
2722
|
function runWizard(config, options) {
|
|
2723
|
+
let tui = null;
|
|
2724
|
+
let taskStream = null;
|
|
2725
|
+
let onSignal = null;
|
|
2726
|
+
let exitInProgress = false;
|
|
1967
2727
|
(async () => {
|
|
1968
2728
|
try {
|
|
1969
2729
|
const installDir = options.installDir || process.cwd();
|
|
1970
|
-
const { startTUI } = await import("./start-tui-
|
|
1971
|
-
const { buildSession } = await import("./wizard-session-
|
|
1972
|
-
const { TaskStreamPush } = await import("./task-stream-
|
|
1973
|
-
const {
|
|
1974
|
-
const {
|
|
1975
|
-
|
|
1976
|
-
const
|
|
2730
|
+
const { startTUI } = await import("./start-tui-Bl8fCbp_.js");
|
|
2731
|
+
const { buildSession, RunPhase } = await import("./wizard-session-DxU5ZMBN.js");
|
|
2732
|
+
const { TaskStreamPush } = await import("./task-stream-z6QFZtpC.js");
|
|
2733
|
+
const { PostHogDestination } = await import("./posthog-B1G0raJU.js");
|
|
2734
|
+
const { logToFile } = await import("./debug-D5kt4fxB.js");
|
|
2735
|
+
tui = startTUI(WIZARD_VERSION, config.id);
|
|
2736
|
+
const activeTui = tui;
|
|
1977
2737
|
const session = buildSession({
|
|
1978
2738
|
debug: options.debug,
|
|
1979
2739
|
forceInstall: options.forceInstall,
|
|
@@ -1987,43 +2747,64 @@ function runWizard(config, options) {
|
|
|
1987
2747
|
menu: options.menu,
|
|
1988
2748
|
integration: options.integration,
|
|
1989
2749
|
benchmark: options.benchmark,
|
|
1990
|
-
yaraReport: options.yaraReport
|
|
2750
|
+
yaraReport: options.yaraReport,
|
|
2751
|
+
noTelemetry: resolveNoTelemetry(options)
|
|
1991
2752
|
});
|
|
1992
2753
|
session.programLabel = config.id;
|
|
1993
2754
|
if (options.skillId) session.skillId = options.skillId;
|
|
1994
2755
|
else if (config.skillId) session.skillId = config.skillId;
|
|
1995
|
-
|
|
1996
|
-
const
|
|
1997
|
-
|
|
2756
|
+
activeTui.store.session = session;
|
|
2757
|
+
const taskStreamEnabled = !session.noTelemetry;
|
|
2758
|
+
taskStream = new TaskStreamPush({
|
|
2759
|
+
store: activeTui.store,
|
|
1998
2760
|
programId: config.id,
|
|
1999
|
-
destinations: [new
|
|
2761
|
+
destinations: [new PostHogDestination({
|
|
2762
|
+
getCredentials: () => activeTui.store.session.credentials,
|
|
2763
|
+
onError: (err) => logToFile("[task-stream-push]", err.message)
|
|
2764
|
+
})],
|
|
2765
|
+
enabled: taskStreamEnabled
|
|
2000
2766
|
});
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2767
|
+
const activeStream = taskStream;
|
|
2768
|
+
activeStream.attach();
|
|
2769
|
+
let signalled = false;
|
|
2770
|
+
onSignal = () => {
|
|
2771
|
+
if (signalled || exitInProgress) return;
|
|
2772
|
+
signalled = true;
|
|
2773
|
+
if (activeTui.store.session.runPhase === RunPhase.Running) activeTui.store.setRunPhase(RunPhase.Error);
|
|
2774
|
+
activeStream.shutdown(2e3).finally(() => {
|
|
2775
|
+
try {
|
|
2776
|
+
activeTui.unmount();
|
|
2777
|
+
} catch {}
|
|
2778
|
+
process.exit(130);
|
|
2779
|
+
});
|
|
2780
|
+
};
|
|
2781
|
+
process.on("SIGINT", onSignal);
|
|
2782
|
+
process.on("SIGTERM", onSignal);
|
|
2783
|
+
await activeTui.store.runReadyHooks();
|
|
2784
|
+
await activeTui.store.getGate("intro");
|
|
2785
|
+
await activeTui.store.getGate("health-check");
|
|
2005
2786
|
const skipAgent = config.run == null;
|
|
2006
2787
|
if (skipAgent) {
|
|
2007
|
-
const { getOrAskForProjectData } = await import("./setup-utils-
|
|
2788
|
+
const { getOrAskForProjectData } = await import("./setup-utils-C5iSJ3eg.js");
|
|
2008
2789
|
const { projectApiKey, host, accessToken, projectId } = await getOrAskForProjectData({
|
|
2009
2790
|
signup: session.signup,
|
|
2010
2791
|
ci: session.ci,
|
|
2011
2792
|
apiKey: session.apiKey,
|
|
2012
2793
|
projectId: session.projectId
|
|
2013
2794
|
});
|
|
2014
|
-
|
|
2795
|
+
activeTui.store.setCredentials({
|
|
2015
2796
|
accessToken,
|
|
2016
2797
|
projectApiKey,
|
|
2017
2798
|
host,
|
|
2018
2799
|
projectId
|
|
2019
2800
|
});
|
|
2020
2801
|
} else {
|
|
2021
|
-
const { runAgent } = await import("./agent-runner-
|
|
2022
|
-
await runAgent(config,
|
|
2802
|
+
const { runAgent } = await import("./agent-runner-C9sSudE0.js");
|
|
2803
|
+
await runAgent(config, activeTui.store.session);
|
|
2023
2804
|
}
|
|
2024
|
-
const isDone = () => skipAgent ?
|
|
2805
|
+
const isDone = () => skipAgent ? activeTui.store.session.outroDismissed : activeTui.store.session.skillsComplete;
|
|
2025
2806
|
await new Promise((resolve) => {
|
|
2026
|
-
const unsub =
|
|
2807
|
+
const unsub = activeTui.store.subscribe(() => {
|
|
2027
2808
|
if (isDone()) {
|
|
2028
2809
|
unsub();
|
|
2029
2810
|
resolve();
|
|
@@ -2034,15 +2815,26 @@ function runWizard(config, options) {
|
|
|
2034
2815
|
resolve();
|
|
2035
2816
|
}
|
|
2036
2817
|
});
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
tui.unmount();
|
|
2818
|
+
exitInProgress = true;
|
|
2819
|
+
await activeStream.shutdown(2e3);
|
|
2820
|
+
process.off("SIGINT", onSignal);
|
|
2821
|
+
process.off("SIGTERM", onSignal);
|
|
2822
|
+
activeTui.unmount();
|
|
2043
2823
|
process.exit(0);
|
|
2044
2824
|
} catch (err) {
|
|
2045
2825
|
if (runtimeEnv("DEBUG") || runtimeEnv("POSTHOG_WIZARD_DEBUG")) console.error("TUI init failed:", err);
|
|
2826
|
+
exitInProgress = true;
|
|
2827
|
+
if (onSignal) {
|
|
2828
|
+
process.off("SIGINT", onSignal);
|
|
2829
|
+
process.off("SIGTERM", onSignal);
|
|
2830
|
+
}
|
|
2831
|
+
if (taskStream) try {
|
|
2832
|
+
await taskStream.shutdown(2e3);
|
|
2833
|
+
} catch {}
|
|
2834
|
+
if (tui) try {
|
|
2835
|
+
tui.unmount();
|
|
2836
|
+
} catch {}
|
|
2837
|
+
process.exit(1);
|
|
2046
2838
|
}
|
|
2047
2839
|
})();
|
|
2048
2840
|
}
|
|
@@ -2069,11 +2861,11 @@ function runWizardCI(config, options, preRun) {
|
|
|
2069
2861
|
}
|
|
2070
2862
|
(async () => {
|
|
2071
2863
|
const path = await import("path");
|
|
2072
|
-
const { buildSession } = await import("./wizard-session-
|
|
2864
|
+
const { buildSession } = await import("./wizard-session-DxU5ZMBN.js");
|
|
2073
2865
|
const { readEnvironment } = await Promise.resolve().then(() => environment_exports);
|
|
2074
|
-
const { readApiKeyFromEnv } = await import("./env-api-key-
|
|
2075
|
-
const { configureLogFileFromEnvironment, logToFile } = await import("./debug-
|
|
2076
|
-
const { wizardAbort, WizardError } = await import("./wizard-abort-
|
|
2866
|
+
const { readApiKeyFromEnv } = await import("./env-api-key-HFqv1l-z.js");
|
|
2867
|
+
const { configureLogFileFromEnvironment, logToFile } = await import("./debug-D5kt4fxB.js");
|
|
2868
|
+
const { wizardAbort, WizardError } = await import("./wizard-abort-CuaS1eXn.js");
|
|
2077
2869
|
configureLogFileFromEnvironment();
|
|
2078
2870
|
const env = readEnvironment();
|
|
2079
2871
|
const apiKey = options.apiKey ?? readApiKeyFromEnv() ?? void 0;
|
|
@@ -2092,6 +2884,7 @@ function runWizardCI(config, options, preRun) {
|
|
|
2092
2884
|
projectId: options.projectId,
|
|
2093
2885
|
benchmark: options.benchmark,
|
|
2094
2886
|
yaraReport: options.yaraReport,
|
|
2887
|
+
noTelemetry: resolveNoTelemetry(options),
|
|
2095
2888
|
...env
|
|
2096
2889
|
});
|
|
2097
2890
|
session.programLabel = config.id;
|
|
@@ -2123,7 +2916,7 @@ function runWizardCI(config, options, preRun) {
|
|
|
2123
2916
|
})
|
|
2124
2917
|
});
|
|
2125
2918
|
}
|
|
2126
|
-
const { runAgent } = await import("./agent-runner-
|
|
2919
|
+
const { runAgent } = await import("./agent-runner-C9sSudE0.js");
|
|
2127
2920
|
await runAgent(config, session);
|
|
2128
2921
|
} catch (error) {
|
|
2129
2922
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -2141,6 +2934,6 @@ function runWizardCI(config, options, preRun) {
|
|
|
2141
2934
|
});
|
|
2142
2935
|
}
|
|
2143
2936
|
//#endregion
|
|
2144
|
-
export {
|
|
2937
|
+
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 };
|
|
2145
2938
|
|
|
2146
2939
|
//# sourceMappingURL=bin.js.map
|