seamshield 0.1.2 → 0.1.3

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/index.js CHANGED
@@ -99,7 +99,7 @@ var require_picocolors = __commonJS({
99
99
  });
100
100
 
101
101
  // src/index.ts
102
- import { spawnSync as spawnSync2 } from "child_process";
102
+ import { spawnSync as spawnSync3 } from "child_process";
103
103
  import { existsSync as existsSync2, mkdirSync, mkdtempSync, readFileSync as readFileSync6, rmSync, writeFileSync } from "fs";
104
104
  import { tmpdir } from "os";
105
105
  import { dirname as dirname3, join as join7, resolve as resolve2 } from "path";
@@ -141,6 +141,7 @@ import { dirname as dirname2, join as join4 } from "path";
141
141
  import { existsSync } from "fs";
142
142
  import { dirname as dirname22, join as join5 } from "path";
143
143
  import { readdirSync as readdirSync2, readFileSync as readFileSync4, statSync } from "fs";
144
+ import { spawnSync as spawnSync2 } from "child_process";
144
145
  import { join as join6, relative as relative2 } from "path";
145
146
  import { z as z3 } from "zod";
146
147
  var ConfigSchema = z.object({
@@ -713,6 +714,8 @@ var SKIP_DIRS = /* @__PURE__ */ new Set([
713
714
  ]);
714
715
  var MAX_FILE_BYTES = 1e6;
715
716
  function walk(root) {
717
+ const gitFiles = gitTrackedAndUnignoredFiles(root);
718
+ if (gitFiles) return gitFiles;
716
719
  const files = [];
717
720
  const visit = (dir) => {
718
721
  let entries;
@@ -743,6 +746,15 @@ function walk(root) {
743
746
  visit(root);
744
747
  return files;
745
748
  }
749
+ function gitTrackedAndUnignoredFiles(root) {
750
+ const result = spawnSync2(
751
+ "git",
752
+ ["-C", root, "ls-files", "--cached", "--others", "--exclude-standard"],
753
+ { encoding: "utf8", timeout: 1500 }
754
+ );
755
+ if (result.error || result.status !== 0 || typeof result.stdout !== "string") return null;
756
+ return result.stdout.split("\n").filter(Boolean).filter((rel) => !rel.split("/").some((part) => SKIP_DIRS.has(part))).filter((rel) => rel !== ".claude/worktrees" && !rel.includes("/.claude/worktrees/")).filter((rel) => rel !== ".worktrees" && !rel.startsWith(".worktrees/")).map((rel) => ({ abs: join6(root, rel), rel }));
757
+ }
746
758
  var FileCache = class {
747
759
  cache = /* @__PURE__ */ new Map();
748
760
  read(abs) {
@@ -1013,7 +1025,7 @@ function bashDecision(command) {
1013
1025
  const name = command.match(/npm\s+(?:i|install|add)\s+(@?[\w.-]+\/?[\w.-]*)/)?.[1];
1014
1026
  if (name) {
1015
1027
  const encoded = name.startsWith("@") ? name.replace("/", "%2F") : name;
1016
- const res = spawnSync2("curl", ["-fsSI", `https://registry.npmjs.org/${encoded}`], {
1028
+ const res = spawnSync3("curl", ["-fsSI", `https://registry.npmjs.org/${encoded}`], {
1017
1029
  encoding: "utf8",
1018
1030
  timeout: 750
1019
1031
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "seamshield",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Security scanner for AI-generated apps: finds the flaws vibecoded projects predictably ship",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -19,9 +19,15 @@ check:
19
19
  - ".cjs"
20
20
  basenames:
21
21
  - ".env*"
22
+ exclude:
23
+ dirs:
24
+ - "scripts"
25
+ - "test"
26
+ - "tests"
27
+ - "__tests__"
22
28
  patterns:
23
29
  - name: next-public-secret-name
24
- regex: "NEXT_PUBLIC_[A-Z0-9_]*(?:SECRET|SERVICE_ROLE|PRIVATE|PASSWORD|ADMIN)[A-Z0-9_]*"
30
+ regex: "(?:^\\s*|process\\.env\\.|import\\.meta\\.env\\.)(NEXT_PUBLIC_[A-Z0-9_]*(?:SECRET|SERVICE_ROLE|PRIVATE|PASSWORD|ADMIN)[A-Z0-9_]*)"
25
31
  fix:
26
32
  summary: Rename the variable to drop the NEXT_PUBLIC_ prefix and read it only on the server.
27
33
  agent_prompt: >