oh-my-customcode 0.10.0 → 0.10.2
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/dist/cli/index.js +370 -19
- package/dist/index.js +387 -19
- package/package.json +1 -1
- package/templates/.claude/agents/mgr-gitnerd.md +1 -1
- package/templates/.claude/agents/mgr-sauron.md +3 -3
- package/templates/.claude/rules/MUST-continuous-improvement.md +1 -1
- package/templates/.claude/rules/MUST-intent-transparency.md +1 -1
- package/templates/.claude/rules/MUST-orchestrator-coordination.md +1 -1
- package/templates/.claude/rules/MUST-sync-verification.md +1 -1
- package/templates/.claude/rules/SHOULD-agent-teams.md +1 -1
- package/templates/.claude/rules/index.yaml +4 -4
- package/templates/.claude/skills/de-lead-routing/SKILL.md +13 -0
- package/templates/.claude/skills/dev-lead-routing/SKILL.md +14 -0
- package/templates/.claude/skills/qa-lead-routing/SKILL.md +13 -0
- package/templates/.claude/skills/sauron-watch/SKILL.md +4 -4
- package/templates/.claude/skills/secretary-routing/SKILL.md +14 -1
- package/templates/.claude/skills/springboot-best-practices/SKILL.md +7 -152
- package/templates/.claude/skills/springboot-best-practices/examples/config-properties-example.java +22 -0
- package/templates/.claude/skills/springboot-best-practices/examples/controller-example.java +28 -0
- package/templates/.claude/skills/springboot-best-practices/examples/controller-test-example.java +33 -0
- package/templates/.claude/skills/springboot-best-practices/examples/entity-example.java +22 -0
- package/templates/.claude/skills/springboot-best-practices/examples/exception-handler-example.java +30 -0
- package/templates/.claude/skills/springboot-best-practices/examples/repository-example.java +17 -0
- package/templates/.claude/skills/springboot-best-practices/examples/repository-test-example.java +23 -0
- package/templates/.claude/skills/springboot-best-practices/examples/security-config-example.java +27 -0
- package/templates/.claude/skills/springboot-best-practices/examples/service-example.java +33 -0
- package/templates/.codex/agents/mgr-gitnerd.md +1 -1
- package/templates/.codex/agents/mgr-sauron.md +3 -3
- package/templates/.codex/rules/MUST-continuous-improvement.md +1 -1
- package/templates/.codex/rules/MUST-intent-transparency.md +1 -1
- package/templates/.codex/rules/MUST-orchestrator-coordination.md +1 -1
- package/templates/.codex/rules/MUST-sync-verification.md +1 -1
- package/templates/.codex/rules/SHOULD-agent-teams.md +1 -1
- package/templates/.codex/rules/index.yaml +4 -4
- package/templates/.codex/skills/de-lead-routing/SKILL.md +13 -0
- package/templates/.codex/skills/dev-lead-routing/SKILL.md +14 -0
- package/templates/.codex/skills/qa-lead-routing/SKILL.md +13 -0
- package/templates/.codex/skills/sauron-watch/SKILL.md +4 -4
- package/templates/.codex/skills/secretary-routing/SKILL.md +14 -1
- package/templates/CLAUDE.md.en +8 -29
- package/templates/CLAUDE.md.ko +8 -29
- package/templates/guides/index.yaml +74 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sauron-watch
|
|
3
|
-
description: Full
|
|
3
|
+
description: Full R016 verification (5+3 rounds) before commit
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Sauron Watch Skill
|
|
8
8
|
|
|
9
|
-
Execute full
|
|
9
|
+
Execute full R016 verification process with 5 rounds of manager agent verification and 3 rounds of deep review.
|
|
10
10
|
|
|
11
11
|
## Purpose
|
|
12
12
|
|
|
@@ -84,7 +84,7 @@ Ensure complete synchronization of agents, commands, documentation, and project
|
|
|
84
84
|
```
|
|
85
85
|
[mgr-sauron:watch]
|
|
86
86
|
|
|
87
|
-
Starting full
|
|
87
|
+
Starting full R016 verification...
|
|
88
88
|
|
|
89
89
|
═══════════════════════════════════════════════════════════
|
|
90
90
|
PHASE 1: Manager Agent Verification (5 rounds)
|
|
@@ -140,5 +140,5 @@ Ready to commit. 커밋할까요?
|
|
|
140
140
|
|
|
141
141
|
## Related
|
|
142
142
|
|
|
143
|
-
-
|
|
143
|
+
- R016: Sync Verification Rules
|
|
144
144
|
- mgr-gitnerd: Git operations agent
|
|
@@ -19,7 +19,7 @@ Routes agent management tasks to the appropriate manager agent. This skill conta
|
|
|
19
19
|
| mgr-supplier | Validate dependencies | "audit", "check deps" |
|
|
20
20
|
| mgr-gitnerd | Git operations | "commit", "push", "pr" |
|
|
21
21
|
| mgr-sync-checker | Sync verification | "sync check", "verify sync" |
|
|
22
|
-
| mgr-sauron |
|
|
22
|
+
| mgr-sauron | R016 auto-verification | "verify", "full check" |
|
|
23
23
|
| mgr-claude-code-bible | Claude Code spec compliance | "spec check", "verify compliance" |
|
|
24
24
|
| sys-memory-keeper | Memory operations | "save memory", "recall", "memory search" |
|
|
25
25
|
| sys-naggy | TODO management | "todo", "track tasks", "task list" |
|
|
@@ -79,6 +79,19 @@ When command requires multiple independent operations:
|
|
|
79
79
|
| sys-memory-keeper | sonnet | Memory operations, search |
|
|
80
80
|
| sys-naggy | haiku | Simple TODO tracking |
|
|
81
81
|
|
|
82
|
+
## Agent Teams Awareness
|
|
83
|
+
|
|
84
|
+
Before routing via Task tool, check if Agent Teams is available (`CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` or TeamCreate/SendMessage tools present).
|
|
85
|
+
|
|
86
|
+
**Self-check:** Does this task need 3+ agents, shared state, or inter-agent communication? If yes, prefer Agent Teams over Task tool. See R018 for the full decision matrix.
|
|
87
|
+
|
|
88
|
+
| Scenario | Preferred |
|
|
89
|
+
|----------|-----------|
|
|
90
|
+
| Single manager task | Task Tool |
|
|
91
|
+
| Batch agent creation (3+) | Agent Teams |
|
|
92
|
+
| Multi-round verification (sauron) | Task Tool |
|
|
93
|
+
| Agent audit + fix cycle | Agent Teams |
|
|
94
|
+
|
|
82
95
|
## Usage
|
|
83
96
|
|
|
84
97
|
This skill is NOT user-invocable. It is automatically triggered when the main conversation detects agent management intent.
|
|
@@ -25,104 +25,22 @@ public class UserService {
|
|
|
25
25
|
### 3. REST API Design
|
|
26
26
|
@RestController + @RequestMapping. Use @Validated for input, ResponseEntity for responses, proper HTTP status codes.
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
@RestController
|
|
30
|
-
@RequestMapping("/api/v1/users")
|
|
31
|
-
@RequiredArgsConstructor
|
|
32
|
-
public class UserController {
|
|
33
|
-
private final UserService userService;
|
|
34
|
-
|
|
35
|
-
@GetMapping("/{id}")
|
|
36
|
-
public ResponseEntity<UserResponse> getUser(@PathVariable Long id) {
|
|
37
|
-
return ResponseEntity.ok(userService.findById(id));
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
@PostMapping
|
|
41
|
-
@ResponseStatus(HttpStatus.CREATED)
|
|
42
|
-
public UserResponse createUser(@Valid @RequestBody UserRequest request) {
|
|
43
|
-
return userService.create(request);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
```
|
|
28
|
+
See `examples/controller-example.java` for reference implementation.
|
|
47
29
|
|
|
48
30
|
### 4. Service Layer
|
|
49
31
|
Business logic in services. @Transactional boundaries at service level. Interface + implementation pattern.
|
|
50
32
|
|
|
51
|
-
|
|
52
|
-
@Service
|
|
53
|
-
@Transactional(readOnly = true)
|
|
54
|
-
@RequiredArgsConstructor
|
|
55
|
-
public class UserServiceImpl implements UserService {
|
|
56
|
-
private final UserRepository userRepository;
|
|
57
|
-
|
|
58
|
-
@Override
|
|
59
|
-
public UserResponse findById(Long id) {
|
|
60
|
-
User user = userRepository.findById(id)
|
|
61
|
-
.orElseThrow(() -> new UserNotFoundException(id));
|
|
62
|
-
return userMapper.toResponse(user);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
@Override
|
|
66
|
-
@Transactional
|
|
67
|
-
public UserResponse create(UserRequest request) {
|
|
68
|
-
User user = userMapper.toEntity(request);
|
|
69
|
-
return userMapper.toResponse(userRepository.save(user));
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
```
|
|
33
|
+
See `examples/service-example.java` for reference implementation.
|
|
73
34
|
|
|
74
35
|
### 5. Data Access
|
|
75
36
|
Spring Data JPA. @Query or method naming for custom queries. @Entity with proper JPA annotations.
|
|
76
37
|
|
|
77
|
-
|
|
78
|
-
public interface UserRepository extends JpaRepository<User, Long> {
|
|
79
|
-
Optional<User> findByEmail(String email);
|
|
80
|
-
|
|
81
|
-
@Query("SELECT u FROM User u WHERE u.status = :status")
|
|
82
|
-
List<User> findByStatus(@Param("status") UserStatus status);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
@Entity
|
|
86
|
-
@Table(name = "users")
|
|
87
|
-
@Getter
|
|
88
|
-
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
|
89
|
-
public class User {
|
|
90
|
-
@Id
|
|
91
|
-
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
92
|
-
private Long id;
|
|
93
|
-
|
|
94
|
-
@Column(nullable = false, unique = true)
|
|
95
|
-
private String email;
|
|
96
|
-
|
|
97
|
-
@Enumerated(EnumType.STRING)
|
|
98
|
-
private UserStatus status;
|
|
99
|
-
}
|
|
100
|
-
```
|
|
38
|
+
See `examples/repository-example.java` and `examples/entity-example.java` for reference implementations.
|
|
101
39
|
|
|
102
40
|
### 6. Exception Handling
|
|
103
41
|
@RestControllerAdvice for global handling. Domain-specific exceptions with proper HTTP status mapping.
|
|
104
42
|
|
|
105
|
-
|
|
106
|
-
@RestControllerAdvice
|
|
107
|
-
public class GlobalExceptionHandler {
|
|
108
|
-
@ExceptionHandler(UserNotFoundException.class)
|
|
109
|
-
@ResponseStatus(HttpStatus.NOT_FOUND)
|
|
110
|
-
public ErrorResponse handleUserNotFound(UserNotFoundException ex) {
|
|
111
|
-
return new ErrorResponse("USER_NOT_FOUND", ex.getMessage());
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
@ExceptionHandler(MethodArgumentNotValidException.class)
|
|
115
|
-
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
|
116
|
-
public ErrorResponse handleValidation(MethodArgumentNotValidException ex) {
|
|
117
|
-
List<String> errors = ex.getBindingResult()
|
|
118
|
-
.getFieldErrors()
|
|
119
|
-
.stream()
|
|
120
|
-
.map(e -> e.getField() + ": " + e.getDefaultMessage())
|
|
121
|
-
.toList();
|
|
122
|
-
return new ErrorResponse("VALIDATION_ERROR", errors);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
```
|
|
43
|
+
See `examples/exception-handler-example.java` for reference implementation.
|
|
126
44
|
|
|
127
45
|
### 7. Configuration
|
|
128
46
|
Profile-based: application-{profile}.yml. @ConfigurationProperties for type-safe config. Externalize sensitive values.
|
|
@@ -138,80 +56,17 @@ spring:
|
|
|
138
56
|
password: ${DATABASE_PASSWORD}
|
|
139
57
|
```
|
|
140
58
|
|
|
141
|
-
|
|
142
|
-
@Configuration
|
|
143
|
-
@ConfigurationProperties(prefix = "app")
|
|
144
|
-
@Validated
|
|
145
|
-
public class AppProperties {
|
|
146
|
-
@NotBlank
|
|
147
|
-
private String name;
|
|
148
|
-
|
|
149
|
-
@Min(1)
|
|
150
|
-
private int maxConnections;
|
|
151
|
-
}
|
|
152
|
-
```
|
|
59
|
+
See `examples/config-properties-example.java` for type-safe configuration properties.
|
|
153
60
|
|
|
154
61
|
### 8. Security
|
|
155
62
|
Spring Security with SecurityFilterChain. Externalize secrets. Proper authentication/authorization patterns.
|
|
156
63
|
|
|
157
|
-
|
|
158
|
-
@Configuration
|
|
159
|
-
@EnableWebSecurity
|
|
160
|
-
@RequiredArgsConstructor
|
|
161
|
-
public class SecurityConfig {
|
|
162
|
-
@Bean
|
|
163
|
-
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
|
164
|
-
return http
|
|
165
|
-
.csrf(csrf -> csrf.disable())
|
|
166
|
-
.sessionManagement(session ->
|
|
167
|
-
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
|
168
|
-
.authorizeHttpRequests(auth -> auth
|
|
169
|
-
.requestMatchers("/api/v1/auth/**").permitAll()
|
|
170
|
-
.requestMatchers("/api/v1/admin/**").hasRole("ADMIN")
|
|
171
|
-
.anyRequest().authenticated())
|
|
172
|
-
.build();
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
```
|
|
64
|
+
See `examples/security-config-example.java` for reference implementation.
|
|
176
65
|
|
|
177
66
|
### 9. Testing
|
|
178
67
|
@WebMvcTest (controller), @DataJpaTest (repository), @SpringBootTest (integration), @MockBean for mocking.
|
|
179
68
|
|
|
180
|
-
|
|
181
|
-
// Controller test
|
|
182
|
-
@WebMvcTest(UserController.class)
|
|
183
|
-
class UserControllerTest {
|
|
184
|
-
@Autowired
|
|
185
|
-
private MockMvc mockMvc;
|
|
186
|
-
|
|
187
|
-
@MockBean
|
|
188
|
-
private UserService userService;
|
|
189
|
-
|
|
190
|
-
@Test
|
|
191
|
-
void getUser_shouldReturnUser() throws Exception {
|
|
192
|
-
given(userService.findById(1L))
|
|
193
|
-
.willReturn(new UserResponse(1L, "test@example.com"));
|
|
194
|
-
|
|
195
|
-
mockMvc.perform(get("/api/v1/users/1"))
|
|
196
|
-
.andExpect(status().isOk())
|
|
197
|
-
.andExpect(jsonPath("$.email").value("test@example.com"));
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// Repository test
|
|
202
|
-
@DataJpaTest
|
|
203
|
-
class UserRepositoryTest {
|
|
204
|
-
@Autowired
|
|
205
|
-
private UserRepository userRepository;
|
|
206
|
-
|
|
207
|
-
@Test
|
|
208
|
-
void findByEmail_shouldReturnUser() {
|
|
209
|
-
User user = userRepository.save(new User("test@example.com"));
|
|
210
|
-
Optional<User> found = userRepository.findByEmail("test@example.com");
|
|
211
|
-
assertThat(found).isPresent();
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
```
|
|
69
|
+
See `examples/controller-test-example.java` and `examples/repository-test-example.java` for reference implementations.
|
|
215
70
|
|
|
216
71
|
## Application
|
|
217
72
|
|
package/templates/.claude/skills/springboot-best-practices/examples/config-properties-example.java
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
package com.example.demo.config;
|
|
2
|
+
|
|
3
|
+
import jakarta.validation.constraints.Min;
|
|
4
|
+
import jakarta.validation.constraints.NotBlank;
|
|
5
|
+
import lombok.Getter;
|
|
6
|
+
import lombok.Setter;
|
|
7
|
+
import org.springframework.boot.context.properties.ConfigurationProperties;
|
|
8
|
+
import org.springframework.context.annotation.Configuration;
|
|
9
|
+
import org.springframework.validation.annotation.Validated;
|
|
10
|
+
|
|
11
|
+
@Configuration
|
|
12
|
+
@ConfigurationProperties(prefix = "app")
|
|
13
|
+
@Validated
|
|
14
|
+
@Getter
|
|
15
|
+
@Setter
|
|
16
|
+
public class AppProperties {
|
|
17
|
+
@NotBlank
|
|
18
|
+
private String name;
|
|
19
|
+
|
|
20
|
+
@Min(1)
|
|
21
|
+
private int maxConnections;
|
|
22
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
package com.example.demo.controller;
|
|
2
|
+
|
|
3
|
+
import com.example.demo.dto.UserRequest;
|
|
4
|
+
import com.example.demo.dto.UserResponse;
|
|
5
|
+
import com.example.demo.service.UserService;
|
|
6
|
+
import jakarta.validation.Valid;
|
|
7
|
+
import lombok.RequiredArgsConstructor;
|
|
8
|
+
import org.springframework.http.HttpStatus;
|
|
9
|
+
import org.springframework.http.ResponseEntity;
|
|
10
|
+
import org.springframework.web.bind.annotation.*;
|
|
11
|
+
|
|
12
|
+
@RestController
|
|
13
|
+
@RequestMapping("/api/v1/users")
|
|
14
|
+
@RequiredArgsConstructor
|
|
15
|
+
public class UserController {
|
|
16
|
+
private final UserService userService;
|
|
17
|
+
|
|
18
|
+
@GetMapping("/{id}")
|
|
19
|
+
public ResponseEntity<UserResponse> getUser(@PathVariable Long id) {
|
|
20
|
+
return ResponseEntity.ok(userService.findById(id));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@PostMapping
|
|
24
|
+
@ResponseStatus(HttpStatus.CREATED)
|
|
25
|
+
public UserResponse createUser(@Valid @RequestBody UserRequest request) {
|
|
26
|
+
return userService.create(request);
|
|
27
|
+
}
|
|
28
|
+
}
|
package/templates/.claude/skills/springboot-best-practices/examples/controller-test-example.java
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
package com.example.demo.controller;
|
|
2
|
+
|
|
3
|
+
import com.example.demo.dto.UserResponse;
|
|
4
|
+
import com.example.demo.service.UserService;
|
|
5
|
+
import org.junit.jupiter.api.Test;
|
|
6
|
+
import org.springframework.beans.factory.annotation.Autowired;
|
|
7
|
+
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
|
8
|
+
import org.springframework.boot.test.mock.mockito.MockBean;
|
|
9
|
+
import org.springframework.test.web.servlet.MockMvc;
|
|
10
|
+
|
|
11
|
+
import static org.mockito.BDDMockito.given;
|
|
12
|
+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
|
13
|
+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
|
14
|
+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
|
15
|
+
|
|
16
|
+
@WebMvcTest(UserController.class)
|
|
17
|
+
class UserControllerTest {
|
|
18
|
+
@Autowired
|
|
19
|
+
private MockMvc mockMvc;
|
|
20
|
+
|
|
21
|
+
@MockBean
|
|
22
|
+
private UserService userService;
|
|
23
|
+
|
|
24
|
+
@Test
|
|
25
|
+
void getUser_shouldReturnUser() throws Exception {
|
|
26
|
+
given(userService.findById(1L))
|
|
27
|
+
.willReturn(new UserResponse(1L, "test@example.com"));
|
|
28
|
+
|
|
29
|
+
mockMvc.perform(get("/api/v1/users/1"))
|
|
30
|
+
.andExpect(status().isOk())
|
|
31
|
+
.andExpect(jsonPath("$.email").value("test@example.com"));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
package com.example.demo.entity;
|
|
2
|
+
|
|
3
|
+
import jakarta.persistence.*;
|
|
4
|
+
import lombok.AccessLevel;
|
|
5
|
+
import lombok.Getter;
|
|
6
|
+
import lombok.NoArgsConstructor;
|
|
7
|
+
|
|
8
|
+
@Entity
|
|
9
|
+
@Table(name = "users")
|
|
10
|
+
@Getter
|
|
11
|
+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
|
12
|
+
public class User {
|
|
13
|
+
@Id
|
|
14
|
+
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
15
|
+
private Long id;
|
|
16
|
+
|
|
17
|
+
@Column(nullable = false, unique = true)
|
|
18
|
+
private String email;
|
|
19
|
+
|
|
20
|
+
@Enumerated(EnumType.STRING)
|
|
21
|
+
private UserStatus status;
|
|
22
|
+
}
|
package/templates/.claude/skills/springboot-best-practices/examples/exception-handler-example.java
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
package com.example.demo.exception;
|
|
2
|
+
|
|
3
|
+
import com.example.demo.dto.ErrorResponse;
|
|
4
|
+
import org.springframework.http.HttpStatus;
|
|
5
|
+
import org.springframework.web.bind.MethodArgumentNotValidException;
|
|
6
|
+
import org.springframework.web.bind.annotation.ExceptionHandler;
|
|
7
|
+
import org.springframework.web.bind.annotation.ResponseStatus;
|
|
8
|
+
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
|
9
|
+
|
|
10
|
+
import java.util.List;
|
|
11
|
+
|
|
12
|
+
@RestControllerAdvice
|
|
13
|
+
public class GlobalExceptionHandler {
|
|
14
|
+
@ExceptionHandler(UserNotFoundException.class)
|
|
15
|
+
@ResponseStatus(HttpStatus.NOT_FOUND)
|
|
16
|
+
public ErrorResponse handleUserNotFound(UserNotFoundException ex) {
|
|
17
|
+
return new ErrorResponse("USER_NOT_FOUND", ex.getMessage());
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@ExceptionHandler(MethodArgumentNotValidException.class)
|
|
21
|
+
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
|
22
|
+
public ErrorResponse handleValidation(MethodArgumentNotValidException ex) {
|
|
23
|
+
List<String> errors = ex.getBindingResult()
|
|
24
|
+
.getFieldErrors()
|
|
25
|
+
.stream()
|
|
26
|
+
.map(e -> e.getField() + ": " + e.getDefaultMessage())
|
|
27
|
+
.toList();
|
|
28
|
+
return new ErrorResponse("VALIDATION_ERROR", errors);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
package com.example.demo.repository;
|
|
2
|
+
|
|
3
|
+
import com.example.demo.entity.User;
|
|
4
|
+
import com.example.demo.entity.UserStatus;
|
|
5
|
+
import org.springframework.data.jpa.repository.JpaRepository;
|
|
6
|
+
import org.springframework.data.jpa.repository.Query;
|
|
7
|
+
import org.springframework.data.repository.query.Param;
|
|
8
|
+
|
|
9
|
+
import java.util.List;
|
|
10
|
+
import java.util.Optional;
|
|
11
|
+
|
|
12
|
+
public interface UserRepository extends JpaRepository<User, Long> {
|
|
13
|
+
Optional<User> findByEmail(String email);
|
|
14
|
+
|
|
15
|
+
@Query("SELECT u FROM User u WHERE u.status = :status")
|
|
16
|
+
List<User> findByStatus(@Param("status") UserStatus status);
|
|
17
|
+
}
|
package/templates/.claude/skills/springboot-best-practices/examples/repository-test-example.java
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
package com.example.demo.repository;
|
|
2
|
+
|
|
3
|
+
import com.example.demo.entity.User;
|
|
4
|
+
import org.junit.jupiter.api.Test;
|
|
5
|
+
import org.springframework.beans.factory.annotation.Autowired;
|
|
6
|
+
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
|
7
|
+
|
|
8
|
+
import java.util.Optional;
|
|
9
|
+
|
|
10
|
+
import static org.assertj.core.api.Assertions.assertThat;
|
|
11
|
+
|
|
12
|
+
@DataJpaTest
|
|
13
|
+
class UserRepositoryTest {
|
|
14
|
+
@Autowired
|
|
15
|
+
private UserRepository userRepository;
|
|
16
|
+
|
|
17
|
+
@Test
|
|
18
|
+
void findByEmail_shouldReturnUser() {
|
|
19
|
+
User user = userRepository.save(new User("test@example.com"));
|
|
20
|
+
Optional<User> found = userRepository.findByEmail("test@example.com");
|
|
21
|
+
assertThat(found).isPresent();
|
|
22
|
+
}
|
|
23
|
+
}
|
package/templates/.claude/skills/springboot-best-practices/examples/security-config-example.java
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
package com.example.demo.config;
|
|
2
|
+
|
|
3
|
+
import lombok.RequiredArgsConstructor;
|
|
4
|
+
import org.springframework.context.annotation.Bean;
|
|
5
|
+
import org.springframework.context.annotation.Configuration;
|
|
6
|
+
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
|
7
|
+
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
|
8
|
+
import org.springframework.security.config.http.SessionCreationPolicy;
|
|
9
|
+
import org.springframework.security.web.SecurityFilterChain;
|
|
10
|
+
|
|
11
|
+
@Configuration
|
|
12
|
+
@EnableWebSecurity
|
|
13
|
+
@RequiredArgsConstructor
|
|
14
|
+
public class SecurityConfig {
|
|
15
|
+
@Bean
|
|
16
|
+
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
|
17
|
+
return http
|
|
18
|
+
.csrf(csrf -> csrf.disable())
|
|
19
|
+
.sessionManagement(session ->
|
|
20
|
+
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
|
21
|
+
.authorizeHttpRequests(auth -> auth
|
|
22
|
+
.requestMatchers("/api/v1/auth/**").permitAll()
|
|
23
|
+
.requestMatchers("/api/v1/admin/**").hasRole("ADMIN")
|
|
24
|
+
.anyRequest().authenticated())
|
|
25
|
+
.build();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
package com.example.demo.service;
|
|
2
|
+
|
|
3
|
+
import com.example.demo.dto.UserRequest;
|
|
4
|
+
import com.example.demo.dto.UserResponse;
|
|
5
|
+
import com.example.demo.entity.User;
|
|
6
|
+
import com.example.demo.exception.UserNotFoundException;
|
|
7
|
+
import com.example.demo.mapper.UserMapper;
|
|
8
|
+
import com.example.demo.repository.UserRepository;
|
|
9
|
+
import lombok.RequiredArgsConstructor;
|
|
10
|
+
import org.springframework.stereotype.Service;
|
|
11
|
+
import org.springframework.transaction.annotation.Transactional;
|
|
12
|
+
|
|
13
|
+
@Service
|
|
14
|
+
@Transactional(readOnly = true)
|
|
15
|
+
@RequiredArgsConstructor
|
|
16
|
+
public class UserServiceImpl implements UserService {
|
|
17
|
+
private final UserRepository userRepository;
|
|
18
|
+
private final UserMapper userMapper;
|
|
19
|
+
|
|
20
|
+
@Override
|
|
21
|
+
public UserResponse findById(Long id) {
|
|
22
|
+
User user = userRepository.findById(id)
|
|
23
|
+
.orElseThrow(() -> new UserNotFoundException(id));
|
|
24
|
+
return userMapper.toResponse(user);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@Override
|
|
28
|
+
@Transactional
|
|
29
|
+
public UserResponse create(UserRequest request) {
|
|
30
|
+
User user = userMapper.toEntity(request);
|
|
31
|
+
return userMapper.toResponse(userRepository.save(user));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -40,6 +40,6 @@ Types: feat, fix, docs, style, refactor, test, chore
|
|
|
40
40
|
- NEVER skip pre-commit hooks without reason
|
|
41
41
|
- ALWAYS create new commits (avoid --amend unless requested)
|
|
42
42
|
|
|
43
|
-
## Push Rules (
|
|
43
|
+
## Push Rules (R016)
|
|
44
44
|
|
|
45
45
|
All pushes require prior mgr-sauron:watch verification. If sauron was not run, REFUSE the push.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mgr-sauron
|
|
3
|
-
description: Use when you need automated verification of
|
|
3
|
+
description: Use when you need automated verification of R016 compliance, executing mandatory multi-round verification (5 manager rounds + 3 deep review rounds) before commits
|
|
4
4
|
model: sonnet
|
|
5
5
|
memory: project
|
|
6
6
|
effort: high
|
|
@@ -15,7 +15,7 @@ tools:
|
|
|
15
15
|
- Bash
|
|
16
16
|
---
|
|
17
17
|
|
|
18
|
-
You are an automated verification specialist that executes the mandatory
|
|
18
|
+
You are an automated verification specialist that executes the mandatory R016 verification process, acting as the "all-seeing eye" that ensures system integrity through comprehensive multi-round verification.
|
|
19
19
|
|
|
20
20
|
## Core Capabilities
|
|
21
21
|
|
|
@@ -34,7 +34,7 @@ You are an automated verification specialist that executes the mandatory R017 ve
|
|
|
34
34
|
|
|
35
35
|
| Command | Description |
|
|
36
36
|
|---------|-------------|
|
|
37
|
-
| `mgr-sauron:watch` | Full
|
|
37
|
+
| `mgr-sauron:watch` | Full R016 verification (5+3 rounds) |
|
|
38
38
|
| `mgr-sauron:quick` | Quick verification (single pass) |
|
|
39
39
|
| `mgr-sauron:report` | Generate verification status report |
|
|
40
40
|
|
|
@@ -117,7 +117,7 @@ The skill's WORKFLOW is followed, but git EXECUTION is delegated to mgr-gitnerd
|
|
|
117
117
|
|
|
118
118
|
## Agent Teams (when enabled)
|
|
119
119
|
|
|
120
|
-
When `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1`: use Agent Teams for 3+ agent coordinated tasks. See
|
|
120
|
+
When `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1`: use Agent Teams for 3+ agent coordinated tasks. See R017 for decision matrix. Task tool remains fallback for simple/independent tasks.
|
|
121
121
|
|
|
122
122
|
## Announcement Format
|
|
123
123
|
|
|
@@ -62,7 +62,7 @@ rules:
|
|
|
62
62
|
scope: agents
|
|
63
63
|
|
|
64
64
|
# Intent Transparency - MUST
|
|
65
|
-
- id:
|
|
65
|
+
- id: R014
|
|
66
66
|
name: intent-transparency
|
|
67
67
|
title: Intent Transparency Rules
|
|
68
68
|
path: ./MUST-intent-transparency.md
|
|
@@ -70,7 +70,7 @@ rules:
|
|
|
70
70
|
scope: orchestrator
|
|
71
71
|
|
|
72
72
|
# Continuous Improvement - MUST
|
|
73
|
-
- id:
|
|
73
|
+
- id: R015
|
|
74
74
|
name: continuous-improvement
|
|
75
75
|
title: Continuous Improvement Rules
|
|
76
76
|
path: ./MUST-continuous-improvement.md
|
|
@@ -78,7 +78,7 @@ rules:
|
|
|
78
78
|
scope: all
|
|
79
79
|
|
|
80
80
|
# Sync Verification - MUST
|
|
81
|
-
- id:
|
|
81
|
+
- id: R016
|
|
82
82
|
name: sync-verification
|
|
83
83
|
title: Sync Verification Rules
|
|
84
84
|
path: ./MUST-sync-verification.md
|
|
@@ -125,7 +125,7 @@ rules:
|
|
|
125
125
|
scope: all
|
|
126
126
|
|
|
127
127
|
# Agent Teams - SHOULD
|
|
128
|
-
- id:
|
|
128
|
+
- id: R017
|
|
129
129
|
name: agent-teams
|
|
130
130
|
title: Agent Teams Rules
|
|
131
131
|
path: ./SHOULD-agent-teams.md
|
|
@@ -219,6 +219,19 @@ Pipeline design completed.
|
|
|
219
219
|
- **secretary-routing**: DE agents accessible through secretary for management tasks
|
|
220
220
|
- **qa-lead-routing**: Coordinates with QA for data quality testing
|
|
221
221
|
|
|
222
|
+
## Agent Teams Awareness
|
|
223
|
+
|
|
224
|
+
Before routing via Task tool, check if Agent Teams is available (`CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` or TeamCreate/SendMessage tools present).
|
|
225
|
+
|
|
226
|
+
**Self-check:** Does this task need 3+ agents, shared state, or inter-agent communication? If yes, prefer Agent Teams over Task tool. See R018 for the full decision matrix.
|
|
227
|
+
|
|
228
|
+
| Scenario | Preferred |
|
|
229
|
+
|----------|-----------|
|
|
230
|
+
| Single-tool DE task | Task Tool |
|
|
231
|
+
| Multi-tool pipeline design (3+ tools) | Agent Teams |
|
|
232
|
+
| Cross-tool data quality analysis | Agent Teams |
|
|
233
|
+
| Quick DAG/model validation | Task Tool |
|
|
234
|
+
|
|
222
235
|
## Usage
|
|
223
236
|
|
|
224
237
|
This skill is NOT user-invocable. It should be automatically triggered when the main conversation detects data engineering intent.
|
|
@@ -77,4 +77,18 @@ user-invocable: false
|
|
|
77
77
|
|
|
78
78
|
Multi-language: detect all languages, route to parallel experts (max 4). Single-language: route to matching expert. Cross-layer (frontend + backend): multiple experts in parallel.
|
|
79
79
|
|
|
80
|
+
## Agent Teams Awareness
|
|
81
|
+
|
|
82
|
+
Before routing via Task tool, check if Agent Teams is available (`CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` or TeamCreate/SendMessage tools present).
|
|
83
|
+
|
|
84
|
+
**Self-check:** Does this task need 3+ agents, shared state, or inter-agent communication? If yes, prefer Agent Teams over Task tool. See R018 for the full decision matrix.
|
|
85
|
+
|
|
86
|
+
| Scenario | Preferred |
|
|
87
|
+
|----------|-----------|
|
|
88
|
+
| Single-language review | Task Tool |
|
|
89
|
+
| Multi-language code review (3+) | Agent Teams |
|
|
90
|
+
| Code review + fix cycle | Agent Teams |
|
|
91
|
+
| Cross-layer debugging (FE + BE + DB) | Agent Teams |
|
|
92
|
+
| Simple file search/validation | Task Tool |
|
|
93
|
+
|
|
80
94
|
Not user-invocable. Auto-triggered on development intent.
|