@posthog/wizard 2.25.0 → 2.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{add-mcp-server-to-clients-t0xe8gn1.js → add-mcp-server-to-clients-C58l_KpV.js} +4 -4
- package/dist/{add-mcp-server-to-clients-t0xe8gn1.js.map → add-mcp-server-to-clients-C58l_KpV.js.map} +1 -1
- package/dist/{agent-interface-BsuUUPle.js → agent-interface-Dq_4h2eN.js} +39 -12
- package/dist/agent-interface-Dq_4h2eN.js.map +1 -0
- package/dist/{agent-runner-L_-kJ3y3.js → agent-runner-BNGW3osc.js} +176 -167
- package/dist/agent-runner-BNGW3osc.js.map +1 -0
- package/dist/{analytics-CDOujOSQ.js → analytics-BX3LKPch.js} +2 -2
- package/dist/{analytics-CDOujOSQ.js.map → analytics-BX3LKPch.js.map} +1 -1
- package/dist/{api-DNS-L-1U.js → api-DCHci5SD.js} +9 -5
- package/dist/api-DCHci5SD.js.map +1 -0
- package/dist/bin.js +583 -119
- package/dist/bin.js.map +1 -1
- package/dist/{ci-install-_9A7tL36.js → ci-install-CHIbwXio.js} +5 -5
- package/dist/{ci-install-_9A7tL36.js.map → ci-install-CHIbwXio.js.map} +1 -1
- package/dist/{debug-BwC7UkGH.js → debug-BizeRFR0.js} +3 -2
- package/dist/{debug-BwC7UkGH.js.map → debug-BizeRFR0.js.map} +1 -1
- package/dist/{debug-CZQcMAJT.js → debug-fg4BAKKA.js} +1 -1
- package/dist/{environment-DQPoj9sU.js → environment-DS5Pq9Wm.js} +3 -3
- package/dist/{environment-DQPoj9sU.js.map → environment-DS5Pq9Wm.js.map} +1 -1
- package/dist/{interactive-DT5dLd7N.js → interactive-DE3WDjk7.js} +3 -3
- package/dist/{interactive-DT5dLd7N.js.map → interactive-DE3WDjk7.js.map} +1 -1
- package/dist/{mcp-prompt-streaming-CBMr458Q.js → mcp-prompt-streaming-zsYd1zJx.js} +4 -4
- package/dist/{mcp-prompt-streaming-CBMr458Q.js.map → mcp-prompt-streaming-zsYd1zJx.js.map} +1 -1
- package/dist/{non-interactive-csP4yGdA.js → non-interactive-DNah9u3t.js} +2 -2
- package/dist/{non-interactive-csP4yGdA.js.map → non-interactive-DNah9u3t.js.map} +1 -1
- package/dist/{package-manager-CB4c2euf.js → package-manager-Dma9-zGs.js} +2 -2
- package/dist/{package-manager-CB4c2euf.js.map → package-manager-Dma9-zGs.js.map} +1 -1
- package/dist/{playground-C-lpKoKC.js → playground-Cwe0Q9HW.js} +145 -48
- package/dist/playground-Cwe0Q9HW.js.map +1 -0
- package/dist/{posthog-integration-BL8-vC0V.js → posthog-integration-CAYZdk0r.js} +11 -11
- package/dist/{posthog-integration-BL8-vC0V.js.map → posthog-integration-CAYZdk0r.js.map} +1 -1
- package/dist/{provisioning-DLOiFSM9.js → provisioning-BmL4ro-o.js} +10 -6
- package/dist/{provisioning-DLOiFSM9.js.map → provisioning-BmL4ro-o.js.map} +1 -1
- package/dist/{registry-BbRzCV5l.js → registry-C3wcDM3X.js} +4 -4
- package/dist/{registry-BbRzCV5l.js.map → registry-C3wcDM3X.js.map} +1 -1
- package/dist/{setup-utils-D87CyNkw.js → setup-utils-CNWIMZ-d.js} +71 -16
- package/dist/setup-utils-CNWIMZ-d.js.map +1 -0
- package/dist/{start-tui-DnAG57vY.js → start-tui-CS802Ww9.js} +311 -54
- package/dist/start-tui-CS802Ww9.js.map +1 -0
- package/dist/{steps-JaxH6u0f.js → steps-BX44xr30.js} +6 -6
- package/dist/{steps-JaxH6u0f.js.map → steps-BX44xr30.js.map} +1 -1
- package/dist/{telemetry-DL28cCwY.js → telemetry-BH-MgWPT.js} +3 -3
- package/dist/{telemetry-DL28cCwY.js.map → telemetry-BH-MgWPT.js.map} +1 -1
- package/dist/{AiOptInRequiredScreen-C-D9tN6r.js → terminal-BSiupnOQ.js} +1047 -85
- package/dist/terminal-BSiupnOQ.js.map +1 -0
- package/dist/{urls-vkJ5c0ix.js → urls-BuEABcmF.js} +2 -2
- package/dist/{urls-vkJ5c0ix.js.map → urls-BuEABcmF.js.map} +1 -1
- package/dist/{wizard-abort-BRXKRL4F.js → wizard-abort-CR3w2Efg.js} +1 -1
- package/dist/{wizard-abort-CLGgMAEe.js → wizard-abort-Dl2MJOP9.js} +3 -3
- package/dist/{wizard-abort-CLGgMAEe.js.map → wizard-abort-Dl2MJOP9.js.map} +1 -1
- package/dist/wizard-session-G3VWD6hv.js.map +1 -1
- package/dist/wizard-ui-WZ48rUgr.js.map +1 -1
- package/package.json +1 -1
- package/dist/AiOptInRequiredScreen-C-D9tN6r.js.map +0 -1
- package/dist/agent-interface-BsuUUPle.js.map +0 -1
- package/dist/agent-runner-L_-kJ3y3.js.map +0 -1
- package/dist/api-DNS-L-1U.js.map +0 -1
- package/dist/playground-C-lpKoKC.js.map +0 -1
- package/dist/setup-utils-D87CyNkw.js.map +0 -1
- package/dist/start-tui-DnAG57vY.js.map +0 -1
package/dist/bin.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $ as getSkillsBaseUrl, P as POSTHOG_DOCS_URL, X as WIZARD_USER_AGENT, _ as SIGNUP_WIZARD_READINESS_CONFIG, a as getLogFilePath, et as VERSION, h as LoggingUI, m as setUI, p as getUI, r as debug, s as logToFile, v as evaluateWizardReadiness, y as getBlockingServiceKeys } from "./debug-
|
|
3
|
-
import { t as analytics } from "./analytics-
|
|
4
|
-
import { r as setEntryCommand } from "./telemetry-
|
|
5
|
-
import { n as isUsingTypeScript } from "./setup-utils-
|
|
6
|
-
import { a as getUiHostFromHost, n as getCloudUrlFromRegion } from "./urls-
|
|
7
|
-
import { o as handleApiError } from "./api-
|
|
2
|
+
import { $ as getSkillsBaseUrl, P as POSTHOG_DOCS_URL, X as WIZARD_USER_AGENT, _ as SIGNUP_WIZARD_READINESS_CONFIG, a as getLogFilePath, et as VERSION, h as LoggingUI, m as setUI, p as getUI, r as debug, s as logToFile, v as evaluateWizardReadiness, y as getBlockingServiceKeys } from "./debug-BizeRFR0.js";
|
|
3
|
+
import { t as analytics } from "./analytics-BX3LKPch.js";
|
|
4
|
+
import { r as setEntryCommand } from "./telemetry-BH-MgWPT.js";
|
|
5
|
+
import { n as isUsingTypeScript } from "./setup-utils-CNWIMZ-d.js";
|
|
6
|
+
import { a as getUiHostFromHost, n as getCloudUrlFromRegion } from "./urls-BuEABcmF.js";
|
|
7
|
+
import { o as handleApiError } from "./api-DCHci5SD.js";
|
|
8
8
|
import "./wizard-session-G3VWD6hv.js";
|
|
9
|
-
import { r as runCleanups } from "./wizard-abort-
|
|
10
|
-
import { n as isNonInteractiveEnvironment } from "./environment-
|
|
11
|
-
import { S as AUDIT_REPORT_FILE, b as AUDIT_CHECKS_FILE, c as recoverOrphanedSettingsBackups, h as fetchSkillMenu, p as WIZARD_TOOL_NAMES, u as AgentSignals, x as AUDIT_CHECKS_KEY } from "./agent-interface-
|
|
12
|
-
import { i as SPINNER_MESSAGE } from "./registry-
|
|
13
|
-
import { a as PRODUCT_SUITE_BLOCK, f as Colors, i as LINE_CHART_BLOCK, l as isClearBlock, m as HEALTH_CHECK_STEP, n as posthogIntegrationConfig, o as StatusPeekTrigger, p as Icons, r as FUNNEL_BLOCK } from "./posthog-integration-
|
|
9
|
+
import { r as runCleanups } from "./wizard-abort-Dl2MJOP9.js";
|
|
10
|
+
import { n as isNonInteractiveEnvironment } from "./environment-DS5Pq9Wm.js";
|
|
11
|
+
import { S as AUDIT_REPORT_FILE, b as AUDIT_CHECKS_FILE, c as recoverOrphanedSettingsBackups, h as fetchSkillMenu, p as WIZARD_TOOL_NAMES, u as AgentSignals, x as AUDIT_CHECKS_KEY } from "./agent-interface-Dq_4h2eN.js";
|
|
12
|
+
import { i as SPINNER_MESSAGE } from "./registry-C3wcDM3X.js";
|
|
13
|
+
import { a as PRODUCT_SUITE_BLOCK, f as Colors, i as LINE_CHART_BLOCK, l as isClearBlock, m as HEALTH_CHECK_STEP, n as posthogIntegrationConfig, o as StatusPeekTrigger, p as Icons, r as FUNNEL_BLOCK } from "./posthog-integration-CAYZdk0r.js";
|
|
14
14
|
import { t as IGNORED_DIRS } from "./file-utils-VAXoyXVA.js";
|
|
15
15
|
import { n as readApiKeyFromEnv } from "./env-api-key-MlzJYAvt.js";
|
|
16
16
|
import { satisfies } from "semver";
|
|
@@ -27,6 +27,7 @@ import { z } from "zod";
|
|
|
27
27
|
import { Box, Text, render, useInput } from "ink";
|
|
28
28
|
import { createContext, createElement, useCallback, useContext, useEffect, useRef, useState } from "react";
|
|
29
29
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
30
|
+
import { access, rm } from "node:fs/promises";
|
|
30
31
|
import * as readline from "node:readline/promises";
|
|
31
32
|
//#region src/commands/command.ts
|
|
32
33
|
/** Extract the bare command word(s) from a yargs name spec, dropping positionals and aliases' arg syntax. */
|
|
@@ -189,7 +190,7 @@ function runProvision(argv) {
|
|
|
189
190
|
}
|
|
190
191
|
async function provision({ email, region, name, jsonMode }) {
|
|
191
192
|
try {
|
|
192
|
-
const { provisionNewAccount } = await import("./provisioning-
|
|
193
|
+
const { provisionNewAccount } = await import("./provisioning-BmL4ro-o.js").then((n) => n.n);
|
|
193
194
|
if (!jsonMode) getUI().log.info(`Provisioning account for ${email} in ${region}...`);
|
|
194
195
|
emitResult(await provisionNewAccount(email, name, region), jsonMode);
|
|
195
196
|
process.exit(0);
|
|
@@ -254,18 +255,18 @@ const basicIntegrationCommand = {
|
|
|
254
255
|
setEntryCommand("integrate");
|
|
255
256
|
(async () => {
|
|
256
257
|
if (argv.ci) {
|
|
257
|
-
const { runCIInstall } = await import("./ci-install-
|
|
258
|
+
const { runCIInstall } = await import("./ci-install-CHIbwXio.js");
|
|
258
259
|
return runCIInstall(argv);
|
|
259
260
|
}
|
|
260
261
|
if (isNonInteractiveEnvironment()) {
|
|
261
|
-
const { failNonInteractive } = await import("./non-interactive-
|
|
262
|
+
const { failNonInteractive } = await import("./non-interactive-DNah9u3t.js");
|
|
262
263
|
return failNonInteractive();
|
|
263
264
|
}
|
|
264
265
|
if (argv.playground) {
|
|
265
|
-
const { runPlayground } = await import("./playground-
|
|
266
|
+
const { runPlayground } = await import("./playground-Cwe0Q9HW.js");
|
|
266
267
|
return runPlayground();
|
|
267
268
|
}
|
|
268
|
-
const { runInteractive } = await import("./interactive-
|
|
269
|
+
const { runInteractive } = await import("./interactive-DE3WDjk7.js");
|
|
269
270
|
runInteractive(argv);
|
|
270
271
|
})();
|
|
271
272
|
}
|
|
@@ -846,7 +847,7 @@ const EVENTS_AUDIT_SEED_CHECKS = [
|
|
|
846
847
|
//#endregion
|
|
847
848
|
//#region src/lib/programs/events-audit/index.ts
|
|
848
849
|
const SETUP_REPORT_FILE = "posthog-events-audit-report.md";
|
|
849
|
-
const DOCS_URL$
|
|
850
|
+
const DOCS_URL$3 = "https://posthog.com/docs/product-analytics/best-practices";
|
|
850
851
|
const eventsAuditConfig = {
|
|
851
852
|
command: "events-audit",
|
|
852
853
|
description: "Audit PostHog event tracking in this project",
|
|
@@ -868,7 +869,7 @@ const eventsAuditConfig = {
|
|
|
868
869
|
successMessage: "Events audit complete! You can view the report at ./posthog-events-audit-report.md",
|
|
869
870
|
estimatedDurationMinutes: 5,
|
|
870
871
|
reportFile: SETUP_REPORT_FILE,
|
|
871
|
-
docsUrl: DOCS_URL$
|
|
872
|
+
docsUrl: DOCS_URL$3,
|
|
872
873
|
errorMessage: "Events audit failed",
|
|
873
874
|
additionalFeatureQueue: session.additionalFeatureQueue,
|
|
874
875
|
customPrompt: (ctx) => `Audit PostHog event capture in this project. Do not modify any project files — produce a read-only report only.
|
|
@@ -886,7 +887,7 @@ Project context:
|
|
|
886
887
|
message: "Your events audit was successful",
|
|
887
888
|
reportFile: SETUP_REPORT_FILE,
|
|
888
889
|
changes: [],
|
|
889
|
-
docsUrl: DOCS_URL$
|
|
890
|
+
docsUrl: DOCS_URL$3,
|
|
890
891
|
continueUrl: sess.signup && cloudUrl ? `${cloudUrl}/products?source=wizard` : void 0,
|
|
891
892
|
dashboardUrl: sess.dashboardUrl ?? (cloudUrl ? `${cloudUrl}/dashboard` : void 0),
|
|
892
893
|
notebookUrl: sess.notebookUrl ?? void 0
|
|
@@ -2415,15 +2416,15 @@ const getContentBlocks = (store) => pace([
|
|
|
2415
2416
|
]);
|
|
2416
2417
|
//#endregion
|
|
2417
2418
|
//#region src/lib/programs/error-tracking-upload-source-maps/index.ts
|
|
2418
|
-
const REPORT_FILE = "posthog-source-maps-report.md";
|
|
2419
|
-
const DOCS_URL = "https://posthog.com/docs/error-tracking/upload-source-maps";
|
|
2419
|
+
const REPORT_FILE$1 = "posthog-source-maps-report.md";
|
|
2420
|
+
const DOCS_URL$1 = "https://posthog.com/docs/error-tracking/upload-source-maps";
|
|
2420
2421
|
const errorTrackingUploadSourceMapsConfig = {
|
|
2421
2422
|
command: "upload-source-maps",
|
|
2422
2423
|
description: "Upload source maps to PostHog Error Tracking",
|
|
2423
2424
|
id: "error-tracking-upload-source-maps",
|
|
2424
2425
|
requiresAi: true,
|
|
2425
2426
|
steps: ERROR_TRACKING_UPLOAD_SOURCE_MAPS_PROGRAM,
|
|
2426
|
-
reportFile: REPORT_FILE,
|
|
2427
|
+
reportFile: REPORT_FILE$1,
|
|
2427
2428
|
getContentBlocks,
|
|
2428
2429
|
requires: ["posthog-integration"],
|
|
2429
2430
|
run: (session) => {
|
|
@@ -2433,8 +2434,8 @@ const errorTrackingUploadSourceMapsConfig = {
|
|
|
2433
2434
|
return Promise.resolve({
|
|
2434
2435
|
integrationLabel: "error-tracking-upload-source-maps",
|
|
2435
2436
|
successMessage: "Source maps wired up!",
|
|
2436
|
-
reportFile: REPORT_FILE,
|
|
2437
|
-
docsUrl: DOCS_URL,
|
|
2437
|
+
reportFile: REPORT_FILE$1,
|
|
2438
|
+
docsUrl: DOCS_URL$1,
|
|
2438
2439
|
spinnerMessage: "Wiring up source maps...",
|
|
2439
2440
|
estimatedDurationMinutes: 3,
|
|
2440
2441
|
abortCases: SOURCE_MAPS_ABORT_CASES,
|
|
@@ -2460,14 +2461,363 @@ const errorTrackingUploadSourceMapsConfig = {
|
|
|
2460
2461
|
return {
|
|
2461
2462
|
kind: "success",
|
|
2462
2463
|
message: "Source maps wired up!",
|
|
2463
|
-
reportFile: REPORT_FILE,
|
|
2464
|
-
docsUrl: DOCS_URL
|
|
2464
|
+
reportFile: REPORT_FILE$1,
|
|
2465
|
+
docsUrl: DOCS_URL$1
|
|
2465
2466
|
};
|
|
2466
2467
|
}
|
|
2467
2468
|
});
|
|
2468
2469
|
}
|
|
2469
2470
|
};
|
|
2470
2471
|
//#endregion
|
|
2472
|
+
//#region src/lib/programs/self-driving/detect.ts
|
|
2473
|
+
/**
|
|
2474
|
+
* Self-driving prerequisite detection + abort vocabulary.
|
|
2475
|
+
*
|
|
2476
|
+
* The only thing worth verifying before auth is local and cheap: that
|
|
2477
|
+
* `session.installDir` is a real, readable directory. We deliberately do
|
|
2478
|
+
* NOT require the base posthog-integration report to be present — it is a
|
|
2479
|
+
* report many users never commit, and `requires: ['posthog-integration']`
|
|
2480
|
+
* is metadata, not a hard runtime gate. Real readiness (integration state
|
|
2481
|
+
* + beta access) is established by the agent's STEP 1 Signals API probe at
|
|
2482
|
+
* the start of the run. The beta gates (the `product-autonomy` access flag
|
|
2483
|
+
* and `signals-scout` enrollment — PostHog-side flag names, unchanged by
|
|
2484
|
+
* the wizard-side "self-driving" rename) are PostHog-internal flags with no
|
|
2485
|
+
* customer-facing read API, which is why that probe lives in the run and
|
|
2486
|
+
* emits a structured `[ABORT]` when the product is not available.
|
|
2487
|
+
*/
|
|
2488
|
+
/**
|
|
2489
|
+
* `[ABORT] <reason>` cases the self-driving skill can emit. The
|
|
2490
|
+
* reason strings are part of the skill contract — the context-mill
|
|
2491
|
+
* `self-driving-setup` skill emits these exact strings.
|
|
2492
|
+
*/
|
|
2493
|
+
const SELF_DRIVING_ABORT_CASES = [
|
|
2494
|
+
{
|
|
2495
|
+
match: /^self-driving is not available for this project$/i,
|
|
2496
|
+
message: "PostHog Self-driving is not available for this project",
|
|
2497
|
+
body: "Self-driving is in beta and is enabled per team by PostHog. This project does not appear to have access yet. Reach out to your PostHog contact (or wizard@posthog.com) to join the beta, then run the wizard again."
|
|
2498
|
+
},
|
|
2499
|
+
{
|
|
2500
|
+
match: /^github connection declined$/i,
|
|
2501
|
+
message: "GitHub connection required",
|
|
2502
|
+
body: "Self-driving needs GitHub access to research issues in your code and open fixes, so setup cannot finish without it. Nothing was left half-configured. When you are ready to install the PostHog GitHub App, run the wizard again."
|
|
2503
|
+
},
|
|
2504
|
+
{
|
|
2505
|
+
match: /^requires-interactive-mode$/i,
|
|
2506
|
+
message: "Interactive terminal required",
|
|
2507
|
+
body: "Self-driving setup asks questions along the way (GitHub and issue trackers), so it needs an interactive terminal. Run the wizard outside CI / non-interactive mode."
|
|
2508
|
+
},
|
|
2509
|
+
{
|
|
2510
|
+
match: /^requirements-incomplete$/i,
|
|
2511
|
+
message: "Setup needs your input",
|
|
2512
|
+
body: "The wizard could not collect the answers this setup needs (the environment was non-interactive, or the question budget ran out). Nothing was left half-configured. Run the wizard again in an interactive terminal."
|
|
2513
|
+
}
|
|
2514
|
+
];
|
|
2515
|
+
/**
|
|
2516
|
+
* Verify `session.installDir` is a readable directory. Writes a
|
|
2517
|
+
* `SelfDrivingDetectError` to frameworkContext on failure — the intro
|
|
2518
|
+
* screen renders it and blocks.
|
|
2519
|
+
*/
|
|
2520
|
+
function detectSelfDrivingPrerequisites(session, setFrameworkContext) {
|
|
2521
|
+
const fail = (error) => setFrameworkContext("detectError", error);
|
|
2522
|
+
const installDir = session.installDir;
|
|
2523
|
+
if (!existsSync(installDir)) {
|
|
2524
|
+
fail({
|
|
2525
|
+
kind: "bad-directory",
|
|
2526
|
+
path: installDir,
|
|
2527
|
+
reason: "missing"
|
|
2528
|
+
});
|
|
2529
|
+
return;
|
|
2530
|
+
}
|
|
2531
|
+
try {
|
|
2532
|
+
if (!statSync(installDir).isDirectory()) {
|
|
2533
|
+
fail({
|
|
2534
|
+
kind: "bad-directory",
|
|
2535
|
+
path: installDir,
|
|
2536
|
+
reason: "not-dir"
|
|
2537
|
+
});
|
|
2538
|
+
return;
|
|
2539
|
+
}
|
|
2540
|
+
} catch {
|
|
2541
|
+
fail({
|
|
2542
|
+
kind: "bad-directory",
|
|
2543
|
+
path: installDir,
|
|
2544
|
+
reason: "unreadable"
|
|
2545
|
+
});
|
|
2546
|
+
return;
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2549
|
+
//#endregion
|
|
2550
|
+
//#region src/lib/programs/self-driving/steps.ts
|
|
2551
|
+
const SELF_DRIVING_PROGRAM = [
|
|
2552
|
+
{
|
|
2553
|
+
id: "detect",
|
|
2554
|
+
label: "Detecting prerequisites",
|
|
2555
|
+
onReady: (ctx) => detectSelfDrivingPrerequisites(ctx.session, ctx.setFrameworkContext)
|
|
2556
|
+
},
|
|
2557
|
+
{
|
|
2558
|
+
id: "intro",
|
|
2559
|
+
label: "Welcome",
|
|
2560
|
+
screenId: "self-driving-intro",
|
|
2561
|
+
gate: (session) => session.setupConfirmed
|
|
2562
|
+
},
|
|
2563
|
+
HEALTH_CHECK_STEP,
|
|
2564
|
+
{
|
|
2565
|
+
id: "auth",
|
|
2566
|
+
label: "Authentication",
|
|
2567
|
+
screenId: "auth",
|
|
2568
|
+
isComplete: (session) => session.credentials !== null
|
|
2569
|
+
},
|
|
2570
|
+
{
|
|
2571
|
+
id: "run",
|
|
2572
|
+
label: "Self-driving",
|
|
2573
|
+
screenId: "run",
|
|
2574
|
+
isComplete: (session) => session.runPhase === "completed" || session.runPhase === "error"
|
|
2575
|
+
},
|
|
2576
|
+
{
|
|
2577
|
+
id: "outro",
|
|
2578
|
+
label: "Done",
|
|
2579
|
+
screenId: "outro",
|
|
2580
|
+
isComplete: (session) => session.outroDismissed
|
|
2581
|
+
}
|
|
2582
|
+
];
|
|
2583
|
+
//#endregion
|
|
2584
|
+
//#region src/lib/programs/self-driving/prompt.ts
|
|
2585
|
+
/**
|
|
2586
|
+
* Build the self-driving run prompt. The installed
|
|
2587
|
+
* `self-driving-setup` skill is the source of truth for the HOW of
|
|
2588
|
+
* every step (which MCP tools to call, which sources/scouts apply, how
|
|
2589
|
+
* to verify); this prompt carries the order, the wizard-specific
|
|
2590
|
+
* mechanics (wizard_ask, abort signals), and the project URLs.
|
|
2591
|
+
*/
|
|
2592
|
+
function buildSelfDrivingPrompt(ctx) {
|
|
2593
|
+
const uiHost = getUiHostFromHost(ctx.host).replace(/\/$/, "");
|
|
2594
|
+
const projectBase = `${uiHost}/project/${ctx.projectId}`;
|
|
2595
|
+
const integrationsSettingsUrl = `${projectBase}/settings/environment-integrations`;
|
|
2596
|
+
const orgAiSettingsUrl = `${uiHost}/settings/organization#organization-ai-consent`;
|
|
2597
|
+
const newWarehouseSourceUrl = `${projectBase}/pipeline/new/source`;
|
|
2598
|
+
const inboxUrl = `${projectBase}/inbox`;
|
|
2599
|
+
const optIn = (value) => value === true ? "ON" : value === false ? "OFF" : "unknown";
|
|
2600
|
+
const optIns = ctx.teamProductOptIns;
|
|
2601
|
+
return `You are setting up PostHog Self-driving for this project: you will enable the right signal sources, make sure GitHub is connected, tune the scout fleet, design custom scouts for what this product uniquely needs, and hand the user a configured inbox.
|
|
2602
|
+
|
|
2603
|
+
Project URLs:
|
|
2604
|
+
- Integrations settings (GitHub App install): ${integrationsSettingsUrl}
|
|
2605
|
+
- Organization AI settings: ${orgAiSettingsUrl}
|
|
2606
|
+
- New data warehouse source (Linear / Zendesk / GitHub issues / pganalyze): ${newWarehouseSourceUrl}
|
|
2607
|
+
- Self-driving inbox: ${inboxUrl}
|
|
2608
|
+
|
|
2609
|
+
Project state read at auth time (PostHog project settings — authoritative
|
|
2610
|
+
for whether a product is enabled, regardless of what this repo
|
|
2611
|
+
instruments; products are often instrumented from other repos or the
|
|
2612
|
+
snippet, so repo evidence may rule a product IN but never OUT):
|
|
2613
|
+
- Session replay recording: ${optIn(optIns?.sessionReplay)}
|
|
2614
|
+
- Exception autocapture (error tracking): ${optIn(optIns?.exceptionAutocapture)}
|
|
2615
|
+
- Surveys: ${optIn(optIns?.surveys)}
|
|
2616
|
+
|
|
2617
|
+
The installed skill is the source of truth for the HOW of every step:
|
|
2618
|
+
which MCP tools to call, which sources and scouts apply to this product,
|
|
2619
|
+
and how to verify each change. The STEPS below give the order and the
|
|
2620
|
+
wizard-specific mechanics — read the matching skill reference before
|
|
2621
|
+
doing the work, and do not invent steps the skill doesn't describe.
|
|
2622
|
+
|
|
2623
|
+
Before doing any work, create your FULL task list in a single TaskCreate
|
|
2624
|
+
call so the user can follow your progress in the TUI. Use exactly these
|
|
2625
|
+
tasks, in this order:
|
|
2626
|
+
1. Check Self-driving access
|
|
2627
|
+
2. Read project and current Self-driving state
|
|
2628
|
+
3. Connect GitHub (required)
|
|
2629
|
+
4. Enable signal sources
|
|
2630
|
+
5. Offer issue-tracker integrations
|
|
2631
|
+
6. Configure the scout fleet
|
|
2632
|
+
7. Design custom scouts
|
|
2633
|
+
8. Write report and hand off
|
|
2634
|
+
Drive the list with TaskUpdate — mark a task in_progress when you start
|
|
2635
|
+
it and completed when done. If a step turns out to be a no-op (e.g.
|
|
2636
|
+
GitHub is already connected), still mark its task completed.
|
|
2637
|
+
|
|
2638
|
+
Wizard mechanics:
|
|
2639
|
+
- Ask the user things ONLY with the wizard_ask MCP tool, and batch
|
|
2640
|
+
related questions (e.g. one multi-select for all issue trackers, not
|
|
2641
|
+
one ask per tool). The per-run ask budget is limited.
|
|
2642
|
+
- If wizard_ask is unavailable (CI / non-interactive), emit
|
|
2643
|
+
${AgentSignals.ABORT} requires-interactive-mode and halt.
|
|
2644
|
+
- When a step requires the user to do something in the browser, give
|
|
2645
|
+
them the exact URL inside the wizard_ask prompt text — do not try to
|
|
2646
|
+
open a browser yourself.
|
|
2647
|
+
- Emit ${AgentSignals.STATUS} lines as you complete each step so the
|
|
2648
|
+
user sees progress.
|
|
2649
|
+
|
|
2650
|
+
Follow these steps IN ORDER. Do not skip or reorder.
|
|
2651
|
+
|
|
2652
|
+
STEP 1 — Check Self-driving access. (skill: "Check access")
|
|
2653
|
+
Probe the Signals API as the skill describes. If the API is not
|
|
2654
|
+
available for this project (permission or not-found errors), emit
|
|
2655
|
+
${AgentSignals.ABORT} self-driving is not available for this project
|
|
2656
|
+
and halt.
|
|
2657
|
+
|
|
2658
|
+
STEP 2 — Read project and current Signals state. (skill: "Read context")
|
|
2659
|
+
If ./posthog-setup-report.md exists, read it as a strong hint for what
|
|
2660
|
+
THIS repo instruments — but it is often absent (users frequently don't
|
|
2661
|
+
commit it), so do NOT depend on it. Combine whatever you find with the
|
|
2662
|
+
project-state block above and the skill's server-side usage probes —
|
|
2663
|
+
repo evidence rules products in, never out. Do a light scan ONLY for
|
|
2664
|
+
what neither covers. List the currently enabled signal sources so every
|
|
2665
|
+
later write is idempotent.
|
|
2666
|
+
|
|
2667
|
+
STEP 3 — Connect GitHub. REQUIRED. (skill: "Connect GitHub")
|
|
2668
|
+
Signals cannot research or fix issues without code access. Check for
|
|
2669
|
+
an existing GitHub integration first; if absent, send the user to
|
|
2670
|
+
${integrationsSettingsUrl} via wizard_ask and verify the connection
|
|
2671
|
+
after they confirm. If the user cannot connect now, emit
|
|
2672
|
+
${AgentSignals.ABORT} github connection declined
|
|
2673
|
+
and halt — never finish setup without GitHub.
|
|
2674
|
+
|
|
2675
|
+
STEP 4 — Enable signal sources. (skill: "Enable sources")
|
|
2676
|
+
Enable the sources that match what this product actually uses, per
|
|
2677
|
+
the skill. Never enable a source for a tool the user hasn't
|
|
2678
|
+
confirmed they use.
|
|
2679
|
+
|
|
2680
|
+
STEP 5 — Offer issue-tracker integrations. (skill: "Connected tools")
|
|
2681
|
+
One batched multi-select wizard_ask for the external tools the skill
|
|
2682
|
+
lists. The run auto-connects the ones it can (GitHub Issues, and
|
|
2683
|
+
Linear via a one-click OAuth link), verifying each with a single
|
|
2684
|
+
silent check — never nudge. It arms the rest as dormant responders to
|
|
2685
|
+
finish later: for tools it can't auto-connect (Zendesk, pganalyze) it
|
|
2686
|
+
never sends the user to paste credentials and never re-prompts. Enable
|
|
2687
|
+
a source only for a tool the user picked.
|
|
2688
|
+
|
|
2689
|
+
STEP 6 — Configure the scout fleet. (skill: "Scouts")
|
|
2690
|
+
Materialize the fleet and disable the scouts whose product surface
|
|
2691
|
+
this project lacks, per the skill.
|
|
2692
|
+
|
|
2693
|
+
STEP 7 — Design custom scouts for this product. (skill: "Custom scouts")
|
|
2694
|
+
You are the only actor that has read this repo — turn that into
|
|
2695
|
+
coverage per the skill: a real gap analysis of the project's
|
|
2696
|
+
watchable surfaces against what the canonical fleet already covers,
|
|
2697
|
+
then custom scouts for the uncovered ones. Keep scout bodies
|
|
2698
|
+
high-level: describe the behavior and signal conditions to watch,
|
|
2699
|
+
referencing repo evidence by file/function name — never paste raw
|
|
2700
|
+
source, secrets, env values, or customer data into a scout body.
|
|
2701
|
+
Never edit canonical scout bodies. Propose all candidates in ONE
|
|
2702
|
+
batched wizard_ask
|
|
2703
|
+
before creating anything; the user declining everything (or finding
|
|
2704
|
+
no gap at all) is a valid outcome, not an abort. Mark the task
|
|
2705
|
+
completed either way.
|
|
2706
|
+
|
|
2707
|
+
STEP 8 — Write the report and hand off. (skill: "Report")
|
|
2708
|
+
Write the report per the skill, including follow-ups for anything
|
|
2709
|
+
deferred. Tell the user findings will start appearing in their inbox
|
|
2710
|
+
at ${inboxUrl} within about 30 minutes.`;
|
|
2711
|
+
}
|
|
2712
|
+
//#endregion
|
|
2713
|
+
//#region src/lib/programs/self-driving/content/tips.ts
|
|
2714
|
+
const SELF_DRIVING_TIPS = [
|
|
2715
|
+
{
|
|
2716
|
+
id: "what-is-a-signal-source",
|
|
2717
|
+
title: "What's a signal source?",
|
|
2718
|
+
description: "A signal source is a PostHog product or connected tool — errors, session replays, support, GitHub or Linear issues — that feeds findings into your Self-driving inbox."
|
|
2719
|
+
},
|
|
2720
|
+
{
|
|
2721
|
+
id: "what-is-a-scout",
|
|
2722
|
+
title: "What's a scout?",
|
|
2723
|
+
description: "Scouts are scheduled checks that scan your data and flag issues — a spike in errors, a dropping funnel — straight to your inbox."
|
|
2724
|
+
},
|
|
2725
|
+
{
|
|
2726
|
+
id: "findings-in-inbox",
|
|
2727
|
+
title: "Findings land in your inbox",
|
|
2728
|
+
description: "Once setup finishes, PostHog starts scanning within ~30 minutes and surfaces what it finds in your Self-driving inbox — grouped, researched, and ready to act on."
|
|
2729
|
+
}
|
|
2730
|
+
];
|
|
2731
|
+
const getTips = () => SELF_DRIVING_TIPS;
|
|
2732
|
+
//#endregion
|
|
2733
|
+
//#region src/lib/programs/self-driving/index.ts
|
|
2734
|
+
const SELF_DRIVING_SKILL_ID = "self-driving-setup";
|
|
2735
|
+
const REPORT_FILE = "posthog-self-driving-report.md";
|
|
2736
|
+
const DOCS_URL = "https://posthog.com/docs";
|
|
2737
|
+
const SUCCESS_MESSAGE = "Self-driving is on! PostHog will start scanning within ~30 minutes and surface findings in your inbox.";
|
|
2738
|
+
const WIZARD_MARKER = ".posthog-wizard";
|
|
2739
|
+
/**
|
|
2740
|
+
* Remove the installed setup skill. It is transient orchestration
|
|
2741
|
+
* knowledge (unlike integration skills such as the Next.js one, which
|
|
2742
|
+
* are worth keeping for the user's coding agents), so the program
|
|
2743
|
+
* cleans it up instead of showing the keep-skills prompt. Marker-
|
|
2744
|
+
* guarded: only directories the wizard installed are touched.
|
|
2745
|
+
*/
|
|
2746
|
+
async function removeInstalledSkill(installDir) {
|
|
2747
|
+
const skillDir = join(installDir, ".claude", "skills", SELF_DRIVING_SKILL_ID);
|
|
2748
|
+
try {
|
|
2749
|
+
await access(join(skillDir, WIZARD_MARKER));
|
|
2750
|
+
} catch {
|
|
2751
|
+
return;
|
|
2752
|
+
}
|
|
2753
|
+
await rm(skillDir, {
|
|
2754
|
+
recursive: true,
|
|
2755
|
+
force: true
|
|
2756
|
+
}).catch(() => void 0);
|
|
2757
|
+
}
|
|
2758
|
+
const run = {
|
|
2759
|
+
skillId: SELF_DRIVING_SKILL_ID,
|
|
2760
|
+
integrationLabel: SELF_DRIVING_SKILL_ID,
|
|
2761
|
+
customPrompt: buildSelfDrivingPrompt,
|
|
2762
|
+
successMessage: SUCCESS_MESSAGE,
|
|
2763
|
+
reportFile: REPORT_FILE,
|
|
2764
|
+
docsUrl: DOCS_URL,
|
|
2765
|
+
spinnerMessage: "Setting up PostHog Self-driving...",
|
|
2766
|
+
estimatedDurationMinutes: 10,
|
|
2767
|
+
abortCases: SELF_DRIVING_ABORT_CASES,
|
|
2768
|
+
maxQuestions: 13,
|
|
2769
|
+
richLinks: true,
|
|
2770
|
+
askTimeoutMs: 1800 * 1e3,
|
|
2771
|
+
postRun: async (session) => {
|
|
2772
|
+
await removeInstalledSkill(session.installDir);
|
|
2773
|
+
},
|
|
2774
|
+
buildOutroData: (_session, credentials) => {
|
|
2775
|
+
return {
|
|
2776
|
+
kind: "success",
|
|
2777
|
+
message: "Self-driving is on. PostHog is scanning your project — first findings hit your inbox within ~30 minutes.",
|
|
2778
|
+
primaryLink: {
|
|
2779
|
+
label: "Your Self-driving inbox",
|
|
2780
|
+
url: `${getUiHostFromHost(credentials.host).replace(/\/$/, "")}/project/${credentials.projectId}/inbox`
|
|
2781
|
+
},
|
|
2782
|
+
nextSteps: {
|
|
2783
|
+
heading: "In your inbox you can:",
|
|
2784
|
+
items: [
|
|
2785
|
+
"Review the findings PostHog surfaces",
|
|
2786
|
+
"Triage what matters and dismiss the noise",
|
|
2787
|
+
"Kick off fixes and open issues"
|
|
2788
|
+
]
|
|
2789
|
+
},
|
|
2790
|
+
reportFile: REPORT_FILE
|
|
2791
|
+
};
|
|
2792
|
+
}
|
|
2793
|
+
};
|
|
2794
|
+
const selfDrivingConfig = {
|
|
2795
|
+
...createSkillProgram({
|
|
2796
|
+
skillId: SELF_DRIVING_SKILL_ID,
|
|
2797
|
+
command: "self-driving",
|
|
2798
|
+
id: "self-driving",
|
|
2799
|
+
description: "Set up PostHog Self-driving for this project",
|
|
2800
|
+
integrationLabel: SELF_DRIVING_SKILL_ID,
|
|
2801
|
+
successMessage: SUCCESS_MESSAGE,
|
|
2802
|
+
reportFile: REPORT_FILE,
|
|
2803
|
+
docsUrl: DOCS_URL,
|
|
2804
|
+
spinnerMessage: "Setting up PostHog Self-driving...",
|
|
2805
|
+
estimatedDurationMinutes: 10,
|
|
2806
|
+
requires: ["posthog-integration"],
|
|
2807
|
+
abortCases: SELF_DRIVING_ABORT_CASES
|
|
2808
|
+
}),
|
|
2809
|
+
steps: SELF_DRIVING_PROGRAM,
|
|
2810
|
+
run,
|
|
2811
|
+
getTips,
|
|
2812
|
+
getContentBlocks: (store) => {
|
|
2813
|
+
const blocks = getContentBlocks$2(store);
|
|
2814
|
+
return blocks.map((b, i) => i === blocks.length - 1 && typeof b === "object" ? {
|
|
2815
|
+
...b,
|
|
2816
|
+
pause: 5e3
|
|
2817
|
+
} : b);
|
|
2818
|
+
}
|
|
2819
|
+
};
|
|
2820
|
+
//#endregion
|
|
2471
2821
|
//#region src/lib/programs/mcp/index.ts
|
|
2472
2822
|
const mcpAddConfig = {
|
|
2473
2823
|
id: "mcp-add",
|
|
@@ -2589,6 +2939,7 @@ const PROGRAM_REGISTRY = [
|
|
|
2589
2939
|
posthogDoctorConfig,
|
|
2590
2940
|
webAnalyticsDoctorConfig,
|
|
2591
2941
|
migrationConfig,
|
|
2942
|
+
selfDrivingConfig,
|
|
2592
2943
|
agentSkillConfig,
|
|
2593
2944
|
mcpAddConfig,
|
|
2594
2945
|
mcpRemoveConfig,
|
|
@@ -2609,6 +2960,7 @@ const Program = {
|
|
|
2609
2960
|
EventsAudit: eventsAuditConfig.id,
|
|
2610
2961
|
PosthogDoctor: posthogDoctorConfig.id,
|
|
2611
2962
|
WebAnalyticsDoctor: webAnalyticsDoctorConfig.id,
|
|
2963
|
+
SelfDriving: selfDrivingConfig.id,
|
|
2612
2964
|
AgentSkill: agentSkillConfig.id,
|
|
2613
2965
|
McpAdd: mcpAddConfig.id,
|
|
2614
2966
|
McpRemove: mcpRemoveConfig.id,
|
|
@@ -2653,7 +3005,7 @@ function runMcpAdd(argv) {
|
|
|
2653
3005
|
const debug = argv.debug;
|
|
2654
3006
|
const localMcp = argv.local;
|
|
2655
3007
|
try {
|
|
2656
|
-
const { startTUI } = await import("./start-tui-
|
|
3008
|
+
const { startTUI } = await import("./start-tui-CS802Ww9.js");
|
|
2657
3009
|
const { buildSession } = await import("./wizard-session-wPJtNl4c.js");
|
|
2658
3010
|
const tui = startTUI(VERSION, Program.McpAdd);
|
|
2659
3011
|
tui.store.session = buildSession({
|
|
@@ -2665,7 +3017,7 @@ function runMcpAdd(argv) {
|
|
|
2665
3017
|
} catch (error) {
|
|
2666
3018
|
if (!isTUIUnavailable(error)) throw error;
|
|
2667
3019
|
setUI(new LoggingUI());
|
|
2668
|
-
const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-
|
|
3020
|
+
const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-C58l_KpV.js").then((n) => n.r);
|
|
2669
3021
|
await addMCPServerToClientsStep({
|
|
2670
3022
|
local: localMcp,
|
|
2671
3023
|
features,
|
|
@@ -2704,7 +3056,7 @@ function runMcpRemove(argv) {
|
|
|
2704
3056
|
const debug = argv.debug;
|
|
2705
3057
|
const localMcp = argv.local;
|
|
2706
3058
|
try {
|
|
2707
|
-
const { startTUI } = await import("./start-tui-
|
|
3059
|
+
const { startTUI } = await import("./start-tui-CS802Ww9.js");
|
|
2708
3060
|
const { buildSession } = await import("./wizard-session-wPJtNl4c.js");
|
|
2709
3061
|
const tui = startTUI(VERSION, Program.McpRemove);
|
|
2710
3062
|
tui.store.session = buildSession({
|
|
@@ -2713,7 +3065,7 @@ function runMcpRemove(argv) {
|
|
|
2713
3065
|
});
|
|
2714
3066
|
} catch {
|
|
2715
3067
|
setUI(new LoggingUI());
|
|
2716
|
-
const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-
|
|
3068
|
+
const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-C58l_KpV.js").then((n) => n.r);
|
|
2717
3069
|
await removeMCPServerFromClientsStep({ local: localMcp });
|
|
2718
3070
|
}
|
|
2719
3071
|
})();
|
|
@@ -2735,7 +3087,7 @@ function runMcpTutorial(argv) {
|
|
|
2735
3087
|
const debug = argv.debug;
|
|
2736
3088
|
const localMcp = argv.local;
|
|
2737
3089
|
try {
|
|
2738
|
-
const { startTUI } = await import("./start-tui-
|
|
3090
|
+
const { startTUI } = await import("./start-tui-CS802Ww9.js");
|
|
2739
3091
|
const { buildSession } = await import("./wizard-session-wPJtNl4c.js");
|
|
2740
3092
|
const tui = startTUI(VERSION, Program.McpTutorial);
|
|
2741
3093
|
tui.store.session = buildSession({
|
|
@@ -2790,7 +3142,7 @@ function runWizard(config, options) {
|
|
|
2790
3142
|
(async () => {
|
|
2791
3143
|
try {
|
|
2792
3144
|
const installDir = options.installDir || process.cwd();
|
|
2793
|
-
const { startTUI } = await import("./start-tui-
|
|
3145
|
+
const { startTUI } = await import("./start-tui-CS802Ww9.js");
|
|
2794
3146
|
const { buildSession, RunPhase } = await import("./wizard-session-wPJtNl4c.js");
|
|
2795
3147
|
const { TaskStreamPush } = await import("./task-stream-BQNSp0qR.js");
|
|
2796
3148
|
const { PostHogDestination } = await import("./posthog-Cr37rnla.js");
|
|
@@ -2846,7 +3198,7 @@ function runWizard(config, options) {
|
|
|
2846
3198
|
await activeTui.store.getGate("health-check");
|
|
2847
3199
|
const skipAgent = config.run == null;
|
|
2848
3200
|
if (skipAgent) {
|
|
2849
|
-
const { getOrAskForProjectData } = await import("./setup-utils-
|
|
3201
|
+
const { getOrAskForProjectData } = await import("./setup-utils-CNWIMZ-d.js").then((n) => n.r);
|
|
2850
3202
|
const { projectApiKey, host, accessToken, projectId } = await getOrAskForProjectData({
|
|
2851
3203
|
signup: session.signup,
|
|
2852
3204
|
ci: session.ci,
|
|
@@ -2861,7 +3213,7 @@ function runWizard(config, options) {
|
|
|
2861
3213
|
projectId
|
|
2862
3214
|
});
|
|
2863
3215
|
} else {
|
|
2864
|
-
const { runAgent } = await import("./agent-runner-
|
|
3216
|
+
const { runAgent } = await import("./agent-runner-BNGW3osc.js");
|
|
2865
3217
|
await runAgent(config, activeTui.store.session);
|
|
2866
3218
|
}
|
|
2867
3219
|
const isDone = () => skipAgent ? activeTui.store.session.outroDismissed : activeTui.store.session.skillsComplete;
|
|
@@ -2938,10 +3290,10 @@ function runWizardCI(config, options) {
|
|
|
2938
3290
|
(async () => {
|
|
2939
3291
|
const path = await import("path");
|
|
2940
3292
|
const { buildSession } = await import("./wizard-session-wPJtNl4c.js");
|
|
2941
|
-
const { readEnvironment } = await import("./environment-
|
|
3293
|
+
const { readEnvironment } = await import("./environment-DS5Pq9Wm.js").then((n) => n.t);
|
|
2942
3294
|
const { readApiKeyFromEnv } = await import("./env-api-key-MlzJYAvt.js").then((n) => n.t);
|
|
2943
|
-
const { configureLogFileFromEnvironment, logToFile } = await import("./debug-
|
|
2944
|
-
const { wizardAbort, WizardError } = await import("./wizard-abort-
|
|
3295
|
+
const { configureLogFileFromEnvironment, logToFile } = await import("./debug-fg4BAKKA.js");
|
|
3296
|
+
const { wizardAbort, WizardError } = await import("./wizard-abort-CR3w2Efg.js");
|
|
2945
3297
|
configureLogFileFromEnvironment();
|
|
2946
3298
|
const env = readEnvironment();
|
|
2947
3299
|
const apiKey = options.apiKey ?? readApiKeyFromEnv() ?? void 0;
|
|
@@ -2992,7 +3344,7 @@ function runWizardCI(config, options) {
|
|
|
2992
3344
|
})
|
|
2993
3345
|
});
|
|
2994
3346
|
}
|
|
2995
|
-
const { runAgent } = await import("./agent-runner-
|
|
3347
|
+
const { runAgent } = await import("./agent-runner-BNGW3osc.js");
|
|
2996
3348
|
await runAgent(config, session);
|
|
2997
3349
|
} catch (error) {
|
|
2998
3350
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -3210,6 +3562,34 @@ const PromptLabel = ({ message }) => {
|
|
|
3210
3562
|
}) });
|
|
3211
3563
|
};
|
|
3212
3564
|
//#endregion
|
|
3565
|
+
//#region src/ui/tui/primitives/ConfirmButton.tsx
|
|
3566
|
+
/**
|
|
3567
|
+
* ConfirmButton — the confirm row used to submit a selection.
|
|
3568
|
+
*
|
|
3569
|
+
* Pure render. Multi-select menus (PickerMenu mode="multi", GroupedPickerMenu)
|
|
3570
|
+
* append this below their options as the final focusable row: the user toggles
|
|
3571
|
+
* options with enter, then arrows down onto this row and presses enter to
|
|
3572
|
+
* submit. This replaces the older "enter anywhere submits" pattern, which
|
|
3573
|
+
* confused people who expected enter to toggle the focused item.
|
|
3574
|
+
*
|
|
3575
|
+
* Renders flat, mirroring the option rows — a focus triangle and the label,
|
|
3576
|
+
* accent and bold when focused, dimmed otherwise — so it lines up under the
|
|
3577
|
+
* options instead of sitting in a separate boxed target.
|
|
3578
|
+
*/
|
|
3579
|
+
const ConfirmButton = ({ label = "Confirm", focused, count }) => {
|
|
3580
|
+
const text = count && count > 0 ? `${label} (${count})` : label;
|
|
3581
|
+
return /* @__PURE__ */ jsxs(Text, {
|
|
3582
|
+
color: focused ? Colors.accent : void 0,
|
|
3583
|
+
bold: focused,
|
|
3584
|
+
dimColor: !focused,
|
|
3585
|
+
children: [
|
|
3586
|
+
focused ? Icons.triangleSmallRight : " ",
|
|
3587
|
+
" ",
|
|
3588
|
+
text
|
|
3589
|
+
]
|
|
3590
|
+
});
|
|
3591
|
+
};
|
|
3592
|
+
//#endregion
|
|
3213
3593
|
//#region src/ui/tui/hooks/keyboard-hints-utils.ts
|
|
3214
3594
|
/** Default priorities by key type. */
|
|
3215
3595
|
const DEFAULT_PRIORITY = {
|
|
@@ -3345,8 +3725,10 @@ function useKeyBindings(id, bindings) {
|
|
|
3345
3725
|
//#region src/ui/tui/primitives/PickerMenu.tsx
|
|
3346
3726
|
/**
|
|
3347
3727
|
* PickerMenu — Single and multi select.
|
|
3348
|
-
* Single mode: custom renderer with small triangle indicator.
|
|
3349
|
-
* Multi mode: checkbox glyphs with
|
|
3728
|
+
* Single mode: custom renderer with small triangle indicator; enter selects.
|
|
3729
|
+
* Multi mode: checkbox glyphs toggled with enter, plus a focusable
|
|
3730
|
+
* Confirm button below the options. The cursor moves onto the button and
|
|
3731
|
+
* enter submits — see MultiPickerMenu for the rationale.
|
|
3350
3732
|
*
|
|
3351
3733
|
* Key bindings are declared via useKeyBindings, which auto-registers
|
|
3352
3734
|
* hints in the KeyboardHintsBar.
|
|
@@ -3372,6 +3754,12 @@ function firstEnabled(options) {
|
|
|
3372
3754
|
const idx = options.findIndex((o) => !o.disabled);
|
|
3373
3755
|
return idx === -1 ? 0 : idx;
|
|
3374
3756
|
}
|
|
3757
|
+
/** Index of the last enabled option, for wrapping from the button onto
|
|
3758
|
+
* the bottom of the grid. */
|
|
3759
|
+
function lastEnabled(options) {
|
|
3760
|
+
for (let i = options.length - 1; i >= 0; i--) if (!options[i]?.disabled) return i;
|
|
3761
|
+
return options.length - 1;
|
|
3762
|
+
}
|
|
3375
3763
|
const PickerMenu = ({ message, options, mode = "single", centered = false, columns = 1, optionMarginBottom = 0, onSelect }) => {
|
|
3376
3764
|
if (mode === "multi") return /* @__PURE__ */ jsx(MultiPickerMenu, {
|
|
3377
3765
|
message,
|
|
@@ -3475,60 +3863,90 @@ const SinglePickerMenu = ({ message, options, centered = false, columns = 1, opt
|
|
|
3475
3863
|
})]
|
|
3476
3864
|
});
|
|
3477
3865
|
};
|
|
3478
|
-
/**
|
|
3866
|
+
/**
|
|
3867
|
+
* Custom multi-select with checkbox glyphs and accent highlight.
|
|
3868
|
+
*
|
|
3869
|
+
* Interaction model (shared with GroupedPickerMenu):
|
|
3870
|
+
* - \u2191\u2193 move the cursor through the options AND onto the Confirm button,
|
|
3871
|
+
* which lives just past the last option.
|
|
3872
|
+
* - enter toggles the focused option (no more "space toggles but enter
|
|
3873
|
+
* advances" split that tripped people up). Space is kept as an
|
|
3874
|
+
* undocumented alias, but the hints bar advertises only enter.
|
|
3875
|
+
* - moving onto the Confirm button and pressing enter submits the
|
|
3876
|
+
* current selection.
|
|
3877
|
+
*/
|
|
3479
3878
|
const MultiPickerMenu = ({ message, options, centered = false, columns = 1, optionMarginBottom = 0, onSelect }) => {
|
|
3480
3879
|
const [focused, setFocused] = useState(() => firstEnabled(options));
|
|
3880
|
+
const [onButton, setOnButton] = useState(false);
|
|
3481
3881
|
const [selected, setSelected] = useState(/* @__PURE__ */ new Set());
|
|
3482
3882
|
const rows = Math.ceil(options.length / columns);
|
|
3483
3883
|
useEffect(() => {
|
|
3484
3884
|
if (focused >= options.length || options[focused]?.disabled) setFocused(firstEnabled(options));
|
|
3485
3885
|
}, [options, focused]);
|
|
3486
|
-
const
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3886
|
+
const confirm = () => {
|
|
3887
|
+
onSelect([...selected].sort((a, b) => a - b).map((i) => options[i].value));
|
|
3888
|
+
};
|
|
3889
|
+
const bindings = [{
|
|
3890
|
+
match: ["upArrow", "downArrow"],
|
|
3891
|
+
label: "↑↓",
|
|
3892
|
+
action: "navigate",
|
|
3893
|
+
handler: (_input, key) => {
|
|
3894
|
+
if (key.upArrow) {
|
|
3895
|
+
if (onButton) {
|
|
3896
|
+
setOnButton(false);
|
|
3897
|
+
setFocused(lastEnabled(options));
|
|
3898
|
+
return;
|
|
3899
|
+
}
|
|
3900
|
+
const col = Math.floor(focused / rows);
|
|
3901
|
+
let r = focused % rows - 1;
|
|
3902
|
+
while (r >= 0 && options[col * rows + r]?.disabled) r--;
|
|
3903
|
+
if (r >= 0) setFocused(col * rows + r);
|
|
3904
|
+
else setOnButton(true);
|
|
3494
3905
|
}
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
if (options[focused]?.exclusive) return new Set([focused]);
|
|
3509
|
-
for (const i of next) if (options[i]?.exclusive) next.delete(i);
|
|
3510
|
-
next.add(focused);
|
|
3511
|
-
return next;
|
|
3512
|
-
});
|
|
3906
|
+
if (key.downArrow) {
|
|
3907
|
+
if (onButton) {
|
|
3908
|
+
setOnButton(false);
|
|
3909
|
+
setFocused(firstEnabled(options));
|
|
3910
|
+
return;
|
|
3911
|
+
}
|
|
3912
|
+
const col = Math.floor(focused / rows);
|
|
3913
|
+
const row = focused % rows;
|
|
3914
|
+
const colLen = Math.min(rows, options.length - col * rows);
|
|
3915
|
+
let r = row + 1;
|
|
3916
|
+
while (r < colLen && options[col * rows + r]?.disabled) r++;
|
|
3917
|
+
if (r < colLen) setFocused(col * rows + r);
|
|
3918
|
+
else setOnButton(true);
|
|
3513
3919
|
}
|
|
3514
|
-
}
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
} else onSelect([...selected].sort().map((i) => options[i].value));
|
|
3920
|
+
}
|
|
3921
|
+
}, {
|
|
3922
|
+
match: ["space", "return"],
|
|
3923
|
+
label: "enter",
|
|
3924
|
+
action: "select",
|
|
3925
|
+
handler: () => {
|
|
3926
|
+
if (onButton) {
|
|
3927
|
+
confirm();
|
|
3928
|
+
return;
|
|
3524
3929
|
}
|
|
3930
|
+
if (options[focused]?.disabled) return;
|
|
3931
|
+
setSelected((prev) => {
|
|
3932
|
+
const next = new Set(prev);
|
|
3933
|
+
if (next.has(focused)) {
|
|
3934
|
+
next.delete(focused);
|
|
3935
|
+
return next;
|
|
3936
|
+
}
|
|
3937
|
+
if (options[focused]?.exclusive) return new Set([focused]);
|
|
3938
|
+
for (const i of next) if (options[i]?.exclusive) next.delete(i);
|
|
3939
|
+
next.add(focused);
|
|
3940
|
+
return next;
|
|
3941
|
+
});
|
|
3525
3942
|
}
|
|
3526
|
-
];
|
|
3943
|
+
}];
|
|
3527
3944
|
if (columns > 1) bindings.splice(1, 0, {
|
|
3528
3945
|
match: ["leftArrow", "rightArrow"],
|
|
3529
3946
|
label: "←→",
|
|
3530
3947
|
action: "navigate",
|
|
3531
3948
|
handler: (_input, key) => {
|
|
3949
|
+
if (onButton) return;
|
|
3532
3950
|
const col = Math.floor(focused / rows);
|
|
3533
3951
|
const row = focused % rows;
|
|
3534
3952
|
let next = focused;
|
|
@@ -3550,43 +3968,65 @@ const MultiPickerMenu = ({ message, options, centered = false, columns = 1, opti
|
|
|
3550
3968
|
return /* @__PURE__ */ jsxs(Box, {
|
|
3551
3969
|
flexDirection: "column",
|
|
3552
3970
|
alignItems: centered ? "center" : void 0,
|
|
3553
|
-
children: [
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
children:
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
children:
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3971
|
+
children: [
|
|
3972
|
+
/* @__PURE__ */ jsx(PromptLabel, { message }),
|
|
3973
|
+
/* @__PURE__ */ jsx(Box, {
|
|
3974
|
+
flexDirection: "row",
|
|
3975
|
+
gap: 4,
|
|
3976
|
+
marginLeft: centered ? 0 : 2,
|
|
3977
|
+
marginTop: 1,
|
|
3978
|
+
children: columnArrays.map((colOpts, colIdx) => /* @__PURE__ */ jsx(Box, {
|
|
3979
|
+
flexDirection: "column",
|
|
3980
|
+
children: colOpts.map((opt, rowIdx) => {
|
|
3981
|
+
const flatIdx = colIdx * rows + rowIdx;
|
|
3982
|
+
const isFocused = !onButton && flatIdx === focused;
|
|
3983
|
+
const isSelected = selected.has(flatIdx);
|
|
3984
|
+
const label = opt.hint ? `${opt.label} (${opt.hint})` : opt.label;
|
|
3985
|
+
const checkbox = isSelected ? Icons.squareFilled : Icons.squareOpen;
|
|
3986
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
3987
|
+
flexDirection: "column",
|
|
3988
|
+
marginBottom: optionMarginBottom,
|
|
3989
|
+
children: [/* @__PURE__ */ jsxs(Box, {
|
|
3990
|
+
gap: 1,
|
|
3991
|
+
children: [
|
|
3992
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3993
|
+
color: isSelected ? "white" : Colors.muted,
|
|
3994
|
+
dimColor: !isFocused && !isSelected,
|
|
3995
|
+
children: checkbox
|
|
3996
|
+
}),
|
|
3997
|
+
opt.icon && /* @__PURE__ */ jsx(Text, {
|
|
3998
|
+
color: opt.icon.color,
|
|
3999
|
+
children: opt.icon.glyph
|
|
4000
|
+
}),
|
|
4001
|
+
/* @__PURE__ */ jsx(Text, {
|
|
4002
|
+
color: opt.disabled ? Colors.muted : isFocused ? Colors.accent : void 0,
|
|
4003
|
+
bold: isFocused && !opt.disabled,
|
|
4004
|
+
dimColor: !isFocused || opt.disabled,
|
|
4005
|
+
children: label
|
|
4006
|
+
})
|
|
4007
|
+
]
|
|
4008
|
+
}), opt.description && /* @__PURE__ */ jsx(Box, {
|
|
4009
|
+
marginLeft: 4,
|
|
4010
|
+
width: 56,
|
|
4011
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
4012
|
+
dimColor: true,
|
|
4013
|
+
wrap: "wrap",
|
|
4014
|
+
children: opt.description
|
|
4015
|
+
})
|
|
4016
|
+
})]
|
|
4017
|
+
}, flatIdx);
|
|
4018
|
+
})
|
|
4019
|
+
}, colIdx))
|
|
4020
|
+
}),
|
|
4021
|
+
/* @__PURE__ */ jsx(Box, {
|
|
4022
|
+
marginTop: 1,
|
|
4023
|
+
marginLeft: centered ? 0 : 2,
|
|
4024
|
+
children: /* @__PURE__ */ jsx(ConfirmButton, {
|
|
4025
|
+
focused: onButton,
|
|
4026
|
+
count: selected.size
|
|
3587
4027
|
})
|
|
3588
|
-
}
|
|
3589
|
-
|
|
4028
|
+
})
|
|
4029
|
+
]
|
|
3590
4030
|
});
|
|
3591
4031
|
};
|
|
3592
4032
|
//#endregion
|
|
@@ -3771,7 +4211,7 @@ async function runDoctorCI(options) {
|
|
|
3771
4211
|
getUI().intro("Welcome to the PostHog setup wizard");
|
|
3772
4212
|
getUI().log.info("Running posthog-doctor in CI mode");
|
|
3773
4213
|
try {
|
|
3774
|
-
const { getOrAskForProjectData } = await import("./setup-utils-
|
|
4214
|
+
const { getOrAskForProjectData } = await import("./setup-utils-CNWIMZ-d.js").then((n) => n.r);
|
|
3775
4215
|
const { host, accessToken, projectId } = await getOrAskForProjectData({
|
|
3776
4216
|
signup: false,
|
|
3777
4217
|
ci: true,
|
|
@@ -3788,7 +4228,7 @@ async function runDoctorCI(options) {
|
|
|
3788
4228
|
for (const issue of sorted) getUI().log.info(` • [${issue.severity}] ${getKindMeta(issue.kind).title}`);
|
|
3789
4229
|
process.exit(1);
|
|
3790
4230
|
} catch (error) {
|
|
3791
|
-
const { ApiError } = await import("./api-
|
|
4231
|
+
const { ApiError } = await import("./api-DCHci5SD.js").then((n) => n.n);
|
|
3792
4232
|
const message = error instanceof ApiError && error.statusCode === 401 ? "Your PostHog API key is invalid or expired." : error instanceof Error ? error.message : String(error);
|
|
3793
4233
|
getUI().log.error(`Doctor failed: ${message}`);
|
|
3794
4234
|
process.exit(1);
|
|
@@ -3836,6 +4276,30 @@ const migrateCommand = nativeCommandFactory(migrationConfig);
|
|
|
3836
4276
|
*/
|
|
3837
4277
|
const revenueCommand = nativeCommandFactory(revenueAnalyticsConfig);
|
|
3838
4278
|
//#endregion
|
|
4279
|
+
//#region src/commands/self-driving.ts
|
|
4280
|
+
const selfDrivingCommand = {
|
|
4281
|
+
name: "self-driving",
|
|
4282
|
+
description: selfDrivingConfig.description,
|
|
4283
|
+
options: {
|
|
4284
|
+
...skillProgramOptions,
|
|
4285
|
+
...selfDrivingConfig.cliOptions ?? {}
|
|
4286
|
+
},
|
|
4287
|
+
check: (argv) => {
|
|
4288
|
+
if (argv.signup) throw new Error("`self-driving` cannot run with --signup. It builds on an existing PostHog integration — run the base `wizard` to create your account and set up PostHog first, then run `wizard self-driving`.");
|
|
4289
|
+
if (argv.ci) throw new Error("`self-driving` cannot run in CI mode — it requires interactive steps (GitHub connect, issue-tracker selection, custom-scout approval).");
|
|
4290
|
+
return true;
|
|
4291
|
+
},
|
|
4292
|
+
handler: (argv) => {
|
|
4293
|
+
const extras = selfDrivingConfig.mapCliOptions?.(argv) ?? {};
|
|
4294
|
+
const options = {
|
|
4295
|
+
...argv,
|
|
4296
|
+
...extras
|
|
4297
|
+
};
|
|
4298
|
+
if (options.ci) runWizardCI(selfDrivingConfig, options);
|
|
4299
|
+
else runWizard(selfDrivingConfig, options);
|
|
4300
|
+
}
|
|
4301
|
+
};
|
|
4302
|
+
//#endregion
|
|
3839
4303
|
//#region src/commands/slack.ts
|
|
3840
4304
|
const slackCommand = {
|
|
3841
4305
|
name: "slack",
|
|
@@ -3851,7 +4315,7 @@ function runSlackConnect(argv) {
|
|
|
3851
4315
|
(async () => {
|
|
3852
4316
|
const debug = argv.debug;
|
|
3853
4317
|
try {
|
|
3854
|
-
const { startTUI } = await import("./start-tui-
|
|
4318
|
+
const { startTUI } = await import("./start-tui-CS802Ww9.js");
|
|
3855
4319
|
const { buildSession } = await import("./wizard-session-wPJtNl4c.js");
|
|
3856
4320
|
const tui = startTUI(VERSION, Program.SlackConnect);
|
|
3857
4321
|
tui.store.session = buildSession({ debug });
|
|
@@ -4228,8 +4692,8 @@ function resolveInstallDir() {
|
|
|
4228
4692
|
if (inline) return inline.slice(14);
|
|
4229
4693
|
return process.env.POSTHOG_WIZARD_INSTALL_DIR ?? process.cwd();
|
|
4230
4694
|
}
|
|
4231
|
-
Wizard.use(basicIntegrationCommand).use(mcpCommand).use(cliCommand).use(auditCommand).use(doctorCommand).use(migrateCommand).use(revenueCommand).use(slackCommand).use(uploadSourcemapsCommand).use(skillCommand).init();
|
|
4695
|
+
Wizard.use(basicIntegrationCommand).use(mcpCommand).use(cliCommand).use(auditCommand).use(doctorCommand).use(migrateCommand).use(revenueCommand).use(selfDrivingCommand).use(slackCommand).use(uploadSourcemapsCommand).use(skillCommand).init();
|
|
4232
4696
|
//#endregion
|
|
4233
|
-
export { POSTHOG_SDKS$1 as _,
|
|
4697
|
+
export { POSTHOG_SDKS$1 as _, ConfirmButton as a, runWizard as c, getProgramConfig as d, DISPLAY_NAME as f, getContentBlocks$2 as g, fetchHealthIssues as h, useKeyboardHintsContext as i, PROGRAM_REGISTRY as l, getKindMeta as m, useKeyBindings as n, PromptLabel as o, SOURCE_MAPS_CONTEXT_KEYS as p, KeyboardHintsProvider as r, runWizardCI as s, PickerMenu as t, Program as u, STRIPE_SDKS as v };
|
|
4234
4698
|
|
|
4235
4699
|
//# sourceMappingURL=bin.js.map
|