blitzstrike 1.0.31 → 1.0.32

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
@@ -51,6 +51,9 @@ code path, not a slogan.
51
51
  master reference of web attack vectors (RCE, SQL, auth, SSRF, XSS, API,
52
52
  business logic, race conditions, cloud, supply chain, CI/CD, AI/LLM, Web3,
53
53
  XS-leaks, …) for BLITZ attack-surface mapping.
54
+ - **Self-update** (`blitzstrike update` + `check_update` tool) — query the npm
55
+ registry for the latest version (semver-aware) and refresh the heavy data
56
+ cache (payloads + templates) in one shot.
54
57
 
55
58
  ### Changed
56
59
 
package/README.md CHANGED
@@ -117,6 +117,8 @@ blitzstrike serve --mcp # start MCP server over stdio (default)
117
117
  blitzstrike doctor # health check: runtime + 130-tool catalog + creds
118
118
  blitzstrike install # write MCP config to detected clients (Claude/Cursor/OpenCode)
119
119
  blitzstrike install --dry-run # preview the config without writing
120
+ blitzstrike sync-data # fetch heavy datasets (payloads + templates) on-demand
121
+ blitzstrike update # check for a newer version + refresh the data cache
120
122
  blitzstrike version # print version
121
123
  ```
122
124
 
@@ -226,6 +228,7 @@ MCP servers. With no client detected, it prints the snippet for manual paste.
226
228
  | `template_lookup(topic)` | Find nuclei detection templates (11.9k YAML signatures). |
227
229
  | `list_attack_vectors()` | List the full web attack-vector taxonomy (34 categories, 588 vectors). |
228
230
  | `attack_vectors(category)` | Enumerate the vector list for one category (e.g. ssrf, business logic, ai/llm). |
231
+ | `check_update()` | Query the npm registry for the latest blitzstrike version. |
229
232
 
230
233
  The intelligence layer (WAF signatures, tech/CVE/port correlations, fuzzer
231
234
  data, vuln ontology, exploit payloads, nuclei detection templates) is sourced
package/dist/index.js CHANGED
@@ -14820,11 +14820,11 @@ var require_src = __commonJS(function(exports, module) {
14820
14820
  });
14821
14821
 
14822
14822
  // src/sync.ts
14823
- import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync4, readFileSync as readFileSync11, readdirSync as readdirSync5, statSync as statSync3, rmSync as rmSync2 } from "node:fs";
14824
- import { join as join9 } from "node:path";
14825
- import { homedir as homedir4 } from "node:os";
14826
- import { fileURLToPath as fileURLToPath7 } from "node:url";
14827
- import { spawnSync as spawnSync3 } from "node:child_process";
14823
+ import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync3, readFileSync as readFileSync10, readdirSync as readdirSync5, statSync as statSync3, rmSync as rmSync2 } from "node:fs";
14824
+ import { join as join8 } from "node:path";
14825
+ import { homedir as homedir3 } from "node:os";
14826
+ import { fileURLToPath as fileURLToPath6 } from "node:url";
14827
+ import { spawnSync as spawnSync2 } from "node:child_process";
14828
14828
  function dirExists(p) {
14829
14829
  try {
14830
14830
  return statSync3(p).isDirectory();
@@ -14838,7 +14838,7 @@ function countFiles(dir) {
14838
14838
  const walk = (d) => {
14839
14839
  for (const e of readdirSync5(d, { withFileTypes: true })) {
14840
14840
  if (e.isDirectory())
14841
- walk(join9(d, e.name));
14841
+ walk(join8(d, e.name));
14842
14842
  else
14843
14843
  n++;
14844
14844
  }
@@ -14851,9 +14851,9 @@ function countFiles(dir) {
14851
14851
  }
14852
14852
  function syncData() {
14853
14853
  if (!dirExists(DATA_ROOT2))
14854
- mkdirSync3(DATA_ROOT2, { recursive: true });
14855
- const payloadsPath = join9(DATA_ROOT2, "payloads");
14856
- const templatesPath = join9(DATA_ROOT2, "templates");
14854
+ mkdirSync2(DATA_ROOT2, { recursive: true });
14855
+ const payloadsPath = join8(DATA_ROOT2, "payloads");
14856
+ const templatesPath = join8(DATA_ROOT2, "templates");
14857
14857
  const hasPayloads = dirExists(payloadsPath) && countFiles(payloadsPath) > 0;
14858
14858
  const hasTemplates = dirExists(templatesPath) && countFiles(templatesPath) > 0;
14859
14859
  if (hasPayloads && hasTemplates) {
@@ -14863,8 +14863,8 @@ function syncData() {
14863
14863
  data_root: DATA_ROOT2
14864
14864
  };
14865
14865
  }
14866
- const localPayloads = join9(ROOT6, "payloads");
14867
- const localTemplates = join9(ROOT6, "templates");
14866
+ const localPayloads = join8(ROOT5, "payloads");
14867
+ const localTemplates = join8(ROOT5, "templates");
14868
14868
  let payloadsSynced = false;
14869
14869
  let templatesSynced = false;
14870
14870
  if (!hasPayloads && dirExists(localPayloads)) {
@@ -14875,21 +14875,21 @@ function syncData() {
14875
14875
  copyDir(localTemplates, templatesPath);
14876
14876
  templatesSynced = true;
14877
14877
  }
14878
- const gitOk = spawnSync3("git", ["--version"]).status === 0;
14878
+ const gitOk = spawnSync2("git", ["--version"]).status === 0;
14879
14879
  if (gitOk && (!dirExists(payloadsPath) || countFiles(payloadsPath) === 0 || !dirExists(templatesPath) || countFiles(templatesPath) === 0)) {
14880
- const tmp = join9(DATA_ROOT2, ".tmp-clone");
14880
+ const tmp = join8(DATA_ROOT2, ".tmp-clone");
14881
14881
  if (dirExists(tmp))
14882
14882
  rmSync2(tmp, { recursive: true, force: true });
14883
- const r = spawnSync3("git", ["clone", "--depth", "1", "--filter=blob:none", "--sparse", GITHUB_REPO, tmp], { timeout: 120000 });
14883
+ const r = spawnSync2("git", ["clone", "--depth", "1", "--filter=blob:none", "--sparse", GITHUB_REPO, tmp], { timeout: 120000 });
14884
14884
  if (r.status === 0) {
14885
- const sparse = spawnSync3("git", ["-C", tmp, "sparse-checkout", "set", "payloads", "templates"], { timeout: 120000 });
14885
+ const sparse = spawnSync2("git", ["-C", tmp, "sparse-checkout", "set", "payloads", "templates"], { timeout: 120000 });
14886
14886
  if (sparse.status === 0) {
14887
14887
  if (!dirExists(payloadsPath) || countFiles(payloadsPath) === 0) {
14888
- copyDir(join9(tmp, "payloads"), payloadsPath);
14888
+ copyDir(join8(tmp, "payloads"), payloadsPath);
14889
14889
  payloadsSynced = true;
14890
14890
  }
14891
14891
  if (!dirExists(templatesPath) || countFiles(templatesPath) === 0) {
14892
- copyDir(join9(tmp, "templates"), templatesPath);
14892
+ copyDir(join8(tmp, "templates"), templatesPath);
14893
14893
  templatesSynced = true;
14894
14894
  }
14895
14895
  }
@@ -14903,26 +14903,67 @@ function syncData() {
14903
14903
  };
14904
14904
  }
14905
14905
  function copyDir(src, dst) {
14906
- const r = spawnSync3("cp", ["-r", src, dst], { timeout: 120000 });
14906
+ const r = spawnSync2("cp", ["-r", src, dst], { timeout: 120000 });
14907
14907
  if (r.status !== 0) {
14908
14908
  manualCopy(src, dst);
14909
14909
  }
14910
14910
  }
14911
14911
  function manualCopy(src, dst) {
14912
- mkdirSync3(dst, { recursive: true });
14912
+ mkdirSync2(dst, { recursive: true });
14913
14913
  for (const e of readdirSync5(src, { withFileTypes: true })) {
14914
- const s = join9(src, e.name);
14915
- const d = join9(dst, e.name);
14914
+ const s = join8(src, e.name);
14915
+ const d = join8(dst, e.name);
14916
14916
  if (e.isDirectory())
14917
14917
  manualCopy(s, d);
14918
14918
  else
14919
- writeFileSync4(d, readFileSync11(s));
14919
+ writeFileSync3(d, readFileSync10(s));
14920
14920
  }
14921
14921
  }
14922
- var ROOT6, DATA_ROOT2, GITHUB_REPO = "https://github.com/shinthink/blitzstrike.git";
14922
+ var ROOT5, DATA_ROOT2, GITHUB_REPO = "https://github.com/shinthink/blitzstrike.git";
14923
14923
  var init_sync = __esm(() => {
14924
- ROOT6 = join9(fileURLToPath7(new URL(".", import.meta.url)), "..");
14925
- DATA_ROOT2 = process.env.BLITZSTRIKE_DATA ?? join9(homedir4(), ".blitzstrike", "data");
14924
+ ROOT5 = join8(fileURLToPath6(new URL(".", import.meta.url)), "..");
14925
+ DATA_ROOT2 = process.env.BLITZSTRIKE_DATA ?? join8(homedir3(), ".blitzstrike", "data");
14926
+ });
14927
+
14928
+ // src/update.ts
14929
+ async function checkLatestVersion(timeoutMs = 1e4) {
14930
+ try {
14931
+ const controller = new AbortController;
14932
+ const t = setTimeout(() => controller.abort(), timeoutMs);
14933
+ const res = await fetch("https://registry.npmjs.org/blitzstrike/latest", { signal: controller.signal });
14934
+ clearTimeout(t);
14935
+ if (!res.ok)
14936
+ return null;
14937
+ const data = await res.json();
14938
+ return data.version ?? null;
14939
+ } catch {
14940
+ return null;
14941
+ }
14942
+ }
14943
+ function semverCompare(a, b) {
14944
+ const pa = a.replace(/^v/, "").split(".").map((n) => parseInt(n, 10) || 0);
14945
+ const pb = b.replace(/^v/, "").split(".").map((n) => parseInt(n, 10) || 0);
14946
+ for (let i = 0;i < 3; i++) {
14947
+ const x = pa[i] ?? 0;
14948
+ const y = pb[i] ?? 0;
14949
+ if (x !== y)
14950
+ return x < y ? -1 : 1;
14951
+ }
14952
+ return 0;
14953
+ }
14954
+ async function runUpdate(currentVersion) {
14955
+ const latest = await checkLatestVersion();
14956
+ const outdated = latest !== null && semverCompare(currentVersion, latest) < 0;
14957
+ return {
14958
+ current: currentVersion,
14959
+ latest,
14960
+ outdated,
14961
+ update_command: "npm install -g blitzstrike@latest # or: bun add -g blitzstrike@latest",
14962
+ data_sync: syncData()
14963
+ };
14964
+ }
14965
+ var init_update = __esm(() => {
14966
+ init_sync();
14926
14967
  });
14927
14968
 
14928
14969
  // node_modules/zod/v3/helpers/util.js
@@ -50833,6 +50874,18 @@ function coverageMatrix() {
50833
50874
  }
50834
50875
 
50835
50876
  // src/server.ts
50877
+ init_update();
50878
+ import { readFileSync as readFileSync11 } from "node:fs";
50879
+ import { join as join9, dirname } from "node:path";
50880
+ import { fileURLToPath as fileURLToPath7 } from "node:url";
50881
+ var VERSION = (() => {
50882
+ try {
50883
+ const root = join9(dirname(fileURLToPath7(import.meta.url)), "..");
50884
+ return JSON.parse(readFileSync11(join9(root, "package.json"), "utf8")).version ?? "unknown";
50885
+ } catch {
50886
+ return "unknown";
50887
+ }
50888
+ })();
50836
50889
  function createServer() {
50837
50890
  const server = new McpServer({
50838
50891
  name: "blitzstrike",
@@ -51589,7 +51642,7 @@ function createServer() {
51589
51642
  } catch {
51590
51643
  return { content: [{ type: "text", text: JSON.stringify({ error: "invalid JSON" }) }] };
51591
51644
  }
51592
- const opts = { title, scope, version: "1.0.23" };
51645
+ const opts = { title, scope, version: VERSION };
51593
51646
  const out = (format ?? "markdown") === "json" ? reportJson(list, opts) : reportMarkdown(list, opts);
51594
51647
  return { content: [{ type: "text", text: out }] };
51595
51648
  });
@@ -51607,6 +51660,14 @@ function createServer() {
51607
51660
  }, async () => {
51608
51661
  return { content: [{ type: "text", text: JSON.stringify(coverageMatrix()) }] };
51609
51662
  });
51663
+ server.registerTool("check_update", {
51664
+ title: "Check for a newer blitzstrike version",
51665
+ description: "UPDATE: query the npm registry for the latest blitzstrike version. Tells a driving agent whether the package or the data cache is stale.",
51666
+ inputSchema: {}
51667
+ }, async () => {
51668
+ const latest = await checkLatestVersion();
51669
+ return { content: [{ type: "text", text: JSON.stringify({ latest, note: "package updates via `npx blitzstrike` (always-latest) or `npm i -g blitzstrike@latest`; heavy data via `blitzstrike sync-data`" }) }] };
51670
+ });
51610
51671
  return server;
51611
51672
  }
51612
51673
  async function serve() {
@@ -51616,14 +51677,14 @@ async function serve() {
51616
51677
  }
51617
51678
 
51618
51679
  // src/cli.ts
51619
- import { readFileSync as readFileSync10, existsSync as existsSync5, writeFileSync as writeFileSync3, mkdirSync as mkdirSync2 } from "node:fs";
51620
- import { join as join8, dirname } from "node:path";
51621
- import { homedir as homedir3 } from "node:os";
51622
- import { fileURLToPath as fileURLToPath6 } from "node:url";
51623
- import { spawnSync as spawnSync2 } from "node:child_process";
51624
- var ROOT5 = join8(fileURLToPath6(new URL(".", import.meta.url)), "..");
51680
+ import { readFileSync as readFileSync12, existsSync as existsSync5, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3 } from "node:fs";
51681
+ import { join as join10, dirname as dirname2 } from "node:path";
51682
+ import { homedir as homedir4 } from "node:os";
51683
+ import { fileURLToPath as fileURLToPath8 } from "node:url";
51684
+ import { spawnSync as spawnSync3 } from "node:child_process";
51685
+ var ROOT6 = join10(fileURLToPath8(new URL(".", import.meta.url)), "..");
51625
51686
  function which(cmd) {
51626
- return spawnSync2(`command -v ${cmd}`, { shell: true }).status === 0;
51687
+ return spawnSync3(`command -v ${cmd}`, { shell: true }).status === 0;
51627
51688
  }
51628
51689
  function installedCount() {
51629
51690
  const tools = loadTools();
@@ -51656,7 +51717,7 @@ function runDoctor() {
51656
51717
  detail: fofa ? "set" : "FOFA_EMAIL/FOFA_KEY not set",
51657
51718
  fix: fofa ? undefined : "export FOFA_EMAIL=... && export FOFA_KEY=... (enables fofa_search)"
51658
51719
  });
51659
- const dataOk = existsSync5(join8(ROOT5, "chains.json")) && existsSync5(join8(ROOT5, "tools-catalog.json"));
51720
+ const dataOk = existsSync5(join10(ROOT6, "chains.json")) && existsSync5(join10(ROOT6, "tools-catalog.json"));
51660
51721
  issues.push({
51661
51722
  name: "Data layers (chains + tools-catalog)",
51662
51723
  status: dataOk ? "ok" : "fail",
@@ -51684,73 +51745,73 @@ BlitzStrike — ${verdict}`);
51684
51745
  function resolveCommand() {
51685
51746
  if (which("blitzstrike"))
51686
51747
  return { command: "blitzstrike", args: ["serve", "--mcp"] };
51687
- const src = join8(ROOT5, "src", "index.ts");
51748
+ const src = join10(ROOT6, "src", "index.ts");
51688
51749
  if (which("bun") && existsSync5(src))
51689
51750
  return { command: "bun", args: ["run", src, "serve", "--mcp"] };
51690
51751
  if (which("npx"))
51691
51752
  return { command: "npx", args: ["-y", "blitzstrike", "serve", "--mcp"] };
51692
51753
  if (which("bunx"))
51693
51754
  return { command: "bunx", args: ["blitzstrike", "serve", "--mcp"] };
51694
- const dist = join8(ROOT5, "dist", "index.js");
51755
+ const dist = join10(ROOT6, "dist", "index.js");
51695
51756
  if (existsSync5(dist))
51696
51757
  return { command: "bun", args: [dist, "serve", "--mcp"] };
51697
51758
  return { command: "npx", args: ["-y", "blitzstrike", "serve", "--mcp"] };
51698
51759
  }
