oh-my-customcode 0.145.0 → 0.147.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/dist/cli/index.js CHANGED
@@ -2334,7 +2334,7 @@ var init_package = __esm(() => {
2334
2334
  workspaces: [
2335
2335
  "packages/*"
2336
2336
  ],
2337
- version: "0.145.0",
2337
+ version: "0.147.0",
2338
2338
  description: "Batteries-included agent harness for Claude Code",
2339
2339
  type: "module",
2340
2340
  bin: {
@@ -2382,7 +2382,7 @@ var init_package = __esm(() => {
2382
2382
  yaml: "^2.8.2"
2383
2383
  },
2384
2384
  devDependencies: {
2385
- "@anthropic-ai/sdk": "^0.95.1",
2385
+ "@anthropic-ai/sdk": "^0.97.1",
2386
2386
  "@biomejs/biome": "^2.3.12",
2387
2387
  "@types/bun": "^1.3.6",
2388
2388
  "@types/js-yaml": "^4.0.9",
package/dist/index.js CHANGED
@@ -2014,7 +2014,7 @@ var package_default = {
2014
2014
  workspaces: [
2015
2015
  "packages/*"
2016
2016
  ],
2017
- version: "0.145.0",
2017
+ version: "0.147.0",
2018
2018
  description: "Batteries-included agent harness for Claude Code",
2019
2019
  type: "module",
2020
2020
  bin: {
@@ -2062,7 +2062,7 @@ var package_default = {
2062
2062
  yaml: "^2.8.2"
2063
2063
  },
2064
2064
  devDependencies: {
2065
- "@anthropic-ai/sdk": "^0.95.1",
2065
+ "@anthropic-ai/sdk": "^0.97.1",
2066
2066
  "@biomejs/biome": "^2.3.12",
2067
2067
  "@types/bun": "^1.3.6",
2068
2068
  "@types/js-yaml": "^4.0.9",
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "workspaces": [
4
4
  "packages/*"
5
5
  ],
6
- "version": "0.145.0",
6
+ "version": "0.147.0",
7
7
  "description": "Batteries-included agent harness for Claude Code",
8
8
  "type": "module",
9
9
  "bin": {
@@ -51,7 +51,7 @@
51
51
  "yaml": "^2.8.2"
52
52
  },
53
53
  "devDependencies": {
54
- "@anthropic-ai/sdk": "^0.95.1",
54
+ "@anthropic-ai/sdk": "^0.97.1",
55
55
  "@biomejs/biome": "^2.3.12",
56
56
  "@types/bun": "^1.3.6",
57
57
  "@types/js-yaml": "^4.0.9",
@@ -546,6 +546,16 @@
546
546
  ],
547
547
  "description": "Auto-extract failure patterns from session outcomes (advisory, exit 0)"
548
548
  },
549
+ {
550
+ "matcher": "*",
551
+ "hooks": [
552
+ {
553
+ "type": "command",
554
+ "command": "bash .claude/hooks/scripts/session-reflection.sh"
555
+ }
556
+ ],
557
+ "description": "Transcript-based self-reflection: detect R007/R008 violations and log to .claude/outputs/reflections/ (Phase 1 MVP, advisory, exit 0)"
558
+ },
549
559
  {
550
560
  "matcher": "*",
551
561
  "hooks": [
@@ -0,0 +1,182 @@
1
+ #!/usr/bin/env bash
2
+ # session-reflection.sh — Stop hook: transcript-based self-reflection for R007/R008 violations
3
+ # Phase 1 MVP: detects header absence (R007) and tool prefix absence (R008)
4
+ # Advisory-only: always exits 0, never blocks session end
5
+ #
6
+ # 환경변수 override (테스트/디버깅용):
7
+ # OMCUSTOM_SESSION_REFLECTION=off — 분석 완전 비활성화
8
+ # OMCUSTOM_TRANSCRIPT_BASE — transcript 디렉토리 경로 override
9
+ # OMCUSTOM_PROJECT_ROOT — 프로젝트 루트 override (.claude/outputs/reflections 기준)
10
+
11
+ set -euo pipefail
12
+
13
+ # ── Stop hook 프로토콜: stdin을 먼저 읽음 ──
14
+ input=$(cat)
15
+
16
+ # ── Opt-out 체크 ──
17
+ if [ "${OMCUSTOM_SESSION_REFLECTION:-}" = "off" ]; then
18
+ echo "$input"
19
+ exit 0
20
+ fi
21
+
22
+ # ── jq 의존성 체크 ──
23
+ if ! command -v jq >/dev/null 2>&1; then
24
+ echo "$input"
25
+ exit 0
26
+ fi
27
+
28
+ # ── session_id 추출 ──
29
+ session_id=$(echo "$input" | jq -r '.session_id // empty' 2>/dev/null)
30
+ if [ -z "$session_id" ]; then
31
+ echo "$input"
32
+ exit 0
33
+ fi
34
+
35
+ # ── 경로 결정 (환경변수 override 지원) ──
36
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
37
+
38
+ # transcript 기본 경로 (OMCUSTOM_TRANSCRIPT_BASE 로 override 가능)
39
+ TRANSCRIPT_BASE="${OMCUSTOM_TRANSCRIPT_BASE:-${HOME}/.claude/projects/-Users-sangyi-workspace-projects-oh-my-customcode}"
40
+ TRANSCRIPT_PATH="${TRANSCRIPT_BASE}/${session_id}.jsonl"
41
+
42
+ if [ ! -f "$TRANSCRIPT_PATH" ]; then
43
+ echo "$input"
44
+ exit 0
45
+ fi
46
+
47
+ # 프로젝트 루트 (OMCUSTOM_PROJECT_ROOT 로 override 가능)
48
+ PROJECT_ROOT="${OMCUSTOM_PROJECT_ROOT:-$(cd "${SCRIPT_DIR}/../../.." && pwd)}"
49
+
50
+ # ── 백그라운드 분석 스크립트를 임시 파일로 생성 ──
51
+ # nohup bash -c "..." 또는 heredoc 방식은 글로브 확장/shell escape/stdin 충돌 문제 발생.
52
+ # 임시 파일 방식은 이 문제를 완전히 회피한다.
53
+ WORKER_SCRIPT="/tmp/.claude-reflection-worker-${PPID}-$$.sh"
54
+
55
+ cat > "$WORKER_SCRIPT" <<'WORKER_EOF'
56
+ #!/usr/bin/env bash
57
+ # Background worker: transcript analysis for R007/R008 violations
58
+
59
+ set -euo pipefail
60
+
61
+ TRANSCRIPT_PATH="$1"
62
+ PROJECT_ROOT="$2"
63
+ SESSION_ID="$3"
64
+ SCRIPT_DIR="$4"
65
+
66
+ # 출력 디렉토리 준비
67
+ OUTPUT_DIR="${PROJECT_ROOT}/.claude/outputs/reflections"
68
+ mkdir -p "${OUTPUT_DIR}"
69
+
70
+ LOG_FILE="${OUTPUT_DIR}/$(date +%Y-%m-%d).md"
71
+ ISO8601="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
72
+
73
+ # ── transcript 파싱 ──
74
+ r007_violations=0
75
+ r008_violations=0
76
+ total_turns=0
77
+ sample_count=0
78
+ sample_lines=""
79
+
80
+ while IFS= read -r line; do
81
+ role=$(echo "$line" | jq -r '.role // empty' 2>/dev/null) || continue
82
+ [ "$role" = "assistant" ] || continue
83
+
84
+ total_turns=$((total_turns + 1))
85
+ turn_idx=$total_turns
86
+
87
+ # content 배열 파싱
88
+ content_raw=$(echo "$line" | jq -c '.content // []' 2>/dev/null) || continue
89
+
90
+ # ── R007: 첫 번째 text 블록의 첫 줄 체크 ──
91
+ first_text=$(echo "$content_raw" | jq -r '[.[] | select(.type == "text")][0].text // empty' 2>/dev/null) || true
92
+ if [ -n "$first_text" ]; then
93
+ first_line=$(printf '%s' "$first_text" | head -1)
94
+ # R007 패턴: '┌─ Agent:' 또는 '[anything]' 단축 형태
95
+ if ! printf '%s' "$first_line" | grep -qE '(^┌─ Agent:|^\[.+\])'; then
96
+ r007_violations=$((r007_violations + 1))
97
+ if [ $sample_count -lt 3 ]; then
98
+ # 120자 truncate (secret-filter.sh는 PostToolUse용이라 여기서는 단순 truncate)
99
+ safe_text=$(printf '%s' "$first_line" | head -c 120)
100
+ sample_lines="${sample_lines}
101
+ - [R007 turn ${turn_idx}]: ${safe_text}"
102
+ sample_count=$((sample_count + 1))
103
+ fi
104
+ fi
105
+ fi
106
+
107
+ # ── R008: tool_use 블록 직전 text에 prefix 체크 ──
108
+ content_length=$(echo "$content_raw" | jq 'length' 2>/dev/null) || continue
109
+
110
+ i=0
111
+ while [ $i -lt "$content_length" ]; do
112
+ block_type=$(echo "$content_raw" | jq -r ".[$i].type // empty" 2>/dev/null) || { i=$((i+1)); continue; }
113
+
114
+ if [ "$block_type" = "tool_use" ]; then
115
+ tool_name=$(echo "$content_raw" | jq -r ".[$i].name // empty" 2>/dev/null) || true
116
+
117
+ # 직전 블록이 text이고 R008 prefix를 포함하는지 체크
118
+ has_prefix=false
119
+ if [ $i -gt 0 ]; then
120
+ prev_type=$(echo "$content_raw" | jq -r ".[$(( i - 1 ))].type // empty" 2>/dev/null) || true
121
+ if [ "$prev_type" = "text" ]; then
122
+ prev_text=$(echo "$content_raw" | jq -r ".[$(( i - 1 ))].text // empty" 2>/dev/null) || true
123
+ # R008 패턴: '[agent-name][model] → Tool:' 또는 '→ Target:'
124
+ if printf '%s' "$prev_text" | grep -qE '\[.+\]\[.+\] ?(→|->|—>) ?(Tool|Target):'; then
125
+ has_prefix=true
126
+ fi
127
+ fi
128
+ fi
129
+
130
+ if [ "$has_prefix" = "false" ]; then
131
+ r008_violations=$((r008_violations + 1))
132
+ if [ $sample_count -lt 3 ]; then
133
+ sample_lines="${sample_lines}
134
+ - [R008 turn ${turn_idx}]: ${tool_name}, missing prefix"
135
+ sample_count=$((sample_count + 1))
136
+ fi
137
+ fi
138
+ fi
139
+
140
+ i=$((i+1))
141
+ done
142
+
143
+ done < "$TRANSCRIPT_PATH"
144
+
145
+ # ── 로그 작성 ──
146
+ {
147
+ echo ""
148
+ echo "## Session ${SESSION_ID} — ${ISO8601}"
149
+ echo ""
150
+ echo "- **R007 violations**: ${r007_violations}"
151
+ echo "- **R008 violations**: ${r008_violations}"
152
+ echo "- Total assistant turns analyzed: ${total_turns}"
153
+ if [ $sample_count -gt 0 ]; then
154
+ echo ""
155
+ echo "### Sample violations (최대 3개)"
156
+ printf '%s\n' "${sample_lines}"
157
+ fi
158
+ } >> "${LOG_FILE}"
159
+
160
+ echo "[session-reflection] Analysis complete: R007=${r007_violations} R008=${r008_violations} turns=${total_turns}" >&2
161
+ WORKER_EOF
162
+
163
+ chmod +x "$WORKER_SCRIPT"
164
+
165
+ # ── 백그라운드로 실행 (Stop hook 시간 예산 <3s 준수) ──
166
+ # setsid로 부모 종료 후에도 실행 지속; 완료 후 임시 파일 자정리
167
+ WORKER_ERR_LOG="/tmp/.claude-reflection-err-${PPID}.log"
168
+
169
+ (
170
+ bash "$WORKER_SCRIPT" \
171
+ "$TRANSCRIPT_PATH" \
172
+ "$PROJECT_ROOT" \
173
+ "$session_id" \
174
+ "$SCRIPT_DIR" \
175
+ 2>>"$WORKER_ERR_LOG"
176
+ rm -f "$WORKER_SCRIPT"
177
+ ) &
178
+ disown $! 2>/dev/null || true
179
+
180
+ # ── 즉시 stdin pass-through 후 exit 0 (Stop hook 체인 유지) ──
181
+ echo "$input"
182
+ exit 0
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "0.145.0",
3
- "lastUpdated": "2026-05-18T00:00:00.000Z",
2
+ "version": "0.147.0",
3
+ "lastUpdated": "2026-05-20T00:00:00.000Z",
4
4
  "omcustomMinClaudeCode": "2.1.121",
5
5
  "omcustomMinClaudeCodeReason": "Sensitive-path direct Write/Edit on .claude/** under bypassPermissions (R010 deprecation, #1101)",
6
6
  "components": [