Monorepo for Aesthetic.Computer
aesthetic.computer
1#!/bin/bash
2# Pre-commit hook: auto-update .piece-commits.json and docs.js stubs
3# for any new or modified pieces in disks/.
4#
5# Install: cp utilities/pre-commit-pieces.sh .git/hooks/pre-commit && chmod +x .git/hooks/pre-commit
6
7REPO_ROOT="$(git rev-parse --show-toplevel)"
8DISKS_DIR="$REPO_ROOT/system/public/aesthetic.computer/disks"
9COMMITS_FILE="$REPO_ROOT/system/public/.piece-commits.json"
10DOCS_FILE="$REPO_ROOT/system/netlify/functions/docs.js"
11
12# --- 1. Regenerate .piece-commits.json ---
13
14# Check if any piece files are being committed
15PIECE_CHANGES=$(git diff --cached --name-only -- "system/public/aesthetic.computer/disks/*.mjs" 2>/dev/null)
16
17if [ -n "$PIECE_CHANGES" ] || [ ! -f "$COMMITS_FILE" ]; then
18 echo "🔄 Regenerating .piece-commits.json..."
19
20 echo "{" > "$COMMITS_FILE"
21 echo ' "commits": {' >> "$COMMITS_FILE"
22
23 first=true
24
25 for file in "$DISKS_DIR"/*.mjs; do
26 [ -f "$file" ] || continue
27 piece=$(basename "$file" .mjs)
28
29 # For staged new files that have no git history yet
30 if git diff --cached --name-only --diff-filter=A 2>/dev/null | grep -q "disks/$piece.mjs"; then
31 hash="0000000"
32 date="$(date -u +"%Y-%m-%d %H:%M:%S +0000")"
33 author="$(git config user.name)"
34 message="(new piece)"
35 else
36 commit_info=$(git log -1 --format="%H|%ai|%an|%s" -- "$file" 2>/dev/null)
37 if [ -z "$commit_info" ]; then
38 continue
39 fi
40 IFS='|' read -r hash date author message <<< "$commit_info"
41 hash="${hash:0:7}"
42 message=$(echo "$message" | sed 's/"/\\"/g' | head -c 100)
43 fi
44
45 if [ "$first" = false ]; then
46 echo "," >> "$COMMITS_FILE"
47 fi
48 first=false
49
50 echo -n " \"$piece\": {" >> "$COMMITS_FILE"
51 echo -n "\"hash\":\"$hash\"," >> "$COMMITS_FILE"
52 echo -n "\"date\":\"$date\"," >> "$COMMITS_FILE"
53 echo -n "\"author\":\"$author\"," >> "$COMMITS_FILE"
54 echo -n "\"message\":\"$message\"" >> "$COMMITS_FILE"
55 echo -n "}" >> "$COMMITS_FILE"
56 done
57
58 echo "" >> "$COMMITS_FILE"
59 echo ' },' >> "$COMMITS_FILE"
60 echo " \"generated\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\"" >> "$COMMITS_FILE"
61 echo "}" >> "$COMMITS_FILE"
62
63 git add "$COMMITS_FILE"
64 echo " ✅ Updated .piece-commits.json"
65fi
66
67# --- 2. Auto-add new pieces to docs.js ---
68
69NEW_PIECES=$(git diff --cached --name-only --diff-filter=A -- "system/public/aesthetic.computer/disks/*.mjs" 2>/dev/null)
70
71if [ -n "$NEW_PIECES" ]; then
72 DOCS_CHANGED=false
73
74 for file in $NEW_PIECES; do
75 piece=$(basename "$file" .mjs)
76
77 # Skip if already in docs.js
78 if grep -q "\"$piece\":\|[[:space:]]$piece:" "$DOCS_FILE" 2>/dev/null; then
79 continue
80 fi
81
82 # Extract description from line 2 comment (// Description text)
83 desc=""
84 if [ -f "$REPO_ROOT/$file" ]; then
85 desc=$(sed -n '2s|^// *||p' "$REPO_ROOT/$file" | sed 's/"/\\"/g' | head -c 120)
86 fi
87
88 # Find the closing }, of the pieces section (last one before the `};` that closes the docs object)
89 # The pieces section ends at the last ` },` line in docs.js
90 CLOSE_LINE=$(grep -n "^ }," "$DOCS_FILE" | tail -1 | cut -d: -f1)
91
92 if [ -n "$CLOSE_LINE" ]; then
93 # Insert stub before the closing brace using a temp file (portable)
94 head -n $((CLOSE_LINE - 1)) "$DOCS_FILE" > "$DOCS_FILE.tmp"
95 cat >> "$DOCS_FILE.tmp" << STUB
96 "$piece": {
97 sig: "$piece",
98 desc: "$desc",
99 done: false,
100 },
101STUB
102 tail -n +"$CLOSE_LINE" "$DOCS_FILE" >> "$DOCS_FILE.tmp"
103 mv "$DOCS_FILE.tmp" "$DOCS_FILE"
104 DOCS_CHANGED=true
105 echo " ✅ Added '$piece' stub to docs.js"
106 fi
107 done
108
109 if [ "$DOCS_CHANGED" = true ]; then
110 git add "$DOCS_FILE"
111 fi
112fi
113
114exit 0