oh-my-customcode 0.153.0 → 0.154.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
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -208,6 +208,16 @@
|
|
|
208
208
|
],
|
|
209
209
|
"description": "Advisory pre-processing of user input \u2014 skill matching hints and intent analysis"
|
|
210
210
|
},
|
|
211
|
+
{
|
|
212
|
+
"matcher": "*",
|
|
213
|
+
"hooks": [
|
|
214
|
+
{
|
|
215
|
+
"type": "command",
|
|
216
|
+
"command": "bash .claude/hooks/scripts/r007-r008-drift-advisor.sh"
|
|
217
|
+
}
|
|
218
|
+
],
|
|
219
|
+
"description": "Proactive R007/R008 drift advisory \u2014 checks last assistant turn for identification omission (#1229)"
|
|
220
|
+
},
|
|
211
221
|
{
|
|
212
222
|
"matcher": "*",
|
|
213
223
|
"hooks": [
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# r007-r008-drift-advisor.sh — UserPromptSubmit hook: PROACTIVE R007/R008 drift advisory (#1229)
|
|
3
|
+
#
|
|
4
|
+
# Inspects the LAST completed assistant turn in the session transcript for R007/R008
|
|
5
|
+
# compliance BEFORE Claude responds. If the previous turn drifted (missing identification
|
|
6
|
+
# header / tool prefix), emits a stderr advisory so the upcoming response self-corrects.
|
|
7
|
+
#
|
|
8
|
+
# This is the PROACTIVE complement to the retroactive session-reflection.sh (Stop hook, #1190).
|
|
9
|
+
# Detection patterns are reused from session-reflection.sh.
|
|
10
|
+
#
|
|
11
|
+
# Advisory-only: ALWAYS exits 0, ALWAYS passes stdin through to stdout, NEVER blocks.
|
|
12
|
+
# Performance: parses ONLY the last assistant turn (not the whole transcript).
|
|
13
|
+
#
|
|
14
|
+
# 환경변수 override (테스트/디버깅용):
|
|
15
|
+
# OMCUSTOM_R007_ADVISOR=off — advisory 완전 비활성화 (pass-through)
|
|
16
|
+
# OMCUSTOM_TRANSCRIPT_BASE — transcript 디렉토리 경로 override
|
|
17
|
+
|
|
18
|
+
set -euo pipefail
|
|
19
|
+
|
|
20
|
+
# ── UserPromptSubmit 프로토콜: stdin을 먼저 읽음 ──
|
|
21
|
+
input=$(cat)
|
|
22
|
+
|
|
23
|
+
# ── Opt-out 체크 ──
|
|
24
|
+
if [ "${OMCUSTOM_R007_ADVISOR:-}" = "off" ]; then
|
|
25
|
+
echo "$input"
|
|
26
|
+
exit 0
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
# ── jq 의존성 체크 ──
|
|
30
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
31
|
+
echo "$input"
|
|
32
|
+
exit 0
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# ── session_id 추출 ──
|
|
36
|
+
session_id=$(echo "$input" | jq -r '.session_id // empty' 2>/dev/null)
|
|
37
|
+
if [ -z "$session_id" ]; then
|
|
38
|
+
echo "$input"
|
|
39
|
+
exit 0
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
# ── 경로 결정 (환경변수 override 지원) ──
|
|
43
|
+
TRANSCRIPT_BASE="${OMCUSTOM_TRANSCRIPT_BASE:-${HOME}/.claude/projects/-Users-sangyi-workspace-projects-oh-my-customcode}"
|
|
44
|
+
TRANSCRIPT_PATH="${TRANSCRIPT_BASE}/${session_id}.jsonl"
|
|
45
|
+
|
|
46
|
+
if [ ! -f "$TRANSCRIPT_PATH" ]; then
|
|
47
|
+
echo "$input"
|
|
48
|
+
exit 0
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
# ── 마지막 assistant 메시지 추출 (성능: 전체 transcript 스캔 회피) ──
|
|
52
|
+
# 파일을 역순으로 읽으며 첫 번째 role=="assistant" 라인을 찾는다.
|
|
53
|
+
last_assistant=""
|
|
54
|
+
while IFS= read -r line; do
|
|
55
|
+
role=$(echo "$line" | jq -r '.role // empty' 2>/dev/null) || continue
|
|
56
|
+
if [ "$role" = "assistant" ]; then
|
|
57
|
+
last_assistant="$line"
|
|
58
|
+
break
|
|
59
|
+
fi
|
|
60
|
+
done < <(tail -r "$TRANSCRIPT_PATH" 2>/dev/null || tac "$TRANSCRIPT_PATH" 2>/dev/null)
|
|
61
|
+
|
|
62
|
+
if [ -z "$last_assistant" ]; then
|
|
63
|
+
echo "$input"
|
|
64
|
+
exit 0
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
# ── content 배열 파싱 ──
|
|
68
|
+
content_raw=$(echo "$last_assistant" | jq -c '.content // []' 2>/dev/null) || content_raw="[]"
|
|
69
|
+
|
|
70
|
+
r007_violations=0
|
|
71
|
+
r008_violations=0
|
|
72
|
+
|
|
73
|
+
# ── R007: 첫 번째 text 블록의 첫 줄 체크 ──
|
|
74
|
+
first_text=$(echo "$content_raw" | jq -r '[.[] | select(.type == "text")][0].text // empty' 2>/dev/null) || first_text=""
|
|
75
|
+
if [ -n "$first_text" ]; then
|
|
76
|
+
first_line=$(printf '%s' "$first_text" | head -1)
|
|
77
|
+
# R007 패턴: '┌─ Agent:' 또는 '[anything]' 단축 형태
|
|
78
|
+
if ! printf '%s' "$first_line" | grep -qE '(^┌─ Agent:|^\[.+\])'; then
|
|
79
|
+
r007_violations=$((r007_violations + 1))
|
|
80
|
+
fi
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
# ── R008: tool_use 블록 직전 text에 prefix 체크 ──
|
|
84
|
+
content_length=$(echo "$content_raw" | jq 'length' 2>/dev/null) || content_length=0
|
|
85
|
+
i=0
|
|
86
|
+
while [ "$i" -lt "$content_length" ]; do
|
|
87
|
+
block_type=$(echo "$content_raw" | jq -r ".[$i].type // empty" 2>/dev/null) || { i=$((i+1)); continue; }
|
|
88
|
+
|
|
89
|
+
if [ "$block_type" = "tool_use" ]; then
|
|
90
|
+
has_prefix=false
|
|
91
|
+
if [ "$i" -gt 0 ]; then
|
|
92
|
+
prev_type=$(echo "$content_raw" | jq -r ".[$(( i - 1 ))].type // empty" 2>/dev/null) || true
|
|
93
|
+
if [ "$prev_type" = "text" ]; then
|
|
94
|
+
prev_text=$(echo "$content_raw" | jq -r ".[$(( i - 1 ))].text // empty" 2>/dev/null) || true
|
|
95
|
+
# R008 패턴: '[agent-name][model] → Tool:' 또는 '→ Target:'
|
|
96
|
+
if printf '%s' "$prev_text" | grep -qE '\[.+\]\[.+\] ?(→|->|—>) ?(Tool|Target):'; then
|
|
97
|
+
has_prefix=true
|
|
98
|
+
fi
|
|
99
|
+
fi
|
|
100
|
+
fi
|
|
101
|
+
if [ "$has_prefix" = "false" ]; then
|
|
102
|
+
r008_violations=$((r008_violations + 1))
|
|
103
|
+
fi
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
i=$((i+1))
|
|
107
|
+
done
|
|
108
|
+
|
|
109
|
+
# ── advisory 출력 (위반 시에만) ──
|
|
110
|
+
if [ "$r007_violations" -gt 0 ] || [ "$r008_violations" -gt 0 ]; then
|
|
111
|
+
printf '[R007/R008 Advisory] 직전 응답에서 식별 누락 감지 (R007 헤더=%d, R008 접두사=%d). 이번 응답은 ┌─ Agent: 헤더로 시작하고, 모든 도구 호출에 [agent][model] → Tool: 접두사를 포함하십시오.\n' \
|
|
112
|
+
"$r007_violations" "$r008_violations" >&2
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
# ── 항상 stdin pass-through 후 exit 0 (advisory는 절대 차단 금지) ──
|
|
116
|
+
echo "$input"
|
|
117
|
+
exit 0
|
package/templates/manifest.json
CHANGED