blitzstrike 2.4.15 → 2.4.17

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/CHANGELOG.md CHANGED
@@ -5,6 +5,28 @@ All notable changes to Blitz Strike are documented here.
5
5
  The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/).
7
7
 
8
+ ## [2.4.17] — 2026-09-14
9
+
10
+ ### Added — auto-provision toolchains + non-interactive installs
11
+
12
+ - Preflight now AUTO-PROVISIONS missing build toolchains (go, cargo, meson, ninja)
13
+ instead of only warning — `install-tools` installs them via apt before the
14
+ mass install, so `go install` / `meson build` / `ninja` no longer fail.
15
+ - All install commands now run with stdin closed (non-interactive) — prompts like
16
+ metasploit's "Overwrite? (y/N)" can no longer hang the run; `yes |` is piped
17
+ where an interactive confirm is required.
18
+
19
+ ## [2.4.16] — 2026-09-14
20
+
21
+ ### Added — auto-fallback install (toolchain provision + pip fallback)
22
+
23
+ - `go install` / `cargo install` tools now auto-provision the missing toolchain
24
+ (`apt-get install golang-go` / `cargo`) before installing — no more
25
+ "go: not found" / "cargo: not found" failures (provisioned once per run).
26
+ - `pip install --break-system-packages` now falls back to `pip install --user`
27
+ when the flag is unsupported (pip < 23.0 on older distros) — no more
28
+ "no such option: --break-system-packages".
29
+
8
30
  ## [2.4.15] — 2026-09-14
9
31
 
10
32
  ### Fixed — detection → verification loop now unmissable
package/dist/index.js CHANGED
@@ -7403,6 +7403,50 @@ import { join as join6 } from "node:path";
7403
7403
  import { fileURLToPath as fileURLToPath3 } from "node:url";
7404
7404
  import { homedir as homedir3 } from "node:os";
7405
7405
  import { spawnSync, spawn } from "node:child_process";
7406
+ function provisionMissingToolchains() {
7407
+ const missing = [];
7408
+ for (const [tc, inst] of Object.entries(TOOLCHAIN_INSTALL)) {
7409
+ if (hasCommand(tc))
7410
+ continue;
7411
+ missing.push(tc);
7412
+ spawnSync(inst, { shell: true, timeout: 300000, stdio: ["ignore", "pipe", "pipe"] });
7413
+ }
7414
+ return missing;
7415
+ }
7416
+ function hasCommand(cmd) {
7417
+ return spawnSync(`command -v ${cmd}`, { shell: true, timeout: 8000 }).status === 0;
7418
+ }
7419
+ function requiredToolchain(cmd) {
7420
+ if (/^\s*go\s+install\b/.test(cmd))
7421
+ return "go";
7422
+ if (/^\s*cargo\s+(install|build)\b/.test(cmd))
7423
+ return "cargo";
7424
+ return null;
7425
+ }
7426
+ function provisionToolchain(cmd) {
7427
+ const tc = requiredToolchain(cmd);
7428
+ if (!tc || hasCommand(tc) || _provisioned.has(tc))
7429
+ return;
7430
+ _provisioned.add(tc);
7431
+ const inst = TOOLCHAIN_INSTALL[tc];
7432
+ if (!inst)
7433
+ return;
7434
+ spawnSync(inst, { shell: true, timeout: 300000 });
7435
+ }
7436
+ function runInstallCommand(cmd, timeoutMs) {
7437
+ provisionToolchain(cmd);
7438
+ let r = spawnSync(cmd, { shell: true, timeout: timeoutMs, cwd: TOOLS_DIR, stdio: ["ignore", "pipe", "pipe"] });
7439
+ let output = `${r.stdout?.toString() ?? ""}${r.stderr?.toString() ?? ""}`;
7440
+ if (r.status !== 0 && /--break-system-packages/.test(cmd)) {
7441
+ const alt = cmd.replace(/--break-system-packages/g, "--user");
7442
+ const r2 = spawnSync(alt, { shell: true, timeout: timeoutMs, cwd: TOOLS_DIR, stdio: ["ignore", "pipe", "pipe"] });
7443
+ if (r2.status === 0)
7444
+ r = r2;
7445
+ output = `${output}
7446
+ ${r2.stdout?.toString() ?? ""}${r2.stderr?.toString() ?? ""}`;
7447
+ }
7448
+ return { status: r.status, output };
7449
+ }
7406
7450
  function loadTools() {
7407
7451
  if (_toolsCache)
7408
7452
  return _toolsCache;
@@ -7519,14 +7563,14 @@ function ensureTool(name) {
7519
7563
  return { name: t.name, installed: false, action: "none", note: `no install command for ${platform}` };
7520
7564
  }
7521
7565
  mkdirSync3(TOOLS_DIR, { recursive: true });
7522
- const r = spawnSync(cmd, { shell: true, timeout: 300000, cwd: TOOLS_DIR });
7523
- const ok = r.status === 0;
7566
+ const { status, output } = runInstallCommand(cmd, 300000);
7567
+ const ok = status === 0;
7524
7568
  return {
7525
7569
  name: t.name,
7526
7570
  installed: ok,
7527
7571
  action: "install",
7528
7572
  command: cmd,
7529
- output: (r.stdout?.toString() ?? "").slice(-400) || (r.stderr?.toString() ?? "").slice(-400)
7573
+ output: output.slice(-400)
7530
7574
  };
7531
7575
  }
