ai-agent-rules 0.11.0__py3-none-any.whl

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.

Potentially problematic release.


This version of ai-agent-rules might be problematic. Click here for more details.

Files changed (42) hide show
  1. ai_agent_rules-0.11.0.dist-info/METADATA +390 -0
  2. ai_agent_rules-0.11.0.dist-info/RECORD +42 -0
  3. ai_agent_rules-0.11.0.dist-info/WHEEL +5 -0
  4. ai_agent_rules-0.11.0.dist-info/entry_points.txt +3 -0
  5. ai_agent_rules-0.11.0.dist-info/licenses/LICENSE +22 -0
  6. ai_agent_rules-0.11.0.dist-info/top_level.txt +1 -0
  7. ai_rules/__init__.py +8 -0
  8. ai_rules/agents/__init__.py +1 -0
  9. ai_rules/agents/base.py +68 -0
  10. ai_rules/agents/claude.py +121 -0
  11. ai_rules/agents/goose.py +44 -0
  12. ai_rules/agents/shared.py +35 -0
  13. ai_rules/bootstrap/__init__.py +75 -0
  14. ai_rules/bootstrap/config.py +261 -0
  15. ai_rules/bootstrap/installer.py +249 -0
  16. ai_rules/bootstrap/updater.py +221 -0
  17. ai_rules/bootstrap/version.py +52 -0
  18. ai_rules/cli.py +2292 -0
  19. ai_rules/completions.py +194 -0
  20. ai_rules/config/AGENTS.md +249 -0
  21. ai_rules/config/chat_agent_hints.md +1 -0
  22. ai_rules/config/claude/agents/code-reviewer.md +121 -0
  23. ai_rules/config/claude/commands/annotate-changelog.md +191 -0
  24. ai_rules/config/claude/commands/comment-cleanup.md +161 -0
  25. ai_rules/config/claude/commands/continue-crash.md +38 -0
  26. ai_rules/config/claude/commands/dev-docs.md +169 -0
  27. ai_rules/config/claude/commands/pr-creator.md +247 -0
  28. ai_rules/config/claude/commands/test-cleanup.md +244 -0
  29. ai_rules/config/claude/commands/update-docs.md +324 -0
  30. ai_rules/config/claude/hooks/subagentStop.py +92 -0
  31. ai_rules/config/claude/mcps.json +1 -0
  32. ai_rules/config/claude/settings.json +116 -0
  33. ai_rules/config/claude/skills/doc-writer/SKILL.md +293 -0
  34. ai_rules/config/claude/skills/doc-writer/resources/templates.md +495 -0
  35. ai_rules/config/claude/skills/prompt-engineer/SKILL.md +272 -0
  36. ai_rules/config/claude/skills/prompt-engineer/resources/prompt_engineering_guide_2025.md +855 -0
  37. ai_rules/config/claude/skills/prompt-engineer/resources/templates.md +232 -0
  38. ai_rules/config/goose/config.yaml +55 -0
  39. ai_rules/config.py +635 -0
  40. ai_rules/display.py +40 -0
  41. ai_rules/mcp.py +370 -0
  42. ai_rules/symlinks.py +207 -0
