oh-my-customcode 0.50.0 → 0.51.1

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
@@ -13,7 +13,7 @@
13
13
 
14
14
  **[한국어 문서 (Korean)](./README_ko.md)**
15
15
 
16
- 45 agents. 90 skills. 21 rules. One command.
16
+ 45 agents. 91 skills. 21 rules. One command.
17
17
 
18
18
  ```bash
19
19
  npm install -g oh-my-customcode && cd your-project && omcustom init
@@ -138,7 +138,7 @@ Each agent declares its tools, model, memory scope, and limitations in YAML fron
138
138
 
139
139
  ---
140
140
 
141
- ### Skills (90)
141
+ ### Skills (91)
142
142
 
143
143
  | Category | Count | Includes |
144
144
  |----------|-------|----------|
@@ -228,7 +228,7 @@ Key rules: R010 (orchestrator never writes files), R009 (parallel execution mand
228
228
 
229
229
  ---
230
230
 
231
- ### Guides (29)
231
+ ### Guides (30)
232
232
 
233
233
  Reference documentation covering best practices, architecture decisions, and integration patterns. Located in `guides/` at project root, covering topics from agent design to CI/CD to observability.
234
234
 
@@ -274,14 +274,14 @@ your-project/
274
274
  ├── CLAUDE.md # Entry point
275
275
  ├── .claude/
276
276
  │ ├── agents/ # 45 agent definitions
277
- │ ├── skills/ # 90 skill modules
277
+ │ ├── skills/ # 91 skill modules
278
278
  │ ├── rules/ # 21 governance rules (R000-R021)
279
279
  │ ├── hooks/ # 15 lifecycle hook scripts
280
280
  │ ├── schemas/ # Tool input validation schemas
281
281
  │ ├── specs/ # Extracted canonical specs
282
282
  │ ├── contexts/ # 4 shared context files
283
283
  │ └── ontology/ # Knowledge graph for RAG
284
- └── guides/ # 29 reference documents
284
+ └── guides/ # 30 reference documents
285
285
  ```
286
286
 
287
287
  ---
