feat: add force-refresh capability and allow framework-owned skill updates during installation

This commit is contained in:
2026-07-27 13:16:14 +09:00
parent 520168ca55
commit 002d9b268d
2 changed files with 228 additions and 18 deletions
+66 -18
View File
@@ -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