@@ -0,0 +1,390 @@
1
+ Metadata-Version: 2.4
2
+ Name: ai-agent-rules
3
+ Version: 0.11.0
4
+ Summary: Manage user-level AI agent configurations
5
+ Author-email: Will Pfleger <pfleger.will@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/willpfleger/ai-rules
8
+ Project-URL: Repository, https://github.com/willpfleger/ai-rules
9
+ Project-URL: Issues, https://github.com/willpfleger/ai-rules/issues
10
+ Keywords: ai,cli,configuration,claude,goose,llm,agent
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Classifier: Topic :: Utilities
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: click>=8.1
25
+ Requires-Dist: hatch>=1.15.1
26
+ Requires-Dist: packaging>=21.0
27
+ Requires-Dist: pytest>=8.4.2
28
+ Requires-Dist: pytest-cov>=7.0.0
29
+ Requires-Dist: pytest-xdist>=3.8.0
30
+ Requires-Dist: pyyaml>=6.0
31
+ Requires-Dist: rich>=13.0
32
+ Requires-Dist: ruff>=0.14.3
33
+ Requires-Dist: tomli>=2.0.0; python_version < "3.11"
34
+ Dynamic: license-file
35
+
36
+ # AI Rules
37
+
38
+ Manage AI agent configurations through symlinks. Keep all your configs in one git-tracked location.
39
+
40
+ [![PyPI Downloads](https://img.shields.io/pypi/dm/ai-agent-rules.svg)](https://pypi.org/project/ai-agent-rules/)
41
+ [![PyPI version](https://img.shields.io/pypi/v/ai-agent-rules.svg)](https://pypi.org/project/ai-agent-rules/)
42
+ [![Python Versions](https://img.shields.io/pypi/pyversions/ai-agent-rules.svg)](https://pypi.org/project/ai-agent-rules/)
43
+ [![CI](https://github.com/wpfleger96/ai-rules/actions/workflows/ci.yml/badge.svg)](https://github.com/wpfleger96/ai-rules/actions/workflows/ci.yml)
44
+ [![GitHub Contributors](https://img.shields.io/github/contributors/wpfleger96/ai-rules.svg)](https://github.com/wpfleger96/ai-rules/graphs/contributors)
45
+ [![Lines of Code](https://aschey.tech/tokei/github/wpfleger96/ai-rules?category=code)](https://github.com/wpfleger96/ai-rules)
46
+ [![License](https://img.shields.io/github/license/wpfleger96/ai-rules.svg)](https://github.com/wpfleger96/ai-rules/blob/main/LICENSE)
47
+
48
+ ## Overview
49
+
50
+ Consolidates config files for AI coding agents (Claude Code, Goose) into a single source of truth via symlinks:
51
+
52
+ - Git-tracked configs synced across machines
53
+ - Edit once, apply everywhere
54
+ - Exclude specific files (e.g., company-managed)
55
+ - Per-agent customizations
56
+
57
+ **Supported:** Claude Code (settings, agents, commands), Goose (hints, config), Shared (AGENTS.md)
58
+
59
+ ## Installation
60
+
61
+ **Requirements:** Python 3.10+, [uv](https://github.com/astral-sh/uv)
62
+
63
+ ### From PyPI (Recommended)
64
+
65
+ One-command setup from PyPI:
66
+
67
+ ```bash
68
+ uvx --from ai-agent-rules ai-rules setup
69
+ ```
70
+
71
+ This will:
72
+ 1. Install AI agent configuration symlinks
73
+ 2. Make `ai-rules` available system-wide
74
+ 3. Auto-install optional tools (claude-code-statusline)
75
+
76
+ After setup, you can run `ai-rules` from any directory.
77
+
78
+ ### Local Development
79
+
80
+ For contributing or local development:
81
+
82
+ ```bash
83
+ git clone https://github.com/wpfleger96/ai-rules.git
84
+ cd ai-rules
85
+ uv tool install -e .
86
+ ai-rules install
87
+ ```
88
+
89
+ ### Updating
90
+
91
+ Check for and install updates:
92
+
93
+ ```bash
94
+ ai-rules upgrade # Check and install updates
95
+ ai-rules upgrade --check # Only check for updates
96
+ ```
97
+
98
+ Auto-update checks run weekly by default. Configure in `~/.ai-rules/update_config.yaml`:
99
+
100
+ ```yaml
101
+ enabled: true
102
+ frequency: weekly # daily, weekly, never
103
+ notify_only: false
104
+ ```
105
+
106
+ ## Usage
107
+
108
+ ### User-Level Configuration
109
+
110
+ ```bash
111
+ ai-rules setup # One-time setup: install symlinks + make available system-wide
112
+ ai-rules upgrade # Upgrade to latest version
113
+ ai-rules upgrade --check # Check for updates without installing
114
+
115
+ ai-rules install # Install all agent configs + optional tools
116
+ ai-rules install --agents claude # Install specific agents
117
+ ai-rules install --dry-run # Preview changes
118
+ ai-rules install --force # Skip confirmations
119
+ ai-rules install --rebuild-cache # Rebuild merged settings cache
120
+
121
+ ai-rules status # Check symlink status + optional tools (✓✗⚠○)
122
+ ai-rules diff # Show config differences
123
+ ai-rules validate # Verify source files exist
124
+ ai-rules update # Re-sync after adding files
125
+ ai-rules uninstall # Remove all symlinks
126
+ ai-rules list-agents # Show available agents
127
+ ```
128
+
129
+ ### Configuration Management
130
+
131
+ ```bash
132
+ # Interactive wizard for first-time setup
133
+ ai-rules config init # Start configuration wizard
134
+
135
+ # View configuration
136
+ ai-rules config show # Show raw config files
137
+ ai-rules config show --merged # Show merged settings with overrides
138
+ ai-rules config show --agent claude # Show config for specific agent
139
+ ai-rules config edit # Edit user config in $EDITOR
140
+
141
+ # Manage exclusions
142
+ ai-rules exclude add "~/.claude/*.json" # Add exclusion pattern (supports globs)
143
+ ai-rules exclude remove "~/.claude/*.json" # Remove exclusion pattern
144
+ ai-rules exclude list # List all exclusions
145
+
146
+ # Manage settings overrides (for machine-specific settings)
147
+ ai-rules override set claude.model "claude-sonnet-4-5-20250929" # Set simple override
148
+ ai-rules override set claude.hooks.SubagentStop[0].hooks[0].command "script.py" # Array notation
149
+ ai-rules override unset claude.model # Remove override
150
+ ai-rules override list # List all overrides
151
+ ```
152
+
153
+ ## Configuration
154
+
155
+ ### Quick Start with Config Wizard
156
+
157
+ Run the interactive configuration wizard for guided setup:
158
+
159
+ ```bash
160
+ ai-rules config init
161
+ ```
162
+
163
+ This will walk you through:
164
+ 1. Selecting common exclusions
165
+ 2. Adding custom exclusion patterns (with glob support)
166
+ 3. Setting up machine-specific settings overrides
167
+
168
+ ### User-Level Config
169
+
170
+ Create `~/.ai-rules-config.yaml` for user-level settings:
171
+
172
+ ```yaml
173
+ version: 1
174
+
175
+ # Global exclusions (apply to all contexts)
176
+ # Supports glob patterns: *.json, **/*.yaml, etc.
177
+ exclude_symlinks:
178
+ - "~/.config/goose/config.yaml"
179
+ - "~/.claude/*.log" # Glob: exclude all log files
180
+ - "~/.claude/agents/debug-*.md" # Glob: exclude debug agents
181
+
182
+ # Machine-specific settings overrides
183
+ # Keeps repo settings.json synced via git, but allows local overrides
184
+ settings_overrides:
185
+ claude:
186
+ model: "claude-sonnet-4-5-20250929" # Override model on personal laptop
187
+ # Other settings inherited from base config/claude/settings.json
188
+ goose:
189
+ provider: "anthropic"
190
+ ```
191
+
192
+ **Config File Location:**
193
+ - `~/.ai-rules-config.yaml` - User-specific config (exclusions and overrides)
194
+
195
+ ### Settings Overrides - Syncing Configs Across Machines
196
+
197
+ **Problem:** You want to sync your `settings.json` via git, but need different settings on different machines (e.g., different model access on work vs personal laptop).
198
+
199
+ **Solution:** Use `settings_overrides` in your user config:
200
+
201
+ ```yaml
202
+ # ~/.ai-rules-config.yaml on personal laptop
203
+ settings_overrides:
204
+ claude:
205
+ model: "claude-sonnet-4-5-20250929" # No Opus access
206
+
207
+ # ~/.ai-rules-config.yaml on work laptop
208
+ settings_overrides:
209
+ claude:
210
+ model: "claude-opus-4-20250514" # Has Opus access
211
+ ```
212
+
213
+ Both machines sync the same `config/claude/settings.json` via git, but each has different local overrides. The system merges them at install time:
214
+
215
+ 1. **Base settings** from `config/claude/settings.json` (git-tracked)
216
+ 2. **Merged with** overrides from `~/.ai-rules-config.yaml` (local only)
217
+ 3. **Cached** in `~/.ai-rules/cache/claude/settings.json`
218
+ 4. **Symlinked** to `~/.claude/settings.json`
219
+
220
+ After changing overrides, run:
221
+ ```bash
222
+ ai-rules install --rebuild-cache
223
+ ```
224
+
225
+ #### Array Notation for Nested Settings
226
+
227
+ Override commands support array index notation for complex nested structures:
228
+
229
+ ```bash
230
+ # Override nested array elements (e.g., hooks)
231
+ ai-rules override set claude.hooks.SubagentStop[0].hooks[0].command "uv run ~/my-hook.py"
232
+
233
+ # Override environment variables
234
+ ai-rules override set claude.env.MY_VAR "value"
235
+
236
+ # The system validates paths and provides helpful suggestions
237
+ ai-rules override set claude.modle "sonnet"
238
+ # Error: Key 'modle' not found at 'modle'
239
+ # Available options: model, env, hooks, statusLine, ...
240
+ ```
241
+
242
+ Path validation ensures you only set valid overrides that exist in the base settings, preventing typos and configuration errors.
243
+
244
+ ## Structure
245
+
246
+ ```
247
+ config/
248
+ ├── AGENTS.md # User-level rules → ~/AGENTS.md, ~/.CLAUDE.md, ~/.config/goose/.goosehints
249
+ ├── claude/
250
+ │ ├── settings.json # → ~/.claude/settings.json
251
+ │ ├── agents/*.md # → ~/.claude/agents/*.md (dynamic)
252
+ │ └── commands/*.md # → ~/.claude/commands/*.md (dynamic)
253
+ └── goose/
254
+ └── config.yaml # → ~/.config/goose/config.yaml
255
+ ```
256
+
257
+ ## Optional Tools
258
+
259
+ AI Rules automatically installs optional tools that enhance functionality:
260
+
261
+ - **claude-code-statusline** - Custom status line for Claude Code showing token usage, git info, time, and workspace details
262
+
263
+ These tools are installed automatically during `setup` and `install` commands. Check installation status:
264
+
265
+ ```bash
266
+ ai-rules status # Shows Optional Tools section
267
+ ```
268
+
269
+ If a tool fails to install, ai-rules continues normally (fail-open behavior).
270
+
271
+ ## Extending
272
+
273
+ **Add Claude agent/command:**
274
+ 1. Create `config/claude/agents/my-agent.md` or `config/claude/commands/my-cmd.md`
275
+ 2. Run `ai-rules update`
276
+
277
+ **Add new AI tool:**
278
+ 1. Add configs to `config/<tool>/`
279
+ 2. Implement `ai_rules/agents/<tool>.py`
280
+ 3. Register in `ai_rules/cli.py::get_agents()`
281
+
282
+ ## Safety
283
+
284
+ - First-run warnings
285
+ - Timestamped backups (`*.ai-rules-backup.YYYYMMDD-HHMMSS`)
286
+ - Interactive prompts and dry-run mode
287
+ - Only manages symlinks (never deletes real files)
288
+ - Contextual error messages with tips
289
+
290
+ ## Development
291
+
292
+ ### Quick Start with Just
293
+
294
+ This project uses [just](https://github.com/casey/just) for task automation.
295
+
296
+ **Install just**:
297
+ ```bash
298
+ # macOS
299
+ brew install just
300
+
301
+ # Linux
302
+ cargo install just
303
+ # or: sudo apt install just (Ubuntu 23.04+)
304
+
305
+ # Windows
306
+ choco install just
307
+ ```
308
+
309
+ **Common commands**:
310
+ ```bash
311
+ just # Run quick quality checks (sync, type-check, lint-check, format-check)
312
+ just --list # List all available recipes
313
+
314
+ # Setup
315
+ just setup # First-time setup: sync deps + install git hooks
316
+ just sync # Sync dependencies only
317
+
318
+ # Code Quality
319
+ just check # Quick quality checks (no tests)
320
+ just check-all # All checks including tests
321
+ just lint # Fix linting issues
322
+ just format # Auto-format code
323
+ just type-check # Run mypy type checking
324
+
325
+ # Testing
326
+ just test # Run all tests (default config)
327
+ just test-unit # Unit tests only
328
+ just test-integration # Integration tests only
329
+ just test-cov # Tests with coverage report
330
+
331
+ # Benchmarking
332
+ just benchmark-save # Run and save baseline
333
+ just benchmark-compare # Compare against baseline
334
+ just benchmark-record # Compare and save
335
+ just benchmark-list # List saved benchmarks
336
+ just benchmark-clean # Remove all benchmarks
337
+
338
+ # Build
339
+ just build # Build package
340
+ just rebuild # Clean and build
341
+ ```
342
+
343
+ ### Running Tests
344
+ The test suite includes both unit tests and integration tests.
345
+
346
+ Using just (recommended):
347
+ ```bash
348
+ just test # Run all tests with default config
349
+ just test-unit # Only unit tests
350
+ just test-integration # Only integration tests
351
+ just test-cov # Tests with coverage report
352
+ ```
353
+
354
+ Using uv directly:
355
+ ```bash
356
+ uv run pytest [--cov=src --cov-report=term-missing] # All tests
357
+ uv run pytest -m unit # Unit tests only
358
+ uv run pytest -m integration # Integration tests only
359
+ ```
360
+
361
+ ## Troubleshooting
362
+
363
+ **Wrong target:** `ai-rules status` then `ai-rules install --force`
364
+
365
+ **Restore backup:**
366
+ ```bash
367
+ ls -la ~/.CLAUDE.md.ai-rules-backup.*
368
+ mv ~/.CLAUDE.md.ai-rules-backup.20250104-143022 ~/.CLAUDE.md
369
+ ```
370
+
371
+ **Disable symlink:** Use the exclude command or add to config manually:
372
+ ```bash
373
+ ai-rules exclude add "~/.claude/settings.json"
374
+ # Or edit manually: ai-rules config edit
375
+ ```
376
+
377
+ **Override not applying:** Rebuild the merged settings cache:
378
+ ```bash
379
+ ai-rules install --rebuild-cache
380
+ ```
381
+
382
+ **View merged settings:** Check what's actually being applied:
383
+ ```bash
384
+ ai-rules config show --merged
385
+ ai-rules config show --merged --agent claude
386
+ ```
387
+
388
+ ## License
389
+
390
+ MIT
@@ -0,0 +1,42 @@
1
+ ai_agent_rules-0.11.0.dist-info/licenses/LICENSE,sha256=eRdOpQ8Kaod-FPwMA-sD9U2817DCp0QNub7f_UpqMe0,1070
2
+ ai_rules/__init__.py,sha256=h0sNb8H1ED7Dy0IXON1Ww3O8cls08Sr_g1osdcQ-4i0,231
3
+ ai_rules/cli.py,sha256=oSxAP5cZlv6LXW81zhDslMR17lpwwp0Ss_IICdVwNQg,77887
4
+ ai_rules/completions.py,sha256=7Ymgfzd93Owlscfn6sWkopbbAfT_J5PXnY5vl3CN_Xs,5736
5
+ ai_rules/config.py,sha256=_updV-Uk2eHN1QK0GiVJv_hlvGefloxPZawisK-K9oA,20943
6
+ ai_rules/display.py,sha256=dltgyoJZSseP1xrj-YBvj8_TOBSTouoiQMjwdC5d2MI,1225
7
+ ai_rules/mcp.py,sha256=jbUgRaIyglVfwIFu61Dbtsbbk_o87NCTYwVgz4VclQ8,11958
8
+ ai_rules/symlinks.py,sha256=gXBVMcDU96pMHXR675ePZSnXKY9d0kEEwXnUazd0xhw,6674
9
+ ai_rules/agents/__init__.py,sha256=VG6BFISMVTETyfs7aAXTa_co6NH_dmvp_5aw09HI35w,32
10
+ ai_rules/agents/base.py,sha256=vVPEkdczTz8oLUS5XdjHrJbARL2kDfaKDwQOVBX6bYI,1981
11
+ ai_rules/agents/claude.py,sha256=5O4e_cOxBdPGYEkL-_pevQquSU7VRb9ohxx6Grn89ko,3756
12
+ ai_rules/agents/goose.py,sha256=7zkXWtSZIdnfCEg3k_2-eUOL9bnIQ2HOInBupELRIrc,1077
13
+ ai_rules/agents/shared.py,sha256=Tj9ll1Z_wZzwM19368r2ku_6aTQYyNCwxzOc_4lXqqg,839
14
+ ai_rules/bootstrap/__init__.py,sha256=HTykRNzbh8-kAByfRlvbeS0pefrbR4VlA4AS-5lwcpY,1840
15
+ ai_rules/bootstrap/config.py,sha256=Cp133LLC2xnyM-RRtmKsZ73cSMdm8GVzCmwHjFrcK1I,6970
16
+ ai_rules/bootstrap/installer.py,sha256=5t0XJh4yKtaXxA5SnprK62eNalNUdrKBWQ-TFhIFpKg,6757
17
+ ai_rules/bootstrap/updater.py,sha256=kW9YUy4DT1F1nNRIvjDHkiuNaLoFP7V4RhbDZO0TiKs,6202
18
+ ai_rules/bootstrap/version.py,sha256=WCj4LwzZk-M62ViOf6qg7mQPk-AlGswwHsJWfv9bEko,1236
19
+ ai_rules/config/AGENTS.md,sha256=BKch0ZjjTZfzBRJ6n_UWrLfrWKu3WtNh7DR-4mRY2-w,11298
20
+ ai_rules/config/chat_agent_hints.md,sha256=lW3nCigFn4iuZ6vsCjntwd-Po7MVGFZynjR9X5__vY0,491
21
+ ai_rules/config/claude/mcps.json,sha256=yj0WO6sFU4GCciYUBWjzvvfqrBh869doeOC2Pp5EI1Y,3
22
+ ai_rules/config/claude/settings.json,sha256=Kf1U5_F6V-c15ipiwAPwmuqiv1esOvl_uEE8PdaiA4E,2926
23
+ ai_rules/config/claude/agents/code-reviewer.md,sha256=hFyRbuAzliQOmRVTTNAy1unV4Xx5kFb9JlWEwULL7nY,4417
24
+ ai_rules/config/claude/commands/annotate-changelog.md,sha256=a9AL9Os8VLScL0hryHmesrMdusG2z0TTxH6myeu4aVU,5573
25
+ ai_rules/config/claude/commands/comment-cleanup.md,sha256=gNLc36PlplP08By-QK4n44gefgPusSQa0lnLQDGujBA,5296
26
+ ai_rules/config/claude/commands/continue-crash.md,sha256=rRi16p7PyS9IYuanuTUCh6fMmXleSoqbNqZFWzoJR0s,1378
27
+ ai_rules/config/claude/commands/dev-docs.md,sha256=ZGHrrsbVwcMkgSGy0cQV-CTRUngHOxuCUiz7BUR3fkY,7258
28
+ ai_rules/config/claude/commands/pr-creator.md,sha256=UnzDyxDdM9x0nLgOKag6lsfMrJ3FPDar01gIcQ5qVOo,8133
29
+ ai_rules/config/claude/commands/test-cleanup.md,sha256=R1SeZ-vTxllh33ee-EI65IMnxKpQxJi70VhDvepc_xk,8109
30
+ ai_rules/config/claude/commands/update-docs.md,sha256=R34D6QaLikZrXJD8iJn0RZ4DkhSqmsQASjZupBlFcxw,12289
31
+ ai_rules/config/claude/hooks/subagentStop.py,sha256=woddjbsQSsukVfWaUMsb0D5vyqir75aMZ5a5KnD8HEI,2981
32
+ ai_rules/config/claude/skills/doc-writer/SKILL.md,sha256=22SvAYgdGwKq5quUSgUsu9nGiDJh_6GEFnvlxa4oEuo,10550
33
+ ai_rules/config/claude/skills/doc-writer/resources/templates.md,sha256=qGkqvY78N8DTox06nQWbGlCF62ckpiNHBiEd9l3blTY,11636
34
+ ai_rules/config/claude/skills/prompt-engineer/SKILL.md,sha256=TA6c1SUvJKy0pQnTwGGj_IbQEXqe4wUrFZJuaBVpNJ4,9664
35
+ ai_rules/config/claude/skills/prompt-engineer/resources/prompt_engineering_guide_2025.md,sha256=h3WlOQTYn1zGymJGSoD6dHCZsOTCe9Tne9a3tuRJFFQ,29592
36
+ ai_rules/config/claude/skills/prompt-engineer/resources/templates.md,sha256=4gIR1i5k-_GxWrZXStFyYAEfqZJvzh1KngZfq1T2pLY,6856
37
+ ai_rules/config/goose/config.yaml,sha256=N_QzIANL_7WnX5xSrMZN_t94wbrGXXHMleQ6gzzIaC8,1396
38
+ ai_agent_rules-0.11.0.dist-info/METADATA,sha256=nRRbjUL974E67Oz5UlCx1WYKfzUoochYPPOaqPGQiTI,12546
39
+ ai_agent_rules-0.11.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
40
+ ai_agent_rules-0.11.0.dist-info/entry_points.txt,sha256=Dnt2pQp6vSWz374RsUNZ5Zh5qmuTy45xR02r5fH_p_E,82
41
+ ai_agent_rules-0.11.0.dist-info/top_level.txt,sha256=1jJObrxql_i5okMXb4dxsiQa_cpjtzwwskVvwedEHow,9
42
+ ai_agent_rules-0.11.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ ai-agent-rules = ai_rules.cli:main
3
+ ai-rules = ai_rules.cli:main
@@ -0,0 +1,22 @@
1
+
2
+ MIT License
3
+
4
+ Copyright (c) 2025 Will Pfleger
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ ai_rules
ai_rules/__init__.py ADDED
@@ -0,0 +1,8 @@
1
+ """AI Rules - Manage AI agent configurations through symlinks."""
2
+
3
+ from importlib.metadata import PackageNotFoundError, version
4
+
5
+ try:
6
+ __version__ = version("ai-agent-rules")
7
+ except PackageNotFoundError:
8
+ __version__ = "dev"
@@ -0,0 +1 @@
1
+ """AI agent implementations."""
@@ -0,0 +1,68 @@
1
+ """Base agent class."""
2
+
3
+ from abc import ABC, abstractmethod
4
+ from functools import cached_property
5
+ from pathlib import Path
6
+
7
+ from ai_rules.config import Config
8
+
9
+
10
+ class Agent(ABC):
11
+ """Base class for AI agent configuration managers."""
12
+
13
+ def __init__(self, config_dir: Path, config: Config):
14
+ self.config_dir = config_dir
15
+ self.config = config
16
+
17
+ @property
18
+ @abstractmethod
19
+ def name(self) -> str:
20
+ """Human-readable name of the agent."""
21
+ pass
22
+
23
+ @property
24
+ @abstractmethod
25
+ def agent_id(self) -> str:
26
+ """Short identifier for the agent (e.g., 'claude', 'goose')."""
27
+ pass
28
+
29
+ @property
30
+ @abstractmethod
31
+ def config_file_name(self) -> str:
32
+ """Config file name for the agent (e.g., 'settings.json', 'config.yaml')."""
33
+ pass
34
+
35
+ @property
36
+ @abstractmethod
37
+ def config_file_format(self) -> str:
38
+ """Config file format ('json' or 'yaml')."""
39
+ pass
40
+
41
+ @cached_property
42
+ @abstractmethod
43
+ def symlinks(self) -> list[tuple[Path, Path]]:
44
+ """Cached list of (target_path, source_path) tuples for symlinks.
45
+
46
+ Returns:
47
+ List of tuples where:
48
+ - target_path: Where symlink should be created (e.g., ~/.CLAUDE.md)
49
+ - source_path: What symlink should point to (e.g., repo/config/AGENTS.md)
50
+ """
51
+ pass
52
+
53
+ def get_filtered_symlinks(self) -> list[tuple[Path, Path]]:
54
+ """Get symlinks filtered by config exclusions."""
55
+ return [
56
+ (target, source)
57
+ for target, source in self.symlinks
58
+ if not self.config.is_excluded(str(target))
59
+ ]
60
+
61
+ def get_deprecated_symlinks(self) -> list[Path]:
62
+ """Get list of deprecated symlink paths that should be cleaned up.
63
+
64
+ Returns:
65
+ List of paths that were previously used but are now deprecated.
66
+ These will be removed during install if they point to our config files.
67
+ """
68
+ return []
@@ -0,0 +1,121 @@
1
+ """Claude Code agent implementation."""
2
+
3
+ from functools import cached_property
4
+ from pathlib import Path
5
+
6
+ from ai_rules.agents.base import Agent
7
+ from ai_rules.mcp import MCPManager, MCPStatus, OperationResult
8
+
9
+
10
+ class ClaudeAgent(Agent):
11
+ """Agent for Claude Code configuration."""
12
+
13
+ DEPRECATED_SYMLINKS: list[Path] = [
14
+ Path("~/CLAUDE.md"),
15
+ ]
16
+
17
+ @property
18
+ def name(self) -> str:
19
+ return "Claude Code"
20
+
21
+ @property
22
+ def agent_id(self) -> str:
23
+ return "claude"
24
+
25
+ @property
26
+ def config_file_name(self) -> str:
27
+ return "settings.json"
28
+
29
+ @property
30
+ def config_file_format(self) -> str:
31
+ return "json"
32
+
33
+ @cached_property
34
+ def symlinks(self) -> list[tuple[Path, Path]]:
35
+ """Cached list of all Claude Code symlinks including dynamic agents/commands."""
36
+ result = []
37
+
38
+ result.append((Path("~/.claude/CLAUDE.md"), self.config_dir / "AGENTS.md"))
39
+
40
+ settings_file = self.config_dir / "claude" / "settings.json"
41
+ if settings_file.exists():
42
+ target_file = self.config.get_settings_file_for_symlink(
43
+ "claude", settings_file
44
+ )
45
+ result.append((Path("~/.claude/settings.json"), target_file))
46
+
47
+ agents_dir = self.config_dir / "claude" / "agents"
48
+ if agents_dir.exists():
49
+ for agent_file in sorted(agents_dir.glob("*.md")):
50
+ result.append(
51
+ (
52
+ Path(f"~/.claude/agents/{agent_file.name}"),
53
+ agent_file,
54
+ )
55
+ )
56
+
57
+ commands_dir = self.config_dir / "claude" / "commands"
58
+ if commands_dir.exists():
59
+ for command_file in sorted(commands_dir.glob("*.md")):
60
+ result.append(
61
+ (
62
+ Path(f"~/.claude/commands/{command_file.name}"),
63
+ command_file,
64
+ )
65
+ )
66
+
67
+ skills_dir = self.config_dir / "claude" / "skills"
68
+ if skills_dir.exists():
69
+ for skill_folder in sorted(skills_dir.glob("*")):
70
+ if skill_folder.is_dir():
71
+ result.append(
72
+ (
73
+ Path(f"~/.claude/skills/{skill_folder.name}"),
74
+ skill_folder,
75
+ )
76
+ )
77
+
78
+ return result
79
+
80
+ def get_deprecated_symlinks(self) -> list[Path]:
81
+ """Return deprecated symlink locations for cleanup."""
82
+ return self.DEPRECATED_SYMLINKS
83
+
84
+ def install_mcps(
85
+ self, force: bool = False, dry_run: bool = False
86
+ ) -> tuple[OperationResult, str, list[str]]:
87
+ """Install managed MCPs into ~/.claude.json.
88
+
89
+ Args:
90
+ force: Skip confirmation prompts
91
+ dry_run: Don't actually modify files
92
+
93
+ Returns:
94
+ Tuple of (result, message, conflicts_list)
95
+ """
96
+ manager = MCPManager()
97
+ return manager.install_mcps(self.config_dir, self.config, force, dry_run)
98
+
99
+ def uninstall_mcps(
100
+ self, force: bool = False, dry_run: bool = False
101
+ ) -> tuple[OperationResult, str]:
102
+ """Uninstall managed MCPs from ~/.claude.json.
103
+
104
+ Args:
105
+ force: Skip confirmation prompts
106
+ dry_run: Don't actually modify files
107
+
108
+ Returns:
109
+ Tuple of (result, message)
110
+ """
111
+ manager = MCPManager()
112
+ return manager.uninstall_mcps(force, dry_run)
113
+
114
+ def get_mcp_status(self) -> MCPStatus:
115
+ """Get status of managed and unmanaged MCPs.
116
+
117
+ Returns:
118
+ MCPStatus object with categorized MCPs
119
+ """
120
+ manager = MCPManager()
121
+ return manager.get_status(self.config_dir, self.config)