feat(templates): add import/export system for agent systems

This commit is contained in:
Kjell Tore Guttormsen 2026-04-12 06:47:14 +02:00
commit ea3ff53d2c
4 changed files with 372 additions and 0 deletions

View 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"