@corbat-tech/coding-standards-mcp 1.0.3 → 2.0.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 (99) hide show
  1. package/README.md +233 -337
  2. package/dist/agent.d.ts +5 -6
  3. package/dist/agent.d.ts.map +1 -1
  4. package/dist/agent.js +95 -217
  5. package/dist/agent.js.map +1 -1
  6. package/dist/analysis/code-analyzer.d.ts +44 -0
  7. package/dist/analysis/code-analyzer.d.ts.map +1 -0
  8. package/dist/analysis/code-analyzer.js +528 -0
  9. package/dist/analysis/code-analyzer.js.map +1 -0
  10. package/dist/errors.d.ts +58 -0
  11. package/dist/errors.d.ts.map +1 -0
  12. package/dist/errors.js +112 -0
  13. package/dist/errors.js.map +1 -0
  14. package/dist/guardrails.d.ts +35 -0
  15. package/dist/guardrails.d.ts.map +1 -0
  16. package/dist/guardrails.js +303 -0
  17. package/dist/guardrails.js.map +1 -0
  18. package/dist/index.js +1 -1
  19. package/dist/index.js.map +1 -1
  20. package/dist/logger.d.ts +36 -0
  21. package/dist/logger.d.ts.map +1 -0
  22. package/dist/logger.js +63 -0
  23. package/dist/logger.js.map +1 -0
  24. package/dist/metrics.d.ts +40 -0
  25. package/dist/metrics.d.ts.map +1 -0
  26. package/dist/metrics.js +97 -0
  27. package/dist/metrics.js.map +1 -0
  28. package/dist/profiles.d.ts +1 -1
  29. package/dist/profiles.d.ts.map +1 -1
  30. package/dist/profiles.js +239 -108
  31. package/dist/profiles.js.map +1 -1
  32. package/dist/prompts.js +1 -1
  33. package/dist/prompts.js.map +1 -1
  34. package/dist/tools/definitions.d.ts +143 -0
  35. package/dist/tools/definitions.d.ts.map +1 -0
  36. package/dist/tools/definitions.js +229 -0
  37. package/dist/tools/definitions.js.map +1 -0
  38. package/dist/tools/handlers/get-context.d.ts +12 -0
  39. package/dist/tools/handlers/get-context.d.ts.map +1 -0
  40. package/dist/tools/handlers/get-context.js +233 -0
  41. package/dist/tools/handlers/get-context.js.map +1 -0
  42. package/dist/tools/handlers/health.d.ts +11 -0
  43. package/dist/tools/handlers/health.d.ts.map +1 -0
  44. package/dist/tools/handlers/health.js +57 -0
  45. package/dist/tools/handlers/health.js.map +1 -0
  46. package/dist/tools/handlers/index.d.ts +12 -0
  47. package/dist/tools/handlers/index.d.ts.map +1 -0
  48. package/dist/tools/handlers/index.js +12 -0
  49. package/dist/tools/handlers/index.js.map +1 -0
  50. package/dist/tools/handlers/init.d.ts +12 -0
  51. package/dist/tools/handlers/init.d.ts.map +1 -0
  52. package/dist/tools/handlers/init.js +102 -0
  53. package/dist/tools/handlers/init.js.map +1 -0
  54. package/dist/tools/handlers/profiles.d.ts +11 -0
  55. package/dist/tools/handlers/profiles.d.ts.map +1 -0
  56. package/dist/tools/handlers/profiles.js +25 -0
  57. package/dist/tools/handlers/profiles.js.map +1 -0
  58. package/dist/tools/handlers/search.d.ts +12 -0
  59. package/dist/tools/handlers/search.d.ts.map +1 -0
  60. package/dist/tools/handlers/search.js +58 -0
  61. package/dist/tools/handlers/search.js.map +1 -0
  62. package/dist/tools/handlers/validate.d.ts +15 -0
  63. package/dist/tools/handlers/validate.d.ts.map +1 -0
  64. package/dist/tools/handlers/validate.js +71 -0
  65. package/dist/tools/handlers/validate.js.map +1 -0
  66. package/dist/tools/handlers/verify.d.ts +38 -0
  67. package/dist/tools/handlers/verify.d.ts.map +1 -0
  68. package/dist/tools/handlers/verify.js +172 -0
  69. package/dist/tools/handlers/verify.js.map +1 -0
  70. package/dist/tools/index.d.ts +22 -0
  71. package/dist/tools/index.d.ts.map +1 -0
  72. package/dist/tools/index.js +75 -0
  73. package/dist/tools/index.js.map +1 -0
  74. package/dist/tools/schemas.d.ts +29 -0
  75. package/dist/tools/schemas.d.ts.map +1 -0
  76. package/dist/tools/schemas.js +20 -0
  77. package/dist/tools/schemas.js.map +1 -0
  78. package/dist/tools.js +2 -2
  79. package/dist/tools.js.map +1 -1
  80. package/dist/types.d.ts +141 -71
  81. package/dist/types.d.ts.map +1 -1
  82. package/dist/types.js +92 -40
  83. package/dist/types.js.map +1 -1
  84. package/package.json +2 -2
  85. package/profiles/examples/microservice-kafka.yaml +122 -0
  86. package/profiles/examples/startup-fast.yaml +67 -0
  87. package/profiles/examples/strict-enterprise.yaml +62 -0
  88. package/profiles/templates/angular.yaml +614 -0
  89. package/profiles/templates/csharp-dotnet.yaml +529 -0
  90. package/profiles/templates/flutter.yaml +547 -0
  91. package/profiles/templates/go.yaml +1276 -0
  92. package/profiles/templates/java-spring-backend.yaml +326 -0
  93. package/profiles/templates/kotlin-spring.yaml +417 -0
  94. package/profiles/templates/nextjs.yaml +536 -0
  95. package/profiles/templates/nodejs.yaml +594 -0
  96. package/profiles/templates/python.yaml +546 -0
  97. package/profiles/templates/react.yaml +456 -0
  98. package/profiles/templates/rust.yaml +508 -0
  99. package/profiles/templates/vue.yaml +483 -0
