Implement all 5 tasks: additive extension model, framework self-enforcement, changelog, project migration, dashboard review
This commit is contained in:
Executable
+125
@@ -0,0 +1,125 @@
|
||||
#!/bin/bash
|
||||
# Migrate a project from the old copy-based model to the additive extension model.
|
||||
# Usage: ./migrate-project.sh /path/to/project
|
||||
set -e
|
||||
|
||||
FRAMEWORK_DIR="$HOME/.automaton"
|
||||
PROJECT_DIR="${1}"
|
||||
|
||||
if [ -z "$PROJECT_DIR" ]; then
|
||||
echo "Usage: $0 /path/to/project"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PROJECT_AUTOMATON="$PROJECT_DIR/.automaton"
|
||||
|
||||
if [ ! -d "$PROJECT_AUTOMATON" ]; then
|
||||
echo "No .automaton/ directory found at $PROJECT_AUTOMATON"
|
||||
echo "Nothing to migrate."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
EXTENSIONS_DIR="$PROJECT_AUTOMATON/extensions"
|
||||
DELETED=()
|
||||
MOVED=()
|
||||
KEPT=()
|
||||
ERRORS=()
|
||||
|
||||
# Directories in the framework that projects may have copied
|
||||
SCAN_DIRS=("prompts" "contracts" "scripts")
|
||||
|
||||
# Function to diff a file with its global counterpart
|
||||
diff_file() {
|
||||
local project_file="$1"
|
||||
local global_file="$2"
|
||||
if [ ! -f "$global_file" ]; then
|
||||
return 2 # file doesn't exist in global
|
||||
fi
|
||||
if diff -q "$project_file" "$global_file" >/dev/null 2>&1; then
|
||||
return 0 # identical
|
||||
else
|
||||
return 1 # different
|
||||
fi
|
||||
}
|
||||
|
||||
# Check root-level framework files
|
||||
echo "Scanning $PROJECT_AUTOMATON for stale framework files..."
|
||||
echo ""
|
||||
|
||||
for dir in "${SCAN_DIRS[@]}"; do
|
||||
project_dir="$PROJECT_AUTOMATON/$dir"
|
||||
global_dir="$FRAMEWORK_DIR/$dir"
|
||||
|
||||
if [ ! -d "$project_dir" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Find all files in the project's copy of this directory
|
||||
while IFS= read -r -d '' project_file; do
|
||||
rel_path="${project_file#$PROJECT_AUTOMATON/}"
|
||||
global_file="$FRAMEWORK_DIR/$rel_path"
|
||||
|
||||
if diff_file "$project_file" "$global_file"; then
|
||||
# Identical to global — safe to delete
|
||||
rm "$project_file"
|
||||
DELETED+=("$rel_path")
|
||||
echo " DELETED $rel_path (identical to global)"
|
||||
elif [ $? -eq 1 ]; then
|
||||
# Different from global — move to extensions/
|
||||
ext_path="$EXTENSIONS_DIR/$dir/$(basename "$project_file")"
|
||||
mkdir -p "$(dirname "$ext_path")"
|
||||
mv "$project_file" "$ext_path"
|
||||
MOVED+=("$rel_path -> extensions/$dir/$(basename "$project_file")")
|
||||
echo " MOVED $rel_path → extensions/$dir/$(basename "$project_file") (customized)"
|
||||
fi
|
||||
done < <(find "$project_dir" -type f -print0 2>/dev/null || true)
|
||||
|
||||
# Remove empty directories after moving/deleting files
|
||||
rmdir "$project_dir" 2>/dev/null || true
|
||||
done
|
||||
|
||||
# Check for other stale root-level files (templates/, references/, etc.)
|
||||
while IFS= read -r -d '' project_file; do
|
||||
rel_path="${project_file#$PROJECT_AUTOMATON/}"
|
||||
global_file="$FRAMEWORK_DIR/$rel_path"
|
||||
|
||||
# Skip protected files
|
||||
basename_file=$(basename "$rel_path")
|
||||
if [ "$basename_file" = ".agent.md" ] || [ "$basename_file" = ".rules.md" ]; then
|
||||
KEPT+=("$rel_path")
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ ! -f "$global_file" ]; then
|
||||
continue # not a framework file, skip
|
||||
fi
|
||||
|
||||
if diff_file "$project_file" "$global_file"; then
|
||||
rm "$project_file"
|
||||
DELETED+=("$rel_path")
|
||||
echo " DELETED $rel_path (identical to global)"
|
||||
elif [ $? -eq 1 ]; then
|
||||
ext_path="$EXTENSIONS_DIR/$(basename "$rel_path")"
|
||||
mkdir -p "$(dirname "$ext_path")"
|
||||
mv "$project_file" "$ext_path"
|
||||
MOVED+=("$rel_path -> extensions/$(basename "$rel_path")")
|
||||
echo " MOVED $rel_path → extensions/$(basename "$rel_path") (customized)"
|
||||
fi
|
||||
done < <(find "$PROJECT_AUTOMATON" -maxdepth 1 -type f -name "*.md" -o -name "*.sh" -print0 2>/dev/null || true)
|
||||
|
||||
# Report
|
||||
echo ""
|
||||
echo "=== Migration Summary ==="
|
||||
echo " Deleted: ${#DELETED[@]} (identical to global, removed)"
|
||||
echo " Moved: ${#MOVED[@]} (customized, moved to extensions/)"
|
||||
echo " Kept: ${#KEPT[@]} (.agent.md and .rules.md preserved)"
|
||||
|
||||
if [ ${#ERRORS[@]} -gt 0 ]; then
|
||||
echo " Errors: ${#ERRORS[@]}"
|
||||
for err in "${ERRORS[@]}"; do
|
||||
echo " - $err"
|
||||
done
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Migration complete."
|
||||
+2
-20
@@ -19,26 +19,8 @@ if [ ! -d ".git" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Fetch latest changes
|
||||
git fetch origin
|
||||
echo ""
|
||||
|
||||
# Check for local changes
|
||||
if ! git diff --quiet HEAD; then
|
||||
echo "WARNING: You have uncommitted changes in $FRAMEWORK_DIR."
|
||||
echo "These will be lost when pulling updates."
|
||||
read -p "Do you want to discard your local changes and update? (y/N) " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Update cancelled."
|
||||
exit 1
|
||||
fi
|
||||
git reset --hard HEAD
|
||||
fi
|
||||
|
||||
# Pull latest changes
|
||||
# Fetch and pull latest changes
|
||||
git pull origin main
|
||||
echo ""
|
||||
|
||||
echo ""
|
||||
echo "Update complete."
|
||||
echo "You can check for breaking changes at: https://gitea.yourdomain.com/hermes/automaton"
|
||||
|
||||
Reference in New Issue
Block a user