feat: add force-refresh capability and allow framework-owned skill updates during installation
This commit is contained in:
+66
-18
@@ -8,10 +8,43 @@
|
||||
set -euo pipefail
|
||||
|
||||
# --- Configuration & Defaults ---
|
||||
TARGET_DIR="${1:-$(pwd)}"
|
||||
TARGET_DIR=""
|
||||
FORCE_REFRESH="${MAM_FORCE_REFRESH:-0}"
|
||||
VENV_NAME=".venv"
|
||||
MIN_PYTHON_VERSION="3.9"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-f|--force|--refresh-skills)
|
||||
FORCE_REFRESH=1
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
cat <<EOF
|
||||
Usage: $0 [options] [target_dir]
|
||||
|
||||
Options:
|
||||
-f, --force, --refresh-skills Force fetch and refresh framework skills under .agents/skills/
|
||||
-h, --help Show this help message
|
||||
EOF
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
if [ -z "$TARGET_DIR" ]; then
|
||||
TARGET_DIR="$1"
|
||||
else
|
||||
echo "❌ Error: Unknown argument: $1" >&2
|
||||
exit 1
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$TARGET_DIR" ]; then
|
||||
TARGET_DIR="$(pwd)"
|
||||
fi
|
||||
|
||||
echo "===================================================================="
|
||||
echo "⚡ Starting Multi-Agent Mux (MAM) Installation"
|
||||
echo "📂 Target Workspace: $TARGET_DIR"
|
||||
@@ -76,17 +109,24 @@ check_assets_present() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# Fetch the orchestration assets if missing or incomplete (for curl one-liner installs).
|
||||
# Helper to classify framework-owned skill definitions vs user-owned project assets
|
||||
is_framework_owned() {
|
||||
case "$1" in
|
||||
.agents/skills/*) return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Fetch the orchestration assets if missing or if skill refresh is requested.
|
||||
#
|
||||
# Safety model (FW-D1): we NEVER extract the repo archive directly into the
|
||||
# target. Running inside an existing project must not overwrite the target's
|
||||
# own files (README.md, FUTURE_WORKS.md, …) or litter it with this repo's
|
||||
# development docs. Instead we stage the download into a throwaway temp dir,
|
||||
# verify it, then copy ONLY the runtime assets (.agents/, documents, .env.example)
|
||||
# into the target with per-file no-clobber guards so a pre-existing target file
|
||||
# always wins.
|
||||
if ! check_assets_present "."; then
|
||||
echo "📥 Orchestration skills not found or incomplete. Fetching from Gitea repository..."
|
||||
# own files (README.md, FUTURE_WORKS.md, AGENTS.md, MULTI_AGENT_RULES.md) or litter
|
||||
# it with development docs. Instead we stage the download into a throwaway temp dir,
|
||||
# verify it, then copy runtime assets: framework skills (.agents/skills/*) are updated,
|
||||
# while user-owned documents use per-file no-clobber guards so pre-existing target files win.
|
||||
if [ "$FORCE_REFRESH" -eq 1 ] || ! check_assets_present "."; then
|
||||
echo "📥 Staging orchestration assets from Gitea repository..."
|
||||
STAGE_DIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$STAGE_DIR"' EXIT
|
||||
|
||||
@@ -112,18 +152,26 @@ if ! check_assets_present "."; then
|
||||
MANIFEST_FILE=".mam/install_manifest.txt"
|
||||
touch "$MANIFEST_FILE"
|
||||
|
||||
# Copy ONLY runtime assets into the target, never overwriting an existing
|
||||
# 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
|
||||
# warning on GNU coreutils 9.x, whereas the explicit guard is portable to
|
||||
# BSD/macOS and makes the no-clobber intent obvious.
|
||||
# Copy runtime assets (.agents/) into the target workspace.
|
||||
# Framework-owned skill files (.agents/skills/*) are updated/overwritten so that
|
||||
# latest skill definitions and metadata frontmatter take effect.
|
||||
# User-owned documents (.agents/MULTI_AGENT_RULES*.md, .agents/INSTALL.md, etc.) use
|
||||
# explicit no-clobber guards so pre-existing user files are untouched and unmanifested.
|
||||
mkdir -p .agents
|
||||
( cd "$STAGE_DIR/.agents" && find . -type f -print ) | while IFS= read -r rel; do
|
||||
dest=".agents/${rel#./}"
|
||||
if [ ! -e "$dest" ]; then
|
||||
mkdir -p "$(dirname "$dest")"
|
||||
mkdir -p "$(dirname "$dest")"
|
||||
|
||||
if is_framework_owned "$dest"; then
|
||||
cp -f "$STAGE_DIR/.agents/$rel" "$dest" || { echo "❌ Error: Failed to copy $rel" >&2; exit 1; }
|
||||
if ! grep -Fqx "$dest" "$MANIFEST_FILE" 2>/dev/null; then
|
||||
echo "$dest" >> "$MANIFEST_FILE"
|
||||
fi
|
||||
elif [ ! -e "$dest" ]; then
|
||||
cp "$STAGE_DIR/.agents/$rel" "$dest" || { echo "❌ Error: Failed to copy $rel" >&2; exit 1; }
|
||||
echo "$dest" >> "$MANIFEST_FILE"
|
||||
if ! grep -Fqx "$dest" "$MANIFEST_FILE" 2>/dev/null; then
|
||||
echo "$dest" >> "$MANIFEST_FILE"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -164,7 +212,7 @@ if ! check_assets_present "."; then
|
||||
|
||||
rm -rf "$STAGE_DIR"
|
||||
trap - EXIT
|
||||
echo "✅ Skills staged into workspace (existing files preserved)."
|
||||
echo "✅ Skills staged into workspace (user documents and custom configs preserved)."
|
||||
fi
|
||||
|
||||
# Sanity check: verify all core files, not just a single one — an empty or
|
||||
|
||||
Reference in New Issue
Block a user