oh-my-customcode 0.30.8 → 0.31.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 CHANGED
@@ -21,7 +21,7 @@ Like oh-my-zsh transformed shell customization, oh-my-customcode makes personali
21
21
 
22
22
  | Feature | Description |
23
23
  |---------|-------------|
24
- | **Batteries Included** | 44 agents, 68 skills, 24 guides, 18 rules, 2 hooks, 4 contexts, ontology graph - ready to use out of the box |
24
+ | **Batteries Included** | 44 agents, 68 skills, 25 guides, 18 rules, 2 hooks, 4 contexts, ontology graph - ready to use out of the box |
25
25
  | **Sub-Agent Model** | Supports hierarchical agent orchestration with specialized roles |
26
26
  | **Dead Simple Customization** | Create a folder + markdown file = new agent or skill |
27
27
  | **Mix and Match** | Use built-in components, create your own, or combine both |
@@ -197,7 +197,7 @@ All commands are invoked inside the Claude Code conversation.
197
197
  | **Deploy** | 2 | vercel-deploy, codex-exec |
198
198
  | **External** | 1 | skills-sh-search |
199
199
 
200
- ### Guides (24)
200
+ ### Guides (25)
201
201
 
202
202
  Comprehensive reference documentation covering:
203
203
  - Agent creation and management
@@ -292,7 +292,8 @@ your-project/
292
292
  │ ├── rules/ # Behavior rules (18 total)
293
293
  │ ├── hooks/ # Event hooks (2 total)
294
294
  │ └── contexts/ # Context files (4 total)
