@ulpi/cli 0.1.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 (92) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +200 -0
  3. package/dist/auth-PN7TMQHV-2W4ICG64.js +15 -0
  4. package/dist/chunk-247GVVKK.js +2259 -0
  5. package/dist/chunk-2CLNOKPA.js +793 -0
  6. package/dist/chunk-2HEE5OKX.js +79 -0
  7. package/dist/chunk-2MZER6ND.js +415 -0
  8. package/dist/chunk-3SBPZRB5.js +772 -0
  9. package/dist/chunk-4VNS5WPM.js +42 -0
  10. package/dist/chunk-6JCMYYBT.js +1546 -0
  11. package/dist/chunk-6OCEY7JY.js +422 -0
  12. package/dist/chunk-74WVVWJ4.js +375 -0
  13. package/dist/chunk-7AL4DOEJ.js +131 -0
  14. package/dist/chunk-7LXY5UVC.js +330 -0
  15. package/dist/chunk-DBMUNBNB.js +3048 -0
  16. package/dist/chunk-JWUUVXIV.js +13694 -0
  17. package/dist/chunk-KIKPIH6N.js +4048 -0
  18. package/dist/chunk-KLEASXUR.js +70 -0
  19. package/dist/chunk-MIAQVCFW.js +39 -0
  20. package/dist/chunk-NNUWU6CV.js +1610 -0
  21. package/dist/chunk-PKD4ASEM.js +115 -0
  22. package/dist/chunk-Q4HIY43N.js +4230 -0
  23. package/dist/chunk-QJ5GSMEC.js +146 -0
  24. package/dist/chunk-SIAQVRKG.js +2163 -0
  25. package/dist/chunk-SPOI23SB.js +197 -0
  26. package/dist/chunk-YM2HV4IA.js +505 -0
  27. package/dist/codemap-RRJIDBQ5.js +636 -0
  28. package/dist/config-EGAXXCGL.js +127 -0
  29. package/dist/dist-6G7JC2RA.js +90 -0
  30. package/dist/dist-7LHZ65GC.js +418 -0
  31. package/dist/dist-LZKZFPVX.js +140 -0
  32. package/dist/dist-R5F4MX3I.js +107 -0
  33. package/dist/dist-R5ZJ4LX5.js +56 -0
  34. package/dist/dist-RJGCUS3L.js +87 -0
  35. package/dist/dist-RKOGLK7R.js +151 -0
  36. package/dist/dist-W7K4WPAF.js +597 -0
  37. package/dist/export-import-4A5MWLIA.js +53 -0
  38. package/dist/history-ATTUKOHO.js +934 -0
  39. package/dist/index.js +2120 -0
  40. package/dist/init-AY5C2ZAS.js +393 -0
  41. package/dist/launchd-LF2QMSKZ.js +148 -0
  42. package/dist/log-TVTUXAYD.js +75 -0
  43. package/dist/mcp-installer-NQCGKQ23.js +124 -0
  44. package/dist/memory-J3G24QHS.js +406 -0
  45. package/dist/ollama-3XCUZMZT-FYKHW4TZ.js +7 -0
  46. package/dist/openai-E7G2YAHU-UYY4ZWON.js +8 -0
  47. package/dist/projects-ATHDD3D6.js +271 -0
  48. package/dist/review-ADUPV3PN.js +152 -0
  49. package/dist/rules-E427DKYJ.js +134 -0
  50. package/dist/server-MOYPE4SM-N7SE2AN7.js +18 -0
  51. package/dist/server-X5P6WH2M-7K2RY34N.js +11 -0
  52. package/dist/skills/ulpi-generate-guardian/SKILL.md +511 -0
  53. package/dist/skills/ulpi-generate-guardian/references/framework-rules.md +692 -0
  54. package/dist/skills/ulpi-generate-guardian/references/language-rules.md +596 -0
  55. package/dist/skills-CX73O3IV.js +76 -0
  56. package/dist/status-4DFHDJMN.js +66 -0
  57. package/dist/templates/biome.yml +24 -0
  58. package/dist/templates/conventional-commits.yml +18 -0
  59. package/dist/templates/django.yml +30 -0
  60. package/dist/templates/docker.yml +30 -0
  61. package/dist/templates/eslint.yml +13 -0
  62. package/dist/templates/express.yml +20 -0
  63. package/dist/templates/fastapi.yml +23 -0
  64. package/dist/templates/git-flow.yml +26 -0
  65. package/dist/templates/github-flow.yml +27 -0
  66. package/dist/templates/go.yml +33 -0
  67. package/dist/templates/jest.yml +24 -0
  68. package/dist/templates/laravel.yml +30 -0
  69. package/dist/templates/monorepo.yml +26 -0
  70. package/dist/templates/nestjs.yml +21 -0
  71. package/dist/templates/nextjs.yml +31 -0
  72. package/dist/templates/nodejs.yml +33 -0
  73. package/dist/templates/npm.yml +15 -0
  74. package/dist/templates/php.yml +25 -0
  75. package/dist/templates/pnpm.yml +15 -0
  76. package/dist/templates/prettier.yml +23 -0
  77. package/dist/templates/prisma.yml +21 -0
  78. package/dist/templates/python.yml +33 -0
  79. package/dist/templates/quality-of-life.yml +111 -0
  80. package/dist/templates/ruby.yml +25 -0
  81. package/dist/templates/rust.yml +34 -0
  82. package/dist/templates/typescript.yml +14 -0
  83. package/dist/templates/vitest.yml +24 -0
  84. package/dist/templates/yarn.yml +15 -0
  85. package/dist/templates-U7T6MARD.js +156 -0
  86. package/dist/ui-L7UAWXDY.js +167 -0
  87. package/dist/ui.html +698 -0
  88. package/dist/ulpi-RMMCUAGP-JCJ273T6.js +161 -0
  89. package/dist/uninstall-6SW35IK4.js +25 -0
  90. package/dist/update-M2B4RLGH.js +61 -0
  91. package/dist/version-checker-ANCS3IHR.js +10 -0
  92. package/package.json +92 -0
