@winspan/claude-forge 8.25.3 → 8.26.3

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.
@@ -1,82 +0,0 @@
1
- #!/usr/bin/env bash
2
- # 检查当前 session 的 context token 使用量,接近限制时发出预警
3
-
4
- WARN_THRESHOLD="${CONTEXT_WARN_THRESHOLD:-150000}"
5
- ALERT_THRESHOLD="${CONTEXT_ALERT_THRESHOLD:-180000}"
6
-
7
- # 从 stdin 读取 hook 输入,提取 session_id 和 cwd(jq 替代 python3)
8
- INPUT=$(cat)
9
- SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // ""')
10
- CWD=$(echo "$INPUT" | jq -r '.cwd // ""')
11
-
12
- # 定位 session 文件
13
- find_session_file() {
14
- local session_id="$1"
15
- local cwd="$2"
16
-
17
- if [ -n "$cwd" ]; then
18
- local sanitized
19
- sanitized=$(echo "$cwd" | sed 's|/|-|g')
20
- local project_dir="$HOME/.claude/projects/${sanitized}"
21
- if [ -n "$session_id" ] && [ -f "$project_dir/${session_id}.jsonl" ]; then
22
- echo "$project_dir/${session_id}.jsonl"
23
- return
24
- fi
25
- local latest
26
- latest=$(ls -t "$project_dir"/*.jsonl 2>/dev/null | head -1)
27
- [ -n "$latest" ] && echo "$latest"
28
- fi
29
- }
30
-
31
- SESSION_FILE=$(find_session_file "$SESSION_ID" "$CWD")
32
-
33
- if [ -z "$SESSION_FILE" ] || [ ! -f "$SESSION_FILE" ]; then
34
- exit 0
35
- fi
36
-
37
- # 只扫描最后 200 行(token 用量只会增大,最新的 assistant 消息在末尾)
38
- # 避免随 session 增长的全文件 O(n) 扫描
39
- CONTEXT_TOKENS=$(tail -200 "$SESSION_FILE" | jq -r '
40
- select(.type == "assistant" and .message.usage != null)
41
- | (.message.usage.input_tokens // 0)
42
- + (.message.usage.cache_read_input_tokens // 0)
43
- + (.message.usage.cache_creation_input_tokens // 0)
44
- ' 2>/dev/null | awk 'BEGIN{max=0} {if($1+0>max) max=$1+0} END{print max}')
45
-
46
- CONTEXT_TOKENS="${CONTEXT_TOKENS:-0}"
47
-
48
- # 冷却机制:同一会话 60 秒内只触发一次告警,避免每次 PostToolUse 重复输出
49
- COOLDOWN_SECS="${CONTEXT_ALERT_COOLDOWN:-60}"
50
- ALERT_FLAG_DIR="${TMPDIR:-/tmp}/claude-forge-ctx"
51
- mkdir -p "$ALERT_FLAG_DIR"
52
- ALERT_FLAG="$ALERT_FLAG_DIR/${SESSION_ID}.alert"
53
-
54
- is_in_cooldown() {
55
- [ -f "$ALERT_FLAG" ] || return 1
56
- local last_alert
57
- last_alert=$(cat "$ALERT_FLAG" 2>/dev/null)
58
- local now
59
- now=$(date +%s)
60
- [ -n "$last_alert" ] && [ $((now - last_alert)) -lt "$COOLDOWN_SECS" ]
61
- }
62
-
63
- if [ "$CONTEXT_TOKENS" -ge "$ALERT_THRESHOLD" ] 2>/dev/null; then
64
- if ! is_in_cooldown; then
65
- date +%s > "$ALERT_FLAG"
66
- # 告急:注入强制指令,要求 Claude 立即提醒用户执行 /compact
67
- echo "{\"systemMessage\": \"⚠️ [Forge 紧急] Context 已用 ${CONTEXT_TOKENS} tokens(阈值 ${ALERT_THRESHOLD}),即将触及上限。请在回复的第一行用醒目格式提醒用户立即输入 /compact 压缩上下文,否则后续对话可能丢失信息。回复内容尽量精简。\"}"
68
- fi
69
-
70
- elif [ "$CONTEXT_TOKENS" -ge "$WARN_THRESHOLD" ] 2>/dev/null; then
71
- if ! is_in_cooldown; then
72
- date +%s > "$ALERT_FLAG"
73
- # 预警:在命令行输出提示(stderr → 终端可见,不影响 Claude Code 响应)
74
- echo "⚠️ Context 预警:已用 ${CONTEXT_TOKENS} tokens,建议执行 /compact" >&2
75
- fi
76
- exit 0
77
- else
78
- # 低于预警阈值时清除冷却标记,允许下次超限时重新告警
79
- rm -f "$ALERT_FLAG"
80
- fi
81
-
82
- exit 0