@posthog/wizard 2.32.0 → 2.33.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-Dc0yssCM.js → add-mcp-server-to-clients-Dhq75Hda.js} +5 -5
- package/dist/{add-mcp-server-to-clients-Dc0yssCM.js.map → add-mcp-server-to-clients-Dhq75Hda.js.map} +1 -1
- package/dist/{agent-interface-c7B2JZEd.js → agent-interface-DCeQ5Oiw.js} +6 -6
- package/dist/{agent-interface-c7B2JZEd.js.map → agent-interface-DCeQ5Oiw.js.map} +1 -1
- package/dist/{agent-runner-Am34bBUT.js → agent-runner-BRajaO84.js} +10 -9
- package/dist/{agent-runner-Am34bBUT.js.map → agent-runner-BRajaO84.js.map} +1 -1
- package/dist/{analytics-CBIKy9PZ.js → analytics-CU4o3eF8.js} +3 -3
- package/dist/analytics-CU4o3eF8.js.map +1 -0
- package/dist/{api-Blg3nvvZ.js → api-BBRfHEZ-.js} +3 -3
- package/dist/{api-Blg3nvvZ.js.map → api-BBRfHEZ-.js.map} +1 -1
- package/dist/bin.js +203 -75
- package/dist/bin.js.map +1 -1
- package/dist/ci-install-D-otkGW6.js +113 -0
- package/dist/ci-install-D-otkGW6.js.map +1 -0
- package/dist/{debug-AdvgwKEw.js → debug-BGMe1wP6.js} +2 -2
- package/dist/{debug-AdvgwKEw.js.map → debug-BGMe1wP6.js.map} +1 -1
- package/dist/{debug-cy_jyRb4.js → debug-BewTLNNr.js} +1 -1
- package/dist/{defaults-BNWIWzjc.js → defaults-DII5CAog.js} +1 -1
- package/dist/{defaults-BNWIWzjc.js.map → defaults-DII5CAog.js.map} +1 -1
- package/dist/{environment-B6TW5v9d.js → environment-G41UFzou.js} +3 -3
- package/dist/{environment-B6TW5v9d.js.map → environment-G41UFzou.js.map} +1 -1
- package/dist/{file-utils-8tUk_eEX.js → file-utils-D9InAvZd.js} +2 -2
- package/dist/{file-utils-8tUk_eEX.js.map → file-utils-D9InAvZd.js.map} +1 -1
- package/dist/headless-ui-xjHVVUqe.js +24 -0
- package/dist/headless-ui-xjHVVUqe.js.map +1 -0
- package/dist/{interactive-CApktTrj.js → interactive-D2CKikzz.js} +3 -3
- package/dist/{interactive-CApktTrj.js.map → interactive-D2CKikzz.js.map} +1 -1
- package/dist/{mcp-prompt-streaming-BKcU9yuz.js → mcp-prompt-streaming-FrArGwfv.js} +4 -4
- package/dist/{mcp-prompt-streaming-BKcU9yuz.js.map → mcp-prompt-streaming-FrArGwfv.js.map} +1 -1
- package/dist/{non-interactive-DejTdRTW.js → non-interactive-BXx6Q-D0.js} +2 -2
- package/dist/{non-interactive-DejTdRTW.js.map → non-interactive-BXx6Q-D0.js.map} +1 -1
- package/dist/{package-manager-DBfgSXNn.js → package-manager-D9ojA4jO.js} +2 -2
- package/dist/{package-manager-DBfgSXNn.js.map → package-manager-D9ojA4jO.js.map} +1 -1
- package/dist/{playground-BOg2U1AT.js → playground-Bgtxrusl.js} +7 -5
- package/dist/{playground-BOg2U1AT.js.map → playground-Bgtxrusl.js.map} +1 -1
- package/dist/{posthog-Cr37rnla.js → posthog-DU6JXG00.js} +1 -1
- package/dist/{posthog-Cr37rnla.js.map → posthog-DU6JXG00.js.map} +1 -1
- package/dist/{posthog-integration-gLhOUdPJ.js → posthog-integration-gnC9v4kg.js} +13 -13
- package/dist/{posthog-integration-gLhOUdPJ.js.map → posthog-integration-gnC9v4kg.js.map} +1 -1
- package/dist/{provisioning-DuzclqPB.js → provisioning-C3qglLdc.js} +3 -3
- package/dist/{provisioning-DuzclqPB.js.map → provisioning-C3qglLdc.js.map} +1 -1
- package/dist/{registry-Dbl-5SnO.js → registry-BVrvFTZ0.js} +4 -4
- package/dist/{registry-Dbl-5SnO.js.map → registry-BVrvFTZ0.js.map} +1 -1
- package/dist/{setup-utils-B6wbp3s0.js → setup-utils-CanVlGbX.js} +8 -8
- package/dist/{setup-utils-B6wbp3s0.js.map → setup-utils-CanVlGbX.js.map} +1 -1
- package/dist/smoke-test.sh +25 -0
- package/dist/{start-tui-IoQh-Nhj.js → start-tui-YE7bybIr.js} +17 -16
- package/dist/{start-tui-IoQh-Nhj.js.map → start-tui-YE7bybIr.js.map} +1 -1
- package/dist/{steps-CJrqlHbo.js → steps-N20e4IoE.js} +7 -7
- package/dist/{steps-CJrqlHbo.js.map → steps-N20e4IoE.js.map} +1 -1
- package/dist/store-D15C9YSW.js +763 -0
- package/dist/store-D15C9YSW.js.map +1 -0
- package/dist/{task-stream-BQNSp0qR.js → task-stream-CPjpHFhI.js} +4 -4
- package/dist/{task-stream-BQNSp0qR.js.map → task-stream-CPjpHFhI.js.map} +1 -1
- package/dist/{telemetry-1m0CyTry.js → telemetry-DknCDWP6.js} +3 -3
- package/dist/{telemetry-1m0CyTry.js.map → telemetry-DknCDWP6.js.map} +1 -1
- package/dist/{terminal-BKI4i72f.js → terminal-Cvv0a-7Q.js} +14 -764
- package/dist/terminal-Cvv0a-7Q.js.map +1 -0
- package/dist/{urls-B3JumpLT.js → urls-DrR6F_A3.js} +2 -2
- package/dist/{urls-B3JumpLT.js.map → urls-DrR6F_A3.js.map} +1 -1
- package/dist/{wizard-abort-PqLMKSh1.js → wizard-abort-Cw818xPr.js} +4 -3
- package/dist/{wizard-abort-PqLMKSh1.js.map → wizard-abort-Cw818xPr.js.map} +1 -1
- package/dist/{wizard-abort-D7SzKUgE.js → wizard-abort-DMvS0YXD.js} +1 -1
- package/dist/wizard-session-BKEdX9mO.js +2 -0
- package/dist/{wizard-session-G3VWD6hv.js → wizard-session-CN55LYyZ.js} +9 -2
- package/dist/{wizard-session-G3VWD6hv.js.map → wizard-session-CN55LYyZ.js.map} +1 -1
- package/package.json +1 -1
- package/dist/analytics-CBIKy9PZ.js.map +0 -1
- package/dist/ci-install-51ntd9x5.js +0 -73
- package/dist/ci-install-51ntd9x5.js.map +0 -1
- package/dist/terminal-BKI4i72f.js.map +0 -1
- package/dist/wizard-session-wPJtNl4c.js +0 -2
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { h as LoggingUI, m as setUI, p as getUI } from "./debug-BGMe1wP6.js";
|
|
2
|
+
import { t as provisionNewAccount } from "./provisioning-C3qglLdc.js";
|
|
3
|
+
import { t as posthogIntegrationConfig } from "./posthog-integration-gnC9v4kg.js";
|
|
4
|
+
import { c as runWizardCI, s as runWizardHeadless } from "./bin.js";
|
|
5
|
+
//#region src/commands/basic-integration/ci-install.ts
|
|
6
|
+
/**
|
|
7
|
+
* CI-mode install entry point (`--ci`, dev/test builds). Thin shell over the
|
|
8
|
+
* shared non-interactive install — see `runNonInteractiveInstall`.
|
|
9
|
+
*/
|
|
10
|
+
function runCIInstall(argv) {
|
|
11
|
+
runNonInteractiveInstall(argv, "ci");
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Headless install entry point (the experimental published-build run path; see
|
|
15
|
+
* @lib/headless-mode). Thin shell over the shared non-interactive install.
|
|
16
|
+
* Today it behaves exactly like `runCIInstall`; it is a separate function so
|
|
17
|
+
* headless can diverge later (auth, prompts, …) without touching the CI path.
|
|
18
|
+
*/
|
|
19
|
+
function runHeadlessInstall(argv) {
|
|
20
|
+
runNonInteractiveInstall(argv, "headless");
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Non-interactive install shared by CI and headless. Validates signup flags,
|
|
24
|
+
* optionally provisions an account, then installs. `mode` only changes
|
|
25
|
+
* user-facing labels, which api-key prefixes are accepted, and which runner is
|
|
26
|
+
* invoked — the install itself is identical (see runNonInteractive).
|
|
27
|
+
*/
|
|
28
|
+
function runNonInteractiveInstall(argv, mode) {
|
|
29
|
+
const options = { ...argv };
|
|
30
|
+
const headless = mode === "headless";
|
|
31
|
+
const label = headless ? "Headless" : "CI";
|
|
32
|
+
const runWizard = headless ? runWizardHeadless : runWizardCI;
|
|
33
|
+
if (!options.apiKey && !options.signup) return failCI(`${label} mode requires --api-key (${headless ? "personal API key phx_xxx or pha_ OAuth access token" : "personal API key phx_xxx"}). To create a new account instead, use --signup --email you@example.com.`);
|
|
34
|
+
if (!options.apiKey && options.signup && !options.email) return failCI(`${label} --signup requires --email to create a new account.`);
|
|
35
|
+
warnOnUnexpectedKeyPrefix(options.apiKey, headless);
|
|
36
|
+
(async () => {
|
|
37
|
+
if (!options.apiKey && options.signup) {
|
|
38
|
+
if (!options.installDir) return failCI(`${label} mode requires --install-dir (directory to install in)`);
|
|
39
|
+
const provisioned = await provisionForSignup(options);
|
|
40
|
+
options.apiKey = provisioned.personalApiKey;
|
|
41
|
+
if (options.projectId == null) options.projectId = provisioned.projectId;
|
|
42
|
+
}
|
|
43
|
+
runWizard(posthogIntegrationConfig, options);
|
|
44
|
+
})().catch(() => {
|
|
45
|
+
process.exit(1);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function failCI(message) {
|
|
49
|
+
setUI(new LoggingUI());
|
|
50
|
+
getUI().intro("PostHog Wizard");
|
|
51
|
+
getUI().log.error(message);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Decide whether to warn about an unexpected `--api-key` prefix, and with what
|
|
56
|
+
* message. Returns `null` when the key is acceptable for the mode.
|
|
57
|
+
*
|
|
58
|
+
* This is the one behavioral fork between `--ci` and headless mode: the LLM
|
|
59
|
+
* Gateway accepts a personal API key (`phx_`) in either mode, but in headless
|
|
60
|
+
* a `pha_` OAuth access token is *also* first-class — PostHog mints one under
|
|
61
|
+
* the wizard's own OAuth application for cloud runs and passes it as the
|
|
62
|
+
* api-key. Outside headless that token is unexpected and still warns.
|
|
63
|
+
*
|
|
64
|
+
* Extracted as a pure predicate so the fork can be unit-tested without a UI.
|
|
65
|
+
*/
|
|
66
|
+
function keyPrefixWarning(apiKey, headless) {
|
|
67
|
+
if (!apiKey || apiKey.startsWith("phx_")) return null;
|
|
68
|
+
if (headless && apiKey.startsWith("pha_")) return null;
|
|
69
|
+
const prefix = apiKey.slice(0, 4);
|
|
70
|
+
return `--api-key does not start with "phx_"${prefix === "pha_" ? " (pha_ is an OAuth access token — CI mode expects a personal API key)" : prefix === "phc_" ? " (phc_ is a project/client key — expected a personal API key)" : ""}. Continuing anyway, but the LLM Gateway may reject it with a 401.`;
|
|
71
|
+
}
|
|
72
|
+
function warnOnUnexpectedKeyPrefix(apiKey, headless) {
|
|
73
|
+
const message = keyPrefixWarning(apiKey, headless);
|
|
74
|
+
if (!message) return;
|
|
75
|
+
setUI(new LoggingUI());
|
|
76
|
+
getUI().intro("PostHog Wizard");
|
|
77
|
+
getUI().log.warn(message);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Provision a new account and return its credentials. Throws on any failure
|
|
81
|
+
* (after logging a user-facing message); the caller's `.catch` turns that
|
|
82
|
+
* into a non-zero exit. The return type carries no failure sentinel.
|
|
83
|
+
*/
|
|
84
|
+
async function provisionForSignup(options) {
|
|
85
|
+
setUI(new LoggingUI());
|
|
86
|
+
getUI().intro("PostHog Wizard");
|
|
87
|
+
const signupRegion = (options.region || "us").toUpperCase();
|
|
88
|
+
getUI().log.info(`Provisioning new PostHog account for ${String(options.email)} in ${signupRegion}...`);
|
|
89
|
+
let result;
|
|
90
|
+
try {
|
|
91
|
+
result = await provisionNewAccount(options.email, options.name ?? "", signupRegion);
|
|
92
|
+
} catch (error) {
|
|
93
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
94
|
+
getUI().log.error(`Provisioning failed: ${msg}`);
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
if (!result.personalApiKey) {
|
|
98
|
+
getUI().log.error("Provisioning succeeded but no personal API key was returned — cannot continue install.");
|
|
99
|
+
throw new Error("provisioning returned no personal API key");
|
|
100
|
+
}
|
|
101
|
+
getUI().log.success("Account ready.");
|
|
102
|
+
getUI().log.info(` Project API Key: ${result.projectApiKey}`);
|
|
103
|
+
getUI().log.info(` Personal API Key: ${result.personalApiKey}`);
|
|
104
|
+
getUI().log.info(` Host: ${result.host}`);
|
|
105
|
+
return {
|
|
106
|
+
personalApiKey: result.personalApiKey,
|
|
107
|
+
projectId: result.projectId
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
//#endregion
|
|
111
|
+
export { runCIInstall, runHeadlessInstall };
|
|
112
|
+
|
|
113
|
+
//# sourceMappingURL=ci-install-D-otkGW6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ci-install-D-otkGW6.js","names":[],"sources":["../src/commands/basic-integration/ci-install.ts"],"sourcesContent":["import type { Arguments } from 'yargs';\nimport { getUI, setUI } from '@ui';\nimport { LoggingUI } from '@ui/logging-ui';\nimport { runWizardCI, runWizardHeadless } from '@lib/runners';\nimport type { NonInteractiveMode } from '@lib/runners';\nimport { provisionNewAccount } from '@utils/provisioning';\nimport { posthogIntegrationConfig } from '@lib/programs/posthog-integration/index';\n\ntype Options = Arguments & {\n region?: string;\n installDir?: string;\n apiKey?: string;\n signup?: boolean;\n email?: string;\n name?: string;\n projectId?: string;\n};\n\n/**\n * CI-mode install entry point (`--ci`, dev/test builds). Thin shell over the\n * shared non-interactive install — see `runNonInteractiveInstall`.\n */\nexport function runCIInstall(argv: Arguments): void {\n runNonInteractiveInstall(argv, 'ci');\n}\n\n/**\n * Headless install entry point (the experimental published-build run path; see\n * @lib/headless-mode). Thin shell over the shared non-interactive install.\n * Today it behaves exactly like `runCIInstall`; it is a separate function so\n * headless can diverge later (auth, prompts, …) without touching the CI path.\n */\nexport function runHeadlessInstall(argv: Arguments): void {\n runNonInteractiveInstall(argv, 'headless');\n}\n\n/**\n * Non-interactive install shared by CI and headless. Validates signup flags,\n * optionally provisions an account, then installs. `mode` only changes\n * user-facing labels, which api-key prefixes are accepted, and which runner is\n * invoked — the install itself is identical (see runNonInteractive).\n */\nfunction runNonInteractiveInstall(\n argv: Arguments,\n mode: NonInteractiveMode,\n): void {\n const options = { ...argv } as Options;\n const headless = mode === 'headless';\n const label = headless ? 'Headless' : 'CI';\n const runWizard = headless ? runWizardHeadless : runWizardCI;\n\n // Base validation (region/install-dir/api-key) is owned by the runner.\n // This layer only adds the signup branch on top.\n if (!options.apiKey && !options.signup) {\n const keyHint = headless\n ? 'personal API key phx_xxx or pha_ OAuth access token'\n : 'personal API key phx_xxx';\n return failCI(\n `${label} mode requires --api-key (${keyHint}). ` +\n 'To create a new account instead, use --signup --email you@example.com.',\n );\n }\n if (!options.apiKey && options.signup && !options.email) {\n return failCI(\n `${label} --signup requires --email to create a new account.`,\n );\n }\n warnOnUnexpectedKeyPrefix(options.apiKey, headless);\n\n void (async () => {\n if (!options.apiKey && options.signup) {\n // Fail before the irreversible provisioning step rather than after it.\n if (!options.installDir) {\n return failCI(\n `${label} mode requires --install-dir (directory to install in)`,\n );\n }\n const provisioned = await provisionForSignup(options);\n options.apiKey = provisioned.personalApiKey;\n if (options.projectId == null) options.projectId = provisioned.projectId;\n }\n runWizard(posthogIntegrationConfig, options);\n })().catch(() => {\n process.exit(1);\n });\n}\n\nfunction failCI(message: string): void {\n setUI(new LoggingUI());\n getUI().intro('PostHog Wizard');\n getUI().log.error(message);\n process.exit(1);\n}\n\n/**\n * Decide whether to warn about an unexpected `--api-key` prefix, and with what\n * message. Returns `null` when the key is acceptable for the mode.\n *\n * This is the one behavioral fork between `--ci` and headless mode: the LLM\n * Gateway accepts a personal API key (`phx_`) in either mode, but in headless\n * a `pha_` OAuth access token is *also* first-class — PostHog mints one under\n * the wizard's own OAuth application for cloud runs and passes it as the\n * api-key. Outside headless that token is unexpected and still warns.\n *\n * Extracted as a pure predicate so the fork can be unit-tested without a UI.\n */\nexport function keyPrefixWarning(\n apiKey: string | undefined,\n headless: boolean,\n): string | null {\n if (!apiKey || apiKey.startsWith('phx_')) return null;\n if (headless && apiKey.startsWith('pha_')) return null;\n const prefix = apiKey.slice(0, 4);\n const hint =\n prefix === 'pha_'\n ? ' (pha_ is an OAuth access token — CI mode expects a personal API key)'\n : prefix === 'phc_'\n ? ' (phc_ is a project/client key — expected a personal API key)'\n : '';\n return `--api-key does not start with \"phx_\"${hint}. Continuing anyway, but the LLM Gateway may reject it with a 401.`;\n}\n\nfunction warnOnUnexpectedKeyPrefix(\n apiKey: string | undefined,\n headless: boolean,\n): void {\n const message = keyPrefixWarning(apiKey, headless);\n if (!message) return;\n setUI(new LoggingUI());\n getUI().intro('PostHog Wizard');\n getUI().log.warn(message);\n}\n\n/**\n * Provision a new account and return its credentials. Throws on any failure\n * (after logging a user-facing message); the caller's `.catch` turns that\n * into a non-zero exit. The return type carries no failure sentinel.\n */\nasync function provisionForSignup(\n options: Options,\n): Promise<{ personalApiKey: string; projectId: string }> {\n setUI(new LoggingUI());\n getUI().intro('PostHog Wizard');\n const signupRegion = ((options.region as string) || 'us').toUpperCase() as\n | 'US'\n | 'EU';\n getUI().log.info(\n `Provisioning new PostHog account for ${String(\n options.email,\n )} in ${signupRegion}...`,\n );\n\n let result;\n try {\n result = await provisionNewAccount(\n options.email as string,\n options.name ?? '',\n signupRegion,\n );\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n getUI().log.error(`Provisioning failed: ${msg}`);\n throw error;\n }\n\n if (!result.personalApiKey) {\n getUI().log.error(\n 'Provisioning succeeded but no personal API key was returned — cannot continue install.',\n );\n throw new Error('provisioning returned no personal API key');\n }\n\n getUI().log.success('Account ready.');\n getUI().log.info(` Project API Key: ${result.projectApiKey}`);\n getUI().log.info(` Personal API Key: ${result.personalApiKey}`);\n getUI().log.info(` Host: ${result.host}`);\n return {\n personalApiKey: result.personalApiKey,\n projectId: result.projectId,\n };\n}\n"],"mappings":";;;;;;;;;AAsBA,SAAgB,aAAa,MAAuB;AAClD,0BAAyB,MAAM,KAAK;;;;;;;;AAStC,SAAgB,mBAAmB,MAAuB;AACxD,0BAAyB,MAAM,WAAW;;;;;;;;AAS5C,SAAS,yBACP,MACA,MACM;CACN,MAAM,UAAU,EAAE,GAAG,MAAM;CAC3B,MAAM,WAAW,SAAS;CAC1B,MAAM,QAAQ,WAAW,aAAa;CACtC,MAAM,YAAY,WAAW,oBAAoB;AAIjD,KAAI,CAAC,QAAQ,UAAU,CAAC,QAAQ,OAI9B,QAAO,OACL,GAAG,MAAM,4BAJK,WACZ,wDACA,2BAE2C,2EAE9C;AAEH,KAAI,CAAC,QAAQ,UAAU,QAAQ,UAAU,CAAC,QAAQ,MAChD,QAAO,OACL,GAAG,MAAM,qDACV;AAEH,2BAA0B,QAAQ,QAAQ,SAAS;AAEnD,EAAM,YAAY;AAChB,MAAI,CAAC,QAAQ,UAAU,QAAQ,QAAQ;AAErC,OAAI,CAAC,QAAQ,WACX,QAAO,OACL,GAAG,MAAM,wDACV;GAEH,MAAM,cAAc,MAAM,mBAAmB,QAAQ;AACrD,WAAQ,SAAS,YAAY;AAC7B,OAAI,QAAQ,aAAa,KAAM,SAAQ,YAAY,YAAY;;AAEjE,YAAU,0BAA0B,QAAQ;KAC1C,CAAC,YAAY;AACf,UAAQ,KAAK,EAAE;GACf;;AAGJ,SAAS,OAAO,SAAuB;AACrC,OAAM,IAAI,WAAW,CAAC;AACtB,QAAO,CAAC,MAAM,iBAAiB;AAC/B,QAAO,CAAC,IAAI,MAAM,QAAQ;AAC1B,SAAQ,KAAK,EAAE;;;;;;;;;;;;;;AAejB,SAAgB,iBACd,QACA,UACe;AACf,KAAI,CAAC,UAAU,OAAO,WAAW,OAAO,CAAE,QAAO;AACjD,KAAI,YAAY,OAAO,WAAW,OAAO,CAAE,QAAO;CAClD,MAAM,SAAS,OAAO,MAAM,GAAG,EAAE;AAOjC,QAAO,uCALL,WAAW,SACP,0EACA,WAAW,SACX,kEACA,GAC6C;;AAGrD,SAAS,0BACP,QACA,UACM;CACN,MAAM,UAAU,iBAAiB,QAAQ,SAAS;AAClD,KAAI,CAAC,QAAS;AACd,OAAM,IAAI,WAAW,CAAC;AACtB,QAAO,CAAC,MAAM,iBAAiB;AAC/B,QAAO,CAAC,IAAI,KAAK,QAAQ;;;;;;;AAQ3B,eAAe,mBACb,SACwD;AACxD,OAAM,IAAI,WAAW,CAAC;AACtB,QAAO,CAAC,MAAM,iBAAiB;CAC/B,MAAM,gBAAiB,QAAQ,UAAqB,MAAM,aAAa;AAGvE,QAAO,CAAC,IAAI,KACV,wCAAwC,OACtC,QAAQ,MACT,CAAC,MAAM,aAAa,KACtB;CAED,IAAI;AACJ,KAAI;AACF,WAAS,MAAM,oBACb,QAAQ,OACR,QAAQ,QAAQ,IAChB,aACD;UACM,OAAO;EACd,MAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAClE,SAAO,CAAC,IAAI,MAAM,wBAAwB,MAAM;AAChD,QAAM;;AAGR,KAAI,CAAC,OAAO,gBAAgB;AAC1B,SAAO,CAAC,IAAI,MACV,yFACD;AACD,QAAM,IAAI,MAAM,4CAA4C;;AAG9D,QAAO,CAAC,IAAI,QAAQ,iBAAiB;AACrC,QAAO,CAAC,IAAI,KAAK,uBAAuB,OAAO,gBAAgB;AAC/D,QAAO,CAAC,IAAI,KAAK,uBAAuB,OAAO,iBAAiB;AAChE,QAAO,CAAC,IAAI,KAAK,uBAAuB,OAAO,OAAO;AACtD,QAAO;EACL,gBAAgB,OAAO;EACvB,WAAW,OAAO;EACnB"}
|
|
@@ -28,7 +28,7 @@ function runtimeEnv(key) {
|
|
|
28
28
|
}
|
|
29
29
|
//#endregion
|
|
30
30
|
//#region src/lib/version.ts
|
|
31
|
-
const VERSION = "2.
|
|
31
|
+
const VERSION = "2.33.0";
|
|
32
32
|
//#endregion
|
|
33
33
|
//#region src/lib/constants.ts
|
|
34
34
|
/**
|
|
@@ -891,4 +891,4 @@ function enableDebugLogs() {
|
|
|
891
891
|
//#endregion
|
|
892
892
|
export { WIZARD_WARLOCK_DISABLED_FLAG_KEY as $, ISSUES_URL as A, POSTHOG_PRIVACY_URL as B, CONTEXT_MILL_RELEASES_URL as C, DETECTION_TIMEOUT_MS as D, DEFAULT_HOST_URL as E, POSTHOG_DEV_CLIENT_ID as F, REMOTE_SKILLS_BASE_URL as G, POSTHOG_PROXY_CLIENT_ID as H, POSTHOG_DOCS_URL as I, WIZARD_ORCHESTRATOR_FLAG_KEY as J, WIZARD_INTERACTION_EVENT_NAME as K, POSTHOG_FLAG_HEADER_PREFIX as L, OAUTH_PORTS as M, OAUTH_TIMEOUT_MS as N, DUMMY_PROJECT_API_KEY as O, POSTHOG_APP_URL as P, WIZARD_USER_AGENT as Q, POSTHOG_OAUTH_URL as R, ANALYTICS_TEAM_TAG as S, DEFAULT_AGENT_MODEL as T, POSTHOG_TERMS_URL as U, POSTHOG_PROPERTY_HEADER_PREFIX as V, POSTHOG_US_CLIENT_ID as W, WIZARD_REMARK_EVENT_NAME as X, WIZARD_PROVISIONING_SCOPES as Y, WIZARD_TOOLS_MENU_FLAG_KEY as Z, SIGNUP_WIZARD_READINESS_CONFIG as _, getLogFilePath as a, ANALYTICS_HOST_URL as b, WIZARD_BENCHMARK_FILE as c, relativeToInstallDir as d, getSkillsBaseUrl as et, skillTmpPath as f, SERVICE_LABELS as g, LoggingUI as h, enableDebugLogs as i, Integration as j, HAIKU_MODEL as k, WIZARD_LOG_FILE as l, setUI as m, configureLogFileFromEnvironment as n, NODE_ENV as nt, initLogFile as o, getUI as p, WIZARD_OAUTH_SCOPES as q, debug as r, runtimeEnv as rt, logToFile as s, configureLogFile as t, VERSION as tt, WIZARD_YARA_REPORT_FILE as u, evaluateWizardReadiness as v, CONTEXT_MILL_URL as w, ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY as x, getBlockingServiceKeys as y, POSTHOG_ORG_AI_SETTINGS_URL as z };
|
|
893
893
|
|
|
894
|
-
//# sourceMappingURL=debug-
|
|
894
|
+
//# sourceMappingURL=debug-BGMe1wP6.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debug-AdvgwKEw.js","names":["errResult","join"],"sources":["../src/env.ts","../src/lib/version.ts","../src/lib/constants.ts","../src/lib/health-checks/statuspage.ts","../src/lib/health-checks/incidentio.ts","../src/lib/health-checks/endpoints.ts","../src/lib/health-checks/readiness.ts","../src/ui/logging-ui.ts","../src/ui/index.ts","../src/utils/paths.ts","../src/utils/debug.ts"],"sourcesContent":["/**\n * Central environment variable access for the PostHog wizard.\n *\n * ── Build-time constants ────────────────────────────────────────────\n * Inlined by tsdown's `env` option at compile time. After build, the\n * runtime value of these env vars has zero effect on the wizard.\n *\n * ── Runtime variables ───────────────────────────────────────────────\n * Read through `runtimeEnv()` with a typed allowlist. This makes every\n * runtime dependency on the environment explicit and grep-able.\n *\n * ── Direct process.env access ───────────────────────────────────────\n * Reserved for subprocess environment configuration (writes) and\n * vendored code. Production source outside those cases should use\n * this module instead.\n */\n\n// ── Build-time constants ─────────────────────────────────────────────\n// tsdown replaces `process.env.NODE_ENV` with a string literal.\n// After build these are just `\"production\"`, `false`, etc.\n\nexport const NODE_ENV = process.env.NODE_ENV as string;\nexport const IS_DEV =\n process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test';\n\n/**\n * True only in published/production builds. tsdown inlines\n * `process.env.NODE_ENV` as the literal `\"production\"` at build time, so this\n * collapses to `true` in `dist/` and stays `false` for `tsx`/dev/test runs\n * (where NODE_ENV is unset, `development`, or `test`). Used to gate features\n * that aren't supported in the shipped package — e.g. `--ci` mode.\n */\nexport const IS_PRODUCTION_BUILD = process.env.NODE_ENV === 'production';\n\n// ── Runtime environment ──────────────────────────────────────────────\n\n/**\n * Exhaustive allowlist of env vars the wizard reads at runtime.\n * Add new keys here when a new runtime dependency is needed.\n */\ntype RuntimeEnvKey =\n // CI-build-only flag overrides (see utils/ci-flag-overrides.ts).\n // Deliberately NOT POSTHOG_WIZARD_-prefixed: yargs .env('POSTHOG_WIZARD')\n // would claim it as an unknown CLI option and strict-reject the run.\n | 'WIZARD_CI_FLAG_OVERRIDES'\n | 'WIZARD_CI_EXCLUDE_TASKS'\n // Wizard CLI configuration (yargs POSTHOG_WIZARD_ prefix)\n | 'POSTHOG_WIZARD_BENCHMARK_CONFIG'\n | 'POSTHOG_WIZARD_BENCHMARK_FILE'\n | 'POSTHOG_WIZARD_LOG_DIR'\n | 'POSTHOG_WIZARD_DEBUG'\n // Local/CI escape hatch to disable Warlock scanning without the PostHog flag.\n | 'POSTHOG_WIZARD_WARLOCK_DISABLED'\n | 'DEBUG'\n // Agent / MCP\n | 'MCP_URL'\n | 'POSTHOG_API_KEY'\n // Platform: terminal detection\n | 'TERM'\n | 'TERM_PROGRAM'\n | 'TERMINAL_EMULATOR'\n | 'CI'\n | 'WT_SESSION'\n | 'TERMINUS_SUBLIME'\n | 'ConEmuTask'\n // Platform: paths\n | 'APPDATA'\n | 'XDG_CONFIG_HOME';\n\n/** Read a runtime environment variable. Only allowlisted keys compile. */\nexport function runtimeEnv(key: RuntimeEnvKey): string | undefined {\n return process.env[key];\n}\n","// Auto-generated by scripts/generate-version.js — do not edit\nexport const VERSION = '2.32.0';\n","/**\n * Shared constants for the PostHog wizard.\n */\n\nimport { VERSION } from './version';\n\n// ── Models ──────────────────────────────────────────────────────────\n\n/**\n * Default model for agent runs. Bare model IDs (no `anthropic/` prefix) so the\n * LLM gateway's Bedrock fallback can match map_to_bedrock_model().\n */\nexport const DEFAULT_AGENT_MODEL = 'claude-sonnet-4-6';\n\n/**\n * Cheaper, faster model for mechanical agent work (e.g. repo classification\n * during source-map detection). Passed via AgentConfig.modelOverride.\n */\nexport const HAIKU_MODEL = 'claude-haiku-4-5-20251001';\n\n// ── Integration / CLI ───────────────────────────────────────────────\n\n/**\n * Detection order matters: put framework-specific integrations BEFORE basic language fallbacks.\n */\nexport enum Integration {\n // Frameworks\n nextjs = 'nextjs',\n nuxt = 'nuxt',\n vue = 'vue',\n reactRouter = 'react-router',\n tanstackStart = 'tanstack-start',\n tanstackRouter = 'tanstack-router',\n reactNative = 'react-native',\n angular = 'angular',\n astro = 'astro',\n django = 'django',\n flask = 'flask',\n fastapi = 'fastapi',\n laravel = 'laravel',\n sveltekit = 'sveltekit',\n swift = 'swift',\n android = 'android',\n rails = 'rails',\n\n // Language fallbacks\n python = 'python',\n ruby = 'ruby',\n javascriptNode = 'javascript_node',\n javascript_web = 'javascript_web',\n}\n\nexport interface Args {\n debug: boolean;\n integration: Integration;\n}\n\n// ── Environment ──────────────────────────────────────────────────────\n\nimport { IS_DEV } from '@env';\nexport { IS_DEV };\nexport const DEBUG = false;\n\n// ── URLs ─────────────────────────────────────────────────────────────\n\nexport const DEFAULT_URL = IS_DEV\n ? 'http://localhost:8010'\n : 'https://us.posthog.com';\n/**\n * Region-agnostic PostHog app URL. Resolves to us.posthog.com or\n * eu.posthog.com server-side based on the signed-in user's profile.\n * Use this for share-with-user links (e.g. settings pages) so they\n * land on the right region without us needing to know it client-side.\n */\nexport const POSTHOG_APP_URL = IS_DEV\n ? 'http://localhost:8010'\n : 'https://app.posthog.com';\nexport const DEFAULT_HOST_URL = IS_DEV\n ? 'http://localhost:8010'\n : 'https://us.i.posthog.com';\nexport const ISSUES_URL = 'https://github.com/posthog/wizard/issues';\nexport const CONTEXT_MILL_URL = 'https://github.com/PostHog/context-mill';\n/**\n * Latest context-mill release page — the BYOAI download link shown in\n * the privacy panel. Deliberately the release PAGE, not a direct asset\n * URL: asset URLs are ~89 chars and hard-wrap inside the 64-col panel,\n * which corrupts terminal copy/paste with a mid-URL line break. This\n * stays under one line; the panel names the exact asset to grab.\n */\nexport const CONTEXT_MILL_RELEASES_URL =\n 'https://github.com/PostHog/context-mill/releases/latest';\nexport const POSTHOG_DOCS_URL = 'https://posthog.com/docs';\nexport const POSTHOG_WIZARD_REPO_URL = 'https://github.com/PostHog/wizard';\nexport const POSTHOG_TERMS_URL = 'https://posthog.com/terms';\nexport const POSTHOG_PRIVACY_URL = 'https://posthog.com/privacy';\nexport const POSTHOG_ORG_AI_SETTINGS_URL =\n 'https://app.posthog.com/settings/organization-details#setting=organization-ai-consent';\nexport const WIZARD_CONTACT_EMAIL = 'wizard@posthog.com';\n\n/** Remote base URL for fetching the skill menu + downloading skills. */\nexport const REMOTE_SKILLS_BASE_URL =\n 'https://github.com/PostHog/context-mill/releases/latest/download';\n/** Local base URL when `--local-mcp` is set (served by context-mill dev server). */\nexport const LOCAL_SKILLS_BASE_URL = 'http://localhost:8765';\n\n/**\n * Pick the skills base URL based on the session's localMcp flag.\n * Single source of truth — do not inline this ternary anywhere.\n */\nexport function getSkillsBaseUrl(localMcp: boolean): string {\n return localMcp ? LOCAL_SKILLS_BASE_URL : REMOTE_SKILLS_BASE_URL;\n}\n\n// ── Analytics (internal) ──────────────────────────────────────────────\n\nexport const ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY = 'sTMFPsFhdP1Ssg';\nexport const ANALYTICS_HOST_URL = 'https://internal-j.posthog.com';\nexport const ANALYTICS_TEAM_TAG = 'docs-and-wizard';\n\n// ── OAuth / Auth ────────────────────────────────────────────────────\n\nexport const POSTHOG_OAUTH_URL = IS_DEV\n ? 'http://localhost:8010'\n : 'https://oauth.posthog.com';\nexport const OAUTH_PORTS = [8239, 8238, 8240, 8237, 8236, 8235] as const;\nexport const POSTHOG_US_CLIENT_ID = 'c4Rdw8DIxgtQfA80IiSnGKlNX8QN00cFWF00QQhM';\nexport const POSTHOG_EU_CLIENT_ID = 'bx2C5sZRN03TkdjraCcetvQFPGH6N2Y9vRLkcKEy';\nexport const POSTHOG_DEV_CLIENT_ID = 'DC5uRLVbGI02YQ82grxgnK6Qn12SXWpCqdPb60oZ';\nexport const POSTHOG_PROXY_CLIENT_ID = POSTHOG_US_CLIENT_ID;\nexport const DUMMY_PROJECT_API_KEY = '_YOUR_POSTHOG_PROJECT_TOKEN_';\n\n/**\n * Scopes the wizard requests during the agentic provisioning signup flow.\n *\n * Each entry is justified by what the wizard's agent step does after signup:\n * - user:read identify the user for analytics + agent context\n * - project:read look up the freshly-provisioned project\n * - llm_gateway:read authenticate to gateway.{us,eu}.posthog.com/wizard\n * (the agent's LLM calls — without this scope, every\n * agent message returns 401)\n * - query:read run HogQL queries when the agent needs data\n * - dashboard:write create the onboarding dashboard during setup\n * - insight:write create the onboarding insights during setup\n * - notebook:write upload the events-audit report as a PostHog notebook\n * in step 6 of the events-audit skill (notebooks-create\n * MCP tool requires this scope)\n *\n * Must be a subset of `ALLOWED_PROVISIONING_SCOPES` in\n * `ee/api/agentic_provisioning/views.py` on the backend.\n */\nexport const WIZARD_PROVISIONING_SCOPES = [\n 'user:read',\n 'project:read',\n 'llm_gateway:read',\n 'dashboard:write',\n 'insight:write',\n 'query:read',\n 'notebook:write',\n] as const;\n\n/**\n * Scopes the wizard requests during the OAuth login flow. Superset of\n * `WIZARD_PROVISIONING_SCOPES` with scopes that only apply to the login\n * path and are not in the provisioning allowlist:\n * - health_issue:read used by `wizard doctor`\n * - wizard_session:read list / retrieve / stream sessions\n * - wizard_session:write stream run state to /api/projects/{id}/wizard/sessions/\n * - organization:read read `organization.is_ai_data_processing_approved`\n * from /api/users/@me/ for the AI opt-in gate\n *\n * NOTE: every scope here must be within the wizard OAuth application's\n * server-side scope ceiling (`OAuthApplication.scopes` in posthog, set\n * via Django admin on BOTH prod regions) — requesting anything outside\n * it fails the WHOLE authorize request with `error=invalid_scope`\n * before the consent screen renders. Procedure: the\n * \"scope-ceiling-invalid-scope\" runbook in PostHog/runbooks. Keep the\n * runbook's worked example in sync when this list changes.\n */\nexport const WIZARD_OAUTH_SCOPES = [\n ...WIZARD_PROVISIONING_SCOPES,\n 'health_issue:read',\n 'wizard_session:read',\n 'wizard_session:write',\n 'organization:read',\n] as const;\n\n// ── Wizard run / variants ───────────────────────────────────────────\n\nexport const WIZARD_INTERACTION_EVENT_NAME = 'wizard interaction';\nexport const WIZARD_REMARK_EVENT_NAME = 'wizard remark';\n/** Boolean feature flag that routes a run to the experimental orchestrator runner. */\nexport const WIZARD_ORCHESTRATOR_FLAG_KEY = 'wizard-orchestrator';\n/** Feature flag key that gates the intro-screen \"Tools\" menu. */\nexport const WIZARD_TOOLS_MENU_FLAG_KEY = 'wizard-tools-menu';\n/**\n * Kill switch: when this flag resolves to 'true', Warlock/YARA scanning is\n * disabled for the run. Defaults off (scanning on) — a missing flag or a failed\n * flag fetch must never silently disable a security control.\n */\nexport const WIZARD_WARLOCK_DISABLED_FLAG_KEY = 'wizard-warlock-disabled';\n/** User-Agent for wizard HTTP requests and MCP server identification. */\nexport const WIZARD_USER_AGENT = `posthog/wizard; version: ${VERSION}`;\n\n// ── HTTP headers ─────────────────────────────────────────────────────\n\n/** Header prefix for PostHog properties (e.g. X-POSTHOG-PROPERTY-VARIANT). */\nexport const POSTHOG_PROPERTY_HEADER_PREFIX = 'X-POSTHOG-PROPERTY-';\n/** Header prefix for PostHog feature flags. */\nexport const POSTHOG_FLAG_HEADER_PREFIX = 'X-POSTHOG-FLAG-';\n\n// ── Timeouts ─────────────────────────────────────────────────────────\n\n/** Timeout for framework / project detection probes (ms). */\nexport const DETECTION_TIMEOUT_MS = 10_000;\n\n/**\n * Timeout for the OAuth authorization flow (ms).\n *\n * Mirrors the server-side authorization-code expiry\n * (`AUTHORIZATION_CODE_EXPIRE_SECONDS`, 5 minutes). Once the code expires the\n * callback is dead and the token exchange can no longer succeed, so we stop\n * waiting at the same moment and prompt the user to re-run rather than letting\n * them complete a login that would fail.\n */\nexport const OAUTH_TIMEOUT_MS = 300_000;\n","import {\n ServiceHealthStatus,\n type BaseHealthResult,\n type ComponentHealthResult,\n} from './types';\n\n// ---------------------------------------------------------------------------\n// Statuspage.io v2 API helpers\n// https://metastatuspage.com/api\n//\n// status.json – page-level rollup; indicator is one of: none | minor | major | critical\n// summary.json – same rollup + component list; component status is one of:\n// operational | degraded_performance | partial_outage | major_outage | under_maintenance\n// https://support.atlassian.com/statuspage/docs/show-service-status-with-components\n// ---------------------------------------------------------------------------\n\ninterface StatuspageStatusResponse {\n status?: { indicator?: string; description?: string };\n}\n\ninterface StatuspageSummaryResponse extends StatuspageStatusResponse {\n components?: { id: string; name: string; status: string }[];\n}\n\nfunction mapIndicator(v: string | null | undefined): ServiceHealthStatus {\n switch (v) {\n case 'none':\n return ServiceHealthStatus.Healthy;\n case 'minor':\n return ServiceHealthStatus.Degraded;\n case 'major':\n case 'critical':\n return ServiceHealthStatus.Down;\n default:\n return ServiceHealthStatus.Degraded;\n }\n}\n\nfunction mapComponentRaw(v: string | null | undefined): ServiceHealthStatus {\n switch (v) {\n case 'operational':\n return ServiceHealthStatus.Healthy;\n case 'degraded_performance':\n case 'under_maintenance':\n return ServiceHealthStatus.Degraded;\n case 'partial_outage':\n case 'major_outage':\n return ServiceHealthStatus.Down;\n default:\n return ServiceHealthStatus.Degraded;\n }\n}\n\nfunction errResult(error: string): BaseHealthResult {\n return { status: ServiceHealthStatus.Degraded, error };\n}\n\nasync function fetchStatuspageIndicator(\n url: string,\n timeoutMs = 5000,\n): Promise<BaseHealthResult> {\n try {\n const controller = new AbortController();\n const tid = setTimeout(() => controller.abort(), timeoutMs);\n const res = await fetch(url, { signal: controller.signal });\n clearTimeout(tid);\n\n if (!res.ok) return errResult(`HTTP ${res.status}`);\n\n const data = (await res.json()) as StatuspageStatusResponse;\n const indicator = data.status?.indicator ?? null;\n return {\n status: mapIndicator(indicator),\n rawIndicator: indicator ?? undefined,\n };\n } catch (e) {\n if (e instanceof Error && e.name === 'AbortError')\n return errResult('Request timed out');\n return errResult(e instanceof Error ? e.message : 'Unknown error');\n }\n}\n\nasync function fetchStatuspageSummary(\n url: string,\n timeoutMs = 5000,\n): Promise<ComponentHealthResult> {\n try {\n const controller = new AbortController();\n const tid = setTimeout(() => controller.abort(), timeoutMs);\n const res = await fetch(url, { signal: controller.signal });\n clearTimeout(tid);\n\n if (!res.ok) return errResult(`HTTP ${res.status}`);\n\n const data = (await res.json()) as StatuspageSummaryResponse;\n const indicator = data.status?.indicator ?? null;\n const overall = mapIndicator(indicator);\n\n const affected = (data.components ?? [])\n .map((c) => ({\n name: c.name,\n status: mapComponentRaw(c.status),\n rawStatus: c.status,\n }))\n .filter((c) => c.status !== ServiceHealthStatus.Healthy);\n\n return {\n status: affected.length > 0 ? ServiceHealthStatus.Degraded : overall,\n rawIndicator: indicator ?? undefined,\n degradedOrDownComponents: affected.length > 0 ? affected : undefined,\n };\n } catch (e) {\n if (e instanceof Error && e.name === 'AbortError')\n return errResult('Request timed out');\n return errResult(e instanceof Error ? e.message : 'Unknown error');\n }\n}\n\n// ---------------------------------------------------------------------------\n// Individual statuspage-backed checks\n// ---------------------------------------------------------------------------\n\nexport const checkAnthropicHealth = (): Promise<BaseHealthResult> =>\n fetchStatuspageIndicator('https://status.claude.com/api/v2/status.json');\n\nexport const checkGithubHealth = (): Promise<BaseHealthResult> =>\n fetchStatuspageIndicator('https://www.githubstatus.com/api/v2/status.json');\n\nexport const checkNpmOverallHealth = (): Promise<BaseHealthResult> =>\n fetchStatuspageIndicator('https://status.npmjs.org/api/v2/status.json');\n\nexport const checkNpmComponentHealth = (): Promise<ComponentHealthResult> =>\n fetchStatuspageSummary('https://status.npmjs.org/api/v2/summary.json');\n\nexport const checkCloudflareOverallHealth = (): Promise<BaseHealthResult> =>\n fetchStatuspageIndicator(\n 'https://www.cloudflarestatus.com/api/v2/status.json',\n );\n\nexport const checkCloudflareComponentHealth =\n (): Promise<ComponentHealthResult> =>\n fetchStatuspageSummary(\n 'https://www.cloudflarestatus.com/api/v2/summary.json',\n );\n","import {\n ServiceHealthStatus,\n type BaseHealthResult,\n type ComponentHealthResult,\n type ComponentStatus,\n} from './types';\n\ninterface IncidentIoAffectedComponent {\n id: string;\n name: string;\n group_name?: string;\n current_status: string;\n}\n\ninterface IncidentIoIncident {\n id: string;\n name: string;\n status: string;\n current_worst_impact: string;\n affected_components: IncidentIoAffectedComponent[];\n}\n\ninterface IncidentIoSummary {\n ongoing_incidents: IncidentIoIncident[];\n in_progress_maintenances: unknown[];\n}\n\nfunction mapIncidentImpact(impact: string): ServiceHealthStatus {\n switch (impact) {\n case 'full_outage':\n return ServiceHealthStatus.Down;\n case 'partial_outage':\n case 'degraded_performance':\n return ServiceHealthStatus.Degraded;\n default:\n return ServiceHealthStatus.Degraded;\n }\n}\n\nfunction mapComponentStatus(status: string): ServiceHealthStatus {\n switch (status) {\n case 'operational':\n return ServiceHealthStatus.Healthy;\n case 'full_outage':\n return ServiceHealthStatus.Down;\n case 'partial_outage':\n case 'degraded_performance':\n return ServiceHealthStatus.Degraded;\n default:\n return ServiceHealthStatus.Degraded;\n }\n}\n\n/**\n * Build an error result for fetch failures. The kind matters for\n * downstream reconciliation:\n *\n * - 'http' (incident.io returned a bad status code) → `Down`. We\n * reached the status page but it told us something is wrong on\n * its side. We have a definitive response.\n * - 'network' (timeout, DNS failure, TCP/TLS failure) → `NoConnection`.\n * We never reached the status page. Treating this as `Degraded`\n * (the previous behavior) silently flipped the reconciliation in\n * `readiness.ts` from \"soft\" to \"confirmed outage\" whenever the\n * user's own network was flaky — exactly the false positive this\n * module is meant to help diagnose.\n */\nfunction errResult(error: string, kind: 'http' | 'network'): BaseHealthResult {\n return {\n status:\n kind === 'http'\n ? ServiceHealthStatus.Down\n : ServiceHealthStatus.NoConnection,\n error,\n };\n}\n\nconst POSTHOG_STATUS_URL = 'https://www.posthogstatus.com/api/v1/summary';\n\nasync function fetchPosthogStatus(\n timeoutMs = 5000,\n): Promise<{ overall: BaseHealthResult; components: ComponentHealthResult }> {\n try {\n const controller = new AbortController();\n const tid = setTimeout(() => controller.abort(), timeoutMs);\n const res = await fetch(POSTHOG_STATUS_URL, { signal: controller.signal });\n clearTimeout(tid);\n\n if (!res.ok) {\n const err = errResult(`HTTP ${res.status}`, 'http');\n return { overall: err, components: err };\n }\n\n const data = (await res.json()) as IncidentIoSummary;\n const incidents = data.ongoing_incidents ?? [];\n\n if (incidents.length === 0) {\n return {\n overall: { status: ServiceHealthStatus.Healthy },\n components: { status: ServiceHealthStatus.Healthy },\n };\n }\n\n let worstOverall = ServiceHealthStatus.Degraded;\n const affected: ComponentStatus[] = [];\n\n for (const incident of incidents) {\n const impact = mapIncidentImpact(incident.current_worst_impact);\n if (impact === ServiceHealthStatus.Down) {\n worstOverall = ServiceHealthStatus.Down;\n }\n\n for (const comp of incident.affected_components ?? []) {\n const compStatus = mapComponentStatus(comp.current_status);\n if (compStatus !== ServiceHealthStatus.Healthy) {\n affected.push({\n name: comp.group_name\n ? `${comp.group_name} — ${comp.name}`\n : comp.name,\n status: compStatus,\n rawStatus: comp.current_status,\n });\n }\n }\n }\n\n return {\n overall: { status: worstOverall },\n components: {\n status:\n affected.length > 0 ? ServiceHealthStatus.Degraded : worstOverall,\n degradedOrDownComponents: affected.length > 0 ? affected : undefined,\n },\n };\n } catch (e) {\n if (e instanceof Error && e.name === 'AbortError') {\n const err = errResult('Request timed out', 'network');\n return { overall: err, components: err };\n }\n const err = errResult(\n e instanceof Error ? e.message : 'Unknown error',\n 'network',\n );\n return { overall: err, components: err };\n }\n}\n\nlet _cache: Promise<{\n overall: BaseHealthResult;\n components: ComponentHealthResult;\n}> | null = null;\n\nfunction getPosthogHealth() {\n if (!_cache) _cache = fetchPosthogStatus();\n return _cache;\n}\n\nexport function resetPosthogHealthCache(): void {\n _cache = null;\n}\n\nexport const checkPosthogOverallHealth = async (): Promise<BaseHealthResult> =>\n (await getPosthogHealth()).overall;\n\nexport const checkPosthogComponentHealth =\n async (): Promise<ComponentHealthResult> =>\n (await getPosthogHealth()).components;\n","import { REMOTE_SKILLS_BASE_URL } from '@lib/constants';\nimport { logToFile } from '@utils/debug';\nimport { ServiceHealthStatus, type BaseHealthResult } from './types';\n\n// ---------------------------------------------------------------------------\n// Direct endpoint health checks\n//\n// These ping PostHog-owned services directly (no Statuspage intermediary).\n// Result taxonomy:\n// - HTTP 2xx-3xx (per `isExpectedStatus`) → Healthy\n// - HTTP 4xx / 5xx → Down (confirmed)\n// - Network error / DNS / timeout (after retries) → NoConnection\n// NoConnection means we don't know whose fault it is; readiness reconciles\n// against the status page before deciding how to surface it to the user.\n//\n// LLM Gateway – FastAPI service\n// Source: posthog/services/llm-gateway/src/llm_gateway/api/health.py\n// GET /_liveness → 200 {\"status\":\"alive\"}\n//\n// MCP – Cloudflare Worker\n// Source: posthog/services/mcp/src/index.ts\n// GET / → 302 to posthog.com docs. The redirect proves the worker is up.\n// ---------------------------------------------------------------------------\n\nfunction noConnectionResult(error: string, attempts: number): BaseHealthResult {\n return {\n status: ServiceHealthStatus.NoConnection,\n error,\n rawIndicator: attempts > 1 ? `attempts=${attempts}` : undefined,\n };\n}\n\nfunction downResult(error: string): BaseHealthResult {\n return { status: ServiceHealthStatus.Down, error };\n}\n\n// Backoffs sized to cover typical wifi flakiness — a single dropped\n// packet recovers via the 500ms retry; a wifi access point reconnect\n// or wifi↔LTE handoff (2-5s) is caught by the 2000ms retry. Tighter\n// schedules miss multi-second blips because all retries land in the\n// same dead window.\nconst RETRY_BACKOFFS_MS = [500, 2000];\n\nasync function attemptFetch(\n url: string,\n timeoutMs: number,\n redirect: 'follow' | 'manual' | 'error',\n): Promise<\n | { kind: 'response'; res: Response }\n | { kind: 'error'; error: Error; timedOut: boolean }\n> {\n const controller = new AbortController();\n const tid = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await fetch(url, { signal: controller.signal, redirect });\n clearTimeout(tid);\n return { kind: 'response', res };\n } catch (e) {\n clearTimeout(tid);\n const err = e instanceof Error ? e : new Error('Unknown error');\n return { kind: 'error', error: err, timedOut: err.name === 'AbortError' };\n }\n}\n\nasync function fetchEndpointHealth(\n url: string,\n timeoutMs = 5000,\n isExpectedStatus: (status: number) => boolean = (s) => s === 200,\n redirect: 'follow' | 'manual' | 'error' = 'follow',\n): Promise<BaseHealthResult> {\n // Total attempts = 1 initial + RETRY_BACKOFFS_MS.length retries. Both\n // unexpected HTTP statuses (4xx/5xx) and network errors trigger a retry:\n // transient 5xx and Cloudflare edge blips often recover on a retry, and\n // even nominally deterministic 4xx can be transient (CDN propagation\n // lag after a release, token rotation, rate-limit window resets). GETs\n // are idempotent so retrying is safe.\n //\n // Final status if every attempt fails:\n // - At least one HTTP response observed → `Down` (server-side evidence)\n // - Only network errors observed → `NoConnection`\n let lastHttpStatus: number | null = null;\n let lastError = 'Unknown error';\n let attempts = 0;\n\n for (let i = 0; i <= RETRY_BACKOFFS_MS.length; i++) {\n if (i > 0) {\n const wait = RETRY_BACKOFFS_MS[i - 1];\n logToFile(\n `[health-checks] retry ${i}/${RETRY_BACKOFFS_MS.length} for ${url} in ${wait}ms (last: ${lastError})`,\n );\n await new Promise((r) => setTimeout(r, wait));\n }\n attempts++;\n\n const outcome = await attemptFetch(url, timeoutMs, redirect);\n\n if (outcome.kind === 'response') {\n const res = outcome.res;\n if (isExpectedStatus(res.status)) {\n const result: BaseHealthResult = {\n status: ServiceHealthStatus.Healthy,\n rawIndicator:\n attempts > 1\n ? `HTTP ${res.status} (attempts=${attempts})`\n : `HTTP ${res.status}`,\n };\n logToFile(\n `[health-checks] GET ${url} -> ${result.status}` +\n ` (${result.rawIndicator})`,\n );\n return result;\n }\n lastHttpStatus = res.status;\n lastError = `HTTP ${res.status}`;\n continue;\n }\n\n lastError = outcome.timedOut\n ? `Request timed out after ${timeoutMs}ms`\n : outcome.error.message;\n }\n\n const result =\n lastHttpStatus !== null\n ? downResult(`HTTP ${lastHttpStatus} (attempts=${attempts})`)\n : noConnectionResult(lastError, attempts);\n logToFile(\n `[health-checks] GET ${url} -> ${result.status}` +\n ` (attempts=${attempts}, ${result.error})`,\n );\n return result;\n}\n\nexport const checkLlmGatewayHealth = (): Promise<BaseHealthResult> =>\n fetchEndpointHealth('https://gateway.us.posthog.com/_liveness');\n\nexport const checkMcpHealth = (): Promise<BaseHealthResult> =>\n fetchEndpointHealth(\n 'https://mcp.posthog.com/',\n 5000,\n // 2xx-3xx counts as up (redirect to docs)\n (s) => s >= 200 && s < 400,\n 'manual',\n );\n\nexport const checkGithubReleasesHealth = (): Promise<BaseHealthResult> =>\n fetchEndpointHealth(`${REMOTE_SKILLS_BASE_URL}/skill-menu.json`);\n","import {\n ServiceHealthStatus,\n type AllServicesHealth,\n type BaseHealthResult,\n type ComponentHealthResult,\n type HealthCheckKey,\n} from './types';\nimport {\n checkAnthropicHealth,\n checkGithubHealth,\n checkNpmOverallHealth,\n checkNpmComponentHealth,\n checkCloudflareOverallHealth,\n checkCloudflareComponentHealth,\n} from './statuspage';\nimport {\n checkPosthogOverallHealth,\n checkPosthogComponentHealth,\n} from './incidentio';\nimport {\n checkLlmGatewayHealth,\n checkMcpHealth,\n checkGithubReleasesHealth,\n} from './endpoints';\nimport { logToFile } from '@utils/debug';\n\n// ---------------------------------------------------------------------------\n// Service labels (used in human-readable reason strings)\n// ---------------------------------------------------------------------------\n\nexport const SERVICE_LABELS: Record<HealthCheckKey, string> = {\n anthropic: 'Anthropic',\n posthogOverall: 'PostHog',\n posthogComponents: 'PostHog (components)',\n github: 'GitHub',\n npmOverall: 'npm',\n npmComponents: 'npm (components)',\n cloudflareOverall: 'Cloudflare',\n cloudflareComponents: 'Cloudflare (components)',\n llmGateway: 'LLM Gateway',\n mcp: 'MCP',\n githubReleases: 'GitHub Releases',\n};\n\n// ---------------------------------------------------------------------------\n// Readiness config\n// ---------------------------------------------------------------------------\n\nexport interface WizardReadinessConfig {\n /** Services where status=Down blocks the run (readiness=No). */\n downBlocksRun: HealthCheckKey[];\n /** Services where status=Degraded (or worse) blocks the run (readiness=No). */\n degradedBlocksRun?: HealthCheckKey[];\n}\n\n/**\n * See README section \"Health checks\" for the full rationale.\n * Adjust these arrays to change what blocks a wizard run.\n */\nexport const DEFAULT_WIZARD_READINESS_CONFIG: WizardReadinessConfig = {\n downBlocksRun: [\n 'anthropic',\n 'npmOverall',\n 'llmGateway',\n 'mcp',\n 'githubReleases',\n ],\n degradedBlocksRun: ['anthropic'],\n};\n\n/**\n * Reduced readiness config for --signup provisioning flows.\n *\n * Provisioning only needs PostHog and the LLM Gateway - it doesn't\n * use Anthropic directly, npm, GitHub Releases, or MCP.\n */\nexport const SIGNUP_WIZARD_READINESS_CONFIG: WizardReadinessConfig = {\n downBlocksRun: ['posthogOverall', 'llmGateway'],\n};\n\n// ---------------------------------------------------------------------------\n// Aggregate check\n// ---------------------------------------------------------------------------\n\nexport async function checkAllExternalServices(): Promise<AllServicesHealth> {\n const [\n anthropic,\n posthogOverall,\n posthogComponents,\n github,\n npmOverall,\n npmComponents,\n cloudflareOverall,\n cloudflareComponents,\n llmGateway,\n mcp,\n githubReleases,\n ] = await Promise.all([\n checkAnthropicHealth(),\n checkPosthogOverallHealth(),\n checkPosthogComponentHealth(),\n checkGithubHealth(),\n checkNpmOverallHealth(),\n checkNpmComponentHealth(),\n checkCloudflareOverallHealth(),\n checkCloudflareComponentHealth(),\n checkLlmGatewayHealth(),\n checkMcpHealth(),\n checkGithubReleasesHealth(),\n ]);\n\n const health: AllServicesHealth = {\n anthropic,\n posthogOverall,\n posthogComponents,\n github,\n npmOverall,\n npmComponents,\n cloudflareOverall,\n cloudflareComponents,\n llmGateway,\n mcp,\n githubReleases,\n };\n return reconcilePosthogReachability(health);\n}\n\n/**\n * When a PostHog-owned endpoint probe returns `NoConnection`, decide\n * whether it's a real outage or a likely-local issue by checking the\n * official status page (`posthogstatus.com`):\n *\n * - Status page says PostHog is `Down` / `Degraded` → upgrade\n * llmGateway / mcp to `Down`. The status page corroborates.\n * - Status page is `Healthy` → keep `NoConnection`. The status page\n * contradicts; this is probably the user's network.\n * - Status page is also `NoConnection` → keep `NoConnection`. User\n * can't reach two independent PostHog properties; almost\n * certainly their network. (This case relies on incidentio.ts\n * correctly emitting `NoConnection` for fetch failures rather\n * than the previous `Degraded`, which used to silently flip the\n * reconciliation into a false positive.)\n *\n * Why `Degraded` corroborates: a `Degraded` reading here only fires\n * when incident.io's API parsed successfully and reported a real\n * `partial_outage` or `degraded_performance` for some component. That's\n * PostHog acknowledging an issue, even if narrower than a full outage.\n * If our gateway probe is also failing, those two signals together\n * justify pointing at PostHog rather than the user.\n *\n * A narrower variant — only corroborate when the affected component is\n * gateway-related (LLM, US/EU Cloud, app) — would be more precise. We\n * have the data in `posthogComponents` but don't use it here. If the\n * analytics show false positives concentrated in this case, it's a\n * cheap follow-up.\n *\n * Mutates a copy of `health` and returns it.\n */\nexport function reconcilePosthogReachability(\n health: AllServicesHealth,\n): AllServicesHealth {\n const posthogStatus = health.posthogOverall.status;\n const corroboratesOutage =\n posthogStatus === ServiceHealthStatus.Down ||\n posthogStatus === ServiceHealthStatus.Degraded;\n\n if (!corroboratesOutage) return health;\n\n const upgrade = (r: BaseHealthResult): BaseHealthResult =>\n r.status === ServiceHealthStatus.NoConnection\n ? {\n ...r,\n status: ServiceHealthStatus.Down,\n error: r.error\n ? `${r.error} (corroborated by status page)`\n : 'corroborated by status page',\n }\n : r;\n\n return {\n ...health,\n llmGateway: upgrade(health.llmGateway),\n mcp: upgrade(health.mcp),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Wizard readiness evaluation\n// ---------------------------------------------------------------------------\n\nexport enum WizardReadiness {\n Yes = 'yes',\n No = 'no',\n YesWithWarnings = 'yes_with_warnings',\n}\n\nexport interface WizardReadinessResult {\n decision: WizardReadiness;\n health: AllServicesHealth;\n reasons: string[];\n}\n\nfunction describeResult(label: string, h: BaseHealthResult): string {\n const parts = [`${label}: ${h.status}`];\n if (h.rawIndicator) parts.push(`indicator=${h.rawIndicator}`);\n if (h.error) parts.push(h.error);\n return parts.join(' — ');\n}\n\nconst MAX_COMPONENT_NAMES = 8;\n\nfunction describeComponents(label: string, h: ComponentHealthResult): string {\n const affected = h.degradedOrDownComponents;\n if (!affected || affected.length === 0)\n return `${label} components: all operational`;\n const shown = affected\n .slice(0, MAX_COMPONENT_NAMES)\n .map((c) => `${c.name} (${c.status})`);\n const suffix =\n affected.length > MAX_COMPONENT_NAMES\n ? `, +${affected.length - MAX_COMPONENT_NAMES} more`\n : '';\n return `${label} components impacted: ${shown.join(', ')}${suffix}`;\n}\n\n// Each probe can take up to one base timeout + two retries with the\n// 500ms / 2000ms backoffs in endpoints.ts (worst case ~17.5s for a\n// network failure that exhausts retries). Probes run in parallel so\n// the aggregate ceiling is one probe, not the sum.\nconst READINESS_TIMEOUT_MS = 20_000;\n\nexport async function evaluateWizardReadiness(\n config: WizardReadinessConfig = DEFAULT_WIZARD_READINESS_CONFIG,\n): Promise<WizardReadinessResult> {\n try {\n const health = await Promise.race([\n checkAllExternalServices(),\n new Promise<AllServicesHealth>((resolve) =>\n setTimeout(\n () => resolve(allUnknown('Health check timed out')),\n READINESS_TIMEOUT_MS,\n ),\n ),\n ]);\n\n const reasons: string[] = [];\n\n for (const key of Object.keys(health) as HealthCheckKey[]) {\n const result = health[key];\n const label = SERVICE_LABELS[key];\n\n reasons.push(describeResult(label, result));\n\n if ('degradedOrDownComponents' in result) {\n reasons.push(describeComponents(label, result));\n }\n }\n\n const blockingKeys = getBlockingServiceKeys(health, config);\n if (blockingKeys.length > 0) {\n const blockingDetails = blockingKeys.map((key) => {\n const h = health[key];\n return `${key} (${h.status}${h.error ? ` — ${h.error}` : ''})`;\n });\n logToFile(`[health-checks] blocked by: ${blockingDetails.join(', ')}`);\n return { decision: WizardReadiness.No, health, reasons };\n }\n\n const hasWarnings = Object.values(health).some(\n (h) => h.status !== ServiceHealthStatus.Healthy,\n );\n\n if (hasWarnings) {\n return { decision: WizardReadiness.YesWithWarnings, health, reasons };\n }\n\n return { decision: WizardReadiness.Yes, health, reasons };\n } catch (err) {\n logToFile(\n `[health-checks] error: ${err instanceof Error ? err.message : err}`,\n );\n // Health checks must never block the wizard run\n return {\n decision: WizardReadiness.Yes,\n health: allUnknown('Unexpected error'),\n reasons: ['Health check failed unexpectedly — proceeding anyway'],\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Blocking service detection\n// ---------------------------------------------------------------------------\n\n/** Keys that are component-level detail, not top-level services. */\nconst COMPONENT_KEYS: HealthCheckKey[] = [\n 'posthogComponents',\n 'npmComponents',\n 'cloudflareComponents',\n];\n\n/**\n * Get the keys of services that would block a wizard run per the given config.\n *\n * `NoConnection` blocks the same services as `Down` — the wizard genuinely\n * can't continue if it can't reach the gateway. The screen shows softer\n * framing in that case (HealthCheckScreen) so we don't falsely accuse\n * PostHog of an outage when the user's network is the likely cause.\n */\nexport function getBlockingServiceKeys(\n health: AllServicesHealth,\n config: WizardReadinessConfig = DEFAULT_WIZARD_READINESS_CONFIG,\n): HealthCheckKey[] {\n return (Object.keys(health) as HealthCheckKey[]).filter((key) => {\n if (COMPONENT_KEYS.includes(key)) return false;\n const result = health[key];\n if (\n config.downBlocksRun.includes(key) &&\n (result.status === ServiceHealthStatus.Down ||\n result.status === ServiceHealthStatus.NoConnection)\n ) {\n return true;\n }\n if (\n (config.degradedBlocksRun ?? []).includes(key) &&\n result.status !== ServiceHealthStatus.Healthy\n ) {\n return true;\n }\n return false;\n });\n}\n\n/** Build an AllServicesHealth where every service is Degraded with the given error. */\nfunction allUnknown(error: string): AllServicesHealth {\n const base: BaseHealthResult = {\n status: ServiceHealthStatus.Degraded,\n error,\n };\n return {\n anthropic: base,\n posthogOverall: base,\n posthogComponents: { ...base },\n github: base,\n npmOverall: base,\n npmComponents: { ...base },\n cloudflareOverall: base,\n cloudflareComponents: { ...base },\n llmGateway: base,\n mcp: base,\n githubReleases: base,\n };\n}\n","/* eslint-disable no-console */\n/**\n * LoggingUI — Logging-only implementation for CI mode.\n * No prompts, no TUI, no interactivity. Just console output.\n */\n\nimport {\n TaskStatus,\n type WizardUI,\n type SpinnerHandle,\n type AuthErrorDetail,\n} from './wizard-ui';\nimport type { SettingsConflict } from '@lib/agent/claude-settings';\nimport type { ApiUser } from '@lib/api';\nimport { OAUTH_TIMEOUT_MS } from '@lib/constants';\nimport {\n type WizardReadinessResult,\n getBlockingServiceKeys,\n SERVICE_LABELS,\n} from '@lib/health-checks/readiness';\nimport type {\n AskAnswers,\n OutroData,\n PendingQuestion,\n} from '@lib/wizard-session';\n\nexport class LoggingUI implements WizardUI {\n intro(message: string): void {\n console.log(`┌ ${message}`);\n }\n\n outro(message: string): void {\n console.log(`└ ${message}`);\n }\n\n outroError(data: OutroData): void {\n console.log(`✖ ${data.message ?? 'Wizard aborted'}`);\n if (data.body) console.log(`│ ${data.body}`);\n if (data.docsUrl) console.log(`│ Docs: ${data.docsUrl}`);\n }\n\n waitForOutroDismissed(): Promise<void> {\n return Promise.resolve();\n }\n\n waitForAiOptIn(): Promise<void> {\n // Non-TUI runs are CI runs, which auto-consent to AI usage.\n return Promise.resolve();\n }\n\n cancel(message: string): void {\n console.log(`■ ${message}`);\n }\n\n log = {\n info(message: string): void {\n console.log(`│ ${message}`);\n },\n warn(message: string): void {\n console.log(`▲ ${message}`);\n },\n error(message: string): void {\n console.log(`✖ ${message}`);\n },\n success(message: string): void {\n console.log(`✔ ${message}`);\n },\n step(message: string): void {\n console.log(`◇ ${message}`);\n },\n };\n\n note(message: string): void {\n console.log(`│ ${message}`);\n }\n\n spinner(): SpinnerHandle {\n return {\n start(message?: string) {\n if (message) console.log(`◌ ${message}`);\n },\n stop(message?: string) {\n if (message) console.log(`● ${message}`);\n },\n message(msg?: string) {\n if (msg) console.log(`◌ ${msg}`);\n },\n };\n }\n\n pushStatus(message: string): void {\n console.log(`◇ ${message}`);\n }\n\n setDetectedFramework(label: string): void {\n console.log(`✔ Framework: ${label}`);\n }\n\n onEnterScreen(_screen: string, _fn: () => void): void {\n // No screen transitions in CI\n }\n\n setLoginUrl(url: string | null): void {\n if (url) {\n console.log(\n `│ If the browser didn't open automatically, use this link:`,\n );\n console.log(`│ ${url}`);\n }\n }\n\n setAuthorizeUrl(_url: string | null): void {\n // Manual-paste modal is TUI-only; CI/non-interactive runs don't use it.\n }\n\n showBlockingOutage(result: WizardReadinessResult): Promise<void> {\n console.log(`▲ Service health issues detected.`);\n const blockingKeys = getBlockingServiceKeys(result.health);\n if (blockingKeys.length > 0) {\n console.log(`│`);\n console.log(`│ Blocking services:`);\n for (const key of blockingKeys) {\n const status = result.health[key].status;\n const error = result.health[key].error;\n const label = SERVICE_LABELS[key];\n const detail = error ? ` — ${error}` : '';\n console.log(`│ ✖ ${label}: ${status}${detail}`);\n }\n console.log(`│`);\n }\n for (const reason of result.reasons) {\n console.log(`│ ${reason}`);\n }\n console.log(\n `│ Continuing anyway — health checks are advisory in non-interactive runs.`,\n );\n return Promise.resolve();\n }\n\n setReadinessWarnings(result: WizardReadinessResult): void {\n console.log(`▲ Service health warnings detected.`);\n for (const reason of result.reasons) {\n console.log(`│ ${reason}`);\n }\n }\n\n showPortConflict(_processInfo: {\n command: string;\n pid: string;\n port: number;\n user: string;\n }): Promise<void> {\n return Promise.resolve();\n }\n\n waitForManualAuthCode(): Promise<string> {\n // No interactive prompt in CI/logging mode — never resolves. CI bypasses\n // OAuth entirely, so this is only here to satisfy the interface.\n return new Promise<string>(() => {\n /* intentionally never resolves */\n });\n }\n\n showSettingsOverride(\n _conflicts: SettingsConflict[],\n _backupAndFix: () => boolean,\n ): Promise<void> {\n return Promise.resolve();\n }\n\n requestQuestion(_question: PendingQuestion): Promise<AskAnswers> {\n return Promise.reject(\n new Error(\n 'wizard_ask is not available in CI / non-interactive mode. ' +\n 'Re-run the wizard without --ci to answer interactively.',\n ),\n );\n }\n\n showAuthError(detail?: AuthErrorDetail): void {\n console.log(`✖ Authentication failed (401)`);\n if (detail?.hasSettingsConflict) {\n console.log(\n `│ Claude Code auth is conflicting with the wizard. Please try again after logging out:`,\n );\n console.log(`│ claude auth logout`);\n } else {\n console.log(\n `│ The PostHog LLM Gateway rejected the API key. Common causes:`,\n );\n console.log(\n `│ - Wrong key type: pass a personal API key (phx_xxx). pha_ is an OAuth access token, phc_ is a project key.`,\n );\n console.log(\n `│ - Missing scope: the personal API key needs the \"llm_gateway:read\" scope.`,\n );\n console.log(`│ - Expired or revoked key.`);\n console.log(\n `│ - Region mismatch: --region must match the region the key was issued in (us vs eu).`,\n );\n }\n if (detail?.logFilePath) {\n console.log(`│ Verbose log: ${detail.logFilePath}`);\n }\n }\n\n showSessionTimeout(): void {\n const minutes = Math.round(OAUTH_TIMEOUT_MS / 60_000);\n console.log(\n `✖ Login timed out. The OAuth link timed out after ${minutes} minutes.`,\n );\n console.log(`│ Re-run the wizard to get a fresh link and try again.`);\n }\n\n startRun(): void {\n // No-op in CI mode\n }\n\n setCredentials(_credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n }): void {\n // No-op in CI mode — credentials are handled directly\n }\n\n setRoleAtOrganization(_role: string | null): void {\n // No-op in CI mode — there's no TUI to render role-tailored prompts\n }\n\n setApiUser(_user: ApiUser | null): void {\n // No-op in CI mode — there's no TUI to read account context from\n // the session.\n }\n\n private lastTodoLine = '';\n\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void {\n const completed = todos.filter(\n (t) => t.status === TaskStatus.Completed,\n ).length;\n const active = todos.filter((t) => t.status === TaskStatus.InProgress);\n if (active.length === 0) return;\n const labels = active.map((t) => t.activeForm || t.content).join(' · ');\n const line = `◌ [${completed}/${todos.length}] ${labels}`;\n // The queue re-renders on every transition; print only what changed.\n if (line === this.lastTodoLine) return;\n this.lastTodoLine = line;\n console.log(line);\n }\n\n setEventPlan(_events: Array<{ name: string; description: string }>): void {\n // No-op in CI mode\n }\n\n setDashboardUrl(_url: string): void {\n // No-op in CI mode\n }\n\n setStage(_stage: string): void {\n // No-op in CI mode\n }\n\n setNotebookUrl(_url: string): void {\n // No-op in CI mode\n }\n\n setOutroData(_data: import('@lib/wizard-session').OutroData): void {\n // No-op in CI mode\n }\n\n setFrameworkContext(_key: string, _value: unknown): void {\n // No-op in CI mode\n }\n\n getFrameworkContext(_key: string): unknown {\n // No frameworkContext in CI mode\n return undefined;\n }\n\n waitForGate(_stepId: string): Promise<void> {\n // No interactive gates in CI mode\n return Promise.resolve();\n }\n}\n","/**\n * UI singleton — provides getUI() and setUI() for the wizard.\n * Default: LoggingUI. Swap to InkUI at startup for TUI mode.\n */\n\nimport type { WizardUI } from './wizard-ui';\nimport { LoggingUI } from './logging-ui';\n\nlet currentUI: WizardUI = new LoggingUI();\n\nexport function getUI(): WizardUI {\n return currentUI;\n}\n\nexport function setUI(ui: WizardUI): void {\n currentUI = ui;\n}\n\nexport type { WizardUI, SpinnerHandle } from './wizard-ui';\n","import { tmpdir } from 'node:os';\nimport { join, sep } from 'node:path';\n\n// /tmp is stable and discoverable on macOS/Linux; Windows needs os.tmpdir()\nconst TMP = process.platform === 'win32' ? tmpdir() : '/tmp';\n\nexport const WIZARD_LOG_FILE = join(TMP, 'posthog-wizard.log');\nexport const WIZARD_BENCHMARK_FILE = join(TMP, 'posthog-wizard-benchmark.json');\nexport const WIZARD_YARA_REPORT_FILE = join(\n TMP,\n 'posthog-wizard-yara-report.json',\n);\n/** Temp path for a skill download zip. */\nexport function skillTmpPath(skillId: string): string {\n return join(TMP, `posthog-skill-${skillId}.zip`);\n}\n\n/**\n * Strip an absolute installDir prefix off a project file path so the UI\n * renders `index.js:12` instead of `/Users/.../index.js:12`. Defends\n * against false matches like `/Users/foo` ⊂ `/Users/foobar/x.js` by\n * normalizing to a trailing path separator before the prefix check.\n */\nexport function relativeToInstallDir(file: string, installDir: string): string {\n const prefix = installDir.endsWith(sep) ? installDir : installDir + sep;\n return file.startsWith(prefix) ? file.slice(prefix.length) : file;\n}\n","import { appendFileSync } from 'fs';\nimport path from 'path';\nimport { inspect } from 'node:util';\nimport { getUI } from '@ui';\nimport { runtimeEnv } from '@env';\nimport { WIZARD_LOG_FILE } from './paths';\n\nlet logFilePath = WIZARD_LOG_FILE;\nlet fileLoggingEnabled = true;\nlet consoleLoggingEnabled = false;\n\nfunction stringify(value: unknown): string {\n if (typeof value === 'string') return value;\n if (value instanceof Error) return value.stack ?? String(value);\n try {\n // JSON.stringify throws on cycles and skips some values — fall back to\n // inspect so a crash log line is never dropped.\n return JSON.stringify(value, null, 2) ?? inspect(value, { depth: 3 });\n } catch {\n return inspect(value, { depth: 3 });\n }\n}\n\nfunction renderLine(args: readonly unknown[]): string {\n return args.map(stringify).join(' ');\n}\n\nexport function getLogFilePath(): string {\n return logFilePath;\n}\n\nexport function configureLogFile(opts: {\n path?: string;\n enabled?: boolean;\n}): void {\n if (opts.path !== undefined) logFilePath = opts.path;\n if (opts.enabled !== undefined) fileLoggingEnabled = opts.enabled;\n}\n\nexport function configureLogFileFromEnvironment(): void {\n const dir = runtimeEnv('POSTHOG_WIZARD_LOG_DIR');\n if (dir) {\n configureLogFile({ path: path.join(dir, 'posthog-wizard.log') });\n }\n}\n\nexport function initLogFile(): void {\n if (!fileLoggingEnabled) return;\n try {\n const divider = '='.repeat(60);\n appendFileSync(\n logFilePath,\n `\\n${divider}\\nPostHog Wizard Run: ${new Date().toISOString()}\\n${divider}\\n`,\n );\n } catch {\n // Logging must never crash the wizard.\n }\n}\n\nexport function logToFile(...args: unknown[]): void {\n if (!fileLoggingEnabled) return;\n try {\n const ts = new Date().toISOString();\n appendFileSync(logFilePath, `[${ts}] ${renderLine(args)}\\n`);\n } catch {\n // Logging must never crash the wizard.\n }\n}\n\nexport function debug(...args: unknown[]): void {\n if (!consoleLoggingEnabled) return;\n getUI().log.info(renderLine(args));\n}\n\nexport function enableDebugLogs(): void {\n consoleLoggingEnabled = true;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"debug-BGMe1wP6.js","names":["errResult","join"],"sources":["../src/env.ts","../src/lib/version.ts","../src/lib/constants.ts","../src/lib/health-checks/statuspage.ts","../src/lib/health-checks/incidentio.ts","../src/lib/health-checks/endpoints.ts","../src/lib/health-checks/readiness.ts","../src/ui/logging-ui.ts","../src/ui/index.ts","../src/utils/paths.ts","../src/utils/debug.ts"],"sourcesContent":["/**\n * Central environment variable access for the PostHog wizard.\n *\n * ── Build-time constants ────────────────────────────────────────────\n * Inlined by tsdown's `env` option at compile time. After build, the\n * runtime value of these env vars has zero effect on the wizard.\n *\n * ── Runtime variables ───────────────────────────────────────────────\n * Read through `runtimeEnv()` with a typed allowlist. This makes every\n * runtime dependency on the environment explicit and grep-able.\n *\n * ── Direct process.env access ───────────────────────────────────────\n * Reserved for subprocess environment configuration (writes) and\n * vendored code. Production source outside those cases should use\n * this module instead.\n */\n\n// ── Build-time constants ─────────────────────────────────────────────\n// tsdown replaces `process.env.NODE_ENV` with a string literal.\n// After build these are just `\"production\"`, `false`, etc.\n\nexport const NODE_ENV = process.env.NODE_ENV as string;\nexport const IS_DEV =\n process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test';\n\n/**\n * True only in published/production builds. tsdown inlines\n * `process.env.NODE_ENV` as the literal `\"production\"` at build time, so this\n * collapses to `true` in `dist/` and stays `false` for `tsx`/dev/test runs\n * (where NODE_ENV is unset, `development`, or `test`). Used to gate features\n * that aren't supported in the shipped package — e.g. `--ci` mode.\n */\nexport const IS_PRODUCTION_BUILD = process.env.NODE_ENV === 'production';\n\n// ── Runtime environment ──────────────────────────────────────────────\n\n/**\n * Exhaustive allowlist of env vars the wizard reads at runtime.\n * Add new keys here when a new runtime dependency is needed.\n */\ntype RuntimeEnvKey =\n // CI-build-only flag overrides (see utils/ci-flag-overrides.ts).\n // Deliberately NOT POSTHOG_WIZARD_-prefixed: yargs .env('POSTHOG_WIZARD')\n // would claim it as an unknown CLI option and strict-reject the run.\n | 'WIZARD_CI_FLAG_OVERRIDES'\n | 'WIZARD_CI_EXCLUDE_TASKS'\n // Wizard CLI configuration (yargs POSTHOG_WIZARD_ prefix)\n | 'POSTHOG_WIZARD_BENCHMARK_CONFIG'\n | 'POSTHOG_WIZARD_BENCHMARK_FILE'\n | 'POSTHOG_WIZARD_LOG_DIR'\n | 'POSTHOG_WIZARD_DEBUG'\n // Local/CI escape hatch to disable Warlock scanning without the PostHog flag.\n | 'POSTHOG_WIZARD_WARLOCK_DISABLED'\n | 'DEBUG'\n // Agent / MCP\n | 'MCP_URL'\n | 'POSTHOG_API_KEY'\n // Platform: terminal detection\n | 'TERM'\n | 'TERM_PROGRAM'\n | 'TERMINAL_EMULATOR'\n | 'CI'\n | 'WT_SESSION'\n | 'TERMINUS_SUBLIME'\n | 'ConEmuTask'\n // Platform: paths\n | 'APPDATA'\n | 'XDG_CONFIG_HOME';\n\n/** Read a runtime environment variable. Only allowlisted keys compile. */\nexport function runtimeEnv(key: RuntimeEnvKey): string | undefined {\n return process.env[key];\n}\n","// Auto-generated by scripts/generate-version.js — do not edit\nexport const VERSION = '2.33.0';\n","/**\n * Shared constants for the PostHog wizard.\n */\n\nimport { VERSION } from './version';\n\n// ── Models ──────────────────────────────────────────────────────────\n\n/**\n * Default model for agent runs. Bare model IDs (no `anthropic/` prefix) so the\n * LLM gateway's Bedrock fallback can match map_to_bedrock_model().\n */\nexport const DEFAULT_AGENT_MODEL = 'claude-sonnet-4-6';\n\n/**\n * Cheaper, faster model for mechanical agent work (e.g. repo classification\n * during source-map detection). Passed via AgentConfig.modelOverride.\n */\nexport const HAIKU_MODEL = 'claude-haiku-4-5-20251001';\n\n// ── Integration / CLI ───────────────────────────────────────────────\n\n/**\n * Detection order matters: put framework-specific integrations BEFORE basic language fallbacks.\n */\nexport enum Integration {\n // Frameworks\n nextjs = 'nextjs',\n nuxt = 'nuxt',\n vue = 'vue',\n reactRouter = 'react-router',\n tanstackStart = 'tanstack-start',\n tanstackRouter = 'tanstack-router',\n reactNative = 'react-native',\n angular = 'angular',\n astro = 'astro',\n django = 'django',\n flask = 'flask',\n fastapi = 'fastapi',\n laravel = 'laravel',\n sveltekit = 'sveltekit',\n swift = 'swift',\n android = 'android',\n rails = 'rails',\n\n // Language fallbacks\n python = 'python',\n ruby = 'ruby',\n javascriptNode = 'javascript_node',\n javascript_web = 'javascript_web',\n}\n\nexport interface Args {\n debug: boolean;\n integration: Integration;\n}\n\n// ── Environment ──────────────────────────────────────────────────────\n\nimport { IS_DEV } from '@env';\nexport { IS_DEV };\nexport const DEBUG = false;\n\n// ── URLs ─────────────────────────────────────────────────────────────\n\nexport const DEFAULT_URL = IS_DEV\n ? 'http://localhost:8010'\n : 'https://us.posthog.com';\n/**\n * Region-agnostic PostHog app URL. Resolves to us.posthog.com or\n * eu.posthog.com server-side based on the signed-in user's profile.\n * Use this for share-with-user links (e.g. settings pages) so they\n * land on the right region without us needing to know it client-side.\n */\nexport const POSTHOG_APP_URL = IS_DEV\n ? 'http://localhost:8010'\n : 'https://app.posthog.com';\nexport const DEFAULT_HOST_URL = IS_DEV\n ? 'http://localhost:8010'\n : 'https://us.i.posthog.com';\nexport const ISSUES_URL = 'https://github.com/posthog/wizard/issues';\nexport const CONTEXT_MILL_URL = 'https://github.com/PostHog/context-mill';\n/**\n * Latest context-mill release page — the BYOAI download link shown in\n * the privacy panel. Deliberately the release PAGE, not a direct asset\n * URL: asset URLs are ~89 chars and hard-wrap inside the 64-col panel,\n * which corrupts terminal copy/paste with a mid-URL line break. This\n * stays under one line; the panel names the exact asset to grab.\n */\nexport const CONTEXT_MILL_RELEASES_URL =\n 'https://github.com/PostHog/context-mill/releases/latest';\nexport const POSTHOG_DOCS_URL = 'https://posthog.com/docs';\nexport const POSTHOG_WIZARD_REPO_URL = 'https://github.com/PostHog/wizard';\nexport const POSTHOG_TERMS_URL = 'https://posthog.com/terms';\nexport const POSTHOG_PRIVACY_URL = 'https://posthog.com/privacy';\nexport const POSTHOG_ORG_AI_SETTINGS_URL =\n 'https://app.posthog.com/settings/organization-details#setting=organization-ai-consent';\nexport const WIZARD_CONTACT_EMAIL = 'wizard@posthog.com';\n\n/** Remote base URL for fetching the skill menu + downloading skills. */\nexport const REMOTE_SKILLS_BASE_URL =\n 'https://github.com/PostHog/context-mill/releases/latest/download';\n/** Local base URL when `--local-mcp` is set (served by context-mill dev server). */\nexport const LOCAL_SKILLS_BASE_URL = 'http://localhost:8765';\n\n/**\n * Pick the skills base URL based on the session's localMcp flag.\n * Single source of truth — do not inline this ternary anywhere.\n */\nexport function getSkillsBaseUrl(localMcp: boolean): string {\n return localMcp ? LOCAL_SKILLS_BASE_URL : REMOTE_SKILLS_BASE_URL;\n}\n\n// ── Analytics (internal) ──────────────────────────────────────────────\n\nexport const ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY = 'sTMFPsFhdP1Ssg';\nexport const ANALYTICS_HOST_URL = 'https://internal-j.posthog.com';\nexport const ANALYTICS_TEAM_TAG = 'docs-and-wizard';\n\n// ── OAuth / Auth ────────────────────────────────────────────────────\n\nexport const POSTHOG_OAUTH_URL = IS_DEV\n ? 'http://localhost:8010'\n : 'https://oauth.posthog.com';\nexport const OAUTH_PORTS = [8239, 8238, 8240, 8237, 8236, 8235] as const;\nexport const POSTHOG_US_CLIENT_ID = 'c4Rdw8DIxgtQfA80IiSnGKlNX8QN00cFWF00QQhM';\nexport const POSTHOG_EU_CLIENT_ID = 'bx2C5sZRN03TkdjraCcetvQFPGH6N2Y9vRLkcKEy';\nexport const POSTHOG_DEV_CLIENT_ID = 'DC5uRLVbGI02YQ82grxgnK6Qn12SXWpCqdPb60oZ';\nexport const POSTHOG_PROXY_CLIENT_ID = POSTHOG_US_CLIENT_ID;\nexport const DUMMY_PROJECT_API_KEY = '_YOUR_POSTHOG_PROJECT_TOKEN_';\n\n/**\n * Scopes the wizard requests during the agentic provisioning signup flow.\n *\n * Each entry is justified by what the wizard's agent step does after signup:\n * - user:read identify the user for analytics + agent context\n * - project:read look up the freshly-provisioned project\n * - llm_gateway:read authenticate to gateway.{us,eu}.posthog.com/wizard\n * (the agent's LLM calls — without this scope, every\n * agent message returns 401)\n * - query:read run HogQL queries when the agent needs data\n * - dashboard:write create the onboarding dashboard during setup\n * - insight:write create the onboarding insights during setup\n * - notebook:write upload the events-audit report as a PostHog notebook\n * in step 6 of the events-audit skill (notebooks-create\n * MCP tool requires this scope)\n *\n * Must be a subset of `ALLOWED_PROVISIONING_SCOPES` in\n * `ee/api/agentic_provisioning/views.py` on the backend.\n */\nexport const WIZARD_PROVISIONING_SCOPES = [\n 'user:read',\n 'project:read',\n 'llm_gateway:read',\n 'dashboard:write',\n 'insight:write',\n 'query:read',\n 'notebook:write',\n] as const;\n\n/**\n * Scopes the wizard requests during the OAuth login flow. Superset of\n * `WIZARD_PROVISIONING_SCOPES` with scopes that only apply to the login\n * path and are not in the provisioning allowlist:\n * - health_issue:read used by `wizard doctor`\n * - wizard_session:read list / retrieve / stream sessions\n * - wizard_session:write stream run state to /api/projects/{id}/wizard/sessions/\n * - organization:read read `organization.is_ai_data_processing_approved`\n * from /api/users/@me/ for the AI opt-in gate\n *\n * NOTE: every scope here must be within the wizard OAuth application's\n * server-side scope ceiling (`OAuthApplication.scopes` in posthog, set\n * via Django admin on BOTH prod regions) — requesting anything outside\n * it fails the WHOLE authorize request with `error=invalid_scope`\n * before the consent screen renders. Procedure: the\n * \"scope-ceiling-invalid-scope\" runbook in PostHog/runbooks. Keep the\n * runbook's worked example in sync when this list changes.\n */\nexport const WIZARD_OAUTH_SCOPES = [\n ...WIZARD_PROVISIONING_SCOPES,\n 'health_issue:read',\n 'wizard_session:read',\n 'wizard_session:write',\n 'organization:read',\n] as const;\n\n// ── Wizard run / variants ───────────────────────────────────────────\n\nexport const WIZARD_INTERACTION_EVENT_NAME = 'wizard interaction';\nexport const WIZARD_REMARK_EVENT_NAME = 'wizard remark';\n/** Boolean feature flag that routes a run to the experimental orchestrator runner. */\nexport const WIZARD_ORCHESTRATOR_FLAG_KEY = 'wizard-orchestrator';\n/** Feature flag key that gates the intro-screen \"Tools\" menu. */\nexport const WIZARD_TOOLS_MENU_FLAG_KEY = 'wizard-tools-menu';\n/**\n * Kill switch: when this flag resolves to 'true', Warlock/YARA scanning is\n * disabled for the run. Defaults off (scanning on) — a missing flag or a failed\n * flag fetch must never silently disable a security control.\n */\nexport const WIZARD_WARLOCK_DISABLED_FLAG_KEY = 'wizard-warlock-disabled';\n/** User-Agent for wizard HTTP requests and MCP server identification. */\nexport const WIZARD_USER_AGENT = `posthog/wizard; version: ${VERSION}`;\n\n// ── HTTP headers ─────────────────────────────────────────────────────\n\n/** Header prefix for PostHog properties (e.g. X-POSTHOG-PROPERTY-VARIANT). */\nexport const POSTHOG_PROPERTY_HEADER_PREFIX = 'X-POSTHOG-PROPERTY-';\n/** Header prefix for PostHog feature flags. */\nexport const POSTHOG_FLAG_HEADER_PREFIX = 'X-POSTHOG-FLAG-';\n\n// ── Timeouts ─────────────────────────────────────────────────────────\n\n/** Timeout for framework / project detection probes (ms). */\nexport const DETECTION_TIMEOUT_MS = 10_000;\n\n/**\n * Timeout for the OAuth authorization flow (ms).\n *\n * Mirrors the server-side authorization-code expiry\n * (`AUTHORIZATION_CODE_EXPIRE_SECONDS`, 5 minutes). Once the code expires the\n * callback is dead and the token exchange can no longer succeed, so we stop\n * waiting at the same moment and prompt the user to re-run rather than letting\n * them complete a login that would fail.\n */\nexport const OAUTH_TIMEOUT_MS = 300_000;\n","import {\n ServiceHealthStatus,\n type BaseHealthResult,\n type ComponentHealthResult,\n} from './types';\n\n// ---------------------------------------------------------------------------\n// Statuspage.io v2 API helpers\n// https://metastatuspage.com/api\n//\n// status.json – page-level rollup; indicator is one of: none | minor | major | critical\n// summary.json – same rollup + component list; component status is one of:\n// operational | degraded_performance | partial_outage | major_outage | under_maintenance\n// https://support.atlassian.com/statuspage/docs/show-service-status-with-components\n// ---------------------------------------------------------------------------\n\ninterface StatuspageStatusResponse {\n status?: { indicator?: string; description?: string };\n}\n\ninterface StatuspageSummaryResponse extends StatuspageStatusResponse {\n components?: { id: string; name: string; status: string }[];\n}\n\nfunction mapIndicator(v: string | null | undefined): ServiceHealthStatus {\n switch (v) {\n case 'none':\n return ServiceHealthStatus.Healthy;\n case 'minor':\n return ServiceHealthStatus.Degraded;\n case 'major':\n case 'critical':\n return ServiceHealthStatus.Down;\n default:\n return ServiceHealthStatus.Degraded;\n }\n}\n\nfunction mapComponentRaw(v: string | null | undefined): ServiceHealthStatus {\n switch (v) {\n case 'operational':\n return ServiceHealthStatus.Healthy;\n case 'degraded_performance':\n case 'under_maintenance':\n return ServiceHealthStatus.Degraded;\n case 'partial_outage':\n case 'major_outage':\n return ServiceHealthStatus.Down;\n default:\n return ServiceHealthStatus.Degraded;\n }\n}\n\nfunction errResult(error: string): BaseHealthResult {\n return { status: ServiceHealthStatus.Degraded, error };\n}\n\nasync function fetchStatuspageIndicator(\n url: string,\n timeoutMs = 5000,\n): Promise<BaseHealthResult> {\n try {\n const controller = new AbortController();\n const tid = setTimeout(() => controller.abort(), timeoutMs);\n const res = await fetch(url, { signal: controller.signal });\n clearTimeout(tid);\n\n if (!res.ok) return errResult(`HTTP ${res.status}`);\n\n const data = (await res.json()) as StatuspageStatusResponse;\n const indicator = data.status?.indicator ?? null;\n return {\n status: mapIndicator(indicator),\n rawIndicator: indicator ?? undefined,\n };\n } catch (e) {\n if (e instanceof Error && e.name === 'AbortError')\n return errResult('Request timed out');\n return errResult(e instanceof Error ? e.message : 'Unknown error');\n }\n}\n\nasync function fetchStatuspageSummary(\n url: string,\n timeoutMs = 5000,\n): Promise<ComponentHealthResult> {\n try {\n const controller = new AbortController();\n const tid = setTimeout(() => controller.abort(), timeoutMs);\n const res = await fetch(url, { signal: controller.signal });\n clearTimeout(tid);\n\n if (!res.ok) return errResult(`HTTP ${res.status}`);\n\n const data = (await res.json()) as StatuspageSummaryResponse;\n const indicator = data.status?.indicator ?? null;\n const overall = mapIndicator(indicator);\n\n const affected = (data.components ?? [])\n .map((c) => ({\n name: c.name,\n status: mapComponentRaw(c.status),\n rawStatus: c.status,\n }))\n .filter((c) => c.status !== ServiceHealthStatus.Healthy);\n\n return {\n status: affected.length > 0 ? ServiceHealthStatus.Degraded : overall,\n rawIndicator: indicator ?? undefined,\n degradedOrDownComponents: affected.length > 0 ? affected : undefined,\n };\n } catch (e) {\n if (e instanceof Error && e.name === 'AbortError')\n return errResult('Request timed out');\n return errResult(e instanceof Error ? e.message : 'Unknown error');\n }\n}\n\n// ---------------------------------------------------------------------------\n// Individual statuspage-backed checks\n// ---------------------------------------------------------------------------\n\nexport const checkAnthropicHealth = (): Promise<BaseHealthResult> =>\n fetchStatuspageIndicator('https://status.claude.com/api/v2/status.json');\n\nexport const checkGithubHealth = (): Promise<BaseHealthResult> =>\n fetchStatuspageIndicator('https://www.githubstatus.com/api/v2/status.json');\n\nexport const checkNpmOverallHealth = (): Promise<BaseHealthResult> =>\n fetchStatuspageIndicator('https://status.npmjs.org/api/v2/status.json');\n\nexport const checkNpmComponentHealth = (): Promise<ComponentHealthResult> =>\n fetchStatuspageSummary('https://status.npmjs.org/api/v2/summary.json');\n\nexport const checkCloudflareOverallHealth = (): Promise<BaseHealthResult> =>\n fetchStatuspageIndicator(\n 'https://www.cloudflarestatus.com/api/v2/status.json',\n );\n\nexport const checkCloudflareComponentHealth =\n (): Promise<ComponentHealthResult> =>\n fetchStatuspageSummary(\n 'https://www.cloudflarestatus.com/api/v2/summary.json',\n );\n","import {\n ServiceHealthStatus,\n type BaseHealthResult,\n type ComponentHealthResult,\n type ComponentStatus,\n} from './types';\n\ninterface IncidentIoAffectedComponent {\n id: string;\n name: string;\n group_name?: string;\n current_status: string;\n}\n\ninterface IncidentIoIncident {\n id: string;\n name: string;\n status: string;\n current_worst_impact: string;\n affected_components: IncidentIoAffectedComponent[];\n}\n\ninterface IncidentIoSummary {\n ongoing_incidents: IncidentIoIncident[];\n in_progress_maintenances: unknown[];\n}\n\nfunction mapIncidentImpact(impact: string): ServiceHealthStatus {\n switch (impact) {\n case 'full_outage':\n return ServiceHealthStatus.Down;\n case 'partial_outage':\n case 'degraded_performance':\n return ServiceHealthStatus.Degraded;\n default:\n return ServiceHealthStatus.Degraded;\n }\n}\n\nfunction mapComponentStatus(status: string): ServiceHealthStatus {\n switch (status) {\n case 'operational':\n return ServiceHealthStatus.Healthy;\n case 'full_outage':\n return ServiceHealthStatus.Down;\n case 'partial_outage':\n case 'degraded_performance':\n return ServiceHealthStatus.Degraded;\n default:\n return ServiceHealthStatus.Degraded;\n }\n}\n\n/**\n * Build an error result for fetch failures. The kind matters for\n * downstream reconciliation:\n *\n * - 'http' (incident.io returned a bad status code) → `Down`. We\n * reached the status page but it told us something is wrong on\n * its side. We have a definitive response.\n * - 'network' (timeout, DNS failure, TCP/TLS failure) → `NoConnection`.\n * We never reached the status page. Treating this as `Degraded`\n * (the previous behavior) silently flipped the reconciliation in\n * `readiness.ts` from \"soft\" to \"confirmed outage\" whenever the\n * user's own network was flaky — exactly the false positive this\n * module is meant to help diagnose.\n */\nfunction errResult(error: string, kind: 'http' | 'network'): BaseHealthResult {\n return {\n status:\n kind === 'http'\n ? ServiceHealthStatus.Down\n : ServiceHealthStatus.NoConnection,\n error,\n };\n}\n\nconst POSTHOG_STATUS_URL = 'https://www.posthogstatus.com/api/v1/summary';\n\nasync function fetchPosthogStatus(\n timeoutMs = 5000,\n): Promise<{ overall: BaseHealthResult; components: ComponentHealthResult }> {\n try {\n const controller = new AbortController();\n const tid = setTimeout(() => controller.abort(), timeoutMs);\n const res = await fetch(POSTHOG_STATUS_URL, { signal: controller.signal });\n clearTimeout(tid);\n\n if (!res.ok) {\n const err = errResult(`HTTP ${res.status}`, 'http');\n return { overall: err, components: err };\n }\n\n const data = (await res.json()) as IncidentIoSummary;\n const incidents = data.ongoing_incidents ?? [];\n\n if (incidents.length === 0) {\n return {\n overall: { status: ServiceHealthStatus.Healthy },\n components: { status: ServiceHealthStatus.Healthy },\n };\n }\n\n let worstOverall = ServiceHealthStatus.Degraded;\n const affected: ComponentStatus[] = [];\n\n for (const incident of incidents) {\n const impact = mapIncidentImpact(incident.current_worst_impact);\n if (impact === ServiceHealthStatus.Down) {\n worstOverall = ServiceHealthStatus.Down;\n }\n\n for (const comp of incident.affected_components ?? []) {\n const compStatus = mapComponentStatus(comp.current_status);\n if (compStatus !== ServiceHealthStatus.Healthy) {\n affected.push({\n name: comp.group_name\n ? `${comp.group_name} — ${comp.name}`\n : comp.name,\n status: compStatus,\n rawStatus: comp.current_status,\n });\n }\n }\n }\n\n return {\n overall: { status: worstOverall },\n components: {\n status:\n affected.length > 0 ? ServiceHealthStatus.Degraded : worstOverall,\n degradedOrDownComponents: affected.length > 0 ? affected : undefined,\n },\n };\n } catch (e) {\n if (e instanceof Error && e.name === 'AbortError') {\n const err = errResult('Request timed out', 'network');\n return { overall: err, components: err };\n }\n const err = errResult(\n e instanceof Error ? e.message : 'Unknown error',\n 'network',\n );\n return { overall: err, components: err };\n }\n}\n\nlet _cache: Promise<{\n overall: BaseHealthResult;\n components: ComponentHealthResult;\n}> | null = null;\n\nfunction getPosthogHealth() {\n if (!_cache) _cache = fetchPosthogStatus();\n return _cache;\n}\n\nexport function resetPosthogHealthCache(): void {\n _cache = null;\n}\n\nexport const checkPosthogOverallHealth = async (): Promise<BaseHealthResult> =>\n (await getPosthogHealth()).overall;\n\nexport const checkPosthogComponentHealth =\n async (): Promise<ComponentHealthResult> =>\n (await getPosthogHealth()).components;\n","import { REMOTE_SKILLS_BASE_URL } from '@lib/constants';\nimport { logToFile } from '@utils/debug';\nimport { ServiceHealthStatus, type BaseHealthResult } from './types';\n\n// ---------------------------------------------------------------------------\n// Direct endpoint health checks\n//\n// These ping PostHog-owned services directly (no Statuspage intermediary).\n// Result taxonomy:\n// - HTTP 2xx-3xx (per `isExpectedStatus`) → Healthy\n// - HTTP 4xx / 5xx → Down (confirmed)\n// - Network error / DNS / timeout (after retries) → NoConnection\n// NoConnection means we don't know whose fault it is; readiness reconciles\n// against the status page before deciding how to surface it to the user.\n//\n// LLM Gateway – FastAPI service\n// Source: posthog/services/llm-gateway/src/llm_gateway/api/health.py\n// GET /_liveness → 200 {\"status\":\"alive\"}\n//\n// MCP – Cloudflare Worker\n// Source: posthog/services/mcp/src/index.ts\n// GET / → 302 to posthog.com docs. The redirect proves the worker is up.\n// ---------------------------------------------------------------------------\n\nfunction noConnectionResult(error: string, attempts: number): BaseHealthResult {\n return {\n status: ServiceHealthStatus.NoConnection,\n error,\n rawIndicator: attempts > 1 ? `attempts=${attempts}` : undefined,\n };\n}\n\nfunction downResult(error: string): BaseHealthResult {\n return { status: ServiceHealthStatus.Down, error };\n}\n\n// Backoffs sized to cover typical wifi flakiness — a single dropped\n// packet recovers via the 500ms retry; a wifi access point reconnect\n// or wifi↔LTE handoff (2-5s) is caught by the 2000ms retry. Tighter\n// schedules miss multi-second blips because all retries land in the\n// same dead window.\nconst RETRY_BACKOFFS_MS = [500, 2000];\n\nasync function attemptFetch(\n url: string,\n timeoutMs: number,\n redirect: 'follow' | 'manual' | 'error',\n): Promise<\n | { kind: 'response'; res: Response }\n | { kind: 'error'; error: Error; timedOut: boolean }\n> {\n const controller = new AbortController();\n const tid = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await fetch(url, { signal: controller.signal, redirect });\n clearTimeout(tid);\n return { kind: 'response', res };\n } catch (e) {\n clearTimeout(tid);\n const err = e instanceof Error ? e : new Error('Unknown error');\n return { kind: 'error', error: err, timedOut: err.name === 'AbortError' };\n }\n}\n\nasync function fetchEndpointHealth(\n url: string,\n timeoutMs = 5000,\n isExpectedStatus: (status: number) => boolean = (s) => s === 200,\n redirect: 'follow' | 'manual' | 'error' = 'follow',\n): Promise<BaseHealthResult> {\n // Total attempts = 1 initial + RETRY_BACKOFFS_MS.length retries. Both\n // unexpected HTTP statuses (4xx/5xx) and network errors trigger a retry:\n // transient 5xx and Cloudflare edge blips often recover on a retry, and\n // even nominally deterministic 4xx can be transient (CDN propagation\n // lag after a release, token rotation, rate-limit window resets). GETs\n // are idempotent so retrying is safe.\n //\n // Final status if every attempt fails:\n // - At least one HTTP response observed → `Down` (server-side evidence)\n // - Only network errors observed → `NoConnection`\n let lastHttpStatus: number | null = null;\n let lastError = 'Unknown error';\n let attempts = 0;\n\n for (let i = 0; i <= RETRY_BACKOFFS_MS.length; i++) {\n if (i > 0) {\n const wait = RETRY_BACKOFFS_MS[i - 1];\n logToFile(\n `[health-checks] retry ${i}/${RETRY_BACKOFFS_MS.length} for ${url} in ${wait}ms (last: ${lastError})`,\n );\n await new Promise((r) => setTimeout(r, wait));\n }\n attempts++;\n\n const outcome = await attemptFetch(url, timeoutMs, redirect);\n\n if (outcome.kind === 'response') {\n const res = outcome.res;\n if (isExpectedStatus(res.status)) {\n const result: BaseHealthResult = {\n status: ServiceHealthStatus.Healthy,\n rawIndicator:\n attempts > 1\n ? `HTTP ${res.status} (attempts=${attempts})`\n : `HTTP ${res.status}`,\n };\n logToFile(\n `[health-checks] GET ${url} -> ${result.status}` +\n ` (${result.rawIndicator})`,\n );\n return result;\n }\n lastHttpStatus = res.status;\n lastError = `HTTP ${res.status}`;\n continue;\n }\n\n lastError = outcome.timedOut\n ? `Request timed out after ${timeoutMs}ms`\n : outcome.error.message;\n }\n\n const result =\n lastHttpStatus !== null\n ? downResult(`HTTP ${lastHttpStatus} (attempts=${attempts})`)\n : noConnectionResult(lastError, attempts);\n logToFile(\n `[health-checks] GET ${url} -> ${result.status}` +\n ` (attempts=${attempts}, ${result.error})`,\n );\n return result;\n}\n\nexport const checkLlmGatewayHealth = (): Promise<BaseHealthResult> =>\n fetchEndpointHealth('https://gateway.us.posthog.com/_liveness');\n\nexport const checkMcpHealth = (): Promise<BaseHealthResult> =>\n fetchEndpointHealth(\n 'https://mcp.posthog.com/',\n 5000,\n // 2xx-3xx counts as up (redirect to docs)\n (s) => s >= 200 && s < 400,\n 'manual',\n );\n\nexport const checkGithubReleasesHealth = (): Promise<BaseHealthResult> =>\n fetchEndpointHealth(`${REMOTE_SKILLS_BASE_URL}/skill-menu.json`);\n","import {\n ServiceHealthStatus,\n type AllServicesHealth,\n type BaseHealthResult,\n type ComponentHealthResult,\n type HealthCheckKey,\n} from './types';\nimport {\n checkAnthropicHealth,\n checkGithubHealth,\n checkNpmOverallHealth,\n checkNpmComponentHealth,\n checkCloudflareOverallHealth,\n checkCloudflareComponentHealth,\n} from './statuspage';\nimport {\n checkPosthogOverallHealth,\n checkPosthogComponentHealth,\n} from './incidentio';\nimport {\n checkLlmGatewayHealth,\n checkMcpHealth,\n checkGithubReleasesHealth,\n} from './endpoints';\nimport { logToFile } from '@utils/debug';\n\n// ---------------------------------------------------------------------------\n// Service labels (used in human-readable reason strings)\n// ---------------------------------------------------------------------------\n\nexport const SERVICE_LABELS: Record<HealthCheckKey, string> = {\n anthropic: 'Anthropic',\n posthogOverall: 'PostHog',\n posthogComponents: 'PostHog (components)',\n github: 'GitHub',\n npmOverall: 'npm',\n npmComponents: 'npm (components)',\n cloudflareOverall: 'Cloudflare',\n cloudflareComponents: 'Cloudflare (components)',\n llmGateway: 'LLM Gateway',\n mcp: 'MCP',\n githubReleases: 'GitHub Releases',\n};\n\n// ---------------------------------------------------------------------------\n// Readiness config\n// ---------------------------------------------------------------------------\n\nexport interface WizardReadinessConfig {\n /** Services where status=Down blocks the run (readiness=No). */\n downBlocksRun: HealthCheckKey[];\n /** Services where status=Degraded (or worse) blocks the run (readiness=No). */\n degradedBlocksRun?: HealthCheckKey[];\n}\n\n/**\n * See README section \"Health checks\" for the full rationale.\n * Adjust these arrays to change what blocks a wizard run.\n */\nexport const DEFAULT_WIZARD_READINESS_CONFIG: WizardReadinessConfig = {\n downBlocksRun: [\n 'anthropic',\n 'npmOverall',\n 'llmGateway',\n 'mcp',\n 'githubReleases',\n ],\n degradedBlocksRun: ['anthropic'],\n};\n\n/**\n * Reduced readiness config for --signup provisioning flows.\n *\n * Provisioning only needs PostHog and the LLM Gateway - it doesn't\n * use Anthropic directly, npm, GitHub Releases, or MCP.\n */\nexport const SIGNUP_WIZARD_READINESS_CONFIG: WizardReadinessConfig = {\n downBlocksRun: ['posthogOverall', 'llmGateway'],\n};\n\n// ---------------------------------------------------------------------------\n// Aggregate check\n// ---------------------------------------------------------------------------\n\nexport async function checkAllExternalServices(): Promise<AllServicesHealth> {\n const [\n anthropic,\n posthogOverall,\n posthogComponents,\n github,\n npmOverall,\n npmComponents,\n cloudflareOverall,\n cloudflareComponents,\n llmGateway,\n mcp,\n githubReleases,\n ] = await Promise.all([\n checkAnthropicHealth(),\n checkPosthogOverallHealth(),\n checkPosthogComponentHealth(),\n checkGithubHealth(),\n checkNpmOverallHealth(),\n checkNpmComponentHealth(),\n checkCloudflareOverallHealth(),\n checkCloudflareComponentHealth(),\n checkLlmGatewayHealth(),\n checkMcpHealth(),\n checkGithubReleasesHealth(),\n ]);\n\n const health: AllServicesHealth = {\n anthropic,\n posthogOverall,\n posthogComponents,\n github,\n npmOverall,\n npmComponents,\n cloudflareOverall,\n cloudflareComponents,\n llmGateway,\n mcp,\n githubReleases,\n };\n return reconcilePosthogReachability(health);\n}\n\n/**\n * When a PostHog-owned endpoint probe returns `NoConnection`, decide\n * whether it's a real outage or a likely-local issue by checking the\n * official status page (`posthogstatus.com`):\n *\n * - Status page says PostHog is `Down` / `Degraded` → upgrade\n * llmGateway / mcp to `Down`. The status page corroborates.\n * - Status page is `Healthy` → keep `NoConnection`. The status page\n * contradicts; this is probably the user's network.\n * - Status page is also `NoConnection` → keep `NoConnection`. User\n * can't reach two independent PostHog properties; almost\n * certainly their network. (This case relies on incidentio.ts\n * correctly emitting `NoConnection` for fetch failures rather\n * than the previous `Degraded`, which used to silently flip the\n * reconciliation into a false positive.)\n *\n * Why `Degraded` corroborates: a `Degraded` reading here only fires\n * when incident.io's API parsed successfully and reported a real\n * `partial_outage` or `degraded_performance` for some component. That's\n * PostHog acknowledging an issue, even if narrower than a full outage.\n * If our gateway probe is also failing, those two signals together\n * justify pointing at PostHog rather than the user.\n *\n * A narrower variant — only corroborate when the affected component is\n * gateway-related (LLM, US/EU Cloud, app) — would be more precise. We\n * have the data in `posthogComponents` but don't use it here. If the\n * analytics show false positives concentrated in this case, it's a\n * cheap follow-up.\n *\n * Mutates a copy of `health` and returns it.\n */\nexport function reconcilePosthogReachability(\n health: AllServicesHealth,\n): AllServicesHealth {\n const posthogStatus = health.posthogOverall.status;\n const corroboratesOutage =\n posthogStatus === ServiceHealthStatus.Down ||\n posthogStatus === ServiceHealthStatus.Degraded;\n\n if (!corroboratesOutage) return health;\n\n const upgrade = (r: BaseHealthResult): BaseHealthResult =>\n r.status === ServiceHealthStatus.NoConnection\n ? {\n ...r,\n status: ServiceHealthStatus.Down,\n error: r.error\n ? `${r.error} (corroborated by status page)`\n : 'corroborated by status page',\n }\n : r;\n\n return {\n ...health,\n llmGateway: upgrade(health.llmGateway),\n mcp: upgrade(health.mcp),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Wizard readiness evaluation\n// ---------------------------------------------------------------------------\n\nexport enum WizardReadiness {\n Yes = 'yes',\n No = 'no',\n YesWithWarnings = 'yes_with_warnings',\n}\n\nexport interface WizardReadinessResult {\n decision: WizardReadiness;\n health: AllServicesHealth;\n reasons: string[];\n}\n\nfunction describeResult(label: string, h: BaseHealthResult): string {\n const parts = [`${label}: ${h.status}`];\n if (h.rawIndicator) parts.push(`indicator=${h.rawIndicator}`);\n if (h.error) parts.push(h.error);\n return parts.join(' — ');\n}\n\nconst MAX_COMPONENT_NAMES = 8;\n\nfunction describeComponents(label: string, h: ComponentHealthResult): string {\n const affected = h.degradedOrDownComponents;\n if (!affected || affected.length === 0)\n return `${label} components: all operational`;\n const shown = affected\n .slice(0, MAX_COMPONENT_NAMES)\n .map((c) => `${c.name} (${c.status})`);\n const suffix =\n affected.length > MAX_COMPONENT_NAMES\n ? `, +${affected.length - MAX_COMPONENT_NAMES} more`\n : '';\n return `${label} components impacted: ${shown.join(', ')}${suffix}`;\n}\n\n// Each probe can take up to one base timeout + two retries with the\n// 500ms / 2000ms backoffs in endpoints.ts (worst case ~17.5s for a\n// network failure that exhausts retries). Probes run in parallel so\n// the aggregate ceiling is one probe, not the sum.\nconst READINESS_TIMEOUT_MS = 20_000;\n\nexport async function evaluateWizardReadiness(\n config: WizardReadinessConfig = DEFAULT_WIZARD_READINESS_CONFIG,\n): Promise<WizardReadinessResult> {\n try {\n const health = await Promise.race([\n checkAllExternalServices(),\n new Promise<AllServicesHealth>((resolve) =>\n setTimeout(\n () => resolve(allUnknown('Health check timed out')),\n READINESS_TIMEOUT_MS,\n ),\n ),\n ]);\n\n const reasons: string[] = [];\n\n for (const key of Object.keys(health) as HealthCheckKey[]) {\n const result = health[key];\n const label = SERVICE_LABELS[key];\n\n reasons.push(describeResult(label, result));\n\n if ('degradedOrDownComponents' in result) {\n reasons.push(describeComponents(label, result));\n }\n }\n\n const blockingKeys = getBlockingServiceKeys(health, config);\n if (blockingKeys.length > 0) {\n const blockingDetails = blockingKeys.map((key) => {\n const h = health[key];\n return `${key} (${h.status}${h.error ? ` — ${h.error}` : ''})`;\n });\n logToFile(`[health-checks] blocked by: ${blockingDetails.join(', ')}`);\n return { decision: WizardReadiness.No, health, reasons };\n }\n\n const hasWarnings = Object.values(health).some(\n (h) => h.status !== ServiceHealthStatus.Healthy,\n );\n\n if (hasWarnings) {\n return { decision: WizardReadiness.YesWithWarnings, health, reasons };\n }\n\n return { decision: WizardReadiness.Yes, health, reasons };\n } catch (err) {\n logToFile(\n `[health-checks] error: ${err instanceof Error ? err.message : err}`,\n );\n // Health checks must never block the wizard run\n return {\n decision: WizardReadiness.Yes,\n health: allUnknown('Unexpected error'),\n reasons: ['Health check failed unexpectedly — proceeding anyway'],\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Blocking service detection\n// ---------------------------------------------------------------------------\n\n/** Keys that are component-level detail, not top-level services. */\nconst COMPONENT_KEYS: HealthCheckKey[] = [\n 'posthogComponents',\n 'npmComponents',\n 'cloudflareComponents',\n];\n\n/**\n * Get the keys of services that would block a wizard run per the given config.\n *\n * `NoConnection` blocks the same services as `Down` — the wizard genuinely\n * can't continue if it can't reach the gateway. The screen shows softer\n * framing in that case (HealthCheckScreen) so we don't falsely accuse\n * PostHog of an outage when the user's network is the likely cause.\n */\nexport function getBlockingServiceKeys(\n health: AllServicesHealth,\n config: WizardReadinessConfig = DEFAULT_WIZARD_READINESS_CONFIG,\n): HealthCheckKey[] {\n return (Object.keys(health) as HealthCheckKey[]).filter((key) => {\n if (COMPONENT_KEYS.includes(key)) return false;\n const result = health[key];\n if (\n config.downBlocksRun.includes(key) &&\n (result.status === ServiceHealthStatus.Down ||\n result.status === ServiceHealthStatus.NoConnection)\n ) {\n return true;\n }\n if (\n (config.degradedBlocksRun ?? []).includes(key) &&\n result.status !== ServiceHealthStatus.Healthy\n ) {\n return true;\n }\n return false;\n });\n}\n\n/** Build an AllServicesHealth where every service is Degraded with the given error. */\nfunction allUnknown(error: string): AllServicesHealth {\n const base: BaseHealthResult = {\n status: ServiceHealthStatus.Degraded,\n error,\n };\n return {\n anthropic: base,\n posthogOverall: base,\n posthogComponents: { ...base },\n github: base,\n npmOverall: base,\n npmComponents: { ...base },\n cloudflareOverall: base,\n cloudflareComponents: { ...base },\n llmGateway: base,\n mcp: base,\n githubReleases: base,\n };\n}\n","/* eslint-disable no-console */\n/**\n * LoggingUI — Logging-only implementation for CI mode.\n * No prompts, no TUI, no interactivity. Just console output.\n */\n\nimport {\n TaskStatus,\n type WizardUI,\n type SpinnerHandle,\n type AuthErrorDetail,\n} from './wizard-ui';\nimport type { SettingsConflict } from '@lib/agent/claude-settings';\nimport type { ApiUser } from '@lib/api';\nimport { OAUTH_TIMEOUT_MS } from '@lib/constants';\nimport {\n type WizardReadinessResult,\n getBlockingServiceKeys,\n SERVICE_LABELS,\n} from '@lib/health-checks/readiness';\nimport type {\n AskAnswers,\n OutroData,\n PendingQuestion,\n} from '@lib/wizard-session';\n\nexport class LoggingUI implements WizardUI {\n intro(message: string): void {\n console.log(`┌ ${message}`);\n }\n\n outro(message: string): void {\n console.log(`└ ${message}`);\n }\n\n outroError(data: OutroData): void {\n console.log(`✖ ${data.message ?? 'Wizard aborted'}`);\n if (data.body) console.log(`│ ${data.body}`);\n if (data.docsUrl) console.log(`│ Docs: ${data.docsUrl}`);\n }\n\n waitForOutroDismissed(): Promise<void> {\n return Promise.resolve();\n }\n\n waitForAiOptIn(): Promise<void> {\n // Non-TUI runs are CI runs, which auto-consent to AI usage.\n return Promise.resolve();\n }\n\n cancel(message: string): void {\n console.log(`■ ${message}`);\n }\n\n log = {\n info(message: string): void {\n console.log(`│ ${message}`);\n },\n warn(message: string): void {\n console.log(`▲ ${message}`);\n },\n error(message: string): void {\n console.log(`✖ ${message}`);\n },\n success(message: string): void {\n console.log(`✔ ${message}`);\n },\n step(message: string): void {\n console.log(`◇ ${message}`);\n },\n };\n\n note(message: string): void {\n console.log(`│ ${message}`);\n }\n\n spinner(): SpinnerHandle {\n return {\n start(message?: string) {\n if (message) console.log(`◌ ${message}`);\n },\n stop(message?: string) {\n if (message) console.log(`● ${message}`);\n },\n message(msg?: string) {\n if (msg) console.log(`◌ ${msg}`);\n },\n };\n }\n\n pushStatus(message: string): void {\n console.log(`◇ ${message}`);\n }\n\n setDetectedFramework(label: string): void {\n console.log(`✔ Framework: ${label}`);\n }\n\n onEnterScreen(_screen: string, _fn: () => void): void {\n // No screen transitions in CI\n }\n\n setLoginUrl(url: string | null): void {\n if (url) {\n console.log(\n `│ If the browser didn't open automatically, use this link:`,\n );\n console.log(`│ ${url}`);\n }\n }\n\n setAuthorizeUrl(_url: string | null): void {\n // Manual-paste modal is TUI-only; CI/non-interactive runs don't use it.\n }\n\n showBlockingOutage(result: WizardReadinessResult): Promise<void> {\n console.log(`▲ Service health issues detected.`);\n const blockingKeys = getBlockingServiceKeys(result.health);\n if (blockingKeys.length > 0) {\n console.log(`│`);\n console.log(`│ Blocking services:`);\n for (const key of blockingKeys) {\n const status = result.health[key].status;\n const error = result.health[key].error;\n const label = SERVICE_LABELS[key];\n const detail = error ? ` — ${error}` : '';\n console.log(`│ ✖ ${label}: ${status}${detail}`);\n }\n console.log(`│`);\n }\n for (const reason of result.reasons) {\n console.log(`│ ${reason}`);\n }\n console.log(\n `│ Continuing anyway — health checks are advisory in non-interactive runs.`,\n );\n return Promise.resolve();\n }\n\n setReadinessWarnings(result: WizardReadinessResult): void {\n console.log(`▲ Service health warnings detected.`);\n for (const reason of result.reasons) {\n console.log(`│ ${reason}`);\n }\n }\n\n showPortConflict(_processInfo: {\n command: string;\n pid: string;\n port: number;\n user: string;\n }): Promise<void> {\n return Promise.resolve();\n }\n\n waitForManualAuthCode(): Promise<string> {\n // No interactive prompt in CI/logging mode — never resolves. CI bypasses\n // OAuth entirely, so this is only here to satisfy the interface.\n return new Promise<string>(() => {\n /* intentionally never resolves */\n });\n }\n\n showSettingsOverride(\n _conflicts: SettingsConflict[],\n _backupAndFix: () => boolean,\n ): Promise<void> {\n return Promise.resolve();\n }\n\n requestQuestion(_question: PendingQuestion): Promise<AskAnswers> {\n return Promise.reject(\n new Error(\n 'wizard_ask is not available in CI / non-interactive mode. ' +\n 'Re-run the wizard without --ci to answer interactively.',\n ),\n );\n }\n\n showAuthError(detail?: AuthErrorDetail): void {\n console.log(`✖ Authentication failed (401)`);\n if (detail?.hasSettingsConflict) {\n console.log(\n `│ Claude Code auth is conflicting with the wizard. Please try again after logging out:`,\n );\n console.log(`│ claude auth logout`);\n } else {\n console.log(\n `│ The PostHog LLM Gateway rejected the API key. Common causes:`,\n );\n console.log(\n `│ - Wrong key type: pass a personal API key (phx_xxx). pha_ is an OAuth access token, phc_ is a project key.`,\n );\n console.log(\n `│ - Missing scope: the personal API key needs the \"llm_gateway:read\" scope.`,\n );\n console.log(`│ - Expired or revoked key.`);\n console.log(\n `│ - Region mismatch: --region must match the region the key was issued in (us vs eu).`,\n );\n }\n if (detail?.logFilePath) {\n console.log(`│ Verbose log: ${detail.logFilePath}`);\n }\n }\n\n showSessionTimeout(): void {\n const minutes = Math.round(OAUTH_TIMEOUT_MS / 60_000);\n console.log(\n `✖ Login timed out. The OAuth link timed out after ${minutes} minutes.`,\n );\n console.log(`│ Re-run the wizard to get a fresh link and try again.`);\n }\n\n startRun(): void {\n // No-op in CI mode\n }\n\n setCredentials(_credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n }): void {\n // No-op in CI mode — credentials are handled directly\n }\n\n setRoleAtOrganization(_role: string | null): void {\n // No-op in CI mode — there's no TUI to render role-tailored prompts\n }\n\n setApiUser(_user: ApiUser | null): void {\n // No-op in CI mode — there's no TUI to read account context from\n // the session.\n }\n\n private lastTodoLine = '';\n\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void {\n const completed = todos.filter(\n (t) => t.status === TaskStatus.Completed,\n ).length;\n const active = todos.filter((t) => t.status === TaskStatus.InProgress);\n if (active.length === 0) return;\n const labels = active.map((t) => t.activeForm || t.content).join(' · ');\n const line = `◌ [${completed}/${todos.length}] ${labels}`;\n // The queue re-renders on every transition; print only what changed.\n if (line === this.lastTodoLine) return;\n this.lastTodoLine = line;\n console.log(line);\n }\n\n setEventPlan(_events: Array<{ name: string; description: string }>): void {\n // No-op in CI mode\n }\n\n setDashboardUrl(_url: string): void {\n // No-op in CI mode\n }\n\n setStage(_stage: string): void {\n // No-op in CI mode\n }\n\n setNotebookUrl(_url: string): void {\n // No-op in CI mode\n }\n\n setOutroData(_data: import('@lib/wizard-session').OutroData): void {\n // No-op in CI mode\n }\n\n setFrameworkContext(_key: string, _value: unknown): void {\n // No-op in CI mode\n }\n\n getFrameworkContext(_key: string): unknown {\n // No frameworkContext in CI mode\n return undefined;\n }\n\n waitForGate(_stepId: string): Promise<void> {\n // No interactive gates in CI mode\n return Promise.resolve();\n }\n}\n","/**\n * UI singleton — provides getUI() and setUI() for the wizard.\n * Default: LoggingUI. Swap to InkUI at startup for TUI mode.\n */\n\nimport type { WizardUI } from './wizard-ui';\nimport { LoggingUI } from './logging-ui';\n\nlet currentUI: WizardUI = new LoggingUI();\n\nexport function getUI(): WizardUI {\n return currentUI;\n}\n\nexport function setUI(ui: WizardUI): void {\n currentUI = ui;\n}\n\nexport type { WizardUI, SpinnerHandle } from './wizard-ui';\n","import { tmpdir } from 'node:os';\nimport { join, sep } from 'node:path';\n\n// /tmp is stable and discoverable on macOS/Linux; Windows needs os.tmpdir()\nconst TMP = process.platform === 'win32' ? tmpdir() : '/tmp';\n\nexport const WIZARD_LOG_FILE = join(TMP, 'posthog-wizard.log');\nexport const WIZARD_BENCHMARK_FILE = join(TMP, 'posthog-wizard-benchmark.json');\nexport const WIZARD_YARA_REPORT_FILE = join(\n TMP,\n 'posthog-wizard-yara-report.json',\n);\n/** Temp path for a skill download zip. */\nexport function skillTmpPath(skillId: string): string {\n return join(TMP, `posthog-skill-${skillId}.zip`);\n}\n\n/**\n * Strip an absolute installDir prefix off a project file path so the UI\n * renders `index.js:12` instead of `/Users/.../index.js:12`. Defends\n * against false matches like `/Users/foo` ⊂ `/Users/foobar/x.js` by\n * normalizing to a trailing path separator before the prefix check.\n */\nexport function relativeToInstallDir(file: string, installDir: string): string {\n const prefix = installDir.endsWith(sep) ? installDir : installDir + sep;\n return file.startsWith(prefix) ? file.slice(prefix.length) : file;\n}\n","import { appendFileSync } from 'fs';\nimport path from 'path';\nimport { inspect } from 'node:util';\nimport { getUI } from '@ui';\nimport { runtimeEnv } from '@env';\nimport { WIZARD_LOG_FILE } from './paths';\n\nlet logFilePath = WIZARD_LOG_FILE;\nlet fileLoggingEnabled = true;\nlet consoleLoggingEnabled = false;\n\nfunction stringify(value: unknown): string {\n if (typeof value === 'string') return value;\n if (value instanceof Error) return value.stack ?? String(value);\n try {\n // JSON.stringify throws on cycles and skips some values — fall back to\n // inspect so a crash log line is never dropped.\n return JSON.stringify(value, null, 2) ?? inspect(value, { depth: 3 });\n } catch {\n return inspect(value, { depth: 3 });\n }\n}\n\nfunction renderLine(args: readonly unknown[]): string {\n return args.map(stringify).join(' ');\n}\n\nexport function getLogFilePath(): string {\n return logFilePath;\n}\n\nexport function configureLogFile(opts: {\n path?: string;\n enabled?: boolean;\n}): void {\n if (opts.path !== undefined) logFilePath = opts.path;\n if (opts.enabled !== undefined) fileLoggingEnabled = opts.enabled;\n}\n\nexport function configureLogFileFromEnvironment(): void {\n const dir = runtimeEnv('POSTHOG_WIZARD_LOG_DIR');\n if (dir) {\n configureLogFile({ path: path.join(dir, 'posthog-wizard.log') });\n }\n}\n\nexport function initLogFile(): void {\n if (!fileLoggingEnabled) return;\n try {\n const divider = '='.repeat(60);\n appendFileSync(\n logFilePath,\n `\\n${divider}\\nPostHog Wizard Run: ${new Date().toISOString()}\\n${divider}\\n`,\n );\n } catch {\n // Logging must never crash the wizard.\n }\n}\n\nexport function logToFile(...args: unknown[]): void {\n if (!fileLoggingEnabled) return;\n try {\n const ts = new Date().toISOString();\n appendFileSync(logFilePath, `[${ts}] ${renderLine(args)}\\n`);\n } catch {\n // Logging must never crash the wizard.\n }\n}\n\nexport function debug(...args: unknown[]): void {\n if (!consoleLoggingEnabled) return;\n getUI().log.info(renderLine(args));\n}\n\nexport function enableDebugLogs(): void {\n consoleLoggingEnabled = true;\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as configureLogFileFromEnvironment, s as logToFile } from "./debug-
|
|
1
|
+
import { n as configureLogFileFromEnvironment, s as logToFile } from "./debug-BGMe1wP6.js";
|
|
2
2
|
export { configureLogFileFromEnvironment, logToFile };
|
|
@@ -257,4 +257,4 @@ const getDefaultServerConfig = (apiKey, selectedFeatures, local) => {
|
|
|
257
257
|
//#endregion
|
|
258
258
|
export { getNativeHTTPServerConfig as a, getDefaultServerConfig as i, AVAILABLE_FEATURES as n, isAllFeaturesSelected as o, buildMCPUrl as r, ALL_FEATURE_VALUES as t };
|
|
259
259
|
|
|
260
|
-
//# sourceMappingURL=defaults-
|
|
260
|
+
//# sourceMappingURL=defaults-DII5CAog.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaults-BNWIWzjc.js","names":["z"],"sources":["../src/steps/add-mcp-server-to-clients/defaults.ts"],"sourcesContent":["import z from 'zod';\n\nexport const DefaultMCPClientConfig = z\n .object({\n mcpServers: z.record(\n z.string(),\n z.union([\n z.object({\n command: z.string().optional(),\n args: z.array(z.string()).optional(),\n env: z.record(z.string(), z.string()).optional(),\n }),\n z.object({\n url: z.string(),\n headers: z.record(z.string(), z.string()).optional(),\n }),\n ]),\n ),\n })\n .passthrough();\n\nexport const AVAILABLE_FEATURES = {\n 'Data & Analytics': [\n {\n value: 'dashboards',\n label: 'Dashboards',\n hint: 'Dashboard creation and management',\n },\n {\n value: 'insights',\n label: 'Insights',\n hint: 'Analytics insights',\n },\n {\n value: 'product_analytics',\n label: 'Product Analytics',\n hint: 'Insight CRUD management',\n },\n {\n value: 'experiments',\n label: 'Experiments',\n hint: 'A/B testing experiments',\n },\n {\n value: 'surveys',\n label: 'Surveys',\n hint: 'Survey management',\n },\n {\n value: 'annotations',\n label: 'Annotations',\n hint: 'Annotation management',\n },\n {\n value: 'replay',\n label: 'Session Replay',\n hint: 'Session recording management',\n },\n {\n value: 'sql',\n label: 'SQL',\n hint: 'SQL query execution',\n },\n {\n value: 'web_analytics',\n label: 'Web Analytics',\n hint: 'Web analytics queries and digests',\n },\n {\n value: 'customer_analytics',\n label: 'Usage metrics',\n hint: 'Customer usage metric tracking',\n },\n {\n value: 'signals',\n label: 'Signals',\n hint: 'Signal reports and source configs',\n },\n ],\n 'AI Engineering': [\n {\n value: 'llm_analytics',\n label: 'LLM Analytics',\n hint: 'LLM usage and cost tracking',\n },\n ],\n 'Development Tools': [\n {\n value: 'error_tracking',\n label: 'Error Tracking',\n hint: 'Error monitoring and debugging',\n },\n {\n value: 'logs',\n label: 'Logs',\n hint: 'Log querying',\n },\n {\n value: 'flags',\n label: 'Feature Flags',\n hint: 'Feature flag management',\n },\n {\n value: 'early_access_features',\n label: 'Early Access Features',\n hint: 'Early access feature management',\n },\n {\n value: 'cohorts',\n label: 'Cohorts',\n hint: 'Cohort management',\n },\n {\n value: 'sdk_doctor',\n label: 'SDK Doctor',\n hint: 'SDK health diagnostics',\n },\n {\n value: 'tracing',\n label: 'APM Tracing',\n hint: 'Distributed trace and span queries',\n },\n ],\n 'Data Management': [\n {\n value: 'events',\n label: 'Events',\n hint: 'Event and property definitions',\n },\n {\n value: 'persons',\n label: 'Persons',\n hint: 'Person and group management',\n },\n {\n value: 'actions',\n label: 'Actions',\n hint: 'Action definitions',\n },\n {\n value: 'data_warehouse',\n label: 'Data Warehouse',\n hint: 'Data warehouse management',\n },\n {\n value: 'endpoints',\n label: 'Endpoints',\n hint: 'Data warehouse endpoint management',\n },\n {\n value: 'data_schema',\n label: 'Data Schema',\n hint: 'Data schema exploration',\n },\n {\n value: 'batch_exports',\n label: 'Batch Exports',\n hint: 'Scheduled data exports',\n },\n ],\n 'CDP & Automation': [\n {\n value: 'hog_functions',\n label: 'Hog Functions',\n hint: 'CDP function management',\n },\n {\n value: 'hog_function_templates',\n label: 'Hog Function Templates',\n hint: 'CDP function template browsing',\n },\n {\n value: 'workflows',\n label: 'Workflows',\n hint: 'Workflow management',\n },\n ],\n 'Platform & Management': [\n {\n value: 'workspace',\n label: 'Workspace',\n hint: 'Organization and project management',\n },\n {\n value: 'docs',\n label: 'Documentation',\n hint: 'PostHog documentation search',\n },\n {\n value: 'notebooks',\n label: 'Notebooks',\n hint: 'Notebook management',\n },\n {\n value: 'alerts',\n label: 'Alerts',\n hint: 'Alert management',\n },\n {\n value: 'platform_features',\n label: 'Platform Features',\n hint: 'Activity logs, approvals, comments, and roles',\n },\n {\n value: 'integrations',\n label: 'Integrations',\n hint: 'Connected integration management',\n },\n {\n value: 'conversations',\n label: 'Conversations',\n hint: 'Support ticket management',\n },\n {\n value: 'core',\n label: 'Subscriptions',\n hint: 'Scheduled insight and dashboard deliveries',\n },\n {\n value: 'search',\n label: 'Search',\n hint: 'Entity search across the project',\n },\n {\n value: 'reverse_proxy',\n label: 'Reverse Proxy',\n hint: 'Reverse proxy record management',\n },\n {\n value: 'debug',\n label: 'Debug',\n hint: 'Debug and diagnostic tools',\n },\n ],\n};\n\nexport const ALL_FEATURE_VALUES = Object.values(AVAILABLE_FEATURES)\n .flat()\n .map((feature) => feature.value);\n\nexport const isAllFeaturesSelected = (features: string[]): boolean =>\n features.length === ALL_FEATURE_VALUES.length &&\n ALL_FEATURE_VALUES.every((feature) => features.includes(feature));\n\nexport const buildMCPUrl = (selectedFeatures?: string[], local?: boolean) => {\n const host = local ? 'http://localhost:8787' : 'https://mcp.posthog.com';\n const baseUrl = `${host}/mcp`;\n\n const params: string[] = [];\n\n // Add features param if not all features selected\n if (\n selectedFeatures &&\n selectedFeatures.length > 0 &&\n !isAllFeaturesSelected(selectedFeatures)\n ) {\n params.push(`features=${selectedFeatures.join(',')}`);\n }\n\n return params.length > 0 ? `${baseUrl}?${params.join('&')}` : baseUrl;\n};\n\nexport const getNativeHTTPServerConfig = (\n apiKey: string | undefined,\n selectedFeatures?: string[],\n local?: boolean,\n) => {\n const config: Record<string, unknown> = {\n url: buildMCPUrl(selectedFeatures, local),\n };\n\n // Only add auth header if API key is provided (not OAuth mode)\n if (apiKey) {\n config.headers = {\n Authorization: `Bearer ${apiKey}`,\n };\n }\n\n return config;\n};\n\nexport const getDefaultServerConfig = (\n apiKey: string | undefined,\n selectedFeatures?: string[],\n local?: boolean,\n) => {\n const urlWithFeatures = buildMCPUrl(selectedFeatures, local);\n\n // OAuth mode: no auth header, let MCP handle OAuth\n if (!apiKey) {\n return {\n command: 'npx',\n args: ['-y', 'mcp-remote@latest', urlWithFeatures],\n };\n }\n\n // API key mode: include auth header\n return {\n command: 'npx',\n args: [\n '-y',\n 'mcp-remote@latest',\n urlWithFeatures,\n '--header',\n `Authorization:\\${POSTHOG_AUTH_HEADER}`,\n ],\n env: {\n POSTHOG_AUTH_HEADER: `Bearer ${apiKey}`,\n },\n };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"defaults-DII5CAog.js","names":["z"],"sources":["../src/steps/add-mcp-server-to-clients/defaults.ts"],"sourcesContent":["import z from 'zod';\n\nexport const DefaultMCPClientConfig = z\n .object({\n mcpServers: z.record(\n z.string(),\n z.union([\n z.object({\n command: z.string().optional(),\n args: z.array(z.string()).optional(),\n env: z.record(z.string(), z.string()).optional(),\n }),\n z.object({\n url: z.string(),\n headers: z.record(z.string(), z.string()).optional(),\n }),\n ]),\n ),\n })\n .passthrough();\n\nexport const AVAILABLE_FEATURES = {\n 'Data & Analytics': [\n {\n value: 'dashboards',\n label: 'Dashboards',\n hint: 'Dashboard creation and management',\n },\n {\n value: 'insights',\n label: 'Insights',\n hint: 'Analytics insights',\n },\n {\n value: 'product_analytics',\n label: 'Product Analytics',\n hint: 'Insight CRUD management',\n },\n {\n value: 'experiments',\n label: 'Experiments',\n hint: 'A/B testing experiments',\n },\n {\n value: 'surveys',\n label: 'Surveys',\n hint: 'Survey management',\n },\n {\n value: 'annotations',\n label: 'Annotations',\n hint: 'Annotation management',\n },\n {\n value: 'replay',\n label: 'Session Replay',\n hint: 'Session recording management',\n },\n {\n value: 'sql',\n label: 'SQL',\n hint: 'SQL query execution',\n },\n {\n value: 'web_analytics',\n label: 'Web Analytics',\n hint: 'Web analytics queries and digests',\n },\n {\n value: 'customer_analytics',\n label: 'Usage metrics',\n hint: 'Customer usage metric tracking',\n },\n {\n value: 'signals',\n label: 'Signals',\n hint: 'Signal reports and source configs',\n },\n ],\n 'AI Engineering': [\n {\n value: 'llm_analytics',\n label: 'LLM Analytics',\n hint: 'LLM usage and cost tracking',\n },\n ],\n 'Development Tools': [\n {\n value: 'error_tracking',\n label: 'Error Tracking',\n hint: 'Error monitoring and debugging',\n },\n {\n value: 'logs',\n label: 'Logs',\n hint: 'Log querying',\n },\n {\n value: 'flags',\n label: 'Feature Flags',\n hint: 'Feature flag management',\n },\n {\n value: 'early_access_features',\n label: 'Early Access Features',\n hint: 'Early access feature management',\n },\n {\n value: 'cohorts',\n label: 'Cohorts',\n hint: 'Cohort management',\n },\n {\n value: 'sdk_doctor',\n label: 'SDK Doctor',\n hint: 'SDK health diagnostics',\n },\n {\n value: 'tracing',\n label: 'APM Tracing',\n hint: 'Distributed trace and span queries',\n },\n ],\n 'Data Management': [\n {\n value: 'events',\n label: 'Events',\n hint: 'Event and property definitions',\n },\n {\n value: 'persons',\n label: 'Persons',\n hint: 'Person and group management',\n },\n {\n value: 'actions',\n label: 'Actions',\n hint: 'Action definitions',\n },\n {\n value: 'data_warehouse',\n label: 'Data Warehouse',\n hint: 'Data warehouse management',\n },\n {\n value: 'endpoints',\n label: 'Endpoints',\n hint: 'Data warehouse endpoint management',\n },\n {\n value: 'data_schema',\n label: 'Data Schema',\n hint: 'Data schema exploration',\n },\n {\n value: 'batch_exports',\n label: 'Batch Exports',\n hint: 'Scheduled data exports',\n },\n ],\n 'CDP & Automation': [\n {\n value: 'hog_functions',\n label: 'Hog Functions',\n hint: 'CDP function management',\n },\n {\n value: 'hog_function_templates',\n label: 'Hog Function Templates',\n hint: 'CDP function template browsing',\n },\n {\n value: 'workflows',\n label: 'Workflows',\n hint: 'Workflow management',\n },\n ],\n 'Platform & Management': [\n {\n value: 'workspace',\n label: 'Workspace',\n hint: 'Organization and project management',\n },\n {\n value: 'docs',\n label: 'Documentation',\n hint: 'PostHog documentation search',\n },\n {\n value: 'notebooks',\n label: 'Notebooks',\n hint: 'Notebook management',\n },\n {\n value: 'alerts',\n label: 'Alerts',\n hint: 'Alert management',\n },\n {\n value: 'platform_features',\n label: 'Platform Features',\n hint: 'Activity logs, approvals, comments, and roles',\n },\n {\n value: 'integrations',\n label: 'Integrations',\n hint: 'Connected integration management',\n },\n {\n value: 'conversations',\n label: 'Conversations',\n hint: 'Support ticket management',\n },\n {\n value: 'core',\n label: 'Subscriptions',\n hint: 'Scheduled insight and dashboard deliveries',\n },\n {\n value: 'search',\n label: 'Search',\n hint: 'Entity search across the project',\n },\n {\n value: 'reverse_proxy',\n label: 'Reverse Proxy',\n hint: 'Reverse proxy record management',\n },\n {\n value: 'debug',\n label: 'Debug',\n hint: 'Debug and diagnostic tools',\n },\n ],\n};\n\nexport const ALL_FEATURE_VALUES = Object.values(AVAILABLE_FEATURES)\n .flat()\n .map((feature) => feature.value);\n\nexport const isAllFeaturesSelected = (features: string[]): boolean =>\n features.length === ALL_FEATURE_VALUES.length &&\n ALL_FEATURE_VALUES.every((feature) => features.includes(feature));\n\nexport const buildMCPUrl = (selectedFeatures?: string[], local?: boolean) => {\n const host = local ? 'http://localhost:8787' : 'https://mcp.posthog.com';\n const baseUrl = `${host}/mcp`;\n\n const params: string[] = [];\n\n // Add features param if not all features selected\n if (\n selectedFeatures &&\n selectedFeatures.length > 0 &&\n !isAllFeaturesSelected(selectedFeatures)\n ) {\n params.push(`features=${selectedFeatures.join(',')}`);\n }\n\n return params.length > 0 ? `${baseUrl}?${params.join('&')}` : baseUrl;\n};\n\nexport const getNativeHTTPServerConfig = (\n apiKey: string | undefined,\n selectedFeatures?: string[],\n local?: boolean,\n) => {\n const config: Record<string, unknown> = {\n url: buildMCPUrl(selectedFeatures, local),\n };\n\n // Only add auth header if API key is provided (not OAuth mode)\n if (apiKey) {\n config.headers = {\n Authorization: `Bearer ${apiKey}`,\n };\n }\n\n return config;\n};\n\nexport const getDefaultServerConfig = (\n apiKey: string | undefined,\n selectedFeatures?: string[],\n local?: boolean,\n) => {\n const urlWithFeatures = buildMCPUrl(selectedFeatures, local);\n\n // OAuth mode: no auth header, let MCP handle OAuth\n if (!apiKey) {\n return {\n command: 'npx',\n args: ['-y', 'mcp-remote@latest', urlWithFeatures],\n };\n }\n\n // API key mode: include auth header\n return {\n command: 'npx',\n args: [\n '-y',\n 'mcp-remote@latest',\n urlWithFeatures,\n '--header',\n `Authorization:\\${POSTHOG_AUTH_HEADER}`,\n ],\n env: {\n POSTHOG_AUTH_HEADER: `Bearer ${apiKey}`,\n },\n };\n};\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-B_-DWIq7.js";
|
|
2
|
-
import "./debug-
|
|
3
|
-
import "./setup-utils-
|
|
2
|
+
import "./debug-BGMe1wP6.js";
|
|
3
|
+
import "./setup-utils-CanVlGbX.js";
|
|
4
4
|
import readEnvModule from "read-env";
|
|
5
5
|
import "fast-glob";
|
|
6
6
|
//#region src/utils/environment.ts
|
|
@@ -19,4 +19,4 @@ function readEnvironment() {
|
|
|
19
19
|
//#endregion
|
|
20
20
|
export { isNonInteractiveEnvironment as n, environment_exports as t };
|
|
21
21
|
|
|
22
|
-
//# sourceMappingURL=environment-
|
|
22
|
+
//# sourceMappingURL=environment-G41UFzou.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"environment-
|
|
1
|
+
{"version":3,"file":"environment-G41UFzou.js","names":[],"sources":["../src/utils/environment.ts"],"sourcesContent":["import readEnvModule from 'read-env';\n\nconst readEnv =\n typeof readEnvModule === 'function'\n ? readEnvModule\n : (readEnvModule as any).default;\nimport { tryGetPackageJson } from './setup-utils';\nimport type { WizardRunOptions } from './types';\nimport fg from 'fast-glob';\nimport { IS_DEV } from '@lib/constants';\n\nexport function isNonInteractiveEnvironment(): boolean {\n if (IS_DEV) {\n return false;\n }\n\n if (!process.stdout.isTTY || !process.stderr.isTTY) {\n return true;\n }\n\n return false;\n}\n\nexport function readEnvironment(): Record<string, unknown> {\n const result = readEnv('POSTHOG_WIZARD');\n\n return result;\n}\n\nexport async function detectEnvVarPrefix(\n options: WizardRunOptions,\n): Promise<string> {\n const packageJson = await tryGetPackageJson(options);\n if (!packageJson) return 'VITE_PUBLIC_';\n\n const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };\n const has = (name: string) => name in deps;\n const hasAnyFile = async (patterns: string[]) => {\n const matches = await fg(patterns, {\n cwd: options.installDir,\n absolute: false,\n onlyFiles: true,\n ignore: ['**/node_modules/**'],\n });\n return matches.length > 0;\n };\n\n // --- Next.js\n if (has('next') || (await hasAnyFile(['**/next.config.{js,ts,mjs,cjs}']))) {\n return 'NEXT_PUBLIC_';\n }\n\n // --- Create React App\n if (\n has('react-scripts') ||\n has('create-react-app') ||\n (await hasAnyFile(['**/config-overrides.js']))\n ) {\n return 'REACT_APP_';\n }\n\n // --- Vite (vanilla, TanStack, Solid, etc.)\n // Note: Vite does not need PUBLIC_ but we use it to follow the docs, to improve the chances of an LLM getting it right.\n if (has('vite') || (await hasAnyFile(['**/vite.config.{js,ts,mjs,cjs}']))) {\n return 'VITE_PUBLIC_';\n }\n\n // --- SvelteKit\n if (\n has('@sveltejs/kit') ||\n (await hasAnyFile(['**/svelte.config.{js,ts}']))\n ) {\n return 'PUBLIC_';\n }\n\n // --- TanStack Start (uses Vite)\n if (\n has('@tanstack/start') ||\n (await hasAnyFile(['**/tanstack.config.{js,ts}']))\n ) {\n return 'VITE_PUBLIC_';\n }\n\n // --- SolidStart (uses Vite)\n if (has('solid-start') || (await hasAnyFile(['**/solid.config.{js,ts}']))) {\n return 'VITE_PUBLIC_';\n }\n\n // --- Astro\n if (has('astro') || (await hasAnyFile(['**/astro.config.{js,ts,mjs}']))) {\n return 'PUBLIC_';\n }\n\n // We default to Vite if we can't detect a specific framework, since it's the most commonly used.\n return 'VITE_PUBLIC_';\n}\n"],"mappings":";;;;;;;;;;AAEA,MAAM,UACJ,OAAO,kBAAkB,aACrB,gBACC,cAAsB;AAM7B,SAAgB,8BAAuC;AAKrD,KAAI,CAAC,QAAQ,OAAO,SAAS,CAAC,QAAQ,OAAO,MAC3C,QAAO;AAGT,QAAO;;AAGT,SAAgB,kBAA2C;AAGzD,QAFe,QAAQ,iBAAiB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as analytics } from "./analytics-
|
|
1
|
+
import { t as analytics } from "./analytics-CU4o3eF8.js";
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import path from "path";
|
|
4
4
|
//#region src/utils/file-utils.ts
|
|
@@ -113,4 +113,4 @@ function safeReadFile(fullPath) {
|
|
|
113
113
|
//#endregion
|
|
114
114
|
export { safeReadFile as n, walkProjectFiles as r, IGNORED_DIRS as t };
|
|
115
115
|
|
|
116
|
-
//# sourceMappingURL=file-utils-
|
|
116
|
+
//# sourceMappingURL=file-utils-D9InAvZd.js.map
|