@posthog/wizard 2.50.0 → 2.52.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-Bd8XRxzi.js → add-mcp-server-to-clients-DJyWMMGj.js} +5 -5
- package/dist/{add-mcp-server-to-clients-Bd8XRxzi.js.map → add-mcp-server-to-clients-DJyWMMGj.js.map} +1 -1
- package/dist/{agent-interface-C_aRBziP.js → agent-interface-DoFVHRFh.js} +30 -69
- package/dist/agent-interface-DoFVHRFh.js.map +1 -0
- package/dist/agent-prompt-loader-D-cPVoL5.js +275 -0
- package/dist/agent-prompt-loader-D-cPVoL5.js.map +1 -0
- package/dist/{agent-runner-NzzrOB02.js → agent-runner-B1qCtjid.js} +100 -318
- package/dist/agent-runner-B1qCtjid.js.map +1 -0
- package/dist/{analytics-CArgq7XO.js → analytics-BXz4SIuS.js} +33 -20
- package/dist/analytics-BXz4SIuS.js.map +1 -0
- package/dist/analytics-D2xds3nw.js +2 -0
- package/dist/{api-CX1g-14-.js → api-BaacjH-Y.js} +3 -3
- package/dist/{api-CX1g-14-.js.map → api-BaacjH-Y.js.map} +1 -1
- package/dist/bin.js +97 -91
- package/dist/bin.js.map +1 -1
- package/dist/bounded-fs-Cx-8nk-1.js +242 -0
- package/dist/bounded-fs-Cx-8nk-1.js.map +1 -0
- package/dist/{ci-install-BYThh_Gl.js → ci-install-D1Mum8Ah.js} +4 -4
- package/dist/{ci-install-BYThh_Gl.js.map → ci-install-D1Mum8Ah.js.map} +1 -1
- package/dist/commandments-BagyrYRW.js +2 -0
- package/dist/{commandments-DSNrOeOC.js → commandments-DiMtIz1o.js} +1 -1
- package/dist/{commandments-DSNrOeOC.js.map → commandments-DiMtIz1o.js.map} +1 -1
- package/dist/{debug-dX5JKcxf.js → debug-C3ZR1TVF.js} +14 -29
- package/dist/debug-C3ZR1TVF.js.map +1 -0
- package/dist/{debug-CdScMjI7.js → debug-DsSCOPe8.js} +1 -1
- package/dist/{defaults-CtWMmC8s.js → defaults-DAE9_QMn.js} +1 -1
- package/dist/{defaults-CtWMmC8s.js.map → defaults-DAE9_QMn.js.map} +1 -1
- package/dist/{env-api-key-C3LzH8Lr.js → env-api-key-DDVkPQmo.js} +1 -1
- package/dist/{env-api-key-C3LzH8Lr.js.map → env-api-key-DDVkPQmo.js.map} +1 -1
- package/dist/{environment-D-xSv8Xv.js → environment-Bi-zynk6.js} +4 -4
- package/dist/environment-Bi-zynk6.js.map +1 -0
- package/dist/{file-watcher-Z28w46F3.js → file-watcher-PmRIDAfM.js} +2 -2
- package/dist/{file-watcher-Z28w46F3.js.map → file-watcher-PmRIDAfM.js.map} +1 -1
- package/dist/{headless-ui-T-cv04Ne.js → headless-ui-C4X9lAOY.js} +2 -2
- package/dist/{headless-ui-T-cv04Ne.js.map → headless-ui-C4X9lAOY.js.map} +1 -1
- package/dist/{interactive-uhGISvkt.js → interactive-HM71vLQe.js} +2 -2
- package/dist/{interactive-uhGISvkt.js.map → interactive-HM71vLQe.js.map} +1 -1
- package/dist/mcp-D0Hpb_nk.js +64 -0
- package/dist/mcp-D0Hpb_nk.js.map +1 -0
- package/dist/{mcp-prompt-streaming-ByofAot4.js → mcp-prompt-streaming-Crk8qFlQ.js} +3 -3
- package/dist/{mcp-prompt-streaming-ByofAot4.js.map → mcp-prompt-streaming-Crk8qFlQ.js.map} +1 -1
- package/dist/{non-interactive-dGAp1rES.js → non-interactive-DdUe8lqX.js} +2 -2
- package/dist/{non-interactive-dGAp1rES.js.map → non-interactive-DdUe8lqX.js.map} +1 -1
- package/dist/{orchestrator-tools-9D5vTenD.js → orchestrator-tools-CpRruqZl.js} +3 -3
- package/dist/{orchestrator-tools-9D5vTenD.js.map → orchestrator-tools-CpRruqZl.js.map} +1 -1
- package/dist/{package-json-DCuoye-H.js → package-json-CDs1ZVKu.js} +1 -1
- package/dist/{package-json-DCuoye-H.js.map → package-json-CDs1ZVKu.js.map} +1 -1
- package/dist/{package-manager-D3M_H5Pk.js → package-manager-wkSzPJqW.js} +2 -2
- package/dist/{package-manager-D3M_H5Pk.js.map → package-manager-wkSzPJqW.js.map} +1 -1
- package/dist/{pi--w-M8eD-.js → pi-CGPjm4oE.js} +91 -140
- package/dist/pi-CGPjm4oE.js.map +1 -0
- package/dist/{playground-GURThvy5.js → playground-lg7h9GHG.js} +7 -7
- package/dist/{playground-GURThvy5.js.map → playground-lg7h9GHG.js.map} +1 -1
- package/dist/{posthog-integration-Dk1hbtRQ.js → posthog-integration-pnxhTbxw.js} +45 -38
- package/dist/posthog-integration-pnxhTbxw.js.map +1 -0
- package/dist/{posthog-DZZbziJ1.js → posthog-mgz-FQlS.js} +1 -1
- package/dist/{posthog-DZZbziJ1.js.map → posthog-mgz-FQlS.js.map} +1 -1
- package/dist/{provisioning-CJQwMFVo.js → provisioning-T4jtJqBa.js} +3 -3
- package/dist/{provisioning-CJQwMFVo.js.map → provisioning-T4jtJqBa.js.map} +1 -1
- package/dist/{queue-tools-DW-pUVKK.js → queue-tools-D7ctuzyo.js} +97 -10
- package/dist/queue-tools-D7ctuzyo.js.map +1 -0
- package/dist/{registry-CYNjgbAh.js → registry-CsFuKtXn.js} +272 -429
- package/dist/registry-CsFuKtXn.js.map +1 -0
- package/dist/{security-D9TV_nIO.js → security-YAaZfmHs.js} +4 -4
- package/dist/{security-D9TV_nIO.js.map → security-YAaZfmHs.js.map} +1 -1
- package/dist/{setup-utils-D5RLhAEe.js → setup-utils-DDzEnDxJ.js} +14 -17
- package/dist/setup-utils-DDzEnDxJ.js.map +1 -0
- package/dist/smoke-test.sh +1 -1
- package/dist/{start-tui-Dvk-0lGv.js → start-tui-pCi7WVAK.js} +72 -87
- package/dist/start-tui-pCi7WVAK.js.map +1 -0
- package/dist/{steps-CcRX3kDT.js → steps-DmsrBqb9.js} +7 -7
- package/dist/{steps-CcRX3kDT.js.map → steps-DmsrBqb9.js.map} +1 -1
- package/dist/{store-DkQLlZF9.js → store-BCRdtfOH.js} +5 -5
- package/dist/{store-DkQLlZF9.js.map → store-BCRdtfOH.js.map} +1 -1
- package/dist/{subagent-Dxh0Pwgv.js → subagent-jNXS8IPU.js} +2 -2
- package/dist/{subagent-Dxh0Pwgv.js.map → subagent-jNXS8IPU.js.map} +1 -1
- package/dist/{task-C-r2xQvb.js → task-CSmrfyNf.js} +30 -46
- package/dist/task-CSmrfyNf.js.map +1 -0
- package/dist/{task-stream-_e6Mf24V.js → task-stream-BZOjOhKu.js} +5 -5
- package/dist/{task-stream-_e6Mf24V.js.map → task-stream-BZOjOhKu.js.map} +1 -1
- package/dist/{tasks-BqpaakPz.js → tasks-BMgQt251.js} +2 -2
- package/dist/{tasks-BqpaakPz.js.map → tasks-BMgQt251.js.map} +1 -1
- package/dist/{telemetry-CeQm0f0H.js → telemetry-qeKIGkte.js} +3 -3
- package/dist/{telemetry-CeQm0f0H.js.map → telemetry-qeKIGkte.js.map} +1 -1
- package/dist/{terminal-2gT6ezna.js → terminal-tbxhJGlI.js} +13 -13
- package/dist/{terminal-2gT6ezna.js.map → terminal-tbxhJGlI.js.map} +1 -1
- package/dist/{tools-C5Lsz2zR.js → tools-DVnBIYFn.js} +10 -8
- package/dist/tools-DVnBIYFn.js.map +1 -0
- package/dist/{wizard-abort-D_Xcbesm.js → wizard-abort-AEhoDJ4P.js} +4 -4
- package/dist/{wizard-abort-D_Xcbesm.js.map → wizard-abort-AEhoDJ4P.js.map} +1 -1
- package/dist/{wizard-abort-CaKAS9_Z.js → wizard-abort-DHC_XStW.js} +1 -1
- package/dist/{wizard-session-tp4Zdbwl.js → wizard-session-BAZql11N.js} +1 -1
- package/dist/{wizard-session-tp4Zdbwl.js.map → wizard-session-BAZql11N.js.map} +1 -1
- package/dist/{wizard-session-DWHe83uk.js → wizard-session-C5lZPPEc.js} +1 -1
- package/dist/{yara-hooks-CGzlyuQA.js → yara-hooks-CKsVxWiN.js} +139 -56
- package/dist/yara-hooks-CKsVxWiN.js.map +1 -0
- package/dist/yara-hooks-DWRdZQuG.js +2 -0
- package/package.json +7 -7
- package/dist/agent-interface-C_aRBziP.js.map +0 -1
- package/dist/agent-runner-NzzrOB02.js.map +0 -1
- package/dist/analytics-C7QE7PWl.js +0 -2
- package/dist/analytics-CArgq7XO.js.map +0 -1
- package/dist/commandments-qTW7pwaT.js +0 -2
- package/dist/debug-dX5JKcxf.js.map +0 -1
- package/dist/environment-D-xSv8Xv.js.map +0 -1
- package/dist/file-utils-BpTQ4NFR.js +0 -140
- package/dist/file-utils-BpTQ4NFR.js.map +0 -1
- package/dist/mcp-B9NosVx4.js +0 -104
- package/dist/mcp-B9NosVx4.js.map +0 -1
- package/dist/pi--w-M8eD-.js.map +0 -1
- package/dist/posthog-integration-Dk1hbtRQ.js.map +0 -1
- package/dist/queue-tools-DW-pUVKK.js.map +0 -1
- package/dist/registry-CYNjgbAh.js.map +0 -1
- package/dist/setup-utils-D5RLhAEe.js.map +0 -1
- package/dist/start-tui-Dvk-0lGv.js.map +0 -1
- package/dist/task-C-r2xQvb.js.map +0 -1
- package/dist/tools-C5Lsz2zR.js.map +0 -1
- package/dist/yara-hooks-CGzlyuQA.js.map +0 -1
- package/dist/yara-hooks-CQaKM0f4.js +0 -2
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { s as logToFile } from "./debug-C3ZR1TVF.js";
|
|
2
|
+
import { n as analytics } from "./analytics-BXz4SIuS.js";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import fg from "fast-glob";
|
|
6
|
+
//#region src/utils/bounded-fs.ts
|
|
7
|
+
/**
|
|
8
|
+
* Bounded filesystem primitives for scanning USER project trees. Every
|
|
9
|
+
* detection-time glob, walk, and project-file read goes through here so the
|
|
10
|
+
* worst case is a constant, never a function of the user's repo.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Errno codes that are expected while walking an arbitrary tree and mean
|
|
14
|
+
* "skip this entry", not "something is broken". Scanning from a broad dir
|
|
15
|
+
* (e.g. `~`) routinely hits OS-protected paths (macOS `Library/Group
|
|
16
|
+
* Containers/group.com.apple.*`) that throw EPERM/EACCES per entry — capturing
|
|
17
|
+
* each as an exception buried real errors under thousands of noise events.
|
|
18
|
+
*/
|
|
19
|
+
const BENIGN_FS_ERROR_CODES = new Set([
|
|
20
|
+
"EACCES",
|
|
21
|
+
"EPERM",
|
|
22
|
+
"ENOENT",
|
|
23
|
+
"ENOTDIR",
|
|
24
|
+
"ELOOP",
|
|
25
|
+
"ENAMETOOLONG",
|
|
26
|
+
"EMFILE",
|
|
27
|
+
"ENFILE"
|
|
28
|
+
]);
|
|
29
|
+
/**
|
|
30
|
+
* Report a swallowed filesystem error. Traversal stays best-effort — the caller
|
|
31
|
+
* still skips the failing entry. Expected errno codes (permission denied, entry
|
|
32
|
+
* vanished, symlink loops…) are logged to the debug file only; anything else is
|
|
33
|
+
* genuinely unexpected and gets captured to error tracking. Preserves the
|
|
34
|
+
* original Error (and its `code`, e.g. EACCES / ENOENT) when available.
|
|
35
|
+
*/
|
|
36
|
+
function reportFsError(step, filePath, error) {
|
|
37
|
+
const code = error?.code;
|
|
38
|
+
if (code && BENIGN_FS_ERROR_CODES.has(code)) {
|
|
39
|
+
logToFile(`[bounded-fs] skipped ${step} (${code}): ${filePath}`);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
analytics.captureException(error instanceof Error ? error : new Error(String(error)), {
|
|
43
|
+
step,
|
|
44
|
+
path: filePath
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Directory names to skip when scanning a project tree — dependency
|
|
49
|
+
* directories, build output, virtual environments, vendored trees.
|
|
50
|
+
* Used verbatim by walkProjectFiles and as glob patterns by boundedGlob.
|
|
51
|
+
*/
|
|
52
|
+
const IGNORED_DIRS = new Set([
|
|
53
|
+
"node_modules",
|
|
54
|
+
".git",
|
|
55
|
+
".next",
|
|
56
|
+
".nuxt",
|
|
57
|
+
".svelte-kit",
|
|
58
|
+
".turbo",
|
|
59
|
+
".cache",
|
|
60
|
+
".parcel-cache",
|
|
61
|
+
"dist",
|
|
62
|
+
"build",
|
|
63
|
+
"out",
|
|
64
|
+
"coverage",
|
|
65
|
+
".coverage",
|
|
66
|
+
"venv",
|
|
67
|
+
".venv",
|
|
68
|
+
"__pycache__",
|
|
69
|
+
".pytest_cache",
|
|
70
|
+
"vendor",
|
|
71
|
+
"target",
|
|
72
|
+
".gradle",
|
|
73
|
+
".idea",
|
|
74
|
+
".vscode",
|
|
75
|
+
"site-packages",
|
|
76
|
+
"DerivedData",
|
|
77
|
+
"Pods"
|
|
78
|
+
]);
|
|
79
|
+
/** IGNORED_DIRS as fast-glob ignore patterns. */
|
|
80
|
+
const PROJECT_IGNORE_GLOBS = [...IGNORED_DIRS].map((dir) => `**/${dir}/**`);
|
|
81
|
+
const MAX_PROJECT_FILE_BYTES = 2 * 1024 * 1024;
|
|
82
|
+
const GLOB_DEADLINE_MS = 8e3;
|
|
83
|
+
/**
|
|
84
|
+
* Streams matches, stops at `limit`, destroys the crawl at GLOB_DEADLINE_MS.
|
|
85
|
+
* Returns paths relative to `cwd`, possibly truncated.
|
|
86
|
+
*/
|
|
87
|
+
async function boundedGlob(patterns, options) {
|
|
88
|
+
const limit = options.limit ?? 500;
|
|
89
|
+
const stream = fg.stream(patterns, {
|
|
90
|
+
cwd: options.cwd,
|
|
91
|
+
dot: options.dot ?? false,
|
|
92
|
+
onlyFiles: true,
|
|
93
|
+
deep: options.deep,
|
|
94
|
+
ignore: [...PROJECT_IGNORE_GLOBS, ...options.extraIgnore ?? []],
|
|
95
|
+
suppressErrors: true,
|
|
96
|
+
followSymbolicLinks: false
|
|
97
|
+
});
|
|
98
|
+
const matches = [];
|
|
99
|
+
return new Promise((resolve) => {
|
|
100
|
+
let settled = false;
|
|
101
|
+
const finish = () => {
|
|
102
|
+
if (settled) return;
|
|
103
|
+
settled = true;
|
|
104
|
+
clearTimeout(timer);
|
|
105
|
+
resolve(matches);
|
|
106
|
+
};
|
|
107
|
+
const timer = setTimeout(() => {
|
|
108
|
+
stream.destroy();
|
|
109
|
+
finish();
|
|
110
|
+
}, GLOB_DEADLINE_MS);
|
|
111
|
+
stream.on("data", (entry) => {
|
|
112
|
+
matches.push(String(entry));
|
|
113
|
+
if (matches.length >= limit) {
|
|
114
|
+
stream.destroy();
|
|
115
|
+
finish();
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
stream.once("error", finish);
|
|
119
|
+
stream.once("end", finish);
|
|
120
|
+
stream.once("close", finish);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Walk a project tree, invoking `onFile(name, fullPath)` for every regular
|
|
125
|
+
* file — including dotfiles like `.env` (the caller decides what it cares
|
|
126
|
+
* about). Skips `IGNORED_DIRS` and hidden directories, follows symlinked
|
|
127
|
+
* directories with realpath-based loop protection, descends at most
|
|
128
|
+
* `maxDepth` levels below `rootDir`, and stops at the per-directory and
|
|
129
|
+
* whole-walk caps. Filesystem errors are reported and skipped (best-effort).
|
|
130
|
+
*/
|
|
131
|
+
function walkProjectFiles(rootDir, onFile, maxDepth = 3) {
|
|
132
|
+
const visited = /* @__PURE__ */ new Set();
|
|
133
|
+
let filesSeen = 0;
|
|
134
|
+
const stack = [{
|
|
135
|
+
dir: rootDir,
|
|
136
|
+
depth: 0
|
|
137
|
+
}];
|
|
138
|
+
while (stack.length > 0 && filesSeen < 1e5) {
|
|
139
|
+
const { dir, depth } = stack.pop();
|
|
140
|
+
let realDir;
|
|
141
|
+
try {
|
|
142
|
+
realDir = fs.realpathSync(dir);
|
|
143
|
+
} catch (error) {
|
|
144
|
+
reportFsError("walkProjectFiles.realpath", dir, error);
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (visited.has(realDir)) continue;
|
|
148
|
+
visited.add(realDir);
|
|
149
|
+
let handle;
|
|
150
|
+
try {
|
|
151
|
+
handle = fs.opendirSync(dir);
|
|
152
|
+
} catch (error) {
|
|
153
|
+
reportFsError("walkProjectFiles.opendir", dir, error);
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
try {
|
|
157
|
+
let entriesRead = 0;
|
|
158
|
+
let entry;
|
|
159
|
+
while ((entry = handle.readSync()) !== null) {
|
|
160
|
+
if (++entriesRead > 1e4 || filesSeen >= 1e5) {
|
|
161
|
+
logToFile(`[bounded-fs] walk capped in ${dir} (entries=${entriesRead}, files=${filesSeen})`);
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
165
|
+
const fullPath = path.join(dir, entry.name);
|
|
166
|
+
let isDir = entry.isDirectory();
|
|
167
|
+
let isFile = entry.isFile();
|
|
168
|
+
if (entry.isSymbolicLink()) try {
|
|
169
|
+
const st = fs.statSync(fullPath);
|
|
170
|
+
isDir = st.isDirectory();
|
|
171
|
+
isFile = st.isFile();
|
|
172
|
+
} catch (error) {
|
|
173
|
+
reportFsError("walkProjectFiles.stat", fullPath, error);
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
if (isDir) {
|
|
177
|
+
if (entry.name.startsWith(".")) continue;
|
|
178
|
+
if (depth < maxDepth) stack.push({
|
|
179
|
+
dir: fullPath,
|
|
180
|
+
depth: depth + 1
|
|
181
|
+
});
|
|
182
|
+
} else if (isFile) {
|
|
183
|
+
filesSeen += 1;
|
|
184
|
+
onFile(entry.name, fullPath);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
} finally {
|
|
188
|
+
try {
|
|
189
|
+
handle.closeSync();
|
|
190
|
+
} catch {}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Read a project file as UTF-8, or null when missing, unreadable, or over
|
|
196
|
+
* `maxBytes` (stat-gated: an oversized file is never materialized).
|
|
197
|
+
*/
|
|
198
|
+
function readProjectFile(filePath, maxBytes = MAX_PROJECT_FILE_BYTES) {
|
|
199
|
+
try {
|
|
200
|
+
if (fs.statSync(filePath).size > maxBytes) return null;
|
|
201
|
+
return fs.readFileSync(filePath, "utf-8");
|
|
202
|
+
} catch {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* `readProjectFile` that also reports unexpected errors to error tracking.
|
|
208
|
+
* For walk callbacks where a failing read is worth a telemetry breadcrumb.
|
|
209
|
+
*/
|
|
210
|
+
function safeReadFile(fullPath) {
|
|
211
|
+
try {
|
|
212
|
+
if (fs.statSync(fullPath).size > 2097152) {
|
|
213
|
+
logToFile(`[bounded-fs] skipped oversized file: ${fullPath}`);
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
return fs.readFileSync(fullPath, "utf-8");
|
|
217
|
+
} catch (error) {
|
|
218
|
+
reportFsError("safeReadFile", fullPath, error);
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* The first `bytes` of a file without materializing the rest.
|
|
224
|
+
*/
|
|
225
|
+
function readFileHead(filePath, bytes) {
|
|
226
|
+
try {
|
|
227
|
+
const fd = fs.openSync(filePath, "r");
|
|
228
|
+
try {
|
|
229
|
+
const buffer = Buffer.alloc(bytes);
|
|
230
|
+
const read = fs.readSync(fd, buffer, 0, bytes, 0);
|
|
231
|
+
return buffer.toString("utf-8", 0, read);
|
|
232
|
+
} finally {
|
|
233
|
+
fs.closeSync(fd);
|
|
234
|
+
}
|
|
235
|
+
} catch {
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
//#endregion
|
|
240
|
+
export { walkProjectFiles as a, safeReadFile as i, readFileHead as n, readProjectFile as r, boundedGlob as t };
|
|
241
|
+
|
|
242
|
+
//# sourceMappingURL=bounded-fs-Cx-8nk-1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bounded-fs-Cx-8nk-1.js","names":[],"sources":["../src/utils/bounded-fs.ts"],"sourcesContent":["/**\n * Bounded filesystem primitives for scanning USER project trees. Every\n * detection-time glob, walk, and project-file read goes through here so the\n * worst case is a constant, never a function of the user's repo.\n */\nimport path from 'path';\nimport fs from 'fs';\nimport type { Dirent } from 'fs';\nimport fg from 'fast-glob';\nimport { analytics } from './analytics';\nimport { logToFile } from './debug';\nimport type { WizardRunOptions } from './types';\n\n/**\n * Errno codes that are expected while walking an arbitrary tree and mean\n * \"skip this entry\", not \"something is broken\". Scanning from a broad dir\n * (e.g. `~`) routinely hits OS-protected paths (macOS `Library/Group\n * Containers/group.com.apple.*`) that throw EPERM/EACCES per entry — capturing\n * each as an exception buried real errors under thousands of noise events.\n */\nconst BENIGN_FS_ERROR_CODES = new Set<string>([\n 'EACCES', // permission denied\n 'EPERM', // operation not permitted (macOS-protected dirs)\n 'ENOENT', // entry vanished mid-walk\n 'ENOTDIR', // path component isn't a directory\n 'ELOOP', // symlink loop\n 'ENAMETOOLONG', // path too long\n 'EMFILE', // too many open files (environmental, not a wizard bug)\n 'ENFILE',\n]);\n\n/**\n * Report a swallowed filesystem error. Traversal stays best-effort — the caller\n * still skips the failing entry. Expected errno codes (permission denied, entry\n * vanished, symlink loops…) are logged to the debug file only; anything else is\n * genuinely unexpected and gets captured to error tracking. Preserves the\n * original Error (and its `code`, e.g. EACCES / ENOENT) when available.\n */\nfunction reportFsError(step: string, filePath: string, error: unknown): void {\n const code = (error as NodeJS.ErrnoException | null)?.code;\n if (code && BENIGN_FS_ERROR_CODES.has(code)) {\n logToFile(`[bounded-fs] skipped ${step} (${code}): ${filePath}`);\n return;\n }\n analytics.captureException(\n error instanceof Error ? error : new Error(String(error)),\n { step, path: filePath },\n );\n}\n\nexport function getDotGitignore({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>) {\n const gitignorePath = path.join(installDir, '.gitignore');\n const gitignoreExists = fs.existsSync(gitignorePath);\n\n if (gitignoreExists) {\n return gitignorePath;\n }\n\n return undefined;\n}\n\n/**\n * Directory names to skip when scanning a project tree — dependency\n * directories, build output, virtual environments, vendored trees.\n * Used verbatim by walkProjectFiles and as glob patterns by boundedGlob.\n */\nexport const IGNORED_DIRS = new Set<string>([\n 'node_modules',\n '.git',\n '.next',\n '.nuxt',\n '.svelte-kit',\n '.turbo',\n '.cache',\n '.parcel-cache',\n 'dist',\n 'build',\n 'out',\n 'coverage',\n '.coverage',\n 'venv',\n '.venv',\n '__pycache__',\n '.pytest_cache',\n 'vendor',\n 'target',\n '.gradle',\n '.idea',\n '.vscode',\n 'site-packages',\n 'DerivedData',\n 'Pods',\n]);\n\n/** IGNORED_DIRS as fast-glob ignore patterns. */\nexport const PROJECT_IGNORE_GLOBS: readonly string[] = [...IGNORED_DIRS].map(\n (dir) => `**/${dir}/**`,\n);\n\n// Files larger than this are skipped, never materialized.\nexport const MAX_PROJECT_FILE_BYTES = 2 * 1024 * 1024;\n\n// A glob returns at most this many entries.\nexport const MAX_GLOB_MATCHES = 500;\n\n// A glob's traversal is destroyed after this long, even when abandoned.\nexport const GLOB_DEADLINE_MS = 8_000;\n\n// A directory contributes at most this many entries to a walk.\nexport const MAX_DIR_ENTRIES = 10_000;\n\n// A walk fires at most this many onFile callbacks.\nexport const MAX_WALK_FILES = 100_000;\n\nexport interface BoundedGlobOptions {\n cwd: string;\n /** Appended to PROJECT_IGNORE_GLOBS. */\n extraIgnore?: readonly string[];\n /** Stop after this many matches. Defaults to MAX_GLOB_MATCHES. */\n limit?: number;\n /** Match dotfiles. Traversal of dot-DIRECTORIES stays blocked by the ignore set. */\n dot?: boolean;\n /** fast-glob `deep` — maximum directory depth. */\n deep?: number;\n}\n\n/**\n * Streams matches, stops at `limit`, destroys the crawl at GLOB_DEADLINE_MS.\n * Returns paths relative to `cwd`, possibly truncated.\n */\nexport async function boundedGlob(\n patterns: string | string[],\n options: BoundedGlobOptions,\n): Promise<string[]> {\n const limit = options.limit ?? MAX_GLOB_MATCHES;\n const stream = fg.stream(patterns, {\n cwd: options.cwd,\n dot: options.dot ?? false,\n onlyFiles: true,\n deep: options.deep,\n ignore: [...PROJECT_IGNORE_GLOBS, ...(options.extraIgnore ?? [])],\n suppressErrors: true,\n followSymbolicLinks: false,\n });\n\n const matches: string[] = [];\n return new Promise((resolve) => {\n let settled = false;\n const finish = (): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve(matches);\n };\n const timer = setTimeout(() => {\n stream.destroy();\n finish();\n }, GLOB_DEADLINE_MS);\n stream.on('data', (entry: string | Buffer) => {\n matches.push(String(entry));\n if (matches.length >= limit) {\n stream.destroy();\n finish();\n }\n });\n stream.once('error', finish);\n stream.once('end', finish);\n stream.once('close', finish);\n });\n}\n\n/**\n * Walk a project tree, invoking `onFile(name, fullPath)` for every regular\n * file — including dotfiles like `.env` (the caller decides what it cares\n * about). Skips `IGNORED_DIRS` and hidden directories, follows symlinked\n * directories with realpath-based loop protection, descends at most\n * `maxDepth` levels below `rootDir`, and stops at the per-directory and\n * whole-walk caps. Filesystem errors are reported and skipped (best-effort).\n */\nexport function walkProjectFiles(\n rootDir: string,\n onFile: (name: string, fullPath: string) => void,\n maxDepth = 3,\n): void {\n const visited = new Set<string>();\n let filesSeen = 0;\n // Explicit stack — no call-stack recursion.\n const stack: Array<{ dir: string; depth: number }> = [\n { dir: rootDir, depth: 0 },\n ];\n\n while (stack.length > 0 && filesSeen < MAX_WALK_FILES) {\n const { dir, depth } = stack.pop()!;\n\n // realpath both resolves symlinked dirs and gives us a stable key to\n // detect loops (symlink cycles, e.g. a -> ../a).\n let realDir: string;\n try {\n realDir = fs.realpathSync(dir);\n } catch (error) {\n reportFsError('walkProjectFiles.realpath', dir, error);\n continue;\n }\n if (visited.has(realDir)) continue;\n visited.add(realDir);\n\n let handle: fs.Dir;\n try {\n handle = fs.opendirSync(dir);\n } catch (error) {\n reportFsError('walkProjectFiles.opendir', dir, error);\n continue;\n }\n try {\n let entriesRead = 0;\n let entry: Dirent | null;\n while ((entry = handle.readSync()) !== null) {\n if (++entriesRead > MAX_DIR_ENTRIES || filesSeen >= MAX_WALK_FILES) {\n logToFile(\n `[bounded-fs] walk capped in ${dir} (entries=${entriesRead}, files=${filesSeen})`,\n );\n break;\n }\n if (IGNORED_DIRS.has(entry.name)) continue;\n\n const fullPath = path.join(dir, entry.name);\n\n // Symlinks report isDirectory()/isFile() as false under withFileTypes,\n // so resolve the target before deciding how to handle the entry.\n let isDir = entry.isDirectory();\n let isFile = entry.isFile();\n if (entry.isSymbolicLink()) {\n try {\n const st = fs.statSync(fullPath);\n isDir = st.isDirectory();\n isFile = st.isFile();\n } catch (error) {\n reportFsError('walkProjectFiles.stat', fullPath, error);\n continue;\n }\n }\n\n if (isDir) {\n if (entry.name.startsWith('.')) continue; // skip hidden directories\n if (depth < maxDepth) stack.push({ dir: fullPath, depth: depth + 1 });\n } else if (isFile) {\n filesSeen += 1;\n onFile(entry.name, fullPath);\n }\n }\n } finally {\n try {\n handle.closeSync();\n } catch {\n /* already closed */\n }\n }\n }\n}\n\n/**\n * Read a project file as UTF-8, or null when missing, unreadable, or over\n * `maxBytes` (stat-gated: an oversized file is never materialized).\n */\nexport function readProjectFile(\n filePath: string,\n maxBytes = MAX_PROJECT_FILE_BYTES,\n): string | null {\n try {\n if (fs.statSync(filePath).size > maxBytes) return null;\n return fs.readFileSync(filePath, 'utf-8');\n } catch {\n return null;\n }\n}\n\n/**\n * `readProjectFile` that also reports unexpected errors to error tracking.\n * For walk callbacks where a failing read is worth a telemetry breadcrumb.\n */\nexport function safeReadFile(fullPath: string): string | null {\n try {\n if (fs.statSync(fullPath).size > MAX_PROJECT_FILE_BYTES) {\n logToFile(`[bounded-fs] skipped oversized file: ${fullPath}`);\n return null;\n }\n return fs.readFileSync(fullPath, 'utf-8');\n } catch (error) {\n reportFsError('safeReadFile', fullPath, error);\n return null;\n }\n}\n\n/**\n * The first `bytes` of a file without materializing the rest.\n */\nexport function readFileHead(filePath: string, bytes: number): string | null {\n try {\n const fd = fs.openSync(filePath, 'r');\n try {\n const buffer = Buffer.alloc(bytes);\n const read = fs.readSync(fd, buffer, 0, bytes, 0);\n return buffer.toString('utf-8', 0, read);\n } finally {\n fs.closeSync(fd);\n }\n } catch {\n return null;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { f as getUI, m as LoggingUI, p as setUI } from "./debug-
|
|
2
|
-
import { t as provisionNewAccount } from "./provisioning-
|
|
3
|
-
import { r as posthogIntegrationConfig } from "./posthog-integration-
|
|
1
|
+
import { f as getUI, m as LoggingUI, p as setUI } from "./debug-C3ZR1TVF.js";
|
|
2
|
+
import { t as provisionNewAccount } from "./provisioning-T4jtJqBa.js";
|
|
3
|
+
import { r as posthogIntegrationConfig } from "./posthog-integration-pnxhTbxw.js";
|
|
4
4
|
import { c as runWizardCI, s as runWizardHeadless } from "./bin.js";
|
|
5
5
|
//#region src/commands/basic-integration/ci-install.ts
|
|
6
6
|
/**
|
|
@@ -110,4 +110,4 @@ async function provisionForSignup(options) {
|
|
|
110
110
|
//#endregion
|
|
111
111
|
export { runCIInstall, runHeadlessInstall };
|
|
112
112
|
|
|
113
|
-
//# sourceMappingURL=ci-install-
|
|
113
|
+
//# sourceMappingURL=ci-install-D1Mum8Ah.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ci-install-
|
|
1
|
+
{"version":3,"file":"ci-install-D1Mum8Ah.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 baseUrl?: 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 { baseUrl: options.baseUrl },\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":";;;;;;;;;AAuBA,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,cACA,EAAE,SAAS,QAAQ,SAAS,CAC7B;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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commandments-
|
|
1
|
+
{"version":3,"file":"commandments-DiMtIz1o.js","names":[],"sources":["../src/lib/agent/commandments.ts"],"sourcesContent":["/**\n * Wizard-wide commandments that are always appended as a system prompt.\n *\n * Keep this as a simple string so it can be inlined into the compiled bundle\n * without extra files, copying, or runtime I/O.\n */\nconst WIZARD_COMMANDMENTS = [\n 'Never hallucinate a PostHog project token, host, or any other secret. Always use the real values that have been configured for this project (for example via environment variables).',\n\n 'Never substitute an empty string or placeholder for the project token when its source is missing — an empty key silently disables analytics with no error. The token is a public client-side key: read it from the environment or config, and where a build genuinely has no environment to read from (e.g. iOS/Android release and archive builds), embed the real token so a value always ships — never an empty one.',\n\n 'Never write API keys, access tokens, or other secrets directly into source code. Always reference environment variables instead, and rely on the wizard-tools MCP server (check_env_keys / set_env_values) to create or update .env files.',\n\n 'Always use the detect_package_manager tool from the wizard-tools MCP server to determine the package manager. Do not guess based on lockfiles or hard-code npm, yarn, pnpm, bun, pip, etc.',\n\n 'Before writing to any file, you MUST read that exact file immediately beforehand using the Read tool, even if you have already read it earlier in the run. This avoids tool failures and stale edits.',\n\n 'Treat feature flags, custom properties, and event names as part of an analytics contract. Prefer reusing existing names and patterns in the project. When you must introduce new ones, make them clear, descriptive, and consistent with existing conventions, and avoid scattering the same flag or property across many unrelated callsites.',\n\n 'Keep PostHog data capture at its defaults unless the user explicitly asks otherwise. Do not disable autocapture, do not disable session recording, and never set opt_out_capturing (or opted_out) to true in the SDK init config — these turn off data the user almost always wants. Note: posthog.opt_out_capturing() called at runtime for GDPR consent flows is legitimate; the rule is about the init configuration.',\n\n \"Never put personally identifiable information — emails, full or partial names, phone numbers, physical or IP addresses, or other user-entered PII — in capture() event properties. PII belongs on the PERSON: send it via identify()/$set (or the SDK's person-property API), and capture events with a stable distinct id derived from the authenticated user or session, never a raw email or name. This holds for every SDK, client and server.\",\n\n 'Prefer minimal, targeted edits that achieve the requested behavior while preserving existing structure and style. Avoid large refactors, broad reformatting, or unrelated changes unless explicitly requested.',\n\n 'When you change a file that already exists, edit it in place. If an edit fails because the text you are matching is not unique, add just enough surrounding context to make it unique, or apply the change to each occurrence — never fall back to rewriting the whole file. Write a file in full only when you are creating it, never to modify one that already exists.',\n\n 'Before you overwrite or delete anything that already exists, look at what you would remove. This integration only adds instrumentation, so keep every part of the project unrelated to PostHog exactly as it was — never drop existing code, comments, or markup to make room for a change.',\n\n 'Do not spawn subagents unless explicitly instructed to do so.',\n\n 'Create tasks as soon as you understand the work you are going to carry out. Break the list into distinct stages of work that the user can follow through. Create all tasks in a single tool call, in the order you will be performing them. Drive the work with TaskUpdate: status in_progress when you begin a task, completed when done.',\n\n 'Keep task titles broad and stage-oriented — describe the purpose or area of work, not the specific files, paths, or symbols involved. Do not name individual files, modules, or directories inside task titles, and do not include illustrative examples within a task title.',\n\n 'Do not assume \"PostHog provider\" or \"PostHogProvider\" in task labels, status messages, or code. Only use a provider if the skill workflow explicitly requires one for the specific framework.',\n\n 'If you see a [YARA WARNING] or [YARA VIOLATION] message, handle it silently. Fix the issue (revert the write, avoid the flagged pattern) without mentioning security warnings or YARA to the user. These are internal guardrails, not user-facing alerts. Never show scary security language to the user.',\n\n // wizard_ask Path A — translate prose question lists into a single tool call.\n // The skill prose is intentionally underspecified; this commandment carries\n // most of the discipline. Tightening: prefer adding rules here over editing\n // individual skill markdown.\n [\n 'When a skill instructs you to gather information from the user, use the `wizard_ask` MCP tool from the wizard-tools server. Never inline questions in your text output expecting a reply — the user has no way to answer text.',\n 'When a skill provides a numbered or bulleted list of questions, translate the entire list into a single `wizard_ask` tool call:',\n ' - One tool call per skill step. Batch every question from that step into the `questions` array — never split into multiple calls.',\n ' - Infer `kind` from the question phrasing: comma-separated alternatives (\"React, Vue, or vanilla JS?\") → `single`; phrasing like \"all that apply\" or \"any of\" → `multi`; everything else → `text`.',\n ' - For `single` and `multi`, extract the alternatives from the prose into `options` as `{ label, value }` pairs. Use the human phrase as `label` and a lowercase-hyphenated form as `value` (e.g., `label: \"Vanilla JS\"`, `value: \"vanilla-js\"`).',\n ' - Use a kebab-case slug of the question label as `id` (e.g., \"Tech stack\" → `tech-stack`, \"Show frequency\" → `show-frequency`).',\n ' - Do not invent fields the schema does not define (no `source`, `category`, `priority`, etc.) — the tool rejects unknown fields and the wizard already knows which skill is running.',\n 'After `wizard_ask` returns, use the answers directly — do not re-ask in text or call `wizard_ask` again for the same fields.',\n ].join('\\n'),\n].join('\\n');\n\nexport function getWizardCommandments(): string {\n return WIZARD_COMMANDMENTS;\n}\n"],"mappings":";;;;;;;AAMA,MAAM,sBAAsB;CAC1B;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA;CAEA;CAMA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK;CACb,CAAC,KAAK,KAAK;AAEZ,SAAgB,wBAAgC;AAC9C,QAAO"}
|
|
@@ -61,7 +61,7 @@ function runtimeEnv(key) {
|
|
|
61
61
|
}
|
|
62
62
|
//#endregion
|
|
63
63
|
//#region src/lib/version.ts
|
|
64
|
-
const VERSION = "2.
|
|
64
|
+
const VERSION = "2.52.0";
|
|
65
65
|
//#endregion
|
|
66
66
|
//#region src/lib/constants.ts
|
|
67
67
|
/**
|
|
@@ -72,7 +72,7 @@ const VERSION = "2.50.0";
|
|
|
72
72
|
* LLM gateway's Bedrock fallback can match map_to_bedrock_model().
|
|
73
73
|
*/
|
|
74
74
|
const DEFAULT_AGENT_MODEL = "claude-sonnet-4-6";
|
|
75
|
-
/** Next sonnet generation
|
|
75
|
+
/** Next sonnet generation (a `MODEL_FLAG_VARIANTS` key in the switchboard). */
|
|
76
76
|
const SONNET_5_MODEL = "claude-sonnet-5";
|
|
77
77
|
/**
|
|
78
78
|
* Cheaper, faster model for mechanical agent work (e.g. repo classification
|
|
@@ -84,24 +84,9 @@ const HAIKU_MODEL = "claude-haiku-4-5-20251001";
|
|
|
84
84
|
* from `PROGRAM_BINDINGS[id].model` or `contextMillOverride`.
|
|
85
85
|
*/
|
|
86
86
|
const OPUS_MODEL = "claude-opus-4-8";
|
|
87
|
-
/**
|
|
88
|
-
* OpenAI-class peer of sonnet, served by the LLM gateway over OpenAI
|
|
89
|
-
* completions. Enables cross-provider A/B without a wizard release.
|
|
90
|
-
*/
|
|
91
|
-
const GPT5_MODEL = "openai/gpt-5";
|
|
92
|
-
/** Newer sonnet-class openai flagship (list: $2.50/$15 per MTok). */
|
|
93
|
-
const GPT5_4_MODEL = "openai/gpt-5.4";
|
|
94
|
-
/**
|
|
95
|
-
* Smaller, faster, cheaper openai reasoning model. The pi runner is paired with
|
|
96
|
-
* this (a reasoning model follows the integration skill; the mini tier keeps a
|
|
97
|
-
* run to a few minutes where flagship gpt-5 takes far longer). Reasoning effort
|
|
98
|
-
* is set per-model in the switchboard capability matrix.
|
|
99
|
-
*/
|
|
100
|
-
const GPT5_MINI_MODEL = "openai/gpt-5-mini";
|
|
101
87
|
const GPT5_6_LUNA_MODEL = "openai/gpt-5.6-luna";
|
|
102
88
|
const GPT5_6_TERRA_MODEL = "openai/gpt-5.6-terra";
|
|
103
89
|
const GPT5_6_SOL_MODEL = "openai/gpt-5.6-sol";
|
|
104
|
-
const GPT5_5_MODEL = "openai/gpt-5.5";
|
|
105
90
|
/**
|
|
106
91
|
* The two agent runner routing axes: **harness** (which agent SDK drives the LLM)
|
|
107
92
|
* and **sequence** (which pipeline shape orchestrates the work). Single source
|
|
@@ -264,18 +249,18 @@ const WIZARD_INTERACTION_EVENT_NAME = "wizard interaction";
|
|
|
264
249
|
const WIZARD_REMARK_EVENT_NAME = "wizard remark";
|
|
265
250
|
/** Boolean feature flag that routes a run to the experimental orchestrator runner. */
|
|
266
251
|
const WIZARD_ORCHESTRATOR_FLAG_KEY = "wizard-orchestrator";
|
|
267
|
-
/**
|
|
268
|
-
const
|
|
269
|
-
/**
|
|
270
|
-
const WIZARD_PI_MODEL_FLAG_KEY = "wizard-pi-model";
|
|
271
|
-
/** Multivariate flag: reasoning-effort override for pi models (minimal/low/medium/high/xhigh). */
|
|
272
|
-
const WIZARD_PI_EFFORT_FLAG_KEY = "wizard-pi-effort";
|
|
273
|
-
/** Boolean flag: on → pi for self-driving. Payload carries `{model, effort?, harness?, sequence?}` (model = wizard-pi-model variant key); missing/invalid payload keeps the non-flagged default. */
|
|
252
|
+
/** Multivariate flag: per-stage orchestrator overrides ride each variant's JSON payload (`{stage: {model?, effort?}}`). */
|
|
253
|
+
const WIZARD_ORCHESTRATOR_OVERRIDE_FLAG_KEY = "wizard-orchestrator-override";
|
|
254
|
+
/** 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. */
|
|
274
255
|
const WIZARD_SELF_DRIVING_USE_PI_HARNESS_FLAG_KEY = "wizard-self-driving-use-pi-harness";
|
|
275
|
-
/** Feature flag key that gates the intro-screen "Tools" menu. */
|
|
276
|
-
const WIZARD_TOOLS_MENU_FLAG_KEY = "wizard-tools-menu";
|
|
277
256
|
/** Boolean flag: agentic project scoping for non-interactive basic-integration runs. */
|
|
278
257
|
const WIZARD_BASIC_INTEGRATION_AGENTIC_DETECTION_FLAG_KEY = "wizard-basic-integration-agentic-detection";
|
|
258
|
+
const WIZARD_FLAG_KEYS = [
|
|
259
|
+
WIZARD_ORCHESTRATOR_FLAG_KEY,
|
|
260
|
+
WIZARD_ORCHESTRATOR_OVERRIDE_FLAG_KEY,
|
|
261
|
+
WIZARD_SELF_DRIVING_USE_PI_HARNESS_FLAG_KEY,
|
|
262
|
+
WIZARD_BASIC_INTEGRATION_AGENTIC_DETECTION_FLAG_KEY
|
|
263
|
+
];
|
|
279
264
|
/** User-Agent for wizard HTTP requests and MCP server identification. */
|
|
280
265
|
const WIZARD_USER_AGENT = `posthog/wizard; version: ${VERSION}`;
|
|
281
266
|
/**
|
|
@@ -984,7 +969,7 @@ let reportedLogFailure = false;
|
|
|
984
969
|
function reportLogFailureOnce(err) {
|
|
985
970
|
if (reportedLogFailure) return;
|
|
986
971
|
reportedLogFailure = true;
|
|
987
|
-
import("./analytics-
|
|
972
|
+
import("./analytics-D2xds3nw.js").then(({ analytics }) => analytics.captureException(err instanceof Error ? err : new Error(String(err)), {
|
|
988
973
|
source: "log-file-write",
|
|
989
974
|
log_path: logFilePath,
|
|
990
975
|
platform: process.platform
|
|
@@ -1028,6 +1013,6 @@ function enableDebugLogs() {
|
|
|
1028
1013
|
consoleLoggingEnabled = true;
|
|
1029
1014
|
}
|
|
1030
1015
|
//#endregion
|
|
1031
|
-
export {
|
|
1016
|
+
export { SONNET_5_MODEL as $, GPT5_6_LUNA_MODEL as A, POSTHOG_APP_URL as B, ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY as C, DEFAULT_AGENT_MODEL as D, CONTEXT_MILL_URL as E, ISSUES_URL as F, POSTHOG_ORG_AI_SETTINGS_URL as G, POSTHOG_DOCS_URL as H, Integration as I, POSTHOG_PROXY_CLIENT_ID as J, POSTHOG_PRIVACY_URL as K, OAUTH_PORTS as L, GPT5_6_TERRA_MODEL as M, HAIKU_MODEL as N, DETECTION_TIMEOUT_MS as O, Harness as P, REMOTE_SKILLS_BASE_URL as Q, OAUTH_TIMEOUT_MS as R, ANALYTICS_HOST_URL as S, CONTEXT_MILL_RELEASES_URL as T, POSTHOG_EU_CLIENT_ID as U, POSTHOG_DEV_CLIENT_ID as V, POSTHOG_FLAG_HEADER_PREFIX as W, POSTHOG_TERMS_URL as X, POSTHOG_STATUS_PAGE_URL as Y, POSTHOG_US_CLIENT_ID as Z, evaluateWizardReadiness as _, runtimeEnv as _t, getLogFilePath as a, WIZARD_OAUTH_SCOPES as at, isTaskStatus as b, regionOption as bt, WIZARD_BENCHMARK_FILE as c, WIZARD_PROVISIONING_SCOPES as ct, relativeToInstallDir as d, WIZARD_USER_AGENT as dt, Sequence as et, getUI as f, getSkillsBaseUrl as ft, SIGNUP_WIZARD_READINESS_CONFIG as g, RUN_SURFACE as gt, SERVICE_LABELS as h, NODE_ENV as ht, enableDebugLogs as i, WIZARD_INTERACTION_EVENT_NAME as it, GPT5_6_SOL_MODEL as j, DUMMY_PROJECT_API_KEY as k, WIZARD_LOG_FILE as l, WIZARD_REMARK_EVENT_NAME as lt, LoggingUI as m, VERSION as mt, configureLogFileFromEnvironment as n, WIZARD_CONTACT_EMAIL as nt, initLogFile as o, WIZARD_ORCHESTRATOR_FLAG_KEY as ot, setUI as p, wizardUserAgentForProgram as pt, POSTHOG_PROPERTY_HEADER_PREFIX as q, debug as r, WIZARD_FLAG_KEYS as rt, logToFile as s, WIZARD_ORCHESTRATOR_OVERRIDE_FLAG_KEY as st, configureLogFile as t, WIZARD_BASIC_INTEGRATION_AGENTIC_DETECTION_FLAG_KEY as tt, WIZARD_YARA_REPORT_FILE as u, WIZARD_SELF_DRIVING_USE_PI_HARNESS_FLAG_KEY as ut, getBlockingServiceKeys as v, headlessOption as vt, ANALYTICS_TEAM_TAG as w, AGENTIC_DETECTION_TIMEOUT_MS as x, TaskStatus as y, isHeadless as yt, OPUS_MODEL as z };
|
|
1032
1017
|
|
|
1033
|
-
//# sourceMappingURL=debug-
|
|
1018
|
+
//# sourceMappingURL=debug-C3ZR1TVF.js.map
|