@posthog/wizard 2.79.1 → 2.80.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +187 -57
- package/dist/{PickerMenu-dG5DQCZA.js → PickerMenu-BGGeYqd-.js} +112 -12
- package/dist/PickerMenu-BGGeYqd-.js.map +1 -0
- package/dist/README.md +9 -6
- package/dist/{agent-interface-FkbaBJwz.js → agent-interface-CemBvTAA.js} +130 -324
- package/dist/agent-interface-CemBvTAA.js.map +1 -0
- package/dist/{agent-prompt-loader-D0weQ-7k.js → agent-prompt-loader-DPnj6SwU.js} +6 -5
- package/dist/agent-prompt-loader-DPnj6SwU.js.map +1 -0
- package/dist/analytics-B3ROGuIr.js +2 -0
- package/dist/analytics-D21z3E5l.js +732 -0
- package/dist/analytics-D21z3E5l.js.map +1 -0
- package/dist/{api-CrbCIQOz.js → api-DtGIqQ2U.js} +2 -3
- package/dist/api-DtGIqQ2U.js.map +1 -0
- package/dist/api-IhROOQNv.js +2 -0
- package/dist/api-key-login-OEntFvu5.js +2 -0
- package/dist/api-key-login-h3E2G3zu.js +55 -0
- package/dist/api-key-login-h3E2G3zu.js.map +1 -0
- package/dist/bin.js +2 -2
- package/dist/bin.js.map +1 -1
- package/dist/{bounded-fs-vAq-T-K7.js → bounded-fs-CAsuF6al.js} +3 -3
- package/dist/{bounded-fs-vAq-T-K7.js.map → bounded-fs-CAsuF6al.js.map} +1 -1
- package/dist/{ci-install-COcV8SY2.js → ci-install-CEYE02t-.js} +22 -26
- package/dist/ci-install-CEYE02t-.js.map +1 -0
- package/dist/console-log-O828zyiq.js +32 -0
- package/dist/console-log-O828zyiq.js.map +1 -0
- package/dist/{debug-kAHwWGg7.js → debug-BfQPD2Hg.js} +18 -52
- package/dist/debug-BfQPD2Hg.js.map +1 -0
- package/dist/{defaults-a9TelDhJ.js → defaults-DDVl3tKN.js} +2 -51
- package/dist/defaults-DDVl3tKN.js.map +1 -0
- package/dist/{emit-BSetXzDV.js → emit-RfAewcWv.js} +1 -1
- package/dist/{emit-BSetXzDV.js.map → emit-RfAewcWv.js.map} +1 -1
- package/dist/{errors-C2domSkK.js → errors-CHrJzAZb.js} +4 -4
- package/dist/{errors-C2domSkK.js.map → errors-CHrJzAZb.js.map} +1 -1
- package/dist/family-picker-BKs-tTyu.js +46 -0
- package/dist/family-picker-BKs-tTyu.js.map +1 -0
- package/dist/{gateway-C9-GlLO9.js → gateway-D3gIlR6b.js} +122 -11
- package/dist/gateway-D3gIlR6b.js.map +1 -0
- package/dist/headless-BJjhP0SI.js +10 -0
- package/dist/headless-BJjhP0SI.js.map +1 -0
- package/dist/headless-DIX68UUA.js +3 -0
- package/dist/host-resolution-D8GhEVoX.js +114 -0
- package/dist/host-resolution-D8GhEVoX.js.map +1 -0
- package/dist/install-Bw8tvDvS.js +2 -0
- package/dist/{add-mcp-server-to-clients-DIaTRWMY.js → install-paPCzPHI.js} +34 -100
- package/dist/install-paPCzPHI.js.map +1 -0
- package/dist/interactive-tdxZKWax.js +11 -0
- package/dist/interactive-tdxZKWax.js.map +1 -0
- package/dist/{telemetry-B7zJdRmA.js → links-Cyj6v8kg.js} +4 -13
- package/dist/links-Cyj6v8kg.js.map +1 -0
- package/dist/{main-CgKxbwMP.js → main-0p-YxUNa.js} +233 -490
- package/dist/main-0p-YxUNa.js.map +1 -0
- package/dist/{mcp-DnAyW0-w.js → mcp-D3Z5MXhA.js} +3 -4
- package/dist/{mcp-DnAyW0-w.js.map → mcp-D3Z5MXhA.js.map} +1 -1
- package/dist/mcp-install-smoke-test.ts +2 -2
- package/dist/{mcp-prompt-streaming-DDWQ-FCA.js → mcp-prompt-streaming-COVbWnHt.js} +12 -12
- package/dist/mcp-prompt-streaming-COVbWnHt.js.map +1 -0
- package/dist/mode-label-DB3ol_sj.js +9 -0
- package/dist/mode-label-DB3ol_sj.js.map +1 -0
- package/dist/{models-WcwUnSKb.js → models-D1SnCzvl.js} +2 -2
- package/dist/{models-WcwUnSKb.js.map → models-D1SnCzvl.js.map} +1 -1
- package/dist/non-interactive-DxRBc73O.js +18 -0
- package/dist/non-interactive-DxRBc73O.js.map +1 -0
- package/dist/{oauth-session-DYM2Hrl2.js → oauth-session-Dde79Ycm.js} +3 -3
- package/dist/{oauth-session-DYM2Hrl2.js.map → oauth-session-Dde79Ycm.js.map} +1 -1
- package/dist/{orchestrator-tools-DbgNBFGA.js → orchestrator-tools-BSNhzzkT.js} +3 -3
- package/dist/{orchestrator-tools-DbgNBFGA.js.map → orchestrator-tools-BSNhzzkT.js.map} +1 -1
- package/dist/{package-json-Atg34fa4.js → package-json-2UrhE6kP.js} +1 -1
- package/dist/{package-json-Atg34fa4.js.map → package-json-2UrhE6kP.js.map} +1 -1
- package/dist/package-json-Dblip2_X.js +2 -0
- package/dist/package-manager-BRXlXo0p.js +105 -0
- package/dist/package-manager-BRXlXo0p.js.map +1 -0
- package/dist/{pi-8KsYsPmM.js → pi-cM_4Gd_9.js} +19 -20
- package/dist/pi-cM_4Gd_9.js.map +1 -0
- package/dist/playground-DTKy0XHT.js +12 -0
- package/dist/playground-DTKy0XHT.js.map +1 -0
- package/dist/posthog-integration-bwHwE87a.js +10291 -0
- package/dist/posthog-integration-bwHwE87a.js.map +1 -0
- package/dist/programs-BhtyA3lE.js +3 -0
- package/dist/programs-SeT1qNik.js +5348 -0
- package/dist/programs-SeT1qNik.js.map +1 -0
- package/dist/provisioning-BcXfeCMc.js +2 -0
- package/dist/{provisioning-Bo2NRxFz.js → provisioning-JbJtq7hq.js} +5 -67
- package/dist/provisioning-JbJtq7hq.js.map +1 -0
- package/dist/{queue-tools-C8mXOh7e.js → queue-tools-BIZSJyt6.js} +7 -9
- package/dist/queue-tools-BIZSJyt6.js.map +1 -0
- package/dist/results-DtKICAdz.js +55 -0
- package/dist/results-DtKICAdz.js.map +1 -0
- package/dist/run-CDurA5tO.js +248 -0
- package/dist/run-CDurA5tO.js.map +1 -0
- package/dist/run-DDCvLILJ.js +246 -0
- package/dist/run-DDCvLILJ.js.map +1 -0
- package/dist/run-tool-CTq9OOdT.js +2 -0
- package/dist/run-tool-DML8JJvt.js +2420 -0
- package/dist/run-tool-DML8JJvt.js.map +1 -0
- package/dist/runners-Dhu4pZTN.js +253 -0
- package/dist/runners-Dhu4pZTN.js.map +1 -0
- package/dist/{security-C71pkwqH.js → security-DEH8Rn0_.js} +5 -5
- package/dist/security-DEH8Rn0_.js.map +1 -0
- package/dist/setup-utils-C5-WM-hS.js +118 -0
- package/dist/setup-utils-C5-WM-hS.js.map +1 -0
- package/dist/smoke-test.sh +1 -1
- package/dist/{playground-BlYRBMj7.js → start-playground-DL4mVEUx.js} +63 -54
- package/dist/start-playground-DL4mVEUx.js.map +1 -0
- package/dist/{subagent-D1TrTchE.js → subagent-CnFvAq6E.js} +3 -3
- package/dist/{subagent-D1TrTchE.js.map → subagent-CnFvAq6E.js.map} +1 -1
- package/dist/{task-DqRlQBfs.js → task-BOScSm4W.js} +17 -18
- package/dist/task-BOScSm4W.js.map +1 -0
- package/dist/{tasks-ChWufsdO.js → tasks-BfJhVky2.js} +1 -1
- package/dist/tasks-BfJhVky2.js.map +1 -0
- package/dist/telemetry-CP4rGicd.js +13 -0
- package/dist/telemetry-CP4rGicd.js.map +1 -0
- package/dist/terminal-J3OD3dN0.js +16162 -0
- package/dist/terminal-J3OD3dN0.js.map +1 -0
- package/dist/tools-CCMV3DmB.js +544 -0
- package/dist/tools-CCMV3DmB.js.map +1 -0
- package/dist/{tools-CkJ2y9Wt.js → tools-Cz8tDptL.js} +9 -9
- package/dist/tools-Cz8tDptL.js.map +1 -0
- package/dist/tui-BUZ2PWqN.js +2 -0
- package/dist/tui-Csf7VJxt.js +25 -0
- package/dist/tui-Csf7VJxt.js.map +1 -0
- package/dist/{steps-BPcg3_3Q.js → upload-step-CEacB2RV.js} +17 -19
- package/dist/upload-step-CEacB2RV.js.map +1 -0
- package/dist/urls-BDELGZHq.js +67 -0
- package/dist/urls-BDELGZHq.js.map +1 -0
- package/dist/warlock-smoke-test.ts +1 -2
- package/dist/{wizard-abort-BPdv07np.js → wizard-abort-D3-75KyV.js} +41 -32
- package/dist/wizard-abort-D3-75KyV.js.map +1 -0
- package/dist/yara-hooks-CZ1tKxy_.js +2 -0
- package/dist/{yara-hooks-BnxejtXK.js → yara-hooks-D8YDyX7o.js} +283 -21
- package/dist/yara-hooks-D8YDyX7o.js.map +1 -0
- package/package.json +7 -8
- package/dist/PickerMenu-dG5DQCZA.js.map +0 -1
- package/dist/add-mcp-server-to-clients-DIaTRWMY.js.map +0 -1
- package/dist/add-mcp-server-to-clients-artmN7mz.js +0 -2
- package/dist/agent-BEjARD2a.js +0 -6
- package/dist/agent-BWFhuLgo.js +0 -3178
- package/dist/agent-BWFhuLgo.js.map +0 -1
- package/dist/agent-interface-FkbaBJwz.js.map +0 -1
- package/dist/agent-prompt-loader-D0weQ-7k.js.map +0 -1
- package/dist/analytics-DFtbRjYh.js +0 -2
- package/dist/analytics-DXK1gc12.js +0 -301
- package/dist/analytics-DXK1gc12.js.map +0 -1
- package/dist/api-Cm9UtKZh.js +0 -2
- package/dist/api-CrbCIQOz.js.map +0 -1
- package/dist/check-screens.tsx +0 -190
- package/dist/ci-install-COcV8SY2.js.map +0 -1
- package/dist/constants-DHCBSfnx.js +0 -260
- package/dist/constants-DHCBSfnx.js.map +0 -1
- package/dist/debug-BuYHGr6_.js +0 -2
- package/dist/debug-kAHwWGg7.js.map +0 -1
- package/dist/defaults-a9TelDhJ.js.map +0 -1
- package/dist/endpoints-BVMYm9F4.js +0 -108
- package/dist/endpoints-BVMYm9F4.js.map +0 -1
- package/dist/env-api-key-BP-NFFXt.js +0 -17
- package/dist/env-api-key-BP-NFFXt.js.map +0 -1
- package/dist/env-api-key-CaWEDj_9.js +0 -2
- package/dist/environment-BATlQxcQ.js +0 -39
- package/dist/environment-BATlQxcQ.js.map +0 -1
- package/dist/environment-CwD8OPYj.js +0 -2
- package/dist/file-C5JMsyR1.js +0 -2
- package/dist/file-DcRKycV8.js +0 -60
- package/dist/file-DcRKycV8.js.map +0 -1
- package/dist/file-watcher-Brq2nnHV.js +0 -123
- package/dist/file-watcher-Brq2nnHV.js.map +0 -1
- package/dist/gateway-C9-GlLO9.js.map +0 -1
- package/dist/headless-ui-CqI2gXlD.js +0 -44
- package/dist/headless-ui-CqI2gXlD.js.map +0 -1
- package/dist/interactive-B_Ti_CsS.js +0 -11
- package/dist/interactive-B_Ti_CsS.js.map +0 -1
- package/dist/local-dev-McsurOC-.js +0 -135
- package/dist/local-dev-McsurOC-.js.map +0 -1
- package/dist/logging-ui-Dza4D0MK.js +0 -226
- package/dist/logging-ui-Dza4D0MK.js.map +0 -1
- package/dist/main-CgKxbwMP.js.map +0 -1
- package/dist/mcp-prompt-streaming-DDWQ-FCA.js.map +0 -1
- package/dist/mint-failure-u8xQKNOn.js +0 -6392
- package/dist/mint-failure-u8xQKNOn.js.map +0 -1
- package/dist/non-interactive-DyVC1AGc.js +0 -18
- package/dist/non-interactive-DyVC1AGc.js.map +0 -1
- package/dist/package-json-D8Ga03tK.js +0 -2
- package/dist/pi-8KsYsPmM.js.map +0 -1
- package/dist/playground-BlYRBMj7.js.map +0 -1
- package/dist/posthog-Bt0Aplb8.js +0 -124
- package/dist/posthog-Bt0Aplb8.js.map +0 -1
- package/dist/posthog-CUgCEhH0.js +0 -2
- package/dist/provisioning-Bo2NRxFz.js.map +0 -1
- package/dist/provisioning-OGFGlzf7.js +0 -2
- package/dist/queue-tools-C8mXOh7e.js.map +0 -1
- package/dist/registry-C06e_x-p.js +0 -2
- package/dist/registry-CD5RQt38.js +0 -3464
- package/dist/registry-CD5RQt38.js.map +0 -1
- package/dist/run-agent-legacy-ChacZImU.js +0 -2
- package/dist/run-agent-legacy-DOlM6DQu.js +0 -3540
- package/dist/run-agent-legacy-DOlM6DQu.js.map +0 -1
- package/dist/runners-ov3EXF1n.js +0 -834
- package/dist/runners-ov3EXF1n.js.map +0 -1
- package/dist/security-C71pkwqH.js.map +0 -1
- package/dist/setup-utils-B26Lf2yF.js +0 -1512
- package/dist/setup-utils-B26Lf2yF.js.map +0 -1
- package/dist/setup-utils-CVS86NYR.js +0 -2
- package/dist/start-tui-Bo2L0bar.js +0 -6962
- package/dist/start-tui-Bo2L0bar.js.map +0 -1
- package/dist/steps-BPcg3_3Q.js.map +0 -1
- package/dist/store-BTzcvRGT.js +0 -992
- package/dist/store-BTzcvRGT.js.map +0 -1
- package/dist/store-BpqySPXm.js +0 -5
- package/dist/task-DqRlQBfs.js.map +0 -1
- package/dist/task-stream-Bw6JaLCX.js +0 -363
- package/dist/task-stream-Bw6JaLCX.js.map +0 -1
- package/dist/tasks-ChWufsdO.js.map +0 -1
- package/dist/telemetry-B7zJdRmA.js.map +0 -1
- package/dist/terminal-zgkEfoCL.js +0 -7196
- package/dist/terminal-zgkEfoCL.js.map +0 -1
- package/dist/tools-CkJ2y9Wt.js.map +0 -1
- package/dist/ui-Q6-RvERF.js +0 -15
- package/dist/ui-Q6-RvERF.js.map +0 -1
- package/dist/version-CHhJjz_H.js +0 -6
- package/dist/version-CHhJjz_H.js.map +0 -1
- package/dist/wizard-abort-BPdv07np.js.map +0 -1
- package/dist/wizard-abort-Br1qMDNa.js +0 -3
- package/dist/wizard-session-2w4Ru-Wz.js +0 -131
- package/dist/wizard-session-2w4Ru-Wz.js.map +0 -1
- package/dist/wizard-session-DGaUHOF3.js +0 -2
- package/dist/wizard-ui-DVqrYaOM.js +0 -16
- package/dist/wizard-ui-DVqrYaOM.js.map +0 -1
- package/dist/yara-hooks-BnxejtXK.js.map +0 -1
- package/dist/yara-hooks-DSuExwb4.js +0 -2
|
@@ -0,0 +1,732 @@
|
|
|
1
|
+
import { _ as TASK_RUN_ID, f as VERSION, g as TASK_ID, h as RUN_SURFACE, o as logToFile } from "./debug-BfQPD2Hg.js";
|
|
2
|
+
import { PostHog } from "posthog-node";
|
|
3
|
+
import { v4 } from "uuid";
|
|
4
|
+
//#region src/shared/local-dev.ts
|
|
5
|
+
/**
|
|
6
|
+
* Local development targets: context-mill (skills), MCP, and PostHog. Each is
|
|
7
|
+
* independently switchable — CI runs local skills against the *production* MCP
|
|
8
|
+
* — with `--local-dev` as a shorthand for all three.
|
|
9
|
+
*
|
|
10
|
+
* `wizard mcp add --local` is unrelated: it writes a `posthog-local` entry into
|
|
11
|
+
* the user's editor config rather than retargeting this run. Hence no
|
|
12
|
+
* `--local` here.
|
|
13
|
+
*/
|
|
14
|
+
const CONTEXT_MILL_LOCAL_URL = "http://localhost:8765";
|
|
15
|
+
const MCP_LOCAL_URL = "http://localhost:8787/mcp";
|
|
16
|
+
/** Pins the API, app, OAuth, and the LLM gateway derived from them. */
|
|
17
|
+
const POSTHOG_LOCAL_URL = "http://localhost:8010";
|
|
18
|
+
/**
|
|
19
|
+
* A specific flag beats `--local-dev` in both directions. `??` is load-bearing:
|
|
20
|
+
* it falls through only on `undefined`, so giving the specific flags a yargs
|
|
21
|
+
* `default: false` would silently break both the umbrella and `--no-local-mcp`.
|
|
22
|
+
*/
|
|
23
|
+
function resolveLocalDev(flags) {
|
|
24
|
+
const umbrella = flags.localDev ?? false;
|
|
25
|
+
return {
|
|
26
|
+
localMcp: flags.localMcp ?? umbrella,
|
|
27
|
+
localContextMill: flags.localContextMill ?? umbrella,
|
|
28
|
+
localPosthog: flags.localPosthog ?? umbrella
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** yargs populates both spellings, so read either. */
|
|
32
|
+
function localDevFromArgv(argv) {
|
|
33
|
+
const read = (kebab, camel) => {
|
|
34
|
+
const value = argv[camel] ?? argv[kebab];
|
|
35
|
+
return typeof value === "boolean" ? value : void 0;
|
|
36
|
+
};
|
|
37
|
+
return resolveLocalDev({
|
|
38
|
+
localDev: read("local-dev", "localDev"),
|
|
39
|
+
localMcp: read("local-mcp", "localMcp"),
|
|
40
|
+
localContextMill: read("local-context-mill", "localContextMill"),
|
|
41
|
+
localPosthog: read("local-posthog", "localPosthog")
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
const PRODUCTION_TARGETS = {
|
|
45
|
+
localMcp: false,
|
|
46
|
+
localContextMill: false,
|
|
47
|
+
localPosthog: false
|
|
48
|
+
};
|
|
49
|
+
let resolved = null;
|
|
50
|
+
/**
|
|
51
|
+
* Resolve this process's targets. Called once from the yargs middleware, which
|
|
52
|
+
* covers every command and the env-var spellings alike.
|
|
53
|
+
*/
|
|
54
|
+
function initLocalDev(argv) {
|
|
55
|
+
resolved = localDevFromArgv(argv);
|
|
56
|
+
return resolved;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Where this run points. Resolved once because the flags are parsed at startup
|
|
60
|
+
* and never change; threading them through state let call sites read whichever
|
|
61
|
+
* field they happened to have, which is how the intro screens ended up asking
|
|
62
|
+
* the MCP flag where to fetch skills.
|
|
63
|
+
*
|
|
64
|
+
* Uninitialized means no CLI parse ran (a direct-call test) — production.
|
|
65
|
+
*/
|
|
66
|
+
function getLocalDev() {
|
|
67
|
+
return resolved ?? PRODUCTION_TARGETS;
|
|
68
|
+
}
|
|
69
|
+
const LOCAL_SERVICES = [
|
|
70
|
+
{
|
|
71
|
+
key: "localContextMill",
|
|
72
|
+
label: "context-mill",
|
|
73
|
+
flag: "--local-context-mill",
|
|
74
|
+
url: `${CONTEXT_MILL_LOCAL_URL}/skill-menu.json`,
|
|
75
|
+
startHint: "npm run dev (in the context-mill repo)"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
key: "localMcp",
|
|
79
|
+
label: "MCP server",
|
|
80
|
+
flag: "--local-mcp",
|
|
81
|
+
url: MCP_LOCAL_URL,
|
|
82
|
+
startHint: "hogli start (or pnpm dev:local-resources in posthog/services/mcp)"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
key: "localPosthog",
|
|
86
|
+
label: "PostHog",
|
|
87
|
+
flag: "--local-posthog",
|
|
88
|
+
url: POSTHOG_LOCAL_URL,
|
|
89
|
+
startHint: "./bin/start (in the posthog repo)"
|
|
90
|
+
}
|
|
91
|
+
];
|
|
92
|
+
const PROBE_TIMEOUT_MS = 2e3;
|
|
93
|
+
const PROBE_ATTEMPTS = 3;
|
|
94
|
+
const PROBE_BACKOFF_MS = 250;
|
|
95
|
+
async function isReachable(url) {
|
|
96
|
+
for (let attempt = 1; attempt <= PROBE_ATTEMPTS; attempt++) try {
|
|
97
|
+
await fetch(url, { signal: AbortSignal.timeout(PROBE_TIMEOUT_MS) });
|
|
98
|
+
return true;
|
|
99
|
+
} catch {
|
|
100
|
+
if (attempt < PROBE_ATTEMPTS) await new Promise((r) => setTimeout(r, PROBE_BACKOFF_MS * 2 ** (attempt - 1)));
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Probe every service the flags asked to be local. Returns one message naming
|
|
106
|
+
* each unreachable one, or undefined if all are up (or none were requested).
|
|
107
|
+
*
|
|
108
|
+
* Without this a dead local server surfaces late and badly: a missing
|
|
109
|
+
* context-mill looks like a registry outage, a missing MCP fails mid-run after
|
|
110
|
+
* the agent has already edited files.
|
|
111
|
+
*/
|
|
112
|
+
async function checkLocalServices(resolved) {
|
|
113
|
+
const requested = LOCAL_SERVICES.filter((s) => resolved[s.key]);
|
|
114
|
+
if (requested.length === 0) return void 0;
|
|
115
|
+
const reachable = await Promise.all(requested.map((s) => isReachable(s.url)));
|
|
116
|
+
const dead = requested.filter((_, i) => !reachable[i]);
|
|
117
|
+
if (dead.length === 0) return void 0;
|
|
118
|
+
return [
|
|
119
|
+
`Local ${dead.length === 1 ? "service is" : "services are"} not running:`,
|
|
120
|
+
"",
|
|
121
|
+
...dead.map((s) => ` ${s.label} — nothing listening at ${new URL(s.url).origin}\n requested by ${s.flag}\n start it with: ${s.startHint}`),
|
|
122
|
+
"",
|
|
123
|
+
"Start the missing services, or drop the flag to use production."
|
|
124
|
+
].join("\n");
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* `--local-mcp` used to select local skills too; anyone still relying on that
|
|
128
|
+
* would silently get production skills. Temporary — drop after a release or two.
|
|
129
|
+
*/
|
|
130
|
+
function localMcpSkillsNotice(flags) {
|
|
131
|
+
if (flags.localMcp !== true) return void 0;
|
|
132
|
+
if (flags.localContextMill !== void 0 || flags.localDev === true) return;
|
|
133
|
+
return "--local-mcp now points only at the local MCP server. For local skills, add --local-context-mill (or use --local-dev for both).";
|
|
134
|
+
}
|
|
135
|
+
//#endregion
|
|
136
|
+
//#region src/shared/constants.ts
|
|
137
|
+
/**
|
|
138
|
+
* Shared constants for the PostHog wizard.
|
|
139
|
+
*/
|
|
140
|
+
/** Next sonnet generation (a `MODEL_FLAG_VARIANTS` key in the switchboard). */
|
|
141
|
+
const SONNET_5_MODEL = "claude-sonnet-5";
|
|
142
|
+
/**
|
|
143
|
+
* Default model for agent runs. Bare model IDs (no `anthropic/` prefix) so the
|
|
144
|
+
* LLM gateway's Bedrock fallback can match map_to_bedrock_model().
|
|
145
|
+
*/
|
|
146
|
+
const DEFAULT_AGENT_MODEL = SONNET_5_MODEL;
|
|
147
|
+
/** Undated haiku, for scan triage. The alias tracks the current 4.5 release rather than pinning one. */
|
|
148
|
+
const HAIKU_TRIAGE_MODEL = "claude-haiku-4-5";
|
|
149
|
+
/**
|
|
150
|
+
* Cheaper, faster model for mechanical agent work (e.g. repo classification
|
|
151
|
+
* during source-map detection). Passed via AgentConfig.modelOverride.
|
|
152
|
+
*/
|
|
153
|
+
const HAIKU_MODEL = HAIKU_TRIAGE_MODEL;
|
|
154
|
+
const GPT5_6_LUNA_MODEL = "openai/gpt-5.6-luna";
|
|
155
|
+
const GPT5_6_TERRA_MODEL = "openai/gpt-5.6-terra";
|
|
156
|
+
const GPT5_6_SOL_MODEL = "openai/gpt-5.6-sol";
|
|
157
|
+
/**
|
|
158
|
+
* The two agent runner routing axes: **harness** (which agent SDK drives the LLM)
|
|
159
|
+
* and **sequence** (which pipeline shape orchestrates the work). Single source
|
|
160
|
+
* of truth for yargs `choices`, session fields, the runner registry, and tests
|
|
161
|
+
* — `Object.values(Harness)` gives an iterable of the values when an array is
|
|
162
|
+
* needed. Adding a member is enough to pick it up everywhere.
|
|
163
|
+
*
|
|
164
|
+
* Naming matches the directory layout — see `src/agent/runner/harness/`
|
|
165
|
+
* and `src/agent/runner/sequence/`.
|
|
166
|
+
*/
|
|
167
|
+
let Harness = /* @__PURE__ */ function(Harness) {
|
|
168
|
+
Harness["anthropic"] = "anthropic";
|
|
169
|
+
Harness["pi"] = "pi";
|
|
170
|
+
return Harness;
|
|
171
|
+
}({});
|
|
172
|
+
let Sequence = /* @__PURE__ */ function(Sequence) {
|
|
173
|
+
Sequence["linear"] = "linear";
|
|
174
|
+
Sequence["orchestrator"] = "orchestrator";
|
|
175
|
+
return Sequence;
|
|
176
|
+
}({});
|
|
177
|
+
/**
|
|
178
|
+
* Detection order matters: put framework-specific integrations BEFORE basic language fallbacks.
|
|
179
|
+
*/
|
|
180
|
+
let Integration = /* @__PURE__ */ function(Integration) {
|
|
181
|
+
Integration["nextjs"] = "nextjs";
|
|
182
|
+
Integration["nuxt"] = "nuxt";
|
|
183
|
+
Integration["vue"] = "vue";
|
|
184
|
+
Integration["reactRouter"] = "react-router";
|
|
185
|
+
Integration["tanstackStart"] = "tanstack-start";
|
|
186
|
+
Integration["tanstackRouter"] = "tanstack-router";
|
|
187
|
+
Integration["reactNative"] = "react-native";
|
|
188
|
+
Integration["angular"] = "angular";
|
|
189
|
+
Integration["astro"] = "astro";
|
|
190
|
+
Integration["django"] = "django";
|
|
191
|
+
Integration["flask"] = "flask";
|
|
192
|
+
Integration["fastapi"] = "fastapi";
|
|
193
|
+
Integration["laravel"] = "laravel";
|
|
194
|
+
Integration["sveltekit"] = "sveltekit";
|
|
195
|
+
Integration["flutter"] = "flutter";
|
|
196
|
+
Integration["kmp"] = "kmp";
|
|
197
|
+
Integration["swift"] = "swift";
|
|
198
|
+
Integration["android"] = "android";
|
|
199
|
+
Integration["rails"] = "rails";
|
|
200
|
+
Integration["elixir"] = "elixir";
|
|
201
|
+
Integration["go"] = "go";
|
|
202
|
+
Integration["rust"] = "rust";
|
|
203
|
+
Integration["java"] = "java";
|
|
204
|
+
Integration["python"] = "python";
|
|
205
|
+
Integration["ruby"] = "ruby";
|
|
206
|
+
Integration["javascript_web"] = "javascript_web";
|
|
207
|
+
Integration["javascriptNode"] = "javascript_node";
|
|
208
|
+
return Integration;
|
|
209
|
+
}({});
|
|
210
|
+
/**
|
|
211
|
+
* The platforms session replay can actually record on. Replay vision watches
|
|
212
|
+
* recordings, so a platform with no recordings has nothing to set up — the
|
|
213
|
+
* run must stop before any work, not after a pointless agent run.
|
|
214
|
+
*
|
|
215
|
+
* Web frameworks record through posthog-js (server-rendered frameworks
|
|
216
|
+
* included — they serve pages), and the mobile SDKs with replay support are
|
|
217
|
+
* React Native, Android, iOS, and Flutter. Excluded: pure backend targets
|
|
218
|
+
* (`javascript_node`, `python`, `ruby`) and KMP, which has no replay support
|
|
219
|
+
* yet.
|
|
220
|
+
*/
|
|
221
|
+
const REPLAY_VISION_SUPPORTED = new Set([
|
|
222
|
+
"nextjs",
|
|
223
|
+
"nuxt",
|
|
224
|
+
"vue",
|
|
225
|
+
"react-router",
|
|
226
|
+
"tanstack-start",
|
|
227
|
+
"tanstack-router",
|
|
228
|
+
"angular",
|
|
229
|
+
"astro",
|
|
230
|
+
"sveltekit",
|
|
231
|
+
"javascript_web",
|
|
232
|
+
"django",
|
|
233
|
+
"flask",
|
|
234
|
+
"fastapi",
|
|
235
|
+
"laravel",
|
|
236
|
+
"rails",
|
|
237
|
+
"react-native",
|
|
238
|
+
"android",
|
|
239
|
+
"swift",
|
|
240
|
+
"flutter"
|
|
241
|
+
]);
|
|
242
|
+
/** The events-audit report. */
|
|
243
|
+
const EVENTS_AUDIT_REPORT_FILE = "posthog-events-audit-report.md";
|
|
244
|
+
const EVENT_INVENTORY_FILE = ".posthog-events-inventory.json";
|
|
245
|
+
/** Per-part filename pattern emitted by events-audit subagents (e.g. `.posthog-events-inventory.part-3.json`). */
|
|
246
|
+
const EVENT_INVENTORY_PART_PATTERN = /^\.posthog-events-inventory\.part-\d+\.json$/;
|
|
247
|
+
/** The integration program's event plan. */
|
|
248
|
+
const EVENT_PLAN_FILE = ".posthog-events.json";
|
|
249
|
+
/** The integration program's setup report; Self-driving reads it as a hint. */
|
|
250
|
+
const SETUP_REPORT_FILE = "posthog-setup-report.md";
|
|
251
|
+
/**
|
|
252
|
+
* Region-agnostic PostHog app URL. Resolves to us.posthog.com or
|
|
253
|
+
* eu.posthog.com server-side based on the signed-in user's profile.
|
|
254
|
+
* Use this for share-with-user links (e.g. settings pages) so they
|
|
255
|
+
* land on the right region without us needing to know it client-side.
|
|
256
|
+
*/
|
|
257
|
+
const POSTHOG_APP_URL = "https://app.posthog.com";
|
|
258
|
+
const ISSUES_URL = "https://github.com/posthog/wizard/issues";
|
|
259
|
+
/** Public status page, linked from transient-failure guidance (e.g. OAuth server_error). */
|
|
260
|
+
const POSTHOG_STATUS_PAGE_URL = "https://www.posthogstatus.com";
|
|
261
|
+
const CONTEXT_MILL_URL = "https://github.com/PostHog/context-mill";
|
|
262
|
+
/**
|
|
263
|
+
* Latest context-mill release page — the BYOAI download link shown in
|
|
264
|
+
* the privacy panel. Deliberately the release PAGE, not a direct asset
|
|
265
|
+
* URL: asset URLs are ~89 chars and hard-wrap inside the 64-col panel,
|
|
266
|
+
* which corrupts terminal copy/paste with a mid-URL line break. This
|
|
267
|
+
* stays under one line; the panel names the exact asset to grab.
|
|
268
|
+
*/
|
|
269
|
+
const CONTEXT_MILL_RELEASES_URL = "https://github.com/PostHog/context-mill/releases/latest";
|
|
270
|
+
const POSTHOG_DOCS_URL = "https://posthog.com/docs";
|
|
271
|
+
const POSTHOG_TERMS_URL = "https://posthog.com/terms";
|
|
272
|
+
const POSTHOG_PRIVACY_URL = "https://posthog.com/privacy";
|
|
273
|
+
const POSTHOG_ORG_AI_SETTINGS_URL = "https://app.posthog.com/settings/organization-details#setting=organization-ai-consent";
|
|
274
|
+
const WIZARD_CONTACT_EMAIL = "wizard@posthog.com";
|
|
275
|
+
/**
|
|
276
|
+
* Two origins for the same release, same filenames. Interchangeable bases, so
|
|
277
|
+
* making AWS primary is a `getSkillsBaseUrl` change, not a code change.
|
|
278
|
+
*/
|
|
279
|
+
const GITHUB_SKILLS_BASE_URL = "https://github.com/PostHog/context-mill/releases/latest/download";
|
|
280
|
+
const AWS_SKILLS_BASE_URL = "https://context-mill.posthog.com/latest";
|
|
281
|
+
/** Alias of `@shared/local-dev`'s constant, kept for existing importers. */
|
|
282
|
+
const LOCAL_SKILLS_BASE_URL = CONTEXT_MILL_LOCAL_URL;
|
|
283
|
+
/**
|
|
284
|
+
* Driven by `--local-context-mill`, NOT `--local-mcp` (which used to select
|
|
285
|
+
* both). Takes no argument on purpose: callers can't pass the wrong flag.
|
|
286
|
+
*/
|
|
287
|
+
function getSkillsBaseUrl() {
|
|
288
|
+
return getLocalDev().localContextMill ? LOCAL_SKILLS_BASE_URL : GITHUB_SKILLS_BASE_URL;
|
|
289
|
+
}
|
|
290
|
+
const ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY = "sTMFPsFhdP1Ssg";
|
|
291
|
+
const ANALYTICS_HOST_URL = "https://internal-j.posthog.com";
|
|
292
|
+
const ANALYTICS_TEAM_TAG = "docs-and-wizard";
|
|
293
|
+
const OAUTH_PORTS = [
|
|
294
|
+
8239,
|
|
295
|
+
8238,
|
|
296
|
+
8240,
|
|
297
|
+
8237,
|
|
298
|
+
8236,
|
|
299
|
+
8235
|
|
300
|
+
];
|
|
301
|
+
const POSTHOG_US_CLIENT_ID = "c4Rdw8DIxgtQfA80IiSnGKlNX8QN00cFWF00QQhM";
|
|
302
|
+
const POSTHOG_EU_CLIENT_ID = "bx2C5sZRN03TkdjraCcetvQFPGH6N2Y9vRLkcKEy";
|
|
303
|
+
const POSTHOG_DEV_CLIENT_ID = "DC5uRLVbGI02YQ82grxgnK6Qn12SXWpCqdPb60oZ";
|
|
304
|
+
const POSTHOG_PROXY_CLIENT_ID = POSTHOG_US_CLIENT_ID;
|
|
305
|
+
const DUMMY_PROJECT_API_KEY = "_YOUR_POSTHOG_PROJECT_TOKEN_";
|
|
306
|
+
/**
|
|
307
|
+
* Scopes the wizard requests during the agentic provisioning signup flow.
|
|
308
|
+
*
|
|
309
|
+
* Each entry is justified by what the wizard's agent step does after signup:
|
|
310
|
+
* - user:read identify the user for analytics + agent context
|
|
311
|
+
* - project:read look up the freshly-provisioned project
|
|
312
|
+
* - llm_gateway:read authenticate to gateway.{us,eu}.posthog.com/wizard
|
|
313
|
+
* (the agent's LLM calls — without this scope, every
|
|
314
|
+
* agent message returns 401)
|
|
315
|
+
* - query:read run HogQL queries when the agent needs data
|
|
316
|
+
* - dashboard:write create the onboarding dashboard during setup
|
|
317
|
+
* - insight:write create the onboarding insights during setup
|
|
318
|
+
* - notebook:write upload the events-audit report as a PostHog notebook
|
|
319
|
+
* in step 6 of the events-audit skill (notebooks-create
|
|
320
|
+
* MCP tool requires this scope)
|
|
321
|
+
* - event_definition:write
|
|
322
|
+
* create event definitions from the completed wizard
|
|
323
|
+
* session's event plan
|
|
324
|
+
*
|
|
325
|
+
* Must be a subset of `ALLOWED_PROVISIONING_SCOPES` in
|
|
326
|
+
* `ee/api/agentic_provisioning/views.py` on the backend.
|
|
327
|
+
*/
|
|
328
|
+
const WIZARD_PROVISIONING_SCOPES = [
|
|
329
|
+
"user:read",
|
|
330
|
+
"project:read",
|
|
331
|
+
"llm_gateway:read",
|
|
332
|
+
"dashboard:write",
|
|
333
|
+
"insight:write",
|
|
334
|
+
"query:read",
|
|
335
|
+
"notebook:write",
|
|
336
|
+
"event_definition:write"
|
|
337
|
+
];
|
|
338
|
+
/**
|
|
339
|
+
* Scopes the wizard requests during the OAuth login flow. Superset of
|
|
340
|
+
* `WIZARD_PROVISIONING_SCOPES` with scopes that only apply to the login
|
|
341
|
+
* path and are not in the provisioning allowlist:
|
|
342
|
+
* - health_issue:read used by `wizard doctor`
|
|
343
|
+
* - wizard_session:read list / retrieve / stream sessions
|
|
344
|
+
* - wizard_session:write stream run state to /api/projects/{id}/wizard/sessions/
|
|
345
|
+
* - event_definition:write
|
|
346
|
+
* create event definitions when a session completes
|
|
347
|
+
* - organization:read read `organization.is_ai_data_processing_approved`
|
|
348
|
+
* from /api/users/@me/ for the AI opt-in gate
|
|
349
|
+
*
|
|
350
|
+
* NOTE: every scope here must be within the wizard OAuth application's
|
|
351
|
+
* server-side scope ceiling (`OAuthApplication.scopes` in posthog, set
|
|
352
|
+
* via Django admin on BOTH prod regions). A scope outside the ceiling
|
|
353
|
+
* does NOT fail the authorize request — the server silently clamps the
|
|
354
|
+
* request to the ceiling (`clamp_scopes_to_ceiling` in posthog) and the
|
|
355
|
+
* token comes back without it. Separately, the consent screen lets the
|
|
356
|
+
* user deselect any scope the app doesn't mark required. Both paths
|
|
357
|
+
* yield a granted `scope` narrower than requested, with no error, so
|
|
358
|
+
* never assume the token carries this list — the token response's
|
|
359
|
+
* `scope` field is the truth, and `missingOAuthScopes` (utils/oauth.ts)
|
|
360
|
+
* diffs it at login. Ceiling procedure: the "scope-ceiling-invalid-scope"
|
|
361
|
+
* runbook in PostHog/runbooks. Keep its worked example in sync when this
|
|
362
|
+
* list changes.
|
|
363
|
+
*/
|
|
364
|
+
const WIZARD_OAUTH_SCOPES = [
|
|
365
|
+
...WIZARD_PROVISIONING_SCOPES,
|
|
366
|
+
"health_issue:read",
|
|
367
|
+
"wizard_session:read",
|
|
368
|
+
"wizard_session:write",
|
|
369
|
+
"wizard_run:write",
|
|
370
|
+
"organization:read"
|
|
371
|
+
];
|
|
372
|
+
const WIZARD_INTERACTION_EVENT_NAME = "wizard interaction";
|
|
373
|
+
const WIZARD_REMARK_EVENT_NAME = "wizard remark";
|
|
374
|
+
/** Multivariate flag: `wizard-run` publishes to WizardRun, anything else to WizardSession. */
|
|
375
|
+
const WIZARD_RUN_SYNC_FLAG_KEY = "wizard-run-sync";
|
|
376
|
+
/** Boolean feature flag that routes a run to the experimental orchestrator runner. */
|
|
377
|
+
const WIZARD_ORCHESTRATOR_FLAG_KEY = "wizard-orchestrator";
|
|
378
|
+
/** Multivariate flag: per-stage orchestrator overrides ride each variant's JSON payload (`{stage: {model?, effort?}}`). */
|
|
379
|
+
const WIZARD_ORCHESTRATOR_OVERRIDE_FLAG_KEY = "wizard-orchestrator-override";
|
|
380
|
+
/** Boolean flag: on → pi for self-driving. Payload carries `{model, effort?, harness?, sequence?}` (model = a `MODEL_FLAG_VARIANTS` key); missing/invalid payload keeps the non-flagged default. */
|
|
381
|
+
const WIZARD_SELF_DRIVING_USE_PI_HARNESS_FLAG_KEY = "wizard-self-driving-use-pi-harness";
|
|
382
|
+
/** Boolean flag: agentic project scoping for non-interactive basic-integration runs. */
|
|
383
|
+
const WIZARD_BASIC_INTEGRATION_AGENTIC_DETECTION_FLAG_KEY = "wizard-basic-integration-agentic-detection";
|
|
384
|
+
/** Boolean flag: the orchestrator queues the program's runner-seeded tasks (the warehouse step). Off, no task is queued and the run is byte-identical to a no-sources project. */
|
|
385
|
+
const WIZARD_ORCHESTRATOR_SEEDED_TASKS_FLAG_KEY = "wizard-orchestrator-seeded-tasks";
|
|
386
|
+
/** Kill switch over a shipped default: ONLY an explicit 'false' excludes the AI Observability and Logs tasks from default integration runs — absent or fetch-failed means include, so the default never vanishes on a network hiccup. */
|
|
387
|
+
const WIZARD_DEFAULT_AIO_LOGS_FLAG_KEY = "wizard-default-aio-logs";
|
|
388
|
+
const WIZARD_FLAG_KEYS = [
|
|
389
|
+
WIZARD_RUN_SYNC_FLAG_KEY,
|
|
390
|
+
WIZARD_ORCHESTRATOR_FLAG_KEY,
|
|
391
|
+
WIZARD_ORCHESTRATOR_OVERRIDE_FLAG_KEY,
|
|
392
|
+
WIZARD_ORCHESTRATOR_SEEDED_TASKS_FLAG_KEY,
|
|
393
|
+
WIZARD_SELF_DRIVING_USE_PI_HARNESS_FLAG_KEY,
|
|
394
|
+
WIZARD_BASIC_INTEGRATION_AGENTIC_DETECTION_FLAG_KEY,
|
|
395
|
+
WIZARD_DEFAULT_AIO_LOGS_FLAG_KEY
|
|
396
|
+
];
|
|
397
|
+
/** User-Agent for wizard HTTP requests and MCP server identification. */
|
|
398
|
+
const WIZARD_USER_AGENT = `posthog/wizard; version: ${VERSION}`;
|
|
399
|
+
/**
|
|
400
|
+
* User-Agent for a specific program's MCP calls, tagged with `program: <id>` so the
|
|
401
|
+
* backend can attribute work per program (e.g. the `self-driving` program's warehouse
|
|
402
|
+
* sources are recorded as `created_via=self_driving` rather than plain `wizard`). The
|
|
403
|
+
* base `posthog/wizard` token is preserved, so anything keying only on that still matches.
|
|
404
|
+
*/
|
|
405
|
+
function wizardUserAgentForProgram(programId) {
|
|
406
|
+
return programId ? `${WIZARD_USER_AGENT}; program: ${programId}` : WIZARD_USER_AGENT;
|
|
407
|
+
}
|
|
408
|
+
/** Timeout for framework / project detection probes (ms). */
|
|
409
|
+
const DETECTION_TIMEOUT_MS = 1e4;
|
|
410
|
+
/** Timeout for the agentic project scan (ms); past it the run falls back to root detection. */
|
|
411
|
+
const AGENTIC_DETECTION_FIRST_ATTEMPT_TIMEOUT_MS = 6e4;
|
|
412
|
+
const AGENTIC_DETECTION_RETRY_TIMEOUT_MS = 9e4;
|
|
413
|
+
/**
|
|
414
|
+
* Timeout for the OAuth authorization flow (ms).
|
|
415
|
+
*
|
|
416
|
+
* How long the user has to complete the browser login. The authorization
|
|
417
|
+
* code is minted at approval and exchanged immediately on callback, so the
|
|
418
|
+
* server-side code expiry (`AUTHORIZATION_CODE_EXPIRE_SECONDS`, 5 minutes)
|
|
419
|
+
* bounds only the approval→exchange gap — manual-paste users have 5 minutes
|
|
420
|
+
* from approval to submit the code — not how long this window may stay open.
|
|
421
|
+
*/
|
|
422
|
+
const OAUTH_TIMEOUT_MS = 18e5;
|
|
423
|
+
//#endregion
|
|
424
|
+
//#region src/shared/run-state.ts
|
|
425
|
+
/** One place to ask, so a new consent state does not need three edits. */
|
|
426
|
+
function mayReportScanResults(session) {
|
|
427
|
+
return session.scanConsent === "granted";
|
|
428
|
+
}
|
|
429
|
+
/** Lives here so analytics infrastructure never learns what consent means. */
|
|
430
|
+
function reportableDiscoveredFeatures(session) {
|
|
431
|
+
return mayReportScanResults(session) ? session.discoveredFeatures : void 0;
|
|
432
|
+
}
|
|
433
|
+
/** Also a scan result, so it travels under the same consent as the rest. */
|
|
434
|
+
function reportablePosthogSdkDetected(session) {
|
|
435
|
+
return mayReportScanResults(session) ? session.posthogSdkDetected : void 0;
|
|
436
|
+
}
|
|
437
|
+
//#endregion
|
|
438
|
+
//#region src/shared/utils/ci-flag-overrides.ts
|
|
439
|
+
function applyCiFlagOverrides(flags, payloads = {}) {
|
|
440
|
+
return {
|
|
441
|
+
flags,
|
|
442
|
+
payloads
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Task types excluded from this run. The exclusion env var (see the allowlist
|
|
447
|
+
* in `env.ts`) is a comma-separated list (e.g. `dashboard`), set by the CI
|
|
448
|
+
* harness that owns the policy — the wizard and the served content stay
|
|
449
|
+
* run-mode agnostic. CI-build only, same as the flag overrides: published
|
|
450
|
+
* builds strip this path.
|
|
451
|
+
*/
|
|
452
|
+
function ciExcludedTaskTypes() {
|
|
453
|
+
return [];
|
|
454
|
+
}
|
|
455
|
+
//#endregion
|
|
456
|
+
//#region src/shared/utils/analytics.ts
|
|
457
|
+
/**
|
|
458
|
+
* The invocation, reduced to flag-safe strings: the command word (first
|
|
459
|
+
* positional, 'default' for the bare flow) and the sorted option NAMES.
|
|
460
|
+
* Option values never leave the machine — they carry paths, emails, keys.
|
|
461
|
+
*/
|
|
462
|
+
function invocationProperties() {
|
|
463
|
+
const args = process.argv.slice(2);
|
|
464
|
+
return {
|
|
465
|
+
command: args.find((a) => !a.startsWith("-")) ?? "default",
|
|
466
|
+
cli_flags: [...new Set(args.filter((a) => a.startsWith("--")).map((a) => a.slice(2).split("=")[0]))].sort().join(",")
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Extract a standard property bag from the current session.
|
|
471
|
+
* Used by store-level analytics and available for ad-hoc captures.
|
|
472
|
+
*/
|
|
473
|
+
function sessionProperties(session) {
|
|
474
|
+
const discoveredFeatures = reportableDiscoveredFeatures(session);
|
|
475
|
+
const posthogSdkDetected = reportablePosthogSdkDetected(session);
|
|
476
|
+
return {
|
|
477
|
+
integration: session.integration,
|
|
478
|
+
skill_id: session.skillId,
|
|
479
|
+
detected_framework: session.detectedFrameworkLabel,
|
|
480
|
+
typescript: session.typescript,
|
|
481
|
+
project_id: session.credentials?.projectId,
|
|
482
|
+
...discoveredFeatures !== void 0 ? { discovered_features: discoveredFeatures } : {},
|
|
483
|
+
scan_consent: session.scanConsent,
|
|
484
|
+
run_phase: session.runPhase,
|
|
485
|
+
...posthogSdkDetected !== void 0 ? { posthog_sdk_detected: posthogSdkDetected } : {}
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
function groupsFromUser(user, host) {
|
|
489
|
+
const groups = { instance: host };
|
|
490
|
+
if (!user) return groups;
|
|
491
|
+
const organizationId = user.organization?.id;
|
|
492
|
+
if (organizationId) groups.organization = organizationId;
|
|
493
|
+
const customerId = user.organization?.customer_id;
|
|
494
|
+
if (customerId) groups.customer = customerId;
|
|
495
|
+
const projectUuid = user.team?.uuid;
|
|
496
|
+
if (projectUuid) groups.project = projectUuid;
|
|
497
|
+
return groups;
|
|
498
|
+
}
|
|
499
|
+
const WIZARD_FLAGS = new Set(WIZARD_FLAG_KEYS);
|
|
500
|
+
function flagResponseValue(value) {
|
|
501
|
+
if (value === "true") return true;
|
|
502
|
+
if (value === "false") return false;
|
|
503
|
+
return value;
|
|
504
|
+
}
|
|
505
|
+
var Analytics = class {
|
|
506
|
+
client;
|
|
507
|
+
tags = {};
|
|
508
|
+
distinctId;
|
|
509
|
+
anonymousId;
|
|
510
|
+
_runId;
|
|
511
|
+
sessionId = null;
|
|
512
|
+
appName = "wizard";
|
|
513
|
+
activeFlags = null;
|
|
514
|
+
activeFlagPayloads = {};
|
|
515
|
+
groups = {};
|
|
516
|
+
personProperties = {};
|
|
517
|
+
terminalEventSent = false;
|
|
518
|
+
constructor() {
|
|
519
|
+
this.client = new PostHog(ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY, {
|
|
520
|
+
host: ANALYTICS_HOST_URL,
|
|
521
|
+
flushAt: 1,
|
|
522
|
+
flushInterval: 0,
|
|
523
|
+
enableExceptionAutocapture: true,
|
|
524
|
+
before_send: (event) => {
|
|
525
|
+
if (!event) return event;
|
|
526
|
+
if (Object.keys(this.groups).length > 0) event.groups = {
|
|
527
|
+
...this.groups,
|
|
528
|
+
...event.groups
|
|
529
|
+
};
|
|
530
|
+
if (event.event === "$exception") {
|
|
531
|
+
event.distinctId = this.distinctId ?? this.anonymousId;
|
|
532
|
+
const { $process_person_profile, ...properties } = event.properties ?? {};
|
|
533
|
+
event.properties = {
|
|
534
|
+
...this.tags,
|
|
535
|
+
...properties
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
if (event.event === "$feature_flag_called") event.properties = {
|
|
539
|
+
...this.tags,
|
|
540
|
+
...event.properties ?? {}
|
|
541
|
+
};
|
|
542
|
+
return event;
|
|
543
|
+
}
|
|
544
|
+
});
|
|
545
|
+
this.tags = { $app_name: this.appName };
|
|
546
|
+
this.tags.build = "prod";
|
|
547
|
+
this.tags.run_surface = RUN_SURFACE;
|
|
548
|
+
this.tags.version = VERSION;
|
|
549
|
+
if (TASK_RUN_ID) this.tags.task_run_id = TASK_RUN_ID;
|
|
550
|
+
if (TASK_ID) this.tags.task_id = TASK_ID;
|
|
551
|
+
this.anonymousId = v4();
|
|
552
|
+
this._runId = v4();
|
|
553
|
+
this.tags.run_id = this._runId;
|
|
554
|
+
this.distinctId = void 0;
|
|
555
|
+
}
|
|
556
|
+
/** Per-process run id, tagged on every event and gateway trace. */
|
|
557
|
+
get runId() {
|
|
558
|
+
return this._runId;
|
|
559
|
+
}
|
|
560
|
+
/** Build type for this run ('prod' | 'dev' | 'ci' | 'headless') — the same value tagged on every analytics event. */
|
|
561
|
+
get build() {
|
|
562
|
+
return String(this.tags.build ?? "dev");
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Associate the run with the logged-in user, once per id. Identifies them
|
|
566
|
+
* (email, name) and records those person properties so events carry them and
|
|
567
|
+
* feature flags can target the individual user — without the email here the
|
|
568
|
+
* wizard only sends `$app_name`, so email-targeted flags never match. Opens
|
|
569
|
+
* the analytics session on first login, then aliases the run's anonymous id
|
|
570
|
+
* onto the identified person so pre-login events merge in.
|
|
571
|
+
*/
|
|
572
|
+
identifyUser(user) {
|
|
573
|
+
const distinctId = user.distinct_id;
|
|
574
|
+
if (this.distinctId === distinctId || distinctId === this.anonymousId) return;
|
|
575
|
+
this.distinctId = distinctId;
|
|
576
|
+
if (!this.sessionId) {
|
|
577
|
+
this.sessionId = v4();
|
|
578
|
+
this.tags.$session_id = this.sessionId;
|
|
579
|
+
}
|
|
580
|
+
const props = {};
|
|
581
|
+
if (user.email) props.email = user.email;
|
|
582
|
+
const name = [user.first_name, user.last_name].filter(Boolean).join(" ").trim();
|
|
583
|
+
if (name) props.name = name;
|
|
584
|
+
this.personProperties = props;
|
|
585
|
+
this.client.identify({
|
|
586
|
+
distinctId,
|
|
587
|
+
properties: { $set: props }
|
|
588
|
+
});
|
|
589
|
+
this.client.alias({
|
|
590
|
+
distinctId,
|
|
591
|
+
alias: this.anonymousId
|
|
592
|
+
});
|
|
593
|
+
this.activeFlags = null;
|
|
594
|
+
this.activeFlagPayloads = {};
|
|
595
|
+
}
|
|
596
|
+
/** Person properties sent with flag evaluation: app name plus the user's. */
|
|
597
|
+
flagPersonProperties() {
|
|
598
|
+
return {
|
|
599
|
+
$app_name: this.appName,
|
|
600
|
+
version: VERSION,
|
|
601
|
+
run_surface: RUN_SURFACE,
|
|
602
|
+
build: String(this.tags.build ?? "dev"),
|
|
603
|
+
os: process.platform,
|
|
604
|
+
node_major: process.versions.node.split(".")[0],
|
|
605
|
+
...invocationProperties(),
|
|
606
|
+
...this.personProperties
|
|
607
|
+
};
|
|
608
|
+
}
|
|
609
|
+
setTag(key, value) {
|
|
610
|
+
this.tags[key] = value;
|
|
611
|
+
}
|
|
612
|
+
setGroups(groups) {
|
|
613
|
+
this.groups = groups;
|
|
614
|
+
}
|
|
615
|
+
captureException(error, properties = {}) {
|
|
616
|
+
this.client.captureException(error, this.distinctId ?? this.anonymousId, {
|
|
617
|
+
team: ANALYTICS_TEAM_TAG,
|
|
618
|
+
...this.tags,
|
|
619
|
+
...properties
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
capture(eventName, properties) {
|
|
623
|
+
this.client.capture({
|
|
624
|
+
distinctId: this.distinctId ?? this.anonymousId,
|
|
625
|
+
event: eventName,
|
|
626
|
+
properties: {
|
|
627
|
+
...this.tags,
|
|
628
|
+
...this.wizardFlagFeatureProperties(),
|
|
629
|
+
...properties
|
|
630
|
+
}
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
groupIdentify(groupType, groupKey, properties) {
|
|
634
|
+
this.client.groupIdentify({
|
|
635
|
+
groupType,
|
|
636
|
+
groupKey,
|
|
637
|
+
properties
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
wizardFlagFeatureProperties() {
|
|
641
|
+
if (this.activeFlags === null) return {};
|
|
642
|
+
const props = {};
|
|
643
|
+
const active = [];
|
|
644
|
+
for (const [key, value] of Object.entries(this.activeFlags)) {
|
|
645
|
+
if (!WIZARD_FLAGS.has(key)) continue;
|
|
646
|
+
const resolved = flagResponseValue(value);
|
|
647
|
+
props[`$feature/${key}`] = resolved;
|
|
648
|
+
if (resolved !== false) active.push(key);
|
|
649
|
+
}
|
|
650
|
+
if (active.length > 0) props.$active_feature_flags = active.sort();
|
|
651
|
+
return props;
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* Capture a wizard-specific event. Automatically prepends "wizard: " to the event name.
|
|
655
|
+
* All new wizard analytics should use this method instead of capture() directly.
|
|
656
|
+
*/
|
|
657
|
+
wizardCapture(eventName, properties) {
|
|
658
|
+
this.capture(`wizard: ${eventName}`, properties);
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Flush pending events without firing the "setup wizard finished" terminal
|
|
662
|
+
* event. Use this from CLI error paths that exit before any wizard run
|
|
663
|
+
* starts — `shutdown()` would inflate the run count with a "finished" event
|
|
664
|
+
* for a parse error that never actually ran the wizard.
|
|
665
|
+
*/
|
|
666
|
+
async flush() {
|
|
667
|
+
await this.client.shutdown();
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* Evaluate all feature flags for the current user at the start of a run.
|
|
671
|
+
* Result is cached; subsequent calls in the same run return the same map.
|
|
672
|
+
* Returns flag key -> string value (booleans become 'true'/'false').
|
|
673
|
+
*/
|
|
674
|
+
async getAllFlagsForWizard() {
|
|
675
|
+
if (this.activeFlags !== null) return this.activeFlags;
|
|
676
|
+
const out = {};
|
|
677
|
+
const payloads = {};
|
|
678
|
+
try {
|
|
679
|
+
const distinctId = this.distinctId ?? this.anonymousId;
|
|
680
|
+
logToFile("[flags] evaluating as", {
|
|
681
|
+
distinctId,
|
|
682
|
+
identified: this.distinctId !== void 0,
|
|
683
|
+
personProperties: this.flagPersonProperties()
|
|
684
|
+
});
|
|
685
|
+
const evaluation = await this.client.evaluateFlags(distinctId, { personProperties: this.flagPersonProperties() });
|
|
686
|
+
for (const key of WIZARD_FLAG_KEYS) {
|
|
687
|
+
const value = evaluation.getFlag(key);
|
|
688
|
+
if (value === void 0) continue;
|
|
689
|
+
out[key] = String(value);
|
|
690
|
+
const payload = evaluation.getFlagPayload(key);
|
|
691
|
+
if (payload !== void 0) payloads[key] = payload;
|
|
692
|
+
}
|
|
693
|
+
} catch (error) {
|
|
694
|
+
logToFile("Failed to get all feature flags:", error);
|
|
695
|
+
this.captureException(error instanceof Error ? error : new Error(String(error)), { step: "get_all_flags" });
|
|
696
|
+
}
|
|
697
|
+
const merged = applyCiFlagOverrides(out, payloads);
|
|
698
|
+
this.activeFlags = merged.flags;
|
|
699
|
+
this.activeFlagPayloads = merged.payloads;
|
|
700
|
+
logToFile("[flags] evaluated", this.activeFlags);
|
|
701
|
+
return this.activeFlags;
|
|
702
|
+
}
|
|
703
|
+
getCachedWizardFlags() {
|
|
704
|
+
return this.activeFlags;
|
|
705
|
+
}
|
|
706
|
+
/** Flag payloads from the same snapshot; empty until the flags are fetched. */
|
|
707
|
+
getWizardFlagPayloads() {
|
|
708
|
+
return this.activeFlagPayloads;
|
|
709
|
+
}
|
|
710
|
+
async shutdown(status) {
|
|
711
|
+
if (Object.keys(this.tags).length === 0) return;
|
|
712
|
+
if (this.terminalEventSent) return;
|
|
713
|
+
this.terminalEventSent = true;
|
|
714
|
+
this.client.capture({
|
|
715
|
+
distinctId: this.distinctId ?? this.anonymousId,
|
|
716
|
+
event: "setup wizard finished",
|
|
717
|
+
properties: {
|
|
718
|
+
...this.tags,
|
|
719
|
+
run_id: this._runId,
|
|
720
|
+
...this.sessionId ? { $session_id: this.sessionId } : {},
|
|
721
|
+
status,
|
|
722
|
+
tags: this.tags
|
|
723
|
+
}
|
|
724
|
+
});
|
|
725
|
+
await this.client.shutdown();
|
|
726
|
+
}
|
|
727
|
+
};
|
|
728
|
+
const analytics = new Analytics();
|
|
729
|
+
//#endregion
|
|
730
|
+
export { WIZARD_REMARK_EVENT_NAME as $, POSTHOG_APP_URL as A, REPLAY_VISION_SUPPORTED as B, HAIKU_MODEL as C, Integration as D, ISSUES_URL as E, POSTHOG_PRIVACY_URL as F, WIZARD_CONTACT_EMAIL as G, SONNET_5_MODEL as H, POSTHOG_PROXY_CLIENT_ID as I, WIZARD_OAUTH_SCOPES as J, WIZARD_DEFAULT_AIO_LOGS_FLAG_KEY as K, POSTHOG_STATUS_PAGE_URL as L, POSTHOG_DOCS_URL as M, POSTHOG_EU_CLIENT_ID as N, OAUTH_PORTS as O, POSTHOG_ORG_AI_SETTINGS_URL as P, WIZARD_PROVISIONING_SCOPES as Q, POSTHOG_TERMS_URL as R, GPT5_6_TERRA_MODEL as S, Harness as T, Sequence as U, SETUP_REPORT_FILE as V, WIZARD_BASIC_INTEGRATION_AGENTIC_DETECTION_FLAG_KEY as W, WIZARD_ORCHESTRATOR_OVERRIDE_FLAG_KEY as X, WIZARD_ORCHESTRATOR_FLAG_KEY as Y, WIZARD_ORCHESTRATOR_SEEDED_TASKS_FLAG_KEY as Z, EVENT_INVENTORY_PART_PATTERN as _, ciExcludedTaskTypes as a, MCP_LOCAL_URL as at, GPT5_6_LUNA_MODEL as b, AGENTIC_DETECTION_RETRY_TIMEOUT_MS as c, getLocalDev as ct, CONTEXT_MILL_URL as d, resolveLocalDev as dt, WIZARD_RUN_SYNC_FLAG_KEY as et, DEFAULT_AGENT_MODEL as f, EVENT_INVENTORY_FILE as g, EVENTS_AUDIT_REPORT_FILE as h, sessionProperties as i, wizardUserAgentForProgram as it, POSTHOG_DEV_CLIENT_ID as j, OAUTH_TIMEOUT_MS as k, AWS_SKILLS_BASE_URL as l, initLocalDev as lt, DUMMY_PROJECT_API_KEY as m, analytics as n, WIZARD_USER_AGENT as nt, mayReportScanResults as o, POSTHOG_LOCAL_URL as ot, DETECTION_TIMEOUT_MS as p, WIZARD_INTERACTION_EVENT_NAME as q, groupsFromUser as r, getSkillsBaseUrl as rt, AGENTIC_DETECTION_FIRST_ATTEMPT_TIMEOUT_MS as s, checkLocalServices as st, Analytics as t, WIZARD_SELF_DRIVING_USE_PI_HARNESS_FLAG_KEY as tt, CONTEXT_MILL_RELEASES_URL as u, localMcpSkillsNotice as ut, EVENT_PLAN_FILE as v, HAIKU_TRIAGE_MODEL as w, GPT5_6_SOL_MODEL as x, GITHUB_SKILLS_BASE_URL as y, POSTHOG_US_CLIENT_ID as z };
|
|
731
|
+
|
|
732
|
+
//# sourceMappingURL=analytics-D21z3E5l.js.map
|