Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .ruler/mcp.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
},
"GitHub": {
"command": "sh",
"args": ["-c", "exec mcp-remote 'https://api.githubcopilot.com/mcp/' --header \"Authorization:Bearer $(gh auth token)\""]
"args": [
"-c",
"exec mcp-remote 'https://api.githubcopilot.com/mcp/' --header \"Authorization:Bearer $(gh auth token)\""
]
},
"MemPalace": {
"command": "python3-mempalace",
Expand Down
212 changes: 9 additions & 203 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ RULES_TARGET_DIR := $(dir $(lastword $(MAKEFILE_LIST))).ruler
SKILLS_SRC_DIR := $(dir $(lastword $(MAKEFILE_LIST)))skills
SKILLS_RULER_DIR := $(dir $(lastword $(MAKEFILE_LIST))).ruler/skills
SKILLS_TARGET_DIRS := $(HOME)/.claude/skills $(HOME)/.cursor/skills $(HOME)/.codex/skills $(HOME)/.roo/skills $(HOME)/.gemini/skills $(HOME)/.agents/skills $(HOME)/.vibe/skills $(HOME)/.config/opencode/skills
SKILLS_STATE_DIR := $(HOME)/.cache/dotagents/skills
SKILLS_MANIFEST_DIR := $(SKILLS_STATE_DIR)/manifests
SKILLS_SPEC_STATE_FILE := $(SKILLS_STATE_DIR)/skills.txt.normalized
SKILLS_EXTERNAL_SOURCE_DIR := $(HOME)/.agents/skills
SKILLS_SCRIPTS_DIR := $(dir $(lastword $(MAKEFILE_LIST)))scripts

MCP_SRC := $(dir $(lastword $(MAKEFILE_LIST))).ruler/mcp.json
MCP_TARGET_DIRS := $(HOME)/.cursor $(HOME)/.claude $(HOME)/.codex
Expand All @@ -27,8 +24,6 @@ MCP_SETTINGS_TARGETS := $(addsuffix /settings.local.json,$(MCP_TARGET_DIRS)) $(d
DOTDIRS := .agent .agents .amazonq .augment .claude .cursor .gemini .idx .junie .kilocode .kiro .opencode .openhands .pi .qwen .roo .skillz .trae .vibe .vscode .windsurf .zed
DOTDIRS_SRC_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))

SKILLS_FILE := $(dir $(lastword $(MAKEFILE_LIST)))SKILLS.txt

# ====================================================================================
# ROOT TARGETS
# ====================================================================================
Expand Down Expand Up @@ -82,208 +77,19 @@ ruler-rules-copy: ## Copy rules to .ruler directory.
# ====================================================================================
# SKILLS
# ====================================================================================

