@jjdenhertog/ai-driven-development
Version:
AI-driven development workflow with learning capabilities for Claude
683 lines (578 loc) ⢠23.5 kB
Markdown
---
description: "UPDATE INDEX - Refresh codebase index after changes"
allowed-tools: ["Read", "Grep", "Glob", "LS", "Bash", "Write"]
disallowed-tools: ["Edit", "MultiEdit", "NotebookEdit", "git", "Task", "TodoWrite", "WebFetch", "WebSearch"]
---
# Command: aidev-update-index
# š CODEBASE INDEX UPDATE š
**PURPOSE:**
Incrementally update the existing codebase index after AI work to:
- Track new components and utilities
- Update usage counts
- Remove deleted items
- Refresh modification times
- Maintain index accuracy
**PREREQUISITES:**
ā
Existing index in `.aidev-storage/index/`
ā
Previous indexation completed
**OUTPUTS:**
ā
Updated index files with changes
ā
`.aidev-storage/index/changes.json` - Change summary
ā
Refreshed metadata with update timestamp
<role-context>
You are a codebase index updater. Your job is to efficiently update the existing index by detecting changes since the last indexation, avoiding full rescans when possible.
</role-context>
<structured-prompt>
This command updates an existing index:
- Detects modified files since last index
- Updates only changed components
- Preserves historical data
- Generates change summary
</structured-prompt>
## Process
### 0. Verify Existing Index
```bash
echo "===================================="
echo "š INDEX UPDATE"
echo "===================================="
# Check for existing index
if [ ! -d ".aidev-storage/index" ]; then
echo "ā No existing index found!"
echo "š” Run 'aidev indexation' first"
exit 1
fi
# Load existing metadata
if [ ! -f ".aidev-storage/index/metadata.json" ]; then
echo "ā Index metadata missing!"
echo "š” Run full indexation first"
exit 1
fi
LAST_UPDATE=$(jq -r '.updated_at' .aidev-storage/index/metadata.json)
echo "š
Last update: $LAST_UPDATE"
# Initialize change tracking
CHANGES='{"added": [], "modified": [], "removed": [], "summary": {}}'
UPDATE_START=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
```
### 1. Detect Changed Files
```bash
echo "š Detecting changes since last update..."
# Find all files modified since last update
# Convert date to timestamp for comparison
if command -v gdate >/dev/null 2>&1; then
# GNU date (from coreutils on macOS)
LAST_TIMESTAMP=$(gdate -d "$LAST_UPDATE" +%s)
else
# BSD date (macOS default)
LAST_TIMESTAMP=$(date -j -f "%Y-%m-%dT%H:%M:%SZ" "$LAST_UPDATE" +%s 2>/dev/null || echo "0")
fi
# Find modified source files
MODIFIED_FILES=""
if [ "$LAST_TIMESTAMP" -gt 0 ]; then
MODIFIED_FILES=$(find . \( -name "*.tsx" -o -name "*.jsx" -o -name "*.ts" -o -name "*.js" -o -name "*.css" -o -name "*.scss" \) -newer .aidev-storage/index/metadata.json 2>/dev/null | grep -v node_modules | sort)
fi
# If timestamp comparison fails, fallback to checking all files
if [ -z "$MODIFIED_FILES" ] && [ "$LAST_TIMESTAMP" -eq 0 ]; then
echo "ā ļø Unable to detect by timestamp, scanning all files..."
MODIFIED_FILES=$(find . \( -name "*.tsx" -o -name "*.jsx" -o -name "*.ts" -o -name "*.js" -o -name "*.css" -o -name "*.scss" \) | grep -v node_modules | sort)
fi
MODIFIED_COUNT=$(echo "$MODIFIED_FILES" | grep -c . || echo 0)
echo "š Found $MODIFIED_COUNT modified files"
```
### 2. Update Component Index
```bash
echo "š Updating component index..."
# Load existing components
COMPONENTS_INDEX=$(cat .aidev-storage/index/components.json)
EXISTING_PATHS=$(echo "$COMPONENTS_INDEX" | jq -r '.components[].path' | sort)
# Track changes
COMPONENT_CHANGES='{"added": 0, "modified": 0, "removed": 0}'
# Process modified files
for FILE in $MODIFIED_FILES; do
# Skip if not a component file
if ! echo "$FILE" | grep -q "\.tsx$\|\.jsx$"; then
continue
fi
# Skip test files
if echo "$FILE" | grep -q "\.test\.\|\.spec\."; then
continue
fi
# Check if file still exists
if [ ! -f "$FILE" ]; then
# Remove from index
COMPONENTS_INDEX=$(echo "$COMPONENTS_INDEX" | jq --arg path "$FILE" '.components |= map(select(.path != $path))')
COMPONENT_CHANGES=$(echo "$COMPONENT_CHANGES" | jq '.removed += 1')
continue
fi
# Extract component name
FILENAME=$(basename "$FILE")
COMPONENT_NAME="${FILENAME%.*}"
# Check if it's a component
if grep -q "export.*function\s\+[A-Z]" "$FILE" 2>/dev/null || \
grep -q "export.*const\s\+[A-Z].*=.*=>" "$FILE" 2>/dev/null || \
grep -q "export\s\+default.*function\s\+[A-Z]" "$FILE" 2>/dev/null; then
# Extract component data (same as original indexation)
PROPS="[]"
if [[ "$FILE" == *.tsx ]]; then
PROPS_DEF=$(grep -A 10 "interface.*Props\|type.*Props" "$FILE" 2>/dev/null | head -20)
if [ ! -z "$PROPS_DEF" ]; then
PROPS=$(echo "$PROPS_DEF" | grep -E "^\s*\w+\s*:" | sed 's/^\s*//' | sed 's/:.*$//' | jq -R -s 'split("\n") | map(select(. != ""))')
fi
fi
# Count usage
USAGE_COUNT=$(grep -r "import.*$COMPONENT_NAME.*from.*['\"].*$(basename $(dirname $FILE))" . --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" 2>/dev/null | wc -l)
# Get file stats
LAST_MODIFIED=$(stat -f "%Sm" -t "%Y-%m-%dT%H:%M:%SZ" "$FILE" 2>/dev/null || date -u +"%Y-%m-%dT%H:%M:%SZ")
FILE_SIZE=$(wc -l < "$FILE")
# Determine complexity
if [ $FILE_SIZE -lt 50 ]; then
COMPLEXITY="low"
elif [ $FILE_SIZE -lt 150 ]; then
COMPLEXITY="medium"
else
COMPLEXITY="high"
fi
# Extract imports
IMPORTS=$(grep "^import" "$FILE" | sed 's/import.*from//' | sed "s/['\";]//g" | jq -R -s 'split("\n") | map(select(. != "")) | map(ltrimstr(" "))')
# Create component entry
COMPONENT_ENTRY=$(jq -n \
--arg name "$COMPONENT_NAME" \
--arg path "$FILE" \
--arg complexity "$COMPLEXITY" \
--arg modified "$LAST_MODIFIED" \
--argjson props "$PROPS" \
--argjson imports "$IMPORTS" \
--arg usage "$USAGE_COUNT" \
--arg size "$FILE_SIZE" \
'{
name: $name,
path: $path,
type: "component",
props: $props,
imports: $imports,
usage_count: ($usage | tonumber),
complexity: $complexity,
last_modified: $modified,
line_count: ($size | tonumber)
}')
# Check if component exists in index
if echo "$COMPONENTS_INDEX" | jq --arg path "$FILE" '.components[] | select(.path == $path)' | grep -q .; then
# Update existing
COMPONENTS_INDEX=$(echo "$COMPONENTS_INDEX" | jq --arg path "$FILE" --argjson entry "$COMPONENT_ENTRY" \
'.components |= map(if .path == $path then $entry else . end)')
COMPONENT_CHANGES=$(echo "$COMPONENT_CHANGES" | jq '.modified += 1')
else
# Add new
COMPONENTS_INDEX=$(echo "$COMPONENTS_INDEX" | jq --argjson entry "$COMPONENT_ENTRY" '.components += [$entry]')
COMPONENT_CHANGES=$(echo "$COMPONENT_CHANGES" | jq '.added += 1')
fi
fi
done
# Check for removed components
for PATH in $EXISTING_PATHS; do
if [ ! -f "$PATH" ]; then
COMPONENTS_INDEX=$(echo "$COMPONENTS_INDEX" | jq --arg path "$PATH" '.components |= map(select(.path != $path))')
COMPONENT_CHANGES=$(echo "$COMPONENT_CHANGES" | jq '.removed += 1')
fi
done
# Save updated components
echo "$COMPONENTS_INDEX" | jq '.' > .aidev-storage/index/components.json
echo "ā
Components: +$(echo "$COMPONENT_CHANGES" | jq -r '.added') ~$(echo "$COMPONENT_CHANGES" | jq -r '.modified') -$(echo "$COMPONENT_CHANGES" | jq -r '.removed')"
```
### 3. Update Tests Index
```bash
echo "š Updating tests index..."
# Load or initialize tests index
if [ -f ".aidev-storage/index/tests.json" ]; then
TESTS_INDEX=$(cat .aidev-storage/index/tests.json)
else
TESTS_INDEX='{"tests": []}'
fi
TEST_CHANGES='{"added": 0, "modified": 0, "removed": 0}'
# Process test files
for FILE in $MODIFIED_FILES; do
# Check if it's a test file
if ! echo "$FILE" | grep -q "\.test\.|\.spec\."; then
continue
fi
# Check if file still exists
if [ ! -f "$FILE" ]; then
TESTS_INDEX=$(echo "$TESTS_INDEX" | jq --arg path "$FILE" '.tests |= map(select(.path != $path))')
TEST_CHANGES=$(echo "$TEST_CHANGES" | jq '.removed += 1')
continue
fi
# Extract test information
TEST_FILENAME=$(basename "$FILE")
COMPONENT_TESTED="${TEST_FILENAME%.test.*}"
COMPONENT_TESTED="${COMPONENT_TESTED%.spec.*}"
# Count test cases
TEST_COUNT=$(grep -E "test\(|it\(|describe\(" "$FILE" | grep -c "it\(\|test\(" || echo 0)
DESCRIBE_COUNT=$(grep -c "describe\(" "$FILE" || echo 0)
# Detect test type
TEST_TYPE="unit"
if grep -q "render\|screen\|fireEvent" "$FILE" 2>/dev/null; then
TEST_TYPE="component"
elif grep -q "request\|response\|api\|endpoint" "$FILE" 2>/dev/null; then
TEST_TYPE="api"
elif grep -q "e2e\|browser\|page\." "$FILE" 2>/dev/null; then
TEST_TYPE="e2e"
fi
# Check for framework-specific tests (things we might want to clean up)
FRAMEWORK_TESTS=$(grep -E "test.*React.*render|test.*routing|test.*Next\.js" "$FILE" | wc -l || echo 0)
# Get file stats
LAST_MODIFIED=$(stat -f "%Sm" -t "%Y-%m-%dT%H:%M:%SZ" "$FILE" 2>/dev/null || date -u +"%Y-%m-%dT%H:%M:%SZ")
FILE_SIZE=$(wc -l < "$FILE")
# Find the component file being tested
COMPONENT_PATH=""
POSSIBLE_PATHS=(
"${FILE%/*.test.*}/${COMPONENT_TESTED}.tsx"
"${FILE%/*.test.*}/${COMPONENT_TESTED}.ts"
"${FILE%/*.test.*}/${COMPONENT_TESTED}.jsx"
"${FILE%/*.test.*}/${COMPONENT_TESTED}.js"
)
for POSSIBLE_PATH in "${POSSIBLE_PATHS[@]}"; do
if [ -f "$POSSIBLE_PATH" ]; then
COMPONENT_PATH="$POSSIBLE_PATH"
break
fi
done
# Create test entry
TEST_ENTRY=$(jq -n \
--arg path "$FILE" \
--arg component "$COMPONENT_TESTED" \
--arg component_path "$COMPONENT_PATH" \
--arg type "$TEST_TYPE" \
--arg test_count "$TEST_COUNT" \
--arg describe_count "$DESCRIBE_COUNT" \
--arg framework_tests "$FRAMEWORK_TESTS" \
--arg modified "$LAST_MODIFIED" \
--arg size "$FILE_SIZE" \
'{
path: $path,
component_tested: $component,
component_path: (if $component_path == "" then null else $component_path end),
type: $type,
test_count: ($test_count | tonumber),
describe_blocks: ($describe_count | tonumber),
framework_test_count: ($framework_tests | tonumber),
last_modified: $modified,
line_count: ($size | tonumber)
}')
# Update or add
if echo "$TESTS_INDEX" | jq --arg path "$FILE" '.tests[] | select(.path == $path)' | grep -q .; then
TESTS_INDEX=$(echo "$TESTS_INDEX" | jq --arg path "$FILE" --argjson entry "$TEST_ENTRY" \
'.tests |= map(if .path == $path then $entry else . end)')
TEST_CHANGES=$(echo "$TEST_CHANGES" | jq '.modified += 1')
else
TESTS_INDEX=$(echo "$TESTS_INDEX" | jq --argjson entry "$TEST_ENTRY" '.tests += [$entry]')
TEST_CHANGES=$(echo "$TEST_CHANGES" | jq '.added += 1')
fi
done
# Save updated tests
echo "$TESTS_INDEX" | jq '.' > .aidev-storage/index/tests.json
echo "ā
Tests: +$(echo "$TEST_CHANGES" | jq -r '.added') ~$(echo "$TEST_CHANGES" | jq -r '.modified') -$(echo "$TEST_CHANGES" | jq -r '.removed')"
```
### 4. Update Hooks Index
```bash
echo "š Updating hooks index..."
# Similar pattern for hooks
HOOKS_INDEX=$(cat .aidev-storage/index/hooks.json)
HOOK_CHANGES='{"added": 0, "modified": 0, "removed": 0}'
# Process modified TypeScript files for hooks
for FILE in $MODIFIED_FILES; do
if ! echo "$FILE" | grep -q "\.ts$\|\.tsx$"; then
continue
fi
# Check for hook exports
if grep -q "export.*function.*use[A-Z]" "$FILE" 2>/dev/null; then
# Process each hook in the file
HOOKS_IN_FILE=$(grep "export.*function.*use[A-Z]" "$FILE" | sed 's/export.*function\s*//' | sed 's/(.*//' | sed 's/\s*$//')
for HOOK_NAME in $HOOKS_IN_FILE; do
# Extract hook data
SIGNATURE=$(grep -A 1 "function $HOOK_NAME" "$FILE" | tr '\n' ' ' | sed 's/export.*function//' | sed 's/{.*//' | sed 's/\s\+/ /g')
USAGE_COUNT=$(grep -r "$HOOK_NAME" . --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" 2>/dev/null | grep -v "function $HOOK_NAME" | wc -l)
DEPS=$(grep -A 20 "function $HOOK_NAME" "$FILE" | grep -E "use[A-Z][a-zA-Z]*\(" | sed 's/.*\(use[A-Z][a-zA-Z]*\).*/\1/' | sort -u | jq -R -s 'split("\n") | map(select(. != ""))')
# Create hook entry
HOOK_ENTRY=$(jq -n \
--arg name "$HOOK_NAME" \
--arg path "$FILE" \
--arg signature "$SIGNATURE" \
--argjson deps "$DEPS" \
--arg usage "$USAGE_COUNT" \
'{
name: $name,
path: $path,
type: "hook",
signature: $signature,
dependencies: $deps,
usage_count: ($usage | tonumber)
}')
# Update or add
if echo "$HOOKS_INDEX" | jq --arg name "$HOOK_NAME" --arg path "$FILE" '.hooks[] | select(.name == $name and .path == $path)' | grep -q .; then
HOOKS_INDEX=$(echo "$HOOKS_INDEX" | jq --arg name "$HOOK_NAME" --arg path "$FILE" --argjson entry "$HOOK_ENTRY" \
'.hooks |= map(if .name == $name and .path == $path then $entry else . end)')
HOOK_CHANGES=$(echo "$HOOK_CHANGES" | jq '.modified += 1')
else
HOOKS_INDEX=$(echo "$HOOKS_INDEX" | jq --argjson entry "$HOOK_ENTRY" '.hooks += [$entry]')
HOOK_CHANGES=$(echo "$HOOK_CHANGES" | jq '.added += 1')
fi
done
fi
done
# Save updated hooks
echo "$HOOKS_INDEX" | jq '.' > .aidev-storage/index/hooks.json
echo "ā
Hooks: +$(echo "$HOOK_CHANGES" | jq -r '.added') ~$(echo "$HOOK_CHANGES" | jq -r '.modified') -$(echo "$HOOK_CHANGES" | jq -r '.removed')"
```
### 4. Update Other Indices (Enhanced CSS Analysis)
```bash
echo "š Updating utilities, styles, and layouts..."
```
**Update Process for Each Index:**
1. **Components Update:**
- Process modified TSX/JSX files
- Update component metadata (props, imports, usage)
- Track added/modified/removed components
2. **Tests Update (NEW):**
- Process modified test files (.test.*, .spec.*)
- Extract test information:
- Component being tested
- Test type (unit/component/api/e2e)
- Number of test cases and describe blocks
- Framework-specific test count (for cleanup)
- Link tests to their components
- Identify orphaned tests (no matching component)
- Track test health metrics
3. **Hooks Update:**
- Process modified files containing hooks
- Update hook signatures and dependencies
- Recalculate usage counts
4. **Styles Update (Enhanced):**
- Process modified style files (CSS, TSX, JSX)
- Extract style definitions based on project approach:
- CSS: class names and rules
- Utilities: className patterns
- CSS-in-JS: styled components and sx props
- Component props: variant/color/size patterns
- Calculate usage counts across components
- **Duplicate Detection:** Compare patterns across files and approaches
- **Unused Detection:** Flag styles with usage_count = 0
- Track design token usage
5. **Utilities Update:**
- Process utility function changes
- Update function signatures
- Track category changes
**Enhanced Style Duplicate Detection:**
For each modified file containing styles:
1. Extract style patterns based on file type:
- `.css`: CSS rules
- `.tsx/.jsx`: className patterns, sx props, styled components
- Theme files: design token definitions
2. Compare patterns with existing index
3. Identify duplicates across different styling approaches:
- `padding: 1rem` in CSS = `p-4` in utilities = `sx={{ p: 2 }}`
- `display: flex; justify-content: center` = `flex justify-center`
4. Flag consolidation opportunities
**Pattern Analysis:**
```json
{
"duplicates": [
{
"primary": {"class": "button", "file": "./Button.css"},
"duplicates": ["actionBtn in ./Form.css", "submitBtn in ./Modal.css"]
}
],
"patterns": {
"unused_count": 15,
"unused_styles": [{"name": "oldButton", "path": "./legacy.css"}]
}
}
```
**Change Summary Output:**
```bash
echo "ā
Components: +5 ~10 -2"
echo "ā
Styles: +20 ~15 -5"
echo "ā ļø Found 8 duplicate CSS patterns"
echo "šļø Found 15 unused styles"
echo "ā
All indices updated"
```
### 5. Recalculate Usage Counts
```bash
echo "š Recalculating usage counts..."
# Update component usage counts for ALL components (even unchanged ones)
TEMP_COMPONENTS='{"components": []}'
COMPONENTS=$(echo "$COMPONENTS_INDEX" | jq -r '.components[]')
echo "$COMPONENTS_INDEX" | jq -c '.components[]' | while read -r COMPONENT; do
COMPONENT_NAME=$(echo "$COMPONENT" | jq -r '.name')
COMPONENT_PATH=$(echo "$COMPONENT" | jq -r '.path')
COMPONENT_DIR=$(basename $(dirname "$COMPONENT_PATH"))
# Recalculate usage
NEW_USAGE=$(grep -r "import.*$COMPONENT_NAME.*from.*['\"].*$COMPONENT_DIR" . --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" 2>/dev/null | wc -l)
# Update usage count
UPDATED_COMPONENT=$(echo "$COMPONENT" | jq --arg usage "$NEW_USAGE" '.usage_count = ($usage | tonumber)')
TEMP_COMPONENTS=$(echo "$TEMP_COMPONENTS" | jq --argjson comp "$UPDATED_COMPONENT" '.components += [$comp]')
done
# Apply updated usage counts
if [ "$(echo "$TEMP_COMPONENTS" | jq '.components | length')" -gt 0 ]; then
echo "$TEMP_COMPONENTS" | jq '.' > .aidev-storage/index/components.json
fi
echo "ā
Usage counts updated"
```
### 6. Generate Change Summary
```bash
echo "š Generating change summary..."
# Collect all changes
TOTAL_ADDED=$(echo "$COMPONENT_CHANGES $HOOK_CHANGES $TEST_CHANGES" | jq -s 'map(.added) | add')
TOTAL_MODIFIED=$(echo "$COMPONENT_CHANGES $HOOK_CHANGES $TEST_CHANGES" | jq -s 'map(.modified) | add')
TOTAL_REMOVED=$(echo "$COMPONENT_CHANGES $HOOK_CHANGES $TEST_CHANGES" | jq -s 'map(.removed) | add')
# Create change summary
CHANGES_SUMMARY=$(jq -n \
--arg start "$LAST_UPDATE" \
--arg end "$UPDATE_START" \
--arg files "$MODIFIED_COUNT" \
--arg added "$TOTAL_ADDED" \
--arg modified "$TOTAL_MODIFIED" \
--arg removed "$TOTAL_REMOVED" \
--argjson component_changes "$COMPONENT_CHANGES" \
--argjson hook_changes "$HOOK_CHANGES" \
--argjson test_changes "$TEST_CHANGES" \
'{
update_period: {
from: $start,
to: $end
},
files_scanned: ($files | tonumber),
total_changes: {
added: ($added | tonumber),
modified: ($modified | tonumber),
removed: ($removed | tonumber)
},
by_type: {
components: $component_changes,
hooks: $hook_changes,
tests: $test_changes
}
}')
# Save change summary
echo "$CHANGES_SUMMARY" | jq '.' > .aidev-storage/index/changes.json
```
### 7. Update Metadata
```bash
echo "š Updating metadata..."
# Load current counts
COMPONENT_COUNT=$(jq '.components | length' .aidev-storage/index/components.json)
HOOKS_COUNT=$(jq '.hooks | length' .aidev-storage/index/hooks.json)
UTILITIES_COUNT=$(jq '.utilities | length' .aidev-storage/index/utilities.json)
STYLES_COUNT=$(jq '.styles | length' .aidev-storage/index/styles.json)
LAYOUTS_COUNT=$(jq '.layouts | length' .aidev-storage/index/layouts.json)
API_COUNT=$(jq '.api_routes | length' .aidev-storage/index/api_routes.json)
TESTS_COUNT=$(jq '.tests | length' .aidev-storage/index/tests.json 2>/dev/null || echo 0)
# Get top used items
MOST_USED_COMPONENTS=$(jq -r '.components | sort_by(.usage_count) | reverse | .[0:5] | map(.name + " (" + (.usage_count | tostring) + ")")' .aidev-storage/index/components.json)
MOST_USED_HOOKS=$(jq -r '.hooks | sort_by(.usage_count) | reverse | .[0:5] | map(.name + " (" + (.usage_count | tostring) + ")")' .aidev-storage/index/hooks.json)
# Get test insights
ORPHANED_TESTS=$(jq -r '[.tests[] | select(.component_path == null)] | length' .aidev-storage/index/tests.json 2>/dev/null || echo 0)
FRAMEWORK_TEST_TOTAL=$(jq -r '[.tests[].framework_test_count] | add' .aidev-storage/index/tests.json 2>/dev/null || echo 0)
# Update metadata
EXISTING_METADATA=$(cat .aidev-storage/index/metadata.json)
UPDATED_METADATA=$(echo "$EXISTING_METADATA" | jq \
--arg updated "$UPDATE_START" \
--arg components "$COMPONENT_COUNT" \
--arg hooks "$HOOKS_COUNT" \
--arg utilities "$UTILITIES_COUNT" \
--arg styles "$STYLES_COUNT" \
--arg layouts "$LAYOUTS_COUNT" \
--arg api_routes "$API_COUNT" \
--arg tests "$TESTS_COUNT" \
--arg orphaned_tests "$ORPHANED_TESTS" \
--arg framework_tests "$FRAMEWORK_TEST_TOTAL" \
--argjson top_components "$MOST_USED_COMPONENTS" \
--argjson top_hooks "$MOST_USED_HOOKS" \
--argjson changes "$CHANGES_SUMMARY" \
'.updated_at = $updated |
.statistics.breakdown.components = ($components | tonumber) |
.statistics.breakdown.hooks = ($hooks | tonumber) |
.statistics.breakdown.utilities = ($utilities | tonumber) |
.statistics.breakdown.styles = ($styles | tonumber) |
.statistics.breakdown.layouts = ($layouts | tonumber) |
.statistics.breakdown.api_routes = ($api_routes | tonumber) |
.statistics.breakdown.tests = ($tests | tonumber) |
.insights.most_used_components = $top_components |
.insights.most_used_hooks = $top_hooks |
.insights.test_health = {
orphaned_tests: ($orphaned_tests | tonumber),
framework_specific_tests: ($framework_tests | tonumber)
} |
.last_update = $changes')
# Save updated metadata
echo "$UPDATED_METADATA" | jq '.' > .aidev-storage/index/metadata.json
```
### 8. Final Summary
```bash
echo ""
echo "===================================="
echo "ā
INDEX UPDATE COMPLETE"
echo "===================================="
echo ""
echo "š Changes Summary:"
echo " - Files scanned: $MODIFIED_COUNT"
echo " - Items added: $TOTAL_ADDED"
echo " - Items modified: $TOTAL_MODIFIED"
echo " - Items removed: $TOTAL_REMOVED"
echo ""
echo "š Current Totals:"
echo " - Components: $COMPONENT_COUNT"
echo " - Hooks: $HOOKS_COUNT"
echo " - Utilities: $UTILITIES_COUNT"
echo " - Styles: $STYLES_COUNT"
echo " - Layouts: $LAYOUTS_COUNT"
echo " - API Routes: $API_COUNT"
echo " - Tests: $TESTS_COUNT"
echo ""
if [ "$ORPHANED_TESTS" -gt 0 ] || [ "$FRAMEWORK_TEST_TOTAL" -gt 0 ]; then
echo "ā ļø Test Health Issues:"
[ "$ORPHANED_TESTS" -gt 0 ] && echo " - Orphaned tests: $ORPHANED_TESTS"
[ "$FRAMEWORK_TEST_TOTAL" -gt 0 ] && echo " - Framework-specific tests: $FRAMEWORK_TEST_TOTAL"
fi
echo ""
echo "š Updated indices: .aidev-storage/index/"
echo "š Change log: .aidev-storage/index/changes.json"
echo ""
echo "ā° Last update: $UPDATE_START"
```
## Key Features
<update-features>
ā
**Incremental Updates**
- Only scans modified files
- Preserves unchanged entries
- Faster than full reindex
ā
**Change Tracking**
- Records what was added/modified/removed
- Maintains update history
- Provides change summary
ā
**Enhanced CSS Analysis**
- Detects new duplicate patterns
- Tracks unused styles
- Updates property analysis
- Identifies consolidation opportunities
ā
**Test Tracking**
- Indexes all test files
- Links tests to components
- Identifies orphaned tests
- Tracks framework-specific tests for cleanup
- Monitors test health metrics
ā
**Usage Recalculation**
- Updates all usage counts
- Reflects current imports
- Maintains accuracy
ā
**Efficient Processing**
- Timestamp-based detection
- Minimal file scanning
- Preserves existing data
- Smart duplicate detection
</update-features>
## Success Criteria
Update is successful when:
- Modified files are detected
- Changes are tracked
- Usage counts are accurate
- Metadata is refreshed
- No data is lost