@soulbatical/tetra-dev-toolkit 1.1.1 → 1.3.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.
@@ -0,0 +1,287 @@
1
+ #!/bin/bash
2
+ # =============================================================================
3
+ # Repo Cleanup Script — Verplaats alles naar de juiste plek
4
+ #
5
+ # Wat het doet:
6
+ # 1. Stray .md files → /docs/_moved/{oorspronkelijk-pad}/
7
+ # 2. Stray .sh scripts → /scripts/_moved/{oorspronkelijk-pad}/
8
+ # 3. Nested docs/ (frontend/docs/, backend/docs/) → /docs/{subdir-naam}/
9
+ # 4. Root clutter files (.txt, .png, .csv, .py) → /docs/_cleanup/
10
+ # 5. Code dir clutter (.txt, .log, .env) → /docs/_cleanup/{code-dir}/
11
+ # 6. Clutter dirs (tmp/, logs/, data/, etc.) → .gitignore
12
+ # 7. .env/.env.local in code dirs → verwijder (secrets horen niet in git)
13
+ #
14
+ # DRY RUN: standaard toont het alleen wat het zou doen.
15
+ # EXECUTE: ./cleanup-repos.sh --execute
16
+ # =============================================================================
17
+
18
+ set -euo pipefail
19
+
20
+ DRY_RUN=true
21
+ [[ "${1:-}" == "--execute" ]] && DRY_RUN=false
22
+
23
+ BASE="$HOME/projecten"
24
+ PROJECTS=(sparkbuddy-live agentrook ralph-manager vincifox snelstart-mcp web-mcp)
25
+
26
+ # Colors
27
+ RED='\033[0;31m'
28
+ GREEN='\033[0;32m'
29
+ YELLOW='\033[1;33m'
30
+ BLUE='\033[0;34m'
31
+ NC='\033[0m'
32
+
33
+ # Counters
34
+ TOTAL_MOVED=0
35
+ TOTAL_GITIGNORED=0
36
+ TOTAL_DELETED=0
37
+
38
+ lower() { echo "$1" | tr '[:upper:]' '[:lower:]'; }
39
+
40
+ log() { echo -e "${BLUE}[INFO]${NC} $1"; }
41
+ warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
42
+ action() { echo -e "${GREEN}[MOVE]${NC} $1"; }
43
+ danger() { echo -e "${RED}[DEL]${NC} $1"; }
44
+
45
+ safe_move() {
46
+ local src="$1" dst="$2"
47
+
48
+ if $DRY_RUN; then
49
+ action "$src → $dst"
50
+ else
51
+ mkdir -p "$(dirname "$PROJECT_PATH/$dst")"
52
+ mv "$PROJECT_PATH/$src" "$PROJECT_PATH/$dst"
53
+ fi
54
+ TOTAL_MOVED=$((TOTAL_MOVED + 1))
55
+ }
56
+
57
+ safe_delete() {
58
+ local target="$1"
59
+ if $DRY_RUN; then
60
+ danger "DELETE $target"
61
+ else
62
+ rm -f "$target"
63
+ fi
64
+ TOTAL_DELETED=$((TOTAL_DELETED + 1))
65
+ }
66
+
67
+ add_gitignore() {
68
+ local project_path="$1" entry="$2"
69
+ local gitignore="$project_path/.gitignore"
70
+
71
+ if [ -f "$gitignore" ] && grep -qF "$entry" "$gitignore" 2>/dev/null; then
72
+ return
73
+ fi
74
+
75
+ if $DRY_RUN; then
76
+ log "Add to .gitignore: $entry"
77
+ else
78
+ echo "$entry" >> "$gitignore"
79
+ fi
80
+ TOTAL_GITIGNORED=$((TOTAL_GITIGNORED + 1))
81
+ }
82
+
83
+ is_allowed_root_md() {
84
+ local name_lc
85
+ name_lc=$(lower "$1")
86
+ case "$name_lc" in
87
+ readme.md|claude.md|changelog.md|license.md|prompt.md|plan.md|contributing.md|code_of_conduct.md)
88
+ return 0 ;;
89
+ *) return 1 ;;
90
+ esac
91
+ }
92
+
93
+ # =============================================================================
94
+ # Main cleanup per project
95
+ # =============================================================================
96
+
97
+ for PROJECT in "${PROJECTS[@]}"; do
98
+ PROJECT_PATH="$BASE/$PROJECT"
99
+ [ -d "$PROJECT_PATH" ] || continue
100
+
101
+ echo ""
102
+ echo "================================================================"
103
+ echo -e "${BLUE}=== $PROJECT ===${NC}"
104
+ echo "================================================================"
105
+
106
+ # --- 1. Nested docs/ → merge into /docs/{subdir-naam}/ (FIRST, before stray .md scan) ---
107
+ log "Checking nested docs/ directories..."
108
+ for subdir in frontend backend backend-mcp backend-pdf mcp shell; do
109
+ nested_docs="$PROJECT_PATH/$subdir/docs"
110
+ [ -d "$nested_docs" ] || continue
111
+
112
+ file_count=$(find "$nested_docs" -type f 2>/dev/null | wc -l | tr -d ' ')
113
+ [[ "$file_count" == "0" ]] && continue
114
+
115
+ log "Moving $subdir/docs/ ($file_count files) → docs/$subdir/"
116
+ while IFS= read -r -d '' file; do
117
+ rel_from_nested="${file#$nested_docs/}"
118
+ safe_move "$subdir/docs/$rel_from_nested" "docs/$subdir/$rel_from_nested"
119
+ done < <(find "$nested_docs" -type f -print0 2>/dev/null)
120
+ done
121
+
122
+ # --- 2. Stray .md files → /docs/_moved/ ---
123
+ log "Checking stray .md files..."
124
+ while IFS= read -r -d '' file; do
125
+ rel="${file#$PROJECT_PATH/}"
126
+ name=$(basename "$file")
127
+ name_lc=$(lower "$name")
128
+ top_dir="${rel%%/*}"
129
+
130
+ # Skip README.md and CLAUDE.md anywhere (standard practice)
131
+ case "$name_lc" in
132
+ readme.md|claude.md) continue ;;
133
+ esac
134
+
135
+ # Skip root allowed .md files
136
+ [[ "$rel" == "$name" ]] && is_allowed_root_md "$name" && continue
137
+
138
+ # Skip /docs/, .ralph/, .claude/, .agents/, e2e/
139
+ case "$top_dir" in
140
+ docs|.ralph|.claude|.agents|e2e) continue ;;
141
+ esac
142
+
143
+ # Skip shell/templates/
144
+ [[ "$rel" == shell/templates/* ]] && continue
145
+
146
+ # Skip files already handled by nested docs merge (avoid double-move)
147
+ [[ "$rel" == */docs/* ]] && continue
148
+
149
+ safe_move "$rel" "docs/_moved/$rel"
150
+ done < <(find "$PROJECT_PATH" -maxdepth 5 -name "*.md" -type f \
151
+ -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/dist/*" \
152
+ -not -path "*/.next/*" -not -path "*/coverage/*" -print0 2>/dev/null)
153
+
154
+ # --- 3. Stray .sh scripts → /scripts/_moved/ ---
155
+ log "Checking stray .sh scripts..."
156
+ while IFS= read -r -d '' file; do
157
+ rel="${file#$PROJECT_PATH/}"
158
+ top_dir="${rel%%/*}"
159
+
160
+ # Skip root-level scripts
161
+ [[ "$rel" != */* ]] && continue
162
+
163
+ # Skip allowed dirs
164
+ case "$top_dir" in
165
+ scripts|shell|hooks|.husky|.ralph|.claude) continue ;;
166
+ esac
167
+
168
+ safe_move "$rel" "scripts/_moved/$rel"
169
+ done < <(find "$PROJECT_PATH" -maxdepth 5 -name "*.sh" -type f \
170
+ -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/dist/*" \
171
+ -print0 2>/dev/null)
172
+
173
+ # --- 4. Root clutter files → /docs/_cleanup/ ---
174
+ log "Checking root clutter..."
175
+ for file in "$PROJECT_PATH"/*; do
176
+ [ -f "$file" ] || continue
177
+ name=$(basename "$file")
178
+ name_lc=$(lower "$name")
179
+
180
+ # Skip dotfiles
181
+ [[ "$name" == .* ]] && continue
182
+
183
+ # Skip known config extensions and types handled by other checks
184
+ case "$name_lc" in
185
+ *.json|*.js|*.cjs|*.mjs|*.ts|*.toml|*.lock) continue ;;
186
+ *.md|*.sh|*.yml|*.yaml) continue ;;
187
+ dockerfile*|procfile) continue ;;
188
+ esac
189
+
190
+ # Check for clutter extensions
191
+ ext=".${name_lc##*.}"
192
+ case "$ext" in
193
+ .txt|.log|.pdf|.csv|.png|.jpg|.jpeg|.gif|.py|.bak|.tmp|.orig|.patch|.diff)
194
+ safe_move "$name" "docs/_cleanup/$name"
195
+ ;;
196
+ esac
197
+ done
198
+
199
+ # --- 5. Code dir clutter → /docs/_cleanup/{code-dir}/ ---
200
+ log "Checking code dir clutter..."
201
+ for codeDir in backend frontend backend-mcp backend-pdf mcp; do
202
+ code_path="$PROJECT_PATH/$codeDir"
203
+ [ -d "$code_path" ] || continue
204
+
205
+ while IFS= read -r -d '' file; do
206
+ name=$(basename "$file")
207
+ name_lc=$(lower "$name")
208
+ rel="${file#$PROJECT_PATH/}"
209
+ rel_from_code="${file#$code_path/}"
210
+ sub_top="${rel_from_code%%/*}"
211
+
212
+ # Skip allowed subdirs
213
+ case "$sub_top" in
214
+ public|static|assets|fixtures|supabase|migrations|prisma|test-fixtures) continue ;;
215
+ esac
216
+
217
+ # .env files → DELETE (secrets!)
218
+ case "$name_lc" in
219
+ .env|.env.local|.env.development|.env.production|.env.staging)
220
+ danger "SECRET: $rel"
221
+ safe_delete "$file"
222
+ continue
223
+ ;;
224
+ esac
225
+
226
+ # Skip templates
227
+ case "$name_lc" in
228
+ *.example|*.test) continue ;;
229
+ esac
230
+
231
+ # Skip standard web files
232
+ case "$name_lc" in
233
+ robots.txt|llms.txt|llms-full.txt|humans.txt|security.txt|ads.txt) continue ;;
234
+ esac
235
+
236
+ # Check for clutter extensions
237
+ ext=".${name_lc##*.}"
238
+ case "$ext" in
239
+ .txt|.log|.pdf|.csv|.bak|.tmp|.orig|.patch|.diff)
240
+ safe_move "$rel" "docs/_cleanup/$rel"
241
+ ;;
242
+ esac
243
+ done < <(find "$code_path" -maxdepth 4 -type f \
244
+ -not -path "*/node_modules/*" -not -path "*/dist/*" -not -path "*/.next/*" \
245
+ -not -path "*/coverage/*" -not -path "*/.turbo/*" -not -path "*/test-results/*" \
246
+ \( -name "*.txt" -o -name "*.log" -o -name "*.pdf" -o -name "*.csv" \
247
+ -o -name "*.bak" -o -name "*.tmp" -o -name "*.orig" \
248
+ -o -name ".env" -o -name ".env.*" \) -print0 2>/dev/null)
249
+ done
250
+
251
+ # --- 6. Clutter dirs → .gitignore ---
252
+ log "Checking clutter directories..."
253
+ for dir_name in tmp temp logs log data venv .venv reports output out backup backups; do
254
+ if [ -d "$PROJECT_PATH/$dir_name" ]; then
255
+ add_gitignore "$PROJECT_PATH" "$dir_name/"
256
+ warn "Directory $dir_name/ → added to .gitignore"
257
+ fi
258
+ done
259
+
260
+ done
261
+
262
+ # =============================================================================
263
+ # Summary
264
+ # =============================================================================
265
+
266
+ echo ""
267
+ echo "================================================================"
268
+ if $DRY_RUN; then
269
+ echo -e "${YELLOW}DRY RUN COMPLETE${NC}"
270
+ echo " Files to move: $TOTAL_MOVED"
271
+ echo " Files to delete: $TOTAL_DELETED"
272
+ echo " Gitignore entries: $TOTAL_GITIGNORED"
273
+ echo ""
274
+ echo "Run with --execute to apply changes:"
275
+ echo " bash cleanup-repos.sh --execute"
276
+ else
277
+ echo -e "${GREEN}CLEANUP COMPLETE${NC}"
278
+ echo " Files moved: $TOTAL_MOVED"
279
+ echo " Files deleted: $TOTAL_DELETED"
280
+ echo " Gitignore entries: $TOTAL_GITIGNORED"
281
+ echo ""
282
+ echo "Next steps:"
283
+ echo " 1. Review /docs/_moved/ and /docs/_cleanup/ per project"
284
+ echo " 2. Delete what you don't need, keep what's useful"
285
+ echo " 3. git add + commit per project"
286
+ fi
287
+ echo "================================================================"
@@ -1,25 +1,26 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * VCA Quality Toolkit - Main CLI
4
+ * Tetra Dev Toolkit - Main CLI
5
5
  *
6
6
  * Usage:
7
- * vca-audit # Run all checks
8
- * vca-audit security # Run security checks only
9
- * vca-audit stability # Run stability checks only
10
- * vca-audit quick # Run quick critical checks
11
- * vca-audit --ci # CI mode (GitHub Actions annotations)
12
- * vca-audit --json # JSON output
7
+ * tetra-audit # Run all checks
8
+ * tetra-audit security # Run security checks only
9
+ * tetra-audit stability # Run stability checks only
10
+ * tetra-audit hygiene # Run repo hygiene checks only
11
+ * tetra-audit quick # Run quick critical checks
12
+ * tetra-audit --ci # CI mode (GitHub Actions annotations)
13
+ * tetra-audit --json # JSON output
13
14
  */
14
15
 
15
16
  import { program } from 'commander'
16
- import { runAllChecks, runSecurityChecks, runStabilityChecks, runCodeQualityChecks, runQuickCheck } from '../lib/runner.js'
17
+ import { runAllChecks, runSecurityChecks, runStabilityChecks, runCodeQualityChecks, runHygieneChecks, runQuickCheck } from '../lib/runner.js'
17
18
  import { formatResults, formatGitHubActions } from '../lib/reporters/terminal.js'
18
19
 
19
20
  program
20
- .name('vca-audit')
21
- .description('VCA Quality Toolkit - Unified quality checks for all projects')
22
- .version('1.0.0')
21
+ .name('tetra-audit')
22
+ .description('Tetra Dev Toolkit - Unified quality checks for all projects')
23
+ .version('1.2.0')
23
24
  .argument('[suite]', 'Check suite to run: security, stability, quick, or all (default)')
24
25
  .option('--ci', 'CI mode - output GitHub Actions annotations')
25
26
  .option('--json', 'Output results as JSON')
@@ -40,6 +41,9 @@ program
40
41
  case 'code-quality':
41
42
  results = await runCodeQualityChecks()
42
43
  break
44
+ case 'hygiene':
45
+ results = await runHygieneChecks()
46
+ break
43
47
  case 'quick':
44
48
  results = await runQuickCheck()
45
49
  break
@@ -56,7 +60,7 @@ program
56
60
 
57
61
  // Also print summary
58
62
  console.log('')
59
- console.log('## VCA Quality Audit Results')
63
+ console.log('## Tetra Quality Audit Results')
60
64
  console.log('')
61
65
  console.log(`- **Status**: ${results.passed ? '✅ PASSED' : '❌ FAILED'}`)
62
66
  console.log(`- **Checks**: ${results.summary.passed} passed, ${results.summary.failed} failed`)
@@ -1,25 +1,25 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * VCA Dev Toolkit - Dev Token CLI
4
+ * Tetra Dev Toolkit - Dev Token CLI
5
5
  *
6
6
  * Manage Supabase dev tokens for API testing.
7
7
  * Auto-detects project from package.json, finds Supabase config from .env files.
8
8
  *
9
9
  * Usage:
10
- * vca-dev-token # Auto-refresh or show status
11
- * vca-dev-token --login # Interactive login (prompts for password)
12
- * vca-dev-token --status # Show current token status
13
- * vca-dev-token --project myapp # Override project detection
10
+ * tetra-dev-token # Auto-refresh or show status
11
+ * tetra-dev-token --login # Interactive login (prompts for password)
12
+ * tetra-dev-token --status # Show current token status
13
+ * tetra-dev-token --project myapp # Override project detection
14
14
  */
15
15
 
16
16
  import { program } from 'commander'
17
17
  import { runDevToken } from '../lib/commands/dev-token.js'
18
18
 
19
19
  program
20
- .name('vca-dev-token')
20
+ .name('tetra-dev-token')
21
21
  .description('Manage Supabase dev tokens for API testing')
22
- .version('1.1.0')
22
+ .version('1.2.0')
23
23
  .option('--login', 'Interactive login (prompts for email/password)')
24
24
  .option('--status', 'Show current token status')
25
25
  .option('--project <name>', 'Override auto-detected project slug')
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * VCA Quality Toolkit - Setup CLI
4
+ * Tetra Dev Toolkit - Setup CLI
5
5
  *
6
6
  * Sets up quality infrastructure in a project:
7
7
  * - Husky pre-commit hooks
@@ -9,10 +9,10 @@
9
9
  * - Configuration file
10
10
  *
11
11
  * Usage:
12
- * vca-setup # Interactive setup
13
- * vca-setup hooks # Setup Husky hooks only
14
- * vca-setup ci # Setup GitHub Actions only
15
- * vca-setup config # Create .vca-quality.json
12
+ * tetra-setup # Interactive setup
13
+ * tetra-setup hooks # Setup Husky hooks only
14
+ * tetra-setup ci # Setup GitHub Actions only
15
+ * tetra-setup config # Create .tetra-quality.json
16
16
  */
17
17
 
18
18
  import { program } from 'commander'
@@ -23,14 +23,14 @@ import { join } from 'path'
23
23
  const projectRoot = process.cwd()
24
24
 
25
25
  program
26
- .name('vca-setup')
27
- .description('Setup VCA Quality Toolkit in your project')
28
- .version('1.0.0')
26
+ .name('tetra-setup')
27
+ .description('Setup Tetra Dev Toolkit in your project')
28
+ .version('1.2.0')
29
29
  .argument('[component]', 'Component to setup: hooks, ci, config, or all (default)')
30
30
  .option('-f, --force', 'Overwrite existing files')
31
31
  .action(async (component, options) => {
32
32
  console.log('')
33
- console.log('🔧 VCA Quality Toolkit - Setup')
33
+ console.log('🔧 Tetra Dev Toolkit - Setup')
34
34
  console.log('═'.repeat(50))
35
35
  console.log('')
36
36
 
@@ -58,7 +58,7 @@ program
58
58
  console.log('✅ Setup complete!')
59
59
  console.log('')
60
60
  console.log('Next steps:')
61
- console.log(' 1. Run `vca-audit` to check your project')
61
+ console.log(' 1. Run `tetra-audit` to check your project')
62
62
  console.log(' 2. Commit the generated files')
63
63
  console.log(' 3. Push to trigger CI checks')
64
64
  console.log('')
@@ -95,14 +95,14 @@ async function setupHooks(options) {
95
95
  const preCommitContent = `#!/bin/sh
96
96
  . "$(dirname "$0")/_/husky.sh"
97
97
 
98
- echo "🔍 Running VCA Quality checks..."
98
+ echo "🔍 Running Tetra quality checks..."
99
99
 
100
100
  # Run quick security checks (fast, blocks commit on critical issues)
101
- npx vca-audit quick
101
+ npx tetra-audit quick
102
102
  if [ $? -ne 0 ]; then
103
103
  echo ""
104
104
  echo "❌ Security issues found! Fix before committing."
105
- echo " Run 'vca-audit' for detailed report."
105
+ echo " Run 'tetra-audit' for detailed report."
106
106
  exit 1
107
107
  fi
108
108
 
@@ -120,6 +120,39 @@ echo "✅ Pre-commit checks passed"
120
120
  console.log(' ⏭️ .husky/pre-commit already exists (use --force to overwrite)')
121
121
  }
122
122
 
123
+ // Create or extend pre-push hook with hygiene check
124
+ const prePushPath = join(huskyDir, 'pre-push')
125
+ const hygieneBlock = `
126
+ # Tetra hygiene check — blocks push if repo contains clutter
127
+ echo "🧹 Running repo hygiene check..."
128
+ npx tetra-audit hygiene
129
+ if [ $? -ne 0 ]; then
130
+ echo ""
131
+ echo "❌ Repo hygiene issues found! Clean up before pushing."
132
+ echo " Run 'npx tetra-audit hygiene --verbose' for details."
133
+ echo " Run 'bash node_modules/@soulbatical/tetra-dev-toolkit/bin/cleanup-repos.sh' to auto-fix."
134
+ exit 1
135
+ fi
136
+ echo "✅ Repo hygiene passed"
137
+ `
138
+
139
+ if (!existsSync(prePushPath)) {
140
+ // No pre-push hook yet — create one
141
+ const prePushContent = `#!/bin/sh\n${hygieneBlock}\n`
142
+ writeFileSync(prePushPath, prePushContent)
143
+ execSync(`chmod +x ${prePushPath}`)
144
+ console.log(' ✅ Created .husky/pre-push with hygiene check')
145
+ } else {
146
+ // Pre-push hook exists — add hygiene check if not already there
147
+ const existing = readFileSync(prePushPath, 'utf-8')
148
+ if (!existing.includes('tetra-audit hygiene')) {
149
+ writeFileSync(prePushPath, existing.trimEnd() + '\n' + hygieneBlock)
150
+ console.log(' ✅ Added hygiene check to existing .husky/pre-push')
151
+ } else {
152
+ console.log(' ⏭️ .husky/pre-push already has hygiene check')
153
+ }
154
+ }
155
+
123
156
  // Add prepare script to package.json
124
157
  if (!pkg.scripts?.prepare?.includes('husky')) {
125
158
  pkg.scripts = pkg.scripts || {}
@@ -149,7 +182,7 @@ on:
149
182
 
150
183
  jobs:
151
184
  quality:
152
- name: 🔍 VCA Quality Audit
185
+ name: 🔍 Tetra Quality Audit
153
186
  runs-on: ubuntu-latest
154
187
 
155
188
  steps:
@@ -165,8 +198,8 @@ jobs:
165
198
  - name: Install dependencies
166
199
  run: npm ci
167
200
 
168
- - name: Run VCA Quality Audit
169
- run: npx @vca/quality-toolkit --ci
201
+ - name: Run Tetra Quality Audit
202
+ run: npx tetra-audit --ci
170
203
 
171
204
  - name: Upload results
172
205
  if: always()
@@ -186,15 +219,16 @@ jobs:
186
219
  async function setupConfig(options) {
187
220
  console.log('📝 Setting up configuration...')
188
221
 
189
- const configPath = join(projectRoot, '.vca-quality.json')
222
+ const configPath = join(projectRoot, '.tetra-quality.json')
190
223
  if (!existsSync(configPath) || options.force) {
191
224
  const config = {
192
- "$schema": "https://vca-tools.dev/schemas/quality-toolkit.json",
225
+ "$schema": "https://tetra-tools.dev/schemas/quality-toolkit.json",
193
226
  "suites": {
194
227
  "security": true,
195
228
  "stability": true,
196
229
  "codeQuality": true,
197
- "supabase": "auto"
230
+ "supabase": "auto",
231
+ "hygiene": true
198
232
  },
199
233
  "security": {
200
234
  "checkHardcodedSecrets": true,
@@ -218,7 +252,7 @@ async function setupConfig(options) {
218
252
  }
219
253
 
220
254
  writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n')
221
- console.log(' ✅ Created .vca-quality.json')
255
+ console.log(' ✅ Created .tetra-quality.json')
222
256
  } else {
223
257
  console.log(' ⏭️ Config already exists (use --force to overwrite)')
224
258
  }