@malamute/ai-rules 1.0.0 → 1.3.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.
Files changed (145) hide show
  1. package/README.md +272 -121
  2. package/bin/cli.js +5 -2
  3. package/configs/_shared/CLAUDE.md +52 -149
  4. package/configs/_shared/rules/conventions/documentation.md +324 -0
  5. package/configs/_shared/rules/conventions/git.md +265 -0
  6. package/configs/_shared/rules/conventions/npm.md +80 -0
  7. package/configs/_shared/{.claude/rules → rules/conventions}/performance.md +1 -1
  8. package/configs/_shared/rules/conventions/principles.md +334 -0
  9. package/configs/_shared/rules/devops/ci-cd.md +262 -0
  10. package/configs/_shared/rules/devops/docker.md +275 -0
  11. package/configs/_shared/rules/devops/nx.md +194 -0
  12. package/configs/_shared/rules/domain/backend/api-design.md +203 -0
  13. package/configs/_shared/rules/lang/csharp/async.md +220 -0
  14. package/configs/_shared/rules/lang/csharp/csharp.md +314 -0
  15. package/configs/_shared/rules/lang/csharp/linq.md +210 -0
  16. package/configs/_shared/rules/lang/python/async.md +337 -0
  17. package/configs/_shared/rules/lang/python/celery.md +476 -0
  18. package/configs/_shared/rules/lang/python/config.md +339 -0
  19. package/configs/{python/.claude/rules → _shared/rules/lang/python}/database/sqlalchemy.md +6 -1
  20. package/configs/_shared/rules/lang/python/deployment.md +523 -0
  21. package/configs/_shared/rules/lang/python/error-handling.md +330 -0
  22. package/configs/_shared/rules/lang/python/migrations.md +421 -0
  23. package/configs/_shared/rules/lang/python/python.md +172 -0
  24. package/configs/_shared/rules/lang/python/repository.md +383 -0
  25. package/configs/{python/.claude/rules → _shared/rules/lang/python}/testing.md +2 -69
  26. package/configs/_shared/rules/lang/typescript/async.md +447 -0
  27. package/configs/_shared/rules/lang/typescript/generics.md +356 -0
  28. package/configs/_shared/rules/lang/typescript/typescript.md +212 -0
  29. package/configs/_shared/rules/quality/error-handling.md +48 -0
  30. package/configs/_shared/rules/quality/logging.md +45 -0
  31. package/configs/_shared/rules/quality/observability.md +240 -0
  32. package/configs/_shared/rules/quality/testing-patterns.md +65 -0
  33. package/configs/_shared/rules/security/secrets-management.md +222 -0
  34. package/configs/_shared/skills/analysis/explore/SKILL.md +257 -0
  35. package/configs/_shared/skills/analysis/security-audit/SKILL.md +184 -0
  36. package/configs/_shared/skills/dev/api-endpoint/SKILL.md +126 -0
  37. package/configs/_shared/{.claude/commands/generate-tests.md → skills/dev/generate-tests/SKILL.md} +6 -0
  38. package/configs/_shared/{.claude/commands/fix-issue.md → skills/git/fix-issue/SKILL.md} +6 -0
  39. package/configs/_shared/{.claude/commands/review-pr.md → skills/git/review-pr/SKILL.md} +6 -0
  40. package/configs/_shared/skills/infra/deploy/SKILL.md +139 -0
  41. package/configs/_shared/skills/infra/docker/SKILL.md +95 -0
  42. package/configs/_shared/skills/infra/migration/SKILL.md +158 -0
  43. package/configs/_shared/skills/nx/nx-affected/SKILL.md +72 -0
  44. package/configs/_shared/skills/nx/nx-lib/SKILL.md +375 -0
  45. package/configs/angular/CLAUDE.md +24 -216
  46. package/configs/angular/{.claude/rules → rules/core}/components.md +69 -15
  47. package/configs/angular/rules/core/resource.md +285 -0
  48. package/configs/angular/rules/core/signals.md +323 -0
  49. package/configs/angular/rules/http.md +338 -0
  50. package/configs/angular/rules/routing.md +291 -0
  51. package/configs/angular/rules/ssr.md +312 -0
  52. package/configs/angular/rules/state/signal-store.md +408 -0
  53. package/configs/angular/{.claude/rules → rules/state}/state.md +2 -2
  54. package/configs/angular/{.claude/rules → rules}/testing.md +7 -7
  55. package/configs/angular/rules/ui/aria.md +422 -0
  56. package/configs/angular/rules/ui/forms.md +424 -0
  57. package/configs/angular/rules/ui/pipes-directives.md +335 -0
  58. package/configs/angular/{.claude/settings.json → settings.json} +3 -0
  59. package/configs/dotnet/CLAUDE.md +53 -286
  60. package/configs/dotnet/rules/background-services.md +552 -0
  61. package/configs/dotnet/rules/configuration.md +426 -0
  62. package/configs/dotnet/rules/ddd.md +447 -0
  63. package/configs/dotnet/rules/dependency-injection.md +343 -0
  64. package/configs/dotnet/rules/mediatr.md +320 -0
  65. package/configs/dotnet/rules/middleware.md +489 -0
  66. package/configs/dotnet/rules/result-pattern.md +363 -0
  67. package/configs/dotnet/rules/validation.md +388 -0
  68. package/configs/dotnet/settings.json +29 -0
  69. package/configs/fastapi/CLAUDE.md +144 -0
  70. package/configs/fastapi/rules/background-tasks.md +254 -0
  71. package/configs/fastapi/rules/dependencies.md +170 -0
  72. package/configs/{python/.claude → fastapi}/rules/fastapi.md +61 -1
  73. package/configs/fastapi/rules/lifespan.md +274 -0
  74. package/configs/fastapi/rules/middleware.md +229 -0
  75. package/configs/fastapi/rules/pydantic.md +433 -0
  76. package/configs/fastapi/rules/responses.md +251 -0
  77. package/configs/fastapi/rules/routers.md +202 -0
  78. package/configs/fastapi/rules/security.md +222 -0
  79. package/configs/fastapi/rules/testing.md +251 -0
  80. package/configs/fastapi/rules/websockets.md +298 -0
  81. package/configs/fastapi/settings.json +35 -0
  82. package/configs/flask/CLAUDE.md +166 -0
  83. package/configs/flask/rules/blueprints.md +208 -0
  84. package/configs/flask/rules/cli.md +285 -0
  85. package/configs/flask/rules/configuration.md +281 -0
  86. package/configs/flask/rules/context.md +238 -0
  87. package/configs/flask/rules/error-handlers.md +278 -0
  88. package/configs/flask/rules/extensions.md +278 -0
  89. package/configs/flask/rules/flask.md +171 -0
  90. package/configs/flask/rules/marshmallow.md +206 -0
  91. package/configs/flask/rules/security.md +267 -0
  92. package/configs/flask/rules/testing.md +284 -0
  93. package/configs/flask/settings.json +35 -0
  94. package/configs/nestjs/CLAUDE.md +57 -215
  95. package/configs/nestjs/rules/common-patterns.md +300 -0
  96. package/configs/nestjs/rules/filters.md +376 -0
  97. package/configs/nestjs/rules/interceptors.md +317 -0
  98. package/configs/nestjs/rules/middleware.md +321 -0
  99. package/configs/nestjs/{.claude/rules → rules}/modules.md +26 -0
  100. package/configs/nestjs/rules/pipes.md +351 -0
  101. package/configs/nestjs/rules/websockets.md +451 -0
  102. package/configs/nestjs/settings.json +31 -0
  103. package/configs/nextjs/CLAUDE.md +69 -331
  104. package/configs/nextjs/rules/api-routes.md +358 -0
  105. package/configs/nextjs/rules/authentication.md +355 -0
  106. package/configs/nextjs/{.claude/rules → rules}/components.md +52 -0
  107. package/configs/nextjs/rules/data-fetching.md +249 -0
  108. package/configs/nextjs/rules/database.md +400 -0
  109. package/configs/nextjs/rules/middleware.md +303 -0
  110. package/configs/nextjs/rules/routing.md +324 -0
  111. package/configs/nextjs/rules/seo.md +350 -0
  112. package/configs/nextjs/rules/server-actions.md +353 -0
  113. package/configs/nextjs/{.claude/rules → rules}/state/zustand.md +6 -6
  114. package/configs/nextjs/{.claude/settings.json → settings.json} +7 -0
  115. package/package.json +24 -9
  116. package/src/cli.js +218 -0
  117. package/src/config.js +63 -0
  118. package/src/index.js +4 -0
  119. package/src/installer.js +414 -0
  120. package/src/merge.js +109 -0
  121. package/src/tech-config.json +45 -0
  122. package/src/utils.js +88 -0
  123. package/configs/dotnet/.claude/settings.json +0 -9
  124. package/configs/nestjs/.claude/settings.json +0 -15
  125. package/configs/python/.claude/rules/flask.md +0 -332
  126. package/configs/python/.claude/settings.json +0 -18
  127. package/configs/python/CLAUDE.md +0 -273
  128. package/src/install.js +0 -315
  129. /package/configs/_shared/{.claude/rules → rules/domain/frontend}/accessibility.md +0 -0
  130. /package/configs/_shared/{.claude/rules → rules/security}/security.md +0 -0
  131. /package/configs/_shared/{.claude/skills → skills/dev}/debug/SKILL.md +0 -0
  132. /package/configs/_shared/{.claude/skills → skills/dev}/learning/SKILL.md +0 -0
  133. /package/configs/_shared/{.claude/skills → skills/dev}/spec/SKILL.md +0 -0
  134. /package/configs/_shared/{.claude/skills → skills/git}/review/SKILL.md +0 -0
  135. /package/configs/dotnet/{.claude/rules → rules}/api.md +0 -0
  136. /package/configs/dotnet/{.claude/rules → rules}/architecture.md +0 -0
  137. /package/configs/dotnet/{.claude/rules → rules}/database/efcore.md +0 -0
  138. /package/configs/dotnet/{.claude/rules → rules}/testing.md +0 -0
  139. /package/configs/nestjs/{.claude/rules → rules}/auth.md +0 -0
  140. /package/configs/nestjs/{.claude/rules → rules}/database/prisma.md +0 -0
  141. /package/configs/nestjs/{.claude/rules → rules}/database/typeorm.md +0 -0
  142. /package/configs/nestjs/{.claude/rules → rules}/testing.md +0 -0
  143. /package/configs/nestjs/{.claude/rules → rules}/validation.md +0 -0
  144. /package/configs/nextjs/{.claude/rules → rules}/state/redux-toolkit.md +0 -0
  145. /package/configs/nextjs/{.claude/rules → rules}/testing.md +0 -0
