@safetnsr/vet 0.3.0 → 0.4.0

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.
Files changed (3) hide show
  1. package/README.md +8 -35
  2. package/dist/cli.js +5 -22
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # vet
2
2
 
3
- vet your AI-generated code. one command, ten checks, zero config.
3
+ vet your AI-generated code. one command, eight checks, zero config.
4
4
 
5
5
  ```bash
6
6
  npx @safetnsr/vet
@@ -15,13 +15,11 @@ works with Claude Code, Cursor, Copilot, Codex, Aider, Windsurf, Cline — anyth
15
15
  | **ready** | is your codebase AI-friendly? | scans structure, docs, types, tests |
16
16
  | **diff** | did the AI leave anti-patterns? | AI-specific patterns: wholesale rewrites, orphaned imports, catch-alls, over-commenting, plus secrets & stubs |
17
17
  | **models** | using deprecated AI models? | scans code for sunset model strings across OpenAI, Anthropic, Google, Cohere |
18
- | **links** | broken markdown links? | validates relative links and wikilinks |
19
18
  | **config** | agent configs in place? | deep analysis of CLAUDE.md, .cursorrules, copilot-instructions — checks completeness, consistency, and specificity against your actual codebase |
20
19
  | **history** | git patterns healthy? | analyzes commit churn, AI attribution, large changes |
21
20
  | **scan** | malicious patterns in agent configs? | scans .claude/, .cursorrules, CLAUDE.md, .mcp/ for prompt injection, shell injection, exfiltration endpoints |
22
21
  | **secrets** | leaked secrets in build output? | scans dist/, build/, .next/ + .env files for API keys, tokens, connection strings using pattern + entropy analysis |
23
22
  | **receipt** | what did the last agent session do? | parses ~/.claude/projects/ JSONL session logs — files changed, commands run, packages installed, SHA256 integrity hash |
24
- | **edge** | how replaceable is your git history? | classifies commits by human-edge score: architecture (90) → debugging (85) → integration (80) → feature (60) → boilerplate (20) → cosmetic (10) |
25
23
 
26
24
  ## usage
27
25
 
@@ -53,23 +51,21 @@ npx @safetnsr/vet init
53
51
  # show last agent session receipt (ASCII or JSON)
54
52
  npx @safetnsr/vet receipt
55
53
  npx @safetnsr/vet receipt --json
56
-
57
- # show human-edge score for git history
58
- npx @safetnsr/vet edge
59
- npx @safetnsr/vet edge --explain
60
54
  ```
61
55
 
62
56
  ## output
63
57
 
64
58
  ```
65
- my-project 6.2/10
59
+ my-project 7.5/10
66
60
 
67
61
  ready ████░░░░░░ 4 3 readiness issues
68
62
  diff ████████░░ 8 3 issues (2 AI-specific) in 5 files
69
63
  models ██████████ 10 all models current
70
- links ██████░░░░ 6 3 broken links in docs/
71
64
  config ███░░░░░░░ 3 Cursor — needs work (3/10)
72
65
  history █████████░ 9 41 commits (~15% AI-attributed)
66
+ scan ██████████ 10 no malicious patterns found
67
+ secrets ██████████ 10 no leaked secrets
68
+ receipt ██████████ 10 last session: 3 files, 2 commands
73
69
 
74
70
  ✗ no README — AI agents have no project context
75
71
  ✗ no tests — AI agents produce better code when tests exist
@@ -81,7 +77,7 @@ npx @safetnsr/vet edge --explain
81
77
 
82
78
  ## --fix
83
79
 
84
- `vet --fix` doesn't just scaffold — it analyzes your codebase and generates project-specific configs:
80
+ `vet --fix` analyzes your codebase and generates project-specific configs:
85
81
 
86
82
  ```bash
87
83
  $ npx @safetnsr/vet --fix
@@ -95,12 +91,10 @@ $ npx @safetnsr/vet --fix
95
91
  fixed 3 issues
