@hivehub/rulebook 5.5.1 → 5.5.2
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/core/claude-settings-manager.d.ts.map +1 -1
- package/dist/core/claude-settings-manager.js +9 -3
- package/dist/core/claude-settings-manager.js.map +1 -1
- package/dist/core/ralph-scripts.d.ts.map +1 -1
- package/dist/core/ralph-scripts.js +7 -6
- package/dist/core/ralph-scripts.js.map +1 -1
- package/dist/utils/file-system.d.ts +22 -0
- package/dist/utils/file-system.d.ts.map +1 -1
- package/dist/utils/file-system.js +31 -0
- package/dist/utils/file-system.js.map +1 -1
- package/dist/utils/git-hooks.d.ts.map +1 -1
- package/dist/utils/git-hooks.js +3 -2
- package/dist/utils/git-hooks.js.map +1 -1
- package/package.json +2 -1
- package/templates/hooks/check-context-and-handoff.sh +76 -76
- package/templates/hooks/enforce-team-for-background-agents.sh +55 -55
- package/templates/hooks/on-compact-reinject.sh +34 -34
- package/templates/hooks/resume-from-handoff.sh +61 -61
- package/templates/hooks/terse-activate.sh +197 -197
- package/templates/hooks/terse-mode-tracker.sh +187 -187
- package/templates/ralph/ralph-history.sh +5 -5
- package/templates/ralph/ralph-init.sh +5 -5
- package/templates/ralph/ralph-pause.sh +5 -5
- package/templates/ralph/ralph-run.sh +5 -5
- package/templates/ralph/ralph-status.sh +5 -5
- package/templates/skills/workflows/ralph/install.sh +87 -87
|
@@ -1,187 +1,187 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# Claude Code UserPromptSubmit hook for rulebook-terse (v5.4.0).
|
|
3
|
-
#
|
|
4
|
-
# Parses slash commands + natural-language activation/deactivation
|
|
5
|
-
# phrases in the user prompt, updates the project-local flag file,
|
|
6
|
-
# and emits a short (~45 token) attention anchor as hookSpecificOutput
|
|
7
|
-
# when a persistent mode is active — keeps the compression register in
|
|
8
|
-
# the model's attention on every user message.
|
|
9
|
-
#
|
|
10
|
-
# Independent sub-skill modes (commit / review) do NOT get the anchor:
|
|
11
|
-
# their own SKILL.md files drive behavior for the single turn they're
|
|
12
|
-
# invoked.
|
|
13
|
-
#
|
|
14
|
-
# Silent-fails on every filesystem error.
|
|
15
|
-
|
|
16
|
-
set -u
|
|
17
|
-
|
|
18
|
-
input="$(cat || true)"
|
|
19
|
-
prompt=""
|
|
20
|
-
cwd=""
|
|
21
|
-
if [ -n "$input" ]; then
|
|
22
|
-
# Parse JSON via node (always available in Claude Code hook env).
|
|
23
|
-
# Emits two lines: prompt on line 1, cwd on line 2.
|
|
24
|
-
parsed="$(printf '%s' "$input" | node -e "
|
|
25
|
-
try {
|
|
26
|
-
const data = JSON.parse(require('fs').readFileSync(0, 'utf8'));
|
|
27
|
-
process.stdout.write((data.prompt || '') + '\\n' + (data.cwd || ''));
|
|
28
|
-
} catch { process.stdout.write('\\n'); }
|
|
29
|
-
" 2>/dev/null || printf '\n')"
|
|
30
|
-
prompt="$(printf '%s' "$parsed" | head -n 1)"
|
|
31
|
-
cwd="$(printf '%s' "$parsed" | tail -n +2)"
|
|
32
|
-
fi
|
|
33
|
-
|
|
34
|
-
PROJECT_ROOT="${cwd:-${CLAUDE_PROJECT_DIR:-$(pwd)}}"
|
|
35
|
-
FLAG_PATH="${PROJECT_ROOT}/.rulebook/.terse-mode"
|
|
36
|
-
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/rulebook"
|
|
37
|
-
USER_CONFIG="${CONFIG_DIR}/config.json"
|
|
38
|
-
PROJECT_CONFIG="${PROJECT_ROOT}/.rulebook/rulebook.json"
|
|
39
|
-
|
|
40
|
-
VALID_MODES_RE='^(off|brief|terse|ultra|commit|review)$'
|
|
41
|
-
MAX_FLAG_BYTES=32
|
|
42
|
-
|
|
43
|
-
resolve_default_mode() {
|
|
44
|
-
if [ -n "${RULEBOOK_TERSE_MODE:-}" ]; then
|
|
45
|
-
local m="$(printf '%s' "$RULEBOOK_TERSE_MODE" | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]')"
|
|
46
|
-
if [[ "$m" =~ $VALID_MODES_RE ]]; then printf '%s' "$m"; return; fi
|
|
47
|
-
fi
|
|
48
|
-
if [ -f "$PROJECT_CONFIG" ]; then
|
|
49
|
-
local m
|
|
50
|
-
m="$(node -e "
|
|
51
|
-
try {
|
|
52
|
-
const cfg = JSON.parse(require('fs').readFileSync(process.argv[1], 'utf8'));
|
|
53
|
-
if (cfg.terse && cfg.terse.defaultMode) process.stdout.write(String(cfg.terse.defaultMode));
|
|
54
|
-
} catch { }
|
|
55
|
-
" "$PROJECT_CONFIG" 2>/dev/null | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]' || true)"
|
|
56
|
-
if [ -n "$m" ] && [[ "$m" =~ $VALID_MODES_RE ]]; then printf '%s' "$m"; return; fi
|
|
57
|
-
fi
|
|
58
|
-
if [ -f "$USER_CONFIG" ]; then
|
|
59
|
-
local m
|
|
60
|
-
m="$(node -e "
|
|
61
|
-
try {
|
|
62
|
-
const cfg = JSON.parse(require('fs').readFileSync(process.argv[1], 'utf8'));
|
|
63
|
-
if (cfg.terse && cfg.terse.defaultMode) process.stdout.write(String(cfg.terse.defaultMode));
|
|
64
|
-
} catch { }
|
|
65
|
-
" "$USER_CONFIG" 2>/dev/null | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]' || true)"
|
|
66
|
-
if [ -n "$m" ] && [[ "$m" =~ $VALID_MODES_RE ]]; then printf '%s' "$m"; return; fi
|
|
67
|
-
fi
|
|
68
|
-
printf 'terse'
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
safe_write_flag() {
|
|
72
|
-
local content="$1"
|
|
73
|
-
local dir
|
|
74
|
-
dir="$(dirname "$FLAG_PATH")"
|
|
75
|
-
mkdir -p "$dir" 2>/dev/null || return 0
|
|
76
|
-
[ -L "$dir" ] && return 0
|
|
77
|
-
[ -L "$FLAG_PATH" ] && return 0
|
|
78
|
-
|
|
79
|
-
local tmp
|
|
80
|
-
tmp="$(mktemp "$dir/.terse-mode.XXXXXX" 2>/dev/null)" || return 0
|
|
81
|
-
{
|
|
82
|
-
umask 077
|
|
83
|
-
printf '%s' "$content" > "$tmp" 2>/dev/null || { rm -f "$tmp"; return 0; }
|
|
84
|
-
}
|
|
85
|
-
chmod 600 "$tmp" 2>/dev/null || true
|
|
86
|
-
mv -f "$tmp" "$FLAG_PATH" 2>/dev/null || rm -f "$tmp"
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
read_flag() {
|
|
90
|
-
# Symlink-safe, size-capped, whitelist-validated read.
|
|
91
|
-
[ ! -f "$FLAG_PATH" ] && return 1
|
|
92
|
-
[ -L "$FLAG_PATH" ] && return 1
|
|
93
|
-
local size
|
|
94
|
-
size="$(wc -c < "$FLAG_PATH" 2>/dev/null || echo "$MAX_FLAG_BYTES")"
|
|
95
|
-
[ "$size" -gt "$MAX_FLAG_BYTES" ] && return 1
|
|
96
|
-
|
|
97
|
-
local raw
|
|
98
|
-
raw="$(head -c "$MAX_FLAG_BYTES" "$FLAG_PATH" 2>/dev/null | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]')"
|
|
99
|
-
if [[ "$raw" =~ $VALID_MODES_RE ]]; then
|
|
100
|
-
printf '%s' "$raw"
|
|
101
|
-
return 0
|
|
102
|
-
fi
|
|
103
|
-
return 1
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
default_mode="$(resolve_default_mode)"
|
|
107
|
-
lower_prompt="$(printf '%s' "$prompt" | tr '[:upper:]' '[:lower:]')"
|
|
108
|
-
|
|
109
|
-
# Parse intent. Order matters: deactivation wins over accidental
|
|
110
|
-
# activation, slash commands win over natural-language patterns.
|
|
111
|
-
new_mode=""
|
|
112
|
-
deactivate=0
|
|
113
|
-
|
|
114
|
-
# Slash commands
|
|
115
|
-
if [[ "$lower_prompt" == /rulebook-terse-commit* ]]; then
|
|
116
|
-
new_mode="commit"
|
|
117
|
-
elif [[ "$lower_prompt" == /rulebook-terse-review* ]]; then
|
|
118
|
-
new_mode="review"
|
|
119
|
-
elif [[ "$lower_prompt" == /rulebook-terse ]]; then
|
|
120
|
-
new_mode="$default_mode"
|
|
121
|
-
elif [[ "$lower_prompt" == /rulebook-terse\ * ]]; then
|
|
122
|
-
arg="$(printf '%s' "$lower_prompt" | awk '{print $2}')"
|
|
123
|
-
case "$arg" in
|
|
124
|
-
off) deactivate=1 ;;
|
|
125
|
-
brief|terse|ultra|commit|review) new_mode="$arg" ;;
|
|
126
|
-
*) : ;; # unknown subcommand → leave state unchanged
|
|
127
|
-
esac
|
|
128
|
-
fi
|
|
129
|
-
|
|
130
|
-
# Natural-language deactivation — checked first so "stop terse" wins.
|
|
131
|
-
if [ -z "$new_mode" ] && [ "$deactivate" -eq 0 ]; then
|
|
132
|
-
if echo "$prompt" | grep -qiE '\b(stop|disable|turn off|deactivate)\b.*\brulebook[- ]?terse\b' \
|
|
133
|
-
|| echo "$prompt" | grep -qiE '\brulebook[- ]?terse\b.*\b(stop|disable|turn off|deactivate)\b' \
|
|
134
|
-
|| echo "$prompt" | grep -qiE '\b(stop|disable) terse\b' \
|
|
135
|
-
|| echo "$prompt" | grep -qiE '\bnormal mode\b'; then
|
|
136
|
-
deactivate=1
|
|
137
|
-
fi
|
|
138
|
-
fi
|
|
139
|
-
|
|
140
|
-
# Natural-language activation
|
|
141
|
-
if [ -z "$new_mode" ] && [ "$deactivate" -eq 0 ]; then
|
|
142
|
-
if echo "$prompt" | grep -qiE '\b(activate|enable|turn on|start)\b.*\brulebook[- ]?terse\b' \
|
|
143
|
-
|| echo "$prompt" | grep -qiE '\brulebook[- ]?terse\b.*\b(mode|activate|enable|turn on|start)\b' \
|
|
144
|
-
|| echo "$prompt" | grep -qiE '\bbe terse\b' \
|
|
145
|
-
|| echo "$prompt" | grep -qiE '\bterse mode\b' \
|
|
146
|
-
|| echo "$prompt" | grep -qiE '\bless tokens?\b'; then
|
|
147
|
-
new_mode="$default_mode"
|
|
148
|
-
fi
|
|
149
|
-
fi
|
|
150
|
-
|
|
151
|
-
# Apply intent
|
|
152
|
-
if [ "$deactivate" -eq 1 ]; then
|
|
153
|
-
rm -f "$FLAG_PATH" 2>/dev/null || true
|
|
154
|
-
elif [ -n "$new_mode" ]; then
|
|
155
|
-
if [ "$new_mode" = "off" ]; then
|
|
156
|
-
rm -f "$FLAG_PATH" 2>/dev/null || true
|
|
157
|
-
else
|
|
158
|
-
safe_write_flag "$new_mode"
|
|
159
|
-
fi
|
|
160
|
-
fi
|
|
161
|
-
|
|
162
|
-
# Emit attention anchor for persistent modes only.
|
|
163
|
-
active_mode="$(read_flag || true)"
|
|
164
|
-
case "$active_mode" in
|
|
165
|
-
brief|terse|ultra)
|
|
166
|
-
if [ "$active_mode" = "brief" ]; then
|
|
167
|
-
keep_clause="Keep articles and full sentences."
|
|
168
|
-
else
|
|
169
|
-
keep_clause="Fragments OK."
|
|
170
|
-
fi
|
|
171
|
-
text="RULEBOOK-TERSE ACTIVE (${active_mode}). Drop filler/hedging/pleasantries. ${keep_clause} Code/tests/commits/security: write full. Quality-gate failures + destructive ops: write full."
|
|
172
|
-
# Emit hookSpecificOutput JSON via node — universal across platforms.
|
|
173
|
-
node -e "
|
|
174
|
-
const text = process.argv[1];
|
|
175
|
-
process.stdout.write(JSON.stringify({
|
|
176
|
-
hookSpecificOutput: {
|
|
177
|
-
hookEventName: 'UserPromptSubmit',
|
|
178
|
-
additionalContext: text
|
|
179
|
-
}
|
|
180
|
-
}));
|
|
181
|
-
" "$text" 2>/dev/null || true
|
|
182
|
-
;;
|
|
183
|
-
*)
|
|
184
|
-
# No active persistent mode, or commit/review sub-skill — no anchor.
|
|
185
|
-
:
|
|
186
|
-
;;
|
|
187
|
-
esac
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Claude Code UserPromptSubmit hook for rulebook-terse (v5.4.0).
|
|
3
|
+
#
|
|
4
|
+
# Parses slash commands + natural-language activation/deactivation
|
|
5
|
+
# phrases in the user prompt, updates the project-local flag file,
|
|
6
|
+
# and emits a short (~45 token) attention anchor as hookSpecificOutput
|
|
7
|
+
# when a persistent mode is active — keeps the compression register in
|
|
8
|
+
# the model's attention on every user message.
|
|
9
|
+
#
|
|
10
|
+
# Independent sub-skill modes (commit / review) do NOT get the anchor:
|
|
11
|
+
# their own SKILL.md files drive behavior for the single turn they're
|
|
12
|
+
# invoked.
|
|
13
|
+
#
|
|
14
|
+
# Silent-fails on every filesystem error.
|
|
15
|
+
|
|
16
|
+
set -u
|
|
17
|
+
|
|
18
|
+
input="$(cat || true)"
|
|
19
|
+
prompt=""
|
|
20
|
+
cwd=""
|
|
21
|
+
if [ -n "$input" ]; then
|
|
22
|
+
# Parse JSON via node (always available in Claude Code hook env).
|
|
23
|
+
# Emits two lines: prompt on line 1, cwd on line 2.
|
|
24
|
+
parsed="$(printf '%s' "$input" | node -e "
|
|
25
|
+
try {
|
|
26
|
+
const data = JSON.parse(require('fs').readFileSync(0, 'utf8'));
|
|
27
|
+
process.stdout.write((data.prompt || '') + '\\n' + (data.cwd || ''));
|
|
28
|
+
} catch { process.stdout.write('\\n'); }
|
|
29
|
+
" 2>/dev/null || printf '\n')"
|
|
30
|
+
prompt="$(printf '%s' "$parsed" | head -n 1)"
|
|
31
|
+
cwd="$(printf '%s' "$parsed" | tail -n +2)"
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
PROJECT_ROOT="${cwd:-${CLAUDE_PROJECT_DIR:-$(pwd)}}"
|
|
35
|
+
FLAG_PATH="${PROJECT_ROOT}/.rulebook/.terse-mode"
|
|
36
|
+
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/rulebook"
|
|
37
|
+
USER_CONFIG="${CONFIG_DIR}/config.json"
|
|
38
|
+
PROJECT_CONFIG="${PROJECT_ROOT}/.rulebook/rulebook.json"
|
|
39
|
+
|
|
40
|
+
VALID_MODES_RE='^(off|brief|terse|ultra|commit|review)$'
|
|
41
|
+
MAX_FLAG_BYTES=32
|
|
42
|
+
|
|
43
|
+
resolve_default_mode() {
|
|
44
|
+
if [ -n "${RULEBOOK_TERSE_MODE:-}" ]; then
|
|
45
|
+
local m="$(printf '%s' "$RULEBOOK_TERSE_MODE" | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]')"
|
|
46
|
+
if [[ "$m" =~ $VALID_MODES_RE ]]; then printf '%s' "$m"; return; fi
|
|
47
|
+
fi
|
|
48
|
+
if [ -f "$PROJECT_CONFIG" ]; then
|
|
49
|
+
local m
|
|
50
|
+
m="$(node -e "
|
|
51
|
+
try {
|
|
52
|
+
const cfg = JSON.parse(require('fs').readFileSync(process.argv[1], 'utf8'));
|
|
53
|
+
if (cfg.terse && cfg.terse.defaultMode) process.stdout.write(String(cfg.terse.defaultMode));
|
|
54
|
+
} catch { }
|
|
55
|
+
" "$PROJECT_CONFIG" 2>/dev/null | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]' || true)"
|
|
56
|
+
if [ -n "$m" ] && [[ "$m" =~ $VALID_MODES_RE ]]; then printf '%s' "$m"; return; fi
|
|
57
|
+
fi
|
|
58
|
+
if [ -f "$USER_CONFIG" ]; then
|
|
59
|
+
local m
|
|
60
|
+
m="$(node -e "
|
|
61
|
+
try {
|
|
62
|
+
const cfg = JSON.parse(require('fs').readFileSync(process.argv[1], 'utf8'));
|
|
63
|
+
if (cfg.terse && cfg.terse.defaultMode) process.stdout.write(String(cfg.terse.defaultMode));
|
|
64
|
+
} catch { }
|
|
65
|
+
" "$USER_CONFIG" 2>/dev/null | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]' || true)"
|
|
66
|
+
if [ -n "$m" ] && [[ "$m" =~ $VALID_MODES_RE ]]; then printf '%s' "$m"; return; fi
|
|
67
|
+
fi
|
|
68
|
+
printf 'terse'
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
safe_write_flag() {
|
|
72
|
+
local content="$1"
|
|
73
|
+
local dir
|
|
74
|
+
dir="$(dirname "$FLAG_PATH")"
|
|
75
|
+
mkdir -p "$dir" 2>/dev/null || return 0
|
|
76
|
+
[ -L "$dir" ] && return 0
|
|
77
|
+
[ -L "$FLAG_PATH" ] && return 0
|
|
78
|
+
|
|
79
|
+
local tmp
|
|
80
|
+
tmp="$(mktemp "$dir/.terse-mode.XXXXXX" 2>/dev/null)" || return 0
|
|
81
|
+
{
|
|
82
|
+
umask 077
|
|
83
|
+
printf '%s' "$content" > "$tmp" 2>/dev/null || { rm -f "$tmp"; return 0; }
|
|
84
|
+
}
|
|
85
|
+
chmod 600 "$tmp" 2>/dev/null || true
|
|
86
|
+
mv -f "$tmp" "$FLAG_PATH" 2>/dev/null || rm -f "$tmp"
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
read_flag() {
|
|
90
|
+
# Symlink-safe, size-capped, whitelist-validated read.
|
|
91
|
+
[ ! -f "$FLAG_PATH" ] && return 1
|
|
92
|
+
[ -L "$FLAG_PATH" ] && return 1
|
|
93
|
+
local size
|
|
94
|
+
size="$(wc -c < "$FLAG_PATH" 2>/dev/null || echo "$MAX_FLAG_BYTES")"
|
|
95
|
+
[ "$size" -gt "$MAX_FLAG_BYTES" ] && return 1
|
|
96
|
+
|
|
97
|
+
local raw
|
|
98
|
+
raw="$(head -c "$MAX_FLAG_BYTES" "$FLAG_PATH" 2>/dev/null | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]')"
|
|
99
|
+
if [[ "$raw" =~ $VALID_MODES_RE ]]; then
|
|
100
|
+
printf '%s' "$raw"
|
|
101
|
+
return 0
|
|
102
|
+
fi
|
|
103
|
+
return 1
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
default_mode="$(resolve_default_mode)"
|
|
107
|
+
lower_prompt="$(printf '%s' "$prompt" | tr '[:upper:]' '[:lower:]')"
|
|
108
|
+
|
|
109
|
+
# Parse intent. Order matters: deactivation wins over accidental
|
|
110
|
+
# activation, slash commands win over natural-language patterns.
|
|
111
|
+
new_mode=""
|
|
112
|
+
deactivate=0
|
|
113
|
+
|
|
114
|
+
# Slash commands
|
|
115
|
+
if [[ "$lower_prompt" == /rulebook-terse-commit* ]]; then
|
|
116
|
+
new_mode="commit"
|
|
117
|
+
elif [[ "$lower_prompt" == /rulebook-terse-review* ]]; then
|
|
118
|
+
new_mode="review"
|
|
119
|
+
elif [[ "$lower_prompt" == /rulebook-terse ]]; then
|
|
120
|
+
new_mode="$default_mode"
|
|
121
|
+
elif [[ "$lower_prompt" == /rulebook-terse\ * ]]; then
|
|
122
|
+
arg="$(printf '%s' "$lower_prompt" | awk '{print $2}')"
|
|
123
|
+
case "$arg" in
|
|
124
|
+
off) deactivate=1 ;;
|
|
125
|
+
brief|terse|ultra|commit|review) new_mode="$arg" ;;
|
|
126
|
+
*) : ;; # unknown subcommand → leave state unchanged
|
|
127
|
+
esac
|
|
128
|
+
fi
|
|
129
|
+
|
|
130
|
+
# Natural-language deactivation — checked first so "stop terse" wins.
|
|
131
|
+
if [ -z "$new_mode" ] && [ "$deactivate" -eq 0 ]; then
|
|
132
|
+
if echo "$prompt" | grep -qiE '\b(stop|disable|turn off|deactivate)\b.*\brulebook[- ]?terse\b' \
|
|
133
|
+
|| echo "$prompt" | grep -qiE '\brulebook[- ]?terse\b.*\b(stop|disable|turn off|deactivate)\b' \
|
|
134
|
+
|| echo "$prompt" | grep -qiE '\b(stop|disable) terse\b' \
|
|
135
|
+
|| echo "$prompt" | grep -qiE '\bnormal mode\b'; then
|
|
136
|
+
deactivate=1
|
|
137
|
+
fi
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
# Natural-language activation
|
|
141
|
+
if [ -z "$new_mode" ] && [ "$deactivate" -eq 0 ]; then
|
|
142
|
+
if echo "$prompt" | grep -qiE '\b(activate|enable|turn on|start)\b.*\brulebook[- ]?terse\b' \
|
|
143
|
+
|| echo "$prompt" | grep -qiE '\brulebook[- ]?terse\b.*\b(mode|activate|enable|turn on|start)\b' \
|
|
144
|
+
|| echo "$prompt" | grep -qiE '\bbe terse\b' \
|
|
145
|
+
|| echo "$prompt" | grep -qiE '\bterse mode\b' \
|
|
146
|
+
|| echo "$prompt" | grep -qiE '\bless tokens?\b'; then
|
|
147
|
+
new_mode="$default_mode"
|
|
148
|
+
fi
|
|
149
|
+
fi
|
|
150
|
+
|
|
151
|
+
# Apply intent
|
|
152
|
+
if [ "$deactivate" -eq 1 ]; then
|
|
153
|
+
rm -f "$FLAG_PATH" 2>/dev/null || true
|
|
154
|
+
elif [ -n "$new_mode" ]; then
|
|
155
|
+
if [ "$new_mode" = "off" ]; then
|
|
156
|
+
rm -f "$FLAG_PATH" 2>/dev/null || true
|
|
157
|
+
else
|
|
158
|
+
safe_write_flag "$new_mode"
|
|
159
|
+
fi
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
# Emit attention anchor for persistent modes only.
|
|
163
|
+
active_mode="$(read_flag || true)"
|
|
164
|
+
case "$active_mode" in
|
|
165
|
+
brief|terse|ultra)
|
|
166
|
+
if [ "$active_mode" = "brief" ]; then
|
|
167
|
+
keep_clause="Keep articles and full sentences."
|
|
168
|
+
else
|
|
169
|
+
keep_clause="Fragments OK."
|
|
170
|
+
fi
|
|
171
|
+
text="RULEBOOK-TERSE ACTIVE (${active_mode}). Drop filler/hedging/pleasantries. ${keep_clause} Code/tests/commits/security: write full. Quality-gate failures + destructive ops: write full."
|
|
172
|
+
# Emit hookSpecificOutput JSON via node — universal across platforms.
|
|
173
|
+
node -e "
|
|
174
|
+
const text = process.argv[1];
|
|
175
|
+
process.stdout.write(JSON.stringify({
|
|
176
|
+
hookSpecificOutput: {
|
|
177
|
+
hookEventName: 'UserPromptSubmit',
|
|
178
|
+
additionalContext: text
|
|
179
|
+
}
|
|
180
|
+
}));
|
|
181
|
+
" "$text" 2>/dev/null || true
|
|
182
|
+
;;
|
|
183
|
+
*)
|
|
184
|
+
# No active persistent mode, or commit/review sub-skill — no anchor.
|
|
185
|
+
:
|
|
186
|
+
;;
|
|
187
|
+
esac
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
# Ralph History — View iteration history
|
|
3
|
-
# Generated by @hivehub/rulebook
|
|
4
|
-
echo "Loading Ralph history..."
|
|
5
|
-
npx @hivehub/rulebook@latest ralph history "$@"
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Ralph History — View iteration history
|
|
3
|
+
# Generated by @hivehub/rulebook
|
|
4
|
+
echo "Loading Ralph history..."
|
|
5
|
+
npx @hivehub/rulebook@latest ralph history "$@"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
# Ralph Init — Initialize autonomous loop
|
|
3
|
-
# Generated by @hivehub/rulebook
|
|
4
|
-
echo "Initializing Ralph autonomous loop..."
|
|
5
|
-
npx @hivehub/rulebook@latest ralph init "$@"
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Ralph Init — Initialize autonomous loop
|
|
3
|
+
# Generated by @hivehub/rulebook
|
|
4
|
+
echo "Initializing Ralph autonomous loop..."
|
|
5
|
+
npx @hivehub/rulebook@latest ralph init "$@"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
# Ralph Pause — Pause autonomous loop
|
|
3
|
-
# Generated by @hivehub/rulebook
|
|
4
|
-
echo "Pausing Ralph autonomous loop..."
|
|
5
|
-
npx @hivehub/rulebook@latest ralph pause "$@"
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Ralph Pause — Pause autonomous loop
|
|
3
|
+
# Generated by @hivehub/rulebook
|
|
4
|
+
echo "Pausing Ralph autonomous loop..."
|
|
5
|
+
npx @hivehub/rulebook@latest ralph pause "$@"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
# Ralph Run — Start autonomous loop
|
|
3
|
-
# Generated by @hivehub/rulebook
|
|
4
|
-
echo "Starting Ralph autonomous loop..."
|
|
5
|
-
npx @hivehub/rulebook@latest ralph run "$@"
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Ralph Run — Start autonomous loop
|
|
3
|
+
# Generated by @hivehub/rulebook
|
|
4
|
+
echo "Starting Ralph autonomous loop..."
|
|
5
|
+
npx @hivehub/rulebook@latest ralph run "$@"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
# Ralph Status — Check loop status
|
|
3
|
-
# Generated by @hivehub/rulebook
|
|
4
|
-
echo "Checking Ralph status..."
|
|
5
|
-
npx @hivehub/rulebook@latest ralph status "$@"
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Ralph Status — Check loop status
|
|
3
|
+
# Generated by @hivehub/rulebook
|
|
4
|
+
echo "Checking Ralph status..."
|
|
5
|
+
npx @hivehub/rulebook@latest ralph status "$@"
|
|
@@ -1,87 +1,87 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Ralph Autonomous Loop Skill Installation
|
|
3
|
-
# This script is executed when users run: rulebook init or rulebook skill enable ralph
|
|
4
|
-
|
|
5
|
-
set -e
|
|
6
|
-
|
|
7
|
-
echo "🔧 Installing Ralph Autonomous Loop Skill..."
|
|
8
|
-
|
|
9
|
-
# Check if rulebook is installed
|
|
10
|
-
if ! command -v rulebook &> /dev/null; then
|
|
11
|
-
echo "❌ Error: @hivehub/rulebook not found"
|
|
12
|
-
echo " Install with: npm install -g @hivehub/rulebook"
|
|
13
|
-
exit 1
|
|
14
|
-
fi
|
|
15
|
-
|
|
16
|
-
# Check if .rulebook config exists
|
|
17
|
-
if [ ! -f ".rulebook" ]; then
|
|
18
|
-
echo "❌ Error: .rulebook config not found"
|
|
19
|
-
echo " Run: rulebook init"
|
|
20
|
-
exit 1
|
|
21
|
-
fi
|
|
22
|
-
|
|
23
|
-
# Enable Ralph in .rulebook config
|
|
24
|
-
echo "📝 Enabling Ralph in .rulebook..."
|
|
25
|
-
if grep -q '"ralph"' .rulebook; then
|
|
26
|
-
# Ralph section exists, update enabled flag
|
|
27
|
-
sed -i.bak 's/"enabled": false/"enabled": true/g' .rulebook && rm -f .rulebook.bak
|
|
28
|
-
else
|
|
29
|
-
# Add Ralph section to config
|
|
30
|
-
# Insert before closing }
|
|
31
|
-
sed -i.bak '$ s/}/,\n "ralph": {\n "enabled": true,\n "maxIterations": 10,\n "tool": "claude",\n "maxContextLoss": 3\n }\n}/' .rulebook && rm -f .rulebook.bak
|
|
32
|
-
fi
|
|
33
|
-
|
|
34
|
-
# Create Ralph directories
|
|
35
|
-
echo "📁 Creating Ralph directories..."
|
|
36
|
-
mkdir -p .rulebook-ralph/history
|
|
37
|
-
|
|
38
|
-
# Create initial PRD if tasks exist
|
|
39
|
-
if [ -d ".rulebook/tasks" ] && [ "$(ls -A .rulebook/tasks)" ]; then
|
|
40
|
-
echo "📋 Generating PRD from existing tasks..."
|
|
41
|
-
rulebook ralph init || echo "⚠️ Could not auto-generate PRD. Run: rulebook ralph init"
|
|
42
|
-
else
|
|
43
|
-
echo "💡 No tasks found. Create tasks first: rulebook task create <task-id>"
|
|
44
|
-
fi
|
|
45
|
-
|
|
46
|
-
# Create .cursorrules entry for Ralph if working with Claude Code
|
|
47
|
-
if [ -f ".cursorrules" ]; then
|
|
48
|
-
echo "🔗 Updating .cursorrules for Ralph..."
|
|
49
|
-
cat >> .cursorrules << 'EOF'
|
|
50
|
-
|
|
51
|
-
## Ralph Autonomous Loop
|
|
52
|
-
|
|
53
|
-
When working with Ralph autonomous loop:
|
|
54
|
-
|
|
55
|
-
1. **Before each iteration**:
|
|
56
|
-
- Read .rulebook-ralph/prd.json for task specifications
|
|
57
|
-
- Read .rulebook-ralph/progress.txt for past learnings
|
|
58
|
-
- Reference recent git commits for architectural context
|
|
59
|
-
|
|
60
|
-
2. **During implementation**:
|
|
61
|
-
- Focus on ONE task from PRD
|
|
62
|
-
- Apply patterns from progress.txt
|
|
63
|
-
- Write tests first (95%+ coverage required)
|
|
64
|
-
|
|
65
|
-
3. **After implementation**:
|
|
66
|
-
- Run quality gates: type-check, lint, tests, coverage
|
|
67
|
-
- Commit with clear message including iteration number
|
|
68
|
-
- Ralph will update progress.txt with learnings
|
|
69
|
-
|
|
70
|
-
4. **Commands**:
|
|
71
|
-
- Check status: rulebook ralph status
|
|
72
|
-
- View history: rulebook ralph history
|
|
73
|
-
- Pause loop: rulebook ralph pause (Ctrl+C)
|
|
74
|
-
- Resume: rulebook ralph resume
|
|
75
|
-
EOF
|
|
76
|
-
fi
|
|
77
|
-
|
|
78
|
-
echo ""
|
|
79
|
-
echo "✅ Ralph Autonomous Loop Skill Installed!"
|
|
80
|
-
echo ""
|
|
81
|
-
echo "📖 Next steps:"
|
|
82
|
-
echo " 1. Create tasks: rulebook task create <task-id>"
|
|
83
|
-
echo " 2. Initialize Ralph: rulebook ralph init"
|
|
84
|
-
echo " 3. Start loop: rulebook ralph run [--max-iterations N] [--tool claude]"
|
|
85
|
-
echo " 4. Monitor: rulebook ralph status"
|
|
86
|
-
echo ""
|
|
87
|
-
echo "📚 For more info: rulebook ralph --help"
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Ralph Autonomous Loop Skill Installation
|
|
3
|
+
# This script is executed when users run: rulebook init or rulebook skill enable ralph
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
echo "🔧 Installing Ralph Autonomous Loop Skill..."
|
|
8
|
+
|
|
9
|
+
# Check if rulebook is installed
|
|
10
|
+
if ! command -v rulebook &> /dev/null; then
|
|
11
|
+
echo "❌ Error: @hivehub/rulebook not found"
|
|
12
|
+
echo " Install with: npm install -g @hivehub/rulebook"
|
|
13
|
+
exit 1
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
# Check if .rulebook config exists
|
|
17
|
+
if [ ! -f ".rulebook" ]; then
|
|
18
|
+
echo "❌ Error: .rulebook config not found"
|
|
19
|
+
echo " Run: rulebook init"
|
|
20
|
+
exit 1
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
# Enable Ralph in .rulebook config
|
|
24
|
+
echo "📝 Enabling Ralph in .rulebook..."
|
|
25
|
+
if grep -q '"ralph"' .rulebook; then
|
|
26
|
+
# Ralph section exists, update enabled flag
|
|
27
|
+
sed -i.bak 's/"enabled": false/"enabled": true/g' .rulebook && rm -f .rulebook.bak
|
|
28
|
+
else
|
|
29
|
+
# Add Ralph section to config
|
|
30
|
+
# Insert before closing }
|
|
31
|
+
sed -i.bak '$ s/}/,\n "ralph": {\n "enabled": true,\n "maxIterations": 10,\n "tool": "claude",\n "maxContextLoss": 3\n }\n}/' .rulebook && rm -f .rulebook.bak
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# Create Ralph directories
|
|
35
|
+
echo "📁 Creating Ralph directories..."
|
|
36
|
+
mkdir -p .rulebook-ralph/history
|
|
37
|
+
|
|
38
|
+
# Create initial PRD if tasks exist
|
|
39
|
+
if [ -d ".rulebook/tasks" ] && [ "$(ls -A .rulebook/tasks)" ]; then
|
|
40
|
+
echo "📋 Generating PRD from existing tasks..."
|
|
41
|
+
rulebook ralph init || echo "⚠️ Could not auto-generate PRD. Run: rulebook ralph init"
|
|
42
|
+
else
|
|
43
|
+
echo "💡 No tasks found. Create tasks first: rulebook task create <task-id>"
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
# Create .cursorrules entry for Ralph if working with Claude Code
|
|
47
|
+
if [ -f ".cursorrules" ]; then
|
|
48
|
+
echo "🔗 Updating .cursorrules for Ralph..."
|
|
49
|
+
cat >> .cursorrules << 'EOF'
|
|
50
|
+
|
|
51
|
+
## Ralph Autonomous Loop
|
|
52
|
+
|
|
53
|
+
When working with Ralph autonomous loop:
|
|
54
|
+
|
|
55
|
+
1. **Before each iteration**:
|
|
56
|
+
- Read .rulebook-ralph/prd.json for task specifications
|
|
57
|
+
- Read .rulebook-ralph/progress.txt for past learnings
|
|
58
|
+
- Reference recent git commits for architectural context
|
|
59
|
+
|
|
60
|
+
2. **During implementation**:
|
|
61
|
+
- Focus on ONE task from PRD
|
|
62
|
+
- Apply patterns from progress.txt
|
|
63
|
+
- Write tests first (95%+ coverage required)
|
|
64
|
+
|
|
65
|
+
3. **After implementation**:
|
|
66
|
+
- Run quality gates: type-check, lint, tests, coverage
|
|
67
|
+
- Commit with clear message including iteration number
|
|
68
|
+
- Ralph will update progress.txt with learnings
|
|
69
|
+
|
|
70
|
+
4. **Commands**:
|
|
71
|
+
- Check status: rulebook ralph status
|
|
72
|
+
- View history: rulebook ralph history
|
|
73
|
+
- Pause loop: rulebook ralph pause (Ctrl+C)
|
|
74
|
+
- Resume: rulebook ralph resume
|
|
75
|
+
EOF
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
echo ""
|
|
79
|
+
echo "✅ Ralph Autonomous Loop Skill Installed!"
|
|
80
|
+
echo ""
|
|
81
|
+
echo "📖 Next steps:"
|
|
82
|
+
echo " 1. Create tasks: rulebook task create <task-id>"
|
|
83
|
+
echo " 2. Initialize Ralph: rulebook ralph init"
|
|
84
|
+
echo " 3. Start loop: rulebook ralph run [--max-iterations N] [--tool claude]"
|
|
85
|
+
echo " 4. Monitor: rulebook ralph status"
|
|
86
|
+
echo ""
|
|
87
|
+
echo "📚 For more info: rulebook ralph --help"
|