.PHONY: skills-clean
skills-clean: ## Remove all globally installed skills and cached install state.
@for target in $(SKILLS_TARGET_DIRS); do \
if [ -d "$$target" ]; then \
rm -rf "$$target"/*; \
echo "Cleaned $$target"; \
fi; \
done
@if [ -d "$(SKILLS_STATE_DIR)" ]; then \
rm -rf "$(SKILLS_STATE_DIR)"; \
echo "Cleared $(SKILLS_STATE_DIR)"; \
fi

.PHONY: skills-managed-clean
skills-managed-clean: ## Remove managed external skills recorded from SKILLS.txt.
@manifest_dir="$(SKILLS_MANIFEST_DIR)"; \
if [ -d "$$manifest_dir" ]; then \
for manifest in "$$manifest_dir"/*.skills; do \
if [ ! -f "$$manifest" ]; then \
continue; \
fi; \
while IFS= read -r skill || [ -n "$$skill" ]; do \
if [ -z "$$skill" ]; then \
continue; \
fi; \
for target in $(SKILLS_TARGET_DIRS); do \
if [ -e "$$target/$$skill" ] || [ -L "$$target/$$skill" ]; then \
rm -rf "$$target/$$skill"; \
echo "Removed $$target/$$skill"; \
fi; \
done; \
done < "$$manifest"; \
done; \
fi
@if [ -d "$(SKILLS_STATE_DIR)" ]; then \
rm -rf "$(SKILLS_STATE_DIR)"; \
echo "Cleared $(SKILLS_STATE_DIR)"; \
fi
# External skills are declared in SKILLS.txt and locked in skills-lock.json.

.PHONY: skills-install
skills-install: ## Ensure skills from SKILLS.txt are installed and reconcile managed removals.
@state_dir="$(SKILLS_STATE_DIR)"; \
manifest_dir="$(SKILLS_MANIFEST_DIR)"; \
spec_state="$(SKILLS_SPEC_STATE_FILE)"; \
external_source="$(SKILLS_EXTERNAL_SOURCE_DIR)"; \
tmp_spec=$$(mktemp); \
spec_changed=0; \
failed=0; \
mkdir -p "$$state_dir" "$$manifest_dir" "$$external_source"; \
list_external_skills() { \
if [ -d "$$external_source" ]; then \
find "$$external_source" -mindepth 1 -maxdepth 1 \( -type d -o -type l \) -exec basename {} \; | LC_ALL=C sort -u; \
fi; \
}; \
remove_repo_skills() { \
manifest_file="$$1"; \
if [ ! -f "$$manifest_file" ]; then \
return 0; \
fi; \
while IFS= read -r skill || [ -n "$$skill" ]; do \
if [ -z "$$skill" ]; then \
continue; \
fi; \
for target in $(SKILLS_TARGET_DIRS); do \
if [ -e "$$target/$$skill" ] || [ -L "$$target/$$skill" ]; then \
rm -rf "$$target/$$skill"; \
fi; \
done; \
done < "$$manifest_file"; \
}; \
list_repo_skills() { \
repo="$$1"; \
bun x skills add $$repo --global --yes --list </dev/null 2>&1 \
| sed 's/\x1b\[[0-9;]*m//g' \
| sed 's/\x1b\[?25[hl]//g' \
| sed 's/\x1b\[999D\x1b\[J//g' \
| grep -E '^│[[:space:]]{4}[a-z]' \
| sed 's/^│[[:space:]]*//'; \
}; \
install_repo() { \
repo="$$1"; \
normalized_skills="$$2"; \
manifest_file="$$3"; \
cleanup_old="$$4"; \
if [ "$$cleanup_old" = "1" ]; then \
remove_repo_skills "$$manifest_file"; \
fi; \
if [ -n "$$normalized_skills" ]; then \
skill_args=$$(printf '%s\n' "$$normalized_skills" | tr ',' '\n' | sed '/^$$/d' | while IFS= read -r s; do printf " --skill %s" "$$s"; done); \
echo "Installing selected skills from $$repo..."; \
if bun x skills add $$repo --global --yes $$skill_args </dev/null; then \
printf '%s\n' "$$normalized_skills" | tr ',' '\n' | sed '/^$$/d' | LC_ALL=C sort > "$$manifest_file"; \
echo "✓ Installed $$repo (selective)"; \
else \
echo "✗ Failed to install $$repo (continuing...)"; \
failed=1; \
fi; \
else \
echo "Installing all skills from $$repo..."; \
if bun x skills add $$repo --global --yes </dev/null; then \
list_repo_skills "$$repo" | LC_ALL=C sort > "$$manifest_file"; \
echo "✓ Installed $$repo (all)"; \
else \
echo "✗ Failed to install $$repo (continuing...)"; \
failed=1; \
fi; \
fi; \
}; \
while IFS= read -r raw_line || [ -n "$$raw_line" ]; do \
line=$$(printf '%s' "$$raw_line" | sed 's/^[[:space:]]*//; s/[[:space:]]*$$//'); \
case "$$line" in \
''|\#*) continue ;; \
esac; \
repo=$$(printf '%s\n' "$$line" | awk '{print $$1}'); \
skills_csv=$$(printf '%s\n' "$$line" | awk '{print $$2}'); \
normalized_skills=$$(printf '%s\n' "$$skills_csv" | tr ',' '\n' | sed '/^$$/d' | LC_ALL=C sort | paste -sd, -); \
printf '%s|%s\n' "$$repo" "$$normalized_skills" >> "$$tmp_spec"; \
done < "$(SKILLS_FILE)"; \
if [ "$${DOTAGENTS_FORCE_SKILLS_INSTALL:-0}" = "1" ]; then \
echo "Forcing managed external skill reinstall..."; \
$(MAKE) skills-managed-clean; \
mkdir -p "$$state_dir" "$$manifest_dir" "$$external_source"; \
while IFS='|' read -r repo normalized_skills || [ -n "$$repo$$normalized_skills" ]; do \
manifest_file="$$manifest_dir/$$(printf '%s' "$$repo" | sed 's#[^A-Za-z0-9_.-]#_#g').skills"; \
install_repo "$$repo" "$$normalized_skills" "$$manifest_file" 0; \
done < "$$tmp_spec"; \
else \
if [ -f "$$spec_state" ] && ! cmp -s "$$tmp_spec" "$$spec_state"; then \
echo "Detected SKILLS.txt changes; applying incremental update..."; \
while IFS='|' read -r old_repo old_skills || [ -n "$$old_repo$$old_skills" ]; do \
if ! grep -qF "$$old_repo|" "$$tmp_spec"; then \
echo "Removing $$old_repo (deleted from SKILLS.txt)..."; \
manifest_file="$$manifest_dir/$$(printf '%s' "$$old_repo" | sed 's#[^A-Za-z0-9_.-]#_#g').skills"; \
remove_repo_skills "$$manifest_file"; \
rm -f "$$manifest_file"; \
fi; \
done < "$$spec_state"; \
fi; \
while IFS='|' read -r repo normalized_skills || [ -n "$$repo$$normalized_skills" ]; do \
manifest_file="$$manifest_dir/$$(printf '%s' "$$repo" | sed 's#[^A-Za-z0-9_.-]#_#g').skills"; \
reinstall_repo=0; \
if [ -f "$$spec_state" ]; then \
old_line=$$(grep "^$$repo|" "$$spec_state" 2>/dev/null || true); \
new_line="$$repo|$$normalized_skills"; \
if [ -n "$$old_line" ] && [ "$$old_line" != "$$new_line" ]; then \
reinstall_repo=1; \
echo "Reinstalling $$repo (skills selection changed)"; \
fi; \
fi; \
if [ "$$reinstall_repo" = "0" ]; then \
if [ ! -f "$$manifest_file" ] || [ ! -s "$$manifest_file" ]; then \
reinstall_repo=1; \
echo "Reinstalling $$repo (missing or empty manifest)"; \
else \
while IFS= read -r skill || [ -n "$$skill" ]; do \
if [ -z "$$skill" ]; then \
continue; \
fi; \
if [ ! -e "$$external_source/$$skill" ] && [ ! -L "$$external_source/$$skill" ]; then \
reinstall_repo=1; \
echo "Reinstalling $$repo (missing $$external_source/$$skill)"; \
break; \
fi; \
done < "$$manifest_file"; \
fi; \
fi; \
if [ "$$reinstall_repo" = "1" ]; then \
install_repo "$$repo" "$$normalized_skills" "$$manifest_file" 1; \
else \
echo "Skipping $$repo (installed state matches SKILLS.txt)"; \
fi; \
done < "$$tmp_spec"; \
fi; \
cp "$$tmp_spec" "$$spec_state"; \
rm -f "$$tmp_spec"; \
if [ "$$failed" = "1" ]; then \
echo "Some skills failed to install (see above)."; \
else \
echo "Managed external skills are in sync."; \
fi
skills-install: ## Install external skills from skills-lock.json (skips already installed).
@bun run $(SKILLS_SCRIPTS_DIR)/skills-install.ts

