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,437 @@
|
|
|
1
|
+
# Development Conventions
|
|
2
|
+
|
|
3
|
+
General development practices, workflow, and operational standards for Java 21+ projects with Spring Boot and Gradle Kotlin DSL.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Philosophy
|
|
8
|
+
|
|
9
|
+
- **Predictable process**: Consistent project structure and naming reduce friction
|
|
10
|
+
- **Build reproducibility**: Gradle wrapper + dependency locking for deterministic builds
|
|
11
|
+
- **Configuration as records**: Type-safe configuration with `@ConfigurationProperties` and records
|
|
12
|
+
- **Feature packaging**: Organize by feature (domain), not by technical layer
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Gradle Kotlin DSL Project Structure
|
|
17
|
+
|
|
18
|
+
### Single Module
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
my-app/
|
|
22
|
+
build.gradle.kts
|
|
23
|
+
settings.gradle.kts
|
|
24
|
+
gradle/
|
|
25
|
+
wrapper/
|
|
26
|
+
gradle-wrapper.jar
|
|
27
|
+
gradle-wrapper.properties
|
|
28
|
+
libs.versions.toml # Version catalog
|
|
29
|
+
config/
|
|
30
|
+
checkstyle/
|
|
31
|
+
google_checks.xml
|
|
32
|
+
spotbugs/
|
|
33
|
+
exclude.xml
|
|
34
|
+
src/
|
|
35
|
+
main/
|
|
36
|
+
java/com/example/myapp/
|
|
37
|
+
resources/
|
|
38
|
+
application.yml
|
|
39
|
+
application-dev.yml
|
|
40
|
+
application-prod.yml
|
|
41
|
+
db/migration/ # Flyway migrations
|
|
42
|
+
test/
|
|
43
|
+
java/com/example/myapp/
|
|
44
|
+
resources/
|
|
45
|
+
application-test.yml
|
|
46
|
+
gradlew
|
|
47
|
+
gradlew.bat
|
|
48
|
+
.java-version # sdkman or jenv
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Multi-Module
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
my-platform/
|
|
55
|
+
settings.gradle.kts
|
|
56
|
+
build.gradle.kts # root: shared config
|
|
57
|
+
gradle/libs.versions.toml
|
|
58
|
+
app/
|
|
59
|
+
build.gradle.kts # Spring Boot application
|
|
60
|
+
domain/
|
|
61
|
+
build.gradle.kts # Pure Java domain models
|
|
62
|
+
infrastructure/
|
|
63
|
+
build.gradle.kts # JPA, external clients
|
|
64
|
+
common/
|
|
65
|
+
build.gradle.kts # Shared utilities
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```kotlin
|
|
69
|
+
// settings.gradle.kts
|
|
70
|
+
rootProject.name = "my-platform"
|
|
71
|
+
include("app", "domain", "infrastructure", "common")
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
```kotlin
|
|
75
|
+
// app/build.gradle.kts
|
|
76
|
+
dependencies {
|
|
77
|
+
implementation(project(":domain"))
|
|
78
|
+
implementation(project(":infrastructure"))
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Dependency Management
|
|
85
|
+
|
|
86
|
+
### Version Catalog (gradle/libs.versions.toml)
|
|
87
|
+
|
|
88
|
+
```toml
|
|
89
|
+
[versions]
|
|
90
|
+
spring-boot = "3.4.1"
|
|
91
|
+
testcontainers = "1.20.4"
|
|
92
|
+
archunit = "1.3.0"
|
|
93
|
+
assertj = "3.27.0"
|
|
94
|
+
|
|
95
|
+
[libraries]
|
|
96
|
+
spring-boot-starter-web = { module = "org.springframework.boot:spring-boot-starter-web" }
|
|
97
|
+
spring-boot-starter-data-jpa = { module = "org.springframework.boot:spring-boot-starter-data-jpa" }
|
|
98
|
+
spring-boot-starter-validation = { module = "org.springframework.boot:spring-boot-starter-validation" }
|
|
99
|
+
spring-boot-starter-test = { module = "org.springframework.boot:spring-boot-starter-test" }
|
|
100
|
+
testcontainers-postgresql = { module = "org.testcontainers:postgresql", version.ref = "testcontainers" }
|
|
101
|
+
testcontainers-junit = { module = "org.testcontainers:junit-jupiter", version.ref = "testcontainers" }
|
|
102
|
+
archunit = { module = "com.tngtech.archunit:archunit-junit5", version.ref = "archunit" }
|
|
103
|
+
assertj = { module = "org.assertj:assertj-core", version.ref = "assertj" }
|
|
104
|
+
|
|
105
|
+
[plugins]
|
|
106
|
+
spring-boot = { id = "org.springframework.boot", version.ref = "spring-boot" }
|
|
107
|
+
spring-dependency-management = { id = "io.spring.dependency-management", version = "1.1.7" }
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
```kotlin
|
|
111
|
+
// build.gradle.kts
|
|
112
|
+
dependencies {
|
|
113
|
+
implementation(libs.spring.boot.starter.web)
|
|
114
|
+
implementation(libs.spring.boot.starter.data.jpa)
|
|
115
|
+
testImplementation(libs.spring.boot.starter.test)
|
|
116
|
+
testImplementation(libs.testcontainers.postgresql)
|
|
117
|
+
testImplementation(libs.archunit)
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Platform/BOM for Consistency
|
|
122
|
+
|
|
123
|
+
```kotlin
|
|
124
|
+
// build.gradle.kts
|
|
125
|
+
dependencies {
|
|
126
|
+
implementation(platform("org.springframework.boot:spring-boot-dependencies:3.4.1"))
|
|
127
|
+
implementation(platform("org.testcontainers:testcontainers-bom:1.20.4"))
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Package Organization (By Feature)
|
|
134
|
+
|
|
135
|
+
```java
|
|
136
|
+
// GOOD: Organized by feature/domain
|
|
137
|
+
com.example.myapp/
|
|
138
|
+
user/
|
|
139
|
+
UserController.java
|
|
140
|
+
UserService.java
|
|
141
|
+
UserRepository.java
|
|
142
|
+
User.java // entity
|
|
143
|
+
dto/
|
|
144
|
+
CreateUserRequest.java // record
|
|
145
|
+
UserResponse.java // record
|
|
146
|
+
order/
|
|
147
|
+
OrderController.java
|
|
148
|
+
OrderService.java
|
|
149
|
+
OrderRepository.java
|
|
150
|
+
Order.java
|
|
151
|
+
dto/
|
|
152
|
+
CreateOrderRequest.java
|
|
153
|
+
common/
|
|
154
|
+
exception/
|
|
155
|
+
AppException.java
|
|
156
|
+
GlobalExceptionHandler.java
|
|
157
|
+
config/
|
|
158
|
+
SecurityConfig.java
|
|
159
|
+
JacksonConfig.java
|
|
160
|
+
|
|
161
|
+
// BAD: Organized by technical layer
|
|
162
|
+
com.example.myapp/
|
|
163
|
+
controller/
|
|
164
|
+
UserController.java
|
|
165
|
+
OrderController.java
|
|
166
|
+
service/
|
|
167
|
+
UserService.java
|
|
168
|
+
OrderService.java
|
|
169
|
+
repository/
|
|
170
|
+
UserRepository.java
|
|
171
|
+
OrderRepository.java
|
|
172
|
+
model/
|
|
173
|
+
User.java
|
|
174
|
+
Order.java
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**Why feature-based**: Changes to a feature touch files in one package. Layer-based requires changes across the entire tree.
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Spring Profiles
|
|
182
|
+
|
|
183
|
+
### Profile Configuration
|
|
184
|
+
|
|
185
|
+
```yaml
|
|
186
|
+
# application.yml (shared defaults)
|
|
187
|
+
spring:
|
|
188
|
+
application:
|
|
189
|
+
name: my-app
|
|
190
|
+
jpa:
|
|
191
|
+
open-in-view: false
|
|
192
|
+
hibernate:
|
|
193
|
+
ddl-auto: validate
|
|
194
|
+
|
|
195
|
+
# application-dev.yml
|
|
196
|
+
spring:
|
|
197
|
+
jpa:
|
|
198
|
+
show-sql: true
|
|
199
|
+
hibernate:
|
|
200
|
+
ddl-auto: update
|
|
201
|
+
devtools:
|
|
202
|
+
restart:
|
|
203
|
+
enabled: true
|
|
204
|
+
logging:
|
|
205
|
+
level:
|
|
206
|
+
com.example: DEBUG
|
|
207
|
+
org.hibernate.SQL: DEBUG
|
|
208
|
+
|
|
209
|
+
# application-prod.yml
|
|
210
|
+
spring:
|
|
211
|
+
jpa:
|
|
212
|
+
show-sql: false
|
|
213
|
+
server:
|
|
214
|
+
tomcat:
|
|
215
|
+
threads:
|
|
216
|
+
max: 200
|
|
217
|
+
accept-count: 100
|
|
218
|
+
logging:
|
|
219
|
+
level:
|
|
220
|
+
root: WARN
|
|
221
|
+
com.example: INFO
|
|
222
|
+
|
|
223
|
+
# application-test.yml
|
|
224
|
+
spring:
|
|
225
|
+
jpa:
|
|
226
|
+
hibernate:
|
|
227
|
+
ddl-auto: create-drop
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Activating Profiles
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
# Environment variable (preferred in production)
|
|
234
|
+
SPRING_PROFILES_ACTIVE=prod ./gradlew bootRun
|
|
235
|
+
|
|
236
|
+
# Command line
|
|
237
|
+
./gradlew bootRun --args='--spring.profiles.active=dev'
|
|
238
|
+
|
|
239
|
+
# In tests (automatic)
|
|
240
|
+
# application-test.yml is loaded when spring.profiles.active=test
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## @ConfigurationProperties with Records
|
|
246
|
+
|
|
247
|
+
```java
|
|
248
|
+
// GOOD: Type-safe, immutable configuration with records (Spring Boot 3.x)
|
|
249
|
+
@ConfigurationProperties(prefix = "app")
|
|
250
|
+
public record AppProperties(
|
|
251
|
+
String name,
|
|
252
|
+
@DefaultValue("false") boolean debug,
|
|
253
|
+
DatabaseProperties database,
|
|
254
|
+
AuthProperties auth
|
|
255
|
+
) {
|
|
256
|
+
public record DatabaseProperties(
|
|
257
|
+
String url,
|
|
258
|
+
@DefaultValue("20") int poolSize,
|
|
259
|
+
@DefaultValue("10") int maxOverflow
|
|
260
|
+
) {}
|
|
261
|
+
|
|
262
|
+
public record AuthProperties(
|
|
263
|
+
String secretKey,
|
|
264
|
+
@DefaultValue("15") int accessTokenExpireMinutes
|
|
265
|
+
) {}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Enable in main class
|
|
269
|
+
@SpringBootApplication
|
|
270
|
+
@ConfigurationPropertiesScan
|
|
271
|
+
public class Application { ... }
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
```yaml
|
|
275
|
+
# application.yml
|
|
276
|
+
app:
|
|
277
|
+
name: my-app
|
|
278
|
+
debug: false
|
|
279
|
+
database:
|
|
280
|
+
url: jdbc:postgresql://localhost:5432/myapp
|
|
281
|
+
pool-size: 20
|
|
282
|
+
auth:
|
|
283
|
+
secret-key: ${AUTH_SECRET_KEY}
|
|
284
|
+
access-token-expire-minutes: 15
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
```java
|
|
288
|
+
// BAD: @Value scattered across classes
|
|
289
|
+
@Service
|
|
290
|
+
public class UserService {
|
|
291
|
+
@Value("${app.auth.secret-key}") private String secretKey; // no type safety
|
|
292
|
+
@Value("${app.auth.expire:15}") private int expireMinutes; // magic strings
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## Conventional Commits
|
|
299
|
+
|
|
300
|
+
### Format
|
|
301
|
+
|
|
302
|
+
```
|
|
303
|
+
{type}({scope}): {short description}
|
|
304
|
+
|
|
305
|
+
{optional body explaining why, not what}
|
|
306
|
+
|
|
307
|
+
{optional footer: BREAKING CHANGE, Closes #123}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Types
|
|
311
|
+
|
|
312
|
+
| Type | Description |
|
|
313
|
+
|---|---|
|
|
314
|
+
| `feat` | New feature or capability |
|
|
315
|
+
| `fix` | Bug fix |
|
|
316
|
+
| `refactor` | Code change that neither fixes nor adds |
|
|
317
|
+
| `test` | Adding or updating tests |
|
|
318
|
+
| `docs` | Documentation only |
|
|
319
|
+
| `chore` | Maintenance, dependencies, tooling |
|
|
320
|
+
| `ci` | CI/CD configuration changes |
|
|
321
|
+
| `perf` | Performance improvement |
|
|
322
|
+
|
|
323
|
+
### Examples
|
|
324
|
+
|
|
325
|
+
```
|
|
326
|
+
feat(user): add email verification endpoint
|
|
327
|
+
fix(order): prevent duplicate payment processing
|
|
328
|
+
refactor(common): extract retry logic to shared utility
|
|
329
|
+
test(user): add integration tests for registration flow
|
|
330
|
+
chore: upgrade Spring Boot to 3.4.1
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
**Rule**: One logical change per commit. If the commit message needs "and", split it.
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## Documentation with Javadoc
|
|
338
|
+
|
|
339
|
+
### When to Write Javadoc
|
|
340
|
+
|
|
341
|
+
| Element | Javadoc Required? |
|
|
342
|
+
|---|---|
|
|
343
|
+
| Public class | Yes |
|
|
344
|
+
| Public method | Yes |
|
|
345
|
+
| Public record | Yes (fields documented via `@param`) |
|
|
346
|
+
| Package (`package-info.java`) | Yes for feature packages |
|
|
347
|
+
| Private/internal methods | Only if non-obvious |
|
|
348
|
+
| Tests | No (test name is the doc) |
|
|
349
|
+
|
|
350
|
+
### Javadoc Style
|
|
351
|
+
|
|
352
|
+
```java
|
|
353
|
+
/**
|
|
354
|
+
* Service for user account management.
|
|
355
|
+
*
|
|
356
|
+
* <p>Handles registration, authentication, and profile operations.
|
|
357
|
+
* Delegates data access to {@link UserRepository}.
|
|
358
|
+
*/
|
|
359
|
+
@Service
|
|
360
|
+
public class UserService {
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Creates a new user account.
|
|
364
|
+
*
|
|
365
|
+
* <p>Validates email uniqueness and hashes the password before persisting.
|
|
366
|
+
*
|
|
367
|
+
* @param request validated creation request with email, name, and password
|
|
368
|
+
* @return the created user with generated ID and timestamps
|
|
369
|
+
* @throws ConflictException if the email is already registered
|
|
370
|
+
*/
|
|
371
|
+
public User createUser(CreateUserRequest request) { ... }
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Immutable user creation request.
|
|
376
|
+
*
|
|
377
|
+
* @param email user's email address, must be unique
|
|
378
|
+
* @param name display name
|
|
379
|
+
* @param password plain-text password (will be hashed)
|
|
380
|
+
*/
|
|
381
|
+
public record CreateUserRequest(
|
|
382
|
+
@NotBlank String email,
|
|
383
|
+
@NotBlank String name,
|
|
384
|
+
@Size(min = 8) String password
|
|
385
|
+
) {}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## Virtual Threads (Java 21+)
|
|
391
|
+
|
|
392
|
+
### Spring Boot Configuration
|
|
393
|
+
|
|
394
|
+
```yaml
|
|
395
|
+
# application.yml -- enable virtual threads for request handling
|
|
396
|
+
spring:
|
|
397
|
+
threads:
|
|
398
|
+
virtual:
|
|
399
|
+
enabled: true
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
```java
|
|
403
|
+
// GOOD: Blocking code is fine with virtual threads -- no reactive needed
|
|
404
|
+
@Service
|
|
405
|
+
public class UserService {
|
|
406
|
+
|
|
407
|
+
public User getUser(Long id) {
|
|
408
|
+
// This blocks a virtual thread (cheap), not a platform thread
|
|
409
|
+
return userRepository.findById(id)
|
|
410
|
+
.orElseThrow(() -> new NotFoundException("User", id));
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// BAD: Using reactive (WebFlux) when virtual threads suffice
|
|
415
|
+
public Mono<User> getUser(Long id) {
|
|
416
|
+
return userRepository.findById(id)
|
|
417
|
+
.switchIfEmpty(Mono.error(new NotFoundException("User", id)));
|
|
418
|
+
}
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
423
|
+
## Anti-Patterns
|
|
424
|
+
|
|
425
|
+
| Anti-Pattern | Problem | Correct Approach |
|
|
426
|
+
|---|---|---|
|
|
427
|
+
| Layer-based packaging | Feature changes touch every package | Package by feature/domain |
|
|
428
|
+
| `@Value` for config | No validation, scattered, magic strings | `@ConfigurationProperties` records |
|
|
429
|
+
| Groovy build scripts | No type safety, poor IDE support | Gradle Kotlin DSL |
|
|
430
|
+
| No version catalog | Versions scattered across build files | `gradle/libs.versions.toml` |
|
|
431
|
+
| Hardcoded profile values | Cannot change per environment | Spring profiles + env variables |
|
|
432
|
+
| Reactive when not needed | Complexity without benefit | Virtual threads for I/O concurrency |
|
|
433
|
+
| No `package-info.java` | Missing `@NonNullApi`, no package docs | Add to every feature package |
|
|
434
|
+
|
|
435
|
+
---
|
|
436
|
+
|
|
437
|
+
_Conventions reduce cognitive load. Follow them consistently so the team can focus on solving problems, not debating structure._
|