@posthog/wizard 2.13.0 → 2.14.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/LICENSE +0 -26
- package/README.md +1 -1
- package/dist/TextBlock-B3cm43YY.js +244 -0
- package/dist/TextBlock-B3cm43YY.js.map +1 -0
- package/dist/{add-mcp-server-to-clients-CUNR00bB.js → add-mcp-server-to-clients-BTW9Ey5Z.js} +7 -7
- package/dist/{add-mcp-server-to-clients-CUNR00bB.js.map → add-mcp-server-to-clients-BTW9Ey5Z.js.map} +1 -1
- package/dist/{agent-interface-CV0-vtxj.js → agent-interface-gP4pkZgS.js} +534 -256
- package/dist/agent-interface-gP4pkZgS.js.map +1 -0
- package/dist/{agent-runner-LvVQH31D.js → agent-runner-Bxi71jnp.js} +102 -20
- package/dist/agent-runner-Bxi71jnp.js.map +1 -0
- package/dist/{analytics-VM7laaFx.js → analytics-Dmnxu2zE.js} +2 -2
- package/dist/{analytics-VM7laaFx.js.map → analytics-Dmnxu2zE.js.map} +1 -1
- package/dist/analytics-tslsXyf9.js +2 -0
- package/dist/bin.js +951 -141
- package/dist/bin.js.map +1 -1
- package/dist/{debug-Cqi6nVfX.js → debug-CYUB-urp.js} +26 -21
- package/dist/debug-CYUB-urp.js.map +1 -0
- package/dist/{debug-BdcTB7EF.js → debug-Du7qXlug.js} +1 -1
- package/dist/{defaults-GbLPuHxj.js → defaults-DgKAzsD1.js} +1 -1
- package/dist/{defaults-GbLPuHxj.js.map → defaults-DgKAzsD1.js.map} +1 -1
- package/dist/{detection-CSjmal-X.js → detection-D651Eb5k.js} +4 -4
- package/dist/detection-D651Eb5k.js.map +1 -0
- package/dist/{file-8iNrXHkG.js → file-BKbKreWF.js} +1 -1
- package/dist/{file-8iNrXHkG.js.map → file-BKbKreWF.js.map} +1 -1
- package/dist/{file-utils-DnTSiTJw.js → file-utils-DPmgn9Vm.js} +1 -1
- package/dist/{file-utils-DnTSiTJw.js.map → file-utils-DPmgn9Vm.js.map} +1 -1
- package/dist/{package-json-F_7oktsp.js → package-json-DZpnf6vU.js} +8 -10
- package/dist/package-json-DZpnf6vU.js.map +1 -0
- package/dist/package-json-_4PEss19.js +2 -0
- package/dist/{package-manager-CD8RQW-e.js → package-manager-liwrN_aI.js} +2 -2
- package/dist/{package-manager-CD8RQW-e.js.map → package-manager-liwrN_aI.js.map} +1 -1
- package/dist/{posthog-vm0k9PKS.js → posthog-BbQf_Hzq.js} +1 -1
- package/dist/{posthog-vm0k9PKS.js.map → posthog-BbQf_Hzq.js.map} +1 -1
- package/dist/posthog-integration-C-FFV5ny.js +1012 -0
- package/dist/posthog-integration-C-FFV5ny.js.map +1 -0
- package/dist/provisioning-ByWo5KcQ.js +2 -0
- package/dist/{provisioning-g9aoVIEd.js → provisioning-C4nHkz-O.js} +3 -3
- package/dist/{provisioning-g9aoVIEd.js.map → provisioning-C4nHkz-O.js.map} +1 -1
- package/dist/{registry-BaMEaAKd.js → registry-B92uyoWK.js} +5 -5
- package/dist/{registry-BaMEaAKd.js.map → registry-B92uyoWK.js.map} +1 -1
- package/dist/setup-utils-D5aNKrba.js +2 -0
- package/dist/{setup-utils-CNV7FSlY.js → setup-utils-LvtZIY18.js} +77 -107
- package/dist/setup-utils-LvtZIY18.js.map +1 -0
- package/dist/{AuditChecksViewer-B0J7zcY2.js → slides-yyC_W0RZ.js} +626 -1058
- package/dist/slides-yyC_W0RZ.js.map +1 -0
- package/dist/smoke-test-ci.sh +4 -4
- package/dist/{start-playground-C9GWnVdM.js → start-playground-BhwBUq-a.js} +259 -10
- package/dist/start-playground-BhwBUq-a.js.map +1 -0
- package/dist/{start-tui-B_zwutLe.js → start-tui-BwQa3kmG.js} +288 -446
- package/dist/start-tui-BwQa3kmG.js.map +1 -0
- package/dist/{steps-Dawz7k3T.js → steps-CGpfOAcr.js} +7 -7
- package/dist/{steps-Dawz7k3T.js.map → steps-CGpfOAcr.js.map} +1 -1
- package/dist/{task-stream-CX7Uf6EM.js → task-stream-DUpUZmFQ.js} +8 -8
- package/dist/task-stream-DUpUZmFQ.js.map +1 -0
- package/dist/telemetry-Fmdx1AYv.js +13 -0
- package/dist/telemetry-Fmdx1AYv.js.map +1 -0
- package/dist/{wizard-abort-Dl0BkqhT.js → wizard-abort-BTBccRto.js} +1 -1
- package/dist/{wizard-abort-CJkNkSjT.js → wizard-abort-D-t5yDkY.js} +3 -3
- package/dist/{wizard-abort-CJkNkSjT.js.map → wizard-abort-D-t5yDkY.js.map} +1 -1
- package/dist/wizard-session-CPhhll4P.js +2 -0
- package/dist/{wizard-session-BcNJTl2I.js → wizard-session-CsI33S4_.js} +6 -3
- package/dist/wizard-session-CsI33S4_.js.map +1 -0
- package/dist/wizard-ui-YdGFRyu_.js.map +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +3 -2
- package/dist/AuditChecksViewer-B0J7zcY2.js.map +0 -1
- package/dist/agent-interface-CV0-vtxj.js.map +0 -1
- package/dist/agent-runner-LvVQH31D.js.map +0 -1
- package/dist/analytics-BH7bEHQR.js +0 -2
- package/dist/debug-Cqi6nVfX.js.map +0 -1
- package/dist/detection-CSjmal-X.js.map +0 -1
- package/dist/package-json-BzVey4Bd.js +0 -2
- package/dist/package-json-F_7oktsp.js.map +0 -1
- package/dist/posthog-integration-BL21S3T6.js +0 -259
- package/dist/posthog-integration-BL21S3T6.js.map +0 -1
- package/dist/provisioning-BdQ1ONIg.js +0 -2
- package/dist/router-COhhuIW3.js +0 -135
- package/dist/router-COhhuIW3.js.map +0 -1
- package/dist/setup-utils-CNV7FSlY.js.map +0 -1
- package/dist/setup-utils-CU4FIqjB.js +0 -2
- package/dist/start-playground-C9GWnVdM.js.map +0 -1
- package/dist/start-tui-B_zwutLe.js.map +0 -1
- package/dist/task-stream-CX7Uf6EM.js.map +0 -1
- package/dist/telemetry-D6bjWA-A.js +0 -13
- package/dist/telemetry-D6bjWA-A.js.map +0 -1
- package/dist/wizard-session-BQC9vy9Z.js +0 -2
- package/dist/wizard-session-BcNJTl2I.js.map +0 -1
package/dist/bin.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { t as __exportAll } from "./rolldown-runtime-B_-DWIq7.js";
|
|
3
|
-
import { D as POSTHOG_DOCS_URL, G as VERSION,
|
|
4
|
-
import { n as analytics } from "./analytics-
|
|
5
|
-
import { u as handleApiError } from "./setup-utils-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
3
|
+
import { D as POSTHOG_DOCS_URL, G as VERSION, W as runtimeEnv, c as getUI, f as SIGNUP_WIZARD_READINESS_CONFIG, l as setUI, m as getBlockingServiceKeys, p as evaluateWizardReadiness, s as logToFile, u as LoggingUI, z as WIZARD_USER_AGENT } from "./debug-CYUB-urp.js";
|
|
4
|
+
import { n as analytics } from "./analytics-Dmnxu2zE.js";
|
|
5
|
+
import { a as isUsingTypeScript, d as getCloudUrlFromRegion, u as handleApiError } from "./setup-utils-LvtZIY18.js";
|
|
6
|
+
import { g as AUDIT_REPORT_FILE, h as AUDIT_CHECKS_KEY, m as AUDIT_CHECKS_FILE, u as WIZARD_TOOL_NAMES } from "./agent-interface-gP4pkZgS.js";
|
|
7
|
+
import { i as SPINNER_MESSAGE } from "./registry-B92uyoWK.js";
|
|
8
|
+
import { a as LINE_CHART_BLOCK, i as FUNNEL_BLOCK, n as posthogIntegrationConfig, o as PRODUCT_SUITE_BLOCK, s as StatusPeekTrigger } from "./posthog-integration-C-FFV5ny.js";
|
|
9
|
+
import { o as Colors } from "./TextBlock-B3cm43YY.js";
|
|
10
|
+
import { t as IGNORED_DIRS } from "./file-utils-DPmgn9Vm.js";
|
|
9
11
|
import { satisfies } from "semver";
|
|
10
12
|
import yargs from "yargs";
|
|
11
13
|
import { hideBin } from "yargs/helpers";
|
|
@@ -15,6 +17,8 @@ import path, { join, relative } from "path";
|
|
|
15
17
|
import axios from "axios";
|
|
16
18
|
import { z } from "zod";
|
|
17
19
|
import "fast-glob";
|
|
20
|
+
import { Text } from "ink";
|
|
21
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
18
22
|
//#region src/utils/environment.ts
|
|
19
23
|
var environment_exports = /* @__PURE__ */ __exportAll({
|
|
20
24
|
isNonInteractiveEnvironment: () => isNonInteractiveEnvironment,
|
|
@@ -29,7 +33,7 @@ function readEnvironment() {
|
|
|
29
33
|
return readEnv("POSTHOG_WIZARD");
|
|
30
34
|
}
|
|
31
35
|
//#endregion
|
|
32
|
-
//#region src/lib/
|
|
36
|
+
//#region src/lib/programs/revenue-analytics/detect.ts
|
|
33
37
|
const POSTHOG_SDKS = [
|
|
34
38
|
"posthog-js",
|
|
35
39
|
"posthog-node",
|
|
@@ -163,47 +167,85 @@ function detectRevenuePrerequisites(session, setFrameworkContext) {
|
|
|
163
167
|
setFrameworkContext("detectedPackagePaths", matches.filter((m) => m.posthogSdks.length > 0 || m.stripeSdks.length > 0).map((m) => m.path));
|
|
164
168
|
}
|
|
165
169
|
//#endregion
|
|
166
|
-
//#region src/lib/
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
170
|
+
//#region src/lib/programs/revenue-analytics/steps.ts
|
|
171
|
+
const REVENUE_ANALYTICS_PROGRAM = [
|
|
172
|
+
{
|
|
173
|
+
id: "detect",
|
|
174
|
+
label: "Detecting prerequisites",
|
|
175
|
+
onReady: (ctx) => detectRevenuePrerequisites(ctx.session, ctx.setFrameworkContext)
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
id: "intro",
|
|
179
|
+
label: "Welcome",
|
|
180
|
+
screenId: "revenue-intro",
|
|
181
|
+
gate: (session) => session.setupConfirmed
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
id: "auth",
|
|
185
|
+
label: "Authentication",
|
|
186
|
+
screenId: "auth",
|
|
187
|
+
isComplete: (session) => session.credentials !== null
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
id: "run",
|
|
191
|
+
label: "Revenue analytics",
|
|
192
|
+
screenId: "run",
|
|
193
|
+
isComplete: (session) => session.runPhase === "completed" || session.runPhase === "error"
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
id: "outro",
|
|
197
|
+
label: "Done",
|
|
198
|
+
screenId: "outro",
|
|
199
|
+
isComplete: (session) => session.outroDismissed
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
id: "skills",
|
|
203
|
+
label: "Skills",
|
|
204
|
+
screenId: "keep-skills"
|
|
205
|
+
}
|
|
206
|
+
];
|
|
207
|
+
//#endregion
|
|
208
|
+
//#region src/lib/programs/agent-skill/content/index.tsx
|
|
209
|
+
/**
|
|
210
|
+
* Agent-skill learn-deck — the short three-line sequence shown while a
|
|
211
|
+
* skill-based program (audit, revenue-analytics, agent-skill, etc.)
|
|
212
|
+
* runs. Skill programs don't need the full PostHog onboarding narrative.
|
|
213
|
+
*/
|
|
214
|
+
const getContentBlocks$1 = (store) => {
|
|
215
|
+
return [
|
|
189
216
|
{
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
217
|
+
content: "Welcome.",
|
|
218
|
+
pause: 3e3,
|
|
219
|
+
mode: 0,
|
|
220
|
+
animationInterval: 160
|
|
194
221
|
},
|
|
195
222
|
{
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
screen: "outro",
|
|
199
|
-
isComplete: (session) => session.outroDismissed
|
|
223
|
+
content: "The Wizard is an agent.",
|
|
224
|
+
pause: 4e3
|
|
200
225
|
},
|
|
201
226
|
{
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
227
|
+
pause: 6e4,
|
|
228
|
+
content: /* @__PURE__ */ jsxs(Text, { children: [
|
|
229
|
+
"Running the ",
|
|
230
|
+
/* @__PURE__ */ jsx(Text, {
|
|
231
|
+
color: "cyan",
|
|
232
|
+
children: store?.session.skillId ?? "unknown"
|
|
233
|
+
}),
|
|
234
|
+
" skill..."
|
|
235
|
+
] })
|
|
205
236
|
}
|
|
206
|
-
]
|
|
237
|
+
];
|
|
238
|
+
};
|
|
239
|
+
//#endregion
|
|
240
|
+
//#region src/lib/programs/revenue-analytics/index.ts
|
|
241
|
+
const revenueAnalyticsConfig = {
|
|
242
|
+
command: "revenue",
|
|
243
|
+
description: "Set up PostHog revenue analytics (e.g. Stripe integration)",
|
|
244
|
+
id: "revenue-analytics-setup",
|
|
245
|
+
steps: REVENUE_ANALYTICS_PROGRAM,
|
|
246
|
+
getContentBlocks: getContentBlocks$1,
|
|
247
|
+
allowedTools: ["Agent"],
|
|
248
|
+
disallowedTools: [WIZARD_TOOL_NAMES.wizardAsk],
|
|
207
249
|
run: {
|
|
208
250
|
skillId: "revenue-analytics-setup",
|
|
209
251
|
integrationLabel: "revenue-analytics-setup",
|
|
@@ -218,48 +260,50 @@ const revenueAnalyticsConfig = {
|
|
|
218
260
|
requires: ["posthog-integration"]
|
|
219
261
|
};
|
|
220
262
|
//#endregion
|
|
221
|
-
//#region src/lib/
|
|
263
|
+
//#region src/lib/programs/agent-skill/steps.ts
|
|
222
264
|
const AGENT_SKILL_STEPS = [
|
|
223
265
|
{
|
|
224
266
|
id: "intro",
|
|
225
267
|
label: "Welcome",
|
|
226
|
-
|
|
268
|
+
screenId: "agent-skill-intro",
|
|
227
269
|
gate: (session) => session.setupConfirmed
|
|
228
270
|
},
|
|
229
271
|
{
|
|
230
272
|
id: "auth",
|
|
231
273
|
label: "Authentication",
|
|
232
|
-
|
|
274
|
+
screenId: "auth",
|
|
233
275
|
isComplete: (session) => session.credentials !== null
|
|
234
276
|
},
|
|
235
277
|
{
|
|
236
278
|
id: "run",
|
|
237
279
|
label: "Running",
|
|
238
|
-
|
|
280
|
+
screenId: "run",
|
|
239
281
|
isComplete: (session) => session.runPhase === "completed" || session.runPhase === "error"
|
|
240
282
|
},
|
|
241
283
|
{
|
|
242
284
|
id: "outro",
|
|
243
285
|
label: "Done",
|
|
244
|
-
|
|
286
|
+
screenId: "outro",
|
|
245
287
|
isComplete: (session) => session.outroDismissed
|
|
246
288
|
},
|
|
247
289
|
{
|
|
248
290
|
id: "skills",
|
|
249
291
|
label: "Skills",
|
|
250
|
-
|
|
292
|
+
screenId: "keep-skills"
|
|
251
293
|
}
|
|
252
294
|
];
|
|
253
295
|
//#endregion
|
|
254
|
-
//#region src/lib/
|
|
255
|
-
var agent_skill_exports = /* @__PURE__ */ __exportAll({
|
|
256
|
-
function
|
|
296
|
+
//#region src/lib/programs/agent-skill/index.ts
|
|
297
|
+
var agent_skill_exports = /* @__PURE__ */ __exportAll({ createSkillProgram: () => createSkillProgram });
|
|
298
|
+
function createSkillProgram(opts) {
|
|
257
299
|
return {
|
|
258
300
|
command: opts.command,
|
|
259
301
|
description: opts.description,
|
|
260
|
-
|
|
302
|
+
id: opts.id,
|
|
303
|
+
skillId: opts.skillId,
|
|
261
304
|
steps: AGENT_SKILL_STEPS,
|
|
262
305
|
reportFile: opts.reportFile,
|
|
306
|
+
getContentBlocks: getContentBlocks$1,
|
|
263
307
|
run: {
|
|
264
308
|
skillId: opts.skillId,
|
|
265
309
|
integrationLabel: opts.integrationLabel,
|
|
@@ -276,17 +320,17 @@ function createSkillWorkflow(opts) {
|
|
|
276
320
|
};
|
|
277
321
|
}
|
|
278
322
|
//#endregion
|
|
279
|
-
//#region src/lib/
|
|
323
|
+
//#region src/lib/programs/audit/detect.ts
|
|
280
324
|
/** `[ABORT] <reason>` cases the audit skill can emit. Reason strings are
|
|
281
325
|
* defined in the skill's `Abort statuses` section. */
|
|
282
326
|
const AUDIT_ABORT_CASES = [{
|
|
283
327
|
match: /^no posthog sdk found$/i,
|
|
284
328
|
message: "No PostHog SDK found",
|
|
285
|
-
body: "The audit needs an existing PostHog integration to review. No PostHog SDK appears in this project’s dependency manifests. Run the basic integration
|
|
329
|
+
body: "The audit needs an existing PostHog integration to review. No PostHog SDK appears in this project’s dependency manifests. Run the basic integration program to install PostHog first, then re-run the audit.",
|
|
286
330
|
docsUrl: "https://posthog.com/docs/getting-started/install"
|
|
287
331
|
}];
|
|
288
332
|
//#endregion
|
|
289
|
-
//#region src/lib/
|
|
333
|
+
//#region src/lib/programs/audit/seed.ts
|
|
290
334
|
/** The 10 data-integrity checks the audit runs. */
|
|
291
335
|
const AUDIT_SEED_CHECKS = [
|
|
292
336
|
{
|
|
@@ -359,7 +403,7 @@ function seedAuditLedger(installDir) {
|
|
|
359
403
|
logToFile(`seedAuditLedger: wrote ${AUDIT_SEED_CHECKS.length} entries to ${target}`);
|
|
360
404
|
}
|
|
361
405
|
//#endregion
|
|
362
|
-
//#region src/lib/
|
|
406
|
+
//#region src/lib/programs/audit/index.ts
|
|
363
407
|
/** Audit-specific screens for the shared agent-skill pipeline. */
|
|
364
408
|
const AUDIT_SCREEN_BY_STEP = {
|
|
365
409
|
intro: "audit-intro",
|
|
@@ -374,17 +418,17 @@ const withAuditScreens = (steps) => steps.map((step) => {
|
|
|
374
418
|
const override = AUDIT_SCREEN_BY_STEP[step.id];
|
|
375
419
|
return override ? {
|
|
376
420
|
...step,
|
|
377
|
-
|
|
421
|
+
screenId: override
|
|
378
422
|
} : step;
|
|
379
423
|
});
|
|
380
424
|
const auditSteps = withAuditScreens(AGENT_SKILL_STEPS);
|
|
381
|
-
const baseConfig$1 =
|
|
425
|
+
const baseConfig$1 = createSkillProgram({
|
|
382
426
|
skillId: "audit",
|
|
383
427
|
command: "audit",
|
|
384
|
-
|
|
428
|
+
id: "audit",
|
|
385
429
|
description: "Audit an existing PostHog integration for correctness and best practices",
|
|
386
430
|
integrationLabel: "audit",
|
|
387
|
-
customPrompt: "Run a comprehensive audit of the existing PostHog integration. Follow the skill
|
|
431
|
+
customPrompt: "Run a comprehensive audit of the existing PostHog integration. Follow the skill program steps in order. Do not modify any project files — only create the final audit report.",
|
|
388
432
|
successMessage: "Audit complete! You can view the audit report at ./posthog-audit-report.md",
|
|
389
433
|
reportFile: AUDIT_REPORT_FILE,
|
|
390
434
|
docsUrl: "https://posthog.com/docs/product-analytics/best-practices",
|
|
@@ -395,16 +439,148 @@ const baseConfig$1 = createSkillWorkflow({
|
|
|
395
439
|
});
|
|
396
440
|
const auditRun = async (session) => {
|
|
397
441
|
seedBeforeAuditRun(session);
|
|
398
|
-
if (!baseConfig$1.run) throw new Error("Audit
|
|
442
|
+
if (!baseConfig$1.run) throw new Error("Audit program has no run configuration.");
|
|
399
443
|
return typeof baseConfig$1.run === "function" ? baseConfig$1.run(session) : baseConfig$1.run;
|
|
400
444
|
};
|
|
401
445
|
const auditConfig = {
|
|
402
446
|
...baseConfig$1,
|
|
403
447
|
steps: auditSteps,
|
|
404
|
-
run: auditRun
|
|
448
|
+
run: auditRun,
|
|
449
|
+
allowedTools: ["Agent"],
|
|
450
|
+
disallowedTools: [WIZARD_TOOL_NAMES.wizardAsk]
|
|
451
|
+
};
|
|
452
|
+
//#endregion
|
|
453
|
+
//#region src/lib/programs/events-audit/steps.ts
|
|
454
|
+
function needsSetup(session) {
|
|
455
|
+
const config = session.frameworkConfig;
|
|
456
|
+
if (!config?.metadata.setup?.questions) return false;
|
|
457
|
+
return config.metadata.setup.questions.some((q) => !(q.key in session.frameworkContext));
|
|
458
|
+
}
|
|
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
|
+
const EVENTS_AUDIT_PROGRAM = [
|
|
471
|
+
{
|
|
472
|
+
id: "intro",
|
|
473
|
+
label: "Welcome",
|
|
474
|
+
screenId: "audit-intro",
|
|
475
|
+
gate: (session) => session.setupConfirmed
|
|
476
|
+
},
|
|
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
|
+
},
|
|
494
|
+
{
|
|
495
|
+
id: "setup",
|
|
496
|
+
label: "Setup",
|
|
497
|
+
screenId: "setup",
|
|
498
|
+
show: needsSetup,
|
|
499
|
+
isComplete: (session) => !needsSetup(session)
|
|
500
|
+
},
|
|
501
|
+
{
|
|
502
|
+
id: "auth",
|
|
503
|
+
label: "Authentication",
|
|
504
|
+
screenId: "auth",
|
|
505
|
+
isComplete: (session) => session.credentials !== null
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
id: "run",
|
|
509
|
+
label: "Events audit",
|
|
510
|
+
screenId: "audit-run",
|
|
511
|
+
isComplete: (session) => session.runPhase === "completed" || session.runPhase === "error"
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
id: "mcp",
|
|
515
|
+
label: "MCP servers",
|
|
516
|
+
screenId: "mcp",
|
|
517
|
+
isComplete: (session) => session.mcpComplete
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
id: "outro",
|
|
521
|
+
label: "Done",
|
|
522
|
+
screenId: "audit-outro",
|
|
523
|
+
isComplete: (session) => session.outroDismissed
|
|
524
|
+
},
|
|
525
|
+
{
|
|
526
|
+
id: "keep-skills",
|
|
527
|
+
label: "Keep Skills",
|
|
528
|
+
screenId: "keep-skills"
|
|
529
|
+
}
|
|
530
|
+
];
|
|
531
|
+
//#endregion
|
|
532
|
+
//#region src/lib/programs/events-audit/index.ts
|
|
533
|
+
const SETUP_REPORT_FILE = "posthog-events-audit-report.md";
|
|
534
|
+
const DOCS_URL = "https://posthog.com/docs/product-analytics/best-practices";
|
|
535
|
+
const eventsAuditConfig = {
|
|
536
|
+
command: "events-audit",
|
|
537
|
+
description: "Audit PostHog event tracking in this project",
|
|
538
|
+
id: "events-audit",
|
|
539
|
+
skillId: "events-audit",
|
|
540
|
+
steps: EVENTS_AUDIT_PROGRAM,
|
|
541
|
+
reportFile: SETUP_REPORT_FILE,
|
|
542
|
+
allowedTools: ["Agent"],
|
|
543
|
+
disallowedTools: [WIZARD_TOOL_NAMES.wizardAsk],
|
|
544
|
+
run: (session) => {
|
|
545
|
+
const typeScriptDetected = isUsingTypeScript({ installDir: session.installDir });
|
|
546
|
+
session.typescript = typeScriptDetected;
|
|
547
|
+
seedAuditLedger(session.installDir);
|
|
548
|
+
session.frameworkContext[AUDIT_CHECKS_KEY] = AUDIT_SEED_CHECKS;
|
|
549
|
+
return Promise.resolve({
|
|
550
|
+
skillId: "events-audit",
|
|
551
|
+
integrationLabel: "events-audit",
|
|
552
|
+
spinnerMessage: SPINNER_MESSAGE,
|
|
553
|
+
successMessage: "Events audit complete! You can view the report at ./posthog-events-audit-report.md",
|
|
554
|
+
estimatedDurationMinutes: 5,
|
|
555
|
+
reportFile: SETUP_REPORT_FILE,
|
|
556
|
+
docsUrl: DOCS_URL,
|
|
557
|
+
errorMessage: "Events audit failed",
|
|
558
|
+
additionalFeatureQueue: session.additionalFeatureQueue,
|
|
559
|
+
customPrompt: (ctx) => `Audit PostHog event capture in this project. Do not modify any project files — produce a read-only report only.
|
|
560
|
+
|
|
561
|
+
Project context:
|
|
562
|
+
- PostHog Project ID: ${ctx.projectId}
|
|
563
|
+
- TypeScript: ${typeScriptDetected ? "Yes" : "No"}
|
|
564
|
+
- PostHog public token: ${ctx.projectApiKey}
|
|
565
|
+
- PostHog Host: ${ctx.host}
|
|
566
|
+
`,
|
|
567
|
+
buildOutroData: (sess, _credentials, cloudRegion) => {
|
|
568
|
+
const cloudUrl = cloudRegion ? getCloudUrlFromRegion(cloudRegion) : void 0;
|
|
569
|
+
return {
|
|
570
|
+
kind: "success",
|
|
571
|
+
message: "Your events audit was successful",
|
|
572
|
+
reportFile: SETUP_REPORT_FILE,
|
|
573
|
+
changes: [],
|
|
574
|
+
docsUrl: DOCS_URL,
|
|
575
|
+
continueUrl: sess.signup && cloudUrl ? `${cloudUrl}/products?source=wizard` : void 0,
|
|
576
|
+
dashboardUrl: sess.dashboardUrl ?? (cloudUrl ? `${cloudUrl}/dashboard` : void 0)
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
}
|
|
405
581
|
};
|
|
406
582
|
//#endregion
|
|
407
|
-
//#region src/lib/
|
|
583
|
+
//#region src/lib/programs/audit-3000/index.ts
|
|
408
584
|
const AUDIT3000_REPORT_FILE = "posthog-audit-3000-report.md";
|
|
409
585
|
const AUDIT3000_EXTRA_CHECKS = [
|
|
410
586
|
{
|
|
@@ -573,14 +749,14 @@ const withAudit3000Screens = (steps) => steps.map((step) => {
|
|
|
573
749
|
const override = AUDIT3000_SCREEN_BY_STEP[step.id];
|
|
574
750
|
return override ? {
|
|
575
751
|
...step,
|
|
576
|
-
|
|
752
|
+
screenId: override
|
|
577
753
|
} : step;
|
|
578
754
|
});
|
|
579
755
|
const audit3000Steps = withAudit3000Screens(AGENT_SKILL_STEPS);
|
|
580
|
-
const baseConfig =
|
|
756
|
+
const baseConfig = createSkillProgram({
|
|
581
757
|
skillId: "audit-3000",
|
|
582
758
|
command: "audit-3000",
|
|
583
|
-
|
|
759
|
+
id: "audit-3000",
|
|
584
760
|
description: "Audit an existing PostHog integration (v3000 — adds event quality, stale-flag hygiene, customer enrichment, use-case match)",
|
|
585
761
|
integrationLabel: "audit-3000",
|
|
586
762
|
customPrompt: "Run the audit-3000 skill end-to-end. Follow the step chain starting at references/1-version.md. Do not modify any project files — only create the final audit report and (when enrichment is enabled) the enrichment report.",
|
|
@@ -594,44 +770,46 @@ const baseConfig = createSkillWorkflow({
|
|
|
594
770
|
});
|
|
595
771
|
const audit3000Run = async (session) => {
|
|
596
772
|
seedBeforeAudit3000Run(session);
|
|
597
|
-
if (!baseConfig.run) throw new Error("audit-3000
|
|
773
|
+
if (!baseConfig.run) throw new Error("audit-3000 program has no run configuration.");
|
|
598
774
|
return typeof baseConfig.run === "function" ? baseConfig.run(session) : baseConfig.run;
|
|
599
775
|
};
|
|
600
776
|
const audit3000Config = {
|
|
601
777
|
...baseConfig,
|
|
602
778
|
steps: audit3000Steps,
|
|
603
|
-
run: audit3000Run
|
|
779
|
+
run: audit3000Run,
|
|
780
|
+
allowedTools: ["Agent"],
|
|
781
|
+
disallowedTools: [WIZARD_TOOL_NAMES.wizardAsk]
|
|
604
782
|
};
|
|
605
783
|
//#endregion
|
|
606
|
-
//#region src/lib/
|
|
607
|
-
const
|
|
784
|
+
//#region src/lib/programs/posthog-doctor/steps.ts
|
|
785
|
+
const POSTHOG_DOCTOR_PROGRAM = [
|
|
608
786
|
{
|
|
609
787
|
id: "intro",
|
|
610
788
|
label: "Welcome",
|
|
611
|
-
|
|
789
|
+
screenId: "doctor-intro",
|
|
612
790
|
gate: (session) => session.setupConfirmed
|
|
613
791
|
},
|
|
614
792
|
{
|
|
615
793
|
id: "auth",
|
|
616
794
|
label: "Authentication",
|
|
617
|
-
|
|
795
|
+
screenId: "auth",
|
|
618
796
|
isComplete: (session) => session.credentials !== null
|
|
619
797
|
},
|
|
620
798
|
{
|
|
621
799
|
id: "report",
|
|
622
800
|
label: "Doctor report",
|
|
623
|
-
|
|
801
|
+
screenId: "doctor-report",
|
|
624
802
|
isComplete: (session) => session.outroData !== null
|
|
625
803
|
},
|
|
626
804
|
{
|
|
627
805
|
id: "outro",
|
|
628
806
|
label: "Done",
|
|
629
|
-
|
|
807
|
+
screenId: "outro",
|
|
630
808
|
isComplete: (session) => session.outroDismissed
|
|
631
809
|
}
|
|
632
810
|
];
|
|
633
811
|
//#endregion
|
|
634
|
-
//#region src/lib/
|
|
812
|
+
//#region src/lib/programs/posthog-doctor/types.ts
|
|
635
813
|
const HealthIssueSeveritySchema = z.enum([
|
|
636
814
|
"critical",
|
|
637
815
|
"warning",
|
|
@@ -655,7 +833,7 @@ const HealthIssueListResponseSchema = z.object({
|
|
|
655
833
|
previous: z.string().nullable().optional()
|
|
656
834
|
});
|
|
657
835
|
//#endregion
|
|
658
|
-
//#region src/lib/
|
|
836
|
+
//#region src/lib/programs/posthog-doctor/fetch.ts
|
|
659
837
|
async function fetchHealthIssues(accessToken, baseUrl, projectId) {
|
|
660
838
|
const endpoint = `/api/environments/${projectId}/health_issues/`;
|
|
661
839
|
const url = `${baseUrl}${endpoint}?status=active&dismissed=false&limit=250`;
|
|
@@ -676,7 +854,7 @@ async function fetchHealthIssues(accessToken, baseUrl, projectId) {
|
|
|
676
854
|
}
|
|
677
855
|
}
|
|
678
856
|
//#endregion
|
|
679
|
-
//#region src/lib/
|
|
857
|
+
//#region src/lib/programs/posthog-doctor/kind-metadata.ts
|
|
680
858
|
const KIND_METADATA = {
|
|
681
859
|
ingestion_lag: {
|
|
682
860
|
title: "Ingestion is delayed",
|
|
@@ -746,36 +924,649 @@ function getKindMeta(kind) {
|
|
|
746
924
|
};
|
|
747
925
|
}
|
|
748
926
|
//#endregion
|
|
749
|
-
//#region src/lib/
|
|
750
|
-
const
|
|
927
|
+
//#region src/lib/programs/posthog-doctor/index.ts
|
|
928
|
+
const posthogDoctorConfig = {
|
|
929
|
+
command: "doctor",
|
|
930
|
+
description: "Diagnose your PostHog project for configuration issues and setup warnings",
|
|
931
|
+
id: "posthog-doctor",
|
|
932
|
+
steps: POSTHOG_DOCTOR_PROGRAM,
|
|
933
|
+
allowedTools: ["Agent"],
|
|
934
|
+
disallowedTools: [WIZARD_TOOL_NAMES.wizardAsk]
|
|
935
|
+
};
|
|
936
|
+
//#endregion
|
|
937
|
+
//#region src/lib/programs/migration/steps.ts
|
|
938
|
+
const MIGRATION_PROGRAM = [
|
|
939
|
+
{
|
|
940
|
+
id: "intro",
|
|
941
|
+
label: "Welcome",
|
|
942
|
+
screenId: "migration-intro",
|
|
943
|
+
gate: (session) => session.setupConfirmed
|
|
944
|
+
},
|
|
945
|
+
{
|
|
946
|
+
id: "auth",
|
|
947
|
+
label: "Authentication",
|
|
948
|
+
screenId: "auth",
|
|
949
|
+
isComplete: (session) => session.credentials !== null
|
|
950
|
+
},
|
|
951
|
+
{
|
|
952
|
+
id: "run",
|
|
953
|
+
label: "Migration",
|
|
954
|
+
screenId: "run",
|
|
955
|
+
isComplete: (session) => session.runPhase === "completed" || session.runPhase === "error"
|
|
956
|
+
},
|
|
957
|
+
{
|
|
958
|
+
id: "outro",
|
|
959
|
+
label: "Done",
|
|
960
|
+
screenId: "outro",
|
|
961
|
+
isComplete: (session) => session.outroDismissed
|
|
962
|
+
},
|
|
963
|
+
{
|
|
964
|
+
id: "skills",
|
|
965
|
+
label: "Skills",
|
|
966
|
+
screenId: "keep-skills"
|
|
967
|
+
}
|
|
968
|
+
];
|
|
969
|
+
//#endregion
|
|
970
|
+
//#region src/lib/programs/migration/content/vendor-stack.tsx
|
|
971
|
+
/**
|
|
972
|
+
* Vendor cost stack — the multi-tool baseline a typical migration target has
|
|
973
|
+
* before consolidating onto PostHog. Numbers from each vendor's published
|
|
974
|
+
* starter pricing.
|
|
975
|
+
*/
|
|
976
|
+
const VENDOR_STACK_BLOCK = {
|
|
977
|
+
type: "lines",
|
|
978
|
+
interval: 600,
|
|
979
|
+
pause: 9e3,
|
|
980
|
+
lines: [
|
|
981
|
+
/* @__PURE__ */ jsx(Text, {
|
|
982
|
+
bold: true,
|
|
983
|
+
children: " Typical pre-migration stack"
|
|
984
|
+
}),
|
|
985
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
986
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
987
|
+
/* @__PURE__ */ jsx(Text, {
|
|
988
|
+
color: "gray",
|
|
989
|
+
children: " Sentry"
|
|
990
|
+
}),
|
|
991
|
+
/* @__PURE__ */ jsx(Text, { children: " error tracking " }),
|
|
992
|
+
/* @__PURE__ */ jsx(Text, {
|
|
993
|
+
color: "red",
|
|
994
|
+
children: "$26/mo+"
|
|
995
|
+
})
|
|
996
|
+
] }),
|
|
997
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
998
|
+
/* @__PURE__ */ jsx(Text, {
|
|
999
|
+
color: "gray",
|
|
1000
|
+
children: " LaunchDarkly"
|
|
1001
|
+
}),
|
|
1002
|
+
/* @__PURE__ */ jsx(Text, { children: " feature flags " }),
|
|
1003
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1004
|
+
color: "red",
|
|
1005
|
+
children: "$8.33/mo+"
|
|
1006
|
+
})
|
|
1007
|
+
] }),
|
|
1008
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
1009
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1010
|
+
color: "gray",
|
|
1011
|
+
children: " Amplitude"
|
|
1012
|
+
}),
|
|
1013
|
+
/* @__PURE__ */ jsx(Text, { children: " product analytics " }),
|
|
1014
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1015
|
+
color: "red",
|
|
1016
|
+
children: "$49/mo+"
|
|
1017
|
+
})
|
|
1018
|
+
] }),
|
|
1019
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
1020
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1021
|
+
color: "gray",
|
|
1022
|
+
children: " Braintrust"
|
|
1023
|
+
}),
|
|
1024
|
+
/* @__PURE__ */ jsx(Text, { children: " LLM analytics " }),
|
|
1025
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1026
|
+
color: "red",
|
|
1027
|
+
children: "$50/mo+"
|
|
1028
|
+
})
|
|
1029
|
+
] }),
|
|
1030
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1031
|
+
color: "gray",
|
|
1032
|
+
children: " ─────────────────────────────────────"
|
|
1033
|
+
}),
|
|
1034
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
1035
|
+
/* @__PURE__ */ jsx(Text, { children: " Total" }),
|
|
1036
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
1037
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1038
|
+
bold: true,
|
|
1039
|
+
color: "red",
|
|
1040
|
+
children: "$133/mo+"
|
|
1041
|
+
})
|
|
1042
|
+
] }),
|
|
1043
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1044
|
+
dimColor: true,
|
|
1045
|
+
children: " plus ~450KB of JavaScript SDKs"
|
|
1046
|
+
})
|
|
1047
|
+
]
|
|
1048
|
+
};
|
|
1049
|
+
//#endregion
|
|
1050
|
+
//#region src/lib/programs/migration/content/free-tier.tsx
|
|
1051
|
+
/**
|
|
1052
|
+
* PostHog free-tier highlights — the numbers a migrating team gets back when
|
|
1053
|
+
* they consolidate. Sourced from posthog.com/pricing.md.
|
|
1054
|
+
*/
|
|
1055
|
+
const FREE_TIER_BLOCK = {
|
|
1056
|
+
type: "lines",
|
|
1057
|
+
interval: 400,
|
|
1058
|
+
pause: 9e3,
|
|
1059
|
+
lines: [
|
|
1060
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1061
|
+
bold: true,
|
|
1062
|
+
children: " Free every month, on every product"
|
|
1063
|
+
}),
|
|
1064
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
1065
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
1066
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1067
|
+
color: Colors.accent,
|
|
1068
|
+
children: " 1,000,000 "
|
|
1069
|
+
}),
|
|
1070
|
+
/* @__PURE__ */ jsx(Text, { children: "events " }),
|
|
1071
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1072
|
+
dimColor: true,
|
|
1073
|
+
children: "product analytics"
|
|
1074
|
+
})
|
|
1075
|
+
] }),
|
|
1076
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
1077
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1078
|
+
color: Colors.accent,
|
|
1079
|
+
children: " 1,000,000 "
|
|
1080
|
+
}),
|
|
1081
|
+
/* @__PURE__ */ jsx(Text, { children: "requests " }),
|
|
1082
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1083
|
+
dimColor: true,
|
|
1084
|
+
children: "feature flags + experiments"
|
|
1085
|
+
})
|
|
1086
|
+
] }),
|
|
1087
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
1088
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1089
|
+
color: Colors.accent,
|
|
1090
|
+
children: " 5,000 "
|
|
1091
|
+
}),
|
|
1092
|
+
/* @__PURE__ */ jsx(Text, { children: "recordings " }),
|
|
1093
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1094
|
+
dimColor: true,
|
|
1095
|
+
children: "session replay"
|
|
1096
|
+
})
|
|
1097
|
+
] }),
|
|
1098
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
1099
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1100
|
+
color: Colors.accent,
|
|
1101
|
+
children: " 100,000 "
|
|
1102
|
+
}),
|
|
1103
|
+
/* @__PURE__ */ jsx(Text, { children: "exceptions " }),
|
|
1104
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1105
|
+
dimColor: true,
|
|
1106
|
+
children: "error tracking"
|
|
1107
|
+
})
|
|
1108
|
+
] }),
|
|
1109
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
1110
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1111
|
+
color: Colors.accent,
|
|
1112
|
+
children: " 100,000 "
|
|
1113
|
+
}),
|
|
1114
|
+
/* @__PURE__ */ jsx(Text, { children: "events " }),
|
|
1115
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1116
|
+
dimColor: true,
|
|
1117
|
+
children: "LLM analytics"
|
|
1118
|
+
})
|
|
1119
|
+
] }),
|
|
1120
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
1121
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1122
|
+
color: Colors.accent,
|
|
1123
|
+
children: " 50 GB "
|
|
1124
|
+
}),
|
|
1125
|
+
/* @__PURE__ */ jsx(Text, { children: "logs " }),
|
|
1126
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1127
|
+
dimColor: true,
|
|
1128
|
+
children: "logs"
|
|
1129
|
+
})
|
|
1130
|
+
] }),
|
|
1131
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
1132
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1133
|
+
color: Colors.accent,
|
|
1134
|
+
children: " 1,500 "
|
|
1135
|
+
}),
|
|
1136
|
+
/* @__PURE__ */ jsx(Text, { children: "responses " }),
|
|
1137
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1138
|
+
dimColor: true,
|
|
1139
|
+
children: "surveys"
|
|
1140
|
+
})
|
|
1141
|
+
] }),
|
|
1142
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
1143
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1144
|
+
color: Colors.accent,
|
|
1145
|
+
children: " 1,000,000 "
|
|
1146
|
+
}),
|
|
1147
|
+
/* @__PURE__ */ jsx(Text, { children: "rows " }),
|
|
1148
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1149
|
+
dimColor: true,
|
|
1150
|
+
children: "data warehouse"
|
|
1151
|
+
})
|
|
1152
|
+
] })
|
|
1153
|
+
]
|
|
1154
|
+
};
|
|
1155
|
+
//#endregion
|
|
1156
|
+
//#region src/lib/programs/migration/content/pricing-structure.tsx
|
|
1157
|
+
/**
|
|
1158
|
+
* Pricing structure block — what happens after the free tier.
|
|
1159
|
+
*/
|
|
1160
|
+
const PRICING_STRUCTURE_BLOCK = {
|
|
1161
|
+
type: "lines",
|
|
1162
|
+
interval: 500,
|
|
1163
|
+
pause: 8e3,
|
|
1164
|
+
lines: [
|
|
1165
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1166
|
+
bold: true,
|
|
1167
|
+
children: " After the free tier"
|
|
1168
|
+
}),
|
|
1169
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
1170
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
1171
|
+
color: Colors.accent,
|
|
1172
|
+
children: " $0 "
|
|
1173
|
+
}), /* @__PURE__ */ jsx(Text, { children: "base price · pay only for what you use" })] }),
|
|
1174
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
1175
|
+
color: Colors.accent,
|
|
1176
|
+
children: " ◆ "
|
|
1177
|
+
}), /* @__PURE__ */ jsx(Text, { children: "per-event prices decrease with volume" })] }),
|
|
1178
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
1179
|
+
color: Colors.accent,
|
|
1180
|
+
children: " ◆ "
|
|
1181
|
+
}), /* @__PURE__ */ jsx(Text, { children: "no per-seat charges — your whole team is included" })] }),
|
|
1182
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
1183
|
+
color: Colors.accent,
|
|
1184
|
+
children: " ◆ "
|
|
1185
|
+
}), /* @__PURE__ */ jsx(Text, { children: "web analytics bundled with product analytics" })] }),
|
|
1186
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
1187
|
+
color: Colors.accent,
|
|
1188
|
+
children: " ◆ "
|
|
1189
|
+
}), /* @__PURE__ */ jsx(Text, { children: "experiments bundled with feature flags" })] }),
|
|
1190
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
1191
|
+
color: Colors.accent,
|
|
1192
|
+
children: " ◆ "
|
|
1193
|
+
}), /* @__PURE__ */ jsx(Text, { children: "revenue analytics bundled with data warehouse" })] })
|
|
1194
|
+
]
|
|
1195
|
+
};
|
|
1196
|
+
//#endregion
|
|
1197
|
+
//#region src/lib/programs/migration/content/index.tsx
|
|
1198
|
+
/**
|
|
1199
|
+
* Migration learn deck (statsig variant). Statsig is the only `migrate`
|
|
1200
|
+
* variant today, so this deck plays as-is when the wizard runs
|
|
1201
|
+
* `migrate --product=statsig`. Three movements:
|
|
1202
|
+
*
|
|
1203
|
+
* 1. Welcome and reassure.
|
|
1204
|
+
* 2. What to expect — the migration is replacement-only, takes a few
|
|
1205
|
+
* minutes, leaves the build green.
|
|
1206
|
+
* 3. What's a little different — how flags and experiments work in
|
|
1207
|
+
* PostHog, presented as right-way guidance rather than gotchas.
|
|
1208
|
+
*
|
|
1209
|
+
* FF/experiments guidance paraphrased from PostHog public docs:
|
|
1210
|
+
* - posthog.com/docs/feature-flags/best-practices
|
|
1211
|
+
* - posthog.com/docs/feature-flags/common-questions
|
|
1212
|
+
* - posthog.com/docs/experiments/best-practices
|
|
1213
|
+
*/
|
|
1214
|
+
const getContentBlocks = (store) => [
|
|
1215
|
+
{
|
|
1216
|
+
content: "Hello.",
|
|
1217
|
+
pause: 3e3,
|
|
1218
|
+
mode: 0,
|
|
1219
|
+
animationInterval: 160
|
|
1220
|
+
},
|
|
1221
|
+
{
|
|
1222
|
+
content: "The Wizard is an agent.",
|
|
1223
|
+
pause: 4e3
|
|
1224
|
+
},
|
|
1225
|
+
{
|
|
1226
|
+
content: "As we speak, it’s making a plan to migrate from Statsig to PostHog.",
|
|
1227
|
+
pause: 6e3
|
|
1228
|
+
},
|
|
1229
|
+
{
|
|
1230
|
+
content: "PostHog covers the cost of running this agent.",
|
|
1231
|
+
pause: 4e3
|
|
1232
|
+
},
|
|
1233
|
+
{
|
|
1234
|
+
type: "clear",
|
|
1235
|
+
pause: 2e3
|
|
1236
|
+
},
|
|
1237
|
+
{
|
|
1238
|
+
pause: 5e3,
|
|
1239
|
+
persist: true,
|
|
1240
|
+
content: /* @__PURE__ */ jsx(StatusPeekTrigger, { store })
|
|
1241
|
+
},
|
|
1242
|
+
{
|
|
1243
|
+
pause: 6e3,
|
|
1244
|
+
persist: true,
|
|
1245
|
+
content: /* @__PURE__ */ jsxs(Text, { children: [
|
|
1246
|
+
"Press",
|
|
1247
|
+
" ",
|
|
1248
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1249
|
+
color: Colors.accent,
|
|
1250
|
+
bold: true,
|
|
1251
|
+
children: "S"
|
|
1252
|
+
}),
|
|
1253
|
+
" ",
|
|
1254
|
+
"to expand or collapse the status."
|
|
1255
|
+
] })
|
|
1256
|
+
},
|
|
1257
|
+
{
|
|
1258
|
+
type: "clear",
|
|
1259
|
+
pause: 2e3
|
|
1260
|
+
},
|
|
1261
|
+
{
|
|
1262
|
+
content: "Here’s what to expect.",
|
|
1263
|
+
pause: 3e3
|
|
1264
|
+
},
|
|
1265
|
+
{
|
|
1266
|
+
content: "The migration takes about ten minutes.",
|
|
1267
|
+
pause: 3e3
|
|
1268
|
+
},
|
|
1269
|
+
{
|
|
1270
|
+
content: "Every Statsig call gets replaced in place with its PostHog equivalent.",
|
|
1271
|
+
pause: 5500
|
|
1272
|
+
},
|
|
1273
|
+
{
|
|
1274
|
+
content: "Nothing new gets added. No extra captures, no surprise instrumentation.",
|
|
1275
|
+
pause: 5500
|
|
1276
|
+
},
|
|
1277
|
+
{
|
|
1278
|
+
content: "The Statsig package gets removed at the end. We’ll run build and lint to clean up after ourselves.",
|
|
1279
|
+
pause: 6500
|
|
1280
|
+
},
|
|
1281
|
+
{
|
|
1282
|
+
type: "clear",
|
|
1283
|
+
pause: 2e3
|
|
1284
|
+
},
|
|
1285
|
+
{
|
|
1286
|
+
content: "A few things work a little differently in PostHog.",
|
|
1287
|
+
pause: 4500
|
|
1288
|
+
},
|
|
1289
|
+
{
|
|
1290
|
+
content: /* @__PURE__ */ jsxs(Text, { children: [
|
|
1291
|
+
"Flags evaluate against a stable user. Call",
|
|
1292
|
+
" ",
|
|
1293
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1294
|
+
bold: true,
|
|
1295
|
+
color: Colors.accent,
|
|
1296
|
+
children: "identify()"
|
|
1297
|
+
}),
|
|
1298
|
+
" ",
|
|
1299
|
+
"first, then check the flag."
|
|
1300
|
+
] }),
|
|
1301
|
+
pause: 6e3,
|
|
1302
|
+
persist: true
|
|
1303
|
+
},
|
|
1304
|
+
{
|
|
1305
|
+
content: "For anything in the first paint, evaluate server-side and bootstrap the values into the client.",
|
|
1306
|
+
pause: 6500
|
|
1307
|
+
},
|
|
1308
|
+
{
|
|
1309
|
+
content: /* @__PURE__ */ jsxs(Text, { children: [
|
|
1310
|
+
"In production, route requests through a reverse proxy to avoid ad blockers breaking your flags.",
|
|
1311
|
+
"\n",
|
|
1312
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1313
|
+
dimColor: true,
|
|
1314
|
+
children: "https://posthog.com/docs/advanced/proxy"
|
|
1315
|
+
})
|
|
1316
|
+
] }),
|
|
1317
|
+
pause: 6500,
|
|
1318
|
+
persist: true
|
|
1319
|
+
},
|
|
1320
|
+
{
|
|
1321
|
+
content: "When a flag reaches 100% rollout, retire it. Flags are signals, not switches.",
|
|
1322
|
+
pause: 5500
|
|
1323
|
+
},
|
|
1324
|
+
{
|
|
1325
|
+
content: /* @__PURE__ */ jsxs(Text, { children: [
|
|
1326
|
+
"Name flags descriptively. No double negatives. Reflect the return type.",
|
|
1327
|
+
" ",
|
|
1328
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1329
|
+
dimColor: true,
|
|
1330
|
+
children: "For example "
|
|
1331
|
+
}),
|
|
1332
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1333
|
+
bold: true,
|
|
1334
|
+
children: "show-new-checkout"
|
|
1335
|
+
}),
|
|
1336
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1337
|
+
dimColor: true,
|
|
1338
|
+
children: "."
|
|
1339
|
+
})
|
|
1340
|
+
] }),
|
|
1341
|
+
pause: 6500,
|
|
1342
|
+
persist: true
|
|
1343
|
+
},
|
|
1344
|
+
{
|
|
1345
|
+
type: "clear",
|
|
1346
|
+
pause: 1500
|
|
1347
|
+
},
|
|
1348
|
+
{
|
|
1349
|
+
content: /* @__PURE__ */ jsx(Text, {
|
|
1350
|
+
bold: true,
|
|
1351
|
+
color: Colors.accent,
|
|
1352
|
+
children: "Experiments"
|
|
1353
|
+
}),
|
|
1354
|
+
pause: 2500,
|
|
1355
|
+
persist: true
|
|
1356
|
+
},
|
|
1357
|
+
{
|
|
1358
|
+
content: "Change one thing per variant. Multiple changes in one variant blur the result.",
|
|
1359
|
+
pause: 5500
|
|
1360
|
+
},
|
|
1361
|
+
{
|
|
1362
|
+
content: "Decide the running time up front. PostHog includes a sample-size and duration calculator in the setup flow.",
|
|
1363
|
+
pause: 6500
|
|
1364
|
+
},
|
|
1365
|
+
{
|
|
1366
|
+
content: "Roll out to 5–10% first. Watch the metrics. Then increase.",
|
|
1367
|
+
pause: 5e3
|
|
1368
|
+
},
|
|
1369
|
+
{
|
|
1370
|
+
content: "Exclude users who already completed the flow. They can’t be affected by the test.",
|
|
1371
|
+
pause: 5500
|
|
1372
|
+
},
|
|
1373
|
+
{
|
|
1374
|
+
type: "clear",
|
|
1375
|
+
pause: 1500
|
|
1376
|
+
},
|
|
1377
|
+
{
|
|
1378
|
+
content: "Flags and experiments live alongside the rest of your data.",
|
|
1379
|
+
pause: 4500
|
|
1380
|
+
},
|
|
1381
|
+
{
|
|
1382
|
+
content: "Ship behind a flag, watch replays, check analytics for impact.",
|
|
1383
|
+
pause: 4500
|
|
1384
|
+
},
|
|
1385
|
+
{
|
|
1386
|
+
type: "clear",
|
|
1387
|
+
pause: 1500
|
|
1388
|
+
},
|
|
1389
|
+
{
|
|
1390
|
+
content: "PostHog also provides every other analytics and AI tool to build your product.",
|
|
1391
|
+
pause: 4500
|
|
1392
|
+
},
|
|
1393
|
+
PRODUCT_SUITE_BLOCK,
|
|
1394
|
+
{
|
|
1395
|
+
type: "clear",
|
|
1396
|
+
pause: 1500
|
|
1397
|
+
},
|
|
1398
|
+
{
|
|
1399
|
+
content: "And consolidating onto one platform saves real money.",
|
|
1400
|
+
pause: 4500
|
|
1401
|
+
},
|
|
1402
|
+
{
|
|
1403
|
+
content: "Here’s the math.",
|
|
1404
|
+
pause: 1500
|
|
1405
|
+
},
|
|
1406
|
+
VENDOR_STACK_BLOCK,
|
|
1407
|
+
{
|
|
1408
|
+
type: "clear",
|
|
1409
|
+
pause: 1500
|
|
1410
|
+
},
|
|
1411
|
+
{
|
|
1412
|
+
content: "Pricing is usage-based, with a generous free tier.",
|
|
1413
|
+
pause: 4e3
|
|
1414
|
+
},
|
|
1415
|
+
FREE_TIER_BLOCK,
|
|
1416
|
+
{
|
|
1417
|
+
type: "clear",
|
|
1418
|
+
pause: 1500
|
|
1419
|
+
},
|
|
1420
|
+
PRICING_STRUCTURE_BLOCK,
|
|
1421
|
+
{
|
|
1422
|
+
type: "clear",
|
|
1423
|
+
pause: 1500
|
|
1424
|
+
},
|
|
1425
|
+
{
|
|
1426
|
+
content: "Gain clarity and really understand your users.",
|
|
1427
|
+
pause: 4e3
|
|
1428
|
+
},
|
|
1429
|
+
{
|
|
1430
|
+
content: "Use trends to measure growth.",
|
|
1431
|
+
pause: 2500
|
|
1432
|
+
},
|
|
1433
|
+
LINE_CHART_BLOCK,
|
|
1434
|
+
{
|
|
1435
|
+
type: "clear",
|
|
1436
|
+
pause: 500
|
|
1437
|
+
},
|
|
1438
|
+
{
|
|
1439
|
+
content: "Use funnels to reveal bottlenecks.",
|
|
1440
|
+
pause: 2500
|
|
1441
|
+
},
|
|
1442
|
+
FUNNEL_BLOCK
|
|
1443
|
+
];
|
|
1444
|
+
//#endregion
|
|
1445
|
+
//#region src/lib/programs/migration/index.ts
|
|
1446
|
+
const MIGRATION_REPORT_FILE = "migration-report.md";
|
|
1447
|
+
const MIGRATION_ABORT_CASES = [{
|
|
1448
|
+
match: /^no source-sdk calls found$/i,
|
|
1449
|
+
message: "No source-SDK calls found",
|
|
1450
|
+
body: "The migration needs an existing third-party SDK to migrate from. No calls to the source SDK appear anywhere in this project. If you haven't installed PostHog yet, you don't need this command — run `npx @posthog/wizard@latest` to add PostHog from scratch."
|
|
1451
|
+
}];
|
|
1452
|
+
/**
|
|
1453
|
+
* Map each `--product=<id>` choice to the context-mill skill ID that handles
|
|
1454
|
+
* it. Adding a variant: drop a new row here. The CLI `choices` and the
|
|
1455
|
+
* runtime lookup both read from this map, so the two stay in sync.
|
|
1456
|
+
*/
|
|
1457
|
+
const PRODUCT_TO_SKILL_ID = { statsig: "migrate-statsig" };
|
|
1458
|
+
const MIGRATE_PRODUCTS = Object.keys(PRODUCT_TO_SKILL_ID);
|
|
1459
|
+
const migrationConfig = {
|
|
1460
|
+
command: "migrate",
|
|
1461
|
+
description: "Migrate to PostHog from another analytics provider",
|
|
1462
|
+
id: "migration",
|
|
1463
|
+
skillId: PRODUCT_TO_SKILL_ID.statsig,
|
|
1464
|
+
steps: MIGRATION_PROGRAM,
|
|
1465
|
+
reportFile: MIGRATION_REPORT_FILE,
|
|
1466
|
+
getContentBlocks,
|
|
1467
|
+
allowedTools: ["Agent"],
|
|
1468
|
+
disallowedTools: [WIZARD_TOOL_NAMES.wizardAsk],
|
|
1469
|
+
cliOptions: { product: {
|
|
1470
|
+
describe: "Source SDK to migrate from",
|
|
1471
|
+
type: "string",
|
|
1472
|
+
choices: MIGRATE_PRODUCTS,
|
|
1473
|
+
demandOption: true
|
|
1474
|
+
} },
|
|
1475
|
+
mapCliOptions: (argv) => ({ skillId: PRODUCT_TO_SKILL_ID[argv.product] }),
|
|
1476
|
+
run: {
|
|
1477
|
+
skillId: PRODUCT_TO_SKILL_ID.statsig,
|
|
1478
|
+
integrationLabel: "migration",
|
|
1479
|
+
customPrompt: () => `Migrate this project from its existing third-party analytics, feature-flag, and observability tools to PostHog. Run the \`migrate\` skill end-to-end: follow the step chain starting at references/1-presence.md. Only replace existing source-SDK call sites with PostHog equivalents — make zero unrelated changes and no net-new instrumentation. The final report is written to ./${MIGRATION_REPORT_FILE}.`,
|
|
1480
|
+
successMessage: `Migration complete! View the report at ./${MIGRATION_REPORT_FILE}`,
|
|
1481
|
+
reportFile: MIGRATION_REPORT_FILE,
|
|
1482
|
+
docsUrl: "",
|
|
1483
|
+
spinnerMessage: "Migrating to PostHog...",
|
|
1484
|
+
estimatedDurationMinutes: 8,
|
|
1485
|
+
abortCases: MIGRATION_ABORT_CASES
|
|
1486
|
+
},
|
|
1487
|
+
requires: ["posthog-integration"]
|
|
1488
|
+
};
|
|
1489
|
+
//#endregion
|
|
1490
|
+
//#region src/lib/programs/mcp/index.ts
|
|
1491
|
+
const mcpAddConfig = {
|
|
1492
|
+
id: "mcp-add",
|
|
1493
|
+
description: "Add PostHog MCP server to supported clients",
|
|
1494
|
+
steps: [{
|
|
1495
|
+
id: "mcp-add",
|
|
1496
|
+
label: "Add MCP server",
|
|
1497
|
+
screenId: "mcp-add",
|
|
1498
|
+
isComplete: (s) => s.mcpComplete
|
|
1499
|
+
}]
|
|
1500
|
+
};
|
|
1501
|
+
const mcpRemoveConfig = {
|
|
1502
|
+
id: "mcp-remove",
|
|
1503
|
+
description: "Remove PostHog MCP server from supported clients",
|
|
1504
|
+
steps: [{
|
|
1505
|
+
id: "mcp-remove",
|
|
1506
|
+
label: "Remove MCP server",
|
|
1507
|
+
screenId: "mcp-remove",
|
|
1508
|
+
isComplete: (s) => s.mcpComplete
|
|
1509
|
+
}]
|
|
1510
|
+
};
|
|
1511
|
+
//#endregion
|
|
1512
|
+
//#region src/lib/programs/program-registry.ts
|
|
1513
|
+
const agentSkillConfig = {
|
|
1514
|
+
id: "agent-skill",
|
|
1515
|
+
description: "Run an arbitrary context-mill skill",
|
|
1516
|
+
steps: AGENT_SKILL_STEPS,
|
|
1517
|
+
getContentBlocks: getContentBlocks$1,
|
|
1518
|
+
allowedTools: ["Agent"]
|
|
1519
|
+
};
|
|
1520
|
+
const PROGRAM_REGISTRY = [
|
|
751
1521
|
posthogIntegrationConfig,
|
|
752
1522
|
revenueAnalyticsConfig,
|
|
753
1523
|
auditConfig,
|
|
1524
|
+
eventsAuditConfig,
|
|
754
1525
|
audit3000Config,
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
}
|
|
1526
|
+
posthogDoctorConfig,
|
|
1527
|
+
migrationConfig,
|
|
1528
|
+
agentSkillConfig,
|
|
1529
|
+
mcpAddConfig,
|
|
1530
|
+
mcpRemoveConfig
|
|
761
1531
|
];
|
|
762
|
-
/**
|
|
763
|
-
|
|
764
|
-
|
|
1532
|
+
/**
|
|
1533
|
+
* Typed program names. Values come from each config's `id`, so there's
|
|
1534
|
+
* no parallel string list to keep in sync — adding `Program.Foo` here is
|
|
1535
|
+
* just exposing `fooConfig.id` under a friendly name for call sites.
|
|
1536
|
+
*/
|
|
1537
|
+
const Program = {
|
|
1538
|
+
PostHogIntegration: posthogIntegrationConfig.id,
|
|
1539
|
+
RevenueAnalyticsSetup: revenueAnalyticsConfig.id,
|
|
1540
|
+
Migration: migrationConfig.id,
|
|
1541
|
+
Audit: auditConfig.id,
|
|
1542
|
+
EventsAudit: eventsAuditConfig.id,
|
|
1543
|
+
Audit3000: audit3000Config.id,
|
|
1544
|
+
PosthogDoctor: posthogDoctorConfig.id,
|
|
1545
|
+
AgentSkill: agentSkillConfig.id,
|
|
1546
|
+
McpAdd: mcpAddConfig.id,
|
|
1547
|
+
McpRemove: mcpRemoveConfig.id
|
|
1548
|
+
};
|
|
1549
|
+
/**
|
|
1550
|
+
* Look up a program config by its id. `ProgramId` is a union of every
|
|
1551
|
+
* registered id, so the lookup is statically guaranteed to find a match
|
|
1552
|
+
* — the `!` is a load-bearing assertion of that invariant, not a hope.
|
|
1553
|
+
*/
|
|
1554
|
+
function getProgramConfig(id) {
|
|
1555
|
+
return PROGRAM_REGISTRY.find((c) => c.id === id);
|
|
765
1556
|
}
|
|
766
|
-
/** All
|
|
767
|
-
function
|
|
768
|
-
return
|
|
1557
|
+
/** All program configs that are exposed as CLI subcommands. */
|
|
1558
|
+
function getSubcommandPrograms() {
|
|
1559
|
+
return PROGRAM_REGISTRY.filter((c) => c.command != null);
|
|
769
1560
|
}
|
|
770
1561
|
//#endregion
|
|
771
1562
|
//#region bin.ts
|
|
772
1563
|
const WIZARD_VERSION = VERSION;
|
|
773
1564
|
const NODE_VERSION_RANGE = ">=18.17.0";
|
|
774
1565
|
if (!satisfies(process.version, NODE_VERSION_RANGE)) {
|
|
775
|
-
|
|
1566
|
+
console.log(`PostHog wizard requires Node.js ${NODE_VERSION_RANGE}. You are using Node.js ${process.version}. Please upgrade your Node.js version.`);
|
|
776
1567
|
process.exit(1);
|
|
777
1568
|
}
|
|
778
|
-
/** Shared yargs options for skill-based
|
|
1569
|
+
/** Shared yargs options for skill-based program subcommands. */
|
|
779
1570
|
const skillSubcommandOptions = {
|
|
780
1571
|
debug: {
|
|
781
1572
|
default: false,
|
|
@@ -925,12 +1716,24 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
925
1716
|
process.exit(1);
|
|
926
1717
|
return;
|
|
927
1718
|
}
|
|
1719
|
+
if (options.apiKey) {
|
|
1720
|
+
const apiKeyValue = String(options.apiKey);
|
|
1721
|
+
if (!apiKeyValue.startsWith("phx_")) {
|
|
1722
|
+
setUI(new LoggingUI());
|
|
1723
|
+
getUI().intro("PostHog Wizard");
|
|
1724
|
+
const prefix = apiKeyValue.slice(0, 4);
|
|
1725
|
+
let hint = "";
|
|
1726
|
+
if (prefix === "pha_") hint = " (pha_ is an OAuth access token — CI mode expects a personal API key)";
|
|
1727
|
+
else if (prefix === "phc_") hint = " (phc_ is a project/client key — CI mode expects a personal API key)";
|
|
1728
|
+
getUI().log.warn(`--api-key does not start with "phx_"${hint}. Continuing anyway, but the LLM Gateway may reject it with a 401.`);
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
928
1731
|
(async () => {
|
|
929
1732
|
if (!options.apiKey && options.signup) {
|
|
930
1733
|
setUI(new LoggingUI());
|
|
931
1734
|
getUI().intro("PostHog Wizard");
|
|
932
1735
|
try {
|
|
933
|
-
const { provisionNewAccount } = await import("./provisioning-
|
|
1736
|
+
const { provisionNewAccount } = await import("./provisioning-ByWo5KcQ.js");
|
|
934
1737
|
const signupRegion = options.region.toUpperCase();
|
|
935
1738
|
getUI().log.info(`Provisioning new PostHog account for ${String(options.email)} in ${signupRegion}...`);
|
|
936
1739
|
const result = await provisionNewAccount(options.email, options.name ?? "", signupRegion);
|
|
@@ -952,11 +1755,11 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
952
1755
|
return;
|
|
953
1756
|
}
|
|
954
1757
|
}
|
|
955
|
-
const { posthogIntegrationConfig } = await import("./posthog-integration-
|
|
956
|
-
const { FRAMEWORK_REGISTRY } = await import("./registry-
|
|
957
|
-
const { detectFramework, gatherFrameworkContext } = await import("./detection-
|
|
958
|
-
const { analytics } = await import("./analytics-
|
|
959
|
-
const { wizardAbort } = await import("./wizard-abort-
|
|
1758
|
+
const { posthogIntegrationConfig } = await import("./posthog-integration-C-FFV5ny.js").then((n) => n.r);
|
|
1759
|
+
const { FRAMEWORK_REGISTRY } = await import("./registry-B92uyoWK.js").then((n) => n.n);
|
|
1760
|
+
const { detectFramework, gatherFrameworkContext } = await import("./detection-D651Eb5k.js").then((n) => n.t);
|
|
1761
|
+
const { analytics } = await import("./analytics-tslsXyf9.js");
|
|
1762
|
+
const { wizardAbort } = await import("./wizard-abort-BTBccRto.js");
|
|
960
1763
|
runWizardCI(posthogIntegrationConfig, options, async (session) => {
|
|
961
1764
|
const integration = session.integration ?? await detectFramework(session.installDir);
|
|
962
1765
|
if (!integration) {
|
|
@@ -989,16 +1792,16 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
989
1792
|
getUI().log.error("This installer requires an interactive terminal (TTY) to run.\nIt appears you are running in a non-interactive environment.\nPlease run the wizard in an interactive terminal.\n\nFor CI/CD environments, use --ci mode:\n npx @posthog/wizard --ci --region us --api-key phx_xxx");
|
|
990
1793
|
process.exit(1);
|
|
991
1794
|
} else if (options.playground) (async () => {
|
|
992
|
-
const { startPlayground } = await import("./start-playground-
|
|
1795
|
+
const { startPlayground } = await import("./start-playground-BhwBUq-a.js");
|
|
993
1796
|
startPlayground(WIZARD_VERSION);
|
|
994
1797
|
})();
|
|
995
1798
|
else if (options.skill) (async () => {
|
|
996
|
-
const {
|
|
1799
|
+
const { createSkillProgram } = await Promise.resolve().then(() => agent_skill_exports);
|
|
997
1800
|
const skillId = options.skill;
|
|
998
|
-
runWizard(
|
|
1801
|
+
runWizard(createSkillProgram({
|
|
999
1802
|
skillId,
|
|
1000
1803
|
command: "skill",
|
|
1001
|
-
|
|
1804
|
+
id: "agent-skill",
|
|
1002
1805
|
description: `Run skill: ${skillId}`,
|
|
1003
1806
|
integrationLabel: skillId,
|
|
1004
1807
|
successMessage: `${skillId} completed!`,
|
|
@@ -1012,7 +1815,7 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1012
1815
|
});
|
|
1013
1816
|
})();
|
|
1014
1817
|
else (async () => {
|
|
1015
|
-
const { posthogIntegrationConfig } = await import("./posthog-integration-
|
|
1818
|
+
const { posthogIntegrationConfig } = await import("./posthog-integration-C-FFV5ny.js").then((n) => n.r);
|
|
1016
1819
|
runWizard(posthogIntegrationConfig, options);
|
|
1017
1820
|
})();
|
|
1018
1821
|
}).command("mcp <command>", "MCP server management commands", (yargs) => {
|
|
@@ -1039,10 +1842,9 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1039
1842
|
const { readApiKeyFromEnv } = await import("./env-api-key-D5G2PrXW.js");
|
|
1040
1843
|
const apiKey = options.apiKey || readApiKeyFromEnv();
|
|
1041
1844
|
try {
|
|
1042
|
-
const { startTUI } = await import("./start-tui-
|
|
1043
|
-
const { buildSession } = await import("./wizard-session-
|
|
1044
|
-
const
|
|
1045
|
-
const tui = startTUI(WIZARD_VERSION, Flow.McpAdd);
|
|
1845
|
+
const { startTUI } = await import("./start-tui-BwQa3kmG.js");
|
|
1846
|
+
const { buildSession } = await import("./wizard-session-CPhhll4P.js");
|
|
1847
|
+
const tui = startTUI(WIZARD_VERSION, Program.McpAdd);
|
|
1046
1848
|
const session = buildSession({
|
|
1047
1849
|
debug: options.debug,
|
|
1048
1850
|
localMcp: options.local,
|
|
@@ -1052,7 +1854,7 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1052
1854
|
tui.store.session = session;
|
|
1053
1855
|
} catch {
|
|
1054
1856
|
setUI(new LoggingUI());
|
|
1055
|
-
const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-
|
|
1857
|
+
const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-BTW9Ey5Z.js").then((n) => n.r);
|
|
1056
1858
|
await addMCPServerToClientsStep({
|
|
1057
1859
|
local: options.local,
|
|
1058
1860
|
features: mcpFeatures,
|
|
@@ -1070,10 +1872,9 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1070
1872
|
const options = { ...argv };
|
|
1071
1873
|
(async () => {
|
|
1072
1874
|
try {
|
|
1073
|
-
const { startTUI } = await import("./start-tui-
|
|
1074
|
-
const { buildSession } = await import("./wizard-session-
|
|
1075
|
-
const
|
|
1076
|
-
const tui = startTUI(WIZARD_VERSION, Flow.McpRemove);
|
|
1875
|
+
const { startTUI } = await import("./start-tui-BwQa3kmG.js");
|
|
1876
|
+
const { buildSession } = await import("./wizard-session-CPhhll4P.js");
|
|
1877
|
+
const tui = startTUI(WIZARD_VERSION, Program.McpRemove);
|
|
1077
1878
|
const session = buildSession({
|
|
1078
1879
|
debug: options.debug,
|
|
1079
1880
|
localMcp: options.local
|
|
@@ -1081,7 +1882,7 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
|
|
|
1081
1882
|
tui.store.session = session;
|
|
1082
1883
|
} catch {
|
|
1083
1884
|
setUI(new LoggingUI());
|
|
1084
|
-
const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-
|
|
1885
|
+
const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-BTW9Ey5Z.js").then((n) => n.r);
|
|
1085
1886
|
await removeMCPServerFromClientsStep({ local: options.local });
|
|
1086
1887
|
}
|
|
1087
1888
|
})();
|
|
@@ -1117,7 +1918,7 @@ cli.command("provision", "Create a new PostHog account (headless, no TUI)", (yar
|
|
|
1117
1918
|
if (!jsonMode) setUI(new LoggingUI());
|
|
1118
1919
|
(async () => {
|
|
1119
1920
|
try {
|
|
1120
|
-
const { provisionNewAccount } = await import("./provisioning-
|
|
1921
|
+
const { provisionNewAccount } = await import("./provisioning-ByWo5KcQ.js");
|
|
1121
1922
|
if (!jsonMode) getUI().log.info(`Provisioning account for ${email} in ${region}...`);
|
|
1122
1923
|
const result = await provisionNewAccount(email, name, region);
|
|
1123
1924
|
if (jsonMode) process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
@@ -1144,14 +1945,21 @@ cli.command("provision", "Create a new PostHog account (headless, no TUI)", (yar
|
|
|
1144
1945
|
}
|
|
1145
1946
|
})();
|
|
1146
1947
|
});
|
|
1147
|
-
for (const
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1948
|
+
for (const programConfig of getSubcommandPrograms()) cli.command(programConfig.command, programConfig.description, (y) => y.options({
|
|
1949
|
+
...skillSubcommandOptions,
|
|
1950
|
+
...programConfig.cliOptions ?? {}
|
|
1951
|
+
}), (argv) => {
|
|
1952
|
+
const extras = programConfig.mapCliOptions?.(argv) ?? {};
|
|
1953
|
+
const options = {
|
|
1954
|
+
...argv,
|
|
1955
|
+
...extras
|
|
1956
|
+
};
|
|
1957
|
+
if (options.ci) runWizardCI(programConfig, options);
|
|
1958
|
+
else runWizard(programConfig, options);
|
|
1151
1959
|
});
|
|
1152
1960
|
cli.help().alias("help", "h").version().alias("version", "v").wrap(process.stdout.isTTY ? cli.terminalWidth() : 80).argv;
|
|
1153
1961
|
/**
|
|
1154
|
-
* Run a full wizard
|
|
1962
|
+
* Run a full wizard program in the TUI. Handles the full lifecycle: start TUI,
|
|
1155
1963
|
* build session, run detection, wait for intro gate, execute the
|
|
1156
1964
|
* agent pipeline, wait for outro dismissal, then exit.
|
|
1157
1965
|
*/
|
|
@@ -1159,13 +1967,13 @@ function runWizard(config, options) {
|
|
|
1159
1967
|
(async () => {
|
|
1160
1968
|
try {
|
|
1161
1969
|
const installDir = options.installDir || process.cwd();
|
|
1162
|
-
const { startTUI } = await import("./start-tui-
|
|
1163
|
-
const { buildSession } = await import("./wizard-session-
|
|
1164
|
-
const { TaskStreamPush } = await import("./task-stream-
|
|
1165
|
-
const { FileDestination } = await import("./file-
|
|
1166
|
-
const { PostHogDestination } = await import("./posthog-
|
|
1167
|
-
const { analytics } = await import("./analytics-
|
|
1168
|
-
const tui = startTUI(WIZARD_VERSION, config.
|
|
1970
|
+
const { startTUI } = await import("./start-tui-BwQa3kmG.js");
|
|
1971
|
+
const { buildSession } = await import("./wizard-session-CPhhll4P.js");
|
|
1972
|
+
const { TaskStreamPush } = await import("./task-stream-DUpUZmFQ.js");
|
|
1973
|
+
const { FileDestination } = await import("./file-BKbKreWF.js");
|
|
1974
|
+
const { PostHogDestination } = await import("./posthog-BbQf_Hzq.js");
|
|
1975
|
+
const { analytics } = await import("./analytics-tslsXyf9.js");
|
|
1976
|
+
const tui = startTUI(WIZARD_VERSION, config.id);
|
|
1169
1977
|
const session = buildSession({
|
|
1170
1978
|
debug: options.debug,
|
|
1171
1979
|
forceInstall: options.forceInstall,
|
|
@@ -1181,12 +1989,13 @@ function runWizard(config, options) {
|
|
|
1181
1989
|
benchmark: options.benchmark,
|
|
1182
1990
|
yaraReport: options.yaraReport
|
|
1183
1991
|
});
|
|
1184
|
-
session.
|
|
1992
|
+
session.programLabel = config.id;
|
|
1185
1993
|
if (options.skillId) session.skillId = options.skillId;
|
|
1994
|
+
else if (config.skillId) session.skillId = config.skillId;
|
|
1186
1995
|
tui.store.session = session;
|
|
1187
1996
|
const taskStream = new TaskStreamPush({
|
|
1188
1997
|
store: tui.store,
|
|
1189
|
-
|
|
1998
|
+
programId: config.id,
|
|
1190
1999
|
destinations: [new FileDestination(), new PostHogDestination()]
|
|
1191
2000
|
});
|
|
1192
2001
|
tui.store.onTasksChanged = () => void taskStream.push();
|
|
@@ -1195,7 +2004,7 @@ function runWizard(config, options) {
|
|
|
1195
2004
|
await tui.store.getGate("health-check");
|
|
1196
2005
|
const skipAgent = config.run == null;
|
|
1197
2006
|
if (skipAgent) {
|
|
1198
|
-
const { getOrAskForProjectData } = await import("./setup-utils-
|
|
2007
|
+
const { getOrAskForProjectData } = await import("./setup-utils-D5aNKrba.js");
|
|
1199
2008
|
const { projectApiKey, host, accessToken, projectId } = await getOrAskForProjectData({
|
|
1200
2009
|
signup: session.signup,
|
|
1201
2010
|
ci: session.ci,
|
|
@@ -1209,7 +2018,7 @@ function runWizard(config, options) {
|
|
|
1209
2018
|
projectId
|
|
1210
2019
|
});
|
|
1211
2020
|
} else {
|
|
1212
|
-
const { runAgent } = await import("./agent-runner-
|
|
2021
|
+
const { runAgent } = await import("./agent-runner-Bxi71jnp.js");
|
|
1213
2022
|
await runAgent(config, tui.store.session);
|
|
1214
2023
|
}
|
|
1215
2024
|
const isDone = () => skipAgent ? tui.store.session.outroDismissed : tui.store.session.skillsComplete;
|
|
@@ -1241,7 +2050,7 @@ function runWizard(config, options) {
|
|
|
1241
2050
|
* CI-mode pipeline shared by every non-interactive entry point.
|
|
1242
2051
|
*
|
|
1243
2052
|
* Validates flags, builds a `ci:true` session, runs `preRun` (or the
|
|
1244
|
-
*
|
|
2053
|
+
* program's `onReady` hooks by default), executes `runAgent`, and
|
|
1245
2054
|
* routes any failure through `wizardAbort`. `wizardAbort` owns all
|
|
1246
2055
|
* exits — never add a raw `process.exit` here.
|
|
1247
2056
|
*/
|
|
@@ -1260,11 +2069,11 @@ function runWizardCI(config, options, preRun) {
|
|
|
1260
2069
|
}
|
|
1261
2070
|
(async () => {
|
|
1262
2071
|
const path = await import("path");
|
|
1263
|
-
const { buildSession } = await import("./wizard-session-
|
|
2072
|
+
const { buildSession } = await import("./wizard-session-CPhhll4P.js");
|
|
1264
2073
|
const { readEnvironment } = await Promise.resolve().then(() => environment_exports);
|
|
1265
2074
|
const { readApiKeyFromEnv } = await import("./env-api-key-D5G2PrXW.js");
|
|
1266
|
-
const { configureLogFileFromEnvironment, logToFile } = await import("./debug-
|
|
1267
|
-
const { wizardAbort, WizardError } = await import("./wizard-abort-
|
|
2075
|
+
const { configureLogFileFromEnvironment, logToFile } = await import("./debug-Du7qXlug.js");
|
|
2076
|
+
const { wizardAbort, WizardError } = await import("./wizard-abort-BTBccRto.js");
|
|
1268
2077
|
configureLogFileFromEnvironment();
|
|
1269
2078
|
const env = readEnvironment();
|
|
1270
2079
|
const apiKey = options.apiKey ?? readApiKeyFromEnv() ?? void 0;
|
|
@@ -1285,10 +2094,11 @@ function runWizardCI(config, options, preRun) {
|
|
|
1285
2094
|
yaraReport: options.yaraReport,
|
|
1286
2095
|
...env
|
|
1287
2096
|
});
|
|
1288
|
-
session.
|
|
2097
|
+
session.programLabel = config.id;
|
|
2098
|
+
if (config.skillId) session.skillId = config.skillId;
|
|
1289
2099
|
const runDef = typeof config.run === "object" ? config.run : null;
|
|
1290
2100
|
getUI().intro("Welcome to the PostHog setup wizard");
|
|
1291
|
-
getUI().log.info(`Running ${config.
|
|
2101
|
+
getUI().log.info(`Running ${config.id} in CI mode`);
|
|
1292
2102
|
try {
|
|
1293
2103
|
if (preRun) await preRun(session);
|
|
1294
2104
|
else {
|
|
@@ -1307,13 +2117,13 @@ function runWizardCI(config, options, preRun) {
|
|
|
1307
2117
|
const detectError = session.frameworkContext.detectError;
|
|
1308
2118
|
if (detectError) await wizardAbort({
|
|
1309
2119
|
message: `Prerequisites not met: ${detectError.kind}\n\nSee ${runDef?.docsUrl ?? "https://posthog.com/docs"}`,
|
|
1310
|
-
error: new WizardError(`${config.
|
|
1311
|
-
integration: config.
|
|
2120
|
+
error: new WizardError(`${config.id} prerequisites failed`, {
|
|
2121
|
+
integration: config.id,
|
|
1312
2122
|
detect_error_kind: detectError.kind
|
|
1313
2123
|
})
|
|
1314
2124
|
});
|
|
1315
2125
|
}
|
|
1316
|
-
const { runAgent } = await import("./agent-runner-
|
|
2126
|
+
const { runAgent } = await import("./agent-runner-Bxi71jnp.js");
|
|
1317
2127
|
await runAgent(config, session);
|
|
1318
2128
|
} catch (error) {
|
|
1319
2129
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -1331,6 +2141,6 @@ function runWizardCI(config, options, preRun) {
|
|
|
1331
2141
|
});
|
|
1332
2142
|
}
|
|
1333
2143
|
//#endregion
|
|
1334
|
-
export {
|
|
2144
|
+
export { getKindMeta as a, POSTHOG_SDKS as c, getContentBlocks as i, STRIPE_SDKS as l, Program as n, fetchHealthIssues as o, getProgramConfig as r, getContentBlocks$1 as s, PROGRAM_REGISTRY as t };
|
|
1335
2145
|
|
|
1336
2146
|
//# sourceMappingURL=bin.js.map
|