@malamute/ai-rules 1.3.1 → 1.3.2
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.
- package/README.md +16 -19
- package/configs/_shared/{CLAUDE.md → rules/conventions/core.md} +5 -0
- package/configs/angular/{CLAUDE.md → rules/core.md} +5 -2
- package/configs/dotnet/{CLAUDE.md → rules/core.md} +5 -2
- package/configs/fastapi/{CLAUDE.md → rules/core.md} +5 -2
- package/configs/flask/{CLAUDE.md → rules/core.md} +5 -2
- package/configs/nestjs/{CLAUDE.md → rules/core.md} +5 -2
- package/configs/nextjs/{CLAUDE.md → rules/core.md} +6 -3
- package/package.json +1 -1
- package/src/installer.js +1 -38
- package/src/merge.js +0 -23
package/README.md
CHANGED
|
@@ -74,26 +74,24 @@ ai-rules list # List available technologies
|
|
|
74
74
|
|
|
75
75
|
```
|
|
76
76
|
your-project/
|
|
77
|
-
├── CLAUDE.md #
|
|
77
|
+
├── CLAUDE.md # Your project-specific info (not touched)
|
|
78
78
|
└── .claude/
|
|
79
79
|
├── settings.json # Allowed/denied commands
|
|
80
80
|
├── rules/ # Framework-specific patterns
|
|
81
|
-
│ ├──
|
|
82
|
-
│ ├──
|
|
83
|
-
│
|
|
81
|
+
│ ├── nextjs/
|
|
82
|
+
│ │ ├── core.md # Stack, architecture, conventions
|
|
83
|
+
│ │ ├── components.md
|
|
84
|
+
│ │ └── ...
|
|
85
|
+
│ ├── conventions/ # Shared conventions
|
|
86
|
+
│ │ └── core.md
|
|
87
|
+
│ └── security/
|
|
84
88
|
└── skills/ # Optional workflows
|
|
85
89
|
├── learning/
|
|
86
90
|
├── review/
|
|
87
91
|
└── debug/
|
|
88
92
|
```
|
|
89
93
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
The main instruction file. Contains:
|
|
93
|
-
- Project architecture overview
|
|
94
|
-
- Technology stack and versions
|
|
95
|
-
- Coding conventions (naming, structure, patterns)
|
|
96
|
-
- Commands to run (build, test, lint)
|
|
94
|
+
> **Note:** Your project's `CLAUDE.md` is never modified. Use it for project-specific context (business domain, team conventions, etc.).
|
|
97
95
|
|
|
98
96
|
### Rules
|
|
99
97
|
|
|
@@ -183,9 +181,8 @@ DRY RUN - No files will be modified
|
|
|
183
181
|
ℹ Would install to: /your/project
|
|
184
182
|
|
|
185
183
|
ℹ Would install angular...
|
|
186
|
-
○ CLAUDE.md (create)
|
|
187
184
|
○ settings.json (create)
|
|
188
|
-
○ rules/ (
|
|
185
|
+
○ rules/angular/ (9 files)
|
|
189
186
|
|
|
190
187
|
Summary:
|
|
191
188
|
10 file(s) would be created
|
|
@@ -287,12 +284,12 @@ ai-rules update
|
|
|
287
284
|
|
|
288
285
|
## How It Works
|
|
289
286
|
|
|
290
|
-
1. **
|
|
291
|
-
2.
|
|
287
|
+
1. **Rules** are loaded by Claude Code based on file paths you're editing
|
|
288
|
+
2. **`rules/core.md`** with `alwaysApply: true` provides framework conventions
|
|
292
289
|
3. **Skills** are invoked on-demand with `/skill-name`
|
|
293
290
|
4. **Settings** define what commands Claude can run
|
|
294
291
|
|
|
295
|
-
|
|
292
|
+
Your project's `CLAUDE.md` stays clean for project-specific context, while framework conventions live in rules.
|
|
296
293
|
|
|
297
294
|
## Contributing
|
|
298
295
|
|
|
@@ -306,13 +303,13 @@ npm install
|
|
|
306
303
|
npm test
|
|
307
304
|
|
|
308
305
|
# Add a new technology
|
|
309
|
-
mkdir configs/your-tech
|
|
310
|
-
# Add
|
|
306
|
+
mkdir -p configs/your-tech/rules
|
|
307
|
+
# Add rules/core.md and other rules
|
|
311
308
|
```
|
|
312
309
|
|
|
313
310
|
### Adding a Technology
|
|
314
311
|
|
|
315
|
-
1. Create `configs/[tech]/
|
|
312
|
+
1. Create `configs/[tech]/rules/core.md` with framework conventions
|
|
316
313
|
2. Add rules in `configs/[tech]/rules/`
|
|
317
314
|
3. Add `configs/[tech]/settings.json` for permissions
|
|
318
315
|
4. Add tests
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
description: "Next.js 15+ project conventions and architecture"
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
# Next.js Project Guidelines
|
|
4
7
|
|
|
5
8
|
## Stack
|
|
6
9
|
|
|
@@ -31,7 +34,7 @@ libs/[domain]/
|
|
|
31
34
|
### Folder Conventions
|
|
32
35
|
|
|
33
36
|
| Pattern | Meaning |
|
|
34
|
-
|
|
37
|
+
|---------|---------|
|
|
35
38
|
| `_folder/` | Private - co-located, not a route |
|
|
36
39
|
| `(folder)/` | Route group - organizational only |
|
|
37
40
|
| `[param]/` | Dynamic segment |
|
package/package.json
CHANGED
package/src/installer.js
CHANGED
|
@@ -2,7 +2,7 @@ import fs from 'fs';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { colors, log, getFilesRecursive, copyDirRecursive, backupFile } from './utils.js';
|
|
4
4
|
import { CONFIGS_DIR, AVAILABLE_TECHS, VERSION, getRulePathsToInclude, shouldIncludeRule } from './config.js';
|
|
5
|
-
import {
|
|
5
|
+
import { mergeSettingsJson, readManifest, writeManifest } from './merge.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Copy skills to target directory with flat structure.
|
|
@@ -187,8 +187,6 @@ export function init(techs, options) {
|
|
|
187
187
|
fs.mkdirSync(path.join(targetDir, '.claude', 'rules'), { recursive: true });
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
let isFirstClaudeMd = true;
|
|
191
|
-
|
|
192
190
|
for (const tech of techs) {
|
|
193
191
|
log.info(`${dryRun ? 'Would install' : 'Installing'} ${tech}...`);
|
|
194
192
|
|
|
@@ -199,24 +197,6 @@ export function init(techs, options) {
|
|
|
199
197
|
process.exit(1);
|
|
200
198
|
}
|
|
201
199
|
|
|
202
|
-
const claudeMdPath = path.join(techDir, 'CLAUDE.md');
|
|
203
|
-
if (fs.existsSync(claudeMdPath)) {
|
|
204
|
-
const op = mergeClaudeMd(
|
|
205
|
-
path.join(targetDir, 'CLAUDE.md'),
|
|
206
|
-
claudeMdPath,
|
|
207
|
-
isFirstClaudeMd,
|
|
208
|
-
{ dryRun, backup, targetDir }
|
|
209
|
-
);
|
|
210
|
-
operations.push(op);
|
|
211
|
-
isFirstClaudeMd = false;
|
|
212
|
-
|
|
213
|
-
if (dryRun) {
|
|
214
|
-
log.dry(` CLAUDE.md (${op.type})`);
|
|
215
|
-
} else {
|
|
216
|
-
log.success(` CLAUDE.md`);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
200
|
const settingsPath = path.join(techDir, 'settings.json');
|
|
221
201
|
if (fs.existsSync(settingsPath)) {
|
|
222
202
|
const op = mergeSettingsJson(
|
|
@@ -312,23 +292,6 @@ export function init(techs, options) {
|
|
|
312
292
|
}
|
|
313
293
|
}
|
|
314
294
|
|
|
315
|
-
// Resolve @../_shared/CLAUDE.md imports
|
|
316
|
-
const targetClaudeMd = path.join(targetDir, 'CLAUDE.md');
|
|
317
|
-
if (!dryRun && fs.existsSync(targetClaudeMd)) {
|
|
318
|
-
let content = fs.readFileSync(targetClaudeMd, 'utf8');
|
|
319
|
-
|
|
320
|
-
if (content.includes('@../_shared/CLAUDE.md')) {
|
|
321
|
-
const sharedClaudeMd = path.join(sharedDir, 'CLAUDE.md');
|
|
322
|
-
if (fs.existsSync(sharedClaudeMd)) {
|
|
323
|
-
const sharedContent = fs.readFileSync(sharedClaudeMd, 'utf8');
|
|
324
|
-
content = content.replace(/@..\/_shared\/CLAUDE\.md/g, '');
|
|
325
|
-
content = sharedContent + '\n\n' + content;
|
|
326
|
-
fs.writeFileSync(targetClaudeMd, content);
|
|
327
|
-
log.success('Merged shared conventions into CLAUDE.md');
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
295
|
writeManifest(
|
|
333
296
|
targetDir,
|
|
334
297
|
{
|
package/src/merge.js
CHANGED
|
@@ -3,29 +3,6 @@ import path from 'path';
|
|
|
3
3
|
import { log, backupFile } from './utils.js';
|
|
4
4
|
import { VERSION } from './config.js';
|
|
5
5
|
|
|
6
|
-
export function mergeClaudeMd(targetPath, sourcePath, isFirst, options = {}) {
|
|
7
|
-
const { dryRun = false, backup = false, targetDir } = options;
|
|
8
|
-
const content = fs.readFileSync(sourcePath, 'utf8');
|
|
9
|
-
const exists = fs.existsSync(targetPath);
|
|
10
|
-
|
|
11
|
-
if (dryRun) {
|
|
12
|
-
return { type: exists ? 'merge' : 'create', path: 'CLAUDE.md' };
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
if (exists && backup && isFirst) {
|
|
16
|
-
backupFile(targetPath, targetDir);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
if (isFirst) {
|
|
20
|
-
fs.writeFileSync(targetPath, content);
|
|
21
|
-
} else {
|
|
22
|
-
const existing = fs.readFileSync(targetPath, 'utf8');
|
|
23
|
-
fs.writeFileSync(targetPath, `${existing}\n\n---\n\n${content}`);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return { type: exists ? 'merge' : 'create', path: 'CLAUDE.md' };
|
|
27
|
-
}
|
|
28
|
-
|
|
29
6
|
export function mergeSettingsJson(targetPath, sourcePath, options = {}) {
|
|
30
7
|
const { dryRun = false, backup = false, targetDir } = options;
|
|
31
8
|
const exists = fs.existsSync(targetPath);
|