fix(shell): keep generated ignores visible to Pi
This commit is contained in:
@@ -55,6 +55,7 @@ pkgs.runCommandLocal "skills-shell-hook-check"
|
|||||||
# collides with a selected one, and a symlink pointing outside the store.
|
# collides with a selected one, and a symlink pointing outside the store.
|
||||||
mkdir -p proj/.agents/skills/handmade
|
mkdir -p proj/.agents/skills/handmade
|
||||||
printf '%s\n' "a hand-authored skill" > proj/.agents/skills/handmade/SKILL.md
|
printf '%s\n' "a hand-authored skill" > proj/.agents/skills/handmade/SKILL.md
|
||||||
|
printf '%s\n' "# fixture ignore" "result" > proj/.gitignore
|
||||||
mkdir -p proj/.agents/skills/sample-gamma
|
mkdir -p proj/.agents/skills/sample-gamma
|
||||||
printf '%s\n' "a hand-authored gamma" > proj/.agents/skills/sample-gamma/SKILL.md
|
printf '%s\n' "a hand-authored gamma" > proj/.agents/skills/sample-gamma/SKILL.md
|
||||||
ln -s /nonexistent/external-target proj/.agents/skills/external
|
ln -s /nonexistent/external-target proj/.agents/skills/external
|
||||||
@@ -94,18 +95,23 @@ pkgs.runCommandLocal "skills-shell-hook-check"
|
|||||||
test -f .claude/skills/sample-alpha/SKILL.md \
|
test -f .claude/skills/sample-alpha/SKILL.md \
|
||||||
|| fail "Claude Code compatibility link does not resolve selected skills"
|
|| fail "Claude Code compatibility link does not resolve selected skills"
|
||||||
|
|
||||||
echo "the .gitignore lists only the skills the hook actually linked, plus itself"
|
echo "the project .gitignore lists only generated links and keeps skill scanners clear"
|
||||||
grep -qx '/.gitignore' .agents/skills/.gitignore || fail ".gitignore does not ignore itself"
|
test ! -e .agents/skills/.gitignore || fail "the hook wrote an ignore file where skill scanners read it"
|
||||||
grep -qx '/sample-alpha' .agents/skills/.gitignore || fail ".gitignore omits sample-alpha"
|
grep -qx '# fixture ignore' .gitignore || fail "the existing .gitignore content was lost"
|
||||||
grep -qx '/sample-beta' .agents/skills/.gitignore || fail ".gitignore omits sample-beta"
|
grep -qx 'result' .gitignore || fail "the existing .gitignore pattern was lost"
|
||||||
for tracked in /handmade /sample-gamma /external; do
|
grep -qx '# BEGIN mkSkillsShellHook' .gitignore || fail ".gitignore lacks the managed block start"
|
||||||
grep -qx "$tracked" .agents/skills/.gitignore \
|
grep -qx '# END mkSkillsShellHook' .gitignore || fail ".gitignore lacks the managed block end"
|
||||||
|
grep -qx '.claude/skills' .gitignore || fail ".gitignore omits the compatibility symlink"
|
||||||
|
grep -qx '.agents/skills/sample-alpha' .gitignore || fail ".gitignore omits sample-alpha"
|
||||||
|
grep -qx '.agents/skills/sample-beta' .gitignore || fail ".gitignore omits sample-beta"
|
||||||
|
for tracked in .agents/skills/handmade .agents/skills/sample-gamma .agents/skills/external; do
|
||||||
|
grep -qx "$tracked" .gitignore \
|
||||||
&& fail ".gitignore lists $tracked, which would untrack a real path"
|
&& fail ".gitignore lists $tracked, which would untrack a real path"
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "no manifest or state file is written: only the fixtures and links exist"
|
echo "no manifest or state file is written: only the fixtures and links exist"
|
||||||
entries=$(ls -A .agents/skills | sort | tr '\n' ' ')
|
entries=$(ls -A .agents/skills | sort | tr '\n' ' ')
|
||||||
[ "$entries" = ".gitignore external handmade sample-alpha sample-beta sample-gamma " ] \
|
[ "$entries" = "external handmade sample-alpha sample-beta sample-gamma " ] \
|
||||||
|| fail "unexpected entries under .agents/skills: [$entries]"
|
|| fail "unexpected entries under .agents/skills: [$entries]"
|
||||||
|
|
||||||
echo "second entry with sample-beta deselected: its symlink is removed, the rest stay"
|
echo "second entry with sample-beta deselected: its symlink is removed, the rest stay"
|
||||||
@@ -119,10 +125,12 @@ pkgs.runCommandLocal "skills-shell-hook-check"
|
|||||||
|| fail "the colliding hand-authored skill was disturbed on re-entry"
|
|| fail "the colliding hand-authored skill was disturbed on re-entry"
|
||||||
[ -L .agents/skills/external ] || fail "the non-store symlink was disturbed on re-entry"
|
[ -L .agents/skills/external ] || fail "the non-store symlink was disturbed on re-entry"
|
||||||
|
|
||||||
echo "the .gitignore tracks the new selection"
|
echo "the .gitignore tracks the new selection without duplicating the managed block"
|
||||||
grep -qx '/sample-alpha' .agents/skills/.gitignore || fail ".gitignore lost sample-alpha"
|
grep -qx '.agents/skills/sample-alpha' .gitignore || fail ".gitignore lost sample-alpha"
|
||||||
grep -qx '/sample-beta' .agents/skills/.gitignore \
|
grep -qx '.agents/skills/sample-beta' .gitignore \
|
||||||
&& fail ".gitignore still lists the deselected sample-beta"
|
&& fail ".gitignore still lists the deselected sample-beta"
|
||||||
|
[ "$(grep -xc '# BEGIN mkSkillsShellHook' .gitignore)" = 1 ] \
|
||||||
|
|| fail ".gitignore has duplicate managed blocks"
|
||||||
|
|
||||||
touch "$out"
|
touch "$out"
|
||||||
''
|
''
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Builds a dev-shell shellHook that links a project's selected skills into its
|
# Builds a dev-shell shellHook that links a project's selected skills into its
|
||||||
# own `.agents/skills/` as direct-child symlinks into the Nix store, with
|
# own `.agents/skills/` as direct-child symlinks into the Nix store, with
|
||||||
# `.claude/skills` as a compatibility symlink when that path is free.
|
# `.claude/skills` as a compatibility symlink when that path is free.
|
||||||
|
# Generated ignores live in the project root so agent skill scanners still see
|
||||||
|
# the linked skills.
|
||||||
skills:
|
skills:
|
||||||
let
|
let
|
||||||
storeDir = builtins.storeDir;
|
storeDir = builtins.storeDir;
|
||||||
@@ -25,13 +27,15 @@ in
|
|||||||
_mkskills_dir=".agents/skills"
|
_mkskills_dir=".agents/skills"
|
||||||
mkdir -p "$_mkskills_dir"
|
mkdir -p "$_mkskills_dir"
|
||||||
|
|
||||||
|
_mkskills_claude_skills_managed=0
|
||||||
mkdir -p .claude
|
mkdir -p .claude
|
||||||
if [ ! -e .claude/skills ] && [ ! -L .claude/skills ]; then
|
if [ ! -e .claude/skills ] && [ ! -L .claude/skills ]; then
|
||||||
ln -s ../.agents/skills .claude/skills
|
ln -s ../.agents/skills .claude/skills
|
||||||
|
_mkskills_claude_skills_managed=1
|
||||||
elif [ -L .claude/skills ]; then
|
elif [ -L .claude/skills ]; then
|
||||||
case "$(readlink .claude/skills)" in
|
case "$(readlink .claude/skills)" in
|
||||||
../.agents/skills) : ;;
|
../.agents/skills) _mkskills_claude_skills_managed=1 ;;
|
||||||
${storeDir}/*) rm -f .claude/skills && ln -s ../.agents/skills .claude/skills ;;
|
${storeDir}/*) rm -f .claude/skills && ln -s ../.agents/skills .claude/skills && _mkskills_claude_skills_managed=1 ;;
|
||||||
esac
|
esac
|
||||||
else
|
else
|
||||||
printf 'mkSkillsShellHook: leaving existing non-symlink .claude/skills in place; Claude Code compatibility link not installed\n' >&2
|
printf 'mkSkillsShellHook: leaving existing non-symlink .claude/skills in place; Claude Code compatibility link not installed\n' >&2
|
||||||
@@ -45,8 +49,9 @@ in
|
|||||||
done
|
done
|
||||||
|
|
||||||
# A real path at a selected skill's name is a hand-authored skill.
|
# A real path at a selected skill's name is a hand-authored skill.
|
||||||
# It is left in place and left out of the managed set, so the .gitignore
|
# It is left in place and left out of the managed set, so the generated
|
||||||
# below keeps tracking it rather than the skill that would have been linked.
|
# ignore block keeps tracking it rather than the skill that would have been
|
||||||
|
# linked.
|
||||||
_mkskills_managed=""
|
_mkskills_managed=""
|
||||||
_mkskills_link() {
|
_mkskills_link() {
|
||||||
_mkskills_dest="$_mkskills_dir/$1"
|
_mkskills_dest="$_mkskills_dir/$1"
|
||||||
@@ -62,17 +67,46 @@ in
|
|||||||
}
|
}
|
||||||
${links}
|
${links}
|
||||||
|
|
||||||
# Regenerate the self-ignoring .gitignore from the current selection, so the
|
if [ -f "$_mkskills_dir/.gitignore" ] \
|
||||||
# store symlinks stay out of git while hand-authored skills, absent from this
|
&& grep -qx '# Generated by mkSkillsShellHook. Nix-delivered skill symlinks, kept out of git.' "$_mkskills_dir/.gitignore"; then
|
||||||
# list, remain tracked.
|
rm -f "$_mkskills_dir/.gitignore"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Regenerate the project-root ignore block from the current selection.
|
||||||
|
# Skill scanners read ignore files under .agents/skills, so the block must
|
||||||
|
# live above the scanned tree.
|
||||||
|
_mkskills_gitignore=".gitignore"
|
||||||
|
_mkskills_gitignore_tmp=".gitignore.mkskills.$$"
|
||||||
|
if [ -f "$_mkskills_gitignore" ]; then
|
||||||
|
awk '
|
||||||
|
$0 == "# BEGIN mkSkillsShellHook" { skip = 1; next }
|
||||||
|
$0 == "# END mkSkillsShellHook" { skip = 0; next }
|
||||||
|
!skip { lines[++n] = $0 }
|
||||||
|
END {
|
||||||
|
while (n > 0 && lines[n] == "") n--
|
||||||
|
for (i = 1; i <= n; i++) print lines[i]
|
||||||
|
}
|
||||||
|
' "$_mkskills_gitignore" > "$_mkskills_gitignore_tmp"
|
||||||
|
else
|
||||||
|
: > "$_mkskills_gitignore_tmp"
|
||||||
|
fi
|
||||||
{
|
{
|
||||||
|
if [ -s "$_mkskills_gitignore_tmp" ]; then
|
||||||
|
cat "$_mkskills_gitignore_tmp"
|
||||||
|
printf '\n'
|
||||||
|
fi
|
||||||
|
printf '%s\n' "# BEGIN mkSkillsShellHook"
|
||||||
printf '%s\n' "# Generated by mkSkillsShellHook. Nix-delivered skill symlinks, kept out of git."
|
printf '%s\n' "# Generated by mkSkillsShellHook. Nix-delivered skill symlinks, kept out of git."
|
||||||
printf '%s\n' "/.gitignore"
|
if [ "$_mkskills_claude_skills_managed" = 1 ]; then
|
||||||
|
printf '%s\n' ".claude/skills"
|
||||||
|
fi
|
||||||
# Disable pathname expansion so a managed name is never glob-expanded.
|
# Disable pathname expansion so a managed name is never glob-expanded.
|
||||||
set -f
|
set -f
|
||||||
for _mkskills_name in $_mkskills_managed; do
|
for _mkskills_name in $_mkskills_managed; do
|
||||||
printf '/%s\n' "$_mkskills_name"
|
printf '.agents/skills/%s\n' "$_mkskills_name"
|
||||||
done
|
done
|
||||||
} > "$_mkskills_dir/.gitignore"
|
printf '%s\n' "# END mkSkillsShellHook"
|
||||||
|
} > "$_mkskills_gitignore"
|
||||||
|
rm -f "$_mkskills_gitignore_tmp"
|
||||||
)
|
)
|
||||||
''
|
''
|
||||||
|
|||||||
Reference in New Issue
Block a user