seamshield 0.1.1 → 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/README.md CHANGED
@@ -1,32 +1,43 @@
1
1
  # SeamShield
2
2
 
3
- SeamShield is the security layer for AI-built JavaScript and TypeScript apps. It scans for the predictable flaws that vibecoded projects ship: committed secrets, client-exposed server keys, client-only auth, open platform rules, unsafe agent config, and dependency supply-chain risks.
3
+ Local security scanner for AI-built JavaScript and TypeScript apps.
4
4
 
5
- The current product surface is:
6
-
7
- - `npx seamshield scan` - CLI scanner with table, JSON, and SARIF output.
8
- - `npx seamshield fix-plan` - writes agent-ready remediation prompts.
9
- - `npx seamshield agent-context` - writes SeamShield instructions for Claude Code or Cursor.
10
- - `npx seamshield guard install` / `guard check` - Claude Code PreToolUse guard for insecure edits and commands.
5
+ SeamShield finds common flaws that AI-generated apps often ship: committed secrets, client-exposed server keys, client-only auth, open platform rules, unsafe agent config, and dependency supply-chain risks.
11
6
 
12
7
  ## Install
13
8
 
14
9
  ```bash
15
- npm install -g seamshield
16
- # or
17
10
  npx seamshield scan .
18
11
  ```
19
12
 
13
+ Or install globally:
14
+
15
+ ```bash
16
+ npm install -g seamshield
17
+ seamshield scan .
18
+ ```
19
+
20
20
  Requires Node.js 20 or newer.
21
21
 
22
+ ## Commands
23
+
24
+ ```bash
25
+ seamshield scan .
26
+ seamshield fix-plan .
27
+ seamshield agent-context . --claude
28
+ seamshield agent-context . --cursor
29
+ seamshield guard install .
30
+ seamshield guard check
31
+ ```
32
+
22
33
  ## Scan
23
34
 
24
35
  ```bash
25
- npx seamshield scan .
26
- npx seamshield scan . --format json
27
- npx seamshield scan . --format sarif
28
- npx seamshield scan . --fail-on high
29
- npx seamshield scan . --offline
36
+ seamshield scan .
37
+ seamshield scan . --format json
38
+ seamshield scan . --format sarif
39
+ seamshield scan . --fail-on high
40
+ seamshield scan . --offline
30
41
  ```
31
42
 
32
43
  Exit codes:
@@ -37,24 +48,19 @@ Exit codes:
37
48
 
38
49
  `--offline` disables npm registry and OSV checks. Static rules still run.
39
50
 
40
- ## Fix Plan
51
+ ## Fix Plans
41
52
 
42
53
  ```bash
43
- npx seamshield fix-plan .
54
+ seamshield fix-plan .
44
55
  ```
45
56
 
46
- This writes `.seamshield/fix-plan.json` with:
47
-
48
- - the finding list,
49
- - redacted evidence,
50
- - per-finding `agent_prompt` text,
51
- - one combined `agent_markdown` block for Claude Code, Cursor, or another coding agent.
57
+ Writes `.seamshield/fix-plan.json` with redacted findings and agent-ready remediation prompts.
52
58
 
53
59
  ## Agent Context
54
60
 
55
61
  ```bash
56
- npx seamshield agent-context . --claude
57
- npx seamshield agent-context . --cursor
62
+ seamshield agent-context . --claude
63
+ seamshield agent-context . --cursor
58
64
  ```
59
65
 
60
66
  Claude writes or updates `CLAUDE.md`. Cursor writes `.cursor/rules/seamshield.mdc`.
@@ -62,14 +68,14 @@ Claude writes or updates `CLAUDE.md`. Cursor writes `.cursor/rules/seamshield.md
62
68
  ## Claude Code Guard
63
69
 
64
70
  ```bash