.PHONY: skills-refresh
skills-refresh: ## Force a clean reinstall of external skills and re-sync local repo skills.
@$(MAKE) skills-managed-clean
@DOTAGENTS_FORCE_SKILLS_INSTALL=1 $(MAKE) skills-install
@$(MAKE) skills-sync
skills-refresh: ## Force a reinstall of all external skills from skills-lock.json.
@bun run $(SKILLS_SCRIPTS_DIR)/skills-install.ts --force

.PHONY: skills-install-repo
skills-install-repo: ## Install a single skill repo. Usage: make skills-install-repo REPO=owner/repo [SKILLS=a,b,c]
@if [ -z "$(REPO)" ]; then \
echo "Error: REPO is required. Usage: make skills-install-repo REPO=owner/repo"; \
exit 1; \
fi
@if [ -n "$(SKILLS)" ]; then \
echo "Installing selected skills from $(REPO) ($(SKILLS))..."; \
bun x skills add $(REPO) --global --yes $(shell echo "$(SKILLS)" | tr ',' '\n' | sed '/^$$/d' | while read -r s; do printf " --skill $$s"; done); \
else \
echo "Installing all skills from $(REPO)..."; \
bun x skills add $(REPO) --global --yes; \
fi
@echo "✓ Installed $(REPO)"
.PHONY: skills-lock
skills-lock: ## Regenerate skills-lock.json from SKILLS.txt.
@bun run $(SKILLS_SCRIPTS_DIR)/skills-lock.ts

