feat(claude): add AGENTS.md commands and refactor symlink handling

Add two new Claude Code slash commands:
- generate-agents.md.md: Generate hierarchical AGENTS.md structures
- refactor-agents.md.md: Refactor existing AGENTS.md files

Changes to siren script:
- Make Claude symlinks conditional on CLI installation
- Extract _add_command_symlinks() for reusable command symlinking
- Extract _cleanup_stale_commands() for generic stale link cleanup
- Add plan mode instructions to CLAUDE.md

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-24 01:17:30 +00:00
parent 717cc6f333
commit daeda663a4
4 changed files with 368 additions and 25 deletions

View File

@@ -52,3 +52,8 @@ everything you do.
- When adding new comments, they must be relevant and specific to the code in
question. They should NOT refer to any specific instructions like "use new X
function".
## Plan Mode
- Make the plan extremely concise. Sacrifice grammar for the sake of concision.
- At the end of each plan, give me a list of unresolved questions to answer, if any.

View File

@@ -0,0 +1,289 @@
---
sources:
- https://github.com/RayFernando1337/llm-cursor-rules/blob/main/generate-agents.md
- https://www.aihero.dev/a-complete-guide-to-agents-md
---
# Task: Analyze this codebase and generate a hierarchical AGENTS.md structure
## Important Caveats
Auto-generated AGENTS.md files tend to be too comprehensive. Use this as a
**starting point only** - then aggressively trim. Target: smallest possible
file that provides value. Most instructions should move to progressive
disclosure (docs/*.md files).
Remember:
- Stale docs actively poison agent context
- File paths go stale quickly - describe capabilities instead
- Each instruction must earn its token cost
- LLMs have ~150-200 instruction limit before degradation
---
## Paths vs Hints
**Bad (goes stale):**
- `Auth logic: src/auth/provider.tsx`
- `API routes: apps/api/src/routes/**`
**Good (survives refactors):**
- `Auth: Uses React Context pattern, look for *Provider or *Context`
- `API routes: Next.js app router convention, check for route.ts files`
- `Models: Prisma schema defines domain entities`
### Anti-Pattern: Static File References
Never document:
- `User model is in src/models/user.ts`
- `Auth handler lives at lib/auth/handlers.ts`
Instead document:
- `User model: Prisma schema, look for "model User"`
- `Auth: middleware pattern, grep for "authenticate" or "withAuth"`
---
## Document Domain Concepts
**Stable (document these):**
- "Organization" vs "Workspace" vs "Team" terminology
- Core domain entities and their relationships
- Business rules that aren't obvious from code
**Unstable (avoid documenting):**
- Specific file paths
- Directory structure
- Import paths
---
## Context & Principles
You are going to help me create a **hierarchical AGENTS.md system** for this
codebase. This is critical for AI coding agents to work efficiently with
minimal token usage.
### Core Principles
1. **Minimal root AGENTS.md** - Only universal guidance, links to sub-files
2. **Nearest-wins hierarchy** - Agents read closest AGENTS.md to edited file
3. **Pattern hints over paths** - Describe grep-able patterns, not file locations
4. **Token efficiency** - Small, actionable guidance over encyclopedic docs
5. **Progressive disclosure** - Link to docs/*.md for detailed rules
6. **Domain concepts** - Document terminology and business rules, not structure
---
## Your Process
### Phase 1: Repository Analysis
First, analyze the codebase and provide me with:
1. **Repository type**: Monorepo, multi-package, or simple single project?
2. **Primary technology stack**: Languages, frameworks, key tools
3. **Major packages** that warrant their own AGENTS.md:
- Only for areas with significantly different tech/patterns
- Skip if root guidance suffices
- Prefer fewer, more focused files over many small ones
4. **Build system**: pnpm/npm/yarn workspaces? Turborepo? Or simple?
5. **Testing conventions**: Framework and colocated vs separate?
6. **Key patterns to document** (as grep-able hints):
- What conventions are used (not where files are)
- Domain terminology agents should understand
- Anti-patterns to avoid
Present this as a **structured map** before generating any AGENTS.md files.
---
### Phase 2: Generate Root AGENTS.md
Create a **minimal root AGENTS.md** (~50-100 lines max, ideally under 50).
Per the guide, root AGENTS.md needs only:
1. One-sentence project description
2. Package manager (if not npm)
3. Build/typecheck commands (if non-standard)
#### Required Sections
**1. Project Overview** (3-5 lines)
- One-sentence description of what this project does
- Package manager and key build commands (only if non-standard)
**2. Navigation** (5-10 lines)
Link to sub-AGENTS.md files and describe how to find things:
```
## Navigation
### Sub-package Docs
Each major package has its own AGENTS.md. Look for them in package roots.
### Finding Things
- Components: exported from *.tsx, usually named after component
- API routes: follow framework conventions (route.ts, [...slug], etc.)
- Config: root-level *.config.* files
- Tests: colocated *.test.* or in __tests__ directories
```
**3. Progressive Disclosure** (2-5 lines)
Link to detailed docs instead of inlining them:
```
## Detailed Docs
- TypeScript conventions: see docs/TYPESCRIPT.md
- Testing patterns: see docs/TESTING.md
```
#### Optional Sections (include only if truly needed)
**Conventions** - Only if non-obvious (commit format, unusual style rules)
**Security** - Only if project has specific secret handling beyond standard
`.env` patterns
---
### Phase 3: Generate Sub-Folder AGENTS.md Files
Only create for directories with significantly different tech/patterns.
Each file should be ~30-50 lines max.
#### Required Sections (3-4 essentials)
**1. Package Identity** (1-2 lines)
- What this package/app/service does
- Primary tech if different from root
**2. Setup & Run** (only if different from root)
- Dev, build, test commands for this package
**3. Patterns & Conventions** (5-15 lines)
Describe patterns agents can grep for, not paths they should navigate to:
```
## Patterns
- Auth: Context provider pattern → grep for createContext, Provider
- API calls: Centralized client → grep for fetchClient, apiClient
- Validation: Zod schemas → grep for z.object, .parse
- State: React Query → grep for useQuery, useMutation
### Do/Don't
- DO: Use functional components with hooks
- DON'T: Use class components (legacy only)
```
**4. Pre-PR Check** (1-2 lines)
Single copy-paste command:
```
pnpm --filter @repo/web typecheck && pnpm --filter @repo/web test
```
#### Optional Sections (include only if critical)
- **Gotchas**: Only truly non-obvious issues (1-3 lines max)
- **Quick Find**: Package-specific search commands
---
### Phase 4: Special Considerations
Add these ONLY if the package has them and they're non-obvious:
**Design System** (if exists)
```
## Design System
- Use design tokens (never hardcode colors)
- Component patterns: functional, composable, typed props
```
**Database** (if exists)
```
## Database
- ORM: [name], migrations via `pnpm db:migrate`
- Never run migrations in tests
```
**API** (if exists)
```
## API Patterns
- Validation: Zod schemas
- Errors: Throw typed ApiError
```
---
## Output Format
Provide files in this order:
1. **Analysis Summary** (from Phase 1)
2. **Root AGENTS.md** (complete, ready to copy)
3. **Each Sub-Folder AGENTS.md** (with file path)
Use this format:
```
---
File: `AGENTS.md` (root)
---
[content]
---
File: `apps/web/AGENTS.md`
---
[content]
```
---
## Maintenance Warning
AGENTS.md files go stale. Review quarterly:
- Remove any file paths that crept in
- Verify pattern hints still match codebase conventions
- Update commands that changed
- Delete rules the agent already knows
- Question if each instruction earns its token cost
---
## Quality Checks
Before generating, verify:
- [ ] Root AGENTS.md under 50 lines? (100 max)
- [ ] Sub-folder files under 50 lines each?
- [ ] **No static file paths in documentation?**
- [ ] **Patterns described as grep-able hints?**
- [ ] **Domain concepts over implementation details?**
- [ ] Progressive disclosure used for detailed rules?
- [ ] Does each instruction earn its token cost?
- [ ] Would this survive a major refactor?
- [ ] Commands are copy-paste ready?
- [ ] No duplication between root and sub-files?
- [ ] Not every directory gets its own file?

View File

@@ -0,0 +1,33 @@
---
source: https://www.aihero.dev/a-complete-guide-to-agents-md
---
# Task: Refactor my AGENTS.md
I want you to refactor my AGENTS.md file to follow progressive disclosure
principles. If there is no AGENTS.md file, look for a CLAUDE.md file instead.
Follow these steps:
1. **Find contradictions**: Identify any instructions that conflict with each
other. For each contradiction, ask me which version I want to keep.
2. **Identify the essentials**: Extract only what belongs in the root AGENTS.md:
- One-sentence project description
- Package manager (if not npm)
- Non-standard build/typecheck commands
- Anything truly relevant to every single task
3. **Group the rest**: Organize remaining instructions into logical categories
(e.g., TypeScript conventions, testing patterns, API design, Git workflow).
For each group, create a separate markdown file.
4. **Create the file structure**: Output:
- A minimal root AGENTS.md with markdown links to the separate files
- Each separate file with its relevant instructions
- A suggested docs/ folder structure
5. **Flag for deletion**: Identify any instructions that are:
- Redundant (the agent already knows this)
- Too vague to be actionable
- Overly obvious (like "write clean code")

66
siren
View File

@@ -38,27 +38,23 @@ define_settings() {
)
# Additional static symlinks to create (source => target).
STATIC_SYMLINKS["claude/CLAUDE.md"]="${HOME}/.claude/CLAUDE.md"
STATIC_SYMLINKS["claude/settings.json"]="${HOME}/.claude/settings.json"
STATIC_SYMLINKS["claude/statusline.sh"]="${HOME}/.claude/statusline.sh"
STATIC_SYMLINKS["cspell/vscode-user-dictionary.txt"]="${HOME}/.cspell/vscode-user-dictionary.txt"
STATIC_SYMLINKS["harper-ls/dictionary.txt"]="$(harper_config_dir)/dictionary.txt"
STATIC_SYMLINKS["harper-ls/file_dictionaries"]="$(harper_config_dir)/file_dictionaries"
STATIC_SYMLINKS["harper-ls/ignored_lints"]="$(harper_config_dir)/ignored_lints"
# Conditionally add symlinks for Claude (only if CLI is installed).
if command -v claude &>/dev/null; then
STATIC_SYMLINKS["claude/CLAUDE.md"]="${HOME}/.claude/CLAUDE.md"
STATIC_SYMLINKS["claude/settings.json"]="${HOME}/.claude/settings.json"
STATIC_SYMLINKS["claude/statusline.sh"]="${HOME}/.claude/statusline.sh"
_add_command_symlinks "claude" "${HOME}/.claude"
fi
# Conditionally add symlinks for Cursor.
if [[ "${SETUP_EDITOR}" == "cursor" ]]; then
STATIC_SYMLINKS["cursor/mcp.json"]="${HOME}/.cursor/mcp.json"
# Symlink all markdown files from cursor/commands/ to ~/.cursor/commands/
local cmd_file
for cmd_file in "${SCRIPT_DIR}/cursor/commands/"*.md; do
if [[ -f "${cmd_file}" ]]; then
local filename
filename="$(basename "${cmd_file}")"
STATIC_SYMLINKS["cursor/commands/${filename}"]="${HOME}/.cursor/commands/${filename}"
fi
done
_add_command_symlinks "cursor" "${HOME}/.cursor"
fi
}
@@ -432,19 +428,37 @@ symlink_static_config() {
done
}
# Private function: Remove stale symlinks in ~/.cursor/commands that point to
# files in cursor/commands/ that no longer exist.
cleanup_stale_cursor_commands() {
local cursor_commands_dir="${HOME}/.cursor/commands"
local source_commands_dir="${SCRIPT_DIR}/cursor/commands"
# Add symlinks for all markdown files in a commands directory.
# Args: $1 = source subdir (e.g., "claude"), $2 = target dir (e.g., ~/.claude)
_add_command_symlinks() {
local source_subdir="$1"
local target_base="$2"
local cmd_file
# Skip if the target directory doesn't exist.
if [[ ! -d "${cursor_commands_dir}" ]]; then
for cmd_file in "${SCRIPT_DIR}/${source_subdir}/commands/"*.md; do
if [[ -f "${cmd_file}" ]]; then
local filename
filename="$(basename "${cmd_file}")"
STATIC_SYMLINKS["${source_subdir}/commands/${filename}"]="${target_base}/commands/${filename}"
fi
done
}
# Remove stale symlinks in a commands directory that point to source files that
# no longer exist.
# Args: $1 = source subdir (e.g., "claude"), $2 = target dir (e.g., ~/.claude)
_cleanup_stale_commands() {
local source_subdir="$1"
local target_base="$2"
local commands_dir="${target_base}/commands"
local source_dir="${SCRIPT_DIR}/${source_subdir}/commands"
if [[ ! -d "${commands_dir}" ]]; then
return
fi
local link
for link in "${cursor_commands_dir}"/*; do
for link in "${commands_dir}"/*; do
# Skip if glob didn't match anything (returns literal pattern).
[[ -e "${link}" || -L "${link}" ]] || continue
@@ -453,12 +467,11 @@ cleanup_stale_cursor_commands() {
continue
fi
# Get the symlink target.
local target
target="$(readlink "${link}")"
# Check if the symlink points to our source directory.
if [[ "${target}" == "${source_commands_dir}/"* ]]; then
if [[ "${target}" == "${source_dir}/"* ]]; then
# If the target file no longer exists, remove the symlink.
if [[ ! -e "${target}" ]]; then
info "Removing stale symlink: ${link}"
@@ -1264,9 +1277,12 @@ do_config() {
symlink_editor_config
symlink_static_config
# Clean up stale symlinks for Cursor commands.
# Clean up stale command symlinks.
if command -v claude &>/dev/null; then
_cleanup_stale_commands "claude" "${HOME}/.claude"
fi
if [[ "${SETUP_EDITOR}" == "cursor" ]]; then
cleanup_stale_cursor_commands
_cleanup_stale_commands "cursor" "${HOME}/.cursor"
fi
info "Symlink setup complete!"