@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 CHANGED
@@ -74,26 +74,24 @@ ai-rules list # List available technologies
74
74
 
75
75
  ```
76
76
  your-project/
77
- ├── CLAUDE.md # Architecture & conventions
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
- │ ├── components.md
82
- │ ├── state.md
83
- └── testing.md
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
- ### CLAUDE.md
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/ (8 files)
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. **CLAUDE.md** is read by Claude Code at session start
291
- 2. **Rules** activate based on file paths you're editing
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
- Claude Code sees your conventions as first-class instructions, not just suggestions in the chat.
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 CLAUDE.md and .claude/rules/
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]/CLAUDE.md` start with `@../_shared/CLAUDE.md`
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,3 +1,8 @@
1
+ ---
2
+ description: "Shared coding conventions across all technologies"
3
+ alwaysApply: true
4
+ ---
5
+
1
6
  # Shared Conventions
2
7
 
3
8
  ## Code Quality
@@ -1,6 +1,9 @@
1
- # Angular Project Guidelines
1
+ ---
2
+ description: "Angular 21+ project conventions and architecture"
3
+ alwaysApply: true
4
+ ---
2
5
 
3
- @../_shared/CLAUDE.md
6
+ # Angular Project Guidelines
4
7
 
5
8
  ## Stack
6
9
 
@@ -1,6 +1,9 @@
1
- # .NET Project Guidelines
1
+ ---
2
+ description: ".NET 9 project conventions and architecture"
3
+ alwaysApply: true
4
+ ---
2
5
 
3
- @../_shared/CLAUDE.md
6
+ # .NET Project Guidelines
4
7
 
5
8
  ## Stack
6
9
 
@@ -1,6 +1,9 @@
1
- # FastAPI Project Guidelines
1
+ ---
2
+ description: "FastAPI project conventions and architecture"
3
+ alwaysApply: true
4
+ ---
2
5
 
3
- @../_shared/CLAUDE.md
6
+ # FastAPI Project Guidelines
4
7
 
5
8
  ## Stack
6
9
 
@@ -1,6 +1,9 @@
1
- # Flask Project Guidelines
1
+ ---
2
+ description: "Flask 3.0+ project conventions and architecture"
3
+ alwaysApply: true
4
+ ---
2
5
 
3
- @../_shared/CLAUDE.md
6
+ # Flask Project Guidelines
4
7
 
5
8
  ## Stack
6
9
 
@@ -1,6 +1,9 @@
1
- # NestJS Project Guidelines
1
+ ---
2
+ description: "NestJS 11+ project conventions and architecture"
3
+ alwaysApply: true
4
+ ---
2
5
 
3
- @../_shared/CLAUDE.md
6
+ # NestJS Project Guidelines
4
7
 
5
8
  ## Stack
6
9
 
@@ -1,6 +1,9 @@
1
- # Next.js Project Guidelines
1
+ ---
2
+ description: "Next.js 15+ project conventions and architecture"
3
+ alwaysApply: true
4
+ ---
2
5
 
3
- @../_shared/CLAUDE.md
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malamute/ai-rules",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "description": "Claude Code configuration boilerplates for Angular, Next.js, NestJS, .NET, Python and more",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
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 { mergeClaudeMd, mergeSettingsJson, readManifest, writeManifest } from './merge.js';
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);