feat(templates): add import/export system for agent systems
This commit is contained in:
parent
efbdbd82ed
commit
ea3ff53d2c
4 changed files with 372 additions and 0 deletions
147
scripts/templates/transfer/import-system.sh
Normal file
147
scripts/templates/transfer/import-system.sh
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
#!/bin/bash
|
||||
# Agent Factory — import-system.sh
|
||||
# Imports an exported agent system tarball into the current project.
|
||||
# Usage: bash import-system.sh <tarball> [--force]
|
||||
# Bash 3.2 compatible.
|
||||
|
||||
set -e
|
||||
|
||||
TARBALL="$1"
|
||||
FORCE="${2:-}"
|
||||
STAGING_DIR="/tmp/agent-import-$$"
|
||||
|
||||
if [ -z "$TARBALL" ]; then
|
||||
echo "Usage: bash import-system.sh <agent-system-*.tar.gz> [--force]" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$TARBALL" ]; then
|
||||
echo "ERROR: File not found: $TARBALL" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[import] Importing: $TARBALL"
|
||||
|
||||
mkdir -p "$STAGING_DIR"
|
||||
tar -xzf "$TARBALL" -C "$STAGING_DIR"
|
||||
|
||||
# Read MANIFEST.md
|
||||
MANIFEST="${STAGING_DIR}/MANIFEST.md"
|
||||
if [ ! -f "$MANIFEST" ]; then
|
||||
echo "ERROR: No MANIFEST.md found in tarball — may not be a valid Agent Factory export" >&2
|
||||
rm -rf "$STAGING_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[import] Manifest found:"
|
||||
head -5 "$MANIFEST"
|
||||
echo ""
|
||||
|
||||
# Check for conflicts (existing files in destination)
|
||||
CONFLICTS=""
|
||||
find "$STAGING_DIR" -type f | sort | while read -r fpath; do
|
||||
rel="${fpath#${STAGING_DIR}/}"
|
||||
dest="${PWD}/${rel}"
|
||||
if [ -f "$dest" ] && [ "$FORCE" != "--force" ]; then
|
||||
echo "[import] CONFLICT: $rel already exists"
|
||||
CONFLICTS="yes"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$CONFLICTS" ] && [ "$FORCE" != "--force" ]; then
|
||||
echo ""
|
||||
echo "Conflicts detected. Re-run with --force to overwrite, or remove conflicting files first." >&2
|
||||
rm -rf "$STAGING_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract files to project
|
||||
echo "[import] Extracting files"
|
||||
find "$STAGING_DIR" -type f | sort | while read -r fpath; do
|
||||
rel="${fpath#${STAGING_DIR}/}"
|
||||
dest="${PWD}/${rel}"
|
||||
destdir="$(dirname "$dest")"
|
||||
mkdir -p "$destdir"
|
||||
cp "$fpath" "$dest"
|
||||
echo "[import] Wrote: $rel"
|
||||
done
|
||||
|
||||
# Replace {{PLACEHOLDER}} variables
|
||||
echo "[import] Replacing placeholders"
|
||||
PROJECT_DIR="$(pwd)"
|
||||
PROJECT_NAME="$(basename "$PROJECT_DIR")"
|
||||
|
||||
find "$PROJECT_DIR/.claude" "$PROJECT_DIR/automation" "$PROJECT_DIR/hooks" \
|
||||
"$PROJECT_DIR/CLAUDE.md" -type f 2>/dev/null | while read -r fpath; do
|
||||
case "$fpath" in
|
||||
*.sh|*.md|*.json|*.yml|*.yaml)
|
||||
python3 - "$fpath" "$PROJECT_DIR" "$PROJECT_NAME" << 'PYEOF'
|
||||
import sys, re
|
||||
path, project_dir, project_name = sys.argv[1], sys.argv[2], sys.argv[3]
|
||||
try:
|
||||
with open(path, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
content = content.replace('{{PROJECT_DIR}}', project_dir)
|
||||
content = content.replace('{{PROJECT_NAME}}', project_name)
|
||||
with open(path, 'w', encoding='utf-8') as f:
|
||||
f.write(content)
|
||||
except Exception:
|
||||
pass
|
||||
PYEOF
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Make .sh files executable
|
||||
echo "[import] Setting executable permissions"
|
||||
find "$PROJECT_DIR/.claude/hooks" "$PROJECT_DIR/hooks" "$PROJECT_DIR/automation" \
|
||||
-name "*.sh" -type f 2>/dev/null | while read -r fpath; do
|
||||
chmod +x "$fpath"
|
||||
echo "[import] chmod +x: $fpath"
|
||||
done
|
||||
|
||||
# Validate frontmatter in agent files
|
||||
echo "[import] Validating agent frontmatter"
|
||||
INVALID_AGENTS=""
|
||||
if [ -d "$PROJECT_DIR/.claude/agents" ]; then
|
||||
for agent in "$PROJECT_DIR/.claude/agents"/*.md; do
|
||||
[ -f "$agent" ] || continue
|
||||
python3 - "$agent" << 'PYEOF'
|
||||
import sys, re
|
||||
path = sys.argv[1]
|
||||
try:
|
||||
with open(path, 'r') as f:
|
||||
content = f.read()
|
||||
if not content.startswith('---'):
|
||||
print(f"WARN: {path} missing YAML frontmatter")
|
||||
sys.exit(0)
|
||||
parts = content.split('---', 2)
|
||||
if len(parts) < 3:
|
||||
print(f"WARN: {path} malformed frontmatter")
|
||||
except Exception as e:
|
||||
print(f"WARN: {path} could not be validated: {e}")
|
||||
PYEOF
|
||||
done
|
||||
fi
|
||||
|
||||
# Validate bash syntax on hook scripts
|
||||
echo "[import] Validating hook syntax"
|
||||
if [ -d "$PROJECT_DIR/.claude/hooks" ]; then
|
||||
for script in "$PROJECT_DIR/.claude/hooks"/*.sh; do
|
||||
[ -f "$script" ] || continue
|
||||
if bash -n "$script" 2>/dev/null; then
|
||||
echo "[import] OK: $script"
|
||||
else
|
||||
echo "[import] WARN: $script failed bash -n check"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
rm -rf "$STAGING_DIR"
|
||||
|
||||
echo ""
|
||||
echo "[import] Import complete."
|
||||
echo "[import] Next steps:"
|
||||
echo " 1. Review CLAUDE.md and update project-specific sections"
|
||||
echo " 2. Add your ANTHROPIC_API_KEY to .env"
|
||||
echo " 3. Run /agent-factory:status to verify the system"
|
||||
Loading…
Add table
Add a link
Reference in a new issue