Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 0 additions & 2 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ jobs:
sudo apt-get install -y yamllint shellcheck
curl -fsSL https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash | bash
sudo mv actionlint /usr/local/bin/actionlint
sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
sudo chmod +x /usr/local/bin/yq

- name: Lint
run: make lint
Expand Down
14 changes: 1 addition & 13 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,5 @@ vscode-settings.json

.claude/worktrees/**

# Private shared configs
ai-stuff/_shared/**/_*.md

# Private cluster context map (contains sensitive account/cluster names)
ai-stuff/claude/config/.clusters.json
ai-stuff/_shared/config/.clusters.json

ai-stuff/claude/skills/add-recipe/*.original*
ai-stuff/claude/skills/**/SKILL.original.md

# Private work-specific traefik migration config. The skill, traefik-dev and traefik-recon moved into
# k8s-gitops-platform-apps on 2026-08-12; only the personal Obsidian layer stays here.
ai-stuff/_shared/config/traefik-epic.md
# Private work-specific agent
ai-stuff/agents/traefik-vault.md
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ include makefiles/shell.mk
include makefiles/tools.mk
include makefiles/utils.mk
include makefiles/ai.mk
include makefiles/skills.mk
include makefiles/claude.mk
include makefiles/cursor.mk
include makefiles/codex.mk
include makefiles/raycast.mk
include makefiles/raycast.mk
include makefiles/targets.mk
include makefiles/ci.mk

Expand Down
56 changes: 28 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ Personal dotfiles and AI tooling for macOS, with a handful of Linux paths. Every
install is a symlink back into this repo, so editing a file here changes the live
configuration immediately and nothing gets copied into `$HOME`.

