Skip to content

Commit 0e2fe37

Browse files
committed
Gitignore build artifacts and fix statusline index.lock contention
- Add dashboard/.svelte-kit/, dashboard/build/, dashboard/mockups/, and .claude/ to .gitignore - Untrack 817 committed build artifacts (git rm --cached) - Replace git-changes statusline widget with cached custom-command that skips git diff when index.lock is held and caches results for 30s - Add allow-list exception to protected-files-guard for .git/index.lock deletion
1 parent 67aa16d commit 0e2fe37

File tree

821 files changed

+82
-30407
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

821 files changed

+82
-30407
lines changed

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,19 @@ container/.devcontainer/.codeforge-preserve
5252
# Specs (local working directory)
5353
.specs/
5454

55+
# Claude Code local state
56+
.claude/
57+
5558
# CLI-specific
5659
cli/.pytest_cache/
5760
cli/.ruff_cache/
5861
.codeforge/data/
5962

63+
# Dashboard-specific
64+
dashboard/.svelte-kit/
65+
dashboard/build/
66+
dashboard/mockups/
67+
6068
# Docs-specific
6169
docs/.astro/
6270

container/.codeforge/config/ccstatusline-settings.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,10 @@
9393
},
9494
{
9595
"id": "a529e50e-b9f3-4150-a812-937ab81545e8",
96-
"type": "git-changes",
96+
"type": "custom-command",
97+
"commandPath": "/usr/local/bin/ccstatusline-git-changes",
98+
"timeout": 500,
99+
"preserveColors": false,
97100
"backgroundColor": "bgBrightBlue"
98101
},
99102
{

container/.devcontainer/features/ccstatusline/install.sh

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,65 @@ CWD_EOF
116116
chmod +x /usr/local/bin/ccstatusline-cwd
117117
echo "[ccstatusline] ✓ CWD helper installed at /usr/local/bin/ccstatusline-cwd"
118118

119+
# Create cached git-changes helper script
120+
# Caches git diff --shortstat output to avoid index.lock contention
121+
# from the statusline polling every render tick
122+
echo "[ccstatusline] Creating git-changes helper..."
123+
cat > /usr/local/bin/ccstatusline-git-changes <<'GITCHANGES_EOF'
124+
#!/bin/bash
125+
# Cached git-changes widget — avoids index.lock contention
126+
# Caches git diff --shortstat for CACHE_TTL seconds (default 30)
127+
CACHE_TTL="${CCSTATUSLINE_GIT_CACHE_TTL:-30}"
128+
CACHE_FILE="/tmp/ccstatusline-git-changes-$$"
129+
130+
# Read cwd from Claude Code JSON on stdin
131+
CWD=$(jq -r '.cwd // empty' 2>/dev/null)
132+
[ -z "$CWD" ] && exit 0
133+
134+
# Use cwd hash so different projects don't share cache
135+
CACHE_KEY=$(echo "$CWD" | md5sum | cut -c1-8)
136+
CACHE_FILE="/tmp/ccstatusline-git-changes-${CACHE_KEY}"
137+
138+
# Return cached value if fresh enough
139+
if [ -f "$CACHE_FILE" ]; then
140+
AGE=$(( $(date +%s) - $(stat -c %Y "$CACHE_FILE" 2>/dev/null || echo 0) ))
141+
if [ "$AGE" -lt "$CACHE_TTL" ]; then
142+
cat "$CACHE_FILE"
143+
exit 0
144+
fi
145+
fi
146+
147+
# Skip if lock is held (don't queue behind another git operation)
148+
if [ -f "$CWD/.git/index.lock" ]; then
149+
[ -f "$CACHE_FILE" ] && cat "$CACHE_FILE"
150+
exit 0
151+
fi
152+
153+
# Run git diff with a short timeout
154+
UNSTAGED=$(timeout 3 git -C "$CWD" diff --shortstat 2>/dev/null || true)
155+
STAGED=$(timeout 3 git -C "$CWD" diff --cached --shortstat 2>/dev/null || true)
156+
157+
# Parse insertions/deletions
158+
INS=0; DEL=0
159+
for STAT in "$UNSTAGED" "$STAGED"; do
160+
I=$(echo "$STAT" | grep -oP '\d+(?=\s+insertions?)' || true)
161+
D=$(echo "$STAT" | grep -oP '\d+(?=\s+deletions?)' || true)
162+
INS=$(( INS + ${I:-0} ))
163+
DEL=$(( DEL + ${D:-0} ))
164+
done
165+
166+
OUTPUT=""
167+
[ "$INS" -gt 0 ] && OUTPUT="+${INS}"
168+
[ "$DEL" -gt 0 ] && OUTPUT="${OUTPUT:+${OUTPUT} }-${DEL}"
169+
[ -z "$OUTPUT" ] && OUTPUT="clean"
170+
171+
echo "$OUTPUT" > "$CACHE_FILE"
172+
echo "$OUTPUT"
173+
GITCHANGES_EOF
174+
175+
chmod +x /usr/local/bin/ccstatusline-git-changes
176+
echo "[ccstatusline] ✓ Git-changes helper installed at /usr/local/bin/ccstatusline-git-changes"
177+
119178
# Create wrapper script to protect configuration
120179
echo "[ccstatusline] Creating wrapper script..."
121180
cat > /usr/local/bin/ccstatusline-wrapper <<'WRAPPER_EOF'

container/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/guard-protected-bash.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@
2020
r"(^|/)\.env\.(?!example$)[^/]+$",
2121
"Blocked: .env.* files contain secrets - edit manually if needed",
2222
),
23-
(r"(^|/)\.git(/|$)", "Blocked: .git is managed by git"),
23+
(
24+
r"(^|/)\.git(/|$)",
25+
"Blocked: .git is managed by git",
26+
{"allow": [r"\.git/index\.lock$"]},
27+
),
2428
(
2529
r"(^|/)package-lock\.json$",
2630
"Blocked: package-lock.json - use npm install instead",
@@ -158,8 +162,13 @@ def extract_write_targets(command: str) -> list[str]:
158162
def check_path(file_path: str) -> tuple[bool, str]:
159163
"""Check if file path matches any protected pattern."""
160164
normalized = file_path.replace("\\", "/")
161-
for pattern, message in PROTECTED_PATTERNS:
165+
for entry in PROTECTED_PATTERNS:
166+
pattern, message = entry[0], entry[1]
167+
opts = entry[2] if len(entry) > 2 else {}
162168
if re.search(pattern, normalized, re.IGNORECASE):
169+
# Check if path matches an allow-list exception
170+
if any(re.search(a, normalized) for a in opts.get("allow", [])):
171+
continue
163172
return True, message
164173
return False, ""
165174

0 commit comments

Comments
 (0)