From eb2cb6de9f988ea2acac988f7f1fb782a25a39ba Mon Sep 17 00:00:00 2001
From: satyaborg <satya.borg@gmail.com>
Date: Fri, 29 May 2026 13:59:36 +1000
Subject: [PATCH] feat!: install skills for codex and claude

---
 README.md             |  7 ++++---
 skill_helpers.sh      | 44 +++++++++++++++++++++++++++++++++++++------
 tests/devloop_test.sh | 29 ++++++++++++++++------------
 3 files changed, 59 insertions(+), 21 deletions(-)

diff --git a/README.md b/README.md
index 9fc8030..f9645ac 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,8 @@ Run without installing:
 ./devloop --help
 ```
 
-`install.sh` also installs the bundled Agent Skills globally under `~/.agents/skills`.
+`install.sh` also installs the bundled Agent Skills globally for Codex under `~/.agents/skills`
+and Claude Code under `~/.claude/skills`.
 After install or update, verify the local setup:
 
 ```sh
@@ -126,8 +127,8 @@ When stdout is a terminal, running `devloop` without arguments opens a menu:
 bash -n devloop install.sh
 ./devloop --help
 tmp="$(mktemp -d)"
-DEVLOOP_BIN_DIR="$tmp/bin" DEVLOOP_SKILLS_DIR="$tmp/skills" ./install.sh
-PATH="$tmp/bin:$PATH" DEVLOOP_SKILLS_DIR="$tmp/skills" devloop doctor
+DEVLOOP_BIN_DIR="$tmp/bin" HOME="$tmp/home" ./install.sh
+PATH="$tmp/bin:$PATH" HOME="$tmp/home" devloop doctor
 ```
 
 The supported runtime is the root [`devloop`](devloop) Bash script.
diff --git a/skill_helpers.sh b/skill_helpers.sh
index 1ddd1e4..6ec51e0 100644
--- a/skill_helpers.sh
+++ b/skill_helpers.sh
@@ -1,7 +1,8 @@
 #!/usr/bin/env bash
 
-devloop_skills_dir() {
-  printf '%s\n' "${DEVLOOP_SKILLS_DIR:-$HOME/.agents/skills}"
+devloop_skills_dirs() {
+  printf '%s\n' "$HOME/.agents/skills"
+  printf '%s\n' "$HOME/.claude/skills"
 }
 
 devloop_checksum_file() {
@@ -59,8 +60,7 @@ devloop_can_replace_skill() {
 
 devloop_install_skills() {
   local root="$1"
-  local skills_dir mode source name dest checksum status
-  skills_dir="$(devloop_skills_dir)"
+  local skills_dir mode status
   mode="${DEVLOOP_SKILL_INSTALL:-copy}"
   status=0
 
@@ -72,6 +72,23 @@ devloop_install_skills() {
       ;;
   esac
 
+  while IFS= read -r skills_dir; do
+    if [ -z "$skills_dir" ]; then continue; fi
+    devloop_install_skills_to_dir "$root" "$skills_dir" "$mode" || status=1
+  done <<EOF
+$(devloop_skills_dirs)
+EOF
+
+  return "$status"
+}
+
+devloop_install_skills_to_dir() {
+  local root="$1"
+  local skills_dir="$2"
+  local mode="$3"
+  local source name dest checksum status
+  status=0
+
   if ! mkdir -p "$skills_dir"; then
     printf 'failed to create skills directory: %s\n' "$skills_dir" >&2
     return 1
@@ -153,8 +170,23 @@ devloop_doctor_optional_command() {
 
 devloop_doctor_skills() {
   local root="$1"
-  local skills_dir source name dest declared bundled installed status
-  skills_dir="$(devloop_skills_dir)"
+  local skills_dir status
+  status=0
+
+  while IFS= read -r skills_dir; do
+    if [ -z "$skills_dir" ]; then continue; fi
+    devloop_doctor_skills_in_dir "$root" "$skills_dir" || status=1
+  done <<EOF
+$(devloop_skills_dirs)
+EOF
+
+  return "$status"
+}
+
+devloop_doctor_skills_in_dir() {
+  local root="$1"
+  local skills_dir="$2"
+  local source name dest declared bundled installed status
   status=0
 
   for source in "$root"/skills/*; do
diff --git a/tests/devloop_test.sh b/tests/devloop_test.sh
index cf14f65..4a04b21 100755
--- a/tests/devloop_test.sh
+++ b/tests/devloop_test.sh
@@ -211,25 +211,28 @@ contains "$uuid_one" "00000000-0000-4000-8000-" "new_uuid fallback format"
 ok "pure helpers"
 
 bin_dir="$work/bin"
-skills_dir="$work/skills"
-DEVLOOP_BIN_DIR="$bin_dir" DEVLOOP_SKILLS_DIR="$skills_dir" "$ROOT/install.sh" >/tmp/devloop-install-test.out
+install_home="$work/install-home"
+DEVLOOP_BIN_DIR="$bin_dir" HOME="$install_home" "$ROOT/install.sh" >/tmp/devloop-install-test.out
 [[ -x "$ROOT/devloop" ]] || fail "devloop is not executable"
 [[ -L "$bin_dir/devloop" ]] || fail "installer did not create symlink"
-[[ -f "$skills_dir/devloop-spec/SKILL.md" ]] || fail "installer did not install spec skill"
-[[ -f "$skills_dir/devloop-spec/references/spec-template.md" ]] || fail "installer did not install spec template reference"
-[[ -f "$skills_dir/devloop-review/SKILL.md" ]] || fail "installer did not install review skill"
-[[ -f "$skills_dir/devloop-review/.devloop-checksum" ]] || fail "installer did not write checksum"
+[[ -f "$install_home/.agents/skills/devloop-spec/SKILL.md" ]] || fail "installer did not install Codex spec skill"
+[[ -f "$install_home/.agents/skills/devloop-spec/references/spec-template.md" ]] || fail "installer did not install Codex spec template reference"
+[[ -f "$install_home/.agents/skills/devloop-review/SKILL.md" ]] || fail "installer did not install Codex review skill"
+[[ -f "$install_home/.agents/skills/devloop-review/.devloop-checksum" ]] || fail "installer did not write Codex checksum"
+[[ -f "$install_home/.claude/skills/devloop-spec/SKILL.md" ]] || fail "installer did not install Claude spec skill"
+[[ -f "$install_home/.claude/skills/devloop-review/SKILL.md" ]] || fail "installer did not install Claude review skill"
+[[ -f "$install_home/.claude/skills/devloop-review/.devloop-checksum" ]] || fail "installer did not write Claude checksum"
 "$bin_dir/devloop" --help >/tmp/devloop-help-test.out
 contains "$(cat /tmp/devloop-help-test.out)" "Spec-driven code and review loop." "installed help"
 ok "installer"
 
-printf '%s\n' "user edit" >> "$skills_dir/devloop-review/SKILL.md"
-DEVLOOP_BIN_DIR="$bin_dir" DEVLOOP_SKILLS_DIR="$skills_dir" "$ROOT/install.sh" >/tmp/devloop-install-skip.out 2>&1
+printf '%s\n' "user edit" >> "$install_home/.agents/skills/devloop-review/SKILL.md"
+DEVLOOP_BIN_DIR="$bin_dir" HOME="$install_home" "$ROOT/install.sh" >/tmp/devloop-install-skip.out 2>&1
 contains "$(cat /tmp/devloop-install-skip.out)" "skipping modified skill" "installer modified skill guard"
 contains "$(cat /tmp/devloop-install-skip.out)" "try: devloop doctor" "installer guidance after skill skip"
-contains "$(cat "$skills_dir/devloop-review/SKILL.md")" "user edit" "installer modified skill preserved"
-DEVLOOP_FORCE=1 DEVLOOP_BIN_DIR="$bin_dir" DEVLOOP_SKILLS_DIR="$skills_dir" "$ROOT/install.sh" >/tmp/devloop-install-force.out
-if grep -q "user edit" "$skills_dir/devloop-review/SKILL.md"; then fail "installer force did not restore skill"; fi
+contains "$(cat "$install_home/.agents/skills/devloop-review/SKILL.md")" "user edit" "installer modified skill preserved"
+DEVLOOP_FORCE=1 DEVLOOP_BIN_DIR="$bin_dir" HOME="$install_home" "$ROOT/install.sh" >/tmp/devloop-install-force.out
+if grep -q "user edit" "$install_home/.agents/skills/devloop-review/SKILL.md"; then fail "installer force did not restore skill"; fi
 ok "installer skill updates"
 
 fake_bin="$work/fake-bin"
@@ -237,10 +240,12 @@ mkdir -p "$fake_bin"
 printf '#!/usr/bin/env bash\nexit 0\n' > "$fake_bin/codex"
 printf '#!/usr/bin/env bash\nexit 0\n' > "$fake_bin/claude"
 chmod +x "$fake_bin/codex" "$fake_bin/claude"
-doctor_output="$(DEVLOOP_SKILLS_DIR="$skills_dir" PATH="$bin_dir:$fake_bin:$PATH" "$bin_dir/devloop" doctor 2>&1)"
+doctor_output="$(HOME="$install_home" PATH="$bin_dir:$fake_bin:$PATH" "$bin_dir/devloop" doctor 2>&1)"
 contains "$doctor_output" "devloop doctor: ready" "doctor"
 contains "$doctor_output" "[ok] skill devloop-spec" "doctor"
 contains "$doctor_output" "Optional UI" "doctor"
+contains "$doctor_output" "$install_home/.agents/skills/devloop-spec" "doctor Codex skill"
+contains "$doctor_output" "$install_home/.claude/skills/devloop-spec" "doctor Claude skill"
 ok "doctor"
 
 agent="$work/spec-agent"
