mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-10 02:24:35 +08:00
feat: Add v1.1 update-memory system with dual-mode operations and enhanced documentation
## New Features - **Dual-mode update-memory commands**: /update-memory-full and /update-memory-related - **Git-aware change detection**: Intelligent context-aware documentation updates - **Complexity-adaptive execution**: Auto-delegation to memory-gemini-bridge for complex projects - **Depth-parallel processing**: Bottom-up execution ensuring proper context propagation - **Enhanced issue tracking integration**: Complete /workflow:issue:* command set documentation ## New Scripts & Infrastructure - detect_changed_modules.sh: Git-based change detection with fallback strategies - get_modules_by_depth.sh: Hierarchical module discovery and organization - update_module_claude.sh: Core CLAUDE.md update execution engine ## Documentation Updates - **README.md**: Added comprehensive update-memory system documentation with usage examples - **README_CN.md**: Complete Chinese localization of new features and technical details - **Command reference tables**: Updated with new /update-memory-* commands and /workflow:issue:* set - **Technical highlights**: Enhanced with dual-mode operations and complexity thresholds - **Usage workflows**: Added detailed examples for different development scenarios ## Technical Improvements - Streamlined memory-gemini-bridge.md (reduced by 200+ lines) - Simplified gemini-unified.md workflow documentation - Added comprehensive CLAUDE.md files for new modules - Enhanced DMS (Distributed Memory System) with 4-layer hierarchy templates ## Architecture Enhancements - **Complexity thresholds**: related mode (>15 modules), full mode (>20 modules) - **Git integration**: Smart change detection with comprehensive status reporting - **User confirmation workflows**: Clear execution plans with mandatory approval steps - **Fallback strategies**: Graceful handling of non-git environments 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
97
.claude/scripts/detect_changed_modules.sh
Normal file
97
.claude/scripts/detect_changed_modules.sh
Normal file
@@ -0,0 +1,97 @@
|
||||
#!/bin/bash
|
||||
# Detect modules affected by git changes or recent modifications
|
||||
# Usage: detect_changed_modules.sh [format]
|
||||
# format: list|grouped|paths (default: paths)
|
||||
|
||||
detect_changed_modules() {
|
||||
local format="${1:-paths}"
|
||||
local changed_files=""
|
||||
local affected_dirs=""
|
||||
|
||||
# Step 1: Try to get git changes (staged + unstaged)
|
||||
if git rev-parse --git-dir > /dev/null 2>&1; then
|
||||
changed_files=$(git diff --name-only HEAD 2>/dev/null; git diff --name-only --cached 2>/dev/null)
|
||||
|
||||
# If no changes in working directory, check last commit
|
||||
if [ -z "$changed_files" ]; then
|
||||
changed_files=$(git diff --name-only HEAD~1 HEAD 2>/dev/null)
|
||||
fi
|
||||
fi
|
||||
|
||||
# Step 2: If no git changes, find recently modified source files (last 24 hours)
|
||||
if [ -z "$changed_files" ]; then
|
||||
changed_files=$(find . -type f \( \
|
||||
-name "*.md" -o \
|
||||
-name "*.js" -o -name "*.ts" -o -name "*.jsx" -o -name "*.tsx" -o \
|
||||
-name "*.py" -o -name "*.go" -o -name "*.rs" -o \
|
||||
-name "*.java" -o -name "*.cpp" -o -name "*.c" -o -name "*.h" -o \
|
||||
-name "*.sh" -o -name "*.ps1" -o \
|
||||
-name "*.json" -o -name "*.yaml" -o -name "*.yml" \
|
||||
\) -not -path '*/.*' -mtime -1 2>/dev/null)
|
||||
fi
|
||||
|
||||
# Step 3: Extract unique parent directories
|
||||
if [ -n "$changed_files" ]; then
|
||||
affected_dirs=$(echo "$changed_files" | \
|
||||
sed 's|/[^/]*$||' | \
|
||||
grep -v '^\.$' | \
|
||||
sort -u)
|
||||
|
||||
# Add current directory if files are in root
|
||||
if echo "$changed_files" | grep -q '^[^/]*$'; then
|
||||
affected_dirs=$(echo -e ".\n$affected_dirs" | sort -u)
|
||||
fi
|
||||
fi
|
||||
|
||||
# Step 4: Output in requested format
|
||||
case "$format" in
|
||||
"list")
|
||||
if [ -n "$affected_dirs" ]; then
|
||||
echo "$affected_dirs" | while read dir; do
|
||||
if [ -d "$dir" ]; then
|
||||
local file_count=$(find "$dir" -maxdepth 1 -type f 2>/dev/null | wc -l)
|
||||
local depth=$(echo "$dir" | tr -cd '/' | wc -c)
|
||||
if [ "$dir" = "." ]; then depth=0; fi
|
||||
|
||||
local types=$(find "$dir" -maxdepth 1 -type f -name "*.*" 2>/dev/null | \
|
||||
grep -E '\.[^/]*$' | sed 's/.*\.//' | sort -u | tr '\n' ',' | sed 's/,$//')
|
||||
echo "depth:$depth|path:$dir|files:$file_count|types:[$types]|status:changed"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
;;
|
||||
|
||||
"grouped")
|
||||
if [ -n "$affected_dirs" ]; then
|
||||
echo "📊 Affected modules by changes:"
|
||||
# Group by depth
|
||||
echo "$affected_dirs" | while read dir; do
|
||||
if [ -d "$dir" ]; then
|
||||
local depth=$(echo "$dir" | tr -cd '/' | wc -c)
|
||||
if [ "$dir" = "." ]; then depth=0; fi
|
||||
echo "$depth:$dir"
|
||||
fi
|
||||
done | sort -n | awk -F: '
|
||||
{
|
||||
if ($1 != prev_depth) {
|
||||
if (prev_depth != "") print ""
|
||||
print " 📁 Depth " $1 ":"
|
||||
prev_depth = $1
|
||||
}
|
||||
print " - " $2 " (changed)"
|
||||
}'
|
||||
else
|
||||
echo "📊 No recent changes detected"
|
||||
fi
|
||||
;;
|
||||
|
||||
"paths"|*)
|
||||
echo "$affected_dirs"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Execute function if script is run directly
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
detect_changed_modules "$@"
|
||||
fi
|
||||
106
.claude/scripts/get_modules_by_depth.sh
Normal file
106
.claude/scripts/get_modules_by_depth.sh
Normal file
@@ -0,0 +1,106 @@
|
||||
#!/bin/bash
|
||||
# Get modules organized by directory depth (deepest first)
|
||||
# Usage: get_modules_by_depth.sh [format]
|
||||
# format: list|grouped|json (default: list)
|
||||
|
||||
# Parse .gitignore patterns and build exclusion filters
|
||||
build_exclusion_filters() {
|
||||
local filters=""
|
||||
|
||||
# Always exclude these system/cache directories
|
||||
local system_excludes=(
|
||||
".git" ".history" ".vscode" "__pycache__" ".pytest_cache"
|
||||
"node_modules" "dist" "build" ".egg-info" ".env"
|
||||
)
|
||||
|
||||
for exclude in "${system_excludes[@]}"; do
|
||||
filters+=" -not -path '*/$exclude' -not -path '*/$exclude/*'"
|
||||
done
|
||||
|
||||
# Parse .gitignore if it exists
|
||||
if [ -f ".gitignore" ]; then
|
||||
while IFS= read -r line; do
|
||||
# Skip empty lines and comments
|
||||
[[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue
|
||||
|
||||
# Remove trailing slash and whitespace
|
||||
line=$(echo "$line" | sed 's|/$||' | xargs)
|
||||
|
||||
# Add to filters
|
||||
filters+=" -not -path '*/$line' -not -path '*/$line/*'"
|
||||
done < .gitignore
|
||||
fi
|
||||
|
||||
echo "$filters"
|
||||
}
|
||||
|
||||
get_modules_by_depth() {
|
||||
local format="${1:-list}"
|
||||
local exclusion_filters=$(build_exclusion_filters)
|
||||
local max_depth=$(eval "find . -type d $exclusion_filters 2>/dev/null" | awk -F/ '{print NF-1}' | sort -n | tail -1)
|
||||
|
||||
case "$format" in
|
||||
"grouped")
|
||||
echo "📊 Modules by depth (deepest first):"
|
||||
for depth in $(seq $max_depth -1 0); do
|
||||
local dirs=$(eval "find . -mindepth $depth -maxdepth $depth -type d $exclusion_filters 2>/dev/null" | \
|
||||
while read dir; do
|
||||
if [ $(find "$dir" -maxdepth 1 -type f 2>/dev/null | wc -l) -gt 0 ]; then
|
||||
local claude_indicator=""
|
||||
[ -f "$dir/CLAUDE.md" ] && claude_indicator=" [✓]"
|
||||
echo "$dir$claude_indicator"
|
||||
fi
|
||||
done)
|
||||
if [ -n "$dirs" ]; then
|
||||
echo " 📁 Depth $depth:"
|
||||
echo "$dirs" | sed 's/^/ - /'
|
||||
fi
|
||||
done
|
||||
;;
|
||||
|
||||
"json")
|
||||
echo "{"
|
||||
echo " \"max_depth\": $max_depth,"
|
||||
echo " \"modules\": {"
|
||||
for depth in $(seq $max_depth -1 0); do
|
||||
local dirs=$(eval "find . -mindepth $depth -maxdepth $depth -type d $exclusion_filters 2>/dev/null" | \
|
||||
while read dir; do
|
||||
if [ $(find "$dir" -maxdepth 1 -type f 2>/dev/null | wc -l) -gt 0 ]; then
|
||||
local has_claude="false"
|
||||
[ -f "$dir/CLAUDE.md" ] && has_claude="true"
|
||||
echo "{\"path\":\"$dir\",\"has_claude\":$has_claude}"
|
||||
fi
|
||||
done | tr '\n' ',')
|
||||
if [ -n "$dirs" ]; then
|
||||
dirs=${dirs%,} # Remove trailing comma
|
||||
echo " \"$depth\": [$dirs]"
|
||||
[ $depth -gt 0 ] && echo ","
|
||||
fi
|
||||
done
|
||||
echo " }"
|
||||
echo "}"
|
||||
;;
|
||||
|
||||
"list"|*)
|
||||
# Simple list format (deepest first)
|
||||
for depth in $(seq $max_depth -1 0); do
|
||||
eval "find . -mindepth $depth -maxdepth $depth -type d $exclusion_filters 2>/dev/null" | \
|
||||
while read dir; do
|
||||
if [ $(find "$dir" -maxdepth 1 -type f 2>/dev/null | wc -l) -gt 0 ]; then
|
||||
local file_count=$(find "$dir" -maxdepth 1 -type f 2>/dev/null | wc -l)
|
||||
local types=$(find "$dir" -maxdepth 1 -type f -name "*.*" 2>/dev/null | \
|
||||
grep -E '\.[^/]*$' | sed 's/.*\.//' | sort -u | tr '\n' ',' | sed 's/,$//')
|
||||
local has_claude="no"
|
||||
[ -f "$dir/CLAUDE.md" ] && has_claude="yes"
|
||||
echo "depth:$depth|path:$dir|files:$file_count|types:[$types]|has_claude:$has_claude"
|
||||
fi
|
||||
done
|
||||
done
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Execute function if script is run directly
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
get_modules_by_depth "$@"
|
||||
fi
|
||||
153
.claude/scripts/update_module_claude.sh
Normal file
153
.claude/scripts/update_module_claude.sh
Normal file
@@ -0,0 +1,153 @@
|
||||
#!/bin/bash
|
||||
# Update CLAUDE.md for a specific module with automatic layer detection
|
||||
# Usage: update_module_claude.sh <module_path> [update_type]
|
||||
# module_path: Path to the module directory
|
||||
# update_type: full|related (default: full)
|
||||
# Script automatically detects layer depth and selects appropriate template
|
||||
|
||||
update_module_claude() {
|
||||
local module_path="$1"
|
||||
local update_type="${2:-full}"
|
||||
|
||||
# Validate parameters
|
||||
if [ -z "$module_path" ]; then
|
||||
echo "❌ Error: Module path is required"
|
||||
echo "Usage: update_module_claude.sh <module_path> [update_type]"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$module_path" ]; then
|
||||
echo "❌ Error: Directory '$module_path' does not exist"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check if directory has files
|
||||
local file_count=$(find "$module_path" -maxdepth 1 -type f 2>/dev/null | wc -l)
|
||||
if [ $file_count -eq 0 ]; then
|
||||
echo "⚠️ Skipping '$module_path' - no files found"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Determine documentation layer based on path patterns
|
||||
local layer=""
|
||||
local template_path=""
|
||||
local analysis_strategy=""
|
||||
|
||||
# Clean path for pattern matching
|
||||
local clean_path=$(echo "$module_path" | sed 's|^\./||')
|
||||
|
||||
# Pattern-based layer detection
|
||||
if [ "$module_path" = "." ]; then
|
||||
# Root directory
|
||||
layer="Layer 1 (Root)"
|
||||
template_path="~/.claude/workflows/gemini-templates/prompts/dms/claude-layer1-root.txt"
|
||||
analysis_strategy="--all-files"
|
||||
elif [[ "$clean_path" =~ ^[^/]+$ ]]; then
|
||||
# Top-level directories (e.g., .claude, src, tests)
|
||||
layer="Layer 2 (Domain)"
|
||||
template_path="~/.claude/workflows/gemini-templates/prompts/dms/claude-layer2-domain.txt"
|
||||
analysis_strategy="@{*/CLAUDE.md}"
|
||||
elif [[ "$clean_path" =~ ^[^/]+/[^/]+$ ]]; then
|
||||
# Second-level directories (e.g., .claude/scripts, src/components)
|
||||
layer="Layer 3 (Module)"
|
||||
template_path="~/.claude/workflows/gemini-templates/prompts/dms/claude-layer3-module.txt"
|
||||
analysis_strategy="@{*/CLAUDE.md}"
|
||||
else
|
||||
# Deeper directories (e.g., .claude/workflows/gemini-templates/prompts)
|
||||
layer="Layer 4 (Sub-Module)"
|
||||
template_path="~/.claude/workflows/gemini-templates/prompts/dms/claude-layer4-submodule.txt"
|
||||
analysis_strategy="--all-files"
|
||||
fi
|
||||
|
||||
# Prepare logging info
|
||||
local module_name=$(basename "$module_path")
|
||||
|
||||
echo "⚡ Updating: $module_path"
|
||||
echo " Layer: $layer | Type: $update_type | Files: $file_count"
|
||||
echo " Template: $(basename "$template_path") | Strategy: $analysis_strategy"
|
||||
|
||||
# Generate prompt with template injection
|
||||
local template_content=""
|
||||
if [ -f "$template_path" ]; then
|
||||
template_content=$(cat "$template_path")
|
||||
else
|
||||
echo " ⚠️ Template not found: $template_path, using fallback"
|
||||
template_content="Update CLAUDE.md documentation for this module following hierarchy standards."
|
||||
fi
|
||||
|
||||
local update_context=""
|
||||
if [ "$update_type" = "full" ]; then
|
||||
update_context="
|
||||
Update Mode: Complete refresh
|
||||
- Perform comprehensive analysis of all content
|
||||
- Document patterns, architecture, and purpose
|
||||
- Consider existing documentation hierarchy
|
||||
- Follow template guidelines strictly"
|
||||
else
|
||||
update_context="
|
||||
Update Mode: Context-aware update
|
||||
- Focus on recent changes and affected areas
|
||||
- Maintain consistency with existing documentation
|
||||
- Update only relevant sections
|
||||
- Follow template guidelines for updated content"
|
||||
fi
|
||||
|
||||
local base_prompt="
|
||||
⚠️ CRITICAL RULES - MUST FOLLOW:
|
||||
1. ONLY modify CLAUDE.md files at any hierarchy level
|
||||
2. NEVER modify source code files
|
||||
3. Focus exclusively on updating documentation
|
||||
4. Follow the template guidelines exactly
|
||||
|
||||
$template_content
|
||||
|
||||
$update_context"
|
||||
|
||||
# Execute update
|
||||
local start_time=$(date +%s)
|
||||
echo " 🔄 Starting update..."
|
||||
|
||||
if cd "$module_path" 2>/dev/null; then
|
||||
# Execute gemini command with layer-specific analysis strategy
|
||||
local gemini_result=0
|
||||
if [ "$analysis_strategy" = "--all-files" ]; then
|
||||
gemini --all-files --yolo -p "$base_prompt
|
||||
|
||||
Module Information:
|
||||
- Name: $module_name
|
||||
- Path: $module_path
|
||||
- Layer: $layer
|
||||
- Analysis Strategy: $analysis_strategy" 2>&1
|
||||
gemini_result=$?
|
||||
else
|
||||
gemini --yolo -p "$analysis_strategy $base_prompt
|
||||
|
||||
Module Information:
|
||||
- Name: $module_name
|
||||
- Path: $module_path
|
||||
- Layer: $layer
|
||||
- Analysis Strategy: $analysis_strategy" 2>&1
|
||||
gemini_result=$?
|
||||
fi
|
||||
|
||||
if [ $gemini_result -eq 0 ]; then
|
||||
local end_time=$(date +%s)
|
||||
local duration=$((end_time - start_time))
|
||||
echo " ✅ Completed in ${duration}s"
|
||||
cd - > /dev/null
|
||||
return 0
|
||||
else
|
||||
echo " ❌ Update failed for $module_path"
|
||||
cd - > /dev/null
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
echo " ❌ Cannot access directory: $module_path"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Execute function if script is run directly
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
update_module_claude "$@"
|
||||
fi
|
||||
Reference in New Issue
Block a user