51699
51760
  function readJson(p) {
51700
51761
  try {
51701
- return JSON.parse(readFileSync10(p, "utf8"));
51762
+ return JSON.parse(readFileSync12(p, "utf8"));
51702
51763
  } catch {
51703
51764
  return null;
51704
51765
  }
51705
51766
  }
51706
51767
  function jsonMcpServersWrite(p) {
51707
51768
  return (command, args) => {
51708
- const dir = dirname(p);
51769
+ const dir = dirname2(p);
51709
51770
  if (!existsSync5(dir))
51710
- mkdirSync2(dir, { recursive: true });
51771
+ mkdirSync3(dir, { recursive: true });
51711
51772
  const existing = readJson(p) ?? {};
51712
51773
  existing.mcpServers = {
51713
51774
  ...existing.mcpServers ?? {},
51714
51775
  blitzstrike: { command, args }
51715
51776
  };
51716
- writeFileSync3(p, JSON.stringify(existing, null, 2));
51777
+ writeFileSync4(p, JSON.stringify(existing, null, 2));
51717
51778
  };
51718
51779
  }
51719
51780
  function opencodeWrite(p) {
51720
51781
  return (_command, _args) => {
51721
- const dir = dirname(p);
51782
+ const dir = dirname2(p);
51722
51783
  if (!existsSync5(dir))
51723
- mkdirSync2(dir, { recursive: true });
51784
+ mkdirSync3(dir, { recursive: true });
51724
51785
  const existing = readJson(p) ?? {};
51725
51786
  existing.mcp = {
51726
51787
  ...existing.mcp ?? {},
51727
51788
  blitzstrike: { type: "local", command: ["npx", "-y", "blitzstrike", "serve", "--mcp"], enabled: true }
51728
51789
  };
51729
- writeFileSync3(p, JSON.stringify(existing, null, 2));
51790
+ writeFileSync4(p, JSON.stringify(existing, null, 2));
51730
51791
  copyOpenCodeAgents();
51731
51792
  };
51732
51793
  }
