feat(vendor): --exclude plus content-type selection (--types/--exclude-types)
vendor add gains --exclude a,b,c (all mode minus those ids) as the mirror of --include, for taking the majority of a source while dropping a few items. Mutual exclusion with --include is a hard error, unknown ids fail naming the available ones (generalized checkIDEntries). vendor add and vendor select gain --types (allow-list) and --exclude-types (deny-list) over the four content types. The filter is stored as the optional, v2-compatible Selection.exclude_types field and survives vendor update: new upstream items of an excluded type never enter the work repository (unlike id expansion, which would silently re-admit them). --types/--exclude-types replace the filter on select, absent flags keep it, and --mode all clears it along with include/exclude. Also fixes materializeTree to create the staging directory for an empty selection — previously select-to-zero failed at the staging rename.
This commit is contained in:
1 parent
1ab97bff43
commit
0c779bc970
9 files changed
+533
-50
No files matched your search
@@ -81,6 +81,26 @@ assert_no_file "$WR3/external" "no partial external area"
|
||||
assert_file "$WR3/external/sp/skills/sp-good/SKILL.md" "renamed folder carries deployed name"
|
||||
assert_no_file "$WR3/external/sp/skills/good-skill" "upstream name absent after rename"
|
||||
|
||||
step "vendor add selection flags (--exclude, --types)"
|
||||
WR4="$WORK/work-repo-4"
|
||||
mkdir -p "$WR4"
|
||||
(cd "$WR4" && "$BIN" vendor add cur "$UP" --exclude broken-skill) > "$WORK/exclude.log" 2>&1
|
||||
assert_exit_zero $? "add --exclude succeeds"
|
||||
assert_no_file "$WR4/external/cur/skills/broken-skill" "excluded skill absent"
|
||||
assert_file "$WR4/external/cur/skills/good-skill/SKILL.md" "non-excluded skill present"
|
||||
assert_contains "$WR4/agent-lib.lock.json" '"exclude": [' "exclude list pinned"
|
||||
WR5="$WORK/work-repo-5"
|
||||
mkdir -p "$WR5"
|
||||
(cd "$WR5" && "$BIN" vendor add typed "$UP" --types skills,commands) > "$WORK/types.log" 2>&1
|
||||
assert_exit_zero $? "add --types succeeds"
|
||||
assert_no_file "$WR5/external/typed/agents" "agent type filtered out"
|
||||
assert_no_file "$WR5/external/typed/mcp" "mcp type filtered out"
|
||||
assert_contains "$WR5/agent-lib.lock.json" '"exclude_types": [' "type filter pinned"
|
||||
set +e
|
||||
(cd "$WR5" && "$BIN" vendor add bad "$UP" --include good-skill --exclude broken-skill) > "$WORK/flagconflict.log" 2>&1; RCX=$?
|
||||
set -e
|
||||
assert_exit_nonzero "$RCX" "--include + --exclude rejected"
|
||||
|
||||
step "validate / list / inspect"
|
||||
(cd "$WR" && "$BIN" validate) > "$WORK/validate.log" 2>&1
|
||||
assert_exit_zero $? "healthy state validates"
|
||||
@@ -114,6 +134,15 @@ assert_no_file "$WR/external/superpowers" "remove leaves no residue"
|
||||
(cd "$WR" && "$BIN" vendor add superpowers "$UP") >/dev/null 2>&1
|
||||
git -C "$WR" add -A && git -C "$WR" commit -qm "vendor superpowers (publication = commit && push)"
|
||||
|
||||
step "vendor select type filter parity"
|
||||
(cd "$WR5" && "$BIN" vendor select typed --exclude-types skills) > "$WORK/types-select.log" 2>&1
|
||||
assert_exit_zero $? "select --exclude-types succeeds"
|
||||
assert_no_file "$WR5/external/typed/skills" "skills dropped after narrowing the filter"
|
||||
assert_contains "$WORK/types-select.log" "type filter" "select reports the type filter"
|
||||
(cd "$WR5" && "$BIN" vendor select typed --mode all) > "$WORK/types-reset.log" 2>&1
|
||||
assert_exit_zero $? "select --mode all clears the filter"
|
||||
assert_file "$WR5/external/typed/skills/good-skill/SKILL.md" "skills restored after --mode all"
|
||||
|
||||
step "employee sync"
|
||||
HOME_DIR="$WORK/employee-home"
|
||||
STATE="$WORK/employee-state"
|
||||
@@ -142,6 +171,31 @@ assert_exit_zero "$RC2" "second sync succeeds"
|
||||
printf '%s' "$OUT2" > "$WORK/sync2.log"
|
||||
assert_contains "$WORK/sync2.log" "kept:" "second run keeps everything"
|
||||
|
||||
step "default branch stays fresh without ref"
|
||||
DB="$WORK/db-repo"
|
||||
mkdir -p "$DB/skills/db-skill"
|
||||
git -C "$DB" init -q -b main
|
||||
printf -- '---\nname: DB\n---\n# v1\n' > "$DB/skills/db-skill/SKILL.md"
|
||||
git -C "$DB" add -A && git -C "$DB" commit -qm "db v1"
|
||||
DBCFG="$WORK/db-config.json"
|
||||
printf '{"repo_url":"%s"}\n' "$DB" > "$DBCFG"
|
||||
DBHOME="$WORK/db-home"; DBSTATE="$WORK/db-state"
|
||||
mkdir -p "$DBHOME" "$DBSTATE"
|
||||
set +e
|
||||
HOME="$DBHOME" USERPROFILE="$DBHOME" AGENT_LIB_STATE_DIR="$DBSTATE" \
|
||||
"$BIN" sync --config "$DBCFG" >/dev/null 2>&1; RCDB=$?
|
||||
set -e
|
||||
assert_exit_zero "$RCDB" "first default-branch sync (clone)"
|
||||
printf -- '---\nname: DB\n---\n# v2\n' > "$DB/skills/db-skill/SKILL.md"
|
||||
git -C "$DB" add -A && git -C "$DB" commit -qm "db v2"
|
||||
set +e
|
||||
HOME="$DBHOME" USERPROFILE="$DBHOME" AGENT_LIB_STATE_DIR="$DBSTATE" \
|
||||
"$BIN" sync --config "$DBCFG" > "$WORK/db2.log" 2>&1; RCDB2=$?
|
||||
set -e
|
||||
assert_exit_zero "$RCDB2" "second default-branch sync (fetch)"
|
||||
assert_contains "$WORK/db2.log" "updated: 1" "default branch advanced past the clone-time revision"
|
||||
grep -q "# v2" "$DBHOME/.agents/skills/db-skill/SKILL.md" && ok "fresh content deployed" || fail "stale clone-time content served"
|
||||
|
||||
step "protected sync: local modification wins"
|
||||
printf -- '---\nname: Own Skill\n---\n# MY EDITS\n' > "$HOME_DIR/.agents/skills/own-skill/SKILL.md"
|
||||
printf -- '---\nname: Own Skill\ndescription: v2\n---\n# Upstream v2\n' > "$WR/skills/own-skill/SKILL.md"
|
||||
@@ -153,6 +207,18 @@ assert_contains "$WORK/sync3.log" "skipped (local modifications kept): 1" "modif
|
||||
grep -q "MY EDITS" "$HOME_DIR/.agents/skills/own-skill/SKILL.md" && ok "local version kept" || fail "local version overwritten"
|
||||
assert_contains "$STATE/sync.log" "SKIP skills/own-skill" "warning logged with item and reason"
|
||||
|
||||
step "forced sync: repository version wins"
|
||||
set +e
|
||||
OUTF="$(HOME="$HOME_DIR" USERPROFILE="$HOME_DIR" AGENT_LIB_STATE_DIR="$STATE" \
|
||||
"$BIN" sync --config "$CFG" --force 2>&1)"; RCF=$?
|
||||
set -e
|
||||
assert_exit_zero "$RCF" "sync --force succeeds"
|
||||
printf '%s' "$OUTF" > "$WORK/syncf.log"
|
||||
assert_contains "$WORK/syncf.log" "updated:" "forced overwrite reported as update"
|
||||
grep -q "Upstream v2" "$HOME_DIR/.agents/skills/own-skill/SKILL.md" && ok "repository version restored" || fail "local modification survived --force"
|
||||
# re-introduce drift so the upstream-deletion walk below has a modified copy
|
||||
printf -- '---\nname: Own Skill\n---\n# MY EDITS\n' > "$HOME_DIR/.agents/skills/own-skill/SKILL.md"
|
||||
|
||||
step "self-created item survives"
|
||||
MINE="$HOME_DIR/.agents/skills/my-private-skill"
|
||||
mkdir -p "$MINE" && printf -- '---\nname: Mine\n---\n' > "$MINE/SKILL.md"
|
||||
@@ -189,6 +255,18 @@ set +e; OUTSJ="$(HOME="$HOME_DIR" USERPROFILE="$HOME_DIR" AGENT_LIB_STATE_DIR="$
|
||||
assert_exit_nonzero "$RCSJ" "status --json keeps drift exit code"
|
||||
printf '%s' "$OUTSJ" | grep -q '"problematic_drift": true' && ok "json drift flag set" || fail "json drift flag missing"
|
||||
|
||||
step "forced sync after upstream deletion removes modified copies"
|
||||
set +e
|
||||
OUTR="$(HOME="$HOME_DIR" USERPROFILE="$HOME_DIR" AGENT_LIB_STATE_DIR="$STATE" \
|
||||
"$BIN" sync --config "$CFG" --force 2>&1)"; RCR=$?
|
||||
set -e
|
||||
assert_exit_zero "$RCR" "sync --force after deletion succeeds"
|
||||
printf '%s' "$OUTR" > "$WORK/syncr.log"
|
||||
assert_contains "$WORK/syncr.log" "removed:" "forced removals reported"
|
||||
assert_no_file "$HOME_DIR/.agents/skills/own-skill" "modified skill removed by force"
|
||||
assert_no_file "$HOME_DIR/.config/opencode/agents/scout.md" "modified agent removed by force"
|
||||
assert_file "$MINE/SKILL.md" "unmanaged item survives --force untouched"
|
||||
|
||||
step "unreachable repository keeps state"
|
||||
BEFORE="$(cat "$HOME_DIR/.agents/skills/fresh-skill/SKILL.md")"
|
||||
printf '{"repo_url":"%s","ref":"main"}\n' "$WORK/nonexistent-repo" > "$CFG"
|
||||
|
||||
Reference in new issue
Block a user