7532
7576
  function toolForHint(hint) {
@@ -7619,7 +7663,8 @@ function ensureToolAsync(name, timeoutMs = 300000) {
7619
7663
  return;
7620
7664
  }
7621
7665
  mkdirSync3(TOOLS_DIR, { recursive: true });
7622
- const inst = spawn(cmd, { shell: true, timeout: timeoutMs, cwd: TOOLS_DIR });
7666
+ provisionToolchain(cmd);
7667
+ const inst = spawn(cmd, { shell: true, timeout: timeoutMs, cwd: TOOLS_DIR, stdio: ["ignore", "pipe", "pipe"] });
7623
7668
  let out = "";
7624
7669
  inst.stdout?.on("data", (d) => {
7625
7670
  out += d.toString();
@@ -7629,7 +7674,25 @@ function ensureToolAsync(name, timeoutMs = 300000) {
7629
7674
  });
7630
7675
  inst.on("error", (e) => resolve({ name: t.name, installed: false, action: "install", error: String(e) }));
7631
7676
  inst.on("close", (icode) => {
7632
- resolve({ name: t.name, installed: icode === 0, action: "install", command: cmd, output: out.slice(-400) });
7677
+ if (icode === 0) {
7678
+ resolve({ name: t.name, installed: true, action: "install", command: cmd, output: out.slice(-400) });
7679
+ return;
7680
+ }
7681
+ if (/--break-system-packages/.test(cmd)) {
7682
+ const alt = cmd.replace(/--break-system-packages/g, "--user");
7683
+ const r2 = spawn(alt, { shell: true, timeout: timeoutMs, cwd: TOOLS_DIR, stdio: ["ignore", "pipe", "pipe"] });
7684
+ let out2 = "";
7685
+ r2.stdout?.on("data", (d) => {
7686
+ out2 += d.toString();
7687
+ });
7688
+ r2.stderr?.on("data", (d) => {
7689
+ out2 += d.toString();
7690
+ });
7691
+ r2.on("error", (e) => resolve({ name: t.name, installed: false, action: "install", error: String(e) }));
7692
+ r2.on("close", (i2) => resolve({ name: t.name, installed: i2 === 0, action: "install", command: alt, output: out2.slice(-400) }));
7693
+ return;
7694
+ }
7695
+ resolve({ name: t.name, installed: false, action: "install", command: cmd, output: out.slice(-400) });
7633
7696
  });
7634
7697
  });
7635
7698
  });
@@ -7664,11 +7727,18 @@ async function installAllTools(opts = {}) {
7664
7727
  results
7665
7728
  };
7666
7729
  }
7667
- var ROOT2, TOOLS_DIR, _toolsCache = null, _skillsCache = null;
7730
+ var ROOT2, TOOLS_DIR, TOOLCHAIN_INSTALL, _provisioned, _toolsCache = null, _skillsCache = null;
7668
7731
  var init_catalog = __esm(() => {
7669
7732
  init_manuals();
7670
7733
  ROOT2 = join6(fileURLToPath3(new URL(".", import.meta.url)), "..");
7671
7734
  TOOLS_DIR = process.env.BLITZSTRIKE_TOOLS_DIR ?? join6(homedir3(), ".blitzstrike", "tools");
7735
+ TOOLCHAIN_INSTALL = {
7736
+ go: "apt-get install -y golang-go",
7737
+ cargo: "apt-get install -y cargo",
7738
+ meson: "apt-get install -y meson",
7739
+ ninja: "apt-get install -y ninja-build"
7740
+ };
7741
+ _provisioned = new Set;
7672
7742
  });
7673
7743
 
7674
7744
  // src/burp-mcp.ts
@@ -15995,12 +16065,9 @@ async function runInstallTools(args) {
15995
16065
  }
15996
16066
  console.log(`Installing catalog tools${category ? ` (category: ${category})` : ""} — concurrency ${concurrency}
15997
16067
  `);
15998
- const chainMap = { go: "golang", java: "default-jdk", python3: "python3", pip3: "python3-pip", cargo: "cargo", make: "build-essential", meson: "meson", ninja: "ninja-build", gcc: "build-essential", git: "git" };
15999
- const missingChains = Object.keys(chainMap).filter((c) => spawnSync5(`command -v ${c}`, { shell: true }).status !== 0);
16000
- if (missingChains.length) {
16001
- console.log(`⚠ Missing toolchains: ${missingChains.join(", ")} (${missingChains.map((c) => chainMap[c]).join(", ")})`);
16002
- console.log(` Tools that need them will FAIL below. Install first, e.g.:
16003
- apt install -y ${missingChains.map((c) => chainMap[c]).join(" ")}
16068
+ const provisioned = provisionMissingToolchains();
16069
+ if (provisioned.length) {
16070
+ console.log(`Provisioned missing toolchains: ${provisioned.join(", ")}
16004
16071
  `);
16005
16072
  }
16006
16073
  const tools = loadTools();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blitzstrike",
3
- "version": "2.4.15",
3
+ "version": "2.4.17",
4
4
  "description": "Blitz Strike — a universal MCP security-audit toolbelt. BLITZ sweeps the attack surface, EAGLE-EYE traces source-to-sink, STRIKE verifies live. 57 attack chains, 130-tool catalog, intelligence data layer. One server, every agent.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -2846,7 +2846,7 @@
2846
2846
  }
2847
2847
  ],
2848
2848
  "install": {
2849
- "linux": "curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb | bash",
2849
+ "linux": "curl -sL https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb -o /tmp/msfinstall && chmod +x /tmp/msfinstall && yes | /tmp/msfinstall",
2850
2850
  "darwin": "brew install metasploit",
2851
2851
  "win32": "manual"
2852
2852
  },