51733
51794
  function copyOpenCodeAgents() {
51734
- const srcDir = join8(ROOT5, "opencode-agents");
51735
- const dstDir = join8(homedir3(), ".config", "opencode", "agents");
51795
+ const srcDir = join10(ROOT6, "opencode-agents");
51796
+ const dstDir = join10(homedir4(), ".config", "opencode", "agents");
51736
51797
  if (!existsSync5(srcDir))
51737
51798
  return;
51738
51799
  if (!existsSync5(dstDir))
51739
- mkdirSync2(dstDir, { recursive: true });
51800
+ mkdirSync3(dstDir, { recursive: true });
51740
51801
  for (const f of ["Blitz Strike.md", "Blitz.md", "Eagle Eye.md", "Strike.md"]) {
51741
- const src = join8(srcDir, f);
51742
- const dst = join8(dstDir, f);
51802
+ const src = join10(srcDir, f);
51803
+ const dst = join10(dstDir, f);
51743
51804
  if (existsSync5(src)) {
51744
- writeFileSync3(dst, readFileSync10(src, "utf8"));
51805
+ writeFileSync4(dst, readFileSync12(src, "utf8"));
51745
51806
  }
51746
51807
  }
51747
51808
  }
51748
51809
  function codexWrite(p) {
51749
51810
  return (command, args) => {
51750
- const dir = dirname(p);
51811
+ const dir = dirname2(p);
51751
51812
  if (!existsSync5(dir))
51752
- mkdirSync2(dir, { recursive: true });
51753
- let existing = existsSync5(p) ? readFileSync10(p, "utf8") : "";
51813
+ mkdirSync3(dir, { recursive: true });
51814
+ let existing = existsSync5(p) ? readFileSync12(p, "utf8") : "";
51754
51815
  if (!existing.trimEnd().endsWith(`
51755
51816
  `))
51756
51817
  existing += `
@@ -51761,15 +51822,15 @@ function codexWrite(p) {
51761
51822
  command = "${command}"
51762
51823
  args = ${JSON.stringify(args)}
51763
51824
  `;
51764
- writeFileSync3(p, existing);
51825
+ writeFileSync4(p, existing);
51765
51826
  };
51766
51827
  }
