The repo's task install (and targets like task install:claude:global) break the per-skill symlink wiring instead of establishing it. Observed 2026-07-04:
After task install: claude:0/40 crush:0/40 vibe:0/40 — every per-skill symlink gone.
A second task install:claude:global gave 22/40 (non-deterministic).
The identical link loop as plain bash, and install.sh, wire 40/40 every time (all four harnesses).
So the Taskfile installer is unreliable/destructive; install.sh is correct.
Likely cause
The multi-line - | install blocks mix Go-template {{.TASKFILE_DIR}}/{{.NON_SKILL_ENTRIES}} with shell $(...) and ${skill}. Suspects: task's default parallel execution of the install aggregate deps, or template/quoting of the regex. task list (single-line) works, so it's the multi-line-block handling, not TASKFILE_DIR resolution.
Repro
git clone https://git.d-ma.be/mathias/skills.git /tmp/skills && cd /tmp/skills
task install
for s in $(ls -1 | grep -Ev '^(Taskfile.yml|install.sh|README.md|SKILLS_INDEX.md)$'); do [ -L ~/.claude/skills/$s ] && echo x; done | wc -l # << 40
SKILLS_CHECKOUT_DIR="$PWD" bash install.sh # now 40/40
Fix options
Make task install delegate to install.sh (proven path) instead of reimplementing the loop — simplest, removes duplication.
If keeping the loops: disable parallel deps, audit template/quoting, add a post-condition assert (links == skills).
Workaround (already documented)
install.sh — curl -fsSL .../install.sh | bash, or SKILLS_CHECKOUT_DIR="$PWD" bash install.sh. SKILLS_INDEX.md now points here.
Surfaced consolidating local-dev's embedded .skills/ into this repo (2026-07-04).
## Problem
The repo's `task install` (and targets like `task install:claude:global`) break the per-skill symlink wiring instead of establishing it. Observed 2026-07-04:
- After `task install`: `claude:0/40 crush:0/40 vibe:0/40` — every per-skill symlink gone.
- A second `task install:claude:global` gave `22/40` (non-deterministic).
- The identical link loop as plain bash, and `install.sh`, wire `40/40` every time (all four harnesses).
So the Taskfile installer is unreliable/destructive; `install.sh` is correct.
## Likely cause
The multi-line `- |` install blocks mix Go-template `{{.TASKFILE_DIR}}`/`{{.NON_SKILL_ENTRIES}}` with shell `$(...)` and `${skill}`. Suspects: task's default parallel execution of the `install` aggregate deps, or template/quoting of the regex. `task list` (single-line) works, so it's the multi-line-block handling, not TASKFILE_DIR resolution.
## Repro
git clone https://git.d-ma.be/mathias/skills.git /tmp/skills && cd /tmp/skills
task install
for s in $(ls -1 | grep -Ev '^(Taskfile.yml|install.sh|README.md|SKILLS_INDEX.md)$'); do [ -L ~/.claude/skills/$s ] && echo x; done | wc -l # << 40
SKILLS_CHECKOUT_DIR="$PWD" bash install.sh # now 40/40
## Fix options
1. Make `task install` delegate to `install.sh` (proven path) instead of reimplementing the loop — simplest, removes duplication.
2. If keeping the loops: disable parallel deps, audit template/quoting, add a post-condition assert (links == skills).
## Workaround (already documented)
`install.sh` — `curl -fsSL .../install.sh | bash`, or `SKILLS_CHECKOUT_DIR="$PWD" bash install.sh`. SKILLS_INDEX.md now points here.
Surfaced consolidating local-dev's embedded `.skills/` into this repo (2026-07-04).
Already fixed — closing on live verification rather than on a new change.
Fix option 1 from this issue is what the repo does today. Taskfile.yml:
install:desc:'Wire THIS checkout into Crush / Pi / OpenCode. Claude Code uses the plugin instead.'cmds:- SKILLS_SKIP_FETCH=1 SKILLS_CHECKOUT_DIR='{{.TASKFILE_DIR}}' bash '{{.TASKFILE_DIR}}/install.sh'
The file's own header records why: "The wiring loops that used to live here were five near-identical copies that drifted; install.sh owns wiring now and this file delegates to it." No multi-line - | block, no template/shell mixing, no parallel aggregate deps — so the mechanism this issue suspected is gone rather than patched.
Verified on koala just now:
$ task install
[skills] using /home/mathias/dev/skills as-is (SKILLS_SKIP_FETCH=1)
[skills] done — 42 skill(s) at ref=main, 3 links total
INSTALL_EXIT=0
$ task doctor
skills doctor: clean — 42 skills, checkout /home/mathias/dev/skills
DOCTOR_EXIT=0
The repro in the issue body no longer applies as written, for a second reason worth noting: the count it asserts (per-skill links in ~/.claude/skills/, 40 of them) is no longer the target shape at all. Wiring is now one directory symlink per harness — ~/.agents/skills → the checkout, with crush and opencode pointing at that link — and Claude Code goes through the plugin, not symlinks. Per-skill links in ~/.claude/skills/ are now a fault, reported by task doctor.
So "0/40" today would mean correct, not broken. Anyone re-testing this should assert on task doctor exiting 0, which is the check that survived the layout change.
Already fixed — closing on live verification rather than on a new change.
Fix option 1 from this issue is what the repo does today. `Taskfile.yml`:
```yaml
install:
desc: 'Wire THIS checkout into Crush / Pi / OpenCode. Claude Code uses the plugin instead.'
cmds:
- SKILLS_SKIP_FETCH=1 SKILLS_CHECKOUT_DIR='{{.TASKFILE_DIR}}' bash '{{.TASKFILE_DIR}}/install.sh'
```
The file's own header records why: *"The wiring loops that used to live here were five near-identical copies that drifted; install.sh owns wiring now and this file delegates to it."* No multi-line `- |` block, no template/shell mixing, no parallel aggregate deps — so the mechanism this issue suspected is gone rather than patched.
Verified on koala just now:
```
$ task install
[skills] using /home/mathias/dev/skills as-is (SKILLS_SKIP_FETCH=1)
[skills] done — 42 skill(s) at ref=main, 3 links total
INSTALL_EXIT=0
$ task doctor
skills doctor: clean — 42 skills, checkout /home/mathias/dev/skills
DOCTOR_EXIT=0
```
The repro in the issue body no longer applies as written, for a second reason worth noting: the count it asserts (per-skill links in `~/.claude/skills/`, 40 of them) is no longer the target shape at all. Wiring is now **one directory symlink per harness** — `~/.agents/skills` → the checkout, with crush and opencode pointing at that link — and Claude Code goes through the plugin, not symlinks. Per-skill links in `~/.claude/skills/` are now a *fault*, reported by `task doctor`.
So "0/40" today would mean correct, not broken. Anyone re-testing this should assert on `task doctor` exiting 0, which is the check that survived the layout change.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
The repo's
task install(and targets liketask install:claude:global) break the per-skill symlink wiring instead of establishing it. Observed 2026-07-04:task install:claude:0/40 crush:0/40 vibe:0/40— every per-skill symlink gone.task install:claude:globalgave22/40(non-deterministic).install.sh, wire40/40every time (all four harnesses).So the Taskfile installer is unreliable/destructive;
install.shis correct.Likely cause
The multi-line
- |install blocks mix Go-template{{.TASKFILE_DIR}}/{{.NON_SKILL_ENTRIES}}with shell$(...)and${skill}. Suspects: task's default parallel execution of theinstallaggregate deps, or template/quoting of the regex.task list(single-line) works, so it's the multi-line-block handling, not TASKFILE_DIR resolution.Repro
Fix options
task installdelegate toinstall.sh(proven path) instead of reimplementing the loop — simplest, removes duplication.Workaround (already documented)
install.sh—curl -fsSL .../install.sh | bash, orSKILLS_CHECKOUT_DIR="$PWD" bash install.sh. SKILLS_INDEX.md now points here.Surfaced consolidating local-dev's embedded
.skills/into this repo (2026-07-04).Already fixed — closing on live verification rather than on a new change.
Fix option 1 from this issue is what the repo does today.
Taskfile.yml:The file's own header records why: "The wiring loops that used to live here were five near-identical copies that drifted; install.sh owns wiring now and this file delegates to it." No multi-line
- |block, no template/shell mixing, no parallel aggregate deps — so the mechanism this issue suspected is gone rather than patched.Verified on koala just now:
The repro in the issue body no longer applies as written, for a second reason worth noting: the count it asserts (per-skill links in
~/.claude/skills/, 40 of them) is no longer the target shape at all. Wiring is now one directory symlink per harness —~/.agents/skills→ the checkout, with crush and opencode pointing at that link — and Claude Code goes through the plugin, not symlinks. Per-skill links in~/.claude/skills/are now a fault, reported bytask doctor.So "0/40" today would mean correct, not broken. Anyone re-testing this should assert on
task doctorexiting 0, which is the check that survived the layout change.