@kurokeita/add-skill 1.21.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,245 @@
1
+ ---
2
+ name: universalize-agents
3
+ description: Use when the user wants to consolidate or "universalize" their AI agent setup across platforms (Claude Code, Codex, Windsurf, GitHub Copilot, Gemini CLI, Antigravity). Discovers each platform's installed skills/agents/commands and master instructions, copies them into a single `.agents/` directory, migrates master instructions into a canonical `AGENTS.md`, and installs a per-platform session-start hook that symlinks `.agents/` back into each platform's directories.
4
+ version: 0.1.0
5
+ ---
6
+
7
+ # Universalize Agents
8
+
9
+ Consolidate a multi-platform AI agent setup into one source of truth
10
+ (`.agents/` + `AGENTS.md`) and wire every platform to re-materialize it via
11
+ symlinks on each session start.
12
+
13
+ This skill is the first step of a larger "universalize agent setup" feature.
14
+ It performs discovery, consolidation, and hook installation. It does **not**
15
+ modify this repository's `src/` or CLI.
16
+
17
+ ## Canonical references
18
+
19
+ Read these before acting — they are the source of truth and must not drift
20
+ from the codebase:
21
+
22
+ - `reference/mapping.md` — reverse map of every platform's
23
+ skills/agents/commands directories (derived from `src/utils/paths.ts`),
24
+ the per-platform hook-config file locations, and the master-instruction
25
+ file names.
26
+ - `scripts/agent-setup.sh` (macOS/Linux) and `scripts/agent-setup.ps1`
27
+ (Windows) — the idempotent symlink templates that get installed.
28
+ - `reference/hook-templates/` — per-platform session-start hook snippets.
29
+
30
+ ## When to Use
31
+
32
+ Invoke when the user asks to "universalize", "consolidate", "unify", or
33
+ "centralize" their agent setup, skills, commands, or instructions across more
34
+ than one AI coding platform.
35
+
36
+ ## Workflow
37
+
38
+ Follow these phases in order. Stop and ask whenever a decision is the user's
39
+ to make.
40
+
41
+ ### Phase 1 — Choose scope
42
+
43
+ Ask the user: **universalize the setup for the current project, or globally?**
44
+
45
+ - `project` → `.agents/` lives at the project root; platform targets are the
46
+ project-relative directories in `reference/mapping.md`.
47
+ - `global` → `.agents/` lives at `$HOME/.agents`; platform targets are the
48
+ `~/...` directories in `reference/mapping.md`.
49
+
50
+ Record the chosen scope and the resolved base directory (`BASE`). Everything
51
+ downstream uses `BASE`.
52
+
53
+ ### Phase 2 — Discover existing setups
54
+
55
+ For each of the six platforms, check whether its directories exist under
56
+ `BASE` (per `reference/mapping.md`). Treat a platform as "in use" if any of
57
+ its skills/agents/commands dirs or its master-instruction file exists.
58
+
59
+ For each in-use platform, enumerate items in its `skills`, `agents`,
60
+ `workflows`, and `rules` source dirs. Some platforms collapse multiple types into one
61
+ directory (Codex puts skills + agents + workflows in `.codex/skills`; Claude
62
+ Code puts workflows in `.claude/skills`). Disambiguate an item's real type by
63
+ reading its frontmatter / the `x-ai-agents-type` metadata this toolchain
64
+ writes when wrapping items — never by directory alone.
65
+
66
+ Report a discovery summary (platforms in use, item counts per type) before
67
+ continuing.
68
+
69
+ ### Phase 3 — Build `.agents/`
70
+
71
+ Create the unified layout under `BASE`:
72
+
73
+ ```text
74
+ .agents/
75
+ skills/ agents/ commands/ rules/ hooks/
76
+ ```
77
+
78
+ Copy discovered items into `.agents/{skills,agents,commands,rules}`. When the
79
+ same-named item is found on more than one platform, copy it once: prefer the
80
+ first platform discovered and warn about the collision rather than silently
81
+ overwriting. Never wipe an existing `.agents/` — merge into it.
82
+
83
+ #### Format normalization
84
+
85
+ The unified store is markdown-only. Normalize as you copy:
86
+
87
+ - **Rules.** Collect standard markdown rule files from the platforms that
88
+ support them — Claude, Gemini, and Antigravity use `<agent-dir>/rules`;
89
+ GitHub Copilot uses `.github/instructions` (see `reference/mapping.md`) —
90
+ into `.agents/rules/`. Codex and Windsurf have none. These are per-platform
91
+ rule files, distinct from the master instruction files consolidated in
92
+ Phase 4. Rules are **not** symlinked back (not in `__LINK_MAP__`); Phase 4
93
+ wires the whole dir into `AGENTS.md`.
94
+ - **Workflows → commands.** Treat every platform's "workflow" items as the
95
+ universal `commands` type and place them in `.agents/commands/`. If a prior
96
+ run left a `.agents/workflows/` directory, move its contents into
97
+ `.agents/commands/` and remove the now-empty `workflows/` dir.
98
+ - **Gemini commands → skills.** Gemini stores commands as TOML
99
+ (`.gemini/commands/*.toml`), which cannot be symlinked back as markdown.
100
+ Convert each Gemini `*.toml` into a skill: parse its `description` and
101
+ `prompt = """..."""` fields, then write `.agents/skills/<name>/SKILL.md`
102
+ with the prompt as the body and this frontmatter:
103
+
104
+ ```markdown
105
+ ---
106
+ name: <toml file name without extension>
107
+ description: <value of the TOML `description` field>
108
+ ---
109
+
110
+ <contents of the TOML `prompt` field>
111
+ ```
112
+
113
+ This is the reverse of `convertToGeminiCommandTOML` in
114
+ `src/utils/toml.ts`. Gemini workflows therefore land in `.agents/skills/`,
115
+ not `.agents/commands/`.
116
+
117
+ ### Phase 4 — Migrate master instructions
118
+
119
+ Detect every master-instruction file present in scope:
120
+
121
+ | Platform | File |
122
+ |---|---|
123
+ | Claude Code | `CLAUDE.md` |
124
+ | Codex / Antigravity / Windsurf | `AGENTS.md` |
125
+ | Gemini CLI | `GEMINI.md` |
126
+ | GitHub Copilot | `.github/copilot-instructions.md` |
127
+
128
+ The canonical target is root `AGENTS.md` (already the native master file for
129
+ Codex, Antigravity, and Windsurf).
130
+
131
+ - **None found** → create a minimal `AGENTS.md`.
132
+ - **Exactly one found** → use it as `AGENTS.md` directly, no prompt.
133
+ - **Two or more distinct files found** → STOP and ask the user how to
134
+ consolidate:
135
+ 1. **Keep one** — show each detected file with a short preview / line
136
+ count; the user picks which becomes `AGENTS.md`.
137
+ 2. **Merge all + trim** — concatenate every source, then de-duplicate
138
+ overlapping instructions into one coherent `AGENTS.md` (semantic
139
+ de-duplication, preserving every unique directive). Surface any
140
+ conflicting directives to the user instead of dropping them silently.
141
+
142
+ After producing `AGENTS.md` (at `BASE`), **replace the entire contents** of
143
+ each non-`AGENTS.md` master file with a single import line — its original
144
+ content now lives in `AGENTS.md`:
145
+
146
+ ```text
147
+ @AGENTS.md
148
+ ```
149
+
150
+ Always create `AGENTS.md` (with the migrated content) before overwriting any
151
+ master file, so nothing is lost. Platforms that natively read `AGENTS.md`
152
+ (Codex, Antigravity, Windsurf) need no such file.
153
+
154
+ **Wiring rules into masters.** Rules are not symlinked into any platform dir.
155
+ Instead, import the whole `.agents/rules/` directory into `AGENTS.md` with a
156
+ single directory import, so every platform that reads `AGENTS.md` (directly, or
157
+ via its `@AGENTS.md` master import) picks them up:
158
+
159
+ ```text
160
+ @.agents/rules/
161
+ ```
162
+
163
+ Add this import only when `.agents/rules/` is non-empty.
164
+
165
+ ### Phase 5 — Install and run the setup script
166
+
167
+ Pick the script for the host OS — `scripts/agent-setup.sh` on macOS/Linux,
168
+ `scripts/agent-setup.ps1` on Windows — copy it into `BASE/.agents/hooks/`
169
+ (keeping its extension), make it executable, and fill its two placeholders:
170
+
171
+ - `__AGENTS_DIR__` → path to `BASE/.agents`: **relative** (`.agents`) for
172
+ project scope, **absolute** for global scope.
173
+ - `__LINK_MAP__` → one `SRC_SUBDIR|DEST_DIR` line per (in-use platform × type),
174
+ using the scope-correct destination dirs from `reference/mapping.md`.
175
+ `SRC_SUBDIR` is `skills`, `agents`, or `commands`. Use **relative** dest
176
+ dirs (e.g. `.claude/skills`) for project scope and **absolute** dirs for
177
+ global scope. The script detects the mode from `__AGENTS_DIR__` and emits
178
+ relative symlinks for project scope, absolute for global.
179
+
180
+ The script symlinks each item individually (not whole directories) so that
181
+ collapsed targets like `.codex/skills` can receive skills + agents + commands
182
+ merged together without conflict. It is idempotent and refuses to clobber a
183
+ real (non-symlink) path.
184
+
185
+ In **project scope** the script keeps the generated symlinks out of git by
186
+ writing a single `.gitignore` per platform at its base dir (the parent of the
187
+ target dirs, e.g. `.claude/.gitignore`) that lists each symlink subdir
188
+ (`skills/`, `commands/`, …). Only the canonical `.agents/` content (which you
189
+ commit) is version-controlled. Global scope skips this (it is not inside a
190
+ repo).
191
+
192
+ Once `.agents/` holds every item and the script is installed, **delete the
193
+ original item files/directories at each platform source dir**. The canonical
194
+ copy now lives in `.agents/`, so the originals are redundant — and because the
195
+ symlink step refuses to overwrite a real path, it cannot link until the
196
+ original is gone. Then run the setup script once to create the symlinks; every
197
+ later session-start run re-applies them idempotently.
198
+
199
+ ### Phase 6 — Install session-start hooks
200
+
201
+ For each in-use platform, register a session-start hook that runs the
202
+ installed setup script in `BASE/.agents/hooks/` (`agent-setup.sh` on
203
+ macOS/Linux, `agent-setup.ps1` on Windows), writing to the config file in
204
+ `reference/mapping.md`:
205
+
206
+ | Platform | Project file | Global file | Format |
207
+ |---|---|---|---|
208
+ | Claude Code | `.claude/settings.json` | `~/.claude/settings.json` | JSON |
209
+ | Gemini / Antigravity | `.gemini/settings.json` | `~/.gemini/settings.json` | JSON |
210
+ | Codex | `.codex/config.toml` | `~/.codex/config.toml` | TOML |
211
+ | Windsurf | — | — | no session-start hook (skip) |
212
+ | GitHub Copilot | `.github/hooks/agent-setup.json` | `~/.copilot/hooks/agent-setup.json` | JSON |
213
+
214
+ Rules for every write:
215
+
216
+ - **Append, never overwrite.** Parse the existing file, inject the hook entry
217
+ only if an equivalent one is absent, then write back. Preserve all other
218
+ keys and formatting as much as the format allows.
219
+ - **Path style follows scope.** The hook command points at the setup script:
220
+ use a **relative** path (`.agents/hooks/agent-setup.sh`) for project scope
221
+ and an **absolute** path for global scope — matching how `__AGENTS_DIR__`
222
+ was filled.
223
+ - Back up the file (`<file>.bak`) before the first modification.
224
+ - Use the verified template for each platform in `reference/hook-templates/`
225
+ (`claude-code.json`, `gemini.json`, `codex.toml`, `copilot.json`).
226
+ **Windsurf has no session-start hook**, so it gets no recurring hook. Keep
227
+ its dirs in the Phase 5 `__LINK_MAP__` so the one-time setup run symlinks
228
+ them, but tell the user the shared `.agents/` will not auto-refresh on
229
+ Windsurf — they re-run the setup script manually to pick up later changes.
230
+ Codex prompts for a trust review of project hooks on first use.
231
+
232
+ ### Phase 7 — Report
233
+
234
+ Summarize: scope, platforms processed, items consolidated per type, how
235
+ master instructions were resolved, which hooks were installed (and which were
236
+ skipped/unverified), and any collisions or backups created.
237
+
238
+ ## Constraints
239
+
240
+ - Append-only for existing config (settings/hook) files; back up first.
241
+ Master instruction files are the exception: replace their contents with the
242
+ `@AGENTS.md` import once the content is migrated into `AGENTS.md`.
243
+ - Per-item symlinks, never whole-directory, never clobber real paths.
244
+ - Do not fabricate hook schemas; verify unverified platforms at runtime.
245
+ - Do not modify this repo's `src/`, CLI, or `paths.ts`.
@@ -0,0 +1,30 @@
1
+ # Hook templates
2
+
3
+ Session-start hook snippets that the `universalize-agents` skill merges into
4
+ each platform's config file (see `../mapping.md` for file locations).
5
+
6
+ ## Verification status
7
+
8
+ | Platform | Template | Status |
9
+ |---|---|---|
10
+ | Claude Code | `claude-code.json` | Verified |
11
+ | Gemini / Antigravity | `gemini.json` | Verified |
12
+ | Codex | `codex.toml` | Verified |
13
+ | GitHub Copilot | `copilot.json` | Verified |
14
+ | Windsurf | — | No session-start hook — one-time symlink only |
15
+
16
+ Windsurf (Cascade) hooks are action-scoped only (`pre_write_code`,
17
+ `post_setup_worktree`, etc.) with no session-start event, so no recurring hook
18
+ is installed. Windsurf still gets a one-time symlink during the setup run (its
19
+ dirs stay in the link map); re-run the setup script manually to pick up later
20
+ changes to the shared `.agents/`.
21
+
22
+ ## Merge rules (all platforms)
23
+
24
+ - Append, never overwrite. Parse the file, inject the hook only if an
25
+ equivalent entry is absent, then write back.
26
+ - Back up the file to `<file>.bak` before the first modification.
27
+ - The hook command is the absolute path to the OS-appropriate setup script
28
+ (`agent-setup.sh` on macOS/Linux, `agent-setup.ps1` on Windows). Copilot
29
+ uses the `bash`/`powershell` fields; Gemini and Codex use a `command`
30
+ string grouped under a `matcher`.
@@ -0,0 +1,15 @@
1
+ {
2
+ "_comment": "VERIFIED. Claude Code SessionStart hook. Merge the SessionStart entry into the existing settings.json hooks object; do not overwrite sibling keys. Replace the command path with the absolute path to <base>/.agents/hooks/agent-setup.sh.",
3
+ "hooks": {
4
+ "SessionStart": [
5
+ {
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "<base>/.agents/hooks/agent-setup.sh"
10
+ }
11
+ ]
12
+ }
13
+ ]
14
+ }
15
+ }
@@ -0,0 +1,10 @@
1
+ # VERIFIED (developers.openai.com/codex/hooks). Append these tables into the
2
+ # existing .codex/config.toml; keep other tables. Replace <COMMAND> with the
3
+ # absolute path to <base>/.agents/hooks/agent-setup.sh. Codex prompts for a
4
+ # trust review of project hooks on first use.
5
+ [[hooks.SessionStart]]
6
+ matcher = "startup"
7
+
8
+ [[hooks.SessionStart.hooks]]
9
+ type = "command"
10
+ command = "<COMMAND>"
@@ -0,0 +1,9 @@
1
+ {
2
+ "_comment": "VERIFIED (docs.github.com hooks-configuration). Write to .github/hooks/agent-setup.json (project) or ~/.copilot/hooks/agent-setup.json (global). Replace <COMMAND> with the absolute path to <base>/.agents/hooks/agent-setup.sh; use the powershell field instead of bash on Windows.",
3
+ "version": 1,
4
+ "hooks": {
5
+ "sessionStart": [
6
+ { "type": "command", "bash": "<COMMAND>", "timeoutSec": 30 }
7
+ ]
8
+ }
9
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "_comment": "VERIFIED (gemini-cli docs/hooks/reference.md). Merge the SessionStart entry into the existing .gemini/settings.json hooks object; keep sibling keys. Replace <COMMAND> with the absolute path to <base>/.agents/hooks/agent-setup.sh (agent-setup.ps1 on Windows). Same schema for Antigravity.",
3
+ "hooks": {
4
+ "SessionStart": [
5
+ {
6
+ "matcher": "startup",
7
+ "hooks": [{ "type": "command", "command": "<COMMAND>" }]
8
+ }
9
+ ]
10
+ }
11
+ }
@@ -0,0 +1,100 @@
1
+ # Platform mapping reference
2
+
3
+ Reverse map used by the `universalize-agents` skill. Source of truth is
4
+ `src/utils/paths.ts` in this repository — keep this file in sync with it.
5
+
6
+ ## Source directories (discover from / symlink to)
7
+
8
+ `Global` paths are under `$HOME`. `Project` paths are relative to the project
9
+ root. A few platforms use a different sub-path between scopes (noted in bold).
10
+
11
+ ### Skills (`.agents/skills`)
12
+
13
+ | Platform | Global | Project |
14
+ |---|---|---|
15
+ | Claude Code | `~/.claude/skills` | `.claude/skills` |
16
+ | Codex | `~/.codex/skills` | `.codex/skills` |
17
+ | GitHub Copilot | `~/.copilot/skills` | `.copilot/skills` |
18
+ | Gemini CLI | `~/.gemini/skills` | `.gemini/skills` |
19
+ | Windsurf | `~/.codeium/windsurf/skills` | `.codeium/windsurf/skills` |
20
+ | Antigravity | `~/.gemini/antigravity/`**`global_skills`** | `.gemini/antigravity/`**`skills`** |
21
+
22
+ ### Agents (`.agents/agents`)
23
+
24
+ | Platform | Global | Project |
25
+ |---|---|---|
26
+ | Claude Code | `~/.claude/agents` | `.claude/agents` |
27
+ | Codex | `~/.codex/skills` | `.codex/skills` |
28
+ | GitHub Copilot | `~/.copilot/agents` | `.copilot/agents` |
29
+ | Gemini CLI | `~/.gemini/agents` | `.gemini/agents` |
30
+ | Windsurf | — | — |
31
+ | Antigravity | — | — |
32
+
33
+ ### Commands / workflows (`.agents/commands`)
34
+
35
+ | Platform | Global | Project |
36
+ |---|---|---|
37
+ | Claude Code | `~/.claude/commands` | `.claude/commands` |
38
+ | Codex | `~/.codex/skills` | `.codex/skills` |
39
+ | GitHub Copilot | `~/.copilot/prompts` | `.copilot/prompts` |
40
+ | Gemini CLI | `~/.gemini/commands` | `.gemini/commands` |
41
+ | Windsurf | `~/.codeium/windsurf/`**`global_workflows`** | `.codeium/windsurf/`**`workflows`** |
42
+ | Antigravity | `~/.gemini/antigravity/`**`global_workflows`** | `.gemini/antigravity/`**`workflows`** |
43
+
44
+ ### Rules (`.agents/rules`)
45
+
46
+ Standard markdown rule files, discovered from the dirs below and consolidated
47
+ into `.agents/rules/`. They are **not** symlinked back — the whole
48
+ `.agents/rules/` dir is `@`-imported into `AGENTS.md` (see SKILL.md Phase 4), so
49
+ every platform picks them up via the master chain. Codex and Windsurf have no
50
+ rules dir to discover from.
51
+
52
+ | Platform | Global | Project |
53
+ |---|---|---|
54
+ | Claude Code | `~/.claude/rules` | `.claude/rules` |
55
+ | Gemini CLI | `~/.gemini/rules` | `.gemini/rules` |
56
+ | Antigravity | `~/.gemini/antigravity/rules` | `.gemini/antigravity/rules` |
57
+ | GitHub Copilot | — | `.github/instructions` |
58
+ | Codex / Windsurf | — | — |
59
+
60
+ ## Collapsed directories
61
+
62
+ These targets hold more than one type, so reverse-discovery must read item
63
+ frontmatter / the `x-ai-agents-type` metadata to recover the true type:
64
+
65
+ - `.codex/skills` — skills **and** agents **and** commands.
66
+
67
+ When symlinking back, use per-item links so these merged directories do not
68
+ collide.
69
+
70
+ ## Format normalization
71
+
72
+ - Workflows are stored under `.agents/commands/` (the universal name); migrate
73
+ any legacy `.agents/workflows/` into it.
74
+ - Gemini commands are TOML and convert to markdown skills in
75
+ `.agents/skills/<name>/SKILL.md` (reverse of `convertToGeminiCommandTOML`
76
+ in `src/utils/toml.ts`). See SKILL.md Phase 3.
77
+
78
+ ## Hook-config files (session-start)
79
+
80
+ Always append into the existing file; back up first; never overwrite.
81
+
82
+ | Platform | Global | Project | Format |
83
+ |---|---|---|---|
84
+ | Claude Code | `~/.claude/settings.json` | `.claude/settings.json` | JSON |
85
+ | Gemini / Antigravity | `~/.gemini/settings.json` | `.gemini/settings.json` | JSON |
86
+ | Codex | `~/.codex/config.toml` | `.codex/config.toml` | TOML |
87
+ | Windsurf | — | — | no session-start event; one-time symlink only |
88
+ | GitHub Copilot | `~/.copilot/hooks/agent-setup.json` | `.github/hooks/agent-setup.json` | JSON |
89
+
90
+ ## Master-instruction files
91
+
92
+ | Platform | File |
93
+ |---|---|
94
+ | Claude Code | `CLAUDE.md` |
95
+ | Codex / Antigravity / Windsurf | `AGENTS.md` |
96
+ | Gemini CLI | `GEMINI.md` |
97
+ | GitHub Copilot | `.github/copilot-instructions.md` |
98
+
99
+ Canonical consolidated target: root `AGENTS.md` (also copied into
100
+ `.agents/rules/`).
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env pwsh
2
+ # Generated by the `universalize-agents` skill. Windows only
3
+ # (see agent-setup.sh for macOS/Linux). Safe to re-run (idempotent).
4
+ # Project scope fills relative paths; global scope fills absolute paths.
5
+ # Creating symlinks on Windows requires Developer Mode or an elevated shell.
6
+
7
+ $ErrorActionPreference = 'Stop'
8
+
9
+ $AgentsDir = '__AGENTS_DIR__'
10
+
11
+ # __LINK_MAP__ contract: one "SRC_SUBDIR|DEST_DIR" line per (platform x type),
12
+ # where SRC_SUBDIR is skills|agents|commands and DEST_DIR matches the scope.
13
+ $LinkMap = @'
14
+ __LINK_MAP__
15
+ '@
16
+
17
+ function Write-AgentLog($message) { Write-Host "agent-setup: $message" }
18
+
19
+ # Relative paths (project scope) resolve from the repo root; this script lives
20
+ # at <root>\.agents\hooks\, so move two levels up. Absolute paths are untouched.
21
+ $IsRelative = -not [System.IO.Path]::IsPathRooted($AgentsDir)
22
+ if ($IsRelative) { Set-Location (Join-Path $PSScriptRoot '..\..') }
23
+
24
+ function Set-AgentLink($src, $dest) {
25
+ if (Test-Path -LiteralPath $dest) {
26
+ $existing = Get-Item -LiteralPath $dest -Force
27
+ if ($existing.LinkType -eq 'SymbolicLink' -and $existing.Target -eq $src) {
28
+ return
29
+ }
30
+ if ($existing.LinkType -ne 'SymbolicLink') {
31
+ # Refuse to replace a real (non-symlink) path that a user may own.
32
+ Write-AgentLog "SKIP (real path in the way): $dest"
33
+ return
34
+ }
35
+ Remove-Item -LiteralPath $dest -Force
36
+ }
37
+ New-Item -ItemType SymbolicLink -Path $dest -Target $src | Out-Null
38
+ }
39
+
40
+ foreach ($line in $LinkMap -split "`r?`n") {
41
+ $line = $line.Trim()
42
+ if (-not $line) { continue }
43
+
44
+ $sub, $destDir = $line -split '\|', 2
45
+ if (-not $sub -or -not $destDir) { continue }
46
+
47
+ $srcDir = Join-Path $AgentsDir $sub
48
+ if (-not (Test-Path -LiteralPath $srcDir)) { continue }
49
+ if (-not (Test-Path -LiteralPath $destDir)) {
50
+ New-Item -ItemType Directory -Path $destDir -Force | Out-Null
51
+ } else {
52
+ # Clean up dangling symlinks in $destDir
53
+ foreach ($link in Get-ChildItem -LiteralPath $destDir -Force) {
54
+ if ($link.LinkType -eq 'SymbolicLink' -and -not (Test-Path -LiteralPath $link.FullName)) {
55
+ Write-AgentLog "removing broken symlink: $($link.FullName)"
56
+ Remove-Item -LiteralPath $link.FullName -Force
57
+ }
58
+ }
59
+ }
60
+
61
+ # Project scope only: keep the generated symlinks out of git via a single
62
+ # .gitignore per platform base dir (the dest's parent), listing each
63
+ # symlink subdir. The canonical content lives in (tracked) .agents/.
64
+ if ($IsRelative) {
65
+ $gi = Join-Path (Split-Path -Parent $destDir) '.gitignore'
66
+ $entry = (Split-Path -Leaf $destDir) + '/'
67
+ $lines = @()
68
+ if (Test-Path -LiteralPath $gi) { $lines = @(Get-Content -LiteralPath $gi) }
69
+ if ($lines -notcontains $entry) { Add-Content -LiteralPath $gi -Value $entry }
70
+ }
71
+
72
+ foreach ($item in Get-ChildItem -LiteralPath $srcDir -Force) {
73
+ $dest = Join-Path $destDir $item.Name
74
+ if ($IsRelative) {
75
+ $target = [System.IO.Path]::GetRelativePath($destDir, (Join-Path $srcDir $item.Name))
76
+ } else {
77
+ $target = $item.FullName
78
+ }
79
+ Set-AgentLink $target $dest
80
+ }
81
+ }
82
+
83
+ Write-AgentLog 'done.'
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env bash
2
+ # Generated by the `universalize-agents` skill. macOS/Linux only
3
+ # (see agent-setup.ps1 for Windows). Safe to re-run (idempotent).
4
+ # Project scope fills relative paths; global scope fills absolute paths.
5
+
6
+ set -euo pipefail
7
+
8
+ AGENTS_DIR="__AGENTS_DIR__"
9
+
10
+ # __LINK_MAP__ contract: one "SRC_SUBDIR|DEST_DIR" line per (platform x type),
11
+ # where SRC_SUBDIR is skills|agents|commands and DEST_DIR matches the scope
12
+ # (relative to repo root for project scope, absolute for global scope).
13
+ LINK_MAP="$(
14
+ cat <<'EOF'
15
+ __LINK_MAP__
16
+ EOF
17
+ )"
18
+
19
+ log() { printf 'agent-setup: %s\n' "$1" >&2; }
20
+
21
+ # Relative paths (project scope) resolve from the repo root; this script lives
22
+ # at <root>/.agents/hooks/, so cd two levels up. Absolute paths are untouched.
23
+ case "$AGENTS_DIR" in
24
+ /*) ;;
25
+ *) cd "$(dirname "$0")/../.." ;;
26
+ esac
27
+
28
+ # Echo the "../" prefix climbing from a relative dir back to the repo root,
29
+ # so a symlink's target is correct relative to the link's own location.
30
+ up_to_root() {
31
+ up=""
32
+ old_ifs="$IFS"
33
+ IFS=/
34
+ for _seg in $1; do up="../$up"; done
35
+ IFS="$old_ifs"
36
+ printf '%s' "$up"
37
+ }
38
+
39
+ link_item() {
40
+ src="$1"
41
+ dest="$2"
42
+
43
+ if [ -L "$dest" ] && [ "$(readlink "$dest")" = "$src" ]; then
44
+ return 0
45
+ fi
46
+
47
+ # Refuse to replace a real (non-symlink) path that a user may own.
48
+ if [ -e "$dest" ] && [ ! -L "$dest" ]; then
49
+ log "SKIP (real path in the way): $dest"
50
+ return 0
51
+ fi
52
+
53
+ rm -f "$dest"
54
+ ln -s "$src" "$dest"
55
+ }
56
+
57
+ printf '%s\n' "$LINK_MAP" | while IFS='|' read -r sub destdir; do
58
+ [ -z "${sub:-}" ] && continue
59
+ [ -z "${destdir:-}" ] && continue
60
+
61
+ srcdir="$AGENTS_DIR/$sub"
62
+ [ -d "$srcdir" ] || continue
63
+
64
+ mkdir -p "$destdir"
65
+
66
+ # Clean up dangling symlinks in $destdir
67
+ for link in "$destdir"/*; do
68
+ [ -e "$link" ] || [ -L "$link" ] || continue
69
+ if [ -L "$link" ] && [ ! -e "$link" ]; then
70
+ log "removing broken symlink: $link"
71
+ rm -f "$link"
72
+ fi
73
+ done
74
+
75
+ # Project scope only: keep the generated symlinks out of git via a single
76
+ # .gitignore per platform base dir (the dest's parent), listing each
77
+ # symlink subdir. The canonical content lives in (tracked) .agents/.
78
+ prefix=""
79
+ case "$AGENTS_DIR" in
80
+ /*) ;;
81
+ *)
82
+ prefix="$(up_to_root "$destdir")"
83
+ gi="$(dirname "$destdir")/.gitignore"
84
+ entry="$(basename "$destdir")/"
85
+ if [ ! -f "$gi" ] || ! grep -qxF "$entry" "$gi"; then
86
+ printf '%s\n' "$entry" >>"$gi"
87
+ fi
88
+ ;;
89
+ esac
90
+
91
+ for item in "$srcdir"/*; do
92
+ [ -e "$item" ] || continue
93
+ name="$(basename "$item")"
94
+ link_item "${prefix}${srcdir}/${name}" "$destdir/$name"
95
+ done
96
+ done
97
+
98
+ log "done."
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: update-agents-md
3
+ description: Refactor a project's AGENTS.md (or CLAUDE.md) file to follow progressive disclosure. Use when requested to reorganize workspace instructions, reduce context bloat, group guidelines, or extract essential workflows.
4
+ ---
5
+
6
+ # Update Agents MD
7
+
8
+ Refactor `AGENTS.md` (or `CLAUDE.md`) to follow progressive disclosure principles, ensuring context-window efficiency and clarity.
9
+
10
+ ## Workflow
11
+
12
+ ### 1. Analyze and Identify
13
+
14
+ - Read the existing `AGENTS.md` (or `CLAUDE.md`) file in the workspace root.
15
+ - Find contradictions or overlapping rules/instructions.
16
+ - Flag instructions that are redundant, vague, or overly obvious for deletion (e.g., basic IDE usage, standard Git commands, or generic advice).
17
+ - Identify the core essentials for the root file:
18
+ - A one-line description of the project.
19
+ - The package manager used (e.g., `npm`, `pnpm`, `yarn`, `bun`).
20
+ - Core build, typecheck, lint, and test commands.
21
+ - The 2–3 most critical workflows (e.g., local development, running tests, preparing a release).
22
+
23
+ ### 2. User Alignment
24
+
25
+ - Present all identified contradictions, redundancies, and proposed deletions to the user.
26
+ - Ask the user which conflicting instructions to keep and confirm the items proposed for deletion.
27
+ - **Stop and wait** for explicit user confirmation before proceeding with modifications.
28
+
29
+ ### 3. Extract and Delegate
30
+
31
+ - Group the remaining guidelines and instructions into clear, logical categories (e.g., database, testing, frontend styling, deployment).
32
+ - For each category, create a separate markdown file under a `docs/` folder (e.g., `docs/database-guidelines.md`).
33
+ - For any complex procedural instructions or task-specific workflows (e.g., how to run a custom migration script, how to publish a package), extract them into a local skill under `.agents/skills/<name>/SKILL.md`.
34
+
35
+ ### 4. Construct Minimal Root File
36
+
37
+ - Re-write the root `AGENTS.md` (or `CLAUDE.md`) to be extremely minimal.
38
+ - Structure it to contain:
39
+ 1. A one-line description of the project.
40
+ 2. The package manager and build/typecheck commands.
41
+ 3. The 2–3 most critical workflows formatted as numbered steps.
42
+ 4. A list of links to the category files under `docs/` (e.g., `[Database Guidelines](docs/database.md)`), with a one-line description explaining when to consult each file.
43
+ - Replace verbose inline code snippets in instructions with precise `file:line` links pointing directly to the source code (e.g., `see [main.ts:L45-L60](file:///path/to/main.ts#L45-L60)`).