From 29c74e796eb9c49f8157c8e9db521cd382058160 Mon Sep 17 00:00:00 2001 From: Marius Colacioiu Date: Mon, 22 Jun 2026 14:29:53 +0200 Subject: [PATCH 1/3] Add Claude Code skill discovery bridge Amp-Thread-ID: https://ampcode.com/threads/T-019eef40-4755-7055-86f1-45d4a0ec8294 Co-authored-by: Amp --- install.sh | 145 ++++++++++++++++++++++++++++++++++ test/integration/install.bats | 98 +++++++++++++++++++++++ 2 files changed, 243 insertions(+) diff --git a/install.sh b/install.sh index 6db90b1..79c62ae 100755 --- a/install.sh +++ b/install.sh @@ -154,6 +154,9 @@ do_uninstall() { local removed=0 + remove_claude_code_skill_symlinks + removed=$((removed + CLAUDE_SKILL_SYMLINKS_REMOVED)) + # Remove AGENTS.md if [[ -f "AGENTS.md" ]]; then if [[ "$DRY_RUN" == "true" ]]; then @@ -189,6 +192,42 @@ skipped_count=0 conflict_count=0 backup_count=0 BACKUP_DIR="" +CLAUDE_SKILL_SYMLINKS_REMOVED=0 + +is_dot_agents_claude_skill_symlink() { + local path="$1" + local link_target + + [[ -L "$path" ]] || return 1 + link_target="$(readlink "$path" 2>/dev/null || true)" + [[ "$link_target" == ../../.agents/skills/* ]] +} + +remove_claude_code_skill_symlinks() { + local claude_skills_dir=".claude/skills" + local skill_link + + CLAUDE_SKILL_SYMLINKS_REMOVED=0 + + [[ -d "$claude_skills_dir" ]] || return 0 + + for skill_link in "$claude_skills_dir"/*; do + [[ -L "$skill_link" ]] || continue + is_dot_agents_claude_skill_symlink "$skill_link" || continue + + if [[ "$DRY_RUN" == "true" ]]; then + log_info "${RED}[REMOVE]${NC} $skill_link" + else + rm -f "$skill_link" + log_info "${RED}[REMOVE]${NC} $skill_link" + fi + CLAUDE_SKILL_SYMLINKS_REMOVED=$((CLAUDE_SKILL_SYMLINKS_REMOVED + 1)) + done + + if [[ "$DRY_RUN" != "true" ]]; then + rmdir "$claude_skills_dir" 2>/dev/null || true + fi +} create_backup_dir() { if [[ -z "$BACKUP_DIR" ]]; then @@ -428,6 +467,107 @@ report_custom_skills() { fi } +cleanup_stale_claude_code_skill_symlinks() { + local agents_skills_dir="$1" + local claude_skills_dir="$2" + local skill_link skill_name + + [[ -d "$claude_skills_dir" ]] || return 0 + + for skill_link in "$claude_skills_dir"/*; do + [[ -L "$skill_link" ]] || continue + is_dot_agents_claude_skill_symlink "$skill_link" || continue + + skill_name="$(basename "$skill_link")" + [[ -f "$agents_skills_dir/$skill_name/SKILL.md" ]] && continue + + if [[ "$DRY_RUN" == "true" ]]; then + log_info " ${RED}[REMOVE]${NC} $skill_link (stale)" + else + rm -f "$skill_link" + log_info " ${RED}[REMOVE]${NC} $skill_link (stale)" + fi + done +} + +setup_claude_code_integration() { + local agents_skills_dir=".agents/skills" + local claude_skills_dir=".claude/skills" + local linked=0 + local skipped=0 + local skill_dir skill_name dest link_target existing_target + + [[ -d ".claude" ]] || return 0 + [[ -d "$agents_skills_dir" ]] || return 0 + + log_info "" + log_info "Detected ${BLUE}.claude/${NC} directory — linking dot-agents skills for Claude Code..." + + if [[ ( -e "$claude_skills_dir" || -L "$claude_skills_dir" ) && ! -d "$claude_skills_dir" ]]; then + log_info " ${YELLOW}[SKIP]${NC} $claude_skills_dir (user-owned)" + return 0 + fi + + if [[ "$DRY_RUN" != "true" ]]; then + if ! mkdir -p "$claude_skills_dir"; then + log_info " ${YELLOW}[SKIP]${NC} $claude_skills_dir (could not create directory)" + return 0 + fi + fi + + for skill_dir in "$agents_skills_dir"/*/; do + [[ -d "$skill_dir" ]] || continue + [[ -f "$skill_dir/SKILL.md" ]] || continue + + skill_name="$(basename "$skill_dir")" + dest="$claude_skills_dir/$skill_name" + link_target="../../.agents/skills/$skill_name" + + if [[ -L "$dest" ]]; then + existing_target="$(readlink "$dest" 2>/dev/null || true)" + if [[ "$existing_target" == "$link_target" ]]; then + continue + fi + if is_dot_agents_claude_skill_symlink "$dest"; then + if [[ "$DRY_RUN" == "true" ]]; then + log_info " ${GREEN}[LINK]${NC} $dest → $link_target" + linked=$((linked + 1)) + continue + fi + rm -f "$dest" + else + log_info " ${YELLOW}[SKIP]${NC} $dest (user-owned symlink)" + skipped=$((skipped + 1)) + continue + fi + elif [[ -e "$dest" ]]; then + log_info " ${YELLOW}[SKIP]${NC} $dest (user-owned)" + skipped=$((skipped + 1)) + continue + fi + + if [[ "$DRY_RUN" == "true" ]]; then + log_info " ${GREEN}[LINK]${NC} $dest → $link_target" + linked=$((linked + 1)) + continue + fi + + if ln -s "$link_target" "$dest"; then + log_info " ${GREEN}[LINK]${NC} $dest" + linked=$((linked + 1)) + else + log_info " ${YELLOW}[SKIP]${NC} $dest (could not create symlink)" + skipped=$((skipped + 1)) + fi + done + + cleanup_stale_claude_code_skill_symlinks "$agents_skills_dir" "$claude_skills_dir" + + if [[ $linked -gt 0 || $skipped -gt 0 ]]; then + log_info " Claude Code skills linked: $linked, skipped: $skipped" + fi +} + ensure_gitignore_entry() { local gitignore_file=".agents/.gitignore" local backup_entry="../.dot-agents-backup/" @@ -626,6 +766,11 @@ main() { # Ensure .agents/.gitignore includes backup directory ensure_gitignore_entry + # Link dot-agents skills into Claude Code's project skill directory when present. + if [[ "$DIFF_ONLY" != "true" ]]; then + setup_claude_code_integration + fi + # Skip metadata write in diff-only mode if [[ "$DIFF_ONLY" != "true" ]]; then write_metadata diff --git a/test/integration/install.bats b/test/integration/install.bats index 2925ed6..a681e64 100755 --- a/test/integration/install.bats +++ b/test/integration/install.bats @@ -413,3 +413,101 @@ teardown() { # Should NOT report core skills (they're from upstream) refute_output --partial "Custom skills preserved:" } + +# ===== Task 6: Claude Code skill discovery tests ===== + +@test "install creates Claude Code skill directory symlinks when .claude exists" { + mkdir -p .claude + + run bash "$INSTALL_SCRIPT" --yes + assert_success + + assert_output --partial "Claude Code skills linked" + + [ -L ".claude/skills/adapt" ] + [ -L ".claude/skills/ralph" ] + [ -L ".claude/skills/research" ] + [ -L ".claude/skills/tmux" ] + + local target + target="$(readlink .claude/skills/adapt)" + [ "$target" = "../../.agents/skills/adapt" ] + + # Directory symlinks expose supporting skill files, not just SKILL.md. + [ -f ".claude/skills/ralph/references/progress-format.md" ] +} + +@test "install does not create .claude when absent" { + run bash "$INSTALL_SCRIPT" --yes + assert_success + + [ ! -d ".claude" ] +} + +@test "install skips Claude Code integration when .claude/skills is user-owned file" { + mkdir -p .claude + echo "user file" > .claude/skills + + run bash "$INSTALL_SCRIPT" --yes + assert_success + + assert_output --partial ".claude/skills (user-owned)" + run cat .claude/skills + assert_output "user file" +} + +@test "install preserves existing Claude Code user skill directory" { + mkdir -p .claude/skills/adapt + echo "# User adapt skill" > .claude/skills/adapt/SKILL.md + + run bash "$INSTALL_SCRIPT" --yes + assert_success + + assert_output --partial "SKIP" + assert_output --partial ".claude/skills/adapt (user-owned)" + + [ ! -L ".claude/skills/adapt" ] + run cat .claude/skills/adapt/SKILL.md + assert_output "# User adapt skill" +} + +@test "install preserves existing Claude Code user symlink" { + mkdir -p .claude/skills + ln -s ../../elsewhere/adapt .claude/skills/adapt + + run bash "$INSTALL_SCRIPT" --yes + assert_success + + assert_output --partial "user-owned symlink" + + local target + target="$(readlink .claude/skills/adapt)" + [ "$target" = "../../elsewhere/adapt" ] +} + +@test "sync removes stale dot-agents Claude Code skill symlinks" { + mkdir -p .claude + + bash "$INSTALL_SCRIPT" --yes + ln -s ../../.agents/skills/old-skill .claude/skills/old-skill + + run bash "$INSTALL_SCRIPT" --yes + assert_success + + [ ! -L ".claude/skills/old-skill" ] +} + +@test "--uninstall removes only dot-agents Claude Code skill symlinks" { + mkdir -p .claude + + bash "$INSTALL_SCRIPT" --yes + mkdir -p .claude/skills/my-custom-skill + echo "# My Custom" > .claude/skills/my-custom-skill/SKILL.md + + run bash "$INSTALL_SCRIPT" --uninstall --yes + assert_success + + [ ! -L ".claude/skills/adapt" ] + [ ! -L ".claude/skills/ralph" ] + [ -f ".claude/skills/my-custom-skill/SKILL.md" ] +} From 95685c693c7e6b2628caed5be2dd03fd3f37294b Mon Sep 17 00:00:00 2001 From: Marius Colacioiu Date: Mon, 22 Jun 2026 14:44:35 +0200 Subject: [PATCH 2/3] Prepare release v0.2.0 Amp-Thread-ID: https://ampcode.com/threads/T-019eef40-4755-7055-86f1-45d4a0ec8294 Co-authored-by: Amp --- CHANGELOG.md | 13 ++++++++++++- README.md | 6 +++++- VERSION | 2 +- docs/skills.md | 11 +++++++++++ install.sh | 2 +- site/index.html | 2 +- 6 files changed, 31 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72f7330..09b67b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,16 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] +## [0.2.0] - 2026-06-22 + +### Added + +- Claude Code project skill discovery: when `.claude/` exists, install/sync links dot-agents skills into `.claude/skills/` so they can appear in Claude Code's `/` menu. + +### Fixed + +- Uninstall now removes dot-agents-managed Claude Code skill symlinks while preserving user-owned Claude Code skills. + ## [0.1.1] - 2026-02-04 ### Added @@ -54,6 +64,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Installer skip logic now correctly includes plans/TEMPLATE.md - Postfix increment operators causing script exit on bash 5.3+ with `set -e` ([#1](https://github.com/colmarius/dot-agents/issues/1)) -[Unreleased]: https://github.com/colmarius/dot-agents/compare/v0.1.1...HEAD +[Unreleased]: https://github.com/colmarius/dot-agents/compare/v0.2.0...HEAD +[0.2.0]: https://github.com/colmarius/dot-agents/compare/v0.1.1...v0.2.0 [0.1.1]: https://github.com/colmarius/dot-agents/compare/v0.1.0...v0.1.1 [0.1.0]: https://github.com/colmarius/dot-agents/releases/tag/v0.1.0 diff --git a/README.md b/README.md index 1b3c45b..f208795 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.s Pin a version: ```bash -curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.sh | bash -s -- --ref v1.0.0 +curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.sh | bash -s -- --ref v0.2.0 ``` ## Documentation @@ -20,6 +20,10 @@ curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.s - **[Full Docs](./docs/README.md)** — Concepts, skills reference - **[Website](https://dot-agents.dev)** — Landing page (source: [site/](./site/)) +## Agent Support + +dot-agents works with any AI coding agent that reads markdown instructions. When a project already has a `.claude/` directory, install/sync also links dot-agents skills into `.claude/skills/` so Claude Code can discover them as project skills. + ## Next Steps Then: diff --git a/VERSION b/VERSION index 17e51c3..0ea3a94 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1.1 +0.2.0 diff --git a/docs/skills.md b/docs/skills.md index 07b2b26..323a883 100644 --- a/docs/skills.md +++ b/docs/skills.md @@ -95,3 +95,14 @@ The `name` and `description` in the frontmatter are used for skill discovery. Th ### Preserving Custom Skills Custom skills in `.agents/skills/` are preserved during `sync.sh` updates. Only upstream skills (adapt, ralph, research, tmux) are updated—your custom skills remain untouched. + +## Claude Code Project Skill Discovery + +Claude Code discovers project skills in `.claude/skills//SKILL.md`. dot-agents keeps `.agents/skills/` as the source of truth, so when `install.sh` or `sync.sh` detects an existing `.claude/` directory it creates directory symlinks such as: + +```text +.claude/skills/adapt -> ../../.agents/skills/adapt +.claude/skills/ralph -> ../../.agents/skills/ralph +``` + +Directory symlinks expose the whole skill, including optional supporting files like `references/` and `scripts/`. The installer skips user-owned Claude Code skills and only removes dot-agents-managed symlinks during uninstall. diff --git a/install.sh b/install.sh index 79c62ae..7698e5f 100755 --- a/install.sh +++ b/install.sh @@ -51,7 +51,7 @@ Examples: curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.sh | bash # Install specific version - curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.sh | bash -s -- --ref v0.1.1 + curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.sh | bash -s -- --ref v0.2.0 # Preview changes first curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.sh | bash -s -- --dry-run diff --git a/site/index.html b/site/index.html index c02b861..69b86d1 100644 --- a/site/index.html +++ b/site/index.html @@ -61,7 +61,7 @@