package/src/install.js DELETED
@@ -1,315 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
-
4
- const CONFIGS_DIR = path.join(__dirname, '..', 'configs');
5
- const AVAILABLE_TECHS = ['angular', 'nextjs', 'nestjs', 'dotnet', 'python'];
6
-
7
- const colors = {
8
- red: (text) => `\x1b[31m${text}\x1b[0m`,
9
- green: (text) => `\x1b[32m${text}\x1b[0m`,
10
- blue: (text) => `\x1b[34m${text}\x1b[0m`,
11
- yellow: (text) => `\x1b[33m${text}\x1b[0m`,
12
- bold: (text) => `\x1b[1m${text}\x1b[0m`,
13
- };
14
-
15
- const log = {
16
- info: (msg) => console.log(`${colors.blue('ℹ')} ${msg}`),
17
- success: (msg) => console.log(`${colors.green('✓')} ${msg}`),
18
- warning: (msg) => console.log(`${colors.yellow('⚠')} ${msg}`),
19
- error: (msg) => console.log(`${colors.red('✗')} ${msg}`),
20
- };
21
-
22
- function printUsage() {
23
- console.log(`
24
- ${colors.bold('AI Rules')} - Claude Code configuration boilerplates
25
-
26
- ${colors.bold('Usage:')}
27
- ai-rules init <tech> [tech2] [options]
28
- ai-rules list
29
-
30
- ${colors.bold('Technologies:')}
31
- angular Angular 21 + Nx + NgRx
32
- nextjs Next.js 15 + React 19
33
- nestjs NestJS + Prisma/TypeORM
34
- dotnet .NET 8 + EF Core
35
- python FastAPI/Flask + SQLAlchemy
36
-
37
- ${colors.bold('Options:')}
38
- --with-skills Include skills (/learning, /review, /spec, /debug)
39
- --with-commands Include commands (fix-issue, review-pr, generate-tests)
40
- --with-rules Include shared rules (security, performance, accessibility)
41
- --all Include skills, commands, and rules
42
- --target <dir> Target directory (default: current directory)
43
-
44
- ${colors.bold('Examples:')}
45
- ai-rules init angular
46
- ai-rules init angular nestjs --all
47
- ai-rules init nextjs python --with-skills
48
- ai-rules init dotnet --target ./my-project
49
- ai-rules list
50
- `);
51
- }
52
-
53
- function copyDirRecursive(src, dest) {
54
- if (!fs.existsSync(src)) return;
55
-
56
- fs.mkdirSync(dest, { recursive: true });
57
-
58
- const entries = fs.readdirSync(src, { withFileTypes: true });
59
-
60
- for (const entry of entries) {
61
- const srcPath = path.join(src, entry.name);
62
- const destPath = path.join(dest, entry.name);
63
-
64
- if (entry.isDirectory()) {
65
- copyDirRecursive(srcPath, destPath);
66
- } else {
67
- fs.copyFileSync(srcPath, destPath);
68
- }
69
- }
70
- }
71
-
72
- function mergeClaudeMd(targetPath, sourcePath, isFirst) {
73
- const content = fs.readFileSync(sourcePath, 'utf8');
74
-
75
- if (isFirst) {
76
- fs.writeFileSync(targetPath, content);
77
- } else {
78
- const existing = fs.readFileSync(targetPath, 'utf8');
79
- fs.writeFileSync(targetPath, `${existing}\n\n---\n\n${content}`);
80
- }
81
- }
82
-
83
- function listTechnologies() {
84
- console.log(`\n${colors.bold('Available technologies:')}\n`);
85
-
86
- const techInfo = {
87
- angular: 'Angular 21 + Nx + NgRx + Signals',
88
- nextjs: 'Next.js 15 + React 19 + App Router',
89
- nestjs: 'NestJS 10 + Prisma/TypeORM + Passport',
90
- dotnet: '.NET 8 + ASP.NET Core + EF Core',
91
- python: 'FastAPI/Flask + SQLAlchemy 2.0',
92
- };
93
-
94
- for (const tech of AVAILABLE_TECHS) {
95
- const techPath = path.join(CONFIGS_DIR, tech);
96
- const exists = fs.existsSync(techPath);
97
- const status = exists ? colors.green('✓') : colors.red('✗');
98
- console.log(` ${status} ${colors.bold(tech.padEnd(10))} ${techInfo[tech]}`);
99
- }
100
-
101
- console.log(`\n${colors.bold('Shared resources:')}\n`);
102
-
103
- const sharedPath = path.join(CONFIGS_DIR, '_shared');
104
- const skills = fs.existsSync(path.join(sharedPath, '.claude', 'skills'));
105
- const commands = fs.existsSync(path.join(sharedPath, '.claude', 'commands'));
106
- const rules = fs.existsSync(path.join(sharedPath, '.claude', 'rules'));
107
-
108
- console.log(` ${skills ? colors.green('✓') : colors.red('✗')} skills /learning, /review, /spec, /debug`);
109
- console.log(` ${commands ? colors.green('✓') : colors.red('✗')} commands fix-issue, review-pr, generate-tests`);
110
- console.log(` ${rules ? colors.green('✓') : colors.red('✗')} rules security, performance, accessibility`);
111
- console.log('');
112
- }
113
-
114
- function init(techs, options) {
115
- const targetDir = options.target || process.cwd();
116
-
117
- log.info(`Installing Claude Code config to: ${targetDir}`);
118
- console.log('');
119
-
120
- // Create directories
121
- fs.mkdirSync(path.join(targetDir, '.claude', 'rules'), { recursive: true });
122
-
123
- // Install each technology
124
- let isFirstClaudeMd = true;
125
-
126
- for (const tech of techs) {
127
- log.info(`Installing ${tech}...`);
128
-
129
- const techDir = path.join(CONFIGS_DIR, tech);
130
-
131
- if (!fs.existsSync(techDir)) {
132
- log.error(`Technology directory not found: ${tech}`);
133
- process.exit(1);
134
- }
135
-
136
- // Copy CLAUDE.md
137
- const claudeMdPath = path.join(techDir, 'CLAUDE.md');
138
- if (fs.existsSync(claudeMdPath)) {
139
- mergeClaudeMd(
140
- path.join(targetDir, 'CLAUDE.md'),
141
- claudeMdPath,
142
- isFirstClaudeMd
143
- );
144
- isFirstClaudeMd = false;
145
- log.success(' CLAUDE.md');
146
- }
147
-
148
- // Copy settings.json
149
- const settingsPath = path.join(techDir, '.claude', 'settings.json');
150
- if (fs.existsSync(settingsPath)) {
151
- const targetSettingsPath = path.join(targetDir, '.claude', 'settings.json');
152
-
153
- if (!fs.existsSync(targetSettingsPath)) {
154
- fs.copyFileSync(settingsPath, targetSettingsPath);
155
- } else {
156
- // Merge permissions
157
- try {
158
- const existing = JSON.parse(fs.readFileSync(targetSettingsPath, 'utf8'));
159
- const incoming = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
160
-
161
- const merged = {
162
- permissions: {
163
- allow: [...new Set([
164
- ...(existing.permissions?.allow || []),
165
- ...(incoming.permissions?.allow || []),
166
- ])],
167
- deny: [],
168
- },
169
- };
170
-
171
- fs.writeFileSync(targetSettingsPath, JSON.stringify(merged, null, 2));
172
- } catch (e) {
173
- log.warning(' Could not merge settings.json');
174
- }
175
- }
176
- log.success(' settings.json');
177
- }
178
-
179
- // Copy rules
180
- const rulesDir = path.join(techDir, '.claude', 'rules');
181
- if (fs.existsSync(rulesDir)) {
182
- copyDirRecursive(rulesDir, path.join(targetDir, '.claude', 'rules'));
183
- log.success(' rules/');
184
- }
185
- }
186
-
187
- // Install shared resources
188
- const sharedDir = path.join(CONFIGS_DIR, '_shared');
189
-
190
- if (options.withSkills || options.all) {
191
- log.info('Installing skills...');
192
- const skillsDir = path.join(sharedDir, '.claude', 'skills');
193
- if (fs.existsSync(skillsDir)) {
194
- copyDirRecursive(skillsDir, path.join(targetDir, '.claude', 'skills'));
195
- log.success(' skills/ (learning, review, spec, debug)');
196
- }
197
- }
198
-
199
- if (options.withCommands || options.all) {
200
- log.info('Installing commands...');
201
- const commandsDir = path.join(sharedDir, '.claude', 'commands');
202
- if (fs.existsSync(commandsDir)) {
203
- copyDirRecursive(commandsDir, path.join(targetDir, '.claude', 'commands'));
204
- log.success(' commands/ (fix-issue, review-pr, generate-tests)');
205
- }
206
- }
207
-
208
- if (options.withRules || options.all) {
209
- log.info('Installing shared rules...');
210
- const rulesDir = path.join(sharedDir, '.claude', 'rules');
211
- if (fs.existsSync(rulesDir)) {
212
- copyDirRecursive(rulesDir, path.join(targetDir, '.claude', 'rules'));
213
- log.success(' rules/ (security, performance, accessibility)');
214
- }
215
- }
216
-
217
- // Resolve @../_shared/CLAUDE.md imports
218
- const targetClaudeMd = path.join(targetDir, 'CLAUDE.md');
219
- if (fs.existsSync(targetClaudeMd)) {
220
- let content = fs.readFileSync(targetClaudeMd, 'utf8');
221
-
222
- if (content.includes('@../_shared/CLAUDE.md')) {
223
- const sharedClaudeMd = path.join(sharedDir, 'CLAUDE.md');
224
- if (fs.existsSync(sharedClaudeMd)) {
225
- const sharedContent = fs.readFileSync(sharedClaudeMd, 'utf8');
226
- content = content.replace(/@..\/_shared\/CLAUDE\.md/g, '');
227
- content = sharedContent + '\n\n' + content;
228
- fs.writeFileSync(targetClaudeMd, content);
229
- log.success('Merged shared conventions into CLAUDE.md');
230
- }
231
- }
232
- }
233
-
234
- console.log('');
235
- log.success('Installation complete!');
236
- console.log('');
237
- console.log('Installed:');
238
- console.log(` - Technologies: ${techs.join(', ')}`);
239
- if (options.withSkills || options.all) {
240
- console.log(' - Skills: /learning, /review, /spec, /debug');
241
- }
242
- if (options.withCommands || options.all) {
243
- console.log(' - Commands: fix-issue, review-pr, generate-tests');
244
- }
245
- if (options.withRules || options.all) {
246
- console.log(' - Rules: security, performance, accessibility');
247
- }
248
- console.log('');
249
- console.log(`Files created in: ${targetDir}`);
250
- }
251
-
252
- function run(args) {
253
- if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
254
- printUsage();
255
- return;
256
- }
257
-
258
- const command = args[0];
259
-
260
- if (command === 'list') {
261
- listTechnologies();
262
- return;
263
- }
264
-
265
- if (command === 'init') {
266
- const options = {
267
- target: null,
268
- withSkills: false,
269
- withCommands: false,
270
- withRules: false,
271
- all: false,
272
- };
273
-
274
- const techs = [];
275
-
276
- for (let i = 1; i < args.length; i++) {
277
- const arg = args[i];
278
-
279
- if (arg === '--with-skills') {
280
- options.withSkills = true;
281
- } else if (arg === '--with-commands') {
282
- options.withCommands = true;
283
- } else if (arg === '--with-rules') {
284
- options.withRules = true;
285
- } else if (arg === '--all') {
286
- options.all = true;
287
- } else if (arg === '--target') {
288
- options.target = args[++i];
289
- } else if (!arg.startsWith('-')) {
290
- if (AVAILABLE_TECHS.includes(arg)) {
291
- techs.push(arg);
292
- } else {
293
- log.error(`Unknown technology: ${arg}`);
294
- console.log(`Available: ${AVAILABLE_TECHS.join(', ')}`);
295
- process.exit(1);
296
- }
297
- }
298
- }
299
-
300
- if (techs.length === 0) {
301
- log.error('No technology specified');
302
- printUsage();
303
- process.exit(1);
304
- }
305
-
306
- init(techs, options);
307
- return;
308
- }
309
-
310
- log.error(`Unknown command: ${command}`);
311
- printUsage();
312
- process.exit(1);
313
- }
314
-
315
- module.exports = { run };
File without changes
File without changes