package/dist/cli/index.js CHANGED
@@ -9323,7 +9323,7 @@ var init_package = __esm(() => {
9323
9323
  package_default = {
9324
9324
  name: "oh-my-customcode",
9325
9325
  workspaces: ["packages/*"],
9326
- version: "0.50.0",
9326
+ version: "0.51.1",
9327
9327
  description: "Batteries-included agent harness for Claude Code",
9328
9328
  type: "module",
9329
9329
  bin: {
package/dist/index.js CHANGED
@@ -1668,7 +1668,7 @@ import { join as join6 } from "node:path";
1668
1668
  var package_default = {
1669
1669
  name: "oh-my-customcode",
1670
1670
  workspaces: ["packages/*"],
1671
- version: "0.50.0",
1671
+ version: "0.51.1",
1672
1672
  description: "Batteries-included agent harness for Claude Code",
1673
1673
  type: "module",
1674
1674
  bin: {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "oh-my-customcode",
3
3
  "workspaces": ["packages/*"],
4
- "version": "0.50.0",
4
+ "version": "0.51.1",
5
5
  "description": "Batteries-included agent harness for Claude Code",
6
6
  "type": "module",
7
7
  "bin": {
@@ -0,0 +1,248 @@
1
+ ---
2
+ name: scout
3
+ description: Analyze external URL to evaluate fit with oh-my-customcode project and auto-create GitHub issue with verdict
4
+ scope: core
5
+ version: 1.0.0
6
+ user-invocable: true
7
+ argument-hint: "<url>"
8
+ ---
9
+
10
+ # /scout — External Link Analysis
11
+
12
+ Analyze an external URL (tech blog, tool, library, methodology) to evaluate its fit with the oh-my-customcode project and auto-create a GitHub issue with a structured verdict.
13
+
14
+ ## Usage
15
+
16
+ ```
17
+ /scout <url>
18
+ /scout https://news.hada.io/topic?id=27673
19
+ /scout https://github.com/user/repo
20
+ ```
21
+
22
+ ## Verdict Taxonomy
23
+
24
+ | Verdict | Meaning | Label | Follow-up |
25
+ |---------|---------|-------|-----------|
26
+ | **INTERNALIZE** | Aligns with project philosophy; should become a skill/agent/guide | `scout:internalize` + `P1`/`P2`/`P3` | `/research` or direct implementation |
27
+ | **INTEGRATE** | Useful but best kept as external dependency | `scout:integrate` + `P2`/`P3` | Plugin/MCP integration review |
28
+ | **SKIP** | Irrelevant or duplicates existing functionality | `scout:skip` | Issue created then closed |
29
+
30
+ ## Pre-flight Guards
31
+
32
+ ### Guard 1: URL Validity (GATE)
33
+
34
+ Before any work, validate the URL:
35
+
36
+ ```bash
37
+ # Check URL is syntactically valid
38
+ echo "$URL" | grep -qE '^https?://'
39
+ ```
40
+
41
+ If invalid: `[Pre-flight] GATE: Invalid or unreachable URL. Please check and retry.` — abort.
42
+
43
+ ### Guard 2: Duplicate Scout (WARN)
44
+
45
+ Search existing GitHub issues for prior scout reports on the same URL domain:
46
+
47
+ ```bash
48
+ DOMAIN=$(echo "$URL" | sed 's|https\?://||' | cut -d'/' -f1)
49
+ gh issue list --state all --label "scout:internalize,scout:integrate,scout:skip" \
50
+ --json number,title,body --jq ".[] | select(.body | contains(\"$DOMAIN\"))" 2>/dev/null
51
+ ```
52
+
53
+ If found: `[Pre-flight] WARN: Similar URL already scouted in issue #N. Proceed anyway? [Y/n]`
54
+
55
+ ## Display Format
56
+
57
+ Before execution, show the plan:
58
+
59
+ ```
60
+ [Scout] {url}
61
+ ├── Phase 1: Fetch & Summarize
62
+ ├── Phase 2: Load Project Philosophy
63
+ ├── Phase 3: Fit Analysis (sonnet)
64
+ └── Phase 4: Issue Creation
65
+
66
+ Estimated: ~1 min | Cost: ~$0.5-1.5
67
+ Execute? [Y/n]
68
+ ```
69
+
70
+ ## Workflow
71
+
72
+ ### Phase 1: Fetch & Summarize
73
+
74
+ 1. `WebFetch(url)` — retrieve page content
75
+ 2. Extract core information:
76
+ - Title and purpose
77
+ - Key technology / methodology
78
+ - Approach and principles
79
+ 3. If fetch fails — report error, abort
80
+
81
+ ### Phase 2: Load Project Philosophy
82
+
83
+ 1. `Read(CLAUDE.md)` — extract architecture philosophy:
84
+ - Compilation metaphor (source -> build -> artifact)
85
+ - Separation of concerns (R006)
86
+ - Dynamic agent creation ("no expert? create one")
87
+ - Skill/agent/guide/rule structure
88
+ 2. `Read(README.md)` — extract project overview and component inventory
89
+ 3. `Glob(.claude/skills/*/SKILL.md)` — list existing skills for overlap detection
90
+
91
+ ### Phase 3: Fit Analysis
92
+
93
+ Spawn 1 sonnet agent with the following analysis prompt.
94
+
95
+ **Inputs**:
96
+ - Fetched content summary (Phase 1)
97
+ - Project philosophy context (Phase 2)
98
+ - Existing skill list (Phase 2)
99
+
100
+ **Analysis dimensions**:
101
+
102
+ | Dimension | Question |
103
+ |-----------|----------|
104
+ | Philosophy alignment | Does it match the compilation metaphor, separation of concerns, "create experts on demand"? |
105
+ | Technical fit | Does it complement or overlap with existing skills/agents/guides? |
106
+ | Integration effort | How much work to internalize vs. use externally? |
107
+ | Value proposition | What concrete benefit does it bring to the project? |
108
+
109
+ **Agent prompt template**:
110
+
111
+ ```
112
+ You are a project fit analyst. Given:
113
+
114
+ 1. External content summary:
115
+ {phase1_summary}
116
+
117
+ 2. Project philosophy:
118
+ {phase2_philosophy}
119
+
120
+ 3. Existing skills ({skill_count} total):
121
+ {skill_list}
122
+
123
+ Analyze the external content against the project philosophy across 4 dimensions:
124
+ - Philosophy alignment
125
+ - Technical fit (overlap with existing skills?)
126
+ - Integration effort (XS/S/M/L)
127
+ - Value proposition
128
+
129
+ Return a structured verdict:
130
+ - verdict: INTERNALIZE | INTEGRATE | SKIP
131
+ - priority: P1 | P2 | P3
132
+ - rationale: 2-3 sentences
133
+ - philosophy_table: criterion/fit/rationale for each dimension
134
+ - recommendation: specific integration plan or skip reason
135
+ - next_steps: 2-3 actionable items
136
+ - escalation: true/false (INTERNALIZE + M/L effort = true)
137
+ ```
138
+
139
+ **Output**: Structured verdict with rationale.
140
+
141
+ ### Phase 4: Issue Creation
142
+
143
+ 1. Ensure scout labels exist (defensive, idempotent):
144
+ ```bash
145
+ gh label create "scout:internalize" --color "0E8A16" --description "Scout: should be internalized" 2>/dev/null || true
146
+ gh label create "scout:integrate" --color "1D76DB" --description "Scout: keep as external" 2>/dev/null || true
147
+ gh label create "scout:skip" --color "D4C5F9" --description "Scout: skip" 2>/dev/null || true
148
+ ```
149
+
150
+ 2. Create GitHub issue:
151
+ ```bash
152
+ gh issue create \
153
+ --title "[scout:{verdict}] {content_title}" \
154
+ --label "scout:{verdict},P{n}" \
155
+ --body "{issue_body}"
156
+ ```
157
+
158
+ 3. If verdict is `SKIP`: auto-close the issue:
159
+ ```bash
160
+ gh issue close {number} -c "Auto-closed: scout verdict is SKIP"
161
+ ```
162
+
163
+ ### Issue Body Template
164
+
165
+ ```markdown
166
+ ## Scout Report: {title}
167
+
168
+ **Source**: {url}
169
+ **Verdict**: {INTERNALIZE / INTEGRATE / SKIP}
170
+ **Priority**: {P1 / P2 / P3}
171
+
172
+ ## Summary
173
+ {2-3 sentence summary of the external content}
174
+
175
+ ## Philosophy Alignment
176
+ | Criterion | Fit | Rationale |
177
+ |-----------|-----|-----------|
178
+ | Compilation metaphor | {check/cross} | {explanation} |
179
+ | Separation of concerns (R006) | {check/cross} | {explanation} |
180
+ | Dynamic agent creation | {check/cross} | {explanation} |
181
+ | Existing skill overlap | {check/cross} | {overlapping skills list} |
182
+
183
+ ## Recommendation
184
+ {Specific integration plan — which skill/agent/guide to create, or why to skip}
185
+
186
+ ## Next Steps
187
+ - [ ] {follow-up action 1}
188
+ - [ ] {follow-up action 2}
189
+
190
+ ---
191
+ Generated by `/scout`
192
+ ```
193
+
194
+ ## Escalation
195
+
196
+ When verdict is `INTERNALIZE` and integration effort is M or L:
197
+
198
+ ```
199
+ [Advisory] Deep analysis recommended.
200
+ └── Consider running: /research {url}
201
+ ```
202
+
203
+ ## Result Display
204
+
205
+ ```
206
+ [Scout Complete] {title}
207
+ ├── Verdict: {INTERNALIZE / INTEGRATE / SKIP}
208
+ ├── Priority: {P1 / P2 / P3}
209
+ ├── Issue: #{number}
210
+ └── Escalation: {/research recommended | none}
211
+ ```
212
+
213
+ ## Model Selection
214
+
215
+ | Phase | Model | Rationale |
216
+ |-------|-------|-----------|
217
+ | Phase 1 (Fetch) | orchestrator | Simple WebFetch, no agent needed |
218
+ | Phase 2 (Load) | orchestrator | Simple Read/Glob, no agent needed |
219
+ | Phase 3 (Analysis) | sonnet | Balanced reasoning for fit analysis |
220
+ | Phase 4 (Issue) | orchestrator | gh issue create via Bash |
221
+
222
+ ## Integration
223
+
224
+ | Rule | How |
225
+ |------|-----|
226
+ | R009 | Single agent in Phase 3 — no parallelism needed |
227
+ | R010 | Orchestrator manages phases 1/2/4; analysis delegated to sonnet agent in Phase 3 |
228
+ | R015 | Display scout plan before execution (Display Format section) |
229
+
230
+ ## When NOT to Use
231
+
232
+ | Scenario | Better Alternative |
233
+ |----------|--------------------|
234
+ | Deep multi-source research | `/research <url>` |
235
+ | Internal project analysis | `/omcustom:analysis` |
236
+ | Known tool evaluation | Direct agent conversation |
237
+ | Bulk URL analysis (5+) | `/research` with URL list |
238
+
239
+ ## Differences from /research
240
+
241
+ | Aspect | /scout | /research |
242
+ |--------|--------|-----------|
243
+ | Purpose | Quick fit evaluation | Deep multi-dimensional analysis |
244
+ | Teams | 1 agent | 10 teams |
245
+ | Cost | ~$0.5-1.5 | ~$8-15 |
246
+ | Duration | 1-2 min | 10-20 min |
247
+ | Output | Issue with verdict | Full report with ADOPT/ADAPT/AVOID |
248
+ | When | First contact with new link | Deep dive after scout recommends |
@@ -119,6 +119,7 @@ oh-my-customcode로 구동됩니다.
119
119
  | `/optimize-bundle` | 번들 크기 최적화 |
120
120
  | `/optimize-report` | 최적화 리포트 생성 |
121
121
  | `/research` | 10-team 병렬 딥 분석 및 교차 검증 |
122
+ | `/scout` | 외부 URL 분석 및 프로젝트 적합성 평가 |
122
123
  | `/deep-plan` | 연구 검증 기반 계획 수립 (research → plan → verify) |
123
124
  | `/deep-verify` | 다중 관점 릴리즈 품질 검증 |
124
125
  | `/omcustom:sauron-watch` | 전체 R017 검증 |
@@ -135,11 +136,11 @@ project/
135
136
  +-- CLAUDE.md # 진입점
136
137
  +-- .claude/
137
138
  | +-- agents/ # 서브에이전트 정의 (45 파일)
138
- | +-- skills/ # 스킬 (90 디렉토리)
139
+ | +-- skills/ # 스킬 (91 디렉토리)
139
140
  | +-- rules/ # 전역 규칙 (R000-R021)
140
141
  | +-- hooks/ # 훅 스크립트 (보안, 검증, HUD)
141
142
  | +-- contexts/ # 컨텍스트 파일 (ecomode)
142
- +-- guides/ # 레퍼런스 문서 (29 토픽)
143
+ +-- guides/ # 레퍼런스 문서 (30 토픽)
143
144
  ```
144
145
 
145
146
  ## 오케스트레이션
@@ -0,0 +1,69 @@
1
+ # Drizzle ORM: sql Template Literal Pitfalls
2
+
3
+ ## The Bug: Column References in Subqueries
4
+
5
+ When using Drizzle ORM's `sql` template literals, `${table.column}` generates a **bare column name without the table qualifier**. This causes silent semantic errors inside aliased subqueries.
6
+
7
+ ### Symptom
8
+
9
+ ```typescript
10
+ // Code
11
+ sql`SELECT ${agentInvocations.errorSummary} as sub_es
12
+ FROM ${agentInvocations} AS ai2
13
+ WHERE ai2.agent_type = ${agentInvocations.agentType}`
14
+
15
+ // Generated SQL (WRONG)
16
+ SELECT "error_summary" as sub_es
17
+ FROM "agent_invocations" AS ai2
18
+ WHERE ai2.agent_type = "agent_type" -- "agent_type" becomes a literal string, always true!
19
+ ```
20
+
21
+ `${agentInvocations.agentType}` expands to the **quoted column name** `"agent_type"` — not the value of the column. The `WHERE` clause compares `ai2.agent_type = "agent_type"`, which SQLite treats as a string literal match — always true for rows where `agent_type` equals the string `"agent_type"`.
22
+
23
+ ### Why Reviewers Miss It
24
+
25
+ - The code *looks* correct — you see `agentInvocations.agentType` and assume it's a column reference.
26
+ - Drizzle's `${table.column}` syntax works fine in top-level queries where table context is unambiguous.
27
+ - The bug only manifests inside subqueries with table aliases (`AS ai2`) — normal queries pass.
28
+ - No compile-time error; the SQL executes but returns wrong results.
29
+
30
+ ## The Fix: Raw SQL for Subquery Internal References
31
+
32
+ Use raw SQL strings for column references *inside* aliased subqueries. Reserve `${table.column}` only for Drizzle's top-level query builder where it resolves correctly.
33
+
34
+ ```typescript
35
+ // CORRECT: raw SQL column references inside aliased subquery
36
+ sql`SELECT ai2.error_summary as sub_es
37
+ FROM ${agentInvocations} AS ai2
38
+ WHERE ai2.agent_type = ${agentInvocations}.agent_type`
39
+ ```
40
+
41
+ Note: `${agentInvocations}` (the table object itself) still correctly expands to the table name and is safe to use for the `FROM` clause. Only *column* references inside subqueries must be written as raw SQL.
42
+
43
+ ## Decision Table
44
+
45
+ | Context | Pattern | Safe? |
46
+ |---------|---------|-------|
47
+ | Top-level `FROM` clause | `${table}` | ✅ Yes |
48
+ | Top-level `WHERE` with parameterized value | `${value}` | ✅ Yes (auto-parameterized) |
49
+ | Top-level `SELECT` column | `${table.column}` | ✅ Yes |
50
+ | Inside aliased subquery `SELECT` | `${table.column}` | ❌ No — bare column name |
51
+ | Inside aliased subquery `WHERE` comparison | `${table.column}` | ❌ No — string literal, not column ref |
52
+ | Inside aliased subquery (fixed) | `alias.column_name` | ✅ Yes |
53
+
54
+ ## Verification
55
+
56
+ Use `.toSQL()` to inspect generated SQL before running:
57
+
58
+ ```typescript
59
+ const query = sql`SELECT ${agentInvocations.errorSummary} as sub_es
60
+ FROM ${agentInvocations} AS ai2
61
+ WHERE ai2.agent_type = ${agentInvocations.agentType}`
62
+
63
+ console.log(query.toSQL())
64
+ // Reveals the bare column names — catches the bug before runtime
65
+ ```
66
+
67
+ ## Key Takeaway
68
+
69
+ > **`${table.column}` in Drizzle's `sql` template generates a bare column identifier, not a qualified reference.** Inside aliased subqueries, this breaks table-qualified comparisons. Always use raw `alias.column_name` strings inside subquery bodies.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.50.0",
2
+ "version": "0.51.1",
3
3
  "lastUpdated": "2026-03-16T00:00:00.000Z",
4
4
  "components": [
5
5
  {
@@ -18,13 +18,13 @@
18
18
  "name": "skills",
19
19
  "path": ".claude/skills",
20
20
  "description": "Reusable skill modules (includes slash commands)",
21
- "files": 90
21
+ "files": 91
22
22
  },
23
23
  {
24
24
  "name": "guides",
25
25
  "path": "guides",
26
26
  "description": "Reference documentation",
27
- "files": 29
27
+ "files": 30
28
28
  },
29
29
  {
30
30
  "name": "hooks",