A shared skill library in [`ai-stuff/skills/`](ai-stuff/skills/) installs into
Claude Code, Codex, Cursor, and anything else that reads the cross-tool
`~/.agents/skills` directory. See [`ai-stuff/README.md`](ai-stuff/README.md).
AI tool configuration for Claude Code, Codex, and Cursor lives in
[`ai-stuff/`](ai-stuff/README.md). Skills live in a separate repo,
[`dgokcin/skills`](https://github.com/dgokcin/skills), and `make skills`
installs them into each tool.

## 📁 Layout

```
.
├── Makefile entry point; includes makefiles/*.mk, defines shared macros
├── makefiles/ one .mk per concern, plus helper scripts in scripts/
├── ai-stuff/ skills, agents, and per-tool AI settings
├── ai-stuff/ agents, shared AI content, and per-tool AI settings
├── nvim/ Neovim config (LazyVim + lazy.nvim, Lua)
├── other/ app configs: lazygit, k9s, tmux, yamllint, vscode, winterm
├── Brewfile Homebrew taps, formulae, casks, and fonts
Expand All @@ -39,11 +40,11 @@ Or run the layers separately:
make brew-bundle # Homebrew packages, casks, and fonts
make tools # Volta/Node plus preferred standalone and npm CLIs
make personal # shell, editors, git, and tool configs
make claude # native CLI, agents, hooks, settings, keybindings, skills
make cursor # agents, hooks, settings, keybindings, skills
make codex # standalone CLI, hooks, AGENTS.md, config, skills
make claude # native CLI, agents, hooks, settings, keybindings
make cursor # agents, hooks, settings, keybindings
make codex # standalone CLI, hooks, AGENTS.md, config
make raycast # script commands plus Raycast preferences (macOS)
make ai # skills only, into every registered tool
make ai-shared # shared AI content only, into ~/.config/ai-shared
```

Run `make help` for the full target list.
Expand Down Expand Up @@ -115,27 +116,27 @@ this repo. Registering the script directory is a one-time click. See

| Target | Does |
| --- | --- |
| `ai` | Run `ai-check`, link shared content, install skills into every registered tool |
| `ai-check` | Lint `SKILL.md` against `agents/openai.yaml` on invocation policy, legacy keys, and stale files |
| `ai-shared` | Link `ai-stuff/_shared` to `~/.config/ai-shared` |
| `ai-list` | Print the skill inventory and tool registry |
| `ai-skill-meta` | Scaffold a missing `agents/openai.yaml` |
| `ai-clean` | Remove installed skills everywhere |
| `claude` | Native Claude Code CLI plus agents, scripts, settings, keybindings, output styles, and `ai-claude` |
| `cursor` | Cursor agents, hook scripts, hooks.json, CLI config, editor settings, plus `ai-agents` |
| `codex` | Standalone Codex CLI plus hooks, scripts, `AGENTS.md`, managed `config.toml`, and `ai-agents` |

Skills are authored once in `ai-stuff/skills/` and symlinked verbatim into each
tool's skills directory. Adding a tool takes two lines in
[`makefiles/ai.mk`](makefiles/ai.mk), and adding a skill needs no Makefile change
at all.
| `claude` | Native Claude Code CLI plus agents, scripts, settings, keybindings, output styles, and `ai-shared` |
| `cursor` | Cursor agents, hook scripts, hooks.json, CLI config, editor settings |
| `codex` | Standalone Codex CLI plus hooks, scripts, `AGENTS.md`, managed `config.toml` |
| `skills` | Clone `~/codes/skills`, pick skills in the `skills` CLI picker, and link them live |
| `skills-all` | Same as `skills`, but installs every skill without prompting |
| `skills-remove` | Pick installed skills to remove |
| `skills-list` | List globally installed skills |

`make skills` runs `npx skills add ~/codes/skills -g` for Claude Code, Codex,
and Cursor. The CLI copies each pick into `~/.agents/skills`, and
`makefiles/scripts/skills-link.sh` swaps those copies for symlinks into
`~/codes/skills`. Skills keep bare names like `/create-pr`, and edits apply
live. Run `make skills` again to pick up a new skill.

### ✅ Checks

| Target | Does |
| --- | --- |
| `lint` | actionlint, shellcheck, yamllint, JSON parse check |
| `test` | Skill metadata lint plus statusline fixture tests |
| `test` | Statusline fixture tests |
| `test-bootstrap` | Dry-run bootstrap and assert every preferred installer is wired in |
| `install-ci` | Symlink install into an isolated `$HOME`, no brew |
| `verify-install` | Assert those symlinks point back at this repo |
Expand All @@ -154,10 +155,9 @@ version and [`CHANGELOG.md`](CHANGELOG.md) from conventional commit messages.

## 🔒 Private files

Some files are gitignored because they carry personal or work-specific detail.
The tracked file is the template, and the private variant sits beside it with a
leading underscore or a dot prefix.
Private skill config (Jira IDs, cluster names, Slack IDs, GitLab hosts) lives in
the gitignored `~/codes/skills/local/`, which `make skills` links to
`~/.config/dgokcin-skills`.

- `ai-stuff/_shared/config/_*.md`
- `ai-stuff/_shared/config/.clusters.json` (cluster and account names)
- `ai-stuff/_shared/config/traefik-epic.md`
The only gitignored file here is `ai-stuff/agents/traefik-vault.md`, a
work-specific agent.
157 changes: 33 additions & 124 deletions ai-stuff/README.md
Original file line number Diff line number Diff line change
@@ -1,142 +1,51 @@
# AI Stuff — Universal Skills, One Source of Truth
# AI Stuff

Skills are authored **once** in [`skills/`](skills/) using the
[Agent Skills](https://agentskills.io) standard (the format Claude Code,
Codex, Cursor, Gemini CLI, and ~50 other tools read natively) and installed
into every tool by symlink. Switching or adding an LLM provider costs one
line in a Makefile table — never a second copy of a skill.

The approach mirrors [BMAD-METHOD](https://github.com/bmad-code-org/BMAD-METHOD)'s
platform installer (`tools/installer/ide/platform-codes.yaml`): one
tool-agnostic skill format + a per-tool directory registry + verbatim
installation. No per-tool transformation, no drift.
Per-tool AI configuration plus the content those tools share. Skills live in
a separate repo, `~/codes/skills`, and `make skills` installs them into
`~/.claude/skills` and `~/.agents/skills` (see [`makefiles/skills.mk`](../makefiles/skills.mk)).

## Layout

```
ai-stuff/
├── skills/ # ⭐ single source of truth — universal Agent Skills
│ ├── _shared -> ../_shared # makes relative ../_shared/... refs resolve
│ ├── slackify/
│ │ ├── SKILL.md # frontmatter drives Claude Code
│ │ └── agents/openai.yaml # picker metadata + policy for Codex
│ ├── daily-recap/SKILL.md + agents/ + scripts/
│ ├── vault-capture/SKILL.md + agents/ + references/
│ ├── .archived/ # retired skills (never installed)
│ └── ...
├── invocation.md # user- vs model-invoked rules, Skill-tool phrasing, openai.yaml schema
├── _shared/ # configs, templates referenced by skills+agents
│ ├── config/ # git-config, jira-config, .clusters.json, ...
│ └── templates/ # property/daily-recap output templates
├── _shared/ # tool-agnostic content, linked to ~/.config/ai-shared
│ └── scripts/ # hook scripts shared across tools
├── agents/ # subagent definitions (Claude Code + Cursor)
├── claude/ # Claude Code-specific settings, keybindings, and hook scripts
├── codex/ # Codex-specific layer
└── cursor/ # Cursor-specific settings, keybindings, agents, and hooks
├── output-styles/ # Claude Code output styles
├── claude/ # Claude Code settings, keybindings, hook scripts, mods
├── codex/ # Codex hooks, AGENTS.md, managed config.toml block
└── cursor/ # Cursor hooks, CLI config, editor settings, keybindings
```

## Installation

Driven by [`makefiles/ai.mk`](../makefiles/ai.mk) — the tool registry:

| Target | Installs to | Covers |
| ------------ | ------------------ | -------------------------------------------------------------------- |
| `ai-claude` | `~/.claude/skills` | Claude Code |
| `ai-agents` | `~/.agents/skills` | Codex, Cursor, Gemini CLI, Windsurf, Copilot, Roo, OpenHands, … |

Codex has no dedicated target: it ignores `~/.codex/skills` and reads only
`.agents/skills` (repo + `$HOME`), so `ai-agents` covers it. Cursor natively
also scans `~/.claude/skills` and `~/.claude/agents` — those entries are the
same symlinked files, deduplicated by `name`.

```bash
make ai # ai-check, then install skills into all registered tools
make ai-check # lint SKILL.md <-> agents/openai.yaml (invocation policy, legacy keys, leftovers)
make ai-skill-meta # scaffold agents/openai.yaml for skills missing one
make ai-list # show skills + tool registry
make ai-clean # remove installed skills everywhere
make claude # claude layer (agents/configs/scripts/settings) + ai-claude
make cursor # cursor agents + ai-agents (+ prunes legacy ~/.cursor layout)
make codex # codex layer (hooks/AGENTS.md/config.toml managed block) + ai-agents
```

Each install: prune legacy names → `rm` old entry → symlink the whole skill
directory. Whole-dir symlinks mean new files inside a skill (references,
scripts) ship without touching any Makefile.

**Add a tool** (e.g. Cline) — 2 lines in `ai.mk`:

```make
AI_TOOLS += cline
ai_skills_dir_cline := ${HOME}/.cline/skills
```
| Target | Installs |
| ----------- | --------------------------------------------------------------- |
| `ai-shared` | `ai-stuff/_shared` to `~/.config/ai-shared` |
| `claude` | agents, output styles, scripts, settings, keybindings, `ai-shared` |
| `cursor` | agents, hook scripts, hooks.json, CLI config, editor settings |
| `codex` | hooks, `AGENTS.md`, `RTK.md`, managed `config.toml` block |

**Add a skill** — create `ai-stuff/skills/<name>/SKILL.md`, decide whether it
is user- or model-invoked per [`invocation.md`](invocation.md), run
`make ai-skill-meta` and curate the generated `agents/openai.yaml`
`short_description`, then `make ai`. Discovery is by wildcard; `ai-check`
refuses to install if the two metadata files disagree.
Every install is a symlink back into this repo.

**Retire a skill** — move its dir to `skills/.archived/` and append the name
to `AI_LEGACY_SKILLS` in `ai.mk` so installs prune it everywhere (BMAD's
`removals.txt` pattern).
## Shared content

## Portability conventions

Skills must work in any tool. Rules used throughout `skills/`:

1. **Shared content = relative markdown links.**
`[git config](../_shared/config/git-config.md)` — resolves from the
skill's directory in the repo *and* in every install tree (the `_shared`
symlink sits next to the installed skills). Never reference
`~/.claude/...` for content another tool needs to read.

2. **`!`command`` dynamic-context lines are kept.**
Claude Code executes them eagerly and injects the output before the model
sees the prompt. Other tools show the line as text — models read it as
"run this command", which degrades gracefully to one extra tool call.

3. **Claude-specific frontmatter keys are kept** (`allowed-tools`, `agent`,
`context: fork`, `disable-model-invocation`). The Agent Skills spec says
unknown keys are ignored, so other tools skip them. Claude Code is the
primary driver here; don't strip its metadata for purity. The one key
with a cross-tool twin is `disable-model-invocation`: it must agree with
`policy.allow_implicit_invocation` in `agents/openai.yaml` (Codex). Rules
and the openai.yaml schema live in [`invocation.md`](invocation.md).

6. **Cross-skill calls say `Call the Skill tool with "<name>"`**, never
`/name`, and only ever target a model-invoked skill. See
[`invocation.md`](invocation.md).

4. **Executable helpers used by universal skills live in `_shared/scripts/`**
and are referenced via `~/.config/ai-shared/scripts/...` (e.g.
`pr-status.sh`, `worktree-cleanup-*.sh`). That path is installed by
`make ai-shared` — part of every tool's install target — so it resolves no
matter which tool invokes the skill. Never reference `~/.claude/scripts/...`
from a universal skill: it only exists when `make claude` ran.

5. **Skill-local assets stay inside the skill** (`references/`, `scripts/`)
and are referenced by bare relative paths — self-contained, BMAD-style.
- **`_shared/`** is reachable at the tool-agnostic path
`~/.config/ai-shared/...`. Agents and external skills reference it there, so
the same file works in every tool and never depends on `~/.claude/...`.
- **`_shared/scripts/`** holds hook scripts (`auto-approve-tools.sh`,
`focus-iterm.applescript`) that each tool's install symlinks into its own
scripts dir. Codex adopted Claude Code's hook protocol, so the same scripts
serve both. Cursor reuses the allowlist through an adapter.
- Hooks have no cross-tool standard, so hook configs stay per-tool.

## Tool-specific layers

Anything that is *not* a skill stays out of `skills/`:

- **`agents/`** — subagent definitions with `tools:`/`model:` frontmatter.
Installed to `~/.claude/agents` and `~/.cursor/agents`. They reference
configs via the tool-agnostic `~/.config/ai-shared/...` path
(`make ai-shared` symlinks it to `ai-stuff/_shared`), so the same agent
file works in every tool that can read files.
- **`claude/`** — `settings.json` (hooks, permissions, statusline, plugins)
and Claude-only hook scripts. See [claude/README.md](claude/README.md).
- **`codex/`** — `hooks.json` + Codex-only hook scripts. Codex skill-picker
metadata is *not* here: it lives beside each skill in `agents/openai.yaml`. See
- **`agents/`** holds subagent definitions with `tools:`/`model:`
frontmatter, installed to `~/.claude/agents` and `~/.cursor/agents`.
- **`claude/`** holds `settings.json` and Claude-only hook scripts. See
[claude/README.md](claude/README.md).
- **`codex/`** holds `hooks.json` and the managed config block. See
[codex/README.md](codex/README.md).
- **`_shared/scripts/`** — scripts shared across tools. Hook scripts
(`auto-approve-tools.sh`, `focus-iterm.applescript`): Codex adopted Claude
Code's hook protocol, so the same scripts serve both — symlinked into each
tool's own scripts dir, never referenced across tool homes. Skill helpers
(`pr-status.sh`, `worktree-cleanup-*.sh`): invoked by universal skills via
the tool-agnostic `~/.config/ai-shared/scripts/...` path.
- Hooks have no cross-tool *standard* (event names/config differ per tool),
so hook configs stay per-tool by design. A skill must never depend on
hooks to function, only get better when they exist.
- **`cursor/`** holds Cursor hooks and settings. See
[cursor/README.md](cursor/README.md).
Loading
Loading