65
- npx seamshield guard install .
71
+ seamshield guard install .
66
72
  ```
67
73
 
68
- The guard installs a Claude Code `PreToolUse` hook for `Write`, `Edit`, `MultiEdit`, and `Bash`.
74
+ Installs a Claude Code `PreToolUse` hook for `Write`, `Edit`, `MultiEdit`, and `Bash`.
69
75
 
70
- It denies block-severity edits such as hardcoded provider keys, service-role keys, private keys, committed dotenv files, open Firebase rules, or RLS disablement. Bash checks deny obvious dangerous commands such as `git add .env*`, `curl ... | sh`, and installs of npm packages that do not resolve.
76
+ The guard denies block-severity edits such as hardcoded provider keys, service-role keys, private keys, committed dotenv files, open Firebase rules, or RLS disablement. Bash checks deny obvious dangerous commands such as `git add .env*`, `curl ... | sh`, and installs of npm packages that do not resolve.
71
77
 
72
- Guard behavior is fail-open: if the hook errors, it allows the tool call and appends diagnostics to `.seamshield/guard.log`. CI/release gates should stay fail-closed.
78
+ Guard behavior is fail-open: if the hook errors, it allows the tool call and appends diagnostics to `.seamshield/guard.log`.
73
79
 
74
80
  ## Configuration
75
81
 
@@ -92,36 +98,21 @@ const fixtureKey = "sk_live_test_fixture_only";
92
98
 
93
99
  ## Privacy
94
100
 
95
- SeamShield v0.x runs locally. Static scanning does not transmit source code. Network dependency checks send package names and versions to the npm registry and OSV only; use `--offline` to disable them. Secret evidence is redacted before findings, JSON, SARIF, and fix plans are emitted.
96
-
97
- ## Rule Coverage
98
-
99
- The rule pack covers:
101
+ SeamShield runs locally. Static scanning does not transmit source code.
100
102
 
101
- - secrets and client exposure,
102
- - Next.js auth footguns,
103
- - Supabase, Convex, and Firebase platform mistakes,
104
- - dependency lockfile, pinning, hallucinated-package, and OSV vulnerability checks,
105
- - agent config secrets and overbroad permissions.
103
+ Network dependency checks send package names and versions to the npm registry and OSV. Use `--offline` to disable those checks.
106
104
 
107
- Rules map back to the SeamShield framework files under `seamshield-final-framework/` and `AI_AGENT_DROP_IN.md`.
108
-
109
- ## Development
110
-
111
- ```bash
112
- pnpm install
113
- pnpm build
114
- pnpm test
115
- pnpm typecheck
116
- ```
105
+ Secret evidence is redacted before findings, JSON, SARIF, and fix plans are emitted.
117
106
 
118
- Before publishing:
107
+ ## Public Rule Coverage
119
108
 
120
- 1. Revoke any exposed npm token and mint a fresh token.
121
- 2. Run `pnpm build`, `pnpm test`, and `pnpm typecheck`.
122
- 3. Verify `node packages/cli/dist/index.js scan examples/vulnerable-next-app --offline`.
123
- 4. Publish from `packages/cli` after confirming package contents with `npm pack --dry-run`.
109
+ - Secrets and client exposure
110
+ - Next.js auth footguns
111
+ - Supabase, Convex, and Firebase platform mistakes
112
+ - Dependency lockfile, pinning, hallucinated-package, and OSV vulnerability checks
113
+ - Agent config secrets and overbroad permissions
124
114
 
125
- ## Framework
115
+ ## Links
126
116
 
127
- The original SeamShield framework remains in `seamshield-final-framework/`: Runtime, Artifact, Update, and Evidence planes; OPA policies; schemas; validators; and adoption guidance.
117
+ - Repository: https://github.com/KaraboGerald/SeamShield
118
+ - Issues: https://github.com/KaraboGerald/SeamShield/issues
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.1",
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",
@@ -42,7 +42,7 @@
42
42
  "node": ">=20"
43
43
  },
44
44
  "scripts": {
45
- "build": "tsup src/index.ts --format esm --clean && tsc -p tsconfig.build.json && rm -rf rules schemas && cp -R ../rules/rules ../rules/schemas . && cp ../../README.md README.md",
45
+ "build": "tsup src/index.ts --format esm --clean && tsc -p tsconfig.build.json && rm -rf rules schemas && cp -R ../rules/rules ../rules/schemas .",
46
46
  "prepack": "pnpm run build",
47
47
  "test": "vitest run"
48
48
  },
@@ -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: >