295
- └── guides/ # Reference docs (24 total)
295
+ └── templates/
296
+ └── guides/ # Reference docs (25 total)
296
297
  ```
297
298
 
298
299
  **Note**: In the official Claude Code format, there is no command registry — slash commands and natural language agent references are used.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-customcode",
3
- "version": "0.30.8",
3
+ "version": "0.31.0",
4
4
  "description": "Batteries-included agent harness for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {
@@ -168,6 +168,7 @@ Violation = immediate correction. No exception for "small changes".
168
168
  | `/optimize-analyze` | Analyze bundle and performance |
169
169
  | `/optimize-bundle` | Optimize bundle size |
170
170
  | `/optimize-report` | Generate optimization report |
171
+ | `/research` | 10-team parallel deep analysis and cross-verification |
171
172
  | `/sauron-watch` | Full R017 verification |
172
173
  | `/structured-dev-cycle` | 6-stage structured development cycle (Plan → Verify → Implement → Verify → Compound → Done) |
173
174
  | `/lists` | Show all available commands |
@@ -168,6 +168,7 @@ oh-my-customcode로 구동됩니다.
168
168
  | `/optimize-analyze` | 번들 및 성능 분석 |
169
169
  | `/optimize-bundle` | 번들 크기 최적화 |
170
170
  | `/optimize-report` | 최적화 리포트 생성 |
171
+ | `/research` | 10-team 병렬 딥 분석 및 교차 검증 |
171
172
  | `/sauron-watch` | 전체 R017 검증 |
172
173
  | `/structured-dev-cycle` | 6단계 구조적 개발 사이클 (Plan → Verify → Implement → Verify → Compound → Done) |
173
174
  | `/lists` | 모든 사용 가능한 커맨드 표시 |
@@ -80,7 +80,7 @@ Detect with: DevTools → Rendering → "Highlight repaints"
80
80
 
81
81
  | Avoid | Use Instead | Reason |
82
82
  |-------|-------------|--------|
83
- | `Opacity` widget | `color.withOpacity()` | Triggers saveLayer |
83
+ | `Opacity` widget | `color.withValues(alpha: 0.5)` | Opacity widget triggers saveLayer |
84
84
  | `ClipRRect` in animations | Pre-clip static content | saveLayer per frame |
85
85
  | `Container` for sizing | `SizedBox` | Lighter, no decoration |
86
86
 
@@ -0,0 +1,29 @@
1
+ # Java 21 Guide
2
+
3
+ metadata:
4
+ name: java21
5
+ description: Java 21 language reference and modern feature documentation
6
+
7
+ source:
8
+ type: external
9
+ origin: docs.oracle.com
10
+ urls:
11
+ - https://docs.oracle.com/en/java/javase/21/
12
+ - https://openjdk.org/projects/loom/
13
+ - https://openjdk.org/jeps/440
14
+ - https://openjdk.org/jeps/441
15
+ - https://openjdk.org/jeps/444
16
+ - https://google.github.io/styleguide/javaguide.html
17
+ last_fetched: "2026-03-11"
18
+
19
+ documents:
20
+ - name: modern-java21
21
+ path: ./modern-java21.md
22
+ description: Java 21 modern features (Virtual Threads, Pattern Matching, Records, Sealed Classes)
23
+
24
+ - name: java-style-guide
25
+ path: ./java-style-guide.md
26
+ description: Google Java Style Guide conventions
27
+
28
+ used_by:
29
+ - lang-java21-expert
@@ -0,0 +1,248 @@
1
+ # Java Style Guide
2
+
3
+ > Source: https://google.github.io/styleguide/javaguide.html
4
+
5
+ ## File Structure
6
+
7
+ ```
8
+ Source file:
9
+ 1. License/copyright (if any)
10
+ 2. Package statement
11
+ 3. Import statements
12
+ 4. Exactly one top-level class
13
+ ```
14
+
15
+ ### Import Ordering
16
+
17
+ ```java
18
+ // 1. Static imports (all together)
19
+ import static org.junit.Assert.assertEquals;
20
+
21
+ // 2. Non-static imports (all together, no subgroups)
22
+ import com.example.Foo;
23
+ import java.util.List;
24
+ import org.springframework.boot.SpringApplication;
25
+ ```
26
+
27
+ No wildcard imports except `static` test imports.
28
+
29
+ ---
30
+
31
+ ## Naming Conventions
32
+
33
+ | Element | Style | Example |
34
+ |---------|-------|---------|
35
+ | Packages | `lowercase` | `com.example.network` |
36
+ | Classes | `UpperCamelCase` | `OrderProcessor` |
37
+ | Records | `UpperCamelCase` | `UserRecord` |
38
+ | Methods | `lowerCamelCase` | `processOrder()` |
39
+ | Local vars | `lowerCamelCase` | `itemCount` |
40
+ | Constants | `UPPER_SNAKE_CASE` | `MAX_RETRIES` |
41
+ | Type params | Single letter or `UpperCamelCase + T` | `T`, `E`, `RequestT` |
42
+
43
+ ### Acronyms
44
+
45
+ Treat acronyms as words: `XmlParser`, not `XMLParser`. Exception: well-known 2-letter ones like `IO`.
46
+
47
+ ---
48
+
49
+ ## Formatting
50
+
51
+ ### Indentation
52
+
53
+ - 2 spaces (not tabs) for block indentation
54
+ - 4 spaces for line continuation
55
+
56
+ ```java
57
+ // Block indentation: 2 spaces
58
+ if (condition) {
59
+ doSomething();
60
+ }
61
+
62
+ // Line continuation: 4 spaces
63
+ String result = longMethodName(
64
+ argument1,
65
+ argument2);
66
+ ```
67
+
68
+ ### Braces
69
+
70
+ Always use braces, even for single-statement bodies:
71
+
72
+ ```java
73
+ // Correct
74
+ if (condition) {
75
+ doSomething();
76
+ }
77
+
78
+ // Wrong (no braces)
79
+ if (condition)
80
+ doSomething();
81
+ ```
82
+
83
+ ### Column Limit
84
+
85
+ 100 characters per line. Wrap when exceeding.
86
+
87
+ ### Blank Lines
88
+
89
+ ```java
90
+ class MyClass {
91
+ private int field; // field
92
+ // one blank line
93
+ public MyClass() { } // constructor
94
+ // one blank line
95
+ public void method() { } // method
96
+ }
97
+ ```
98
+
99
+ ---
100
+
101
+ ## Class Structure
102
+
103
+ ```java
104
+ public class MyClass {
105
+ // 1. Static fields
106
+ private static final Logger log = LoggerFactory.getLogger(MyClass.class);
107
+
108
+ // 2. Instance fields
109
+ private final String name;
110
+
111
+ // 3. Constructors
112
+ public MyClass(String name) {
113
+ this.name = name;
114
+ }
115
+
116
+ // 4. Static factory methods (if applicable)
117
+ public static MyClass of(String name) {
118
+ return new MyClass(name);
119
+ }
120
+
121
+ // 5. Instance methods (public → package → protected → private)
122
+ public String getName() { return name; }
123
+
124
+ private void helper() { }
125
+
126
+ // 6. Inner classes/interfaces (last)
127
+ }
128
+ ```
129
+
130
+ ---
131
+
132
+ ## Programming Practices
133
+
134
+ ### Annotations
135
+
136
+ ```java
137
+ // One annotation per line for class/method
138
+ @Override
139
+ @Nullable
140
+ public String format(String input) { }
141
+
142
+ // Multiple short annotations on one line for field is OK
143
+ @Nullable @Deprecated String field;
144
+ ```
145
+
146
+ ### Numeric Literals
147
+
148
+ ```java
149
+ long big = 1_000_000L;
150
+ double pi = 3.14_159;
151
+ int hex = 0xFF_EC_D1_8C;
152
+ ```
153
+
154
+ ### Switch Expressions (prefer over statements)
155
+
156
+ ```java
157
+ // Prefer switch expression
158
+ int days = switch (month) {
159
+ case JANUARY, MARCH, MAY, JULY, AUGUST, OCTOBER, DECEMBER -> 31;
160
+ case APRIL, JUNE, SEPTEMBER, NOVEMBER -> 30;
161
+ case FEBRUARY -> 28;
162
+ };
163
+ ```
164
+
165
+ ### Avoid Long Methods
166
+
167
+ Keep methods short and focused. Extract helpers for blocks exceeding ~20 lines.
168
+
169
+ ---
170
+
171
+ ## Javadoc
172
+
173
+ ### Required for
174
+
175
+ - Every `public` class, interface, enum, record
176
+ - Every `public` or `protected` method (unless trivially obvious)
177
+
178
+ ### Format
179
+
180
+ ```java
181
+ /**
182
+ * Returns the user associated with the given ID.
183
+ *
184
+ * <p>This method performs a database lookup. It is safe to call
185
+ * from multiple threads.
186
+ *
187
+ * @param id the user identifier (must be positive)
188
+ * @return the user, or empty if not found
189
+ * @throws IllegalArgumentException if {@code id <= 0}
190
+ */
191
+ public Optional<User> findById(long id) { }
192
+ ```
193
+
194
+ ### Inline Tags
195
+
196
+ ```java
197
+ /**
198
+ * See {@link UserRepository} for persistence details.
199
+ * Use {@code null} to reset the state.
200
+ */
201
+ ```
202
+
203
+ ### Prohibited: Non-Javadoc Comments for API
204
+
205
+ ```java
206
+ // Wrong: plain comment for public method
207
+ // Returns the user by id
208
+ public Optional<User> findById(long id) { }
209
+
210
+ // Correct: Javadoc
211
+ /** Returns the user by id, or empty if not found. */
212
+ public Optional<User> findById(long id) { }
213
+ ```
214
+
215
+ ---
216
+
217
+ ## Common Antipatterns to Avoid
218
+
219
+ ```java
220
+ // ❌ Raw types
221
+ List list = new ArrayList();
222
+ // ✓
223
+ List<String> list = new ArrayList<>();
224
+
225
+ // ❌ String concatenation in loop
226
+ String s = "";
227
+ for (String item : items) s += item;
228
+ // ✓
229
+ StringBuilder sb = new StringBuilder();
230
+ for (String item : items) sb.append(item);
231
+ String s = sb.toString();
232
+
233
+ // ❌ Return null for collections
234
+ public List<String> getItems() { return null; }
235
+ // ✓
236
+ public List<String> getItems() { return Collections.emptyList(); }
237
+
238
+ // ❌ Catch Exception broadly
239
+ try { process(); } catch (Exception e) { }
240
+ // ✓
241
+ try { process(); } catch (IOException e) { log.error("IO error", e); }
242
+
243
+ // ❌ Mutable public field
244
+ public String name;
245
+ // ✓
246
+ private String name;
247
+ public String getName() { return name; }
248
+ ```
@@ -0,0 +1,303 @@
1
+ # Modern Java 21 Features
2
+
3
+ > Sources: https://openjdk.org/jeps/ (JEP 431, 440, 441, 444)
4
+
5
+ ## Virtual Threads (JEP 444)
6
+
7
+ Virtual Threads are lightweight threads managed by the JVM, enabling millions of concurrent tasks without thread pool tuning.
8
+
9
+ ### Key Properties
10
+
11
+ | Property | Platform Thread | Virtual Thread |
12
+ |----------|----------------|----------------|
13
+ | Creation cost | High (OS thread) | Low (JVM-managed) |
14
+ | Memory footprint | ~1MB per thread | ~few KB |
15
+ | Blocking behavior | Blocks OS thread | Unmounts carrier thread |
16
+ | Pooling | Needed | Not recommended |
17
+
18
+ ### Usage
19
+
20
+ ```java
21
+ // Virtual Thread executor (preferred for I/O-bound tasks)
22
+ try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
23
+ List<Future<String>> futures = IntStream.range(0, 10_000)
24
+ .mapToObj(i -> executor.submit(() -> fetchData(i)))
25
+ .toList();
26
+ // all 10,000 tasks run concurrently
27
+ }
28
+
29
+ // Direct creation
30
+ Thread.ofVirtual().name("vt-worker").start(() -> processRequest());
31
+
32
+ // Factory for thread pools
33
+ ThreadFactory factory = Thread.ofVirtual().name("worker-", 0).factory();
34
+ ```
35
+
36
+ ### Structured Concurrency (JEP 453, Preview)
37
+
38
+ ```java
39
+ try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
40
+ Future<String> user = scope.fork(() -> fetchUser(id));
41
+ Future<String> orders = scope.fork(() -> fetchOrders(id));
42
+
43
+ scope.join().throwIfFailed();
44
+
45
+ return new UserProfile(user.get(), orders.get());
46
+ }
47
+ ```
48
+
49
+ ### Pinning Avoidance
50
+
51
+ Virtual Threads are **pinned** (cannot unmount) inside `synchronized` blocks. Prefer `ReentrantLock`:
52
+
53
+ ```java
54
+ // Avoid (causes pinning)
55
+ synchronized (lock) {
56
+ callBlockingIO();
57
+ }
58
+
59
+ // Prefer
60
+ private final ReentrantLock lock = new ReentrantLock();
61
+ lock.lock();
62
+ try {
63
+ callBlockingIO();
64
+ } finally {
65
+ lock.unlock();
66
+ }
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Pattern Matching for instanceof (JEP 394)
72
+
73
+ ```java
74
+ // Before Java 16
75
+ if (obj instanceof String) {
76
+ String s = (String) obj;
77
+ return s.length();
78
+ }
79
+
80
+ // Java 21
81
+ if (obj instanceof String s) {
82
+ return s.length();
83
+ }
84
+
85
+ // With guard
86
+ if (obj instanceof String s && !s.isEmpty()) {
87
+ return s.toUpperCase();
88
+ }
89
+ ```
90
+
91
+ ---
92
+
93
+ ## Pattern Matching for switch (JEP 441)
94
+
95
+ ```java
96
+ // Type patterns
97
+ String format = switch (obj) {
98
+ case Integer i -> String.format("int %d", i);
99
+ case Double d -> String.format("double %.2f", d);
100
+ case String s -> String.format("String '%s'", s);
101
+ case null -> "null value";
102
+ default -> obj.toString();
103
+ };
104
+
105
+ // Guarded patterns (when clause)
106
+ String classify = switch (number) {
107
+ case Integer i when i < 0 -> "negative";
108
+ case Integer i when i == 0 -> "zero";
109
+ case Integer i -> "positive";
110
+ default -> "non-integer";
111
+ };
112
+ ```
113
+
114
+ ---
115
+
116
+ ## Record Classes (JEP 395)
117
+
118
+ Records are immutable data carriers with auto-generated `equals`, `hashCode`, `toString`, and accessors.
119
+
120
+ ```java
121
+ // Basic record
122
+ record Point(int x, int y) {}
123
+
124
+ Point p = new Point(3, 4);
125
+ int x = p.x(); // accessor (not getX())
126
+ System.out.println(p); // Point[x=3, y=4]
127
+
128
+ // Compact constructor (validation)
129
+ record Range(int min, int max) {
130
+ Range {
131
+ if (min > max)
132
+ throw new IllegalArgumentException(
133
+ "min %d > max %d".formatted(min, max));
134
+ }
135
+ }
136
+
137
+ // Custom methods
138
+ record Circle(double radius) {
139
+ static final double PI = Math.PI;
140
+
141
+ double area() { return PI * radius * radius; }
142
+
143
+ Circle scale(double factor) { return new Circle(radius * factor); }
144
+ }
145
+
146
+ // Implementing interface
147
+ interface Describable { String describe(); }
148
+ record Color(int r, int g, int b) implements Describable {
149
+ public String describe() {
150
+ return "rgb(%d,%d,%d)".formatted(r, g, b);
151
+ }
152
+ }
153
+ ```
154
+
155
+ ### When to Use Records vs Classes
156
+
157
+ | Use Record | Use Class |
158
+ |------------|-----------|
159
+ | Pure data containers | Entities with mutable state |
160
+ | DTOs, value objects | Domain objects with lifecycle |
161
+ | API response types | Services, repositories |
162
+ | Config/settings | Mutable builders |
163
+
164
+ ---
165
+
166
+ ## Record Patterns (JEP 440)
167
+
168
+ Deconstruct records directly in `instanceof` and `switch`:
169
+
170
+ ```java
171
+ // instanceof deconstruction
172
+ if (obj instanceof Point(int x, int y)) {
173
+ System.out.println("x=" + x + ", y=" + y);
174
+ }
175
+
176
+ // switch deconstruction
177
+ String describe = switch (shape) {
178
+ case Circle(double r) -> "circle r=%.2f".formatted(r);
179
+ case Rectangle(double w, double h) -> "rect %.1fx%.1f".formatted(w, h);
180
+ default -> "unknown";
181
+ };
182
+
183
+ // Nested patterns
184
+ record ColoredPoint(Point point, Color color) {}
185
+
186
+ if (obj instanceof ColoredPoint(Point(int x, int y), Color(int r, int g, int b))) {
187
+ System.out.printf("Colored point at (%d,%d) with rgb(%d,%d,%d)%n",
188
+ x, y, r, g, b);
189
+ }
190
+ ```
191
+
192
+ ---
193
+
194
+ ## Sealed Classes (JEP 409)
195
+
196
+ Sealed classes restrict which classes can implement/extend them, enabling exhaustive pattern matching.
197
+
198
+ ```java
199
+ // Sealed interface with records
200
+ sealed interface Shape permits Circle, Rectangle, Triangle {}
201
+
202
+ record Circle(double radius) implements Shape {}
203
+ record Rectangle(double width, double height) implements Shape {}
204
+ record Triangle(double base, double height) implements Shape {}
205
+
206
+ // Exhaustive switch — no default needed
207
+ double area = switch (shape) {
208
+ case Circle(double r) -> Math.PI * r * r;
209
+ case Rectangle(double w, double h) -> w * h;
210
+ case Triangle(double b, double h) -> 0.5 * b * h;
211
+ };
212
+
213
+ // Sealed class hierarchy (non-record)
214
+ sealed class Vehicle permits Car, Truck, Motorcycle {}
215
+ final class Car extends Vehicle { }
216
+ non-sealed class Truck extends Vehicle { } // allows further subclassing
217
+ ```
218
+
219
+ ### Benefits
220
+
221
+ - Compiler enforces exhaustive handling in `switch`
222
+ - Clear closed type hierarchy in domain model
223
+ - Better than `enum` when subtypes carry different data
224
+
225
+ ---
226
+
227
+ ## Sequenced Collections (JEP 431)
228
+
229
+ New interfaces: `SequencedCollection`, `SequencedSet`, `SequencedMap`.
230
+
231
+ ```java
232
+ // SequencedCollection
233
+ List<String> list = new ArrayList<>(List.of("a", "b", "c"));
234
+ String first = list.getFirst(); // "a"
235
+ String last = list.getLast(); // "c"
236
+ list.addFirst("z"); // ["z", "a", "b", "c"]
237
+ list.addLast("end"); // ["z", "a", "b", "c", "end"]
238
+ list.removeFirst(); // ["a", "b", "c", "end"]
239
+
240
+ // Reversed view (live, backed by original)
241
+ List<String> reversed = list.reversed();
242
+
243
+ // SequencedMap
244
+ LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
245
+ map.put("one", 1);
246
+ map.put("two", 2);
247
+ map.put("three", 3);
248
+
249
+ Map.Entry<String, Integer> first = map.firstEntry(); // "one"=1
250
+ Map.Entry<String, Integer> last = map.lastEntry(); // "three"=3
251
+ map.putFirst("zero", 0); // inserts at front
252
+ SequencedMap<String, Integer> rev = map.reversed();
253
+ ```
254
+
255
+ ---
256
+
257
+ ## Migration from Legacy Java
258
+
259
+ ### Replace instanceof chains
260
+
261
+ ```java
262
+ // Legacy (avoid)
263
+ if (obj instanceof String) {
264
+ return ((String) obj).length();
265
+ } else if (obj instanceof Integer) {
266
+ return ((Integer) obj).intValue();
267
+ }
268
+
269
+ // Modern
270
+ return switch (obj) {
271
+ case String s -> s.length();
272
+ case Integer i -> i;
273
+ default -> -1;
274
+ };
275
+ ```
276
+
277
+ ### Replace POJOs with Records
278
+
279
+ ```java
280
+ // Legacy POJO (avoid for pure data)
281
+ public class Point {
282
+ private final int x, y;
283
+ public Point(int x, int y) { this.x = x; this.y = y; }
284
+ public int getX() { return x; }
285
+ public int getY() { return y; }
286
+ @Override public boolean equals(Object o) { ... }
287
+ @Override public int hashCode() { ... }
288
+ @Override public String toString() { ... }
289
+ }
290
+
291
+ // Modern Record
292
+ record Point(int x, int y) {}
293
+ ```
294
+
295
+ ### Replace thread pools for I/O with Virtual Threads
296
+
297
+ ```java
298
+ // Legacy (avoid for I/O-bound)
299
+ ExecutorService pool = Executors.newFixedThreadPool(200);
300
+
301
+ // Modern
302
+ ExecutorService pool = Executors.newVirtualThreadPerTaskExecutor();
303
+ ```
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.30.8",
2
+ "version": "0.31.0",
3
3
  "lastUpdated": "2026-03-09T00:00:00.000Z",
4
4
  "components": [
5
5
  {
@@ -24,7 +24,7 @@
24
24
  "name": "guides",
25
25
  "path": "guides",
26
26
  "description": "Reference documentation",
27
- "files": 24
27
+ "files": 25
28
28
  },
29
29
  {
30
30
  "name": "hooks",
@@ -1,9 +0,0 @@
1
- <claude-mem-context>
2
- # Recent Activity
3
-
4
- ### Feb 5, 2026
5
-
6
- | ID | Time | T | Title | Read |
7
- |----|------|---|-------|------|
8
- | #8 | 8:07 PM | 🔵 | Skill Definition Structure | ~626 |
9
- </claude-mem-context>