@soulbatical/tetra-dev-toolkit 1.3.0 → 1.3.1

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 ADDED
@@ -0,0 +1,198 @@
1
+ # @soulbatical/tetra-dev-toolkit
2
+
3
+ Quality, security, and hygiene checks for all Soulbatical projects.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install --save-dev @soulbatical/tetra-dev-toolkit
9
+ ```
10
+
11
+ ## Setup (A-Z)
12
+
13
+ One command installs everything — hooks, CI, config:
14
+
15
+ ```bash
16
+ npx tetra-setup
17
+ ```
18
+
19
+ This creates:
20
+ - `.husky/pre-commit` — quick security checks before every commit
21
+ - `.husky/pre-push` — hygiene check before every push (blocks clutter)
22
+ - `.github/workflows/quality.yml` — full audit on PR/push to main
23
+ - `.tetra-quality.json` — project config (override defaults)
24
+
25
+ To install individual components:
26
+
27
+ ```bash
28
+ npx tetra-setup hooks # Husky hooks only
29
+ npx tetra-setup ci # GitHub Actions only
30
+ npx tetra-setup config # Config file only
31
+ ```
32
+
33
+ Re-running `tetra-setup hooks` on an existing project adds missing hooks without overwriting existing ones.
34
+
35
+ ## Usage
36
+
37
+ ```bash
38
+ npx tetra-audit # Run all checks
39
+ npx tetra-audit security # Security checks only
40
+ npx tetra-audit stability # Stability checks only
41
+ npx tetra-audit codeQuality # Code quality checks only
42
+ npx tetra-audit supabase # Supabase checks only
43
+ npx tetra-audit hygiene # Repo hygiene checks only
44
+ npx tetra-audit quick # Quick critical checks (pre-commit)
45
+ npx tetra-audit --ci # CI mode (GitHub Actions annotations)
46
+ npx tetra-audit --json # JSON output
47
+ npx tetra-audit --verbose # Detailed output with fix suggestions
48
+ ```
49
+
50
+ Exit codes: `0` = passed, `1` = failed, `2` = error.
51
+
52
+ ## Check Suites
53
+
54
+ ### Security (5 checks)
55
+
56
+ | Check | Severity | What it catches |
57
+ |-------|----------|-----------------|
58
+ | Hardcoded Secrets | critical | API keys, tokens, JWTs in source code |
59
+ | Service Key Exposure | critical | Supabase service role keys in frontend |
60
+ | Deprecated Supabase Admin | high | Legacy `createClient(serviceKey)` patterns |
61
+ | SystemDB Whitelist | high | Unauthorized system database access |
62
+ | Gitignore Validation | high | Missing .gitignore entries, tracked .env files |
63
+
64
+ ### Stability (3 checks)
65
+
66
+ | Check | Severity | What it catches |
67
+ |-------|----------|-----------------|
68
+ | Husky Hooks | medium | Missing pre-commit/pre-push hooks |
69
+ | CI Pipeline | medium | Missing or incomplete GitHub Actions config |
70
+ | NPM Audit | high | Known vulnerabilities in dependencies |
71
+
72
+ ### Code Quality (1 check)
73
+
74
+ | Check | Severity | What it catches |
75
+ |-------|----------|-----------------|
76
+ | API Response Format | medium | Non-standard `{ success, data }` response format |
77
+
78
+ ### Supabase (2 checks, auto-detected)
79
+
80
+ | Check | Severity | What it catches |
81
+ |-------|----------|-----------------|
82
+ | RLS Policy Audit | critical | Tables without Row Level Security |
83
+ | RPC Param Mismatch | critical | TypeScript `.rpc()` calls with wrong parameter names vs SQL |
84
+
85
+ ### Hygiene (1 check)
86
+
87
+ | Check | Severity | What it catches |
88
+ |-------|----------|-----------------|
89
+ | File Organization | high | Stray .md, .sh, clutter in code dirs, root mess, nested docs/ |
90
+
91
+ ## Health Checks
92
+
93
+ Separate from audit suites, health checks provide a scored assessment (0-N points) used by the Ralph Manager dashboard:
94
+
95
+ | Check | Max | What it measures |
96
+ |-------|-----|------------------|
97
+ | File Organization | 6pt | Docs in /docs, scripts in /scripts, clean root & code dirs |
98
+ | Git | 4pt | Clean working tree, branch hygiene, commit frequency |
99
+ | Gitignore | 3pt | Critical entries present |
100
+ | CLAUDE.md | 3pt | Project instructions for AI assistants |
101
+ | Secrets | 3pt | No exposed secrets |
102
+ | Tests | 4pt | Test framework, coverage, test files |
103
+ | Naming Conventions | 5pt | File/dir naming consistency |
104
+ | Infrastructure YML | 3pt | Railway/Docker config |
105
+ | Doppler Compliance | 2pt | Secrets management via Doppler |
106
+ | MCP Servers | 2pt | MCP configuration |
107
+ | Stella Integration | 2pt | Stella package integration |
108
+ | Quality Toolkit | 2pt | Tetra dev-toolkit installed |
109
+ | Repo Visibility | 1pt | Private repo |
110
+ | RLS Audit | 3pt | Row Level Security policies |
111
+ | Plugins | 2pt | Claude Code plugin config |
112
+ | VinciFox Widget | 1pt | Widget installation |
113
+
114
+ ## Auto-fix: Cleanup Script
115
+
116
+ For hygiene issues, an auto-fix script is included:
117
+
118
+ ```bash
119
+ # Dry run (shows what would change)
120
+ bash node_modules/@soulbatical/tetra-dev-toolkit/bin/cleanup-repos.sh
121
+
122
+ # Execute
123
+ bash node_modules/@soulbatical/tetra-dev-toolkit/bin/cleanup-repos.sh --execute
124
+ ```
125
+
126
+ What it does:
127
+ - `.md` files in code dirs -> `docs/_moved/`
128
+ - `.sh` scripts in code dirs -> `scripts/_moved/`
129
+ - Root clutter (`.txt`, `.png`, `.csv`) -> `docs/_cleanup/`
130
+ - Code dir clutter -> `docs/_cleanup/{dir}/`
131
+ - `.env` secrets in code dirs -> deleted
132
+ - `tmp/`, `logs/`, `data/` dirs -> added to `.gitignore`
133
+
134
+ ## Configuration
135
+
136
+ Override defaults in `.tetra-quality.json` or `"tetra-quality"` key in `package.json`:
137
+
138
+ ```json
139
+ {
140
+ "suites": {
141
+ "security": true,
142
+ "stability": true,
143
+ "codeQuality": true,
144
+ "supabase": "auto",
145
+ "hygiene": true
146
+ },
147
+ "supabase": {
148
+ "publicRpcFunctions": ["get_public_data"],
149
+ "publicTables": ["public_lookup"]
150
+ },
151
+ "stability": {
152
+ "allowedVulnerabilities": {
153
+ "critical": 0,
154
+ "high": 0,
155
+ "moderate": 10
156
+ }
157
+ }
158
+ }
159
+ ```
160
+
161
+ ## CLI Tools
162
+
163
+ | Command | Description |
164
+ |---------|-------------|
165
+ | `tetra-audit` | Run quality/security/hygiene checks |
166
+ | `tetra-setup` | Install hooks, CI, and config |
167
+ | `tetra-dev-token` | Generate development tokens |
168
+
169
+ ## Changelog
170
+
171
+ ### 1.3.0 (2025-02-21)
172
+
173
+ **New: Hygiene suite**
174
+ - Added `tetra-audit hygiene` — detects stray docs, scripts, clutter in code dirs, root mess
175
+ - Added `cleanup-repos.sh` auto-fix script in `bin/`
176
+ - `tetra-setup hooks` now creates pre-push hook with hygiene gate
177
+ - Re-running `tetra-setup hooks` on existing repos adds hygiene check without overwriting
178
+
179
+ **New: RPC Param Mismatch check**
180
+ - Added `rpc-param-mismatch` check in supabase suite
181
+ - Statically compares `.rpc()` calls in TypeScript with SQL function parameter names
182
+ - Catches PGRST202 errors before they hit production
183
+
184
+ **Improved: File Organization health check**
185
+ - Extended from 5pt to 6pt — added root clutter detection
186
+ - Root clutter: `.txt`, `.png`, `.csv`, `.pdf`, `.py` files and `tmp/`, `logs/`, `data/` dirs
187
+ - Gitignored dirs no longer counted as clutter
188
+ - `CLAUDE.md` allowed anywhere (not just root)
189
+
190
+ ### 1.2.0
191
+
192
+ - Initial public version
193
+ - Security suite: hardcoded secrets, service key exposure, deprecated admin, systemdb whitelist, gitignore
194
+ - Stability suite: husky hooks, CI pipeline, npm audit
195
+ - Code quality suite: API response format
196
+ - Supabase suite: RLS policy audit
197
+ - Health checks: 16 checks, max 37pt
198
+ - CLI: `tetra-audit`, `tetra-setup`, `tetra-dev-token`
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Health Checks — All 15 project health checks
2
+ * Health Checks — All 16 project health checks
3
3
  *
4
4
  * Main entry: scanProjectHealth(projectPath, projectName, options?)
5
5
  * Individual checks available via named imports.
@@ -25,3 +25,4 @@ export { check as checkClaudeMd } from './claude-md.js'
25
25
  export { check as checkDopplerCompliance } from './doppler-compliance.js'
26
26
  export { check as checkInfrastructureYml } from './infrastructure-yml.js'
27
27
  export { check as checkFileOrganization } from './file-organization.js'
28
+ export { check as checkRpcParamMismatch } from './rpc-param-mismatch.js'
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Health Check: RPC Parameter Mismatch
3
+ *
4
+ * Compares .rpc() calls in TypeScript with SQL function definitions
5
+ * to detect parameter name mismatches that cause PGRST202 runtime errors.
6
+ *
7
+ * Score: 3 (full) with deductions:
8
+ * - Critical mismatch (extra param in TS): -1.5 per finding (max -3)
9
+ * - Low (missing params): -0.25 per finding (max -1)
10
+ */
11
+
12
+ import { createCheck } from './types.js'
13
+ import { run as runAuditCheck } from '../supabase/rpc-param-mismatch.js'
14
+
15
+ export async function check(projectPath) {
16
+ const result = createCheck('rpc-param-mismatch', 3, {
17
+ sqlFunctionsFound: 0,
18
+ rpcCallsFound: 0,
19
+ rpcCallsChecked: 0,
20
+ criticalMismatches: [],
21
+ missingParams: [],
22
+ message: ''
23
+ })
24
+ result.score = 3 // Start full, deduct for issues
25
+
26
+ // Re-use the audit check with default config paths
27
+ const config = {
28
+ paths: {
29
+ backend: ['backend/src', 'src'],
30
+ migrations: ['supabase/migrations', 'backend/supabase/migrations', 'migrations']
31
+ }
32
+ }
33
+
34
+ let auditResult
35
+ try {
36
+ auditResult = await runAuditCheck(config, projectPath)
37
+ } catch {
38
+ result.details.message = 'Failed to run RPC param mismatch check'
39
+ return result
40
+ }
41
+
42
+ if (auditResult.skipped) {
43
+ result.score = 3
44
+ result.details.message = auditResult.skipReason || 'Skipped'
45
+ return result
46
+ }
47
+
48
+ result.details.sqlFunctionsFound = auditResult.details.sqlFunctionsFound
49
+ result.details.rpcCallsFound = auditResult.details.rpcCallsFound
50
+ result.details.rpcCallsChecked = auditResult.details.rpcCallsChecked
51
+
52
+ // Process findings
53
+ const criticals = auditResult.findings.filter(f => f.severity === 'critical')
54
+ const lows = auditResult.findings.filter(f => f.severity === 'low')
55
+
56
+ result.details.criticalMismatches = criticals.map(f => ({
57
+ file: f.file,
58
+ line: f.line,
59
+ function: f.rpcFunction,
60
+ extraParams: f.extraInTs,
61
+ expectedParams: f.sqlParams
62
+ }))
63
+
64
+ result.details.missingParams = lows.map(f => ({
65
+ file: f.file,
66
+ line: f.line,
67
+ function: f.rpcFunction,
68
+ tsParamCount: f.tsParams?.length,
69
+ sqlParamCount: f.sqlParams?.length
70
+ }))
71
+
72
+ // Score deductions
73
+ if (criticals.length > 0) {
74
+ const deduction = Math.min(3, criticals.length * 1.5)
75
+ result.score -= deduction
76
+ result.status = 'error'
77
+ result.details.message = `${criticals.length} RPC parameter mismatch(es) — will cause PGRST202 runtime errors`
78
+ }
79
+
80
+ if (lows.length > 0 && result.status === 'ok') {
81
+ const deduction = Math.min(1, lows.length * 0.25)
82
+ result.score -= deduction
83
+ if (result.status === 'ok' && lows.length > 5) result.status = 'warning'
84
+ }
85
+
86
+ if (result.status === 'ok') {
87
+ result.details.message = `${auditResult.details.rpcCallsChecked} RPC calls verified against SQL definitions`
88
+ }
89
+
90
+ result.score = Math.max(0, result.score)
91
+ return result
92
+ }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Project Health Scanner
3
3
  *
4
- * Orchestrates all 15 health checks and produces a HealthReport.
4
+ * Orchestrates all 16 health checks and produces a HealthReport.
5
5
  * This is the main entry point — consumers call scanProjectHealth().
6
6
  */
7
7
 
@@ -21,6 +21,7 @@ import { check as checkClaudeMd } from './claude-md.js'
21
21
  import { check as checkDopplerCompliance } from './doppler-compliance.js'
22
22
  import { check as checkInfrastructureYml } from './infrastructure-yml.js'
23
23
  import { check as checkFileOrganization } from './file-organization.js'
24
+ import { check as checkRpcParamMismatch } from './rpc-param-mismatch.js'
24
25
  import { calculateHealthStatus } from './types.js'
25
26
 
26
27
  /**
@@ -50,7 +51,8 @@ export async function scanProjectHealth(projectPath, projectName, options = {})
50
51
  checkClaudeMd(projectPath),
51
52
  checkDopplerCompliance(projectPath),
52
53
  checkInfrastructureYml(projectPath),
53
- checkFileOrganization(projectPath)
54
+ checkFileOrganization(projectPath),
55
+ checkRpcParamMismatch(projectPath)
54
56
  ])
55
57
 
56
58
  const totalScore = checks.reduce((sum, c) => sum + c.score, 0)
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  /**
8
- * @typedef {'plugins'|'mcps'|'git'|'tests'|'secrets'|'quality-toolkit'|'naming-conventions'|'rls-audit'|'gitignore'|'repo-visibility'|'vincifox-widget'|'stella-integration'|'claude-md'|'doppler-compliance'|'infrastructure-yml'|'file-organization'} HealthCheckType
8
+ * @typedef {'plugins'|'mcps'|'git'|'tests'|'secrets'|'quality-toolkit'|'naming-conventions'|'rls-audit'|'rpc-param-mismatch'|'gitignore'|'repo-visibility'|'vincifox-widget'|'stella-integration'|'claude-md'|'doppler-compliance'|'infrastructure-yml'|'file-organization'} HealthCheckType
9
9
  *
10
10
  * @typedef {'ok'|'warning'|'error'} HealthStatus
11
11
  *
@@ -66,7 +66,7 @@ export function calculateHealthStatus(checks) {
66
66
 
67
67
  // Critical checks override percentage
68
68
  if (checks.some(c =>
69
- (c.type === 'secrets' || c.type === 'rls-audit' || c.type === 'repo-visibility') && c.status === 'error'
69
+ (c.type === 'secrets' || c.type === 'rls-audit' || c.type === 'rpc-param-mismatch' || c.type === 'repo-visibility') && c.status === 'error'
70
70
  )) {
71
71
  return 'unhealthy'
72
72
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soulbatical/tetra-dev-toolkit",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "publishConfig": {
5
5
  "access": "restricted"
6
6
  },