51767
51828
  function hermesWrite(p) {
51768
51829
  return (command, args) => {
51769
- const dir = dirname(p);
51830
+ const dir = dirname2(p);
51770
51831
  if (!existsSync5(dir))
51771
- mkdirSync2(dir, { recursive: true });
51772
- let existing = existsSync5(p) ? readFileSync10(p, "utf8") : "";
51832
+ mkdirSync3(dir, { recursive: true });
51833
+ let existing = existsSync5(p) ? readFileSync12(p, "utf8") : "";
51773
51834
  existing = existing.replace(/^ blitzstrike:\n(?: .*\n?)*/m, "");
51774
51835
  if (!existing.trimEnd().endsWith(`
51775
51836
  `))
@@ -51790,80 +51851,80 @@ mcp_servers:
51790
51851
  args: ${JSON.stringify(args)}
51791
51852
  `;
51792
51853
  }
51793
- writeFileSync3(p, existing);
51854
+ writeFileSync4(p, existing);
51794
51855
  };
51795
51856
  }
51796
51857
  function detectAgents() {
51797
- const home = homedir3();
51858
+ const home = homedir4();
51798
51859
  const agents = [];
51799
- const claudeJson = join8(home, ".claude.json");
51860
+ const claudeJson = join10(home, ".claude.json");
51800
51861
  agents.push({
51801
51862
  name: "Claude Code",
51802
51863
  detectPath: claudeJson,
51803
51864
  installed: () => existsSync5(claudeJson) || which("claude"),
51804
51865
  write: jsonMcpServersWrite(claudeJson)
51805
51866
  });
51806
- const claudeDesktop = join8(home, ".config", "Claude", "claude_desktop_config.json");
51867
+ const claudeDesktop = join10(home, ".config", "Claude", "claude_desktop_config.json");
51807
51868
  agents.push({
51808
51869
  name: "Claude Desktop",
51809
51870
  detectPath: claudeDesktop,
51810
51871
  installed: () => existsSync5(claudeDesktop),
51811
51872
  write: jsonMcpServersWrite(claudeDesktop)
51812
51873
  });
51813
- const cursor = join8(home, ".cursor", "mcp.json");
51874
+ const cursor = join10(home, ".cursor", "mcp.json");
51814
51875
  agents.push({
51815
51876
  name: "Cursor",
51816
51877
  detectPath: cursor,
51817
- installed: () => existsSync5(join8(home, ".cursor")) || which("cursor"),
51878
+ installed: () => existsSync5(join10(home, ".cursor")) || which("cursor"),
51818
51879
  write: jsonMcpServersWrite(cursor)
51819
51880
  });
51820
- const opencode = join8(home, ".config", "opencode", "opencode.jsonc");
51881
+ const opencode = join10(home, ".config", "opencode", "opencode.jsonc");
51821
51882
  agents.push({
51822
51883
  name: "OpenCode",
51823
51884
  detectPath: opencode,
51824
- installed: () => existsSync5(join8(home, ".config", "opencode")) || which("opencode"),
51885
+ installed: () => existsSync5(join10(home, ".config", "opencode")) || which("opencode"),
51825
51886
  write: opencodeWrite(opencode)
51826
51887
  });
51827
- const codex = join8(home, ".codex", "config.toml");
51888
+ const codex = join10(home, ".codex", "config.toml");
51828
51889
  agents.push({
51829
51890
  name: "Codex",
51830
51891
  detectPath: codex,
51831
- installed: () => existsSync5(join8(home, ".codex")) || which("codex"),
51892
+ installed: () => existsSync5(join10(home, ".codex")) || which("codex"),
51832
51893
  write: codexWrite(codex)
51833
51894
  });
51834
- const hermes = join8(home, ".hermes", "config.yaml");
51895
+ const hermes = join10(home, ".hermes", "config.yaml");
51835
51896
  agents.push({
51836
51897
  name: "Hermes",
51837
51898
  detectPath: hermes,
51838
- installed: () => existsSync5(join8(home, ".hermes")) || which("hermes"),
51899
+ installed: () => existsSync5(join10(home, ".hermes")) || which("hermes"),
51839
51900
  write: hermesWrite(hermes)
51840
51901
  });
51841
- const gemini = join8(home, ".gemini", "settings.json");
51902
+ const gemini = join10(home, ".gemini", "settings.json");
51842
51903
  agents.push({
51843
51904
  name: "Gemini CLI",
51844
51905
  detectPath: gemini,
51845
- installed: () => existsSync5(join8(home, ".gemini")) || which("gemini"),
51906
+ installed: () => existsSync5(join10(home, ".gemini")) || which("gemini"),
51846
51907
  write: jsonMcpServersWrite(gemini)
51847
51908
  });
51848
- const windsurf = join8(home, ".codeium", "windsurf", "mcp_config.json");
51909
+ const windsurf = join10(home, ".codeium", "windsurf", "mcp_config.json");
51849
51910
  agents.push({
51850
51911
  name: "Windsurf",
51851
51912
  detectPath: windsurf,
51852
- installed: () => existsSync5(join8(home, ".codeium")) || which("windsurf"),
51913
+ installed: () => existsSync5(join10(home, ".codeium")) || which("windsurf"),
51853
51914
  write: jsonMcpServersWrite(windsurf)
51854
51915
  });
51855
- const copilot = join8(home, ".copilot", "mcp.json");
51916
+ const copilot = join10(home, ".copilot", "mcp.json");
51856
51917
  agents.push({
51857
51918
  name: "Copilot",
51858
51919
  detectPath: copilot,
51859
- installed: () => existsSync5(join8(home, ".copilot")),
51920
+ installed: () => existsSync5(join10(home, ".copilot")),
51860
51921
  write: jsonMcpServersWrite(copilot)
51861
51922
  });
51862
- const cline = join8(home, ".cline", "mcp_settings.json");
51923
+ const cline = join10(home, ".cline", "mcp_settings.json");
51863
51924
  agents.push({
51864
51925
  name: "Cline",
51865
51926
  detectPath: cline,
51866
- installed: () => existsSync5(join8(home, ".cline")),
51927
+ installed: () => existsSync5(join10(home, ".cline")),
51867
51928
  write: jsonMcpServersWrite(cline)
51868
51929
  });
51869
51930
  return agents;
@@ -51907,29 +51968,31 @@ Registered with ${ok}/${installed.length} agent(s).`);
51907
51968
  }