@@ -0,0 +1,511 @@
1
+ ---
2
+ name: ulpi-generate-guards
3
+ description: Use when the user asks to generate ULPI configuration for a project. Detects language, framework, package manager, and tooling to create optimized guards.yml with preconditions, permissions, postconditions, and pipelines. Invoke via /ulpi-generate-guards or when user says "generate guards", "create guards.yml", "setup ulpi", "configure guardian".
4
+ ---
5
+
6
+ <EXTREMELY-IMPORTANT>
7
+ Before generating ANY guards.yml configuration, you **ABSOLUTELY MUST**:
8
+
9
+ 1. Verify the target directory exists
10
+ 2. Check for existing `.ulpi/guards.yml` (ask before overwriting)
11
+ 3. Detect at least one technology signal (language, framework, or package manager)
12
+
13
+ **Generating without verification = wrong rules, overwritten configs, broken guards**
14
+
15
+ This is not optional. Every generation requires disciplined verification.
16
+ </EXTREMELY-IMPORTANT>
17
+
18
+ # Generate ULPI Configuration
19
+
20
+ ## MANDATORY FIRST RESPONSE PROTOCOL
21
+
22
+ Before generating ANY configuration, you **MUST** complete this checklist:
23
+
24
+ 1. ☐ Verify target directory exists
25
+ 2. ☐ Check for existing guards.yml
26
+ 3. ☐ Detect language (tsconfig.json, pyproject.toml, go.mod, etc.)
27
+ 4. ☐ Detect framework (next.config.*, artisan, manage.py, etc.)
28
+ 5. ☐ Detect package manager (pnpm-lock.yaml, yarn.lock, etc.)
29
+ 6. ☐ Announce: "Generating ULPI configuration for [language]/[framework]/[package_manager]"
30
+
31
+ Do NOT ask "Proceed?" — the user invoked this skill explicitly. Show the detected stack as an informational summary, then generate immediately.
32
+
33
+ **Generating WITHOUT completing this checklist = wrong or harmful rules.**
34
+
35
+ ## Purpose
36
+
37
+ This skill generates configuration for **ULPI**, a tool that:
38
+ - Auto-approves safe operations (reads, package manager commands)
39
+ - Blocks dangerous commands (force push, database wipes, env file edits)
40
+ - Enforces best practices (read-before-write)
41
+ - Runs postconditions (lint, test, generate) after file changes
42
+
43
+ **Output:** `.ulpi/guards.yml` configuration file
44
+
45
+ **Does NOT:** Install ULPI, run the generated rules, or modify existing configurations without confirmation.
46
+
47
+ ## Overview
48
+
49
+ Analyze a project directory, detect the technology stack, and generate a complete `guards.yml` configuration for ULPI. Creates rules that auto-approve safe operations, block dangerous commands, and enforce best practices.
50
+
51
+ ## When to Use
52
+
53
+ - User says "generate guards", "create guards.yml", "/ulpi-generate-guards"
54
+ - User says "setup ulpi", "configure guardian for this project"
55
+ - $ARGUMENTS contains a path (e.g., `/ulpi-generate-guards /path/to/project`)
56
+
57
+ **Never generate unprompted.** Only when explicitly requested.
58
+
59
+ ## Step 1: Determine Target Directory
60
+
61
+ **Gate: Valid directory confirmed before proceeding to Step 2.**
62
+
63
+ If $ARGUMENTS has a path, use it. Otherwise use current working directory.
64
+
65
+ Verify the directory exists before proceeding. If not found, stop and inform the user.
66
+
67
+ Check for existing `.ulpi/guards.yml`:
68
+ - If found, ask user: merge, overwrite, or abort?
69
+ - Never overwrite without explicit confirmation
70
+
71
+ ## Step 2: Detect Technology Stack
72
+
73
+ **Gate: Stack detected before proceeding to Step 3.**
74
+
75
+ Scan for indicator files in priority order:
76
+
77
+ ### Language Detection
78
+
79
+ | Signal | Language |
80
+ |--------|----------|
81
+ | `tsconfig.json` | TypeScript |
82
+ | `package.json` (no tsconfig) | JavaScript |
83
+ | `pyproject.toml`, `requirements.txt` | Python |
84
+ | `go.mod` | Go |
85
+ | `Cargo.toml` | Rust |
86
+ | `composer.json` | PHP |
87
+ | `Gemfile` | Ruby |
88
+ | `pom.xml`, `build.gradle` | Java |
89
+ | `*.csproj`, `*.sln` | C# |
90
+ | `mix.exs` | Elixir |
91
+
92
+ ### Framework Detection
93
+
94
+ | Signal | Framework |
95
+ |--------|-----------|
96
+ | `next.config.*` | Next.js |
97
+ | `nuxt.config.*` | Nuxt |
98
+ | `angular.json` | Angular |
99
+ | `svelte.config.*` | SvelteKit |
100
+ | `nest-cli.json` | NestJS |
101
+ | `artisan` | Laravel |
102
+ | `manage.py` + django | Django |
103
+ | `fastapi` in deps | FastAPI |
104
+ | `actix-web` in Cargo.toml | Actix |
105
+ | `gin` in go.mod | Gin |
106
+
107
+ ### Package Manager Detection
108
+
109
+ | Signal | Package Manager |
110
+ |--------|-----------------|
111
+ | `pnpm-lock.yaml` | pnpm |
112
+ | `yarn.lock` | yarn |
113
+ | `package-lock.json` | npm |
114
+ | `bun.lockb` | bun |
115
+ | `poetry.lock` | poetry |
116
+ | `uv.lock` | uv |
117
+ | `Cargo.lock` | cargo |
118
+ | `composer.lock` | composer |
119
+ | `Gemfile.lock` | bundler |
120
+
121
+ ### Tooling Detection
122
+
123
+ | Signal | Tool | Type |
124
+ |--------|------|------|
125
+ | `vitest.config.*` | Vitest | test |
126
+ | `jest.config.*` | Jest | test |
127
+ | `pytest.ini` | pytest | test |
128
+ | `.eslintrc*` | ESLint | lint |
129
+ | `.prettierrc*` | Prettier | format |
130
+ | `biome.json` | Biome | lint+format |
131
+ | `prisma/schema.prisma` | Prisma | ORM |
132
+ | `drizzle.config.*` | Drizzle | ORM |
133
+
134
+ ### Monorepo Detection
135
+
136
+ | Signal | Structure |
137
+ |--------|-----------|
138
+ | `turbo.json` | Turborepo |
139
+ | `lerna.json` | Lerna |
140
+ | `pnpm-workspace.yaml` | pnpm workspaces |
141
+ | `"workspaces"` in package.json | Yarn/npm workspaces |
142
+
143
+ For monorepos: Generate root-level rules that apply to all packages.
144
+
145
+ ## Step 3: Extract Commands from Config
146
+
147
+ **Gate: Commands extracted before proceeding to Step 4.**
148
+
149
+ For Node.js projects, read package.json scripts to identify:
150
+ - `test_command` (from "test" script)
151
+ - `build_command` (from "build" script)
152
+ - `lint_command` (from "lint" script)
153
+ - `format_command` (from "format" script)
154
+
155
+ For Python projects, check pyproject.toml for tool configurations.
156
+
157
+ For Rust projects, use standard cargo commands.
158
+
159
+ ## Step 4: Generate guards.yml
160
+
161
+ **Gate: Complete rules generated before proceeding to Step 5.**
162
+
163
+ Create `.ulpi/guards.yml` with these sections:
164
+
165
+ ### Header
166
+
167
+ ```yaml
168
+ # ULPI — Generated Configuration
169
+ # Stack: {language} / {framework} / {package_manager}
170
+ # Generated: {timestamp}
171
+
172
+ project:
173
+ name: "{project_name}"
174
+ runtime: "{runtime}"
175
+ package_manager: "{package_manager}"
176
+ ```
177
+
178
+ ### Universal Preconditions (Always Include)
179
+
180
+ ```yaml
181
+ preconditions:
182
+ read-before-write:
183
+ enabled: true
184
+ trigger: PreToolUse
185
+ matcher: "Write|Edit|MultiEdit"
186
+ requires_read: true
187
+ message: "Read {file_path} before editing it."
188
+ locked: true
189
+ priority: 10
190
+ ```
191
+
192
+ ### Universal Permissions (Always Include)
193
+
194
+ ```yaml
195
+ permissions:
196
+ auto-approve-reads:
197
+ enabled: true
198
+ trigger: PermissionRequest
199
+ matcher: "Read|LS|Glob|Grep"
200
+ decision: allow
201
+ priority: 100
202
+
203
+ no-force-push:
204
+ enabled: true
205
+ trigger: PreToolUse
206
+ matcher: Bash
207
+ command_pattern: "git push --force"
208
+ decision: deny
209
+ message: "Force push blocked. Use --force-with-lease."
210
+ locked: true
211
+ priority: 1
212
+
213
+ block-env-files:
214
+ enabled: true
215
+ trigger: PreToolUse
216
+ matcher: "Write|Edit"
217
+ file_pattern: ".env*"
218
+ decision: deny
219
+ message: "Cannot edit .env files directly."
220
+ priority: 50
221
+
222
+ block-node-modules:
223
+ enabled: true
224
+ trigger: PreToolUse
225
+ matcher: "Write|Edit"
226
+ file_pattern: "node_modules/**"
227
+ decision: deny
228
+ locked: true
229
+ priority: 1
230
+
231
+ block-dist:
232
+ enabled: true
233
+ trigger: PreToolUse
234
+ matcher: "Write|Edit"
235
+ file_pattern: "**/dist/**"
236
+ decision: deny
237
+ locked: true
238
+ priority: 1
239
+ ```
240
+
241
+ ### Language-Specific Rules
242
+
243
+ Add based on detected language. See `references/language-rules.md`.
244
+
245
+ ### Framework-Specific Rules
246
+
247
+ Add based on detected framework. See `references/framework-rules.md`.
248
+
249
+ ## Step 5: Write Configuration
250
+
251
+ **Gate: File written before proceeding to Step 6.**
252
+
253
+ Create the `.ulpi/` directory if it doesn't exist.
254
+
255
+ Write the generated YAML to `guards.yml`.
256
+
257
+ Verify the file was written successfully.
258
+
259
+ ## Step 6: Report Results
260
+
261
+ **Gate: Results reported before marking complete.**
262
+
263
+ Report to the user:
264
+ - Stack detected
265
+ - Rules created (counts)
266
+ - File location
267
+ - Suggested next steps
268
+
269
+ ## Pre-Generation Checklist
270
+
271
+ Before generating, verify:
272
+ - [ ] Target directory exists and is accessible
273
+ - [ ] No existing guards.yml OR user approved overwrite
274
+ - [ ] At least one technology detected
275
+
276
+ ## Error Handling
277
+
278
+ | Situation | Action |
279
+ |-----------|--------|
280
+ | Directory not found | Stop and inform user |
281
+ | No tech stack detected | Generate minimal universal rules only |
282
+ | Multiple frameworks | Ask user which is primary |
283
+ | Existing guards.yml | Ask: merge, overwrite, or abort |
284
+ | Conflicting signals | Prefer more specific (framework > language) |
285
+
286
+ ## About Postconditions
287
+
288
+ Postconditions are **disabled by default** because they run automatically after file changes and may:
289
+ - Slow down workflows
290
+ - Produce unexpected side effects
291
+ - Conflict with user's preferred workflow
292
+
293
+ **To enable:** User should manually set `enabled: true` for desired postconditions after reviewing them.
294
+
295
+ ## Safety Rules
296
+
297
+ | Rule | Reason |
298
+ |------|--------|
299
+ | Always include read-before-write | Prevents editing files without reading first |
300
+ | Always block force push | Prevents history destruction |
301
+ | Always block .env edits | Protects secrets |
302
+ | Always block node_modules/dist | Build artifacts should not be edited |
303
+ | Auto-approve reads | Safe operations should not prompt |
304
+ | Auto-approve detected package manager | Reduces friction |
305
+ | Never overwrite without asking | Preserves existing configuration |
306
+ | Always verify directory exists | Prevents errors |
307
+
308
+ ## Quick Reference: Command Detection
309
+
310
+ ```
311
+ package.json scripts:
312
+ "test" → test_command
313
+ "build" → build_command
314
+ "lint" → lint_command
315
+ "format" → format_command
316
+ "dev" → auto-approve permission
317
+
318
+ pyproject.toml:
319
+ [tool.pytest] → pytest
320
+ [tool.ruff] → ruff
321
+ [tool.black] → black
322
+
323
+ Cargo.toml:
324
+ cargo test → test_command
325
+ cargo build → build_command
326
+ cargo clippy → lint_command
327
+ ```
328
+
329
+ ---
330
+
331
+ ## Quality Checklist (Must Score 8/10)
332
+
333
+ Score yourself honestly before marking generation complete:
334
+
335
+ ### Detection Accuracy (0-2 points)
336
+ - **0 points:** Guessed technology without file verification
337
+ - **1 point:** Detected some signals but missed others
338
+ - **2 points:** Verified all signals, detection matches reality
339
+
340
+ ### Stack Announcement (0-2 points)
341
+ - **0 points:** Generated without showing detected stack
342
+ - **1 point:** Showed partial detection
343
+ - **2 points:** Full detection shown before generation
344
+
345
+ ### Rule Coverage (0-2 points)
346
+ - **0 points:** Missing universal rules (read-before-write, block-env)
347
+ - **1 point:** Universal rules present but missing language/framework rules
348
+ - **2 points:** Complete coverage: universal + language + framework + tooling
349
+
350
+ ### Safety Rules (0-2 points)
351
+ - **0 points:** Missing critical blocks (force-push, env files)
352
+ - **1 point:** Some safety rules but incomplete
353
+ - **2 points:** All dangerous operations blocked
354
+
355
+ ### Output Quality (0-2 points)
356
+ - **0 points:** Invalid YAML or missing required fields
357
+ - **1 point:** Valid but poorly organized
358
+ - **2 points:** Clean, well-commented, properly structured YAML
359
+
360
+ **Minimum passing score: 8/10**
361
+
362
+ ---
363
+
364
+ ## Common Rationalizations (All Wrong)
365
+
366
+ These are excuses. Don't fall for them:
367
+
368
+ - **"The directory is obvious"** → STILL verify it exists
369
+ - **"I know this is a Node.js project"** → STILL detect from config files
370
+ - **"There's no existing guards.yml"** → STILL check before generating
371
+ - **"The user wants it fast"** → STILL show detected stack first
372
+ - **"These are standard rules"** → STILL customize for detected stack
373
+ - **"Postconditions are disabled anyway"** → STILL generate them correctly
374
+
375
+ ---
376
+
377
+ ## Failure Modes
378
+
379
+ ### Failure Mode 1: Wrong Technology Detection
380
+
381
+ **Symptom:** Generated Python rules for a TypeScript project
382
+ **Fix:** Always verify with config files, not assumptions
383
+
384
+ ### Failure Mode 2: Overwritten Existing Config
385
+
386
+ **Symptom:** User's custom guards.yml was replaced without warning
387
+ **Fix:** Always check for existing file, ask before overwriting
388
+
389
+ ### Failure Mode 3: Missing Critical Safety Rules
390
+
391
+ **Symptom:** Agent force-pushed after generation (rule wasn't blocked)
392
+ **Fix:** Always include universal safety rules regardless of stack
393
+
394
+ ### Failure Mode 4: Invalid YAML Generated
395
+
396
+ **Symptom:** ULPI fails to parse guards.yml
397
+ **Fix:** Validate YAML structure before writing
398
+
399
+ ---
400
+
401
+ ## Quick Workflow Summary
402
+
403
+ ```
404
+ STEP 1: DETERMINE TARGET
405
+ ├── Parse $ARGUMENTS for path
406
+ ├── Default to current directory
407
+ ├── Verify directory exists
408
+ ├── Check for existing guards.yml
409
+ └── Gate: Valid directory confirmed
410
+
411
+ STEP 2: DETECT TECHNOLOGY
412
+ ├── Scan for language signals
413
+ ├── Scan for framework signals
414
+ ├── Scan for package manager signals
415
+ ├── Scan for tooling (test, lint, ORM)
416
+ ├── Check for monorepo structure
417
+ ├── Announce detected stack (informational, no question)
418
+ └── Gate: Stack detected
419
+
420
+ STEP 3: EXTRACT COMMANDS
421
+ ├── Read package.json scripts
422
+ ├── Read pyproject.toml tools
423
+ ├── Identify test/build/lint commands
424
+ └── Gate: Commands extracted
425
+
426
+ STEP 4: GENERATE RULES
427
+ ├── Start with universal rules
428
+ ├── Add language-specific rules
429
+ ├── Add framework-specific rules
430
+ ├── Add tooling rules
431
+ └── Gate: Complete rules generated
432
+
433
+ STEP 5: WRITE CONFIGURATION
434
+ ├── Create .ulpi/ directory
435
+ ├── Write guards.yml
436
+ ├── Verify file written
437
+ └── Gate: File written
438
+
439
+ STEP 6: REPORT RESULTS
440
+ ├── Show stack summary
441
+ ├── Show rule counts
442
+ ├── Show file location
443
+ ├── Suggest next steps
444
+ └── Gate: Complete
445
+ ```
446
+
447
+ ---
448
+
449
+ ## Completion Announcement
450
+
451
+ When generation is complete, announce:
452
+
453
+ ```
454
+ ULPI configuration generated.
455
+
456
+ **Quality Score: X/10**
457
+ - Detection Accuracy: X/2
458
+ - Stack Announcement: X/2
459
+ - Rule Coverage: X/2
460
+ - Safety Rules: X/2
461
+ - Output Quality: X/2
462
+
463
+ **Stack Detected:**
464
+ - Language: [language]
465
+ - Framework: [framework]
466
+ - Package Manager: [package_manager]
467
+ - Test Runner: [test_runner]
468
+ - Linter: [linter]
469
+
470
+ **Rules Generated:**
471
+ - Preconditions: [count]
472
+ - Permissions: [count]
473
+ - Postconditions: [count]
474
+
475
+ **Output:** .ulpi/guards.yml
476
+
477
+ **Next steps:**
478
+ Run `ulpi rules validate` to verify configuration.
479
+ ```
480
+
481
+ ---
482
+
483
+ ## Integration with Other Skills
484
+
485
+ The `ulpi-generate-guards` skill integrates with:
486
+
487
+ - **`start`** — Detects ULPI configuration needs during project setup
488
+ - **`commit`** — Generated rules can auto-approve git operations
489
+ - **`create-pr`** — Generated rules can auto-approve PR creation commands
490
+
491
+ **Workflow Chain:**
492
+
493
+ ```
494
+ New project or directory
495
+
496
+
497
+ ulpi-generate-guards skill (this skill)
498
+
499
+
500
+ guards.yml created
501
+
502
+
503
+ ULPI uses rules during development
504
+ ```
505
+
506
+ ---
507
+
508
+ ## Resources
509
+
510
+ See `references/language-rules.md` for language-specific rule templates.
511
+ See `references/framework-rules.md` for framework-specific rule templates.