96
92
  ```
97
93
 
98
- the generated CLAUDE.md includes your actual stack, directory structure, and framework-specific rules — not generic boilerplate.
94
+ the generated CLAUDE.md includes your actual stack, directory structure, and framework-specific rules.
99
95
 
100
96
  ## AI-specific diff patterns
101
97
 
102
- vet catches things that are specific to AI-generated code:
103
-
104
98
  | pattern | what it catches |
105
99
  |---------|----------------|
106
100
  | `[ai] wholesale rewrite` | AI rewrote an entire function when a small edit would suffice |
@@ -144,34 +138,13 @@ Shows a receipt for the last Claude Code agent session — what files it touched
144
138
  ╚══════════════════════════════════════════════╝
145
139
  ```
146
140
 
147
- ### `vet edge`
148
-
149
- Analyzes git history and scores how AI-replaceable your contributions are:
150
-
151
- ```
152
- Human Edge Report 72/100
153
-
154
- 🏗️ Architecture 12 (28%) ████████████
155
- 🔍 Debugging 8 (19%) ████████
156
- 🔗 Integration 6 (14%) ██████
157
- ⚡ Feature 10 (24%) ██████████
158
- 📋 Boilerplate 5 (12%) █████
159
- 🎨 Cosmetic 1 (2%) █
160
-
161
- Top commits
162
- 90 a3f2b1c refactor: extract auth middleware across all routes
163
- 85 7e8d9f1 fix: resolve race condition in session cleanup
164
-
165
- → Strong position. Your work is deeply contextual and hard to automate.
166
- ```
167
-
168
141
  ## config
169
142
 
170
143
  create `.vetrc` in your project root (optional):
171
144
 
172
145
  ```json
173
146
  {
174
- "checks": ["ready", "diff", "models", "links", "config", "history", "scan", "secrets", "receipt", "edge"],
147
+ "checks": ["ready", "diff", "models", "config", "history", "scan", "secrets", "receipt"],
175
148
  "ignore": ["vendor/", "generated/"],
176
149
  "thresholds": { "min": 6 }
177
150
  }
package/dist/cli.js CHANGED
@@ -5,13 +5,11 @@ import { isGitRepo, readFile, c } from './util.js';
5
5
  import { checkReady } from './checks/ready.js';
6
6
  import { checkDiff } from './checks/diff.js';
7
7
  import { checkModels } from './checks/models.js';
8
- import { checkLinks } from './checks/links.js';
9
8
  import { checkConfig } from './checks/config.js';
10
9
  import { checkHistory } from './checks/history.js';
11
10
  import { checkScan } from './checks/scan.js';
12
11
  import { checkSecrets } from './checks/secrets.js';
13
12
  import { checkReceipt, runReceiptCommand } from './checks/receipt.js';
14
- import { checkEdge, runEdgeCommand } from './checks/edge.js';
15
13
  import { score } from './scorer.js';
16
14
  import { reportPretty, reportJSON } from './reporter.js';
17
15
  const args = process.argv.slice(2);
@@ -40,28 +38,24 @@ if (flags.has('--help') || flags.has('-h')) {
40
38
  npx @safetnsr/vet --watch live monitoring during AI sessions
41
39
  npx @safetnsr/vet init generate configs + hooks
42
40
  npx @safetnsr/vet receipt show last agent session receipt
43
- npx @safetnsr/vet edge show human-edge score for git history
44
41
 
45
42
  ${c.dim}checks:${c.reset}
46
43
  ready codebase readiness for AI agents
47
44
  diff AI-specific anti-patterns in recent changes
48
45
  models deprecated/risky model usage
49
- links dead markdown links
50
46
  config agent config hygiene
51
47
  history git history quality
52
48
  scan malicious patterns in agent config files
53
49
  secrets leaked secrets in build output and .env files
54
50
  receipt last agent session audit (informational)
55
- edge human replaceability score from git history
56
51
 
57
52
  ${c.dim}options:${c.reset}
58
53
  --ci CI mode (exit 1 if score < threshold)
59
- --fix auto-fix configs, models, links
54
+ --fix auto-fix configs, models
60
55
  --since REF diff against specific commit/range
61
56
  --watch re-run on file changes
62
57
  --json JSON output
63
58
  --pretty force pretty output (even in pipes)
64
- --explain show detailed reasoning (edge subcommand)
65
59
  -h, --help show this help
66
60
  -v, --version show version
67
61
  `);