51908
51969
 
51909
51970
  // src/index.ts
51910
- import { readFileSync as readFileSync12, existsSync as existsSync6 } from "node:fs";
51911
- import { join as join10 } from "node:path";
51912
- import { fileURLToPath as fileURLToPath8 } from "node:url";
51913
- var ROOT7 = join10(fileURLToPath8(new URL(".", import.meta.url)), "..");
51971
+ import { readFileSync as readFileSync13, existsSync as existsSync6 } from "node:fs";
51972
+ import { join as join11 } from "node:path";
51973
+ import { fileURLToPath as fileURLToPath9 } from "node:url";
51974
+ var ROOT7 = join11(fileURLToPath9(new URL(".", import.meta.url)), "..");
51914
51975
  function readVersion() {
51915
51976
  try {
51916
- const p = join10(ROOT7, "package.json");
51977
+ const p = join11(ROOT7, "package.json");
51917
51978
  if (existsSync6(p))
51918
- return JSON.parse(readFileSync12(p, "utf8")).version ?? "1.0.0";
51979
+ return JSON.parse(readFileSync13(p, "utf8")).version ?? "1.0.0";
51919
51980
  } catch {}
51920
51981
  return "1.0.0";
51921
51982
  }
51922
- var VERSION = readVersion();
51983
+ var VERSION2 = readVersion();
51923
51984
  function usage() {
51924
- return `BlitzStrike ${VERSION} — MCP security-audit toolbelt
51985
+ return `BlitzStrike ${VERSION2} — MCP security-audit toolbelt
51925
51986
 
51926
51987
  Usage:
51927
51988
  blitzstrike serve --mcp Start the MCP server over stdio (default transport)
51928
51989
  blitzstrike doctor Environment health check (runtime + tools + creds)
51929
51990
  blitzstrike install Write MCP client config to detected clients
51930
51991
  blitzstrike install --dry-run Print the config without writing
51931
- blitzstrike version Print version
51932
- blitzstrike --help This help`;
51992
+ blitzstrike sync-data Fetch heavy datasets (payloads + templates) on-demand
51993
+ blitzstrike update Check for a newer version + refresh the data cache
51994
+ blitzstrike version Print version
51995
+ blitzstrike --help This help`;
51933
51996
  }