Ship faster with structured AI workflows

Then point your agent at a real problem and iterate.

Pin a version - curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.sh | bash -s -- --ref v0.1.1 + curl -fsSL https://raw.githubusercontent.com/colmarius/dot-agents/main/install.sh | bash -s -- --ref v0.2.0
From e32de5df1489e499b3a33b9d5175c1f3d7aecd01 Mon Sep 17 00:00:00 2001 From: Marius Colacioiu Date: Mon, 22 Jun 2026 14:57:20 +0200 Subject: [PATCH 3/3] Document Claude Code skill discovery Amp-Thread-ID: https://ampcode.com/threads/T-019eef40-4755-7055-86f1-45d4a0ec8294 Co-authored-by: Amp --- QUICKSTART.md | 9 +++++++++ docs/README.md | 1 + site/index.html | 1 + 3 files changed, 11 insertions(+) diff --git a/QUICKSTART.md b/QUICKSTART.md index 1e0cf6c..7d2e799 100644 --- a/QUICKSTART.md +++ b/QUICKSTART.md @@ -47,6 +47,8 @@ your-project/ └── tmux/ ``` +If the project already has a `.claude/` directory, dot-agents also links skills into `.claude/skills/` so Claude Code can discover them as project skills and invoke them with slash commands such as `/adapt`. + ### Verify Installation **cmd:** @@ -55,6 +57,13 @@ ls -la .agents/ cat AGENTS.md | head -20 ``` +For Claude Code projects, you can also check: + +**cmd:** +```bash +ls -la .claude/skills/ +``` + ## 2. Adapt AGENTS.md **prompt:** diff --git a/docs/README.md b/docs/README.md index ed01508..7b9a7dd 100644 --- a/docs/README.md +++ b/docs/README.md @@ -13,6 +13,7 @@ ## Reference - [Skills](./skills.md) +- [Claude Code Project Skill Discovery](./skills.md#claude-code-project-skill-discovery) - [AGENTS.md Template](../AGENTS.md) ## For Contributors diff --git a/site/index.html b/site/index.html index 69b86d1..f93d6ae 100644 --- a/site/index.html +++ b/site/index.html @@ -76,6 +76,7 @@

What you get

├── research/ # Discoveries and context └── skills/ # adapt, ralph, research, tmux +

Using Claude Code? If .claude/ already exists, install/sync links these skills into .claude/skills/ for project skill discovery.