@posthog/wizard 2.77.0 → 2.79.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -26
- package/dist/{add-mcp-server-to-clients-BnRyE4pw.js → add-mcp-server-to-clients-amlJWW7W.js} +6 -5
- package/dist/{add-mcp-server-to-clients-BnRyE4pw.js.map → add-mcp-server-to-clients-amlJWW7W.js.map} +1 -1
- package/dist/agent-CNrEC-9v.js +3184 -0
- package/dist/agent-CNrEC-9v.js.map +1 -0
- package/dist/{agent-interface-Avtr_5M5.js → agent-interface-BXvmAm4c.js} +462 -385
- package/dist/agent-interface-BXvmAm4c.js.map +1 -0
- package/dist/{agent-prompt-loader-CHixNPgY.js → agent-prompt-loader-DiKUbhi_.js} +6 -6
- package/dist/agent-prompt-loader-DiKUbhi_.js.map +1 -0
- package/dist/analytics-DxwRi2Hf.js +2 -0
- package/dist/{analytics-C67F2vee.js → analytics-VRYdebXW.js} +10 -6
- package/dist/analytics-VRYdebXW.js.map +1 -0
- package/dist/{api-Dj1yabTj.js → api-DGuJTzjr.js} +4 -17
- package/dist/api-DGuJTzjr.js.map +1 -0
- package/dist/bin.js +415 -70
- package/dist/bin.js.map +1 -1
- package/dist/{bounded-fs-CWRYuLAn.js → bounded-fs-Cpn129A4.js} +4 -4
- package/dist/bounded-fs-Cpn129A4.js.map +1 -0
- package/dist/check-screens.tsx +1 -1
- package/dist/{ci-install-CvXL5h13.js → ci-install-BPA6gzEq.js} +6 -5
- package/dist/ci-install-BPA6gzEq.js.map +1 -0
- package/dist/constants-CuJfQEcC.js +260 -0
- package/dist/constants-CuJfQEcC.js.map +1 -0
- package/dist/{debug-CziFS0cA.js → debug-B9k4ideV.js} +1 -1
- package/dist/debug-Cj-8vfXY.js +171 -0
- package/dist/debug-Cj-8vfXY.js.map +1 -0
- package/dist/{defaults-4c4YwTmW.js → defaults-C6J7yL4O.js} +1 -1
- package/dist/{defaults-4c4YwTmW.js.map → defaults-C6J7yL4O.js.map} +1 -1
- package/dist/endpoints-DnIX0pZH.js +108 -0
- package/dist/endpoints-DnIX0pZH.js.map +1 -0
- package/dist/{env-api-key-BZ5wE3Y4.js → env-api-key-BWdKpGEr.js} +3 -3
- package/dist/env-api-key-BWdKpGEr.js.map +1 -0
- package/dist/{environment-BEvsey6i.js → environment-DZYUSCpV.js} +6 -6
- package/dist/environment-DZYUSCpV.js.map +1 -0
- package/dist/{errors-BoJvrdw8.js → errors-ddDE6MbA.js} +27 -76
- package/dist/errors-ddDE6MbA.js.map +1 -0
- package/dist/{file-BoD3REGB.js → file-dEhr-l3n.js} +3 -3
- package/dist/file-dEhr-l3n.js.map +1 -0
- package/dist/{file-watcher-BPFazvG_.js → file-watcher-CPM-Nn9L.js} +2 -2
- package/dist/{file-watcher-BPFazvG_.js.map → file-watcher-CPM-Nn9L.js.map} +1 -1
- package/dist/{gateway-session-xPFv6p5c.js → gateway-CVU1G0H3.js} +205 -20
- package/dist/gateway-CVU1G0H3.js.map +1 -0
- package/dist/generate-version.cjs +1 -1
- package/dist/{headless-ui-CsmQrDIl.js → headless-ui-pY2xB5ug.js} +13 -2
- package/dist/headless-ui-pY2xB5ug.js.map +1 -0
- package/dist/{interactive-Dej-sxvR.js → interactive-BOGlinZe.js} +2 -2
- package/dist/interactive-BOGlinZe.js.map +1 -0
- package/dist/{local-dev-DPZiIPCK.js → local-dev-McsurOC-.js} +2 -2
- package/dist/local-dev-McsurOC-.js.map +1 -0
- package/dist/logging-ui-CUxNYF2t.js +226 -0
- package/dist/logging-ui-CUxNYF2t.js.map +1 -0
- package/dist/mcp-JcsBBnWv.js +97 -0
- package/dist/mcp-JcsBBnWv.js.map +1 -0
- package/dist/{mcp-prompt-streaming-BU_kuur_.js → mcp-prompt-streaming-B-p_Pvb2.js} +7 -6
- package/dist/mcp-prompt-streaming-B-p_Pvb2.js.map +1 -0
- package/dist/{mint-failure-BrleGqMd.js → mint-failure-CZFZpHpW.js} +749 -130
- package/dist/mint-failure-CZFZpHpW.js.map +1 -0
- package/dist/models-DnAY67Lg.js +83 -0
- package/dist/models-DnAY67Lg.js.map +1 -0
- package/dist/{non-interactive-DcOjH2fw.js → non-interactive-DR1CWXY1.js} +3 -3
- package/dist/non-interactive-DR1CWXY1.js.map +1 -0
- package/dist/oauth-session-CQTFOk-I.js +74 -0
- package/dist/oauth-session-CQTFOk-I.js.map +1 -0
- package/dist/{orchestrator-tools-DXwr8Sp3.js → orchestrator-tools-CBdt-SXO.js} +4 -4
- package/dist/orchestrator-tools-CBdt-SXO.js.map +1 -0
- package/dist/{package-json-xt3eeyBI.js → package-json-DY70kkNp.js} +2 -2
- package/dist/package-json-DY70kkNp.js.map +1 -0
- package/dist/{pi-mY8I2XkG.js → pi-BtqcLX3y.js} +444 -81
- package/dist/pi-BtqcLX3y.js.map +1 -0
- package/dist/{playground-CDUUKLkC.js → playground-Dz-ZVjBk.js} +11 -7
- package/dist/playground-Dz-ZVjBk.js.map +1 -0
- package/dist/{posthog-Hc_-9wrr.js → posthog-6Uqw_Eux.js} +9 -4
- package/dist/posthog-6Uqw_Eux.js.map +1 -0
- package/dist/{provisioning-xfdjhFtA.js → provisioning-Zf7yPcEs.js} +6 -5
- package/dist/provisioning-Zf7yPcEs.js.map +1 -0
- package/dist/{queue-tools-C8y_xZJi.js → queue-tools-B7_aCyd-.js} +7 -86
- package/dist/queue-tools-B7_aCyd-.js.map +1 -0
- package/dist/{registry-DTmREJ-f.js → registry-B6iLGorH.js} +307 -48
- package/dist/registry-B6iLGorH.js.map +1 -0
- package/dist/run-agent-legacy-6WcYMaR9.js +3541 -0
- package/dist/run-agent-legacy-6WcYMaR9.js.map +1 -0
- package/dist/{security-Dw2oFJjP.js → security-lkBwWbrK.js} +17 -7
- package/dist/security-lkBwWbrK.js.map +1 -0
- package/dist/{setup-utils-fjJTBhaB.js → setup-utils-dCViCC6s.js} +47 -19
- package/dist/setup-utils-dCViCC6s.js.map +1 -0
- package/dist/smoke-test.sh +1 -1
- package/dist/{start-tui-UNe2xQ0U.js → start-tui-oCWMgsDP.js} +40 -46
- package/dist/start-tui-oCWMgsDP.js.map +1 -0
- package/dist/{steps-C2yqOk_h.js → steps-gx0Pq4I4.js} +7 -7
- package/dist/{steps-C2yqOk_h.js.map → steps-gx0Pq4I4.js.map} +1 -1
- package/dist/{store-Bic4Cr3L.js → store-xYy_6Ruv.js} +19 -29
- package/dist/store-xYy_6Ruv.js.map +1 -0
- package/dist/{subagent-Dz41vV9j.js → subagent-Bfy0sfhU.js} +8 -3
- package/dist/subagent-Bfy0sfhU.js.map +1 -0
- package/dist/{task-5-fw_Vw3.js → task-BOfw7GPc.js} +124 -36
- package/dist/task-BOfw7GPc.js.map +1 -0
- package/dist/{task-stream-dVzl6b_q.js → task-stream-kYlm9qd0.js} +47 -17
- package/dist/task-stream-kYlm9qd0.js.map +1 -0
- package/dist/{tasks-D1c2z1aw.js → tasks-Bbv_lOBG.js} +17 -13
- package/dist/tasks-Bbv_lOBG.js.map +1 -0
- package/dist/{telemetry-BRnxBRWK.js → telemetry-Bpv-Mh5B.js} +5 -5
- package/dist/telemetry-Bpv-Mh5B.js.map +1 -0
- package/dist/{terminal-9bvRa4Qt.js → terminal-D07EQ2y0.js} +41 -76
- package/dist/terminal-D07EQ2y0.js.map +1 -0
- package/dist/{tools-Dp6i9k70.js → tools-Cc41af5W.js} +11 -11
- package/dist/tools-Cc41af5W.js.map +1 -0
- package/dist/ui-CGXtC7Vn.js +15 -0
- package/dist/ui-CGXtC7Vn.js.map +1 -0
- package/dist/version-Cadof0Z_.js +6 -0
- package/dist/version-Cadof0Z_.js.map +1 -0
- package/dist/warlock-smoke-test.ts +2 -2
- package/dist/{wizard-abort-lE6umflt.js → wizard-abort-HDbP3YcS.js} +23 -20
- package/dist/wizard-abort-HDbP3YcS.js.map +1 -0
- package/dist/wizard-abort-Y-Ip2K4z.js +3 -0
- package/dist/{wizard-session-FSJCkTcP.js → wizard-session-2w4Ru-Wz.js} +12 -16
- package/dist/wizard-session-2w4Ru-Wz.js.map +1 -0
- package/dist/wizard-session-DGaUHOF3.js +2 -0
- package/dist/wizard-ui-DoyOZxK8.js +16 -0
- package/dist/wizard-ui-DoyOZxK8.js.map +1 -0
- package/dist/yara-hooks-B49RIk5d.js +2 -0
- package/dist/{yara-hooks-BTNJ6MGW.js → yara-hooks-DCfROpZt.js} +19 -68
- package/dist/yara-hooks-DCfROpZt.js.map +1 -0
- package/package.json +2 -1
- package/dist/agent-interface-Avtr_5M5.js.map +0 -1
- package/dist/agent-prompt-loader-CHixNPgY.js.map +0 -1
- package/dist/agent-runner-COOIUJCP.js +0 -6188
- package/dist/agent-runner-COOIUJCP.js.map +0 -1
- package/dist/analytics-C67F2vee.js.map +0 -1
- package/dist/analytics-CJA1uLlk.js +0 -2
- package/dist/api-Dj1yabTj.js.map +0 -1
- package/dist/bounded-fs-CWRYuLAn.js.map +0 -1
- package/dist/ci-install-CvXL5h13.js.map +0 -1
- package/dist/debug-B4kzIZPi.js +0 -754
- package/dist/debug-B4kzIZPi.js.map +0 -1
- package/dist/env-api-key-BZ5wE3Y4.js.map +0 -1
- package/dist/environment-BEvsey6i.js.map +0 -1
- package/dist/errors-BoJvrdw8.js.map +0 -1
- package/dist/file-BoD3REGB.js.map +0 -1
- package/dist/gateway-session-C118uACz.js +0 -2
- package/dist/gateway-session-xPFv6p5c.js.map +0 -1
- package/dist/headless-ui-CsmQrDIl.js.map +0 -1
- package/dist/interactive-Dej-sxvR.js.map +0 -1
- package/dist/local-dev-DPZiIPCK.js.map +0 -1
- package/dist/mcp-Cbuw_xss.js +0 -64
- package/dist/mcp-Cbuw_xss.js.map +0 -1
- package/dist/mcp-prompt-streaming-BU_kuur_.js.map +0 -1
- package/dist/mint-failure-BrleGqMd.js.map +0 -1
- package/dist/non-interactive-DcOjH2fw.js.map +0 -1
- package/dist/orchestrator-tools-DXwr8Sp3.js.map +0 -1
- package/dist/package-json-xt3eeyBI.js.map +0 -1
- package/dist/package-manager-DR23m5Jg.js +0 -290
- package/dist/package-manager-DR23m5Jg.js.map +0 -1
- package/dist/pi-mY8I2XkG.js.map +0 -1
- package/dist/playground-CDUUKLkC.js.map +0 -1
- package/dist/posthog-Hc_-9wrr.js.map +0 -1
- package/dist/provisioning-xfdjhFtA.js.map +0 -1
- package/dist/queue-tools-C8y_xZJi.js.map +0 -1
- package/dist/registry-DTmREJ-f.js.map +0 -1
- package/dist/security-Dw2oFJjP.js.map +0 -1
- package/dist/setup-utils-fjJTBhaB.js.map +0 -1
- package/dist/start-tui-UNe2xQ0U.js.map +0 -1
- package/dist/store-Bic4Cr3L.js.map +0 -1
- package/dist/subagent-Dz41vV9j.js.map +0 -1
- package/dist/task-5-fw_Vw3.js.map +0 -1
- package/dist/task-stream-dVzl6b_q.js.map +0 -1
- package/dist/tasks-D1c2z1aw.js.map +0 -1
- package/dist/telemetry-BRnxBRWK.js.map +0 -1
- package/dist/terminal-9bvRa4Qt.js.map +0 -1
- package/dist/tools-Dp6i9k70.js.map +0 -1
- package/dist/wizard-abort-CAcInAxg.js +0 -2
- package/dist/wizard-abort-lE6umflt.js.map +0 -1
- package/dist/wizard-session-CYvyYnti.js +0 -2
- package/dist/wizard-session-FSJCkTcP.js.map +0 -1
- package/dist/yara-hooks-BTNJ6MGW.js.map +0 -1
- package/dist/yara-hooks-CFY4pGcW.js +0 -2
|
@@ -1,31 +1,433 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import "./
|
|
7
|
-
import {
|
|
8
|
-
import { i as
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { i as
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
1
|
+
import { s as ErrorCodes } from "./errors-ddDE6MbA.js";
|
|
2
|
+
import { r as debug, s as logToFile, x as regionOption, y as headlessOption } from "./debug-Cj-8vfXY.js";
|
|
3
|
+
import { $ as getSkillsBaseUrl, Q as WIZARD_USER_AGENT, U as WIZARD_INTERACTION_EVENT_NAME, f as EVENTS_AUDIT_REPORT_FILE, h as EVENT_PLAN_FILE, k as POSTHOG_DOCS_URL, n as AGENTIC_DETECTION_RETRY_TIMEOUT_MS, t as AGENTIC_DETECTION_FIRST_ATTEMPT_TIMEOUT_MS, u as DETECTION_TIMEOUT_MS, w as Integration } from "./constants-CuJfQEcC.js";
|
|
4
|
+
import { r as mayReportScanResults } from "./wizard-session-2w4Ru-Wz.js";
|
|
5
|
+
import { n as analytics } from "./analytics-VRYdebXW.js";
|
|
6
|
+
import { i as withUtm, n as openTrackedLink } from "./telemetry-Bpv-Mh5B.js";
|
|
7
|
+
import { a as safeReadFile, o as walkProjectFiles } from "./bounded-fs-Cpn129A4.js";
|
|
8
|
+
import { i as tryGetPackageJson, n as isUsingTypeScript, p as detectNodePackageManagers } from "./setup-utils-dCViCC6s.js";
|
|
9
|
+
import { a as getBlockingServiceKeys, i as evaluateWizardReadiness, r as SIGNUP_WIZARD_READINESS_CONFIG } from "./logging-ui-CUxNYF2t.js";
|
|
10
|
+
import { t as getUI } from "./ui-CGXtC7Vn.js";
|
|
11
|
+
import { i as requestDeepLink } from "./provisioning-Zf7yPcEs.js";
|
|
12
|
+
import { s as handleApiError } from "./api-DGuJTzjr.js";
|
|
13
|
+
import { i as wizardAbort } from "./wizard-abort-HDbP3YcS.js";
|
|
14
|
+
import { s as AgentSignals } from "./gateway-CVU1G0H3.js";
|
|
15
|
+
import { I as WIZARD_TOOL_NAMES, n as buildRunTags, nt as LONGER_ASK_TIMEOUT_MS } from "./agent-interface-BXvmAm4c.js";
|
|
16
|
+
import { c as shouldDisableAsk, i as resolveScanBindings, n as runAgent } from "./agent-CNrEC-9v.js";
|
|
17
|
+
import { g as AUDIT_REPORT_FILE, h as AUDIT_CHECKS_FILE } from "./yara-hooks-DCfROpZt.js";
|
|
18
|
+
import { y as writeJsonAtomic } from "./queue-tools-B7_aCyd-.js";
|
|
19
|
+
import { a as detectWarehousePrerequisites, c as discoverFeatures, f as authenticate, h as stampAiSdkDetected, i as WAREHOUSE_ABORT_CASES, l as AUDIT_CHECKS_KEY, m as createUiReducer, o as getDetectedWarehouseSources, r as DETECTED_WAREHOUSE_SOURCES_KEY, s as detectWarehouseSources, t as runProgramAgent } from "./run-agent-legacy-6WcYMaR9.js";
|
|
20
|
+
import { i as SPINNER_MESSAGE, t as FRAMEWORK_REGISTRY } from "./registry-B6iLGorH.js";
|
|
21
|
+
import * as semver from "semver";
|
|
16
22
|
import { existsSync, readFileSync, readdirSync, statSync } from "fs";
|
|
17
|
-
import path, { join } from "path";
|
|
23
|
+
import path, { isAbsolute, join, relative, resolve, sep } from "path";
|
|
18
24
|
import * as os from "node:os";
|
|
19
25
|
import * as path$2 from "node:path";
|
|
20
26
|
import { spawnSync } from "node:child_process";
|
|
21
27
|
import * as fs$1 from "node:fs";
|
|
22
28
|
import axios from "axios";
|
|
23
29
|
import { z } from "zod";
|
|
30
|
+
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
24
31
|
import { Text } from "ink";
|
|
25
32
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
26
33
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
27
34
|
import { access, rm } from "node:fs/promises";
|
|
28
|
-
//#region src/
|
|
35
|
+
//#region src/programs/detection/framework.ts
|
|
36
|
+
/**
|
|
37
|
+
* Framework detection — identify which PostHog-supported framework
|
|
38
|
+
* is present in the project directory.
|
|
39
|
+
*
|
|
40
|
+
* Pure function: takes an install dir, returns the detected integration
|
|
41
|
+
* (or undefined). No store mutations, no UI calls.
|
|
42
|
+
*/
|
|
43
|
+
/**
|
|
44
|
+
* Loop through all registered frameworks and return the first one
|
|
45
|
+
* whose `detect()` predicate matches the given directory.
|
|
46
|
+
* Returns undefined if no framework is detected or detection times out.
|
|
47
|
+
*/
|
|
48
|
+
async function detectFramework(installDir) {
|
|
49
|
+
for (const integration of Object.values(Integration)) {
|
|
50
|
+
const config = FRAMEWORK_REGISTRY[integration];
|
|
51
|
+
try {
|
|
52
|
+
if (await Promise.race([config.detection.detect({ installDir }), new Promise((resolve) => setTimeout(() => resolve(false), 1e4))])) return integration;
|
|
53
|
+
} catch {}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
//#region src/programs/detection/context.ts
|
|
58
|
+
/**
|
|
59
|
+
* Framework context gathering — run gatherContext and version checks
|
|
60
|
+
* for a detected framework.
|
|
61
|
+
*
|
|
62
|
+
* Pure functions: take a framework config and options, return results.
|
|
63
|
+
* No store mutations, no UI calls.
|
|
64
|
+
*/
|
|
65
|
+
/**
|
|
66
|
+
* Run a framework's `gatherContext()` to collect variant-specific
|
|
67
|
+
* metadata (e.g., router type for Next.js, Expo vs bare for React Native).
|
|
68
|
+
*
|
|
69
|
+
* Returns the gathered context, or an empty object on failure/timeout.
|
|
70
|
+
*/
|
|
71
|
+
async function gatherFrameworkContext(config, options) {
|
|
72
|
+
if (!config.metadata.gatherContext) return {};
|
|
73
|
+
try {
|
|
74
|
+
return await Promise.race([config.metadata.gatherContext(options), new Promise((resolve) => setTimeout(() => resolve({}), DETECTION_TIMEOUT_MS))]);
|
|
75
|
+
} catch {
|
|
76
|
+
return {};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Check whether the installed framework version meets the minimum requirement.
|
|
81
|
+
*
|
|
82
|
+
* Returns `{ supported: true }` if the version is fine (or no check is needed).
|
|
83
|
+
* Returns the version details if unsupported.
|
|
84
|
+
*/
|
|
85
|
+
async function checkFrameworkVersion(config, options) {
|
|
86
|
+
if (!config.detection.minimumVersion || !config.detection.getInstalledVersion) return { supported: true };
|
|
87
|
+
const version = await config.detection.getInstalledVersion(options);
|
|
88
|
+
if (!version) return { supported: true };
|
|
89
|
+
const coerced = semver.coerce(version);
|
|
90
|
+
if (coerced && semver.lt(coerced, config.detection.minimumVersion)) return { supported: {
|
|
91
|
+
current: version,
|
|
92
|
+
minimum: config.detection.minimumVersion,
|
|
93
|
+
docsUrl: config.metadata.unsupportedVersionDocsUrl ?? config.metadata.docsUrl
|
|
94
|
+
} };
|
|
95
|
+
return { supported: true };
|
|
96
|
+
}
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region src/programs/detection/agentic.ts
|
|
99
|
+
/**
|
|
100
|
+
* Agentic project detection.
|
|
101
|
+
*
|
|
102
|
+
* A reusable detection tool that drives an agent over the repo: it finds
|
|
103
|
+
* project roots, resolves monorepo/workspace markers, reads package manifests,
|
|
104
|
+
* classifies each project against a caller-supplied set of targets, and reports
|
|
105
|
+
* which projects already have a PostHog SDK installed.
|
|
106
|
+
*
|
|
107
|
+
* Product-knowledge-free by design — the caller passes the targets to classify
|
|
108
|
+
* into (e.g. source-map skill variants) and maps the result back. Sits next to
|
|
109
|
+
* the other detection tools (framework, features, package-manager) so it's
|
|
110
|
+
* discoverable. Runs AFTER auth: it goes through the same `runAgent` every
|
|
111
|
+
* program uses, which needs credentials.
|
|
112
|
+
*/
|
|
113
|
+
var AgenticDetectionTimeoutError = class extends Error {
|
|
114
|
+
constructor(attempt, timeoutMs) {
|
|
115
|
+
super(`Project scan attempt ${attempt} timed out after ${timeoutMs / 1e3}s`);
|
|
116
|
+
this.name = "AgenticDetectionTimeoutError";
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Every project-manifest / workspace-marker filename the wizard's frameworks
|
|
121
|
+
* are identified by. One brace-expansion Glob over all of these locates every
|
|
122
|
+
* project root in the repo in a single call, regardless of language.
|
|
123
|
+
*
|
|
124
|
+
* Counterpart: POSTHOG_MANIFESTS in @programs/self-driving/detect (SDK
|
|
125
|
+
* grep); keep the two in sync.
|
|
126
|
+
*/
|
|
127
|
+
const PROJECT_MANIFESTS = [
|
|
128
|
+
"package.json",
|
|
129
|
+
"pnpm-workspace.yaml",
|
|
130
|
+
"turbo.json",
|
|
131
|
+
"nx.json",
|
|
132
|
+
"lerna.json",
|
|
133
|
+
"requirements.txt",
|
|
134
|
+
"pyproject.toml",
|
|
135
|
+
"setup.py",
|
|
136
|
+
"Pipfile",
|
|
137
|
+
"manage.py",
|
|
138
|
+
"Gemfile",
|
|
139
|
+
"composer.json",
|
|
140
|
+
"pom.xml",
|
|
141
|
+
"Cargo.toml",
|
|
142
|
+
"mix.exs",
|
|
143
|
+
"go.mod",
|
|
144
|
+
"*.csproj",
|
|
145
|
+
"Package.swift",
|
|
146
|
+
"Podfile",
|
|
147
|
+
"project.yml",
|
|
148
|
+
"project.pbxproj",
|
|
149
|
+
"pubspec.yaml",
|
|
150
|
+
"build.gradle",
|
|
151
|
+
"build.gradle.kts",
|
|
152
|
+
"settings.gradle",
|
|
153
|
+
"settings.gradle.kts",
|
|
154
|
+
"gradle/libs.versions.toml"
|
|
155
|
+
];
|
|
156
|
+
/** The single brace-expansion glob covering every supported manifest. */
|
|
157
|
+
function manifestGlob() {
|
|
158
|
+
return `**/{${PROJECT_MANIFESTS.join(",")}}`;
|
|
159
|
+
}
|
|
160
|
+
function buildPrompt$1(cwd, targets, purpose, recommend) {
|
|
161
|
+
const targetList = targets.map((t) => `- ${t.id} → ${t.name}`).join("\n");
|
|
162
|
+
const projectShape = `{"path":string,"framework":string,"matchingTargets":string[],"targetId":string|null,"hasPostHog":boolean,"evidence":string${recommend ? ",\"recommended\":boolean" : ""}}`;
|
|
163
|
+
return [
|
|
164
|
+
`You are scanning a code repository to ${purpose}. Be fast and mechanical — do not over-explore. Keep any reasoning to one short sentence, then run the tool calls and output the JSON.`,
|
|
165
|
+
"",
|
|
166
|
+
`Working directory: ${cwd}`,
|
|
167
|
+
"",
|
|
168
|
+
"A \"project\" is a directory containing one or more of the manifest files below. Find projects by their manifests, NOT by walking directories — never report a directory that has no manifest.",
|
|
169
|
+
"",
|
|
170
|
+
"Do exactly this:",
|
|
171
|
+
`1. Run Glob ONCE with this pattern to find every project manifest in the repo in a single call: "${manifestGlob()}". Discard any result whose path contains node_modules/, dist/, build/, .next/, out/, coverage/, vendor/, .venv/, site-packages/, target/, Pods/, Carthage/, or DerivedData/. Group the remaining results by directory — each directory is one project. Three exceptions to "directory = project": a project.pbxproj lives inside a "<Name>.xcodeproj/" wrapper, so the project root is the PARENT of that .xcodeproj directory; a project.yml at a directory root is an XcodeGen-generated Xcode app rooted at that directory; a gradle/libs.versions.toml is a version catalog belonging to the gradle project rooted at the PARENT of that gradle/ directory (read it alongside the build.gradle when deciding hasPostHog), never its own project.`,
|
|
172
|
+
"2. Decide repoType: \"monorepo\" if the root package.json has a \"workspaces\" field OR a pnpm-workspace.yaml / turbo.json / nx.json / lerna.json was found at the root, else \"single\".",
|
|
173
|
+
`3. For EACH project directory, ONE AT A TIME: Read its manifest(s) ONCE, decide the fields below, then IMMEDIATELY — before reading any other project — write that project's verdict as one JSON line of shape ${projectShape}. Never write a verdict from memory of an earlier Read; the manifest you just read is the only source. Decide from its dependency lists:`,
|
|
174
|
+
" - the human-readable framework name (e.g. \"Next.js\", \"Django\", \"Rails\"),",
|
|
175
|
+
" - matchingTargets: EVERY target id from the list below whose technology appears in THIS manifest, in the priority order of the list. An id belongs here only if you can point at the dependency or setting in the manifest you just read — never carry one over from another project,",
|
|
176
|
+
" - targetId: the FIRST entry of matchingTargets (the list is ordered by priority, most specific first). null when matchingTargets is empty,",
|
|
177
|
+
` - hasPostHog: true if any dependency is a PostHog SDK. This includes: a name containing "posthog" in any ecosystem (e.g. posthog-js, posthog-node, @posthog/*, posthog for pip/gem/hex, a com.posthog:* gradle/maven coordinate, a PostHog NuGet PackageReference); an SPM package named "PostHog" or a repositoryURL of github.com/PostHog/posthog-ios (in Package.swift or a .pbxproj); or a "pod 'PostHog'" line in a Podfile. Else false.`,
|
|
178
|
+
" - evidence: the manifest fact that decided targetId, with the file it came from (e.g. \"rollup in devDependencies of backend/package.json\"). When targetId is null, name the closest fact you saw. One short clause, quoted from the manifest you just read.",
|
|
179
|
+
" Do NOT read any file other than these manifests.",
|
|
180
|
+
...recommend ? ["4. Pick exactly ONE project as recommended — the main user-facing client application. Prefer a frontend web app or a mobile app over backend servers/APIs, libraries, CLIs, tooling, and example/demo/docs apps. If several client apps exist, pick the primary production app; if no client app exists, pick the primary application project."] : [],
|
|
181
|
+
"",
|
|
182
|
+
"Target ids (id → name), in priority order — most specific first; if several match a project, keep the one listed earliest:",
|
|
183
|
+
targetList,
|
|
184
|
+
"",
|
|
185
|
+
"Output requirements:",
|
|
186
|
+
"- After the last verdict line, respond with ONLY a single JSON object assembling the verdict lines you wrote, copied VERBATIM — same path, framework, targetId and evidence per project. No prose, no markdown code fences.",
|
|
187
|
+
`- Shape: {"repoType":"monorepo"|"single","projects":[${projectShape}]}`,
|
|
188
|
+
"- \"path\" is the project directory relative to the working directory; use \".\" for the repo root.",
|
|
189
|
+
"- \"targetId\" MUST be exactly one of the target ids above when it matches; if several match, use the one listed earliest; otherwise null.",
|
|
190
|
+
"- Include projects whose stack matches no target too (targetId: null).",
|
|
191
|
+
...recommend ? ["- Exactly one project has \"recommended\": true; every other project has \"recommended\": false."] : [],
|
|
192
|
+
"- If there are no manifests at all, return {\"repoType\":\"single\",\"projects\":[]}."
|
|
193
|
+
].join("\n");
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Build the detection report from the agent's output, or null when it holds
|
|
197
|
+
* neither a project verdict nor a `projects` array. Exported for testing.
|
|
198
|
+
*
|
|
199
|
+
* The verdict lines are far more reliable than the model's final assembly
|
|
200
|
+
* (prose, pretty-printing, per-object fences), so every parseable line
|
|
201
|
+
* contributes: objects with a `path` merge by path (last wins), and a
|
|
202
|
+
* one-line assembly's `projects` merge the same way. `repoType` is
|
|
203
|
+
* approximated from the count — it only feeds telemetry and display.
|
|
204
|
+
*/
|
|
205
|
+
function deriveReportJson(text) {
|
|
206
|
+
const byPath = /* @__PURE__ */ new Map();
|
|
207
|
+
let sawReport = false;
|
|
208
|
+
for (const line of text.split("\n")) {
|
|
209
|
+
const start = line.indexOf("{");
|
|
210
|
+
const end = line.lastIndexOf("}");
|
|
211
|
+
if (start === -1 || end <= start) continue;
|
|
212
|
+
let parsed;
|
|
213
|
+
try {
|
|
214
|
+
parsed = JSON.parse(line.slice(start, end + 1));
|
|
215
|
+
} catch {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
const obj = parsed ?? {};
|
|
219
|
+
sawReport ||= Array.isArray(obj.projects);
|
|
220
|
+
const candidates = Array.isArray(obj.projects) ? obj.projects : [obj];
|
|
221
|
+
for (const candidate of candidates) {
|
|
222
|
+
const p = candidate ?? {};
|
|
223
|
+
if (typeof p.path === "string") byPath.set(p.path, p);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (byPath.size === 0 && !sawReport) return null;
|
|
227
|
+
const projects = [...byPath.values()];
|
|
228
|
+
return {
|
|
229
|
+
repoType: projects.length > 1 ? "monorepo" : "single",
|
|
230
|
+
projects
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Clamp an agent-reported project path to a safe repo-relative dir. The path
|
|
235
|
+
* is LLM output: absolute paths or `..` segments could steer later phases
|
|
236
|
+
* (e.g. integrate-run's targetDir) outside the repo, so they clamp to '.'.
|
|
237
|
+
*/
|
|
238
|
+
function coercePath(raw) {
|
|
239
|
+
if (typeof raw !== "string" || raw.length === 0) return ".";
|
|
240
|
+
if (isAbsolute(raw) || raw.split(/[\\/]/).includes("..")) return ".";
|
|
241
|
+
return raw;
|
|
242
|
+
}
|
|
243
|
+
/** Resolve an agent-reported path to an absolute dir clamped to the root — the caller-side counterpart of coercePath. */
|
|
244
|
+
function resolveProjectDir(installDir, rel) {
|
|
245
|
+
if (typeof rel !== "string" || rel === ".") return installDir;
|
|
246
|
+
const root = resolve(installDir);
|
|
247
|
+
const dir = resolve(root, rel);
|
|
248
|
+
return dir === root || dir.startsWith(root + sep) ? dir : root;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Validate the agent's raw JSON into a report, clamping each targetId to the
|
|
252
|
+
* supplied set and each path to a repo-relative dir. Exported for testing.
|
|
253
|
+
* `recommended` is stripped unless requested; at most one (the first) survives.
|
|
254
|
+
*/
|
|
255
|
+
function coerceAgenticReport(parsed, validTargetIds, options) {
|
|
256
|
+
const recommend = options?.recommend === true;
|
|
257
|
+
const rerankIds = options?.rerankIds ?? [];
|
|
258
|
+
const obj = parsed ?? {};
|
|
259
|
+
const repoType = obj.repoType === "monorepo" ? "monorepo" : "single";
|
|
260
|
+
const rawProjects = Array.isArray(obj.projects) ? obj.projects : [];
|
|
261
|
+
let recommendedSeen = false;
|
|
262
|
+
return {
|
|
263
|
+
repoType,
|
|
264
|
+
projects: rawProjects.map((raw) => {
|
|
265
|
+
const p = raw ?? {};
|
|
266
|
+
const pick = typeof p.targetId === "string" && validTargetIds.includes(p.targetId) ? p.targetId : null;
|
|
267
|
+
const enumerated = Array.isArray(p.matchingTargets) ? validTargetIds.find((id) => p.matchingTargets.includes(id)) ?? null : null;
|
|
268
|
+
const targetId = pick === null ? enumerated : enumerated !== null && rerankIds.includes(enumerated) && rerankIds.includes(pick) ? enumerated : pick;
|
|
269
|
+
const recommended = recommend && !recommendedSeen && p.recommended === true;
|
|
270
|
+
recommendedSeen ||= recommended;
|
|
271
|
+
return {
|
|
272
|
+
path: coercePath(p.path),
|
|
273
|
+
framework: typeof p.framework === "string" ? p.framework : "Unknown",
|
|
274
|
+
targetId,
|
|
275
|
+
hasPostHog: p.hasPostHog === true,
|
|
276
|
+
...recommend ? { recommended } : {}
|
|
277
|
+
};
|
|
278
|
+
})
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
function detectionReportSchema(recommend) {
|
|
282
|
+
return z.object({
|
|
283
|
+
repoType: z.enum(["monorepo", "single"]),
|
|
284
|
+
projects: z.array(z.object({
|
|
285
|
+
path: z.string(),
|
|
286
|
+
framework: z.string(),
|
|
287
|
+
matchingTargets: z.array(z.string()),
|
|
288
|
+
targetId: z.string().nullable(),
|
|
289
|
+
hasPostHog: z.boolean(),
|
|
290
|
+
evidence: z.string(),
|
|
291
|
+
...recommend ? { recommended: z.boolean() } : {}
|
|
292
|
+
}).strict())
|
|
293
|
+
}).strict();
|
|
294
|
+
}
|
|
295
|
+
/** Read-only scan with a typed result and transcript recovery. */
|
|
296
|
+
function detectionRunDefinition(prompt) {
|
|
297
|
+
return {
|
|
298
|
+
integrationLabel: "agentic-detect",
|
|
299
|
+
readOnly: true,
|
|
300
|
+
prompt: () => prompt,
|
|
301
|
+
collectTranscript: true,
|
|
302
|
+
requestRemark: false,
|
|
303
|
+
detectPackageManager: detectNodePackageManagers,
|
|
304
|
+
spinnerMessage: "Scanning the repo...",
|
|
305
|
+
successMessage: "Detection complete",
|
|
306
|
+
errorMessage: "Detection failed",
|
|
307
|
+
estimatedDurationMinutes: 1,
|
|
308
|
+
reportFile: "",
|
|
309
|
+
docsUrl: POSTHOG_DOCS_URL
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
/** What the UI saw before `runAgent`: no run lifecycle, spinner, outro, or setup logs below warn. */
|
|
313
|
+
function reachesUi(event) {
|
|
314
|
+
switch (event.kind) {
|
|
315
|
+
case "lifecycle":
|
|
316
|
+
case "completion":
|
|
317
|
+
case "spinner": return false;
|
|
318
|
+
case "log": return event.level === "warn" || event.level === "error";
|
|
319
|
+
default: return true;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
/** Scan through `runAgent` with the bound triage model, then the SDK fallback. */
|
|
323
|
+
async function detectProjectsWithAgent(session, options) {
|
|
324
|
+
if (!session.credentials) throw new Error("Detection requires authenticated credentials.");
|
|
325
|
+
const { targets, programId, purpose = "set up a PostHog integration", recommend = false, rerankIds, onEvent } = options;
|
|
326
|
+
const wizardMetadata = {
|
|
327
|
+
...buildRunTags({
|
|
328
|
+
programId,
|
|
329
|
+
integration: "agentic-detect",
|
|
330
|
+
runId: analytics.runId,
|
|
331
|
+
build: analytics.build
|
|
332
|
+
}),
|
|
333
|
+
call_type: "detection"
|
|
334
|
+
};
|
|
335
|
+
const wizardFlags = await analytics.getAllFlagsForWizard();
|
|
336
|
+
const wizardFlagPayloads = analytics.getWizardFlagPayloads();
|
|
337
|
+
const switchboard = {
|
|
338
|
+
program: programId,
|
|
339
|
+
composed: true,
|
|
340
|
+
flags: wizardFlags,
|
|
341
|
+
flagPayloads: wizardFlagPayloads,
|
|
342
|
+
cliHarness: session.harness
|
|
343
|
+
};
|
|
344
|
+
const bindings = resolveScanBindings(switchboard);
|
|
345
|
+
const reportSchema = detectionReportSchema(recommend);
|
|
346
|
+
const schema = zodToJsonSchema(reportSchema);
|
|
347
|
+
const config = {
|
|
348
|
+
programId,
|
|
349
|
+
run: detectionRunDefinition(buildPrompt$1(session.installDir, targets, purpose, recommend)),
|
|
350
|
+
composed: true,
|
|
351
|
+
binding: bindings[0],
|
|
352
|
+
switchboard,
|
|
353
|
+
skillsBaseUrl: getSkillsBaseUrl(),
|
|
354
|
+
wizardFlags,
|
|
355
|
+
wizardFlagPayloads,
|
|
356
|
+
wizardMetadata,
|
|
357
|
+
scanReport: "defer"
|
|
358
|
+
};
|
|
359
|
+
const input = {
|
|
360
|
+
installDir: session.installDir,
|
|
361
|
+
credentials: session.credentials,
|
|
362
|
+
project: null,
|
|
363
|
+
apiUser: null,
|
|
364
|
+
flags: {
|
|
365
|
+
ci: session.ci,
|
|
366
|
+
signup: session.signup,
|
|
367
|
+
debug: session.debug,
|
|
368
|
+
e2eAsk: false,
|
|
369
|
+
localMcp: session.localMcp,
|
|
370
|
+
captureAio: false,
|
|
371
|
+
benchmark: false,
|
|
372
|
+
yaraReport: session.yaraReport
|
|
373
|
+
},
|
|
374
|
+
host: {
|
|
375
|
+
projectId: session.projectId,
|
|
376
|
+
apiKey: session.apiKey
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
const reduceUi = createUiReducer(getUI());
|
|
380
|
+
const forward = (event) => {
|
|
381
|
+
if (event.kind === "activity") onEvent?.(event.line);
|
|
382
|
+
if (reachesUi(event)) reduceUi(event);
|
|
383
|
+
};
|
|
384
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
385
|
+
const timeoutMs = attempt === 0 ? AGENTIC_DETECTION_FIRST_ATTEMPT_TIMEOUT_MS : AGENTIC_DETECTION_RETRY_TIMEOUT_MS;
|
|
386
|
+
const result = await runAgent({
|
|
387
|
+
...config,
|
|
388
|
+
binding: bindings[attempt],
|
|
389
|
+
run: {
|
|
390
|
+
...config.run,
|
|
391
|
+
structured: {
|
|
392
|
+
schema,
|
|
393
|
+
timeoutMs
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}, input, { onProgress: forward });
|
|
397
|
+
if (result.outcome !== "success" && result.failure.code === ErrorCodes.AgenticDetectionTimeout) {
|
|
398
|
+
if (attempt === 0) {
|
|
399
|
+
onEvent?.("Project scan timed out; retrying...");
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
throw new AgenticDetectionTimeoutError(attempt + 1, timeoutMs);
|
|
403
|
+
}
|
|
404
|
+
if (result.outcome !== "success") {
|
|
405
|
+
if (result.failure.code === ErrorCodes.AgentInvalidStructuredOutput && attempt === 0) {
|
|
406
|
+
onEvent?.("Project scan returned invalid output; retrying...");
|
|
407
|
+
continue;
|
|
408
|
+
}
|
|
409
|
+
throw result.failure.error ?? new Error(result.failure.message);
|
|
410
|
+
}
|
|
411
|
+
if (result.structuredOutput !== void 0) {
|
|
412
|
+
const structured = reportSchema.safeParse(result.structuredOutput);
|
|
413
|
+
if (structured.success) return coerceAgenticReport(structured.data, targets.map((t) => t.id), {
|
|
414
|
+
recommend,
|
|
415
|
+
rerankIds
|
|
416
|
+
});
|
|
417
|
+
if (attempt === 0) onEvent?.("Project scan returned invalid output; retrying...");
|
|
418
|
+
continue;
|
|
419
|
+
}
|
|
420
|
+
const derived = deriveReportJson(result.snapshot.transcriptTail ?? "");
|
|
421
|
+
if (derived !== null) return coerceAgenticReport(derived, targets.map((t) => t.id), {
|
|
422
|
+
recommend,
|
|
423
|
+
rerankIds
|
|
424
|
+
});
|
|
425
|
+
if (attempt === 0) onEvent?.("Retrying project scan...");
|
|
426
|
+
}
|
|
427
|
+
throw new Error("Agent did not return a JSON object after retry");
|
|
428
|
+
}
|
|
429
|
+
//#endregion
|
|
430
|
+
//#region src/programs/detection/project-scope.ts
|
|
29
431
|
/** Non-interactive project scoping — scan the repo agentically and pick which project the run integrates. */
|
|
30
432
|
/** Integration framework targets for the agentic detector (id → display name). */
|
|
31
433
|
const INTEGRATION_TARGETS = Object.entries(FRAMEWORK_REGISTRY).map(([id, config]) => ({
|
|
@@ -62,13 +464,13 @@ function captureOutcome(outcome, properties = {}) {
|
|
|
62
464
|
});
|
|
63
465
|
}
|
|
64
466
|
/** Flag-gated non-interactive monorepo phase: scan, auto-choose the recommended project, re-point session.installDir; every failure leaves the session untouched. */
|
|
65
|
-
async function scopeInstallDirToProject(session) {
|
|
467
|
+
async function scopeInstallDirToProject(session, runner) {
|
|
66
468
|
await authenticate(session, "posthog-integration");
|
|
67
469
|
if ((await analytics.getAllFlagsForWizard())["wizard-basic-integration-agentic-detection"] !== "true") {
|
|
68
470
|
captureOutcome("flag-off");
|
|
69
471
|
return;
|
|
70
472
|
}
|
|
71
|
-
|
|
473
|
+
runner.log.info("Scanning the repo for projects...");
|
|
72
474
|
const startedAt = Date.now();
|
|
73
475
|
let report;
|
|
74
476
|
try {
|
|
@@ -81,7 +483,7 @@ async function scopeInstallDirToProject(session) {
|
|
|
81
483
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
82
484
|
if (error instanceof AgenticDetectionTimeoutError) {
|
|
83
485
|
captureOutcome("timeout", { duration_ms: Date.now() - startedAt });
|
|
84
|
-
|
|
486
|
+
runner.log.warn(`${error.message}; continuing with the install dir as-is.`);
|
|
85
487
|
return;
|
|
86
488
|
}
|
|
87
489
|
analytics.captureException(error, { step: "agentic_detection" });
|
|
@@ -89,7 +491,7 @@ async function scopeInstallDirToProject(session) {
|
|
|
89
491
|
duration_ms: Date.now() - startedAt,
|
|
90
492
|
error_message: error.message
|
|
91
493
|
});
|
|
92
|
-
|
|
494
|
+
runner.log.warn(`Project scan failed (${error.message}); continuing with the install dir as-is.`);
|
|
93
495
|
return;
|
|
94
496
|
}
|
|
95
497
|
const { projects } = report;
|
|
@@ -106,7 +508,7 @@ async function scopeInstallDirToProject(session) {
|
|
|
106
508
|
const project = chooseIntegrationProject(projects);
|
|
107
509
|
if (!project) {
|
|
108
510
|
captureOutcome("no-project", scanProperties);
|
|
109
|
-
|
|
511
|
+
runner.log.info("The scan found no supported project; continuing with the install dir as-is.");
|
|
110
512
|
return;
|
|
111
513
|
}
|
|
112
514
|
session.installDir = resolveProjectDir(session.installDir, project.path);
|
|
@@ -115,10 +517,10 @@ async function scopeInstallDirToProject(session) {
|
|
|
115
517
|
chosen_framework: project.targetId,
|
|
116
518
|
chosen_path: project.path
|
|
117
519
|
});
|
|
118
|
-
|
|
520
|
+
runner.log.info(`Continuing with ${project.path} (${project.framework}).`);
|
|
119
521
|
}
|
|
120
522
|
//#endregion
|
|
121
|
-
//#region src/
|
|
523
|
+
//#region src/programs/shared/health-check-step.ts
|
|
122
524
|
function healthCheckReady(session) {
|
|
123
525
|
if (!session.readinessResult) return false;
|
|
124
526
|
if (session.signup) {
|
|
@@ -150,7 +552,180 @@ const HEALTH_CHECK_STEP = {
|
|
|
150
552
|
}
|
|
151
553
|
};
|
|
152
554
|
//#endregion
|
|
153
|
-
//#region src/
|
|
555
|
+
//#region src/programs/shared/package-scanning.ts
|
|
556
|
+
const POSTHOG_SDKS = new Set([
|
|
557
|
+
"posthog-js",
|
|
558
|
+
"posthog-node",
|
|
559
|
+
"posthog-react-native",
|
|
560
|
+
"posthog-android",
|
|
561
|
+
"posthog-ios"
|
|
562
|
+
]);
|
|
563
|
+
const STRIPE_SDKS = new Set([
|
|
564
|
+
"stripe",
|
|
565
|
+
"@stripe/stripe-js",
|
|
566
|
+
"@stripe/react-stripe-js"
|
|
567
|
+
]);
|
|
568
|
+
const MAX_PACKAGE_MATCHES = 500;
|
|
569
|
+
/**
|
|
570
|
+
* Find all package.json files under installDir via the shared bounded walk
|
|
571
|
+
* (depth cap, ignored dirs, symlink-loop protection, per-dir entry cap).
|
|
572
|
+
* Returns matches with detected SDKs.
|
|
573
|
+
*/
|
|
574
|
+
function findPackageJsons(installDir, maxDepth = 3) {
|
|
575
|
+
const matches = [];
|
|
576
|
+
walkProjectFiles(installDir, (name, fullPath) => {
|
|
577
|
+
if (name !== "package.json" || matches.length >= MAX_PACKAGE_MATCHES) return;
|
|
578
|
+
const content = safeReadFile(fullPath);
|
|
579
|
+
if (content === null) return;
|
|
580
|
+
try {
|
|
581
|
+
const pkg = JSON.parse(content);
|
|
582
|
+
const depNames = [...Object.keys(pkg.dependencies ?? {}), ...Object.keys(pkg.devDependencies ?? {})];
|
|
583
|
+
const posthogSdks = depNames.filter((d) => POSTHOG_SDKS.has(d));
|
|
584
|
+
const stripeSdks = depNames.filter((d) => STRIPE_SDKS.has(d));
|
|
585
|
+
matches.push({
|
|
586
|
+
path: relative(installDir, fullPath) || "package.json",
|
|
587
|
+
posthogSdks,
|
|
588
|
+
stripeSdks
|
|
589
|
+
});
|
|
590
|
+
} catch {}
|
|
591
|
+
}, maxDepth);
|
|
592
|
+
return matches;
|
|
593
|
+
}
|
|
594
|
+
//#endregion
|
|
595
|
+
//#region src/programs/posthog-integration/detect.ts
|
|
596
|
+
async function detectPostHogIntegration(ctx) {
|
|
597
|
+
const session = ctx.session;
|
|
598
|
+
const installDir = session.installDir;
|
|
599
|
+
const detectedIntegration = await detectFramework(installDir);
|
|
600
|
+
if (detectedIntegration) {
|
|
601
|
+
const config = FRAMEWORK_REGISTRY[detectedIntegration];
|
|
602
|
+
const sessionOptions = {
|
|
603
|
+
installDir,
|
|
604
|
+
debug: session.debug,
|
|
605
|
+
signup: session.signup,
|
|
606
|
+
ci: session.ci,
|
|
607
|
+
benchmark: session.benchmark,
|
|
608
|
+
yaraReport: session.yaraReport
|
|
609
|
+
};
|
|
610
|
+
const context = await gatherFrameworkContext(config, sessionOptions);
|
|
611
|
+
for (const [key, value] of Object.entries(context)) if (!(key in session.frameworkContext)) ctx.setFrameworkContext(key, value);
|
|
612
|
+
ctx.setFrameworkConfig(detectedIntegration, config);
|
|
613
|
+
ctx.setSkillId(detectedIntegration);
|
|
614
|
+
if (!session.detectedFrameworkLabel) ctx.setDetectedFramework(config.metadata.name);
|
|
615
|
+
const versionResult = await checkFrameworkVersion(config, sessionOptions);
|
|
616
|
+
if (versionResult.supported !== true) ctx.setUnsupportedVersion(versionResult.supported);
|
|
617
|
+
}
|
|
618
|
+
for (const feature of discoverFeatures(installDir)) ctx.addDiscoveredFeature(feature);
|
|
619
|
+
detectWarehouseSourcesForSuggestion(ctx, installDir);
|
|
620
|
+
detectExistingPostHog(ctx, installDir);
|
|
621
|
+
ctx.setDetectionComplete();
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* How the scan went, for the reporter to read later. Three states, and the
|
|
625
|
+
* absent one carries the most weight:
|
|
626
|
+
*
|
|
627
|
+
* absent this program never scanned. Only `posthog-integration` runs the
|
|
628
|
+
* scan below, but every program's intro screen resolves consent
|
|
629
|
+
* through the same store method, so the reporter is reached on runs
|
|
630
|
+
* where no scan ever happened.
|
|
631
|
+
* 'failed' the scan threw. A zero-count row would read as "scanned, found
|
|
632
|
+
* nothing", which is a different fact.
|
|
633
|
+
* 'ok' the scan ran. Zero sources is a real result and gets reported.
|
|
634
|
+
*/
|
|
635
|
+
const WAREHOUSE_SCAN_STATE_KEY = "warehouseScanState";
|
|
636
|
+
/**
|
|
637
|
+
* Scan for data warehouse source signals (Postgres, Stripe, Hubspot, …) and,
|
|
638
|
+
* when found, stash them for a `wizard warehouse` suggestion on the outro.
|
|
639
|
+
* Runs unconditionally during `detect`, before the intro screen has asked
|
|
640
|
+
* about sharing. Reporting what this finds is a separate, later concern.
|
|
641
|
+
* See `reportWarehouseSourcesDetected` below.
|
|
642
|
+
*
|
|
643
|
+
* Deliberately a suggestion, not an inline agent run: a second credential-
|
|
644
|
+
* collecting agent run before the outro could `process.exit()` on any of its
|
|
645
|
+
* failure paths and cost the user the success outro on a run where PostHog
|
|
646
|
+
* installed fine.
|
|
647
|
+
*
|
|
648
|
+
* Calls `detectWarehouseSources` (a pure scan) rather than the warehouse
|
|
649
|
+
* program's `detectWarehousePrerequisites`, which writes a `detectError` when
|
|
650
|
+
* it finds nothing — that's right for `wizard warehouse` but here would show a
|
|
651
|
+
* spurious error and trip the CI prerequisites abort. No sources is a no-op.
|
|
652
|
+
*
|
|
653
|
+
* Best-effort: never let a scan failure break the wizard flow.
|
|
654
|
+
*/
|
|
655
|
+
function detectWarehouseSourcesForSuggestion(ctx, installDir) {
|
|
656
|
+
try {
|
|
657
|
+
const sources = detectWarehouseSources(installDir);
|
|
658
|
+
ctx.setFrameworkContext(WAREHOUSE_SCAN_STATE_KEY, "ok");
|
|
659
|
+
if (sources.length === 0) return;
|
|
660
|
+
ctx.setFrameworkContext(DETECTED_WAREHOUSE_SOURCES_KEY, sources);
|
|
661
|
+
} catch (error) {
|
|
662
|
+
ctx.setFrameworkContext(WAREHOUSE_SCAN_STATE_KEY, "failed");
|
|
663
|
+
analytics.captureException(error instanceof Error ? error : new Error(String(error)), { step: "detectWarehouseSourcesForSuggestion" });
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* Fires the org stamp once per session, right after `authenticate()` succeeds
|
|
668
|
+
* — never from the consent path, since consent on the intro screen resolves
|
|
669
|
+
* before login and `session.apiUser` is unset there. Called right after
|
|
670
|
+
* `authenticate()` from run-wizard.ts's auth step and from bootstrap.ts,
|
|
671
|
+
* whichever completes it first for a given program; a no-op on every call
|
|
672
|
+
* after that. In the `--ci` path, project-scope.ts authenticates first as a
|
|
673
|
+
* prerequisite (no evidence gathered yet, so nothing would stamp there
|
|
674
|
+
* anyway) and this only ever runs from the later, idempotent bootstrap.ts
|
|
675
|
+
* call — still correctly finding no evidence, since CI skips the detect step.
|
|
676
|
+
*/
|
|
677
|
+
function maybeStampAiSdkDetected(session) {
|
|
678
|
+
if (session.aiSdkStampReported) return;
|
|
679
|
+
session.aiSdkStampReported = true;
|
|
680
|
+
stampAiSdkDetected({
|
|
681
|
+
apiUser: session.apiUser,
|
|
682
|
+
discoveredFeatures: session.discoveredFeatures,
|
|
683
|
+
warehouseSources: getDetectedWarehouseSources(session),
|
|
684
|
+
mayReportScanResults: mayReportScanResults(session)
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* The single place scan results become telemetry. Called from
|
|
689
|
+
* `WizardStore.completeSetup()`, the point consent becomes final — the privacy
|
|
690
|
+
* panel's choice is reversible until then, so nothing may report earlier.
|
|
691
|
+
* The org stamp is a separate concern: see `maybeStampAiSdkDetected`, which
|
|
692
|
+
* runs post-auth rather than at consent resolution.
|
|
693
|
+
*
|
|
694
|
+
* Returns true when consent has resolved and the caller should latch
|
|
695
|
+
* `warehouseSourcesReported`, which is not the same as "this sent something":
|
|
696
|
+
* a decline, a failed scan, and a program that never scanned all resolve
|
|
697
|
+
* without sending.
|
|
698
|
+
*/
|
|
699
|
+
function reportWarehouseSourcesDetected(session) {
|
|
700
|
+
if (session.warehouseSourcesReported) return false;
|
|
701
|
+
if (session.scanConsent === "undecided") return false;
|
|
702
|
+
if (mayReportScanResults(session)) {
|
|
703
|
+
const sources = getDetectedWarehouseSources(session);
|
|
704
|
+
if (session.frameworkContext[WAREHOUSE_SCAN_STATE_KEY] !== "ok") return true;
|
|
705
|
+
analytics.wizardCapture("warehouse sources detected", {
|
|
706
|
+
warehouse_source_count: sources.length,
|
|
707
|
+
warehouse_source_kinds: sources.map((s) => s.kind),
|
|
708
|
+
warehouse_source_modes: sources.map((s) => s.mode)
|
|
709
|
+
});
|
|
710
|
+
if (sources.length > 0) {
|
|
711
|
+
analytics.setTag("warehouse_source_kinds", sources.map((s) => s.kind).join(","));
|
|
712
|
+
analytics.setTag("warehouse_source_count", sources.length);
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
return true;
|
|
716
|
+
}
|
|
717
|
+
/** Dependency-level signal, not a verified install. A failed scan reports false. */
|
|
718
|
+
function detectExistingPostHog(ctx, installDir) {
|
|
719
|
+
try {
|
|
720
|
+
const pkgJsons = findPackageJsons(installDir);
|
|
721
|
+
ctx.setPosthogSdkDetected(pkgJsons.some((p) => p.posthogSdks.length > 0));
|
|
722
|
+
} catch (error) {
|
|
723
|
+
analytics.captureException(error instanceof Error ? error : new Error(String(error)), { step: "detectExistingPosthog" });
|
|
724
|
+
ctx.setPosthogSdkDetected(false);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
//#endregion
|
|
728
|
+
//#region src/programs/posthog-integration/steps.ts
|
|
154
729
|
function needsSetup$1(session) {
|
|
155
730
|
const config = session.frameworkConfig;
|
|
156
731
|
if (!config?.metadata.setup?.questions) return false;
|
|
@@ -471,7 +1046,7 @@ const StatusPeekTrigger = ({ store, duration = 1e4 }) => {
|
|
|
471
1046
|
return /* @__PURE__ */ jsx(Text, { children: "You can view the Wizard's status below." });
|
|
472
1047
|
};
|
|
473
1048
|
//#endregion
|
|
474
|
-
//#region src/
|
|
1049
|
+
//#region src/ui/tui/decks/posthog-integration/data-flow.tsx
|
|
475
1050
|
/**
|
|
476
1051
|
* POSTHOG_DATA_FLOW — ASCII diagram of the PostHog event ingestion flow.
|
|
477
1052
|
*/
|
|
@@ -640,7 +1215,7 @@ const POSTHOG_DATA_FLOW = {
|
|
|
640
1215
|
]
|
|
641
1216
|
};
|
|
642
1217
|
//#endregion
|
|
643
|
-
//#region src/
|
|
1218
|
+
//#region src/ui/tui/decks/posthog-integration/product-suite.tsx
|
|
644
1219
|
/**
|
|
645
1220
|
* PRODUCT_SUITE_BLOCK — Two-column listing of PostHog products.
|
|
646
1221
|
*/
|
|
@@ -760,7 +1335,7 @@ const PRODUCT_SUITE_BLOCK = {
|
|
|
760
1335
|
]
|
|
761
1336
|
};
|
|
762
1337
|
//#endregion
|
|
763
|
-
//#region src/
|
|
1338
|
+
//#region src/ui/tui/decks/posthog-integration/line-chart.tsx
|
|
764
1339
|
/**
|
|
765
1340
|
* LINE_CHART_BLOCK — ASCII trends chart illustrating an insight.
|
|
766
1341
|
*/
|
|
@@ -884,7 +1459,7 @@ const LINE_CHART_BLOCK = {
|
|
|
884
1459
|
]
|
|
885
1460
|
};
|
|
886
1461
|
//#endregion
|
|
887
|
-
//#region src/
|
|
1462
|
+
//#region src/ui/tui/decks/posthog-integration/funnel.tsx
|
|
888
1463
|
/**
|
|
889
1464
|
* FUNNEL_BLOCK — ASCII funnel illustrating step conversion.
|
|
890
1465
|
*/
|
|
@@ -1064,7 +1639,7 @@ const FUNNEL_BLOCK = {
|
|
|
1064
1639
|
]
|
|
1065
1640
|
};
|
|
1066
1641
|
//#endregion
|
|
1067
|
-
//#region src/
|
|
1642
|
+
//#region src/ui/tui/decks/posthog-integration/index.tsx
|
|
1068
1643
|
/**
|
|
1069
1644
|
* Integration learn-deck — the narrative script played while the agent
|
|
1070
1645
|
* runs the PostHog integration flow. Weaves typewriter lines, pauses,
|
|
@@ -1195,10 +1770,65 @@ const getContentBlocks$5 = (store) => [
|
|
|
1195
1770
|
content: "PostHog has all the dev tools you need.",
|
|
1196
1771
|
pause: 3e3
|
|
1197
1772
|
},
|
|
1198
|
-
PRODUCT_SUITE_BLOCK
|
|
1773
|
+
PRODUCT_SUITE_BLOCK,
|
|
1774
|
+
{
|
|
1775
|
+
type: "clear",
|
|
1776
|
+
pause: 2e3
|
|
1777
|
+
},
|
|
1778
|
+
{
|
|
1779
|
+
content: "The wizard is wiring up your PostHog stack with...",
|
|
1780
|
+
pause: 2500
|
|
1781
|
+
},
|
|
1782
|
+
{
|
|
1783
|
+
type: "lines",
|
|
1784
|
+
interval: 1e3,
|
|
1785
|
+
pause: 12e3,
|
|
1786
|
+
lines: [
|
|
1787
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
1788
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1789
|
+
color: "cyan",
|
|
1790
|
+
children: " ◆ "
|
|
1791
|
+
}),
|
|
1792
|
+
"Product Analytics ",
|
|
1793
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1794
|
+
color: "cyan",
|
|
1795
|
+
children: "◆ "
|
|
1796
|
+
}),
|
|
1797
|
+
"Web Analytics"
|
|
1798
|
+
] }),
|
|
1799
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
1800
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1801
|
+
color: "cyan",
|
|
1802
|
+
children: " ◆ "
|
|
1803
|
+
}),
|
|
1804
|
+
"Error Tracking ",
|
|
1805
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1806
|
+
color: "cyan",
|
|
1807
|
+
children: "◆ "
|
|
1808
|
+
}),
|
|
1809
|
+
"Session Replay"
|
|
1810
|
+
] }),
|
|
1811
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
1812
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1813
|
+
color: "cyan",
|
|
1814
|
+
children: " ◆ "
|
|
1815
|
+
}),
|
|
1816
|
+
"AI Observability ",
|
|
1817
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1818
|
+
color: "cyan",
|
|
1819
|
+
children: "◆ "
|
|
1820
|
+
}),
|
|
1821
|
+
"Logs"
|
|
1822
|
+
] }),
|
|
1823
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
1824
|
+
color: "cyan",
|
|
1825
|
+
children: " ◆ "
|
|
1826
|
+
}), "Data Warehouse sources"] })
|
|
1827
|
+
]
|
|
1828
|
+
}
|
|
1199
1829
|
];
|
|
1200
1830
|
//#endregion
|
|
1201
|
-
//#region src/
|
|
1831
|
+
//#region src/programs/posthog-integration/handoff.ts
|
|
1202
1832
|
/**
|
|
1203
1833
|
* The one-line prompt the operator pastes into their own coding agent after a
|
|
1204
1834
|
* run: open the setup-report notebook, work its "Verify before merging"
|
|
@@ -1212,7 +1842,7 @@ function buildCodingAgentPrompt(notebookUrl) {
|
|
|
1212
1842
|
return `Open ${notebookUrl} (the PostHog setup report) and work through its "Verify before merging" checklist: investigate each item, then list the changes you'd make and get my approval before applying any of them.`;
|
|
1213
1843
|
}
|
|
1214
1844
|
//#endregion
|
|
1215
|
-
//#region src/
|
|
1845
|
+
//#region src/programs/posthog-integration/index.ts
|
|
1216
1846
|
const DASHBOARD_DEEP_LINK_KEY = "dashboardDeepLink";
|
|
1217
1847
|
const WAREHOUSE_SOURCES_DOCS_URL = "https://posthog.com/docs/data-warehouse/sources";
|
|
1218
1848
|
/** Task type of the seeded step below, matched against the drain's result. */
|
|
@@ -1369,8 +1999,8 @@ const posthogIntegrationConfig = {
|
|
|
1369
1999
|
disallowedTools: [WIZARD_TOOL_NAMES.wizardAsk],
|
|
1370
2000
|
seedTasks: warehouseSeedTasks,
|
|
1371
2001
|
excludedTaskTypes: (flags) => flags["wizard-default-aio-logs"] === "false" ? ["ai-observability", "logs"] : [],
|
|
1372
|
-
ciPreRun: async (session) => {
|
|
1373
|
-
await scopeInstallDirToProject(session);
|
|
2002
|
+
ciPreRun: async (session, runner) => {
|
|
2003
|
+
await scopeInstallDirToProject(session, runner);
|
|
1374
2004
|
const integration = await detectFramework(session.installDir);
|
|
1375
2005
|
if (!integration) {
|
|
1376
2006
|
await wizardAbort({
|
|
@@ -1393,7 +2023,7 @@ const posthogIntegrationConfig = {
|
|
|
1393
2023
|
});
|
|
1394
2024
|
for (const [key, value] of Object.entries(context)) if (!(key in session.frameworkContext)) session.frameworkContext[key] = value;
|
|
1395
2025
|
},
|
|
1396
|
-
run: async (session) => {
|
|
2026
|
+
run: async (session, runner) => {
|
|
1397
2027
|
const config = session.frameworkConfig;
|
|
1398
2028
|
const typeScriptDetected = isUsingTypeScript({ installDir: session.installDir });
|
|
1399
2029
|
session.typescript = typeScriptDetected;
|
|
@@ -1403,10 +2033,10 @@ const posthogIntegrationConfig = {
|
|
|
1403
2033
|
if (usesPackageJson) {
|
|
1404
2034
|
const packageJson = await tryGetPackageJson({ installDir: session.installDir });
|
|
1405
2035
|
if (packageJson) {
|
|
1406
|
-
const { hasDeclaredDependency } = await import("./package-json-
|
|
1407
|
-
if (!hasDeclaredDependency(config.detection.packageName, packageJson))
|
|
2036
|
+
const { hasDeclaredDependency } = await import("./package-json-DY70kkNp.js").then((n) => n.i);
|
|
2037
|
+
if (!hasDeclaredDependency(config.detection.packageName, packageJson)) runner.log.warn(`${config.detection.packageDisplayName} does not seem to be installed. Continuing anyway — the agent will handle it.`);
|
|
1408
2038
|
frameworkVersion = config.detection.getVersion(packageJson);
|
|
1409
|
-
} else
|
|
2039
|
+
} else runner.log.warn("Could not find package.json. Continuing anyway — the agent will handle it.");
|
|
1410
2040
|
} else frameworkVersion = config.detection.getVersion(null);
|
|
1411
2041
|
if (frameworkVersion && config.detection.getVersionBucket) {
|
|
1412
2042
|
const versionBucket = config.detection.getVersionBucket(frameworkVersion);
|
|
@@ -1428,7 +2058,6 @@ const posthogIntegrationConfig = {
|
|
|
1428
2058
|
reportFile: SETUP_REPORT_FILE,
|
|
1429
2059
|
docsUrl: config.metadata.docsUrl,
|
|
1430
2060
|
errorMessage: "Integration failed",
|
|
1431
|
-
additionalFeatureQueue: session.additionalFeatureQueue,
|
|
1432
2061
|
richLinks: true,
|
|
1433
2062
|
customPrompt: (ctx) => {
|
|
1434
2063
|
const additionalLines = config.prompts.getAdditionalContextLines ? config.prompts.getAdditionalContextLines(frameworkContext) : [];
|
|
@@ -1473,7 +2102,7 @@ ${warehouseReportInstruction(session)}
|
|
|
1473
2102
|
postRun: async (sess, credentials) => {
|
|
1474
2103
|
const envVars = config.environment.getEnvVars(credentials.projectApiKey, credentials.host.apiHost);
|
|
1475
2104
|
if (config.environment.uploadToHosting) {
|
|
1476
|
-
const { uploadEnvironmentVariablesStep } = await import("./steps-
|
|
2105
|
+
const { uploadEnvironmentVariablesStep } = await import("./steps-gx0Pq4I4.js");
|
|
1477
2106
|
const uploadedEnvVars = await uploadEnvironmentVariablesStep(envVars, {
|
|
1478
2107
|
integration: config.metadata.integration,
|
|
1479
2108
|
session: sess
|
|
@@ -1524,11 +2153,11 @@ const integrationRunStep = {
|
|
|
1524
2153
|
id: "run",
|
|
1525
2154
|
label: "Integration",
|
|
1526
2155
|
screenId: "run",
|
|
1527
|
-
run: (session) =>
|
|
2156
|
+
run: (session) => runProgramAgent(posthogIntegrationConfig, session, { composed: true }),
|
|
1528
2157
|
isComplete: (session) => session.runPhase === "completed" || session.runPhase === "error"
|
|
1529
2158
|
};
|
|
1530
2159
|
//#endregion
|
|
1531
|
-
//#region src/
|
|
2160
|
+
//#region src/programs/revenue-analytics/detect.ts
|
|
1532
2161
|
/**
|
|
1533
2162
|
* Revenue analytics prerequisite detection.
|
|
1534
2163
|
*
|
|
@@ -1621,7 +2250,7 @@ function detectRevenuePrerequisites(session, setFrameworkContext) {
|
|
|
1621
2250
|
setFrameworkContext("detectedPackagePaths", matches.filter((m) => m.posthogSdks.length > 0 || m.stripeSdks.length > 0).map((m) => m.path));
|
|
1622
2251
|
}
|
|
1623
2252
|
//#endregion
|
|
1624
|
-
//#region src/
|
|
2253
|
+
//#region src/programs/revenue-analytics/steps.ts
|
|
1625
2254
|
const REVENUE_ANALYTICS_PROGRAM = [
|
|
1626
2255
|
{
|
|
1627
2256
|
id: "detect",
|
|
@@ -1660,7 +2289,7 @@ const REVENUE_ANALYTICS_PROGRAM = [
|
|
|
1660
2289
|
}
|
|
1661
2290
|
];
|
|
1662
2291
|
//#endregion
|
|
1663
|
-
//#region src/
|
|
2292
|
+
//#region src/ui/tui/decks/agent-skill/index.tsx
|
|
1664
2293
|
/**
|
|
1665
2294
|
* Agent-skill learn-deck — the short three-line sequence shown while a
|
|
1666
2295
|
* skill-based program (audit, revenue-analytics, agent-skill, etc.)
|
|
@@ -1692,7 +2321,7 @@ const getContentBlocks$4 = (store) => {
|
|
|
1692
2321
|
];
|
|
1693
2322
|
};
|
|
1694
2323
|
//#endregion
|
|
1695
|
-
//#region src/
|
|
2324
|
+
//#region src/programs/revenue-analytics/index.ts
|
|
1696
2325
|
const revenueAnalyticsConfig = {
|
|
1697
2326
|
command: "revenue-analytics",
|
|
1698
2327
|
description: "Set up PostHog for Revenue Analytics",
|
|
@@ -1716,7 +2345,7 @@ const revenueAnalyticsConfig = {
|
|
|
1716
2345
|
requires: ["posthog-integration"]
|
|
1717
2346
|
};
|
|
1718
2347
|
//#endregion
|
|
1719
|
-
//#region src/
|
|
2348
|
+
//#region src/programs/warehouse-source/steps.ts
|
|
1720
2349
|
const WAREHOUSE_SOURCE_PROGRAM = [
|
|
1721
2350
|
{
|
|
1722
2351
|
id: "detect",
|
|
@@ -1754,7 +2383,7 @@ const WAREHOUSE_SOURCE_PROGRAM = [
|
|
|
1754
2383
|
}
|
|
1755
2384
|
];
|
|
1756
2385
|
//#endregion
|
|
1757
|
-
//#region src/
|
|
2386
|
+
//#region src/programs/warehouse-source/index.ts
|
|
1758
2387
|
/**
|
|
1759
2388
|
* Inject the detected sources (and their creation mode) into the prompt so the
|
|
1760
2389
|
* skill knows what to set up. The *how* — in-CLI creation vs deep-link, field
|
|
@@ -1797,7 +2426,7 @@ const warehouseSourceConfig = {
|
|
|
1797
2426
|
requires: ["posthog-integration"]
|
|
1798
2427
|
};
|
|
1799
2428
|
//#endregion
|
|
1800
|
-
//#region src/
|
|
2429
|
+
//#region src/programs/agent-skill/steps.ts
|
|
1801
2430
|
const AGENT_SKILL_STEPS = [
|
|
1802
2431
|
{
|
|
1803
2432
|
id: "intro",
|
|
@@ -1831,7 +2460,7 @@ const AGENT_SKILL_STEPS = [
|
|
|
1831
2460
|
}
|
|
1832
2461
|
];
|
|
1833
2462
|
//#endregion
|
|
1834
|
-
//#region src/
|
|
2463
|
+
//#region src/programs/agent-skill/index.ts
|
|
1835
2464
|
function createSkillProgram(opts) {
|
|
1836
2465
|
return {
|
|
1837
2466
|
command: opts.command,
|
|
@@ -1857,7 +2486,7 @@ function createSkillProgram(opts) {
|
|
|
1857
2486
|
};
|
|
1858
2487
|
}
|
|
1859
2488
|
//#endregion
|
|
1860
|
-
//#region src/
|
|
2489
|
+
//#region src/programs/audit/detect.ts
|
|
1861
2490
|
/** `[ABORT] <reason>` cases the audit skill can emit. Reason strings are
|
|
1862
2491
|
* defined in the skill's `Abort statuses` section. */
|
|
1863
2492
|
const AUDIT_ABORT_CASES = [{
|
|
@@ -1868,7 +2497,7 @@ const AUDIT_ABORT_CASES = [{
|
|
|
1868
2497
|
docsUrl: "https://posthog.com/docs/getting-started/install"
|
|
1869
2498
|
}];
|
|
1870
2499
|
//#endregion
|
|
1871
|
-
//#region src/
|
|
2500
|
+
//#region src/programs/audit/seed.ts
|
|
1872
2501
|
/**
|
|
1873
2502
|
* The 10 source-tree checks the audit runs, plus one row for the PostHog-side
|
|
1874
2503
|
* sweep and two workflow rows at the end (so the skill's
|
|
@@ -1984,7 +2613,7 @@ function seedAuditLedger(installDir, checks = AUDIT_SEED_CHECKS) {
|
|
|
1984
2613
|
logToFile(`seedAuditLedger: wrote ${checks.length} entries to ${target}`);
|
|
1985
2614
|
}
|
|
1986
2615
|
//#endregion
|
|
1987
|
-
//#region src/
|
|
2616
|
+
//#region src/programs/audit/index.ts
|
|
1988
2617
|
/** Audit-specific screens for the shared agent-skill pipeline. */
|
|
1989
2618
|
const AUDIT_SCREEN_BY_STEP = {
|
|
1990
2619
|
intro: "audit-intro",
|
|
@@ -2018,10 +2647,10 @@ const baseConfig = createSkillProgram({
|
|
|
2018
2647
|
requires: ["posthog-integration"],
|
|
2019
2648
|
abortCases: AUDIT_ABORT_CASES
|
|
2020
2649
|
});
|
|
2021
|
-
const auditRun = async (session) => {
|
|
2650
|
+
const auditRun = async (session, runner) => {
|
|
2022
2651
|
seedBeforeAuditRun(session);
|
|
2023
2652
|
if (!baseConfig.run) throw new Error("Audit program has no run configuration.");
|
|
2024
|
-
const baseRun = typeof baseConfig.run === "function" ? await baseConfig.run(session) : baseConfig.run;
|
|
2653
|
+
const baseRun = typeof baseConfig.run === "function" ? await baseConfig.run(session, runner) : baseConfig.run;
|
|
2025
2654
|
return {
|
|
2026
2655
|
...baseRun,
|
|
2027
2656
|
buildOutroData: (sess, credentials) => {
|
|
@@ -2057,7 +2686,7 @@ const auditConfig = {
|
|
|
2057
2686
|
}
|
|
2058
2687
|
};
|
|
2059
2688
|
//#endregion
|
|
2060
|
-
//#region src/
|
|
2689
|
+
//#region src/programs/events-audit/steps.ts
|
|
2061
2690
|
function needsSetup(session) {
|
|
2062
2691
|
const config = session.frameworkConfig;
|
|
2063
2692
|
if (!config?.metadata.setup?.questions) return false;
|
|
@@ -2109,7 +2738,7 @@ const EVENTS_AUDIT_PROGRAM = [
|
|
|
2109
2738
|
}
|
|
2110
2739
|
];
|
|
2111
2740
|
//#endregion
|
|
2112
|
-
//#region src/
|
|
2741
|
+
//#region src/programs/events-audit/seed.ts
|
|
2113
2742
|
/**
|
|
2114
2743
|
* The 7 phases the events-audit skill marches through. One check per area
|
|
2115
2744
|
* so PendingChecksList renders a clean linear pipeline (area = bold header,
|
|
@@ -2165,7 +2794,7 @@ const EVENTS_AUDIT_SEED_CHECKS = [
|
|
|
2165
2794
|
}
|
|
2166
2795
|
];
|
|
2167
2796
|
//#endregion
|
|
2168
|
-
//#region src/
|
|
2797
|
+
//#region src/programs/events-audit/index.ts
|
|
2169
2798
|
const DOCS_URL$3 = "https://posthog.com/docs/product-analytics/best-practices";
|
|
2170
2799
|
/**
|
|
2171
2800
|
* No CLI word of its own since the audit family took over: `wizard audit
|
|
@@ -2178,7 +2807,7 @@ const eventsAuditConfig = {
|
|
|
2178
2807
|
id: "events-audit",
|
|
2179
2808
|
skillId: "events-audit",
|
|
2180
2809
|
steps: EVENTS_AUDIT_PROGRAM,
|
|
2181
|
-
reportFile:
|
|
2810
|
+
reportFile: EVENTS_AUDIT_REPORT_FILE,
|
|
2182
2811
|
auditLedgerFile: AUDIT_CHECKS_FILE,
|
|
2183
2812
|
allowedTools: [
|
|
2184
2813
|
"Agent",
|
|
@@ -2198,10 +2827,9 @@ const eventsAuditConfig = {
|
|
|
2198
2827
|
spinnerMessage: SPINNER_MESSAGE,
|
|
2199
2828
|
successMessage: "Events audit complete! You can view the report at ./posthog-events-audit-report.md",
|
|
2200
2829
|
estimatedDurationMinutes: 5,
|
|
2201
|
-
reportFile:
|
|
2830
|
+
reportFile: EVENTS_AUDIT_REPORT_FILE,
|
|
2202
2831
|
docsUrl: DOCS_URL$3,
|
|
2203
2832
|
errorMessage: "Events audit failed",
|
|
2204
|
-
additionalFeatureQueue: session.additionalFeatureQueue,
|
|
2205
2833
|
customPrompt: (ctx) => `Audit PostHog event capture in this project. Do not modify any project files — produce a read-only report only.
|
|
2206
2834
|
|
|
2207
2835
|
Project context:
|
|
@@ -2215,7 +2843,7 @@ Project context:
|
|
|
2215
2843
|
return {
|
|
2216
2844
|
kind: "success",
|
|
2217
2845
|
message: "Your events audit was successful",
|
|
2218
|
-
reportFile:
|
|
2846
|
+
reportFile: EVENTS_AUDIT_REPORT_FILE,
|
|
2219
2847
|
changes: [],
|
|
2220
2848
|
docsUrl: DOCS_URL$3,
|
|
2221
2849
|
continueUrl: sess.signup ? `${cloudUrl}/products?source=wizard` : void 0,
|
|
@@ -2227,7 +2855,7 @@ Project context:
|
|
|
2227
2855
|
}
|
|
2228
2856
|
};
|
|
2229
2857
|
//#endregion
|
|
2230
|
-
//#region src/
|
|
2858
|
+
//#region src/programs/posthog-doctor/steps.ts
|
|
2231
2859
|
const POSTHOG_DOCTOR_PROGRAM = [
|
|
2232
2860
|
{
|
|
2233
2861
|
id: "intro",
|
|
@@ -2256,7 +2884,7 @@ const POSTHOG_DOCTOR_PROGRAM = [
|
|
|
2256
2884
|
}
|
|
2257
2885
|
];
|
|
2258
2886
|
//#endregion
|
|
2259
|
-
//#region src/
|
|
2887
|
+
//#region src/programs/posthog-doctor/types.ts
|
|
2260
2888
|
const HealthIssueSeveritySchema = z.enum([
|
|
2261
2889
|
"critical",
|
|
2262
2890
|
"warning",
|
|
@@ -2280,7 +2908,7 @@ const HealthIssueListResponseSchema = z.object({
|
|
|
2280
2908
|
previous: z.string().nullable().optional()
|
|
2281
2909
|
});
|
|
2282
2910
|
//#endregion
|
|
2283
|
-
//#region src/
|
|
2911
|
+
//#region src/programs/posthog-doctor/fetch.ts
|
|
2284
2912
|
async function fetchHealthIssues(accessToken, baseUrl, projectId) {
|
|
2285
2913
|
const endpoint = `/api/environments/${projectId}/health_issues/`;
|
|
2286
2914
|
const url = `${baseUrl}${endpoint}?status=active&dismissed=false&limit=250`;
|
|
@@ -2301,7 +2929,7 @@ async function fetchHealthIssues(accessToken, baseUrl, projectId) {
|
|
|
2301
2929
|
}
|
|
2302
2930
|
}
|
|
2303
2931
|
//#endregion
|
|
2304
|
-
//#region src/
|
|
2932
|
+
//#region src/programs/posthog-doctor/kind-metadata.ts
|
|
2305
2933
|
const KIND_METADATA = {
|
|
2306
2934
|
ingestion_lag: {
|
|
2307
2935
|
title: "Ingestion is delayed",
|
|
@@ -2371,7 +2999,7 @@ function getKindMeta(kind) {
|
|
|
2371
2999
|
};
|
|
2372
3000
|
}
|
|
2373
3001
|
//#endregion
|
|
2374
|
-
//#region src/
|
|
3002
|
+
//#region src/programs/posthog-doctor/index.ts
|
|
2375
3003
|
const posthogDoctorConfig = {
|
|
2376
3004
|
command: "doctor",
|
|
2377
3005
|
description: "Diagnose your PostHog project setup",
|
|
@@ -2382,7 +3010,7 @@ const posthogDoctorConfig = {
|
|
|
2382
3010
|
disallowedTools: [WIZARD_TOOL_NAMES.wizardAsk]
|
|
2383
3011
|
};
|
|
2384
3012
|
//#endregion
|
|
2385
|
-
//#region src/
|
|
3013
|
+
//#region src/programs/web-analytics-doctor/detect.ts
|
|
2386
3014
|
const WEB_ANALYTICS_ABORT_CASES = [
|
|
2387
3015
|
{
|
|
2388
3016
|
match: /^no web analytics events$/i,
|
|
@@ -2449,7 +3077,7 @@ function detectWebAnalyticsPrerequisites(session, setFrameworkContext) {
|
|
|
2449
3077
|
setFrameworkContext("detectedPosthogSdks", sdks);
|
|
2450
3078
|
}
|
|
2451
3079
|
//#endregion
|
|
2452
|
-
//#region src/
|
|
3080
|
+
//#region src/programs/web-analytics-doctor/steps.ts
|
|
2453
3081
|
const WEB_ANALYTICS_DOCTOR_PROGRAM = [{
|
|
2454
3082
|
id: "detect",
|
|
2455
3083
|
label: "Detecting prerequisites",
|
|
@@ -2475,7 +3103,7 @@ const webAnalyticsDoctorConfig = {
|
|
|
2475
3103
|
parentCommand: "audit"
|
|
2476
3104
|
};
|
|
2477
3105
|
//#endregion
|
|
2478
|
-
//#region src/
|
|
3106
|
+
//#region src/programs/migration/steps.ts
|
|
2479
3107
|
const MIGRATION_PROGRAM = [
|
|
2480
3108
|
{
|
|
2481
3109
|
id: "intro",
|
|
@@ -2509,7 +3137,7 @@ const MIGRATION_PROGRAM = [
|
|
|
2509
3137
|
}
|
|
2510
3138
|
];
|
|
2511
3139
|
//#endregion
|
|
2512
|
-
//#region src/
|
|
3140
|
+
//#region src/ui/tui/decks/migration/vendor-stack.tsx
|
|
2513
3141
|
/**
|
|
2514
3142
|
* Vendor cost stack — the multi-tool baseline a typical migration target has
|
|
2515
3143
|
* before consolidating onto PostHog. Numbers from each vendor's published
|
|
@@ -2589,7 +3217,7 @@ const VENDOR_STACK_BLOCK = {
|
|
|
2589
3217
|
]
|
|
2590
3218
|
};
|
|
2591
3219
|
//#endregion
|
|
2592
|
-
//#region src/
|
|
3220
|
+
//#region src/ui/tui/decks/migration/free-tier.tsx
|
|
2593
3221
|
/**
|
|
2594
3222
|
* PostHog free-tier highlights — the numbers a migrating team gets back when
|
|
2595
3223
|
* they consolidate. Sourced from posthog.com/pricing.md.
|
|
@@ -2695,7 +3323,7 @@ const FREE_TIER_BLOCK = {
|
|
|
2695
3323
|
]
|
|
2696
3324
|
};
|
|
2697
3325
|
//#endregion
|
|
2698
|
-
//#region src/
|
|
3326
|
+
//#region src/ui/tui/decks/migration/pricing-structure.tsx
|
|
2699
3327
|
/**
|
|
2700
3328
|
* Pricing structure block — what happens after the free tier.
|
|
2701
3329
|
*/
|
|
@@ -2736,7 +3364,7 @@ const PRICING_STRUCTURE_BLOCK = {
|
|
|
2736
3364
|
]
|
|
2737
3365
|
};
|
|
2738
3366
|
//#endregion
|
|
2739
|
-
//#region src/
|
|
3367
|
+
//#region src/ui/tui/decks/migration/index.tsx
|
|
2740
3368
|
/**
|
|
2741
3369
|
* Migration learn deck (statsig variant). Statsig is the only `migrate`
|
|
2742
3370
|
* variant today, so this deck plays as-is when the wizard runs
|
|
@@ -2984,7 +3612,7 @@ const getContentBlocks$3 = (store) => [
|
|
|
2984
3612
|
FUNNEL_BLOCK
|
|
2985
3613
|
];
|
|
2986
3614
|
//#endregion
|
|
2987
|
-
//#region src/
|
|
3615
|
+
//#region src/programs/migration/index.ts
|
|
2988
3616
|
const MIGRATION_REPORT_FILE = "migration-report.md";
|
|
2989
3617
|
const MIGRATION_ABORT_CASES = [{
|
|
2990
3618
|
match: /^no source-sdk calls found$/i,
|
|
@@ -3016,7 +3644,7 @@ const migrationConfig = {
|
|
|
3016
3644
|
requires: ["posthog-integration"]
|
|
3017
3645
|
};
|
|
3018
3646
|
//#endregion
|
|
3019
|
-
//#region src/
|
|
3647
|
+
//#region src/programs/error-tracking-upload-source-maps/detect.ts
|
|
3020
3648
|
const DISPLAY_NAME = {
|
|
3021
3649
|
web: "Web (JavaScript)",
|
|
3022
3650
|
nextjs: "Next.js",
|
|
@@ -3125,7 +3753,7 @@ const SOURCE_MAPS_CONTEXT_KEYS = {
|
|
|
3125
3753
|
selectedPath: "sourceMapsSelectedPath"
|
|
3126
3754
|
};
|
|
3127
3755
|
//#endregion
|
|
3128
|
-
//#region src/
|
|
3756
|
+
//#region src/programs/error-tracking-upload-source-maps/steps.ts
|
|
3129
3757
|
function projectSelected(session) {
|
|
3130
3758
|
return session.frameworkContext[SOURCE_MAPS_CONTEXT_KEYS.selectedVariant] != null;
|
|
3131
3759
|
}
|
|
@@ -3168,7 +3796,7 @@ const ERROR_TRACKING_UPLOAD_SOURCE_MAPS_PROGRAM = [
|
|
|
3168
3796
|
}
|
|
3169
3797
|
];
|
|
3170
3798
|
//#endregion
|
|
3171
|
-
//#region src/
|
|
3799
|
+
//#region src/programs/error-tracking-upload-source-maps/prompt.ts
|
|
3172
3800
|
const SOURCE_MAPS_DETECTION_FAILED_PROMPT = `Detection did not pick a source maps skill variant for this project.
|
|
3173
3801
|
Emit: ${AgentSignals.ABORT} unsupported-platform
|
|
3174
3802
|
Then halt.`;
|
|
@@ -3366,7 +3994,7 @@ STEP 9 — Summarise and hand off. (skill: "Verify and hand off")
|
|
|
3366
3994
|
`;
|
|
3367
3995
|
}
|
|
3368
3996
|
//#endregion
|
|
3369
|
-
//#region src/
|
|
3997
|
+
//#region src/ui/tui/decks/error-tracking-upload-source-maps/index.tsx
|
|
3370
3998
|
/**
|
|
3371
3999
|
* Source-maps learn-deck — the narrative played in the run screen's left
|
|
3372
4000
|
* pane (LearnCard) while the agent wires source-map upload into the build.
|
|
@@ -3803,18 +4431,9 @@ function installSteeringSnippet(filePath) {
|
|
|
3803
4431
|
};
|
|
3804
4432
|
}
|
|
3805
4433
|
//#endregion
|
|
3806
|
-
//#region src/
|
|
3807
|
-
/**
|
|
3808
|
-
* Machine-global posthog-cli pre-install, shared by the programs whose symbol
|
|
3809
|
-
* upload shells out to it (error-tracking and error-tracking-upload-source-maps).
|
|
3810
|
-
*
|
|
3811
|
-
* The agent cannot install a global package — warlock blocks `npm install -g`
|
|
3812
|
-
* — so the wizard does it in-process, at most once per process. Warn, don't
|
|
3813
|
-
* fail: the run still instruments capture, and only the release build's upload
|
|
3814
|
-
* needs the CLI.
|
|
3815
|
-
*/
|
|
4434
|
+
//#region src/programs/shared/posthog-cli-preinstall.ts
|
|
3816
4435
|
let attempted = false;
|
|
3817
|
-
function preinstallPostHogCliOnce(failureEvent, properties) {
|
|
4436
|
+
function preinstallPostHogCliOnce(failureEvent, properties, log) {
|
|
3818
4437
|
if (attempted) return;
|
|
3819
4438
|
attempted = true;
|
|
3820
4439
|
const result = installOrUpdatePostHogCli();
|
|
@@ -3823,10 +4442,10 @@ function preinstallPostHogCliOnce(failureEvent, properties) {
|
|
|
3823
4442
|
...properties,
|
|
3824
4443
|
error: String(result.error).slice(0, 500)
|
|
3825
4444
|
});
|
|
3826
|
-
|
|
4445
|
+
log.warn(`Could not pre-install posthog-cli (${result.error}). Your release build will fail to upload debug symbols until it's installed: npm install -g @posthog/cli@latest`);
|
|
3827
4446
|
}
|
|
3828
4447
|
//#endregion
|
|
3829
|
-
//#region src/
|
|
4448
|
+
//#region src/programs/error-tracking-upload-source-maps/index.ts
|
|
3830
4449
|
const REPORT_FILE$1 = "posthog-source-maps-report.md";
|
|
3831
4450
|
const DOCS_URL$1 = "https://posthog.com/docs/error-tracking/upload-source-maps";
|
|
3832
4451
|
/**
|
|
@@ -3834,8 +4453,8 @@ const DOCS_URL$1 = "https://posthog.com/docs/error-tracking/upload-source-maps";
|
|
|
3834
4453
|
* (`VARIANTS_REQUIRING_POSTHOG_CLI`). See `preinstallPostHogCliOnce` for the
|
|
3835
4454
|
* once-per-process guard and the warn-don't-fail handling.
|
|
3836
4455
|
*/
|
|
3837
|
-
function ensurePostHogCli(variant) {
|
|
3838
|
-
preinstallPostHogCliOnce("source maps posthog-cli preinstall failed", { variant });
|
|
4456
|
+
function ensurePostHogCli(variant, log) {
|
|
4457
|
+
preinstallPostHogCliOnce("source maps posthog-cli preinstall failed", { variant }, log);
|
|
3839
4458
|
}
|
|
3840
4459
|
const errorTrackingUploadSourceMapsConfig = {
|
|
3841
4460
|
command: "upload-source-maps",
|
|
@@ -3846,13 +4465,13 @@ const errorTrackingUploadSourceMapsConfig = {
|
|
|
3846
4465
|
reportFile: REPORT_FILE$1,
|
|
3847
4466
|
getContentBlocks: getContentBlocks$2,
|
|
3848
4467
|
requires: ["posthog-integration"],
|
|
3849
|
-
run: (_session) => {
|
|
4468
|
+
run: (_session, runner) => {
|
|
3850
4469
|
const readSelection = () => {
|
|
3851
|
-
const variant =
|
|
4470
|
+
const variant = runner.getFrameworkContext(SOURCE_MAPS_CONTEXT_KEYS.selectedVariant);
|
|
3852
4471
|
return {
|
|
3853
4472
|
variant,
|
|
3854
|
-
displayName:
|
|
3855
|
-
projectPath:
|
|
4473
|
+
displayName: runner.getFrameworkContext(SOURCE_MAPS_CONTEXT_KEYS.selectedDisplayName),
|
|
4474
|
+
projectPath: runner.getFrameworkContext(SOURCE_MAPS_CONTEXT_KEYS.selectedPath),
|
|
3856
4475
|
skillId: variant ? `error-tracking-upload-source-maps-${variant}` : void 0
|
|
3857
4476
|
};
|
|
3858
4477
|
};
|
|
@@ -3868,7 +4487,7 @@ const errorTrackingUploadSourceMapsConfig = {
|
|
|
3868
4487
|
customPrompt: (ctx) => {
|
|
3869
4488
|
const { variant, displayName, projectPath, skillId } = readSelection();
|
|
3870
4489
|
if (!skillId || !variant) return SOURCE_MAPS_DETECTION_FAILED_PROMPT;
|
|
3871
|
-
if (VARIANTS_REQUIRING_POSTHOG_CLI.has(variant)) ensurePostHogCli(variant);
|
|
4490
|
+
if (VARIANTS_REQUIRING_POSTHOG_CLI.has(variant)) ensurePostHogCli(variant, runner.log);
|
|
3872
4491
|
const uiHost = ctx.host.appHost.replace(/\/$/, "");
|
|
3873
4492
|
return buildSourceMapsUploadPrompt({
|
|
3874
4493
|
displayName,
|
|
@@ -3884,7 +4503,7 @@ const errorTrackingUploadSourceMapsConfig = {
|
|
|
3884
4503
|
},
|
|
3885
4504
|
postRun: () => {
|
|
3886
4505
|
const { variant } = readSelection();
|
|
3887
|
-
if (variant)
|
|
4506
|
+
if (variant) runner.setFrameworkContext("sourceMapsCompletedVariant", variant);
|
|
3888
4507
|
return Promise.resolve();
|
|
3889
4508
|
},
|
|
3890
4509
|
buildOutroData: () => {
|
|
@@ -3899,13 +4518,13 @@ const errorTrackingUploadSourceMapsConfig = {
|
|
|
3899
4518
|
}
|
|
3900
4519
|
};
|
|
3901
4520
|
//#endregion
|
|
3902
|
-
//#region src/
|
|
4521
|
+
//#region src/ui/tui/decks/error-tracking/index.tsx
|
|
3903
4522
|
const getContentBlocks$1 = (store) => buildSourceMapsDeck(store, {
|
|
3904
4523
|
intro: "I'm wiring PostHog Error Tracking into your project.",
|
|
3905
4524
|
wiring: "If your platform ships minified code or stripped binaries, I also hook source-map or debug-symbol upload into your build, tied to each release you ship."
|
|
3906
4525
|
});
|
|
3907
4526
|
//#endregion
|
|
3908
|
-
//#region src/
|
|
4527
|
+
//#region src/programs/replay-vision/index.ts
|
|
3909
4528
|
const REPLAY_VISION_REPORT_FILE = "posthog-replay-vision-report.md";
|
|
3910
4529
|
/**
|
|
3911
4530
|
* The platforms session replay can actually record on. Replay vision watches
|
|
@@ -4018,8 +4637,8 @@ const replayVisionConfig = {
|
|
|
4018
4637
|
}),
|
|
4019
4638
|
agentFlow: "replay-vision",
|
|
4020
4639
|
steps: [DETECT_STEP, ...AGENT_SKILL_STEPS],
|
|
4021
|
-
ciPreRun: async (session) => {
|
|
4022
|
-
await scopeInstallDirToProject(session);
|
|
4640
|
+
ciPreRun: async (session, runner) => {
|
|
4641
|
+
await scopeInstallDirToProject(session, runner);
|
|
4023
4642
|
const integration = await detectFramework(session.installDir);
|
|
4024
4643
|
if (!integration) {
|
|
4025
4644
|
await wizardAbort({
|
|
@@ -4049,7 +4668,7 @@ const replayVisionConfig = {
|
|
|
4049
4668
|
}
|
|
4050
4669
|
};
|
|
4051
4670
|
//#endregion
|
|
4052
|
-
//#region src/
|
|
4671
|
+
//#region src/ui/tui/decks/error-tracking/tips.ts
|
|
4053
4672
|
const ERROR_TRACKING_TIPS = [
|
|
4054
4673
|
{
|
|
4055
4674
|
id: "session-replay",
|
|
@@ -4073,7 +4692,7 @@ const ERROR_TRACKING_TIPS = [
|
|
|
4073
4692
|
];
|
|
4074
4693
|
const getTips$1 = () => ERROR_TRACKING_TIPS;
|
|
4075
4694
|
//#endregion
|
|
4076
|
-
//#region src/
|
|
4695
|
+
//#region src/programs/error-tracking/detect-agentic.ts
|
|
4077
4696
|
/** frameworkContext key for the picked project's path, relative to the repo root. */
|
|
4078
4697
|
const ERROR_TRACKING_PROJECT_PATH_KEY = "errorTrackingProjectPath";
|
|
4079
4698
|
/** KMP skill variants carry no `framework` tag, so orchestrator preflight aborts every KMP run. */
|
|
@@ -4118,7 +4737,7 @@ async function gatherErrorTrackingContext(session) {
|
|
|
4118
4737
|
for (const [key, value] of Object.entries(context)) if (!(key in session.frameworkContext)) session.frameworkContext[key] = value;
|
|
4119
4738
|
}
|
|
4120
4739
|
//#endregion
|
|
4121
|
-
//#region src/
|
|
4740
|
+
//#region src/programs/error-tracking/index.ts
|
|
4122
4741
|
const ERROR_TRACKING_REPORT_FILE = "posthog-error-tracking-report.md";
|
|
4123
4742
|
const ERROR_TRACKING_DOCS_URL = "https://posthog.com/docs/error-tracking";
|
|
4124
4743
|
/**
|
|
@@ -4150,9 +4769,9 @@ async function abortUnsupportedPlatform(integration) {
|
|
|
4150
4769
|
* shell out to it. See `preinstallPostHogCliOnce` for the once-per-process
|
|
4151
4770
|
* guard and the warn-don't-fail handling.
|
|
4152
4771
|
*/
|
|
4153
|
-
function maybePreinstallPostHogCli(integration) {
|
|
4772
|
+
function maybePreinstallPostHogCli(integration, log) {
|
|
4154
4773
|
if (!integration || !SYMBOL_UPLOAD_CLI_FRAMEWORKS.has(integration)) return;
|
|
4155
|
-
preinstallPostHogCliOnce("error tracking posthog-cli preinstall failed", { integration });
|
|
4774
|
+
preinstallPostHogCliOnce("error tracking posthog-cli preinstall failed", { integration }, log);
|
|
4156
4775
|
}
|
|
4157
4776
|
/**
|
|
4158
4777
|
* After login, the scan lists the repo's projects and the user picks one, as in
|
|
@@ -4247,12 +4866,12 @@ const errorTrackingConfig = {
|
|
|
4247
4866
|
reportFile: ERROR_TRACKING_REPORT_FILE,
|
|
4248
4867
|
getContentBlocks: getContentBlocks$1,
|
|
4249
4868
|
getTips: getTips$1,
|
|
4250
|
-
run: (session) => {
|
|
4251
|
-
maybePreinstallPostHogCli(session.integration);
|
|
4869
|
+
run: (session, runner) => {
|
|
4870
|
+
maybePreinstallPostHogCli(session.integration, runner.log);
|
|
4252
4871
|
return Promise.resolve(ERROR_TRACKING_RUN);
|
|
4253
4872
|
},
|
|
4254
|
-
ciPreRun: async (session) => {
|
|
4255
|
-
await scopeInstallDirToProject(session);
|
|
4873
|
+
ciPreRun: async (session, runner) => {
|
|
4874
|
+
await scopeInstallDirToProject(session, runner);
|
|
4256
4875
|
const integration = await detectFramework(session.installDir);
|
|
4257
4876
|
if (!integration) {
|
|
4258
4877
|
await wizardAbort({
|
|
@@ -4273,7 +4892,7 @@ const errorTrackingConfig = {
|
|
|
4273
4892
|
}
|
|
4274
4893
|
};
|
|
4275
4894
|
//#endregion
|
|
4276
|
-
//#region src/
|
|
4895
|
+
//#region src/programs/self-driving/detect.ts
|
|
4277
4896
|
/**
|
|
4278
4897
|
* Self-driving prerequisite detection + abort vocabulary.
|
|
4279
4898
|
*
|
|
@@ -4539,7 +5158,7 @@ function detectConnectedTools(installDir, setFrameworkContext) {
|
|
|
4539
5158
|
}
|
|
4540
5159
|
}
|
|
4541
5160
|
//#endregion
|
|
4542
|
-
//#region src/
|
|
5161
|
+
//#region src/programs/self-driving/detect-agentic.ts
|
|
4543
5162
|
function classify(integration, hasPostHog) {
|
|
4544
5163
|
if (integration == null) return {
|
|
4545
5164
|
instrumentable: false,
|
|
@@ -4594,7 +5213,7 @@ async function prepSelfDrivingIntegration(session) {
|
|
|
4594
5213
|
for (const [key, value] of Object.entries(context)) if (!(key in session.frameworkContext)) session.frameworkContext[key] = value;
|
|
4595
5214
|
}
|
|
4596
5215
|
//#endregion
|
|
4597
|
-
//#region src/
|
|
5216
|
+
//#region src/programs/self-driving/steps.ts
|
|
4598
5217
|
/** True once detection found PostHog already present in the project. */
|
|
4599
5218
|
const postHogPresent = (session) => session.frameworkContext[POSTHOG_PRESENT_KEY] === true;
|
|
4600
5219
|
/** Absolute dir to integrate into: the picked sub-app (LLM output — the shared resolver clamps escapes), else the repo root. */
|
|
@@ -4670,7 +5289,7 @@ const SELF_DRIVING_PROGRAM = [
|
|
|
4670
5289
|
}
|
|
4671
5290
|
];
|
|
4672
5291
|
//#endregion
|
|
4673
|
-
//#region src/
|
|
5292
|
+
//#region src/programs/self-driving/prompt.ts
|
|
4674
5293
|
/**
|
|
4675
5294
|
* Render the deterministic codebase-tool scan for the prompt. STEP 4 and
|
|
4676
5295
|
* STEP 5 read this instead of the agent doing its own flaky "light scan":
|
|
@@ -4873,7 +5492,7 @@ STEP 7 — Write the report and hand off. (skill: "Report")
|
|
|
4873
5492
|
at ${inboxUrl} within about 30 minutes.`;
|
|
4874
5493
|
}
|
|
4875
5494
|
//#endregion
|
|
4876
|
-
//#region src/
|
|
5495
|
+
//#region src/programs/self-driving/step-keys.ts
|
|
4877
5496
|
/**
|
|
4878
5497
|
* First match wins, so order is the rule. Entity words come before verbs: "Checking GitHub
|
|
4879
5498
|
* connection" is the GitHub step, not the access-check step, and "Connecting issue trackers" must
|
|
@@ -4942,7 +5561,7 @@ const PRICING_LONG = `A report that ships a pull request costs a flat $15. Every
|
|
|
4942
5561
|
*/
|
|
4943
5562
|
const NO_DEFAULT_LIMIT = "A paid plan has no monthly cap until you set one. Add a PR limit in your inbox sidebar, and agents pause when they hit it.";
|
|
4944
5563
|
//#endregion
|
|
4945
|
-
//#region src/
|
|
5564
|
+
//#region src/ui/tui/decks/self-driving/tips.ts
|
|
4946
5565
|
const SELF_DRIVING_TIPS = [
|
|
4947
5566
|
{
|
|
4948
5567
|
id: "signal-source",
|
|
@@ -4982,7 +5601,7 @@ const SELF_DRIVING_TIPS = [
|
|
|
4982
5601
|
];
|
|
4983
5602
|
const getTips = () => SELF_DRIVING_TIPS;
|
|
4984
5603
|
//#endregion
|
|
4985
|
-
//#region src/
|
|
5604
|
+
//#region src/ui/tui/decks/self-driving/pipeline-diagram.tsx
|
|
4986
5605
|
/**
|
|
4987
5606
|
* PIPELINE_BLOCK — ASCII diagram of the Self-driving loop: sources feed
|
|
4988
5607
|
* scouts, scouts raise signals, signals group into reports, reports land
|
|
@@ -5070,7 +5689,7 @@ const PIPELINE_BLOCK = {
|
|
|
5070
5689
|
]
|
|
5071
5690
|
};
|
|
5072
5691
|
//#endregion
|
|
5073
|
-
//#region src/
|
|
5692
|
+
//#region src/ui/tui/decks/self-driving/index.tsx
|
|
5074
5693
|
/**
|
|
5075
5694
|
* Self-driving learn-deck — the narrative script played while the agent
|
|
5076
5695
|
* sets up Self-driving. Teaches the vocabulary ladder (signal source →
|
|
@@ -5296,7 +5915,7 @@ const getContentBlocks = (store) => {
|
|
|
5296
5915
|
];
|
|
5297
5916
|
};
|
|
5298
5917
|
//#endregion
|
|
5299
|
-
//#region src/
|
|
5918
|
+
//#region src/programs/self-driving/index.ts
|
|
5300
5919
|
const SELF_DRIVING_SKILL_ID = "self-driving-setup";
|
|
5301
5920
|
const REPORT_FILE = "posthog-self-driving-report.md";
|
|
5302
5921
|
const DOCS_URL = "https://posthog.com/docs";
|
|
@@ -5383,7 +6002,7 @@ const selfDrivingConfig = {
|
|
|
5383
6002
|
getContentBlocks
|
|
5384
6003
|
};
|
|
5385
6004
|
//#endregion
|
|
5386
|
-
//#region src/
|
|
6005
|
+
//#region src/programs/mcp/index.ts
|
|
5387
6006
|
const mcpAddConfig = {
|
|
5388
6007
|
id: "mcp-add",
|
|
5389
6008
|
requiresAi: false,
|
|
@@ -5464,7 +6083,7 @@ const mcpTutorialConfig = {
|
|
|
5464
6083
|
}]
|
|
5465
6084
|
};
|
|
5466
6085
|
//#endregion
|
|
5467
|
-
//#region src/
|
|
6086
|
+
//#region src/programs/mcp-analytics/index.ts
|
|
5468
6087
|
const MCP_ANALYTICS_REPORT_FILE = "posthog-mcp-analytics-report.md";
|
|
5469
6088
|
/**
|
|
5470
6089
|
* `[ABORT]` reasons the mcp-analytics skill emits when the project can't be
|
|
@@ -5518,7 +6137,7 @@ const mcpAnalyticsConfig = createSkillProgram({
|
|
|
5518
6137
|
abortCases: MCP_ANALYTICS_ABORT_CASES
|
|
5519
6138
|
});
|
|
5520
6139
|
//#endregion
|
|
5521
|
-
//#region src/
|
|
6140
|
+
//#region src/programs/ai-observability/index.ts
|
|
5522
6141
|
const AI_OBSERVABILITY_STEPS = AGENT_SKILL_STEPS.map((step) => step.id === "intro" ? {
|
|
5523
6142
|
...step,
|
|
5524
6143
|
screenId: "ai-observability-intro"
|
|
@@ -5577,7 +6196,7 @@ final report is written to ./${AI_OBSERVABILITY_REPORT_FILE}.`,
|
|
|
5577
6196
|
}
|
|
5578
6197
|
};
|
|
5579
6198
|
//#endregion
|
|
5580
|
-
//#region src/
|
|
6199
|
+
//#region src/programs/metrics/index.ts
|
|
5581
6200
|
const METRICS_STEPS = AGENT_SKILL_STEPS.map((step) => step.id === "intro" ? {
|
|
5582
6201
|
...step,
|
|
5583
6202
|
screenId: "metrics-intro"
|
|
@@ -5641,7 +6260,7 @@ is written to ./${METRICS_REPORT_FILE}.`,
|
|
|
5641
6260
|
}
|
|
5642
6261
|
};
|
|
5643
6262
|
//#endregion
|
|
5644
|
-
//#region src/
|
|
6263
|
+
//#region src/programs/slack/index.ts
|
|
5645
6264
|
const slackConnectConfig = {
|
|
5646
6265
|
id: "slack",
|
|
5647
6266
|
description: "Connect PostHog to your Slack",
|
|
@@ -5653,7 +6272,7 @@ const slackConnectConfig = {
|
|
|
5653
6272
|
}]
|
|
5654
6273
|
};
|
|
5655
6274
|
//#endregion
|
|
5656
|
-
//#region src/
|
|
6275
|
+
//#region src/programs/program-registry.ts
|
|
5657
6276
|
const agentSkillConfig = {
|
|
5658
6277
|
id: "agent-skill",
|
|
5659
6278
|
description: "Run an arbitrary context-mill skill",
|
|
@@ -5767,6 +6386,6 @@ function isRunFailure(session) {
|
|
|
5767
6386
|
return session.outroData?.kind === "error" && session.credentials !== null;
|
|
5768
6387
|
}
|
|
5769
6388
|
//#endregion
|
|
5770
|
-
export { wordWrap as $, installOrUpdatePostHogCli as A, webAnalyticsDoctorConfig as B, ERROR_TRACKING_PROJECT_PATH_KEY as C, CLI_STEERING_TARGETS as D, errorTrackingUploadSourceMapsConfig as E, MANUAL_SDK_INSTALL as F, createSkillProgram as G, getKindMeta as H, MANUAL_SDK_VARIANTS as I, getContentBlocks$4 as J, warehouseSourceConfig as K, RUST_SDK_CRATE as L, AUTOMATABLE_VARIANTS as M, DISPLAY_NAME as N, detectTargets as O, GO_SDK_MODULE as P, computeVisibleRange as Q, SOURCE_MAPS_CONTEXT_KEYS as R, errorTrackingConfig as S, replayVisionConfig as T, fetchHealthIssues as U, posthogDoctorConfig as V, auditConfig as W, posthogIntegrationConfig as X, SETUP_REPORT_FILE as Y, TextBlock as Z, PRICING_SHORT as _, PROGRAM_REGISTRY as a, GITHUB_REQUIRED_MESSAGE as b, getCommandPath as c, metricsConfig as d, isClearBlock as et, aiObservabilityConfig as f, PRICING_LONG as g, NO_DEFAULT_LIMIT as h, isRunFailure as i, Icons as it, installSteeringSnippet as j, findTarget as k, getLaunchablePrograms as l, selfDrivingConfig as m, MINT_FAILURE_CONTACT as n, isObjectBlock as nt, Program as o, mcpAnalyticsConfig as p, revenueAnalyticsConfig as q, MINT_FAILURE_MESSAGE as r, Colors as rt, agentSkillConfig as s, MINT_FAILURE_BODY as t, isLinesBlock as tt, getProgramConfig as u, detectSelfDrivingIntegrationProjects as v, detectErrorTrackingProjects as w, SELF_DRIVING_INTEGRATE_PATH_KEY as x, GITHUB_REQUIRED_BODY as y, migrationConfig as z };
|
|
6389
|
+
export { wordWrap as $, installOrUpdatePostHogCli as A, webAnalyticsDoctorConfig as B, ERROR_TRACKING_PROJECT_PATH_KEY as C, CLI_STEERING_TARGETS as D, errorTrackingUploadSourceMapsConfig as E, MANUAL_SDK_INSTALL as F, createSkillProgram as G, getKindMeta as H, MANUAL_SDK_VARIANTS as I, getContentBlocks$4 as J, warehouseSourceConfig as K, RUST_SDK_CRATE as L, AUTOMATABLE_VARIANTS as M, DISPLAY_NAME as N, detectTargets as O, GO_SDK_MODULE as P, computeVisibleRange as Q, SOURCE_MAPS_CONTEXT_KEYS as R, errorTrackingConfig as S, replayVisionConfig as T, fetchHealthIssues as U, posthogDoctorConfig as V, auditConfig as W, posthogIntegrationConfig as X, SETUP_REPORT_FILE as Y, TextBlock as Z, PRICING_SHORT as _, PROGRAM_REGISTRY as a, maybeStampAiSdkDetected as at, GITHUB_REQUIRED_MESSAGE as b, getCommandPath as c, STRIPE_SDKS as ct, metricsConfig as d, isClearBlock as et, aiObservabilityConfig as f, PRICING_LONG as g, NO_DEFAULT_LIMIT as h, isRunFailure as i, Icons as it, installSteeringSnippet as j, findTarget as k, getLaunchablePrograms as l, detectProjectsWithAgent as lt, selfDrivingConfig as m, MINT_FAILURE_CONTACT as n, isObjectBlock as nt, Program as o, reportWarehouseSourcesDetected as ot, mcpAnalyticsConfig as p, revenueAnalyticsConfig as q, MINT_FAILURE_MESSAGE as r, Colors as rt, agentSkillConfig as s, POSTHOG_SDKS as st, MINT_FAILURE_BODY as t, isLinesBlock as tt, getProgramConfig as u, detectSelfDrivingIntegrationProjects as v, detectErrorTrackingProjects as w, SELF_DRIVING_INTEGRATE_PATH_KEY as x, GITHUB_REQUIRED_BODY as y, migrationConfig as z };
|
|
5771
6390
|
|
|
5772
|
-
//# sourceMappingURL=mint-failure-
|
|
6391
|
+
//# sourceMappingURL=mint-failure-CZFZpHpW.js.map
|