Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 701d3f10d9 | |||
| 5d69ad4f0b | |||
| db75b7deb0 |
@@ -106,6 +106,11 @@ if ! check_assets_present "."; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Create metadata directory and initialize manifest before copying
|
||||||
|
mkdir -p .mam
|
||||||
|
MANIFEST_FILE=".mam/install_manifest.txt"
|
||||||
|
touch "$MANIFEST_FILE"
|
||||||
|
|
||||||
# Copy ONLY runtime assets into the target, never overwriting an existing
|
# Copy ONLY runtime assets into the target, never overwriting an existing
|
||||||
# target file. We merge per-file (POSIX find + an explicit "[ ! -e ]" guard)
|
# target file. We merge per-file (POSIX find + an explicit "[ ! -e ]" guard)
|
||||||
# instead of `cp -n`: `cp -n` is non-portable and now prints a deprecation
|
# instead of `cp -n`: `cp -n` is non-portable and now prints a deprecation
|
||||||
@@ -117,6 +122,7 @@ if ! check_assets_present "."; then
|
|||||||
if [ ! -e "$dest" ]; then
|
if [ ! -e "$dest" ]; then
|
||||||
mkdir -p "$(dirname "$dest")"
|
mkdir -p "$(dirname "$dest")"
|
||||||
cp "$STAGE_DIR/.agents/$rel" "$dest" || { echo "❌ Error: Failed to copy $rel" >&2; exit 1; }
|
cp "$STAGE_DIR/.agents/$rel" "$dest" || { echo "❌ Error: Failed to copy $rel" >&2; exit 1; }
|
||||||
|
echo "$dest" >> "$MANIFEST_FILE"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -125,11 +131,25 @@ if ! check_assets_present "."; then
|
|||||||
for doc in AGENT.md AGENT.ko.md MESSAGING.md BOOTSTRAP.md BOOTSTRAP.ko.md INSTRUCTION.md; do
|
for doc in AGENT.md AGENT.ko.md MESSAGING.md BOOTSTRAP.md BOOTSTRAP.ko.md INSTRUCTION.md; do
|
||||||
if [ -f "$STAGE_DIR/$doc" ] && [ ! -e "$doc" ]; then
|
if [ -f "$STAGE_DIR/$doc" ] && [ ! -e "$doc" ]; then
|
||||||
cp "$STAGE_DIR/$doc" . || { echo "❌ Error: Failed to copy $doc" >&2; exit 1; }
|
cp "$STAGE_DIR/$doc" . || { echo "❌ Error: Failed to copy $doc" >&2; exit 1; }
|
||||||
|
echo "$doc" >> "$MANIFEST_FILE"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if [ -f "$STAGE_DIR/deploy/remove.sh" ] && [ ! -e "remove.sh" ]; then
|
||||||
|
cp "$STAGE_DIR/deploy/remove.sh" remove.sh || { echo "❌ Error: Failed to copy remove.sh" >&2; exit 1; }
|
||||||
|
chmod +x remove.sh
|
||||||
|
echo "remove.sh" >> "$MANIFEST_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$STAGE_DIR/deploy/update.sh" ] && [ ! -e "update.sh" ]; then
|
||||||
|
cp "$STAGE_DIR/deploy/update.sh" update.sh || { echo "❌ Error: Failed to copy update.sh" >&2; exit 1; }
|
||||||
|
chmod +x update.sh
|
||||||
|
echo "update.sh" >> "$MANIFEST_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -f "$STAGE_DIR/.env.example" ] && [ ! -e ".env.example" ]; then
|
if [ -f "$STAGE_DIR/.env.example" ] && [ ! -e ".env.example" ]; then
|
||||||
cp "$STAGE_DIR/.env.example" . || { echo "❌ Error: Failed to copy .env.example" >&2; exit 1; }
|
cp "$STAGE_DIR/.env.example" . || { echo "❌ Error: Failed to copy .env.example" >&2; exit 1; }
|
||||||
|
echo ".env.example" >> "$MANIFEST_FILE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -rf "$STAGE_DIR"
|
rm -rf "$STAGE_DIR"
|
||||||
@@ -220,6 +240,11 @@ TMUX_SERVER_NAME=default
|
|||||||
EOF
|
EOF
|
||||||
chmod 0600 "$ENV_FILE"
|
chmod 0600 "$ENV_FILE"
|
||||||
echo "✅ Config file .env initialized with chmod 0600."
|
echo "✅ Config file .env initialized with chmod 0600."
|
||||||
|
|
||||||
|
# Record the newly created .env in the manifest
|
||||||
|
mkdir -p .mam
|
||||||
|
touch .mam/install_manifest.txt
|
||||||
|
echo "$ENV_FILE" >> .mam/install_manifest.txt
|
||||||
else
|
else
|
||||||
echo "ℹ️ $ENV_FILE already exists. Skipping config override."
|
echo "ℹ️ $ENV_FILE already exists. Skipping config override."
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -0,0 +1,211 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# ==============================================================================
|
||||||
|
# remove.sh — Multi-Agent Mux (MAM) Orchestration Uninstaller
|
||||||
|
# ==============================================================================
|
||||||
|
# Safely removes MAM orchestration skills, virtual environment, and metadata.
|
||||||
|
# Leaves pre-existing user configurations and files untouched by reading
|
||||||
|
# the installation manifest (.mam/install_manifest.txt).
|
||||||
|
# ==============================================================================
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
TARGET_DIR=""
|
||||||
|
FORCE=0
|
||||||
|
PURGE_ENV=0
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
-y|--yes|--force)
|
||||||
|
FORCE=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--purge-env)
|
||||||
|
PURGE_ENV=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
TARGET_DIR="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$TARGET_DIR" ]; then
|
||||||
|
TARGET_DIR="$(pwd)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "===================================================================="
|
||||||
|
echo "⚡ Starting Multi-Agent Mux (MAM) Uninstallation"
|
||||||
|
echo "📂 Target Workspace: $TARGET_DIR"
|
||||||
|
echo "===================================================================="
|
||||||
|
|
||||||
|
if [ ! -d "$TARGET_DIR" ]; then
|
||||||
|
echo "❌ Error: Target directory '$TARGET_DIR' does not exist." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$TARGET_DIR"
|
||||||
|
|
||||||
|
# 1. Non-interactive input safety guard (set -e read crash prevention)
|
||||||
|
if [ ! -t 0 ] && [ $FORCE -eq 0 ]; then
|
||||||
|
echo "❌ Error: Non-interactive terminal detected. Please run with -y/--yes/--force." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if there is anything to remove
|
||||||
|
MANIFEST_FILE=".mam/install_manifest.txt"
|
||||||
|
any_exist=0
|
||||||
|
manifest_files=()
|
||||||
|
|
||||||
|
# Load the install manifest if it exists
|
||||||
|
if [ -f "$MANIFEST_FILE" ]; then
|
||||||
|
any_exist=1
|
||||||
|
while IFS= read -r line; do
|
||||||
|
if [ -n "$line" ]; then
|
||||||
|
manifest_files+=("$line")
|
||||||
|
fi
|
||||||
|
done < "$MANIFEST_FILE"
|
||||||
|
else
|
||||||
|
# Fallback to the core MAM directories to check if any exist
|
||||||
|
fallback_assets=(
|
||||||
|
".agents/skills/lib.sh"
|
||||||
|
".agents/skills/multi-agent-mux-create"
|
||||||
|
".agents/skills/multi-agent-mux-delegate-job"
|
||||||
|
".agents/skills/multi-agent-mux-monitor"
|
||||||
|
".agents/skills/multi-agent-mux-resume"
|
||||||
|
".agents/skills/multi-agent-mux-status"
|
||||||
|
".agents/skills/multi-agent-mux-stop"
|
||||||
|
".venv"
|
||||||
|
".mam"
|
||||||
|
)
|
||||||
|
for asset in "${fallback_assets[@]}"; do
|
||||||
|
if [ -e "$asset" ] || [ -h "$asset" ]; then
|
||||||
|
any_exist=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $any_exist -eq 0 ]; then
|
||||||
|
echo "ℹ️ No MAM assets detected in '$TARGET_DIR'. Nothing to do."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Request confirmation if not forced
|
||||||
|
if [ $FORCE -eq 0 ]; then
|
||||||
|
echo "⚠️ WARNING: This will permanently remove the MAM orchestration skills, "
|
||||||
|
echo " virtual environment (.venv), local metadata (.mam), and docs."
|
||||||
|
echo " (Your own custom files inside .agents/ will NOT be touched)."
|
||||||
|
|
||||||
|
if ! read -p "❓ Are you sure you want to proceed? [y/N]: " -r response; then
|
||||||
|
response="n"
|
||||||
|
fi
|
||||||
|
if [[ ! "$response" =~ ^[yY](es)?$ ]]; then
|
||||||
|
echo "❌ Uninstallation cancelled by user."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
delete_asset() {
|
||||||
|
local asset="$1"
|
||||||
|
if [ -e "$asset" ] || [ -h "$asset" ]; then
|
||||||
|
echo "🗑️ Removing: $asset"
|
||||||
|
rm -rf "$asset"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 2. Uninstall files using the manifest if present
|
||||||
|
if [ ${#manifest_files[@]} -gt 0 ]; then
|
||||||
|
echo "📜 Manifest found. Reversing installer-created files..."
|
||||||
|
for f in ${manifest_files[@]+"${manifest_files[@]}"}; do
|
||||||
|
# Skip .env and remove.sh for now, they are handled separately
|
||||||
|
if [ "$f" = ".env" ] || [ "$f" = "remove.sh" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
delete_asset "$f"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
# Fallback: Delete MAM skills manually (only if manifest is missing)
|
||||||
|
echo "⚠️ No manifest found. Deleting standard MAM skills..."
|
||||||
|
delete_asset ".agents/skills/lib.sh"
|
||||||
|
delete_asset ".agents/skills/multi-agent-mux-create"
|
||||||
|
delete_asset ".agents/skills/multi-agent-mux-delegate-job"
|
||||||
|
delete_asset ".agents/skills/multi-agent-mux-monitor"
|
||||||
|
delete_asset ".agents/skills/multi-agent-mux-resume"
|
||||||
|
delete_asset ".agents/skills/multi-agent-mux-status"
|
||||||
|
delete_asset ".agents/skills/multi-agent-mux-stop"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 3. Clean up empty parent directories under .agents recursively to avoid littering
|
||||||
|
if [ -d ".agents" ]; then
|
||||||
|
find .agents -depth -type d -exec rmdir {} + 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 4. Remove virtual environment, monitor cache, and metadata database
|
||||||
|
delete_asset ".venv"
|
||||||
|
delete_asset ".cache/multi-agent-mux-monitor"
|
||||||
|
delete_asset ".mam" # Deletes manifest file too
|
||||||
|
|
||||||
|
# 5. Clean up .env file (Only if created by installer, or forced with --purge-env)
|
||||||
|
# If .env is in manifest, it means MAM created it.
|
||||||
|
env_created_by_mam=0
|
||||||
|
for f in ${manifest_files[@]+"${manifest_files[@]}"}; do
|
||||||
|
if [ "$f" = ".env" ]; then
|
||||||
|
env_created_by_mam=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -f ".env" ]; then
|
||||||
|
should_delete_env=0
|
||||||
|
if [ $PURGE_ENV -eq 1 ]; then
|
||||||
|
should_delete_env=1
|
||||||
|
elif [ $env_created_by_mam -eq 1 ]; then
|
||||||
|
# Even if MAM created it, ask or rename to backup to prevent loss of custom secrets
|
||||||
|
if [ $FORCE -eq 1 ]; then
|
||||||
|
should_delete_env=1
|
||||||
|
else
|
||||||
|
if ! read -p "❓ MAM-created '.env' found. Delete it? (Saying No preserves it) [y/N]: " -r env_response; then
|
||||||
|
env_response="n"
|
||||||
|
fi
|
||||||
|
if [[ "$env_response" =~ ^[yY](es)?$ ]]; then
|
||||||
|
should_delete_env=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $should_delete_env -eq 1 ]; then
|
||||||
|
delete_asset ".env"
|
||||||
|
else
|
||||||
|
if [ $env_created_by_mam -eq 1 ]; then
|
||||||
|
backup_name=".env.mam-backup"
|
||||||
|
if [ -e "$backup_name" ]; then
|
||||||
|
backup_name=".env.mam-backup.$(date +%Y%m%d%H%M%S)"
|
||||||
|
fi
|
||||||
|
echo "💾 Backing up .env configuration to $backup_name..."
|
||||||
|
mv ".env" "$backup_name"
|
||||||
|
else
|
||||||
|
echo "ℹ️ Preserving user-owned .env configuration."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 6. Remove uninstaller file itself (if we are in the target root)
|
||||||
|
# Simple check: only delete remove.sh if it is recorded in the manifest
|
||||||
|
remove_in_manifest=0
|
||||||
|
for f in ${manifest_files[@]+"${manifest_files[@]}"}; do
|
||||||
|
if [ "$f" = "remove.sh" ]; then
|
||||||
|
remove_in_manifest=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -f "remove.sh" ] && [ $remove_in_manifest -eq 1 ]; then
|
||||||
|
echo "🗑️ Removing uninstaller: remove.sh"
|
||||||
|
# Self-delete is the final action
|
||||||
|
rm -f "remove.sh"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "===================================================================="
|
||||||
|
echo "🎉 Uninstallation complete!"
|
||||||
|
echo "===================================================================="
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# ==============================================================================
|
||||||
|
# update.sh — Multi-Agent Mux (MAM) Orchestration Updater
|
||||||
|
# ==============================================================================
|
||||||
|
# Safely updates MAM skills, virtual environment, and docs to the latest version.
|
||||||
|
# Preserves user configuration (.env) and local metadata/jobs database (.mam).
|
||||||
|
# ==============================================================================
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
TARGET_DIR=""
|
||||||
|
FORCE=0
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
-y|--yes|--force)
|
||||||
|
FORCE=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
TARGET_DIR="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$TARGET_DIR" ]; then
|
||||||
|
TARGET_DIR="$(pwd)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "===================================================================="
|
||||||
|
echo "⚡ Starting Multi-Agent Mux (MAM) Update"
|
||||||
|
echo "📂 Target Workspace: $TARGET_DIR"
|
||||||
|
echo "===================================================================="
|
||||||
|
|
||||||
|
if [ ! -d "$TARGET_DIR" ]; then
|
||||||
|
echo "❌ Error: Target directory '$TARGET_DIR' does not exist." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$TARGET_DIR"
|
||||||
|
|
||||||
|
# 1. Verification of existing install
|
||||||
|
if [ ! -f "remove.sh" ]; then
|
||||||
|
echo "❌ Error: No MAM installation (remove.sh) found in '$TARGET_DIR'." >&2
|
||||||
|
echo " Please run install.sh first to set up the workspace." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Request confirmation if not forced
|
||||||
|
if [ $FORCE -eq 0 ]; then
|
||||||
|
echo "⚠️ WARNING: This will update MAM orchestration skills, virtual environment, "
|
||||||
|
echo " and docs to the latest version."
|
||||||
|
echo " (Your configuration, job history, and custom skills will be preserved)."
|
||||||
|
if [ ! -t 0 ]; then
|
||||||
|
echo "❌ Error: Non-interactive terminal detected. Please run with -y/--yes/--force." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! read -p "❓ Proceed with update? [y/N]: " -r response; then
|
||||||
|
response="n"
|
||||||
|
fi
|
||||||
|
if [[ ! "$response" =~ ^[yY](es)?$ ]]; then
|
||||||
|
echo "❌ Update cancelled by user."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. Stage backups of user configurations and metadata to prevent deletion
|
||||||
|
echo "💾 Backing up configuration and database..."
|
||||||
|
HAS_ENV=0
|
||||||
|
if [ -f ".env" ]; then
|
||||||
|
HAS_ENV=1
|
||||||
|
mv ".env" ".env.update-tmp"
|
||||||
|
fi
|
||||||
|
|
||||||
|
HAS_MAM=0
|
||||||
|
if [ -d ".mam" ]; then
|
||||||
|
HAS_MAM=1
|
||||||
|
# Move .mam out of the way of remove.sh
|
||||||
|
mv ".mam" ".mam.update-tmp"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 3. Perform uninstallation of existing files
|
||||||
|
echo "🗑️ Removing existing installation..."
|
||||||
|
bash remove.sh --force
|
||||||
|
|
||||||
|
# 4. Fetch and run the latest installer from Gitea
|
||||||
|
echo "📥 Fetching and running the latest installer..."
|
||||||
|
INSTALLER_URL="https://git.godopu.com/tmpl/multi-agent-mux/raw/branch/main/deploy/install.sh"
|
||||||
|
if command -v curl &>/dev/null; then
|
||||||
|
curl -fsSL "$INSTALLER_URL" | bash -s -- "$TARGET_DIR"
|
||||||
|
elif command -v wget &>/dev/null; then
|
||||||
|
wget -qO- "$INSTALLER_URL" | bash -s -- "$TARGET_DIR"
|
||||||
|
else
|
||||||
|
echo "❌ Error: Neither 'curl' nor 'wget' is available to fetch the installer." >&2
|
||||||
|
|
||||||
|
# Restore backups before failing
|
||||||
|
if [ $HAS_ENV -eq 1 ]; then mv ".env.update-tmp" ".env"; fi
|
||||||
|
if [ $HAS_MAM -eq 1 ]; then mv ".mam.update-tmp" ".mam"; fi
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 5. Restore backups of configuration and database
|
||||||
|
echo "🔄 Restoring configuration and database..."
|
||||||
|
if [ $HAS_ENV -eq 1 ]; then
|
||||||
|
# Overwrite the default .env created by installer (if any) with the user's backup
|
||||||
|
mv -f ".env.update-tmp" ".env"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $HAS_MAM -eq 1 ]; then
|
||||||
|
# The installer created a new .mam directory with a new manifest.
|
||||||
|
# We want to merge the old .mam database/jobs back while keeping the new manifest.
|
||||||
|
if [ -d ".mam.update-tmp" ]; then
|
||||||
|
# Copy SQLite databases
|
||||||
|
for db in .mam.update-tmp/db.sqlite*; do
|
||||||
|
if [ -f "$db" ]; then
|
||||||
|
cp -f "$db" .mam/
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
# Copy jobs history
|
||||||
|
if [ -d ".mam.update-tmp/jobs" ] && [ "$(ls -A .mam.update-tmp/jobs 2>/dev/null)" ]; then
|
||||||
|
mkdir -p .mam/jobs
|
||||||
|
cp -rf .mam.update-tmp/jobs/* .mam/jobs/
|
||||||
|
fi
|
||||||
|
# Copy delegate logs
|
||||||
|
if [ -d ".mam.update-tmp/delegate_job_logs" ] && [ "$(ls -A .mam.update-tmp/delegate_job_logs 2>/dev/null)" ]; then
|
||||||
|
mkdir -p .mam/delegate_job_logs
|
||||||
|
cp -rf .mam.update-tmp/delegate_job_logs/* .mam/delegate_job_logs/
|
||||||
|
fi
|
||||||
|
# Clean up the backup directory
|
||||||
|
rm -rf ".mam.update-tmp"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "===================================================================="
|
||||||
|
echo "🎉 Update complete!"
|
||||||
|
echo "===================================================================="
|
||||||
Reference in New Issue
Block a user