51934
51997
  async function main() {
51935
51998
  const args = process.argv.slice(2);
@@ -51938,7 +52001,7 @@ async function main() {
51938
52001
  return;
51939
52002
  }
51940
52003
  if (args[0] === "version" || args[0] === "--version" || args[0] === "-v") {
51941
- console.log(`blitzstrike ${VERSION}`);
52004
+ console.log(`blitzstrike ${VERSION2}`);
51942
52005
  return;
51943
52006
  }
51944
52007
  if (args[0] === "doctor") {
@@ -51958,6 +52021,22 @@ async function main() {
51958
52021
  console.log(` templates: ${r.templates.files} files ${r.templates.synced ? "(synced)" : "(already present)"}`);
51959
52022
  return;
51960
52023
  }
52024
+ if (args[0] === "update") {
52025
+ await Promise.resolve().then(() => init_update());
52026
+ const r = await runUpdate(VERSION2);
52027
+ console.log("Blitz Strike self-update");
52028
+ console.log(` current: ${r.current}`);
52029
+ console.log(` latest: ${r.latest ?? "unknown (registry unreachable)"}`);
52030
+ if (r.outdated) {
52031
+ console.log(` status: OUTDATED — update with: ${r.update_command}`);
52032
+ } else if (r.latest === null) {
52033
+ console.log(` status: could not reach npm registry`);
52034
+ } else {
52035
+ console.log(` status: up to date`);
52036
+ }
52037
+ console.log(` data: payloads ${r.data_sync.payloads.files} files, templates ${r.data_sync.templates.files} files ${r.data_sync.payloads.synced ? "(refreshed)" : ""}`);
52038
+ return;
52039
+ }
51961
52040
  if (args[0] === "serve") {
51962
52041
  await serve();
51963
52042
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blitzstrike",
3
- "version": "1.0.31",
3
+ "version": "1.0.32",
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": {