.PHONY: ruler-skills-copy
ruler-skills-copy: ## Copy skills from root to .ruler/skills directory (overwrites, preserves other files).
Expand Down
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,23 @@ Rules for Agents
make sync
```

This runs the full pipeline: prepares `.ruler/`, generates agent instruction files (`~/.claude/CLAUDE.md`, etc.) via Ruler, reconciles managed external skills from `SKILLS.txt` against the actual installed skill directories, then syncs commands, local repo skills, MCP config, and dot directories to `$HOME`.
This runs the full pipeline: prepares `.ruler/`, generates agent instruction files (`~/.claude/CLAUDE.md`, etc.) via Ruler, installs external skills from `skills-lock.json`, then syncs commands, local repo skills, MCP config, and dot directories to `$HOME`.

To force a clean reinstall of external skills, run:
## External skills

External skills are declared in `SKILLS.txt` (canonical: repo plus comma-separated selection, no selection installs all) and locked in `skills-lock.json`, both committed. Installs go through the [skills CLI](https://github.com/vercel-labs/skills); global scope is scripted here because the CLI's own lock restore is project-only (see [vercel-labs/skills#549](https://github.com/vercel-labs/skills/issues/549)).

```bash
# Regenerate skills-lock.json from SKILLS.txt
make skills-lock

# Install everything in the lock that is missing (idempotent)
make skills-install

