red64-cli 0.5.0 → 0.6.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.
- package/README.md +64 -58
- package/dist/components/screens/StartScreen.d.ts.map +1 -1
- package/dist/components/screens/StartScreen.js +2 -2
- package/dist/components/screens/StartScreen.js.map +1 -1
- package/dist/services/AgentInvoker.js +4 -4
- package/dist/services/AgentInvoker.js.map +1 -1
- package/dist/services/ClaudeHealthCheck.d.ts +5 -0
- package/dist/services/ClaudeHealthCheck.d.ts.map +1 -1
- package/dist/services/ClaudeHealthCheck.js +43 -5
- package/dist/services/ClaudeHealthCheck.js.map +1 -1
- package/dist/services/index.d.ts +1 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +1 -1
- package/dist/services/index.js.map +1 -1
- package/framework/stacks/c/code-quality.md +326 -0
- package/framework/stacks/c/coding-style.md +347 -0
- package/framework/stacks/c/conventions.md +513 -0
- package/framework/stacks/c/error-handling.md +350 -0
- package/framework/stacks/c/feedback.md +158 -0
- package/framework/stacks/c/memory-safety.md +408 -0
- package/framework/stacks/c/tech.md +122 -0
- package/framework/stacks/c/testing.md +472 -0
- package/framework/stacks/cpp/code-quality.md +282 -0
- package/framework/stacks/cpp/coding-style.md +363 -0
- package/framework/stacks/cpp/conventions.md +420 -0
- package/framework/stacks/cpp/error-handling.md +264 -0
- package/framework/stacks/cpp/feedback.md +104 -0
- package/framework/stacks/cpp/memory-safety.md +351 -0
- package/framework/stacks/cpp/tech.md +160 -0
- package/framework/stacks/cpp/testing.md +323 -0
- package/framework/stacks/java/code-quality.md +357 -0
- package/framework/stacks/java/coding-style.md +400 -0
- package/framework/stacks/java/conventions.md +437 -0
- package/framework/stacks/java/error-handling.md +408 -0
- package/framework/stacks/java/feedback.md +180 -0
- package/framework/stacks/java/tech.md +126 -0
- package/framework/stacks/java/testing.md +485 -0
- package/framework/stacks/javascript/async-patterns.md +216 -0
- package/framework/stacks/javascript/code-quality.md +182 -0
- package/framework/stacks/javascript/coding-style.md +293 -0
- package/framework/stacks/javascript/conventions.md +268 -0
- package/framework/stacks/javascript/error-handling.md +216 -0
- package/framework/stacks/javascript/feedback.md +80 -0
- package/framework/stacks/javascript/tech.md +114 -0
- package/framework/stacks/javascript/testing.md +209 -0
- package/framework/stacks/loco/code-quality.md +156 -0
- package/framework/stacks/loco/coding-style.md +247 -0
- package/framework/stacks/loco/error-handling.md +225 -0
- package/framework/stacks/loco/feedback.md +35 -0
- package/framework/stacks/loco/loco.md +342 -0
- package/framework/stacks/loco/structure.md +193 -0
- package/framework/stacks/loco/tech.md +129 -0
- package/framework/stacks/loco/testing.md +211 -0
- package/framework/stacks/rust/code-quality.md +370 -0
- package/framework/stacks/rust/coding-style.md +475 -0
- package/framework/stacks/rust/conventions.md +430 -0
- package/framework/stacks/rust/error-handling.md +399 -0
- package/framework/stacks/rust/feedback.md +152 -0
- package/framework/stacks/rust/memory-safety.md +398 -0
- package/framework/stacks/rust/tech.md +121 -0
- package/framework/stacks/rust/testing.md +528 -0
- package/package.json +14 -2
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
# Development Conventions
|
|
2
|
+
|
|
3
|
+
General development practices, Cargo workspace structure, module organization, and operational standards for Rust projects.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Philosophy
|
|
8
|
+
|
|
9
|
+
- **Predictable process**: Consistent workflows reduce friction and errors
|
|
10
|
+
- **Cargo is the build system**: Do not fight it; organize around workspaces and features
|
|
11
|
+
- **Minimal visibility**: Default to `pub(crate)`, expose only what is needed
|
|
12
|
+
- **Documentation as code**: `///` doc comments generate your API reference
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Cargo Workspace Structure
|
|
17
|
+
|
|
18
|
+
### Recommended Layout
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
my-project/
|
|
22
|
+
Cargo.toml # Workspace root
|
|
23
|
+
Cargo.lock # Committed for applications, not for libraries
|
|
24
|
+
rustfmt.toml # Shared formatting config
|
|
25
|
+
deny.toml # Dependency policy
|
|
26
|
+
.config/
|
|
27
|
+
nextest.toml # Test runner config
|
|
28
|
+
crates/
|
|
29
|
+
app/ # Binary crate (Axum server)
|
|
30
|
+
Cargo.toml
|
|
31
|
+
src/
|
|
32
|
+
main.rs
|
|
33
|
+
lib.rs
|
|
34
|
+
routes/
|
|
35
|
+
middleware/
|
|
36
|
+
core/ # Domain logic (no framework dependencies)
|
|
37
|
+
Cargo.toml
|
|
38
|
+
src/
|
|
39
|
+
lib.rs
|
|
40
|
+
models/
|
|
41
|
+
services/
|
|
42
|
+
errors.rs
|
|
43
|
+
db/ # Database layer
|
|
44
|
+
Cargo.toml
|
|
45
|
+
src/
|
|
46
|
+
lib.rs
|
|
47
|
+
repos/
|
|
48
|
+
migrations/
|
|
49
|
+
tests/ # Workspace-level integration tests
|
|
50
|
+
scripts/ # Development and deployment scripts
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Workspace `Cargo.toml`
|
|
54
|
+
|
|
55
|
+
```toml
|
|
56
|
+
[workspace]
|
|
57
|
+
resolver = "2"
|
|
58
|
+
members = ["crates/*"]
|
|
59
|
+
|
|
60
|
+
[workspace.package]
|
|
61
|
+
edition = "2024"
|
|
62
|
+
rust-version = "1.85"
|
|
63
|
+
authors = ["Team <team@example.com>"]
|
|
64
|
+
license = "MIT"
|
|
65
|
+
|
|
66
|
+
[workspace.dependencies]
|
|
67
|
+
# Pin shared dependencies at workspace level
|
|
68
|
+
axum = "0.8"
|
|
69
|
+
serde = { version = "1", features = ["derive"] }
|
|
70
|
+
serde_json = "1"
|
|
71
|
+
sqlx = { version = "0.8", features = ["runtime-tokio", "tls-rustls", "postgres"] }
|
|
72
|
+
tokio = { version = "1", features = ["full"] }
|
|
73
|
+
tracing = "0.1"
|
|
74
|
+
thiserror = "2"
|
|
75
|
+
anyhow = "1"
|
|
76
|
+
|
|
77
|
+
[workspace.lints.clippy]
|
|
78
|
+
pedantic = { level = "warn", priority = -1 }
|
|
79
|
+
module_name_repetitions = "allow"
|
|
80
|
+
must_use_candidate = "allow"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Crate `Cargo.toml`
|
|
84
|
+
|
|
85
|
+
```toml
|
|
86
|
+
[package]
|
|
87
|
+
name = "my-app"
|
|
88
|
+
version = "0.1.0"
|
|
89
|
+
edition.workspace = true
|
|
90
|
+
rust-version.workspace = true
|
|
91
|
+
|
|
92
|
+
[dependencies]
|
|
93
|
+
axum.workspace = true
|
|
94
|
+
serde.workspace = true
|
|
95
|
+
tokio.workspace = true
|
|
96
|
+
my-core = { path = "../core" }
|
|
97
|
+
my-db = { path = "../db" }
|
|
98
|
+
|
|
99
|
+
[dev-dependencies]
|
|
100
|
+
rstest = "0.23"
|
|
101
|
+
mockall = "0.13"
|
|
102
|
+
cargo-husky = { version = "1", features = ["precommit-hook"] }
|
|
103
|
+
|
|
104
|
+
[lints]
|
|
105
|
+
workspace = true
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Feature Flags
|
|
111
|
+
|
|
112
|
+
### Defining Features
|
|
113
|
+
|
|
114
|
+
```toml
|
|
115
|
+
[features]
|
|
116
|
+
default = ["postgres"]
|
|
117
|
+
postgres = ["sqlx/postgres"]
|
|
118
|
+
mysql = ["sqlx/mysql"]
|
|
119
|
+
sqlite = ["sqlx/sqlite"]
|
|
120
|
+
full = ["postgres", "mysql", "sqlite"]
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Using Features in Code
|
|
124
|
+
|
|
125
|
+
```rust
|
|
126
|
+
// Conditional compilation with features
|
|
127
|
+
#[cfg(feature = "postgres")]
|
|
128
|
+
pub mod postgres_repo;
|
|
129
|
+
|
|
130
|
+
#[cfg(feature = "sqlite")]
|
|
131
|
+
pub mod sqlite_repo;
|
|
132
|
+
|
|
133
|
+
// Feature-gated dependencies
|
|
134
|
+
#[cfg(feature = "tracing")]
|
|
135
|
+
use tracing::instrument;
|
|
136
|
+
|
|
137
|
+
#[cfg_attr(feature = "tracing", instrument(skip(pool)))]
|
|
138
|
+
pub async fn get_user(pool: &PgPool, id: i64) -> Result<User> {
|
|
139
|
+
// ...
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Feature Flag Rules
|
|
144
|
+
|
|
145
|
+
| Rule | Reason |
|
|
146
|
+
|---|---|
|
|
147
|
+
| Features must be additive | Enabling a feature must not break other features |
|
|
148
|
+
| No feature removes functionality | Only adds capabilities |
|
|
149
|
+
| Default features for common use case | Minimal set for typical usage |
|
|
150
|
+
| Document all features in README | Users need to know what is available |
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Module Organization
|
|
155
|
+
|
|
156
|
+
### File-Based vs `mod.rs`
|
|
157
|
+
|
|
158
|
+
```rust
|
|
159
|
+
// PREFERRED (Rust 2024): File-based modules
|
|
160
|
+
// src/models.rs (for simple modules)
|
|
161
|
+
// src/models/user.rs (for modules with submodules, use src/models.rs as the parent)
|
|
162
|
+
|
|
163
|
+
// ACCEPTABLE: mod.rs style
|
|
164
|
+
// src/models/mod.rs (re-exports submodules)
|
|
165
|
+
|
|
166
|
+
// BAD: Mixing both styles in the same project
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Re-export Pattern
|
|
170
|
+
|
|
171
|
+
```rust
|
|
172
|
+
// src/models.rs (or src/models/mod.rs)
|
|
173
|
+
mod user;
|
|
174
|
+
mod post;
|
|
175
|
+
mod comment;
|
|
176
|
+
|
|
177
|
+
// Re-export public types for ergonomic imports
|
|
178
|
+
pub use comment::Comment;
|
|
179
|
+
pub use post::{Post, PostStatus};
|
|
180
|
+
pub use user::{User, NewUser};
|
|
181
|
+
|
|
182
|
+
// Consumers import from the module, not the file:
|
|
183
|
+
// use crate::models::User; // GOOD
|
|
184
|
+
// use crate::models::user::User; // Also fine but less ergonomic
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Visibility Rules
|
|
190
|
+
|
|
191
|
+
### Default to `pub(crate)`
|
|
192
|
+
|
|
193
|
+
```rust
|
|
194
|
+
// GOOD: Minimal visibility
|
|
195
|
+
pub(crate) struct UserService {
|
|
196
|
+
pool: PgPool,
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
pub(crate) async fn create_user(pool: &PgPool, data: &NewUser) -> Result<User> {
|
|
200
|
+
// ...
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Public only for items that are part of the crate's API
|
|
204
|
+
pub struct User {
|
|
205
|
+
pub id: i64,
|
|
206
|
+
pub email: String,
|
|
207
|
+
pub name: String,
|
|
208
|
+
pub(crate) password_hash: String, // Not exposed to consumers
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// BAD: Everything pub
|
|
212
|
+
pub struct UserService {
|
|
213
|
+
pub pool: PgPool, // Leaks implementation detail
|
|
214
|
+
pub cache: HashMap<i64, User>, // Internal state exposed
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Visibility Guidelines
|
|
219
|
+
|
|
220
|
+
| Scope | Use For |
|
|
221
|
+
|---|---|
|
|
222
|
+
| `pub` | Public API items (types, traits, functions consumers need) |
|
|
223
|
+
| `pub(crate)` | Internal shared items (services, utilities, helpers) |
|
|
224
|
+
| `pub(super)` | Items shared with parent module only |
|
|
225
|
+
| Private (default) | Implementation details within a module |
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Documentation
|
|
230
|
+
|
|
231
|
+
### Doc Comments
|
|
232
|
+
|
|
233
|
+
```rust
|
|
234
|
+
//! Crate-level documentation.
|
|
235
|
+
//!
|
|
236
|
+
//! This crate provides user management functionality including
|
|
237
|
+
//! registration, authentication, and profile operations.
|
|
238
|
+
|
|
239
|
+
/// A registered user in the system.
|
|
240
|
+
///
|
|
241
|
+
/// Users are created through [`UserService::create`] and can be
|
|
242
|
+
/// looked up by ID or email address.
|
|
243
|
+
///
|
|
244
|
+
/// # Examples
|
|
245
|
+
///
|
|
246
|
+
/// ```
|
|
247
|
+
/// use my_core::models::User;
|
|
248
|
+
///
|
|
249
|
+
/// let user = User {
|
|
250
|
+
/// id: 1,
|
|
251
|
+
/// email: "alice@example.com".to_string(),
|
|
252
|
+
/// name: "Alice".to_string(),
|
|
253
|
+
/// };
|
|
254
|
+
/// assert_eq!(user.email, "alice@example.com");
|
|
255
|
+
/// ```
|
|
256
|
+
pub struct User {
|
|
257
|
+
/// Unique identifier assigned by the database.
|
|
258
|
+
pub id: i64,
|
|
259
|
+
/// Email address, guaranteed unique across all users.
|
|
260
|
+
pub email: String,
|
|
261
|
+
/// Display name.
|
|
262
|
+
pub name: String,
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/// Create a new user account.
|
|
266
|
+
///
|
|
267
|
+
/// Validates email uniqueness and hashes the password before
|
|
268
|
+
/// persisting to the database.
|
|
269
|
+
///
|
|
270
|
+
/// # Errors
|
|
271
|
+
///
|
|
272
|
+
/// Returns [`AppError::Conflict`] if the email is already registered.
|
|
273
|
+
/// Returns [`AppError::Database`] if the database operation fails.
|
|
274
|
+
pub async fn create_user(pool: &PgPool, data: &NewUser) -> Result<User, AppError> {
|
|
275
|
+
// ...
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### When to Write Doc Comments
|
|
280
|
+
|
|
281
|
+
| Element | Doc Comment Required? |
|
|
282
|
+
|---|---|
|
|
283
|
+
| Public struct/enum | Yes |
|
|
284
|
+
| Public function/method | Yes |
|
|
285
|
+
| Public trait | Yes |
|
|
286
|
+
| Crate root (`lib.rs`) | Yes (`//!`) |
|
|
287
|
+
| `pub(crate)` items | Only if non-obvious |
|
|
288
|
+
| Private items | Only if non-obvious |
|
|
289
|
+
| Test functions | No (name is the doc) |
|
|
290
|
+
|
|
291
|
+
### Building Documentation
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
# Build docs for your crate
|
|
295
|
+
cargo doc --no-deps --open
|
|
296
|
+
|
|
297
|
+
# Build docs for all dependencies too
|
|
298
|
+
cargo doc --open
|
|
299
|
+
|
|
300
|
+
# Check doc links are valid
|
|
301
|
+
cargo doc --no-deps 2>&1 | grep "warning"
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Git Workflow
|
|
307
|
+
|
|
308
|
+
### Branch Strategy
|
|
309
|
+
|
|
310
|
+
```
|
|
311
|
+
main # Production-ready, always deployable
|
|
312
|
+
└── feat/... # Feature branches (short-lived)
|
|
313
|
+
└── fix/... # Bug fix branches
|
|
314
|
+
└── chore/... # Maintenance, dependency updates
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Conventional Commits
|
|
318
|
+
|
|
319
|
+
```
|
|
320
|
+
feat: add user registration endpoint
|
|
321
|
+
fix: prevent duplicate email registration
|
|
322
|
+
refactor: extract password hashing to utility module
|
|
323
|
+
test: add integration tests for payment flow
|
|
324
|
+
docs: update API authentication guide
|
|
325
|
+
chore: upgrade axum to 0.8
|
|
326
|
+
ci: add cargo deny check to pipeline
|
|
327
|
+
perf: optimize user query with index hint
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Commit Types
|
|
331
|
+
|
|
332
|
+
| Type | Description |
|
|
333
|
+
|---|---|
|
|
334
|
+
| `feat` | New feature or capability |
|
|
335
|
+
| `fix` | Bug fix |
|
|
336
|
+
| `refactor` | Code change that neither fixes nor adds |
|
|
337
|
+
| `test` | Adding or updating tests |
|
|
338
|
+
| `docs` | Documentation only |
|
|
339
|
+
| `chore` | Maintenance, dependencies, tooling |
|
|
340
|
+
| `ci` | CI/CD configuration changes |
|
|
341
|
+
| `perf` | Performance improvement |
|
|
342
|
+
|
|
343
|
+
**Rule**: One logical change per commit. If the commit message needs "and", split it.
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## Environment Configuration
|
|
348
|
+
|
|
349
|
+
### Using `dotenvy` and Typed Config
|
|
350
|
+
|
|
351
|
+
```rust
|
|
352
|
+
use serde::Deserialize;
|
|
353
|
+
|
|
354
|
+
#[derive(Debug, Deserialize)]
|
|
355
|
+
pub struct Config {
|
|
356
|
+
#[serde(default = "default_port")]
|
|
357
|
+
pub port: u16,
|
|
358
|
+
pub database_url: String,
|
|
359
|
+
pub redis_url: String,
|
|
360
|
+
#[serde(default)]
|
|
361
|
+
pub debug: bool,
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
fn default_port() -> u16 {
|
|
365
|
+
8080
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
impl Config {
|
|
369
|
+
pub fn from_env() -> Result<Self, envy::Error> {
|
|
370
|
+
dotenvy::dotenv().ok(); // Load .env if present
|
|
371
|
+
envy::from_env()
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### `.env` Files
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
# .env (local development -- NEVER commit)
|
|
380
|
+
DATABASE_URL=postgres://user:pass@localhost:5432/myapp
|
|
381
|
+
REDIS_URL=redis://localhost:6379
|
|
382
|
+
DEBUG=true
|
|
383
|
+
|
|
384
|
+
# .env.example (committed, documents required vars)
|
|
385
|
+
DATABASE_URL=postgres://user:pass@localhost:5432/myapp
|
|
386
|
+
REDIS_URL=redis://localhost:6379
|
|
387
|
+
DEBUG=false
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
## Dependency Management
|
|
393
|
+
|
|
394
|
+
### Rules
|
|
395
|
+
|
|
396
|
+
- Use workspace dependencies for shared crates
|
|
397
|
+
- Pin major versions in `Cargo.toml`
|
|
398
|
+
- Commit `Cargo.lock` for applications (not libraries)
|
|
399
|
+
- Run `cargo update` regularly (weekly or per sprint)
|
|
400
|
+
- Audit with `cargo audit` and `cargo deny` in CI
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
# Update all dependencies
|
|
404
|
+
cargo update
|
|
405
|
+
|
|
406
|
+
# Update specific dependency
|
|
407
|
+
cargo update -p axum
|
|
408
|
+
|
|
409
|
+
# Check for outdated dependencies
|
|
410
|
+
cargo install cargo-outdated
|
|
411
|
+
cargo outdated
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## Anti-Patterns
|
|
417
|
+
|
|
418
|
+
| Anti-Pattern | Problem | Correct Approach |
|
|
419
|
+
|---|---|---|
|
|
420
|
+
| Giant `lib.rs` with all code | Unnavigable | Split into modules by domain |
|
|
421
|
+
| `pub` on everything | Leaks internals | Default to `pub(crate)` |
|
|
422
|
+
| No workspace for multi-crate | Duplicated dependency versions | Use workspace dependencies |
|
|
423
|
+
| Missing `Cargo.lock` in apps | Non-reproducible builds | Commit lock file for binaries |
|
|
424
|
+
| Wildcard versions (`*`) | Breaking updates | Pin at least major version |
|
|
425
|
+
| No doc comments on public API | Undiscoverable API | Document all public items |
|
|
426
|
+
| Feature flags that remove functionality | Breaks consumers | Features must be additive |
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
_Conventions reduce cognitive load. Follow them consistently so the team can focus on solving problems, not debating structure._
|