@posthog/wizard 2.44.0 → 2.45.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-D5qsqCkj.js → add-mcp-server-to-clients-CNzZMSat.js} +5 -5
- package/dist/{add-mcp-server-to-clients-D5qsqCkj.js.map → add-mcp-server-to-clients-CNzZMSat.js.map} +1 -1
- package/dist/{agent-interface-BvTxWiol.js → agent-interface-CF7GsdFf.js} +297 -157
- package/dist/agent-interface-CF7GsdFf.js.map +1 -0
- package/dist/{agent-runner-BF6_f8Qh.js → agent-runner-B0LTVFfw.js} +130 -598
- package/dist/agent-runner-B0LTVFfw.js.map +1 -0
- package/dist/{analytics-DSlQuwOT.js → analytics-DQEuL6qS.js} +2 -2
- package/dist/{analytics-DSlQuwOT.js.map → analytics-DQEuL6qS.js.map} +1 -1
- package/dist/analytics-YD3D38z2.js +2 -0
- package/dist/{api-BXduJZrw.js → api-uCMvDII5.js} +3 -3
- package/dist/{api-BXduJZrw.js.map → api-uCMvDII5.js.map} +1 -1
- package/dist/bin.js +57 -101
- package/dist/bin.js.map +1 -1
- package/dist/{ci-install-GirEJqu2.js → ci-install-Bow8-f0j.js} +4 -4
- package/dist/{ci-install-GirEJqu2.js.map → ci-install-Bow8-f0j.js.map} +1 -1
- package/dist/commandments-CyB7Icr1.js +42 -0
- package/dist/commandments-CyB7Icr1.js.map +1 -0
- package/dist/commandments-DguPfCX8.js +2 -0
- package/dist/{debug-BOFxiVVs.js → debug-BixHZmHv.js} +1 -1
- package/dist/{debug-DXfQFmcM.js → debug-DBmxx59Q.js} +21 -5
- package/dist/debug-DBmxx59Q.js.map +1 -0
- package/dist/{defaults-BWLIffh5.js → defaults-8zjNjGGi.js} +1 -1
- package/dist/{defaults-BWLIffh5.js.map → defaults-8zjNjGGi.js.map} +1 -1
- package/dist/{env-api-key-cjD4yfGT.js → env-api-key-AcC_tz8G.js} +1 -1
- package/dist/{env-api-key-cjD4yfGT.js.map → env-api-key-AcC_tz8G.js.map} +1 -1
- package/dist/{environment-F1yw21dG.js → environment-kZtkp7eG.js} +3 -3
- package/dist/{environment-F1yw21dG.js.map → environment-kZtkp7eG.js.map} +1 -1
- package/dist/{file-utils-D-7YfJ7A.js → file-utils-BAhYy5vC.js} +2 -2
- package/dist/{file-utils-D-7YfJ7A.js.map → file-utils-BAhYy5vC.js.map} +1 -1
- package/dist/file-watcher-BL-IRbR7.js +123 -0
- package/dist/file-watcher-BL-IRbR7.js.map +1 -0
- package/dist/{headless-ui-Dni0gPND.js → headless-ui-DWmMyhaP.js} +5 -4
- package/dist/headless-ui-DWmMyhaP.js.map +1 -0
- package/dist/{interactive-Bmi82rsO.js → interactive-Cyic0bGL.js} +2 -2
- package/dist/{interactive-Bmi82rsO.js.map → interactive-Cyic0bGL.js.map} +1 -1
- package/dist/{mcp-xKRDnrcq.js → mcp-BSGmEWjt.js} +3 -3
- package/dist/mcp-BSGmEWjt.js.map +1 -0
- package/dist/{mcp-prompt-streaming-AtntLsJ8.js → mcp-prompt-streaming-C227vG1X.js} +3 -3
- package/dist/{mcp-prompt-streaming-AtntLsJ8.js.map → mcp-prompt-streaming-C227vG1X.js.map} +1 -1
- package/dist/{non-interactive-BIHqcW8g.js → non-interactive-DQA9vn9f.js} +2 -2
- package/dist/{non-interactive-BIHqcW8g.js.map → non-interactive-DQA9vn9f.js.map} +1 -1
- package/dist/orchestrator-tools-NuWONNkF.js +99 -0
- package/dist/orchestrator-tools-NuWONNkF.js.map +1 -0
- package/dist/{package-json-CDs1ZVKu.js → package-json-DCuoye-H.js} +1 -1
- package/dist/{package-json-CDs1ZVKu.js.map → package-json-DCuoye-H.js.map} +1 -1
- package/dist/{package-manager-C6R_zpML.js → package-manager-DKtR3xzM.js} +2 -2
- package/dist/{package-manager-C6R_zpML.js.map → package-manager-DKtR3xzM.js.map} +1 -1
- package/dist/pi-DJCln9jJ.js +603 -0
- package/dist/pi-DJCln9jJ.js.map +1 -0
- package/dist/{playground-DwL36I2u.js → playground-CbEndzc8.js} +7 -8
- package/dist/{playground-DwL36I2u.js.map → playground-CbEndzc8.js.map} +1 -1
- package/dist/{posthog-DwKlq0HM.js → posthog-DFyux4Vw.js} +1 -1
- package/dist/{posthog-DwKlq0HM.js.map → posthog-DFyux4Vw.js.map} +1 -1
- package/dist/{posthog-integration-BhLKCFsI.js → posthog-integration-dmWJZ8mj.js} +131 -26
- package/dist/posthog-integration-dmWJZ8mj.js.map +1 -0
- package/dist/{provisioning-jVZm2E-A.js → provisioning-CcxCry5p.js} +3 -3
- package/dist/{provisioning-jVZm2E-A.js.map → provisioning-CcxCry5p.js.map} +1 -1
- package/dist/queue-tools-Bw-AANLM.js +366 -0
- package/dist/queue-tools-Bw-AANLM.js.map +1 -0
- package/dist/{registry-DcoBCMQR.js → registry-D2V88NoC.js} +96 -18
- package/dist/registry-D2V88NoC.js.map +1 -0
- package/dist/{security-jxjVsOpd.js → security-DOtBCBvx.js} +4 -4
- package/dist/{security-jxjVsOpd.js.map → security-DOtBCBvx.js.map} +1 -1
- package/dist/{setup-utils-BQCl28D8.js → setup-utils-Qp-u6BZk.js} +7 -7
- package/dist/{setup-utils-BQCl28D8.js.map → setup-utils-Qp-u6BZk.js.map} +1 -1
- package/dist/{start-tui-DgSKFMVh.js → start-tui-DHa_9aiB.js} +19 -80
- package/dist/start-tui-DHa_9aiB.js.map +1 -0
- package/dist/{steps-erepgD0V.js → steps-D07HUQyE.js} +7 -7
- package/dist/{steps-erepgD0V.js.map → steps-D07HUQyE.js.map} +1 -1
- package/dist/{store-C79GoHCQ.js → store-DSwsITKX.js} +5 -6
- package/dist/store-DSwsITKX.js.map +1 -0
- package/dist/{subagent-aDlD_Ltz.js → subagent-Dk4K5MDa.js} +2 -2
- package/dist/{subagent-aDlD_Ltz.js.map → subagent-Dk4K5MDa.js.map} +1 -1
- package/dist/task-CQnV9Qd2.js +305 -0
- package/dist/task-CQnV9Qd2.js.map +1 -0
- package/dist/{task-stream-0Pk0tPBN.js → task-stream-B7qia9eW.js} +72 -7
- package/dist/task-stream-B7qia9eW.js.map +1 -0
- package/dist/{tasks-ZkrluXCa.js → tasks-C7BQp659.js} +2 -2
- package/dist/{tasks-ZkrluXCa.js.map → tasks-C7BQp659.js.map} +1 -1
- package/dist/{telemetry-DZShaH-y.js → telemetry-DgahJGSx.js} +3 -3
- package/dist/{telemetry-DZShaH-y.js.map → telemetry-DgahJGSx.js.map} +1 -1
- package/dist/{terminal-CEhufbJ4.js → terminal-Bb6tZkf-.js} +13 -13
- package/dist/{terminal-CEhufbJ4.js.map → terminal-Bb6tZkf-.js.map} +1 -1
- package/dist/{tools-BIPMan6l.js → tools-BJEvSUWN.js} +4 -4
- package/dist/{tools-BIPMan6l.js.map → tools-BJEvSUWN.js.map} +1 -1
- package/dist/{types-y3HkjtSq.js → types-BRe_EzTW.js} +1 -1
- package/dist/{types-y3HkjtSq.js.map → types-BRe_EzTW.js.map} +1 -1
- package/dist/{wizard-abort-C14PzXZ8.js → wizard-abort-BxtdkgI-.js} +4 -4
- package/dist/{wizard-abort-C14PzXZ8.js.map → wizard-abort-BxtdkgI-.js.map} +1 -1
- package/dist/{wizard-abort-UCm4Pd5m.js → wizard-abort-DpDmuCfA.js} +1 -1
- package/dist/{wizard-session-C5lZPPEc.js → wizard-session-DWHe83uk.js} +1 -1
- package/dist/{wizard-session-BAZql11N.js → wizard-session-tp4Zdbwl.js} +1 -1
- package/dist/{wizard-session-BAZql11N.js.map → wizard-session-tp4Zdbwl.js.map} +1 -1
- package/dist/{wizard-tools-B7SLjCic.js → wizard-tools-Dg8o2lcH.js} +64 -387
- package/dist/wizard-tools-Dg8o2lcH.js.map +1 -0
- package/dist/yara-hooks-CncaWRuC.js +2 -0
- package/dist/{yara-hooks-CPH8N4yz.js → yara-hooks-pw86rZ8y.js} +4 -4
- package/dist/{yara-hooks-CPH8N4yz.js.map → yara-hooks-pw86rZ8y.js.map} +1 -1
- package/package.json +1 -1
- package/dist/agent-interface-BvTxWiol.js.map +0 -1
- package/dist/agent-runner-BF6_f8Qh.js.map +0 -1
- package/dist/analytics-C7Xx6csw.js +0 -2
- package/dist/debug-DXfQFmcM.js.map +0 -1
- package/dist/headless-ui-Dni0gPND.js.map +0 -1
- package/dist/mcp-xKRDnrcq.js.map +0 -1
- package/dist/posthog-integration-BhLKCFsI.js.map +0 -1
- package/dist/registry-DcoBCMQR.js.map +0 -1
- package/dist/start-tui-DgSKFMVh.js.map +0 -1
- package/dist/store-C79GoHCQ.js.map +0 -1
- package/dist/task-stream-0Pk0tPBN.js.map +0 -1
- package/dist/wizard-tools-B7SLjCic.js.map +0 -1
- package/dist/wizard-ui-WZ48rUgr.js +0 -15
- package/dist/wizard-ui-WZ48rUgr.js.map +0 -1
- package/dist/yara-hooks-VZlj4Lib.js +0 -2
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { n as __require } from "./rolldown-runtime-B_-DWIq7.js";
|
|
2
|
-
import {
|
|
3
|
-
import { n as analytics } from "./analytics-
|
|
4
|
-
import { n as ADDITIONAL_FEATURE_PROMPTS } from "./wizard-session-
|
|
5
|
-
import { i as wizardAbort, n as registerCleanup, t as WizardError } from "./wizard-abort-
|
|
6
|
-
import { n as createWizardToolsServer, t as WIZARD_TOOL_NAMES } from "./wizard-tools-
|
|
7
|
-
import { l as prewarmYaraScanner, n as createPostToolUseYaraHooks, r as createPreToolUseYaraHooks } from "./yara-hooks-
|
|
2
|
+
import { J as POSTHOG_FLAG_HEADER_PREFIX, St as runtimeEnv, Z as POSTHOG_PROPERTY_HEADER_PREFIX, a as getLogFilePath, f as getUI, lt as WIZARD_ORCHESTRATOR_FLAG_KEY, o as initLogFile, pt as WIZARD_REMARK_EVENT_NAME, r as debug, s as logToFile, vt as wizardUserAgentForProgram } from "./debug-DBmxx59Q.js";
|
|
3
|
+
import { n as analytics } from "./analytics-DQEuL6qS.js";
|
|
4
|
+
import { n as ADDITIONAL_FEATURE_PROMPTS } from "./wizard-session-tp4Zdbwl.js";
|
|
5
|
+
import { i as wizardAbort, n as registerCleanup, t as WizardError } from "./wizard-abort-BxtdkgI-.js";
|
|
6
|
+
import { n as createWizardToolsServer, t as WIZARD_TOOL_NAMES } from "./wizard-tools-Dg8o2lcH.js";
|
|
7
|
+
import { l as prewarmYaraScanner, n as createPostToolUseYaraHooks, r as createPreToolUseYaraHooks } from "./yara-hooks-pw86rZ8y.js";
|
|
8
|
+
import { t as getWizardCommandments } from "./commandments-CyB7Icr1.js";
|
|
8
9
|
import { createRequire } from "node:module";
|
|
9
10
|
import * as fs$1 from "fs";
|
|
10
11
|
import path from "path";
|
|
@@ -160,6 +161,7 @@ const LINTING_TOOLS = [
|
|
|
160
161
|
"sql-formatter",
|
|
161
162
|
"sqlfmt",
|
|
162
163
|
"squawk",
|
|
164
|
+
"svelte-check",
|
|
163
165
|
"svgo",
|
|
164
166
|
"stringslint",
|
|
165
167
|
"swiftformat",
|
|
@@ -175,6 +177,282 @@ const LINTING_TOOLS = [
|
|
|
175
177
|
"yamllint"
|
|
176
178
|
];
|
|
177
179
|
//#endregion
|
|
180
|
+
//#region src/lib/agent/bash-fence.ts
|
|
181
|
+
/**
|
|
182
|
+
* Bash command fence: exact per-manager allowlists + shell-shape gates.
|
|
183
|
+
*
|
|
184
|
+
* In effect this gates the pi harness only — on the Anthropic arm `Bash` is
|
|
185
|
+
* pre-allowed (BASE_ALLOWED_TOOLS), so canUseTool never sees it and the SDK's
|
|
186
|
+
* OS sandbox + YARA hooks gate execution instead. pi has no OS sandbox yet,
|
|
187
|
+
* so this string fence is its only execution gate.
|
|
188
|
+
*
|
|
189
|
+
* Threat model: the agent can already Write project files, so commands that
|
|
190
|
+
* execute project-defined code (installs, builds) are equivalent risk by
|
|
191
|
+
* construction. The fence must prevent: direct arbitrary shell, outward
|
|
192
|
+
* registry actions (publish/push/deploy), arbitrary-package execution
|
|
193
|
+
* (`npx <anything>` downloads and runs it), and shell injection. Matching is
|
|
194
|
+
* token-exact per manager — keyword prefixes admitted `npm publish` via `pub`.
|
|
195
|
+
*/
|
|
196
|
+
const NODE_MANAGERS = new Set([
|
|
197
|
+
"npm",
|
|
198
|
+
"pnpm",
|
|
199
|
+
"yarn",
|
|
200
|
+
"bun"
|
|
201
|
+
]);
|
|
202
|
+
const GRADLE_MANAGERS = new Set([
|
|
203
|
+
"gradle",
|
|
204
|
+
"gradlew",
|
|
205
|
+
"./gradlew"
|
|
206
|
+
]);
|
|
207
|
+
const MAVEN_MANAGERS = new Set([
|
|
208
|
+
"mvn",
|
|
209
|
+
"mvnw",
|
|
210
|
+
"./mvnw"
|
|
211
|
+
]);
|
|
212
|
+
const NODE_SUBCOMMANDS = [
|
|
213
|
+
"install",
|
|
214
|
+
"i",
|
|
215
|
+
"ci",
|
|
216
|
+
"add",
|
|
217
|
+
"remove",
|
|
218
|
+
"uninstall",
|
|
219
|
+
"update",
|
|
220
|
+
"view"
|
|
221
|
+
];
|
|
222
|
+
const NODE_SCRIPT_NAMES = [
|
|
223
|
+
"build",
|
|
224
|
+
"lint",
|
|
225
|
+
"format",
|
|
226
|
+
"tsc",
|
|
227
|
+
"typecheck",
|
|
228
|
+
"type-check",
|
|
229
|
+
"check-types",
|
|
230
|
+
"check",
|
|
231
|
+
"types"
|
|
232
|
+
];
|
|
233
|
+
const NPX_TOOLS = new Set([
|
|
234
|
+
...LINTING_TOOLS,
|
|
235
|
+
"tsc",
|
|
236
|
+
"expo",
|
|
237
|
+
"pod-install",
|
|
238
|
+
"cap"
|
|
239
|
+
]);
|
|
240
|
+
const PIP_SUBCOMMANDS = [
|
|
241
|
+
"install",
|
|
242
|
+
"uninstall",
|
|
243
|
+
"show",
|
|
244
|
+
"list",
|
|
245
|
+
"index"
|
|
246
|
+
];
|
|
247
|
+
const BUNDLE_SUBCOMMANDS = [
|
|
248
|
+
"install",
|
|
249
|
+
"add",
|
|
250
|
+
"remove",
|
|
251
|
+
"update",
|
|
252
|
+
"show"
|
|
253
|
+
];
|
|
254
|
+
const MAVEN_GOALS = [
|
|
255
|
+
"install",
|
|
256
|
+
"compile",
|
|
257
|
+
"package",
|
|
258
|
+
"verify",
|
|
259
|
+
"dependency:tree"
|
|
260
|
+
];
|
|
261
|
+
/** Managers whose first subcommand is checked exactly against a fixed set. */
|
|
262
|
+
const SIMPLE_MANAGERS = {
|
|
263
|
+
pip: PIP_SUBCOMMANDS,
|
|
264
|
+
pip3: PIP_SUBCOMMANDS,
|
|
265
|
+
poetry: [
|
|
266
|
+
"install",
|
|
267
|
+
"add",
|
|
268
|
+
"remove",
|
|
269
|
+
"show",
|
|
270
|
+
"lock",
|
|
271
|
+
"update"
|
|
272
|
+
],
|
|
273
|
+
pipenv: ["install", "uninstall"],
|
|
274
|
+
uv: [
|
|
275
|
+
"add",
|
|
276
|
+
"remove",
|
|
277
|
+
"sync"
|
|
278
|
+
],
|
|
279
|
+
pdm: [
|
|
280
|
+
"install",
|
|
281
|
+
"add",
|
|
282
|
+
"remove"
|
|
283
|
+
],
|
|
284
|
+
conda: ["install", "remove"],
|
|
285
|
+
composer: [
|
|
286
|
+
"install",
|
|
287
|
+
"require",
|
|
288
|
+
"update",
|
|
289
|
+
"remove",
|
|
290
|
+
"show"
|
|
291
|
+
],
|
|
292
|
+
bundle: BUNDLE_SUBCOMMANDS,
|
|
293
|
+
bundler: BUNDLE_SUBCOMMANDS,
|
|
294
|
+
gem: [
|
|
295
|
+
"install",
|
|
296
|
+
"uninstall",
|
|
297
|
+
"list",
|
|
298
|
+
"search"
|
|
299
|
+
],
|
|
300
|
+
swift: ["package", "build"],
|
|
301
|
+
pod: [
|
|
302
|
+
"install",
|
|
303
|
+
"update",
|
|
304
|
+
"search"
|
|
305
|
+
],
|
|
306
|
+
carthage: ["bootstrap", "update"]
|
|
307
|
+
};
|
|
308
|
+
const GRADLE_EXACT_TASKS = new Set([
|
|
309
|
+
"build",
|
|
310
|
+
"clean",
|
|
311
|
+
"dependencies"
|
|
312
|
+
]);
|
|
313
|
+
const GRADLE_TASK_VERBS = [
|
|
314
|
+
"assemble",
|
|
315
|
+
"compile",
|
|
316
|
+
"bundle",
|
|
317
|
+
"lint"
|
|
318
|
+
];
|
|
319
|
+
const XCODEBUILD_DENIED_ACTIONS = new Set(["test", "test-without-building"]);
|
|
320
|
+
const DANGEROUS_OPERATORS = /[;`$()]/;
|
|
321
|
+
const ALLOWED_TOOLS_SUMMARY = "Allowed: npm/pnpm/yarn/bun (install|i|ci|add|remove|uninstall|update|view, run <build/lint/typecheck script>), npx <lint tool|tsc|expo|pod-install|cap>, pip/pip3/poetry/pipenv/uv/pdm/conda (install/add/remove/...), composer (install|require|update|remove|show), bundle (install|add|remove|update|show|exec <lint tool>), gem (install|uninstall|list|search), swift (package|build), pod (install|update|search), carthage (bootstrap|update), xcodebuild (build/clean/archive actions), gradle/gradlew (build|clean|dependencies|assemble*/compile*/bundle*/lint* tasks), mvn (install|compile|package|verify|dependency:tree).";
|
|
322
|
+
function deny(analyticsReason, message) {
|
|
323
|
+
return {
|
|
324
|
+
allowed: false,
|
|
325
|
+
message,
|
|
326
|
+
analyticsReason
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
function denyCommand(command, feedback) {
|
|
330
|
+
return deny("not in allowlist", `Bash command not allowed: \`${command.length > 120 ? command.slice(0, 117) + "..." : command}\`. ${feedback}`);
|
|
331
|
+
}
|
|
332
|
+
function isNodeScriptName(token) {
|
|
333
|
+
return NODE_SCRIPT_NAMES.some((name) => token === name || token.startsWith(name + ":"));
|
|
334
|
+
}
|
|
335
|
+
function isLintingTool(token) {
|
|
336
|
+
return LINTING_TOOLS.includes(token) || token === "tsc";
|
|
337
|
+
}
|
|
338
|
+
function nodeDecision(parts, command) {
|
|
339
|
+
const bin = parts[0];
|
|
340
|
+
let i = 1;
|
|
341
|
+
if (bin === "yarn" && parts[i] === "workspace" && parts[i + 1]) i += 2;
|
|
342
|
+
for (;;) {
|
|
343
|
+
const t = parts[i];
|
|
344
|
+
if (t === "-r" || t === "--recursive") i++;
|
|
345
|
+
else if (t && (t.startsWith("--filter=") || t.startsWith("--workspace="))) i++;
|
|
346
|
+
else if ((t === "--filter" || t === "--workspace" || t === "-w" && bin === "npm") && parts[i + 1]) i += 2;
|
|
347
|
+
else if (t === "-w" && bin === "pnpm") i++;
|
|
348
|
+
else break;
|
|
349
|
+
}
|
|
350
|
+
const sub = parts[i];
|
|
351
|
+
const feedback = `Allowed ${bin} usage: ${bin} ${NODE_SUBCOMMANDS.join("|")} [args], ${bin} run <script named ${NODE_SCRIPT_NAMES.join("/")}>, ${bin} exec <lint tool>, or ${bin} <that script name or lint tool> directly.`;
|
|
352
|
+
if (!sub) return denyCommand(command, feedback);
|
|
353
|
+
if (sub === "run") {
|
|
354
|
+
const target = parts[i + 1];
|
|
355
|
+
if (target && isNodeScriptName(target)) return { allowed: true };
|
|
356
|
+
return denyCommand(command, feedback);
|
|
357
|
+
}
|
|
358
|
+
if (sub === "exec") {
|
|
359
|
+
const target = parts[i + 1];
|
|
360
|
+
if (target && isLintingTool(target)) return { allowed: true };
|
|
361
|
+
return denyCommand(command, feedback);
|
|
362
|
+
}
|
|
363
|
+
if (NODE_SUBCOMMANDS.includes(sub)) return { allowed: true };
|
|
364
|
+
if (isNodeScriptName(sub) || isLintingTool(sub)) return { allowed: true };
|
|
365
|
+
return denyCommand(command, feedback);
|
|
366
|
+
}
|
|
367
|
+
function npxDecision(parts, command) {
|
|
368
|
+
const target = parts[1];
|
|
369
|
+
if (!target || target.startsWith("-")) return denyCommand(command, "npx may only run a known tool directly: tsc, expo, pod-install, cap, or a lint/format tool (eslint, prettier, biome, ...).");
|
|
370
|
+
const name = target.replace(/@[^@/]*$/, "");
|
|
371
|
+
if (NPX_TOOLS.has(name)) return { allowed: true };
|
|
372
|
+
return denyCommand(command, "npx may only run a known tool directly: tsc, expo, pod-install, cap, or a lint/format tool (eslint, prettier, biome, ...).");
|
|
373
|
+
}
|
|
374
|
+
function gradleDecision(parts, command) {
|
|
375
|
+
let sawTask = false;
|
|
376
|
+
for (const raw of parts.slice(1)) {
|
|
377
|
+
if (raw.startsWith("-")) continue;
|
|
378
|
+
const task = raw.replace(/^(?::[\w.-]+)+:/, "");
|
|
379
|
+
if (!(GRADLE_EXACT_TASKS.has(task) || GRADLE_TASK_VERBS.some((verb) => task.startsWith(verb) && /^[A-Z]/.test(task.slice(verb.length))))) return denyCommand(command, "Allowed gradle tasks: build, clean, dependencies, or assemble*/compile*/bundle*/lint* variants (flags OK).");
|
|
380
|
+
sawTask = true;
|
|
381
|
+
}
|
|
382
|
+
return sawTask ? { allowed: true } : denyCommand(command, "Give gradle an allowed task: build, clean, dependencies, assembleDebug, ...");
|
|
383
|
+
}
|
|
384
|
+
function mavenDecision(parts, command) {
|
|
385
|
+
let sawGoal = false;
|
|
386
|
+
for (const raw of parts.slice(1)) {
|
|
387
|
+
if (raw.startsWith("-")) continue;
|
|
388
|
+
if (!MAVEN_GOALS.includes(raw)) return denyCommand(command, `Allowed mvn goals: ${MAVEN_GOALS.join(", ")} (flags OK).`);
|
|
389
|
+
sawGoal = true;
|
|
390
|
+
}
|
|
391
|
+
return sawGoal ? { allowed: true } : denyCommand(command, `Give mvn an allowed goal: ${MAVEN_GOALS.join(", ")}.`);
|
|
392
|
+
}
|
|
393
|
+
function xcodebuildDecision(parts, command) {
|
|
394
|
+
for (const t of parts.slice(1)) if (XCODEBUILD_DENIED_ACTIONS.has(t)) return denyCommand(command, "xcodebuild test actions are not allowed; build, clean, and archive are.");
|
|
395
|
+
return { allowed: true };
|
|
396
|
+
}
|
|
397
|
+
/** Grammar decision for a single operator-free, pipe-free command. */
|
|
398
|
+
function commandDecision(command) {
|
|
399
|
+
const parts = command.split(/\s+/).filter(Boolean);
|
|
400
|
+
const bin = parts[0];
|
|
401
|
+
if (!bin) return denyCommand(command, ALLOWED_TOOLS_SUMMARY);
|
|
402
|
+
if (NODE_MANAGERS.has(bin)) return nodeDecision(parts, command);
|
|
403
|
+
if (bin === "npx") return npxDecision(parts, command);
|
|
404
|
+
if (GRADLE_MANAGERS.has(bin)) return gradleDecision(parts, command);
|
|
405
|
+
if (MAVEN_MANAGERS.has(bin)) return mavenDecision(parts, command);
|
|
406
|
+
if (bin === "xcodebuild") return xcodebuildDecision(parts, command);
|
|
407
|
+
if ((bin === "python" || bin === "python3") && parts[1] === "manage.py" && parts[2] === "check") return { allowed: true };
|
|
408
|
+
if (bin === "uv" && parts[1] === "pip") {
|
|
409
|
+
if (parts[2] && PIP_SUBCOMMANDS.includes(parts[2])) return { allowed: true };
|
|
410
|
+
return denyCommand(command, `Allowed uv pip subcommands: ${PIP_SUBCOMMANDS.join(", ")}.`);
|
|
411
|
+
}
|
|
412
|
+
if ((bin === "bundle" || bin === "bundler") && parts[1] === "exec") {
|
|
413
|
+
if (parts[2] && isLintingTool(parts[2])) return { allowed: true };
|
|
414
|
+
return denyCommand(command, `bundle exec may only run a lint/format tool (rubocop, ...). Allowed bundle subcommands: ${BUNDLE_SUBCOMMANDS.join(", ")}, exec <lint tool>.`);
|
|
415
|
+
}
|
|
416
|
+
const subs = SIMPLE_MANAGERS[bin];
|
|
417
|
+
if (subs) {
|
|
418
|
+
if (parts[1] && subs.includes(parts[1])) return { allowed: true };
|
|
419
|
+
const exec = bin === "bundle" || bin === "bundler" ? ", exec <lint tool>" : "";
|
|
420
|
+
return denyCommand(command, `Allowed ${bin} subcommands: ${subs.join(", ")}${exec}.`);
|
|
421
|
+
}
|
|
422
|
+
return denyCommand(command, `\`${bin}\` is not an allowed tool. ${ALLOWED_TOOLS_SUMMARY}`);
|
|
423
|
+
}
|
|
424
|
+
function tailArgsAreSafe(argStr) {
|
|
425
|
+
const args = argStr.trim().split(/\s+/).filter(Boolean);
|
|
426
|
+
for (let i = 0; i < args.length; i++) {
|
|
427
|
+
const a = args[i];
|
|
428
|
+
if (/^-[nc]$/.test(a)) {
|
|
429
|
+
if (!/^[+-]?\d+$/.test(args[i + 1] ?? "")) return false;
|
|
430
|
+
i++;
|
|
431
|
+
} else if (!/^-[nc]?\+?\d+$/.test(a)) return false;
|
|
432
|
+
}
|
|
433
|
+
return true;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Full fence decision for a Bash command: shell-shape gates (separators,
|
|
437
|
+
* redirects, pipes) first, then the per-manager grammar.
|
|
438
|
+
*/
|
|
439
|
+
function evaluateBashCommand(rawCommand) {
|
|
440
|
+
const command = rawCommand.trim();
|
|
441
|
+
if (/[\r\n]/.test(command)) return deny("dangerous operators", "Bash command not allowed. Multi-line commands are not permitted — run one command at a time.");
|
|
442
|
+
if (DANGEROUS_OPERATORS.test(command)) return deny("dangerous operators", "Bash command not allowed. Shell operators like ; ` $ ( ) are not permitted.");
|
|
443
|
+
const normalized = command.replace(/\s*\d*>&\d+\s*/g, " ").replace(/\s*\d*>\s*\/dev\/null\s*/g, " ").trim();
|
|
444
|
+
if (/[<>]/.test(normalized)) return deny("disallowed redirect", "Bash command not allowed. Redirects are not permitted (only 2>&1 and >/dev/null).");
|
|
445
|
+
const pipeMatch = normalized.match(/^(.+?)\s*\|\s*(?:tail|head)((?:\s+\S+)*)\s*$/);
|
|
446
|
+
if (pipeMatch) {
|
|
447
|
+
const base = pipeMatch[1].trim();
|
|
448
|
+
if (/[|&]/.test(base)) return deny("multiple pipes", "Bash command not allowed. Only a single pipe to tail/head is permitted.");
|
|
449
|
+
if (!tailArgsAreSafe(pipeMatch[2])) return deny("disallowed pipe", "Bash command not allowed. tail/head may only take numeric flags (-n 50, -c 200) — no file arguments.");
|
|
450
|
+
return commandDecision(base);
|
|
451
|
+
}
|
|
452
|
+
if (/[|&]/.test(normalized)) return deny("disallowed pipe", "Bash command not allowed. Pipes are only permitted as a single | tail/head for output limiting.");
|
|
453
|
+
return commandDecision(normalized);
|
|
454
|
+
}
|
|
455
|
+
//#endregion
|
|
178
456
|
//#region src/lib/agent/triage-provider.ts
|
|
179
457
|
/**
|
|
180
458
|
* LLM provider for warlock security-scan triage.
|
|
@@ -231,44 +509,6 @@ function createTriageLLMProvider(auth) {
|
|
|
231
509
|
};
|
|
232
510
|
}
|
|
233
511
|
//#endregion
|
|
234
|
-
//#region src/lib/agent/commandments.ts
|
|
235
|
-
/**
|
|
236
|
-
* Wizard-wide commandments that are always appended as a system prompt.
|
|
237
|
-
*
|
|
238
|
-
* Keep this as a simple string so it can be inlined into the compiled bundle
|
|
239
|
-
* without extra files, copying, or runtime I/O.
|
|
240
|
-
*/
|
|
241
|
-
const WIZARD_COMMANDMENTS = [
|
|
242
|
-
"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).",
|
|
243
|
-
"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.",
|
|
244
|
-
"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.",
|
|
245
|
-
"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.",
|
|
246
|
-
"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.",
|
|
247
|
-
"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.",
|
|
248
|
-
"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.",
|
|
249
|
-
"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.",
|
|
250
|
-
"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.",
|
|
251
|
-
"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.",
|
|
252
|
-
"Do not spawn subagents unless explicitly instructed to do so.",
|
|
253
|
-
"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.",
|
|
254
|
-
"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.",
|
|
255
|
-
"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.",
|
|
256
|
-
"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.",
|
|
257
|
-
[
|
|
258
|
-
"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.",
|
|
259
|
-
"When a skill provides a numbered or bulleted list of questions, translate the entire list into a single `wizard_ask` tool call:",
|
|
260
|
-
" - One tool call per skill step. Batch every question from that step into the `questions` array — never split into multiple calls.",
|
|
261
|
-
" - 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`.",
|
|
262
|
-
" - 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\"`).",
|
|
263
|
-
" - Use a kebab-case slug of the question label as `id` (e.g., \"Tech stack\" → `tech-stack`, \"Show frequency\" → `show-frequency`).",
|
|
264
|
-
" - 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.",
|
|
265
|
-
"After `wizard_ask` returns, use the answers directly — do not re-ask in text or call `wizard_ask` again for the same fields."
|
|
266
|
-
].join("\n")
|
|
267
|
-
].join("\n");
|
|
268
|
-
function getWizardCommandments() {
|
|
269
|
-
return WIZARD_COMMANDMENTS;
|
|
270
|
-
}
|
|
271
|
-
//#endregion
|
|
272
512
|
//#region src/lib/agent/agent-phase.ts
|
|
273
513
|
/** Maps a Claude SDK tool name to the phase that tool implies. Returns null
|
|
274
514
|
* when the tool doesn't drive the visualizer (Task*, TodoWrite, etc.). */
|
|
@@ -959,62 +1199,9 @@ function buildAgentEnv(wizardMetadata, wizardFlags) {
|
|
|
959
1199
|
return encoded;
|
|
960
1200
|
}
|
|
961
1201
|
/**
|
|
962
|
-
*
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
"npm",
|
|
966
|
-
"pnpm",
|
|
967
|
-
"yarn",
|
|
968
|
-
"bun",
|
|
969
|
-
"npx",
|
|
970
|
-
"pip",
|
|
971
|
-
"pip3",
|
|
972
|
-
"poetry",
|
|
973
|
-
"pipenv",
|
|
974
|
-
"uv"
|
|
975
|
-
];
|
|
976
|
-
/**
|
|
977
|
-
* Safe scripts/commands that can be run with any package manager.
|
|
978
|
-
* Uses startsWith matching, so 'build' matches 'build', 'build:prod', etc.
|
|
979
|
-
* Note: Linting tools are in LINTING_TOOLS and checked separately.
|
|
980
|
-
*/
|
|
981
|
-
const SAFE_SCRIPTS = [
|
|
982
|
-
"install",
|
|
983
|
-
"add",
|
|
984
|
-
"ci",
|
|
985
|
-
"build",
|
|
986
|
-
"tsc",
|
|
987
|
-
"typecheck",
|
|
988
|
-
"type-check",
|
|
989
|
-
"check-types",
|
|
990
|
-
"types",
|
|
991
|
-
"lint",
|
|
992
|
-
"format"
|
|
993
|
-
];
|
|
994
|
-
/**
|
|
995
|
-
* Dangerous shell operators that could allow command injection.
|
|
996
|
-
* Note: We handle `2>&1` and `| tail/head` separately as safe patterns.
|
|
997
|
-
*/
|
|
998
|
-
const DANGEROUS_OPERATORS = /[;`$()]/;
|
|
999
|
-
/**
|
|
1000
|
-
* Check if command is an allowed package manager command.
|
|
1001
|
-
* Matches: <pkg-manager> [run|exec] <safe-script> [args...]
|
|
1002
|
-
*/
|
|
1003
|
-
function matchesAllowedPrefix(command) {
|
|
1004
|
-
const parts = command.split(/\s+/);
|
|
1005
|
-
if (parts.length === 0 || !PACKAGE_MANAGERS.includes(parts[0])) return false;
|
|
1006
|
-
let scriptIndex = 1;
|
|
1007
|
-
if (parts[scriptIndex] === "run" || parts[scriptIndex] === "exec") scriptIndex++;
|
|
1008
|
-
if (parts[scriptIndex] === "i") return true;
|
|
1009
|
-
const scriptPart = parts.slice(scriptIndex).join(" ");
|
|
1010
|
-
return SAFE_SCRIPTS.some((safe) => scriptPart.startsWith(safe)) || LINTING_TOOLS.some((tool) => scriptPart.startsWith(tool));
|
|
1011
|
-
}
|
|
1012
|
-
/**
|
|
1013
|
-
* Permission hook that allows only safe commands.
|
|
1014
|
-
* - Package manager install commands
|
|
1015
|
-
* - Build/typecheck/lint commands for verification
|
|
1016
|
-
* - Piping to tail/head for output limiting is allowed
|
|
1017
|
-
* - Stderr redirection (2>&1) is allowed
|
|
1202
|
+
* Permission hook that allows only safe commands. Bash commands are gated by
|
|
1203
|
+
* the exact per-manager fence in bash-fence.ts (install/build/typecheck/lint
|
|
1204
|
+
* commands, single | tail/head, 2>&1).
|
|
1018
1205
|
*
|
|
1019
1206
|
* `wizardAskPending` is true while a wizard_ask overlay is open — when set,
|
|
1020
1207
|
* Write/Edit calls are denied as a defense-in-depth measure against a
|
|
@@ -1040,7 +1227,8 @@ function wizardCanUseTool(toolName, input, context = {}) {
|
|
|
1040
1227
|
if (toolName === "Read" || toolName === "Write" || toolName === "Edit") {
|
|
1041
1228
|
const filePath = typeof input.file_path === "string" ? input.file_path : "";
|
|
1042
1229
|
const basename = path.basename(filePath);
|
|
1043
|
-
|
|
1230
|
+
const isEnvExample = /^\.env\.(example|sample|template|dist)$/.test(basename);
|
|
1231
|
+
if (basename.startsWith(".env") && !isEnvExample) {
|
|
1044
1232
|
logToFile(`Denying ${toolName} on env file: ${filePath}`);
|
|
1045
1233
|
return {
|
|
1046
1234
|
behavior: "deny",
|
|
@@ -1071,56 +1259,8 @@ function wizardCanUseTool(toolName, input, context = {}) {
|
|
|
1071
1259
|
updatedInput: input
|
|
1072
1260
|
};
|
|
1073
1261
|
const command = (typeof input.command === "string" ? input.command : "").trim();
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
debug(`Denying bash command with dangerous operators: ${command}`);
|
|
1077
|
-
analytics.wizardCapture("bash denied", {
|
|
1078
|
-
reason: "dangerous operators",
|
|
1079
|
-
command
|
|
1080
|
-
});
|
|
1081
|
-
return {
|
|
1082
|
-
behavior: "deny",
|
|
1083
|
-
message: `Bash command not allowed. Shell operators like ; \` $ ( ) are not permitted.`
|
|
1084
|
-
};
|
|
1085
|
-
}
|
|
1086
|
-
const normalized = command.replace(/\s*\d*>&\d+\s*/g, " ").trim();
|
|
1087
|
-
const pipeMatch = normalized.match(/^(.+?)\s*\|\s*(tail|head)(\s+\S+)*\s*$/);
|
|
1088
|
-
if (pipeMatch) {
|
|
1089
|
-
const baseCommand = pipeMatch[1].trim();
|
|
1090
|
-
if (/[|&]/.test(baseCommand)) {
|
|
1091
|
-
logToFile(`Denying bash command with multiple pipes: ${command}`);
|
|
1092
|
-
debug(`Denying bash command with multiple pipes: ${command}`);
|
|
1093
|
-
analytics.wizardCapture("bash denied", {
|
|
1094
|
-
reason: "multiple pipes",
|
|
1095
|
-
command
|
|
1096
|
-
});
|
|
1097
|
-
return {
|
|
1098
|
-
behavior: "deny",
|
|
1099
|
-
message: `Bash command not allowed. Only single pipe to tail/head is permitted.`
|
|
1100
|
-
};
|
|
1101
|
-
}
|
|
1102
|
-
if (matchesAllowedPrefix(baseCommand)) {
|
|
1103
|
-
logToFile(`Allowing bash command with output limiter: ${command}`);
|
|
1104
|
-
debug(`Allowing bash command with output limiter: ${command}`);
|
|
1105
|
-
return {
|
|
1106
|
-
behavior: "allow",
|
|
1107
|
-
updatedInput: input
|
|
1108
|
-
};
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1111
|
-
if (/[|&]/.test(normalized)) {
|
|
1112
|
-
logToFile(`Denying bash command with pipe/&: ${command}`);
|
|
1113
|
-
debug(`Denying bash command with pipe/&: ${command}`);
|
|
1114
|
-
analytics.wizardCapture("bash denied", {
|
|
1115
|
-
reason: "disallowed pipe",
|
|
1116
|
-
command
|
|
1117
|
-
});
|
|
1118
|
-
return {
|
|
1119
|
-
behavior: "deny",
|
|
1120
|
-
message: `Bash command not allowed. Pipes are only permitted with tail/head for output limiting.`
|
|
1121
|
-
};
|
|
1122
|
-
}
|
|
1123
|
-
if (matchesAllowedPrefix(normalized)) {
|
|
1262
|
+
const decision = evaluateBashCommand(command);
|
|
1263
|
+
if (decision.allowed) {
|
|
1124
1264
|
logToFile(`Allowing bash command: ${command}`);
|
|
1125
1265
|
debug(`Allowing bash command: ${command}`);
|
|
1126
1266
|
return {
|
|
@@ -1128,15 +1268,15 @@ function wizardCanUseTool(toolName, input, context = {}) {
|
|
|
1128
1268
|
updatedInput: input
|
|
1129
1269
|
};
|
|
1130
1270
|
}
|
|
1131
|
-
logToFile(`Denying bash command: ${command}`);
|
|
1132
|
-
debug(`Denying bash command: ${command}`);
|
|
1271
|
+
logToFile(`Denying bash command (${decision.analyticsReason}): ${command}`);
|
|
1272
|
+
debug(`Denying bash command (${decision.analyticsReason}): ${command}`);
|
|
1133
1273
|
analytics.wizardCapture("bash denied", {
|
|
1134
|
-
reason:
|
|
1274
|
+
reason: decision.analyticsReason,
|
|
1135
1275
|
command
|
|
1136
1276
|
});
|
|
1137
1277
|
return {
|
|
1138
1278
|
behavior: "deny",
|
|
1139
|
-
message:
|
|
1279
|
+
message: decision.message
|
|
1140
1280
|
};
|
|
1141
1281
|
}
|
|
1142
1282
|
/**
|
|
@@ -1807,6 +1947,6 @@ function handleSDKMessage(message, options, spinner, signals, receivedSuccessRes
|
|
|
1807
1947
|
}
|
|
1808
1948
|
}
|
|
1809
1949
|
//#endregion
|
|
1810
|
-
export { wizardCanUseTool as a, classifySettingsConflicts as c, sanitizeAgentSubprocessEnv as d, AgentOutputSignals as f, createTriageLLMProvider as
|
|
1950
|
+
export { wizardCanUseTool as a, classifySettingsConflicts as c, sanitizeAgentSubprocessEnv as d, AgentOutputSignals as f, createTriageLLMProvider as h, runAgent as i, recoverOrphanedSettingsBackups as l, REMARK_INSTRUCTION as m, buildRunTags as n, backupAndFixClaudeSettings as o, AgentSignals as p, initializeAgent as r, checkAllSettingsConflicts as s, buildAgentEnv as t, restoreClaudeSettings as u };
|
|
1811
1951
|
|
|
1812
|
-
//# sourceMappingURL=agent-interface-
|
|
1952
|
+
//# sourceMappingURL=agent-interface-CF7GsdFf.js.map
|