Harden installer: partial-install detection, complete runtime docs, explicit copy checks

This commit is contained in:
2026-06-24 10:43:08 +09:00
parent 387b43d8e3
commit b37407874d
+40 -17
View File
@@ -57,18 +57,35 @@ cd "$TARGET_DIR"
REPO_URL="https://git.godopu.com/tmpl/multi-agent-mux.git"
ARCHIVE_URL="https://git.godopu.com/tmpl/multi-agent-mux/archive/main.tar.gz"
# Fetch the orchestration assets if missing (for curl one-liner installs).
# Helper to verify presence of all core runtime files.
# Keying off a set of core files helps detect and recover from partial/interrupted installations.
check_assets_present() {
local dir="${1:-.}"
local core_files=(
".agents/skills/lib.sh"
".agents/skills/multi-agent-mux-create/scripts/create_session.sh"
".agents/skills/multi-agent-mux-delegate-job/scripts/registry.py"
".agents/skills/multi-agent-mux-status/scripts/status.sh"
)
for f in "${core_files[@]}"; do
if [ ! -f "$dir/$f" ]; then
return 1
fi
done
return 0
}
# Fetch the orchestration assets if missing or incomplete (for curl one-liner installs).
#
# 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/, AGENT.md, .env.example)
# 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. We key off lib.sh (a file), not the .agents/skills directory, so
# an empty/partial dir can't masquerade as a valid install.
if [ ! -f ".agents/skills/lib.sh" ]; then
echo "📥 Orchestration skills not found. Fetching from Gitea repository..."
# always wins.
if ! check_assets_present "."; then
echo "📥 Orchestration skills not found or incomplete. Fetching from Gitea repository..."
STAGE_DIR="$(mktemp -d)"
trap 'rm -rf "$STAGE_DIR"' EXIT
@@ -84,8 +101,8 @@ if [ ! -f ".agents/skills/lib.sh" ]; then
fi
# Verify the staged tree before we trust and copy from it.
if [ ! -f "$STAGE_DIR/.agents/skills/lib.sh" ]; then
echo "❌ Error: fetched source is missing '.agents/skills/lib.sh'. Aborting (no files copied)." >&2
if ! check_assets_present "$STAGE_DIR"; then
echo "❌ Error: fetched source is missing core runtime assets. Aborting (no files copied)." >&2
exit 1
fi
@@ -99,14 +116,20 @@ if [ ! -f ".agents/skills/lib.sh" ]; then
dest=".agents/${rel#./}"
if [ ! -e "$dest" ]; then
mkdir -p "$(dirname "$dest")"
cp "$STAGE_DIR/.agents/$rel" "$dest"
cp "$STAGE_DIR/.agents/$rel" "$dest" || { echo "❌ Error: Failed to copy $rel" >&2; exit 1; }
fi
done
if [ -f "$STAGE_DIR/AGENT.md" ] && [ ! -e "AGENT.md" ]; then
cp "$STAGE_DIR/AGENT.md" .
fi
# Copy non-dev documents if they don't already exist.
# We skip dev-specific docs like README.md, DONE.md, and FUTURE_WORKS.md.
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
cp "$STAGE_DIR/$doc" . || { echo "❌ Error: Failed to copy $doc" >&2; exit 1; }
fi
done
if [ -f "$STAGE_DIR/.env.example" ] && [ ! -e ".env.example" ]; then
cp "$STAGE_DIR/.env.example" .
cp "$STAGE_DIR/.env.example" . || { echo "❌ Error: Failed to copy .env.example" >&2; exit 1; }
fi
rm -rf "$STAGE_DIR"
@@ -114,10 +137,10 @@ if [ ! -f ".agents/skills/lib.sh" ]; then
echo "✅ Skills staged into workspace (existing files preserved)."
fi
# Sanity check: verify a FILE, not just the directory — an empty .agents/skills
# would otherwise pass and yield a silently broken install.
if [ ! -f ".agents/skills/lib.sh" ]; then
echo "❌ Error: '.agents/skills/lib.sh' missing after setup. Target layout might be invalid." >&2
# Sanity check: verify all core files, not just a single one — an empty or
# incomplete layout would yield a silently broken install.
if ! check_assets_present "."; then
echo "❌ Error: Core runtime assets missing after setup. Target layout might be invalid." >&2
exit 1
fi
echo "✅ Orchestration skills present."