@hivehub/rulebook 5.5.0 → 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.
@@ -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"