From fdb07cdb9f5ba7797abae83deb8ef6535307e6de Mon Sep 17 00:00:00 2001 From: eggmasonvalue Date: Sun, 6 Sep 2026 18:21:51 +0530 Subject: [PATCH] feat(bootstrap): configure allowScripts for agent-browser in SecStack npm root --- README.md | 14 ++++++++------ scripts/bootstrap.mjs | 32 +++++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index b197860..7755752 100644 --- a/README.md +++ b/README.md @@ -27,12 +27,14 @@ From Bash, bootstrap the profile with one command: (tmp=$(mktemp -d) && git clone --depth 1 https://github.com/eggmasonvalue/secstack "$tmp" && node "$tmp/scripts/bootstrap.mjs"; status=$?; rm -rf "$tmp"; [ "$status" -eq 0 ]) ``` -The bootstrap is safe to rerun. It installs the unpinned top-level Pi package sources, -merges only SecStack-managed package entries, shell-path configuration, and `quietStartup` -preference into the SecStack profile's `settings.json` and creates a profile-local Python environment. It links the -profile's `SYSTEM.md` to the installed SecStack package, so `pi update --extensions` updates the -research-agent identity and prompt envelope. It does not install coding-task guidance or link -global `AGENTS.md` or `APPEND_SYSTEM.md` files into the profile. +The bootstrap is safe to rerun. It configures `allowScripts` for `agent-browser` in the +profile's npm root (`~/.pi/secstack-agent/npm/package.json`), installs the unpinned top-level +Pi package sources, merges only SecStack-managed package entries, shell-path configuration, +and `quietStartup` preference into the SecStack profile's `settings.json` and creates a +profile-local Python environment. It links the profile's `SYSTEM.md` to the installed SecStack +package, so `pi update --extensions` updates the research-agent identity and prompt envelope. +It does not install coding-task guidance or link global `AGENTS.md` or `APPEND_SYSTEM.md` files +into the profile. It does not overwrite the profile's `auth.json`, `models.json`, provider settings, model selections, UI preferences, sessions, or unrelated settings. diff --git a/scripts/bootstrap.mjs b/scripts/bootstrap.mjs index 5c27028..845c3af 100644 --- a/scripts/bootstrap.mjs +++ b/scripts/bootstrap.mjs @@ -3,8 +3,9 @@ * Install SecStack and its independently managed Pi packages into the isolated * SecStack profile. * - * This script deliberately changes only the SecStack profile's package list, - * shell command prefix, quietStartup setting, and optional Bash launcher. + * This script deliberately changes the SecStack profile's package list, + * shell command prefix, quietStartup setting, allowScripts in the profile's npm + * root, and optional Bash launcher. */ import { execFileSync } from "node:child_process"; import { @@ -25,7 +26,9 @@ import { dirname, join, relative, resolve } from "node:path"; const agentDir = resolve(join(homedir(), ".pi", "secstack-agent")); const settingsPath = join(agentDir, "settings.json"); -const npmBin = join(agentDir, "npm", "node_modules", ".bin"); +const npmDir = join(agentDir, "npm"); +const npmPackageJsonPath = join(npmDir, "package.json"); +const npmBin = join(npmDir, "node_modules", ".bin"); const venvDir = join(agentDir, ".venv"); const systemPromptPath = join(agentDir, "SYSTEM.md"); const bashrcPath = join(homedir(), ".bashrc"); @@ -299,8 +302,31 @@ async function offerLauncher() { } } +function ensureNpmAllowScripts() { + mkdirSync(npmDir, { recursive: true }); + let pkg = { name: "pi-extensions", private: true }; + if (existsSync(npmPackageJsonPath)) { + try { + pkg = JSON.parse(readFileSync(npmPackageJsonPath, "utf8")); + } catch { + // Keep default + } + } + const allowScripts = + pkg.allowScripts && typeof pkg.allowScripts === "object" + ? pkg.allowScripts + : {}; + if (!allowScripts["agent-browser"]) { + pkg.allowScripts = { ...allowScripts, "agent-browser": true }; + const temp = join(npmDir, `.package.${process.pid}.tmp`); + writeFileSync(temp, `${JSON.stringify(pkg, null, 2)}\n`, "utf8"); + renameSync(temp, npmPackageJsonPath); + } +} + async function main() { console.log(`Configuring SecStack Pi under ${agentDir}`); + ensureNpmAllowScripts(); for (const source of managedSources) { runPi(["install", source]); }