feat(kyberforge): retarget forge skills to author/audit APM content #93

Merged
Defame1297 merged 14 commits from feat/89-apm-native-authoring into main 2026-08-12 11:48:50 +00:00
2 changed files with 25 additions and 7 deletions
Showing only changes of commit 099bdec1b2 - Show all commits

View File

@@ -91,6 +91,9 @@ ROOT="$(cd "$ROOT" && pwd)"
# (plugin/APM scope) — stop and return it.
# - an apm.yml with no `type:` field is a marketplace-only manifest — skip
# it, keep walking up.
# - reaching $HOME marks the user-scope boundary — stop, even if $HOME is
# itself a .git-tracked dotfiles directory (checked before the .git test
# below, so a dotfiles repo at $HOME can't shadow user scope).
# - a .git directory marks the project-scope boundary — stop.
# - filesystem root reached with neither found — boundary-reached.
find_package_root() {

Scaffolds into the wrong directory for existing plugins. find_package_root() dropped the direct plugin.json check at $ROOT, so scaffolding a new agent inside an existing plugin.json-only plugin creates files in the wrong place.

Reproduced: new-agent.sh <name> plugins/kyberforge/ creates plugins/kyberforge/.claude/agents/<name>.md + .github/agents/<name>.agent.md instead of plugins/kyberforge/agents/<name>.md/.agent.md, diverging from where every other agent in that plugin actually lives.

**Scaffolds into the wrong directory for existing plugins.** `find_package_root()` dropped the direct `plugin.json` check at `$ROOT`, so scaffolding a new agent inside an existing plugin.json-only plugin creates files in the wrong place. Reproduced: `new-agent.sh <name> plugins/kyberforge/` creates `plugins/kyberforge/.claude/agents/<name>.md` + `.github/agents/<name>.agent.md` instead of `plugins/kyberforge/agents/<name>.md`/`.agent.md`, diverging from where every other agent in that plugin actually lives.
@@ -101,6 +104,11 @@ find_package_root() {
echo "$current"
return
fi
if [[ "$current" == "$HOME" ]]; then
echo "user"
echo "$current"
return
fi
if [[ -d "$current/.git" ]]; then
echo "project"
echo "$current"
@@ -127,17 +135,16 @@ case "$WALK_KIND" in
SCOPE="plugin"
PACKAGE_ROOT="$WALK_ROOT"
;;
user)
SCOPE="user"
;;
project)
SCOPE="project"
;;
boundary-reached)
if [[ "$ROOT" == "$HOME" ]]; then
SCOPE="user"
else
# Default fallback, same as the pre-walk-up script: no plugin/APM
# marker and not exactly $HOME means project scope.
SCOPE="project"
fi
# Default fallback, same as the pre-walk-up script: no plugin/APM
# marker, no $HOME boundary, and no .git means project scope.
SCOPE="project"
;;
esac

View File

@@ -211,6 +211,17 @@ teardown() {
rm -rf "$FAKE_HOME"
}
@test "user scope: \$HOME being a dotfiles .git repo does not shadow user scope" {
FAKE_HOME="$(mktemp -d)"
mkdir "$FAKE_HOME/.git"
run env HOME="$FAKE_HOME" bash "$SCRIPT" my-agent "~"
assert_success
assert [ -f "$FAKE_HOME/.claude/agents/my-agent.md" ]
assert [ -f "$FAKE_HOME/.copilot/agents/my-agent.agent.md" ]
refute [ -d "$FAKE_HOME/.github" ]
rm -rf "$FAKE_HOME"
}
# ---------------------------------------------------------------------------
# Name validation
# ---------------------------------------------------------------------------