# Force a reinstall of everything in the lock
make skills-refresh
```

To add skills: edit `SKILLS.txt`, run `make skills-lock && make skills-install && make skills-lock` (the second lock captures resolved metadata), and commit both files. To remove: delete from `SKILLS.txt`, run `bunx skills remove <name> --global --yes`, then `make skills-lock`.

Installs track each source's default branch: the skills CLI does not record commit SHAs in its lock yet, so entries are not pinned to a commit.
19 changes: 8 additions & 11 deletions SKILLS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ anthropics/knowledge-work-plugins memory-management,start,task-management,update
austintgriffith/ethskills ethskills

# better-auth/skills (5 total) - keep all
better-auth/skills better-auth-best-practices,create-auth-skill,email-and-password-best-practices,organization-best-practices,two-factor-authentication-best-practices

# better-context/skills - keep btca-local
better-context/skills btca-local
better-auth/skills better-auth-best-practices,create-auth,email-and-password-best-practices,organization-best-practices,two-factor-authentication-best-practices

# blader/arbitrage (1 total) - keep all
blader/arbitrage arbitrage
Expand Down Expand Up @@ -65,13 +62,13 @@ garrytan/gstack gstack
getsentry/skills agents-md,claude-settings-audit,code-review,code-simplifier,commit,create-branch,find-bugs,gh-review-requests,gha-security-review,iterate-pr,pr-writer,security-review

# github/awesome-copilot (257 total) - keep essential dev/infra skills
github/awesome-copilot chrome-devtools,conventional-commit,create-implementation-plan,create-readme,create-specification,dependabot,doublecheck,editorconfig,eval-driven-dev,git-commit,github-issues,make-repo-contribution,multi-stage-dockerfile,my-issues,my-pull-requests,playwright-generate-test,prd,pytest-coverage,refactor,refactor-plan,secret-scanning,security-review,typescript-mcp-server-generator,update-implementation-plan,webapp-testing
github/awesome-copilot chrome-devtools,conventional-commit,create-implementation-plan,create-readme,create-specification,dependabot,doublecheck,editorconfig,eval-driven-dev,git-commit,github-issues,make-repo-contribution,multi-stage-dockerfile,playwright-generate-test,prd,pytest-coverage,refactor,refactor-plan,secret-scanning,security-review,typescript-mcp-server-generator,update-implementation-plan,webapp-testing

# github/gh-stack (1 total) - keep all
github/gh-stack gh-stack

# google/skills (58 total) - keep all
google/skills agent-platform-alert-configuration,agent-platform-deploy,agent-platform-endpoint-management,agent-platform-eval-flywheel,agent-platform-inference,agent-platform-migrate-from-ai-studio,agent-platform-model-registry,agent-platform-prompt-management,agent-platform-rag-engine-management,agent-platform-skill-registry,agent-platform-tuning,agent-platform-tuning-management,alloydb-basics,bigquery-ai-ml,bigquery-basics,bigquery-bigframes,bigtable-basics,cloud-run-basics,cloud-sql-basics,datalineage-bigquery-asset-impact-analysis,detection-engineering-coverage-evaluation,firebase-basics,gcloud,gemini-agents-api,gemini-api,gemini-interactions-api,gke-app-onboarding,gke-backup-dr,gke-basics,gke-batch-hpc,gke-cluster-creation,gke-compute-classes,gke-cost,gke-golden-path,gke-inference,gke-multitenancy,gke-networking,gke-observability,gke-reliability,gke-scaling,gke-security,gke-storage,gke-upgrades,google-agents-cli-onboarding,google-analytics-admin-api-basics,google-analytics-data-api-basics,google-cloud-networking-observability,google-cloud-recipe-auth,google-cloud-recipe-foundation-builder,google-cloud-recipe-onboarding,google-cloud-waf-cost-optimization,google-cloud-waf-operational-excellence,google-cloud-waf-performance-optimization,google-cloud-waf-reliability,google-cloud-waf-security,google-cloud-waf-sustainability,iam-recommendations-fetcher,workload-manager-basics
google/skills agent-platform-alert-configuration,agent-platform-deploy,agent-platform-endpoint-management,agent-platform-eval-flywheel,agent-platform-inference,agent-platform-migrate-from-ai-studio,agent-platform-model-registry,agent-platform-prompt-management,agent-platform-rag-engine-management,agent-platform-skill-registry,agent-platform-tuning,agent-platform-tuning-management,alloydb-basics,bigquery-ai-ml,bigquery-basics,bigquery-bigframes,bigtable-basics,cloud-run-basics,cloud-sql-basics,datalineage-bigquery-asset-impact-analysis,detection-engineering-coverage-evaluation,firebase-basics,gcloud,gemini-agents-api,gemini-api,gemini-interactions-api,gke-app-onboarding,gke-backup-dr,gke-basics,gke-batch-hpc,gke-cluster-creation,gke-compute-classes,gke-cost-analysis,gke-cost-optimization,gke-golden-path,gke-inference,gke-multitenancy,gke-networking,gke-observability,gke-reliability,gke-workload-scaling,gke-platform-security,gke-workload-security,gke-storage,gke-upgrades,google-agents-cli-onboarding,google-analytics-admin-api-basics,google-analytics-data-api-basics,google-cloud-networking-observability,google-cloud-recipe-auth,google-cloud-recipe-foundation-builder,google-cloud-recipe-onboarding,google-cloud-waf-cost-optimization,google-cloud-waf-operational-excellence,google-cloud-waf-performance-optimization,google-cloud-waf-reliability,google-cloud-waf-security,google-cloud-waf-sustainability,workload-manager-basics

# googleworkspace/cli (93 total) - keep core gmail/calendar/drive
googleworkspace/cli gws-calendar,gws-calendar-agenda,gws-calendar-insert,gws-docs,gws-docs-write,gws-drive,gws-drive-upload,gws-gmail,gws-gmail-read,gws-gmail-send,gws-sheets,gws-sheets-read,gws-tasks
Expand All @@ -86,7 +83,7 @@ higgsfield-ai/skills higgsfield-generate,higgsfield-marketplace-cards,higgsfield
https://index.how/to/articulate

# inference-sh/skills (78 total) - keep core tools
inference-sh/skills web-search,web-research,ai-sdk,agent-browser,agent-ui
inference-sh/skills web-search,agent-browser,agent-ui

# Jakubantalik/transitions.dev (1 total) - keep all
Jakubantalik/transitions.dev transitions-dev
Expand All @@ -104,7 +101,7 @@ kitlangton/skills effect
kucherenko/jscpd dry-refactoring,jscpd

# kunchenguid/axi (2 total) - keep all
kunchenguid/axi axi,no-mistakes
kunchenguid/axi axi

# kunchenguid/no-mistakes (1 total) - keep all
kunchenguid/no-mistakes
Expand All @@ -122,10 +119,10 @@ ogulcancelik/herdr herdr
openclaw/agent-skills autoreview

# PaulRBerg/agent-skills (23 total) - keep dev tools
PaulRBerg/agent-skills biome-js,bump-deps,bump-release,cli-gh,code-polish,code-review,code-simplify,effect-ts,md-docs,tailwind-css,yeet
PaulRBerg/agent-skills bump-deps,bump-release,cli-gh,code-polish,effect-ts,tailwind-css,yeet

# mattpocock/skills (38 total) - keep all
mattpocock/skills ask-matt,claude-handoff,code-review,codebase-design,design-an-interface,diagnosing-bugs,domain-modeling,edit-article,git-guardrails-claude-code,grill-me,grill-with-docs,grilling,handoff,implement,improve-codebase-architecture,loop-me,migrate-to-shoehorn,obsidian-vault,prototype,qa,request-refactor-plan,research,resolving-merge-conflicts,scaffold-exercises,setup-matt-pocock-skills,setup-pre-commit,tdd,teach,to-issues,to-prd,triage,ubiquitous-language,wayfinder,wizard,writing-beats,writing-fragments,writing-great-skills,writing-shape
mattpocock/skills ask-matt,claude-handoff,code-review,codebase-design,design-an-interface,diagnosing-bugs,domain-modeling,edit-article,git-guardrails-claude-code,grill-me,grill-with-docs,grilling,handoff,implement,improve-codebase-architecture,loop-me,migrate-to-shoehorn,obsidian-vault,prototype,qa,request-refactor-plan,research,resolving-merge-conflicts,scaffold-exercises,setup-matt-pocock-skills,setup-pre-commit,tdd,teach,to-tickets,to-spec,triage,ubiquitous-language,wayfinder,wizard,writing-beats,writing-fragments,writing-great-skills,writing-shape

# max-sixty/worktrunk (2 total) - keep all
max-sixty/worktrunk worktrunk,wt-switch-create
Expand Down Expand Up @@ -191,7 +188,7 @@ vercel/chat add-adapter,chat-sdk
vercel/turborepo turborepo

# vercel-labs/agent-browser (5 total) - keep core
vercel-labs/agent-browser agent-browser,vercel-sandbox
vercel-labs/agent-browser agent-browser

# vercel-labs/agent-skills (6 total) - keep core
vercel-labs/agent-skills vercel-composition-patterns,deploy-to-vercel,vercel-react-best-practices,vercel-cli-with-tokens
Expand Down
Loading