auto-continue.sh
2.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#!/usr/bin/env bash
# Stop 钩子:让 ERP workflow 在回合中途结束时自动续跑,除非命中「终止标记」或「防循环上限」。
#
# 设计:
# 1. 终止标记 [ERP-HALT] —— 终止/硬护栏 skill(coding-start 全部完成、test-gate 红、
# feature-tdd 路径护栏、interrupt-check 中断)会打印它。出现即放行停下。
# 2. 防循环 —— 连续「无工具调用」的空转停止累加计数;达到上限放行停下。
# 正常推进时由 PostToolUse 的 reset-stall-counter.sh 清零,故真流程不受限。
# 3. 否则 —— block 并喂一句「继续推进」指令,用户无需手敲 continue。
set -u
INPUT="$(cat)"
SENTINEL='[ERP-HALT]'
MAX_STALL=8
# —— 从 stdin JSON 取字段(不依赖 jq)——
get_str() {
printf '%s' "$INPUT" \
| sed -n "s/.*\"$1\"[[:space:]]*:[[:space:]]*\"\([^\"]*\)\".*/\1/p" \
| head -n1
}
TRANSCRIPT="$(get_str transcript_path)"
# 反转义 Windows 路径里的 \\ 与 \/
TRANSCRIPT="${TRANSCRIPT//\\\\//}"
TRANSCRIPT="${TRANSCRIPT//\\//}"
# 计数器文件(按会话 transcript 路径派生 key,避免多会话互相干扰)
KEY="$(printf '%s' "$TRANSCRIPT" | tr -cd 'A-Za-z0-9' | tail -c 40)"
[ -z "$KEY" ] && KEY="default"
CNT_FILE="${TMPDIR:-/tmp}/erp-autocont-$KEY"
SIZE_FILE="${TMPDIR:-/tmp}/erp-autosize-$KEY"
allow_stop() { rm -f "$CNT_FILE" "$SIZE_FILE" 2>/dev/null; exit 0; }
# 1) 终止标记出现在最近的 transcript 尾部 → 放行停下
if [ -n "$TRANSCRIPT" ] && [ -f "$TRANSCRIPT" ]; then
if tail -c 16000 "$TRANSCRIPT" 2>/dev/null | grep -qF "$SENTINEL"; then
allow_stop
fi
fi
# 2) 进展自复位(自包含,不依赖 PostToolUse):transcript 自上次停止以来显著增长
# → 说明这一轮做了实质工作(工具调用 + 结果),清零空转计数。
CUR_SIZE=0
[ -n "$TRANSCRIPT" ] && [ -f "$TRANSCRIPT" ] && CUR_SIZE="$(wc -c < "$TRANSCRIPT" 2>/dev/null | tr -d ' ')"
case "$CUR_SIZE" in (''|*[!0-9]*) CUR_SIZE=0 ;; esac
LAST_SIZE=0
[ -f "$SIZE_FILE" ] && LAST_SIZE="$(cat "$SIZE_FILE" 2>/dev/null || echo 0)"
case "$LAST_SIZE" in (''|*[!0-9]*) LAST_SIZE=0 ;; esac
echo "$CUR_SIZE" > "$SIZE_FILE"
if [ $((CUR_SIZE - LAST_SIZE)) -gt 4000 ]; then
rm -f "$CNT_FILE" 2>/dev/null
fi
# 3) 防循环:连续空转停止达到上限 → 放行停下
CNT=0
[ -f "$CNT_FILE" ] && CNT="$(cat "$CNT_FILE" 2>/dev/null || echo 0)"
case "$CNT" in (''|*[!0-9]*) CNT=0 ;; esac
if [ "$CNT" -ge "$MAX_STALL" ]; then
allow_stop
fi
echo $((CNT + 1)) > "$CNT_FILE"
# 3) 拦下停止 → 续跑
printf '%s' '{"decision":"block","reason":"继续推进 ERP workflow:直接执行流程的下一步——若当前 skill 已结束,立即用 Skill 工具调用对应派发器(A 阶段 plan-start / B 阶段 coding-start)或链中的下一个 skill;不要输出收尾叙述、不要停下等用户输入。只有打印了 [ERP-HALT] 的终止/硬护栏点才应停下。"}'
exit 0