@@ -0,0 +1,508 @@
1
+ # ============================================================================
2
+ # CORBAT MCP - Rust Profile
3
+ # ============================================================================
4
+ # Production-ready standards for Rust backend applications.
5
+ # Based on Rust idioms, ownership patterns, and the Rust API Guidelines.
6
+ # ============================================================================
7
+
8
+ name: "Rust Backend Standards"
9
+ description: "Production-ready standards for Rust backend with ownership patterns, error handling, and idiomatic Rust"
10
+
11
+ # ----------------------------------------------------------------------------
12
+ # ARCHITECTURE
13
+ # ----------------------------------------------------------------------------
14
+ architecture:
15
+ type: clean
16
+ enforceLayerDependencies: true
17
+ layers:
18
+ - name: domain
19
+ description: "Core business logic. Pure Rust with no external dependencies. Contains entities, value objects, and traits."
20
+ allowedDependencies: []
21
+ modules:
22
+ - "src/domain"
23
+ - "src/domain/entities"
24
+ - "src/domain/value_objects"
25
+ - "src/domain/errors"
26
+ - "src/domain/traits"
27
+
28
+ - name: application
29
+ description: "Use cases and application services. Orchestrates domain objects."
30
+ allowedDependencies:
31
+ - domain
32
+ modules:
33
+ - "src/application"
34
+ - "src/application/use_cases"
35
+ - "src/application/services"
36
+ - "src/application/ports"
37
+
38
+ - name: infrastructure
39
+ description: "External adapters: HTTP handlers, database repositories, external APIs."
40
+ allowedDependencies:
41
+ - domain
42
+ - application
43
+ modules:
44
+ - "src/infrastructure"
45
+ - "src/infrastructure/http"
46
+ - "src/infrastructure/persistence"
47
+ - "src/infrastructure/external"
48
+
49
+ # ----------------------------------------------------------------------------
50
+ # OWNERSHIP & BORROWING
51
+ # ----------------------------------------------------------------------------
52
+ ownership:
53
+ enabled: true
54
+
55
+ patterns:
56
+ preferBorrowing: true
57
+ useSlicesOverVecs: true
58
+ avoidUnnecessaryClone: true
59
+ useRcArcJudiciously: true
60
+ examples:
61
+ - "Accept &str instead of String when not taking ownership"
62
+ - "Accept &[T] instead of Vec<T> or &Vec<T>"
63
+ - "Return owned types from constructors"
64
+ - "Use Cow<str> for flexible borrowing"
65
+
66
+ lifetimes:
67
+ elisionWhenPossible: true
68
+ explicitWhenClear: true
69
+ avoidStaticUnlessNeeded: true
70
+ examples:
71
+ - "fn process(data: &str) -> &str // elision"
72
+ - "fn longest<'a>(x: &'a str, y: &'a str) -> &'a str // explicit"
73
+
74
+ smartPointers:
75
+ box: "Heap allocation, recursive types"
76
+ rc: "Shared ownership, single-threaded"
77
+ arc: "Shared ownership, multi-threaded"
78
+ refCell: "Interior mutability, single-threaded"
79
+ mutex: "Interior mutability, multi-threaded"
80
+ rwLock: "Multiple readers OR single writer"
81
+
82
+ # ----------------------------------------------------------------------------
83
+ # ERROR HANDLING
84
+ # ----------------------------------------------------------------------------
85
+ errorHandling:
86
+ format: "Result<T, E> and Option<T>"
87
+
88
+ libraries:
89
+ thiserror: "Library error types (custom Error derive)"
90
+ anyhow: "Application error handling (context, backtraces)"
91
+
92
+ patterns:
93
+ resultForFallible: true
94
+ optionForAbsence: true
95
+ questionMarkPropagation: true
96
+ contextWrapping: true
97
+ noPanicInLibraries: true
98
+
99
+ customErrors:
100
+ approach: "thiserror derive"
101
+ example: |
102
+ #[derive(Debug, thiserror::Error)]
103
+ pub enum OrderError {
104
+ #[error("Order {0} not found")]
105
+ NotFound(OrderId),
106
+
107
+ #[error("Invalid order status transition from {from} to {to}")]
108
+ InvalidStatusTransition { from: OrderStatus, to: OrderStatus },
109
+
110
+ #[error("Order validation failed: {0}")]
111
+ Validation(String),
112
+
113
+ #[error(transparent)]
114
+ Database(#[from] sqlx::Error),
115
+ }
116
+
117
+ applicationErrors:
118
+ approach: "anyhow for context"
119
+ example: |
120
+ async fn process_order(id: OrderId) -> anyhow::Result<Order> {
121
+ let order = repository
122
+ .find_by_id(id)
123
+ .await
124
+ .context("Failed to fetch order from database")?
125
+ .ok_or_else(|| anyhow!("Order {} not found", id))?;
126
+
127
+ Ok(order)
128
+ }
129
+
130
+ avoid:
131
+ - "panic! in library code"
132
+ - "unwrap() without certainty"
133
+ - "expect() without meaningful message"
134
+ - "Ignoring Result with let _ ="
135
+
136
+ # ----------------------------------------------------------------------------
137
+ # CODE QUALITY
138
+ # ----------------------------------------------------------------------------
139
+ codeQuality:
140
+ maxMethodLines: 30
141
+ maxClassLines: 300
142
+ maxFileLines: 500
143
+ maxMethodParameters: 4
144
+ maxCyclomaticComplexity: 10
145
+ requireDocumentation: true
146
+ requireTests: true
147
+ minimumTestCoverage: 70
148
+
149
+ principles:
150
+ - "Make illegal states unrepresentable"
151
+ - "Parse, don't validate"
152
+ - "Prefer iterators over loops"
153
+ - "Leverage the type system"
154
+ - "Zero-cost abstractions"
155
+ - "Fearless concurrency"
156
+
157
+ linting:
158
+ clippy:
159
+ enabled: true
160
+ pedantic: true
161
+ deny:
162
+ - "clippy::unwrap_used"
163
+ - "clippy::expect_used"
164
+ - "clippy::panic"
165
+ - "clippy::todo"
166
+ allow:
167
+ - "clippy::module_name_repetitions"
168
+ rustfmt:
169
+ enabled: true
170
+ config: "rustfmt.toml"
171
+
172
+ # ----------------------------------------------------------------------------
173
+ # NAMING CONVENTIONS
174
+ # ----------------------------------------------------------------------------
175
+ naming:
176
+ general:
177
+ module: snake_case
178
+ type: PascalCase
179
+ trait: PascalCase
180
+ function: snake_case
181
+ method: snake_case
182
+ variable: snake_case
183
+ constant: SCREAMING_SNAKE_CASE
184
+ lifetime: lowercase_short
185
+ typeParameter: PascalCase_short
186
+
187
+ conventions:
188
+ constructors: "new, with_*, from_*"
189
+ conversions: "into_*, to_*, as_*"
190
+ getters: "field_name (no get_ prefix)"
191
+ setters: "set_field_name"
192
+ predicates: "is_*, has_*"
193
+ fallible: "try_*"
194
+ async: "No special suffix"
195
+
196
+ testing:
197
+ testModule: "tests"
198
+ testFunction: "test_function_scenario"
199
+ integrationTest: "tests/*.rs"
200
+
201
+ # ----------------------------------------------------------------------------
202
+ # TESTING
203
+ # ----------------------------------------------------------------------------
204
+ testing:
205
+ framework: "built-in (#[test])"
206
+ assertionLibrary: "built-in (assert!, assert_eq!)"
207
+ mockingLibrary: "mockall"
208
+ propertyTesting: "proptest"
209
+
210
+ types:
211
+ unit:
212
+ location: "Same file, #[cfg(test)] mod tests"
213
+ coverage: 70
214
+ patterns:
215
+ - "arrange_act_assert"
216
+ - "given_when_then"
217
+
218
+ integration:
219
+ location: "tests/*.rs"
220
+ useTestContainers: true
221
+ example: |
222
+ #[tokio::test]
223
+ async fn test_create_order_integration() {
224
+ let db = TestDatabase::new().await;
225
+ let app = TestApp::new(db.pool()).await;
226
+
227
+ let response = app
228
+ .post("/api/orders")
229
+ .json(&create_order_request())
230
+ .send()
231
+ .await;
232
+
233
+ assert_eq!(response.status(), StatusCode::CREATED);
234
+ }
235
+
236
+ documentation:
237
+ enabled: true
238
+ runWithTests: true
239
+ example: |
240
+ /// Creates a new order with the given items.
241
+ ///
242
+ /// # Examples
243
+ ///
244
+ /// ```
245
+ /// let order = Order::new(customer_id, vec![item]);
246
+ /// assert!(order.is_pending());
247
+ /// ```
248
+
249
+ patterns:
250
+ rstest: true
251
+ parameterized: true
252
+ fixtures: true
253
+ example: |
254
+ #[rstest]
255
+ #[case(vec![], 0)]
256
+ #[case(vec![10], 10)]
257
+ #[case(vec![1, 2, 3], 6)]
258
+ fn test_calculate_total(#[case] items: Vec<i32>, #[case] expected: i32) {
259
+ assert_eq!(calculate_total(&items), expected);
260
+ }
261
+
262
+ testcontainers:
263
+ enabled: true
264
+ containers:
265
+ - "postgres"
266
+ - "redis"
267
+ - "kafka"
268
+
269
+ # ----------------------------------------------------------------------------
270
+ # ASYNC RUNTIME
271
+ # ----------------------------------------------------------------------------
272
+ async:
273
+ runtime: "Tokio"
274
+ patterns:
275
+ asyncAwait: true
276
+ spawnForConcurrency: true
277
+ selectForMultiple: true
278
+ channelsForCommunication: true
279
+
280
+ tokio:
281
+ features:
282
+ - "rt-multi-thread"
283
+ - "macros"
284
+ - "time"
285
+ - "sync"
286
+ macros:
287
+ - "#[tokio::main]"
288
+ - "#[tokio::test]"
289
+
290
+ avoid:
291
+ - "Blocking in async context"
292
+ - "spawn_blocking for CPU-bound"
293
+ - "Unbounded channels in production"
294
+
295
+ # ----------------------------------------------------------------------------
296
+ # HTTP/WEB
297
+ # ----------------------------------------------------------------------------
298
+ httpFramework:
299
+ preferred: "Axum"
300
+ alternatives:
301
+ - "Actix-web"
302
+ - "Warp"
303
+
304
+ axumPatterns:
305
+ extractors: true
306
+ state: true
307
+ middleware: true
308
+ errorHandling: true
309
+ example: |
310
+ async fn create_order(
311
+ State(app_state): State<AppState>,
312
+ Json(request): Json<CreateOrderRequest>,
313
+ ) -> Result<Json<OrderResponse>, AppError> {
314
+ let order = app_state
315
+ .order_service
316
+ .create_order(request.into())
317
+ .await?;
318
+
319
+ Ok(Json(order.into()))
320
+ }
321
+
322
+ middleware:
323
+ - "tower::ServiceBuilder"
324
+ - "TraceLayer"
325
+ - "TimeoutLayer"
326
+ - "CorsLayer"
327
+
328
+ gracefulShutdown:
329
+ enabled: true
330
+ signalHandling: true
331
+
332
+ # ----------------------------------------------------------------------------
333
+ # DATABASE
334
+ # ----------------------------------------------------------------------------
335
+ database:
336
+ driver: "SQLx"
337
+ features:
338
+ - "Compile-time query checking"
339
+ - "Async/await"
340
+ - "Connection pooling"
341
+
342
+ patterns:
343
+ repository: true
344
+ preparedStatements: true
345
+ transactions: true
346
+ example: |
347
+ pub async fn find_by_id(&self, id: OrderId) -> Result<Option<Order>, sqlx::Error> {
348
+ sqlx::query_as!(
349
+ OrderRow,
350
+ r#"SELECT id, customer_id, status as "status: OrderStatus", total
351
+ FROM orders WHERE id = $1"#,
352
+ id.0
353
+ )
354
+ .fetch_optional(&self.pool)
355
+ .await
356
+ .map(|row| row.map(Order::from))
357
+ }
358
+
359
+ migrations:
360
+ tool: "sqlx-cli"
361
+ location: "migrations"
362
+ naming: "{timestamp}_{description}.sql"
363
+
364
+ # ----------------------------------------------------------------------------
365
+ # OBSERVABILITY
366
+ # ----------------------------------------------------------------------------
367
+ observability:
368
+ enabled: true
369
+
370
+ logging:
371
+ framework: "tracing"
372
+ format: "JSON"
373
+ structuredLogging: true
374
+ subscribers:
375
+ - "tracing_subscriber"
376
+ - "tracing_bunyan_formatter"
377
+ spans: true
378
+ example: |
379
+ #[tracing::instrument(skip(pool), fields(order_id = %id))]
380
+ pub async fn get_order(pool: &PgPool, id: OrderId) -> Result<Order> {
381
+ tracing::info!("Fetching order");
382
+ // ...
383
+ }
384
+
385
+ metrics:
386
+ framework: "metrics + metrics-exporter-prometheus"
387
+ types:
388
+ - "counter!"
389
+ - "gauge!"
390
+ - "histogram!"
391
+
392
+ tracing:
393
+ framework: "tracing + opentelemetry"
394
+ propagation: "W3C"
395
+ exporters:
396
+ - "Jaeger"
397
+ - "OTLP"
398
+
399
+ healthChecks:
400
+ endpoints:
401
+ - "/health"
402
+ - "/health/ready"
403
+ - "/health/live"
404
+
405
+ # ----------------------------------------------------------------------------
406
+ # PROJECT STRUCTURE
407
+ # ----------------------------------------------------------------------------
408
+ projectStructure:
409
+ layout: "Workspace with multiple crates"
410
+
411
+ example: |
412
+ myapp/
413
+ ├── Cargo.toml (workspace)
414
+ ├── crates/
415
+ │ ├── domain/
416
+ │ │ ├── Cargo.toml
417
+ │ │ └── src/lib.rs
418
+ │ ├── application/
419
+ │ │ ├── Cargo.toml
420
+ │ │ └── src/lib.rs
421
+ │ ├── infrastructure/
422
+ │ │ ├── Cargo.toml
423
+ │ │ └── src/lib.rs
424
+ │ └── api/
425
+ │ ├── Cargo.toml
426
+ │ └── src/main.rs
427
+ ├── migrations/
428
+ └── tests/
429
+
430
+ cargoFeatures:
431
+ useFeaturesForOptional: true
432
+ defaultFeatures: "minimal"
433
+ example: |
434
+ [features]
435
+ default = []
436
+ postgres = ["sqlx/postgres"]
437
+ mysql = ["sqlx/mysql"]
438
+ full = ["postgres", "mysql"]
439
+
440
+ # ----------------------------------------------------------------------------
441
+ # SERDE & SERIALIZATION
442
+ # ----------------------------------------------------------------------------
443
+ serialization:
444
+ library: "serde"
445
+ formats:
446
+ - "serde_json"
447
+ - "toml"
448
+ - "yaml"
449
+
450
+ patterns:
451
+ deriveForDTOs: true
452
+ customSerializers: true
453
+ renaming: true
454
+ example: |
455
+ #[derive(Debug, Serialize, Deserialize)]
456
+ #[serde(rename_all = "camelCase")]
457
+ pub struct OrderResponse {
458
+ pub id: OrderId,
459
+ pub customer_id: CustomerId,
460
+ #[serde(with = "time::serde::rfc3339")]
461
+ pub created_at: OffsetDateTime,
462
+ pub status: OrderStatus,
463
+ }
464
+
465
+ # ----------------------------------------------------------------------------
466
+ # TECHNOLOGIES
467
+ # ----------------------------------------------------------------------------
468
+ technologies:
469
+ - name: rust
470
+ version: "1.75+"
471
+ edition: "2021"
472
+ specificRules:
473
+ useClippy: true
474
+ useRustfmt: true
475
+ denyUnsafeUnlessDocumented: true
476
+ preferIterators: true
477
+ useResultForErrors: true
478
+
479
+ - name: axum
480
+ version: "0.7+"
481
+ specificRules:
482
+ useExtractors: true
483
+ useState: true
484
+ useTowerMiddleware: true
485
+ useTypedRoutes: true
486
+
487
+ - name: sqlx
488
+ version: "0.7+"
489
+ specificRules:
490
+ useCompileTimeChecking: true
491
+ useQueryAs: true
492
+ useTransactions: true
493
+ usePooling: true
494
+
495
+ - name: tokio
496
+ version: "1.0+"
497
+ specificRules:
498
+ useMultiThread: true
499
+ useMacros: true
500
+ useSpawnForConcurrency: true
501
+ avoidBlockingInAsync: true
502
+
503
+ - name: testing
504
+ specificRules:
505
+ useRstest: true
506
+ usePropertyTesting: true
507
+ useTestcontainers: true
508
+ documentationTests: true