mirror of
https://github.com/msitarzewski/agency-agents.git
synced 2026-10-17 08:36:18 +00:00
fix(convert): refuse duplicate agent slugs before writing
This commit is contained in:
@@ -25,6 +25,9 @@ jobs:
|
||||
- name: Validate converted YAML frontmatter
|
||||
run: bash scripts/test-convert-frontmatter.sh
|
||||
|
||||
- name: Reject colliding agent slugs before conversion
|
||||
run: bash scripts/test-convert-slug-collisions.sh
|
||||
|
||||
- name: Validate converted outputs (round-trip, strict parse, counts, drift)
|
||||
# Drift is advisory on pull requests (agent PRs always move their own manifest line;
|
||||
# maintainers regenerate at landing) and enforced on pushes to main.
|
||||
|
||||
@@ -695,6 +695,35 @@ clean_tool_output() {
|
||||
find "$dir" -mindepth 1 -maxdepth 1 ! -name 'README.md' -exec rm -rf {} +
|
||||
}
|
||||
|
||||
# Every per-agent integration writes to a path derived from the normalized
|
||||
# name. Refuse collisions before cleaning any existing output: otherwise the
|
||||
# later source file silently replaces the earlier agent in the generated tree.
|
||||
check_agent_slug_collisions() {
|
||||
local dir dirpath file slug relative i
|
||||
local seen_slugs=() seen_files=()
|
||||
local collisions=0
|
||||
for dir in "${AGENT_DIRS[@]}"; do
|
||||
dirpath="$REPO_ROOT/$dir"
|
||||
[[ -d "$dirpath" ]] || continue
|
||||
while IFS= read -r -d '' file; do
|
||||
is_agent_file "$file" || continue
|
||||
slug="$(agent_slug "$file")"
|
||||
[[ -n "$slug" ]] || continue
|
||||
relative="${file#"$REPO_ROOT"/}"
|
||||
for i in "${!seen_slugs[@]}"; do
|
||||
if [[ "${seen_slugs[i]}" == "$slug" ]]; then
|
||||
error "duplicate agent slug '$slug': ${seen_files[i]} and $relative"
|
||||
collisions=$((collisions + 1))
|
||||
break
|
||||
fi
|
||||
done
|
||||
seen_slugs+=("$slug")
|
||||
seen_files+=("$relative")
|
||||
done < <(find "$dirpath" -name "*.md" -type f -print0)
|
||||
done
|
||||
(( collisions == 0 ))
|
||||
}
|
||||
|
||||
run_conversions() {
|
||||
local tool="$1"
|
||||
local count=0
|
||||
@@ -772,6 +801,8 @@ main() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
check_agent_slug_collisions || exit 1
|
||||
|
||||
header "The Agency -- Converting agents to tool-specific formats"
|
||||
echo " Repo: $REPO_ROOT"
|
||||
echo " Output: $OUT_DIR"
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env bash
|
||||
# Duplicate normalized names must not silently overwrite one agent's output.
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
scratch="$(mktemp -d)"
|
||||
trap 'rm -rf "$scratch"' EXIT
|
||||
|
||||
mkdir -p "$scratch/repo/scripts" "$scratch/repo/engineering" "$scratch/output/gemini-cli"
|
||||
cp "$SCRIPT_DIR/convert.sh" "$SCRIPT_DIR/lib.sh" "$scratch/repo/scripts/"
|
||||
|
||||
cat > "$scratch/repo/engineering/first.md" <<'EOF'
|
||||
---
|
||||
name: Dev Ops
|
||||
description: First agent
|
||||
color: blue
|
||||
---
|
||||
# First agent
|
||||
EOF
|
||||
cat > "$scratch/repo/engineering/second.md" <<'EOF'
|
||||
---
|
||||
name: Dev/Ops
|
||||
description: Second agent
|
||||
color: red
|
||||
---
|
||||
# Second agent
|
||||
EOF
|
||||
|
||||
printf 'keep existing output\n' > "$scratch/output/gemini-cli/sentinel"
|
||||
if bash "$scratch/repo/scripts/convert.sh" --tool gemini-cli --out "$scratch/output" > "$scratch/log" 2>&1; then
|
||||
echo "FAIL: converter accepted two agents with the same output slug"
|
||||
exit 1
|
||||
fi
|
||||
grep -q "duplicate agent slug 'dev-ops'" "$scratch/log"
|
||||
grep -q 'engineering/first.md' "$scratch/log"
|
||||
grep -q 'engineering/second.md' "$scratch/log"
|
||||
[[ "$(cat "$scratch/output/gemini-cli/sentinel")" == 'keep existing output' ]]
|
||||
echo "PASS: duplicate slug refused before existing output changed"
|
||||
Reference in New Issue
Block a user