@@ -77,7 +71,7 @@ if (flags.has('--version') || flags.has('-v')) {
77
71
  }
78
72
  process.exit(0);
79
73
  }
80
- const COMMANDS = ['init', 'receipt', 'edge'];
74
+ const COMMANDS = ['init', 'receipt'];
81
75
  const command = COMMANDS.includes(positional[0]) ? positional[0] : undefined;
82
76
  const cwd = resolve(positional.find(p => !COMMANDS.includes(p)) || '.');
83
77
  const isCI = flags.has('--ci');
@@ -105,11 +99,6 @@ if (command === 'receipt') {
105
99
  await runReceiptCommand(format);
106
100
  process.exit(0);
107
101
  }
108
- if (command === 'edge') {
109
- const explain = flags.has('--explain');
110
- runEdgeCommand(cwd, explain);
111
- process.exit(0);
112
- }
113
102
  if (!isGitRepo(cwd)) {
114
103
  console.error(`${c.red}not a git repository${c.reset}. vet operates on git repos.`);
115
104
  process.exit(1);
@@ -119,12 +108,10 @@ if (isFix) {
119
108
  console.log(`\n ${c.bold}vet --fix${c.reset}\n`);
120
109
  const { fixConfig } = await import('./fix/config.js');
121
110
  const { fixModels } = await import('./fix/models.js');
122
- const { fixLinks } = await import('./fix/links.js');
123
111
  const configResult = fixConfig(cwd);
124
112
  const modelsResult = fixModels(cwd, ignore);
125
- const linksResult = fixLinks(cwd, ignore);
126
- const allMessages = [...configResult.messages, ...modelsResult.messages, ...linksResult.messages];
127
- const totalFixed = configResult.fixed + modelsResult.fixed + linksResult.fixed;
113
+ const allMessages = [...configResult.messages, ...modelsResult.messages];
114
+ const totalFixed = configResult.fixed + modelsResult.fixed;
128
115
  if (allMessages.length > 0) {
129
116
  for (const msg of allMessages)
130
117
  console.log(msg);
@@ -133,7 +120,7 @@ if (isFix) {
133
120
  process.exit(0);
134
121
  }
135
122
  async function runChecks() {
136
- const allChecks = ['ready', 'diff', 'models', 'links', 'config', 'history', 'scan', 'secrets', 'receipt', 'edge'];
123
+ const allChecks = ['ready', 'diff', 'models', 'config', 'history', 'scan', 'secrets', 'receipt'];
137
124
  const enabledChecks = config.checks || allChecks;
138
125
  const results = [];
139
126
  // ready and models are async (try rich subpackages first, fallback to built-in)
@@ -143,8 +130,6 @@ async function runChecks() {
143
130
  results.push(checkDiff(cwd, { since }));
144
131
  if (enabledChecks.includes('models'))
145
132
  results.push(await checkModels(cwd, ignore));
146
- if (enabledChecks.includes('links'))
147
- results.push(checkLinks(cwd, ignore));
148
133
  if (enabledChecks.includes('config'))
149
134
  results.push(checkConfig(cwd, ignore));
150
135
  if (enabledChecks.includes('history'))
@@ -155,8 +140,6 @@ async function runChecks() {
155
140
  results.push(await checkSecrets(cwd));
156
141
  if (enabledChecks.includes('receipt'))
157
142
  results.push(await checkReceipt(cwd));
158
- if (enabledChecks.includes('edge'))
159
- results.push(checkEdge(cwd));
160
143
  return score(cwd, results);
161
144
  }
162
145
  // --watch mode
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@safetnsr/vet",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "vet your AI-generated code — one command, six checks, zero config",
5
5
  "type": "module",
6
6
  "bin": {