Skip to content

Commit 6ef0fd7

Browse files
authored
Add status command, validation script, troubleshooting guide, and CI/CD (#2)
- Add /ralph:status command to check loop state - Add validation script to verify prerequisites - Support --flag=value argument format in setup.sh - Add TROUBLESHOOTING.md guide for common issues - Add GitHub Actions workflow for automated testing - Add status command tests - Add version bump utility script - Enhance help command with examples - Update README with new features and validation steps
1 parent a2af076 commit 6ef0fd7

10 files changed

Lines changed: 340 additions & 0 deletions

File tree

.github/workflows/test.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Test Ralph Extension
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Install dependencies
17+
run: |
18+
sudo apt-get update
19+
sudo apt-get install -y jq
20+
21+
- name: Make scripts executable
22+
run: |
23+
chmod +x scripts/*.sh
24+
chmod +x hooks/*.sh
25+
chmod +x tests/*.sh
26+
27+
- name: Run setup tests
28+
run: bash tests/setup_test.sh
29+
30+
- name: Run hook tests
31+
run: bash tests/hook_test.sh
32+
33+
- name: Run status tests
34+
run: bash tests/status_test.sh
35+
36+
- name: Validate scripts
37+
run: |
38+
bash -n scripts/setup.sh
39+
bash -n scripts/cancel.sh
40+
bash -n scripts/status.sh
41+
bash -n scripts/validate.sh
42+
bash -n hooks/stop-hook.sh

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ Install the extension directly from GitHub:
2828
gemini extensions install https://github.com/gemini-cli-extensions/ralph --auto-update
2929
```
3030

31+
### Verify Installation
32+
33+
After installing, validate your setup:
34+
35+
```bash
36+
bash ~/.gemini/extensions/ralph/scripts/validate.sh
37+
```
38+
3139
## Configuration
3240

3341
To use Ralph, you must enable hooks and preview features in your `~/.gemini/settings.json`:
@@ -60,6 +68,7 @@ Start a loop by using the `/ralph:loop` command followed by your task.
6068

6169
### Manual Controls
6270

71+
- `/ralph:status`: Check the current status of an active loop.
6372
- `/ralph:cancel`: Stops an active loop and cleans up all state files.
6473
- `/ralph:help`: Displays detailed usage information and configuration tips.
6574

TROUBLESHOOTING.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Troubleshooting Ralph
2+
3+
## Common Issues
4+
5+
### Loop Won't Start
6+
7+
**Symptom**: Running `/ralph:loop` doesn't start the loop.
8+
9+
**Solutions**:
10+
1. Verify hooks are enabled in `~/.gemini/settings.json`:
11+
```json
12+
{
13+
"hooksConfig": {
14+
"enabled": true
15+
}
16+
}
17+
```
18+
19+
2. Check that the extension directory is included:
20+
```json
21+
{
22+
"context": {
23+
"includeDirectories": ["~/.gemini/extensions/ralph"]
24+
}
25+
}
26+
```
27+
28+
3. Ensure `jq` is installed: `brew install jq`
29+
30+
### Loop Won't Stop
31+
32+
**Symptom**: Loop continues even after completion promise is output.
33+
34+
**Solutions**:
35+
1. Verify the promise format is exact: `<promise>YOUR_TEXT</promise>`
36+
2. Check the state file: `cat .gemini/ralph/state.json`
37+
3. Manually cancel: `/ralph:cancel`
38+
39+
### Ghost Loop
40+
41+
**Symptom**: Old loop interferes with new tasks.
42+
43+
**Solution**: The hook should auto-detect this, but you can manually clean up:
44+
```bash
45+
rm -rf .gemini/ralph
46+
```
47+
48+
### Permission Errors
49+
50+
**Symptom**: Scripts fail with permission denied.
51+
52+
**Solution**: Make scripts executable:
53+
```bash
54+
chmod +x ~/.gemini/extensions/ralph/scripts/*.sh
55+
chmod +x ~/.gemini/extensions/ralph/hooks/*.sh
56+
```
57+
58+
## Debugging
59+
60+
### Check Loop Status
61+
```bash
62+
/ralph:status
63+
```
64+
65+
### View State File
66+
```bash
67+
cat .gemini/ralph/state.json | jq
68+
```
69+
70+
### Enable Debug Logging
71+
Add to your prompt:
72+
```
73+
Before each action, output the current iteration number and your plan.
74+
```
75+
76+
## Getting Help
77+
78+
If you encounter issues not covered here:
79+
1. Check the [README](README.md) for configuration details
80+
2. Review test files in `tests/` for expected behavior
81+
3. Open an issue on GitHub with:
82+
- Your `~/.gemini/settings.json` (redact sensitive info)
83+
- The command you ran
84+
- Contents of `.gemini/ralph/state.json` (if exists)
85+
- Error messages

commands/ralph/help.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,26 @@ Display the Ralph help documentation. Do NOT use any other subagent for this. Es
44
55
Summarize the available commands for the user:
66
- `/ralph:loop <PROMPT> [OPTIONS]`: Start a Ralph loop.
7+
- `/ralph:status`: Check the current status of an active loop.
78
- `/ralph:cancel`: Cancel an active Ralph loop and clean up all temporary files.
89
- `/ralph:help`: Show this message.
910
1011
**Options:**
1112
- `--max-iterations <N>`: Stop after N iterations (default: 5).
1213
- `--completion-promise <TEXT>`: Only stop when the agent outputs `<promise>TEXT</promise>`.
14+
15+
**Examples:**
16+
```bash
17+
# Basic loop with iteration limit
18+
/ralph:loop "Build a REST API" --max-iterations 10
19+
20+
# Loop with completion promise
21+
/ralph:loop "Fix all linting errors" --completion-promise "ALL_CLEAN"
22+
23+
# Combined options
24+
/ralph:loop "Implement feature X" --max-iterations 15 --completion-promise "FEATURE_COMPLETE"
25+
```
26+
27+
**Troubleshooting:**
28+
For common issues and solutions, see TROUBLESHOOTING.md in the extension directory.
1329
"""

commands/ralph/status.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
description = "Check the status of the current Ralph loop."
2+
prompt = """
3+
You are checking the Ralph loop status.
4+
5+
Run the status script to display the current loop state:
6+
```bash
7+
bash "${extensionPath}/scripts/status.sh"
8+
```
9+
"""

scripts/bump-version.sh

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/bin/bash
2+
# Copyright 2026 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# https://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
# Bump version in gemini-extension.json
17+
18+
if [[ $# -ne 1 ]]; then
19+
echo "Usage: $0 <new_version>"
20+
echo "Example: $0 1.1.0"
21+
exit 1
22+
fi
23+
24+
NEW_VERSION="$1"
25+
26+
if [[ ! "$NEW_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
27+
echo "Error: Version must be in format X.Y.Z"
28+
exit 1
29+
fi
30+
31+
jq --arg version "$NEW_VERSION" '.version = $version' gemini-extension.json > gemini-extension.json.tmp
32+
mv gemini-extension.json.tmp gemini-extension.json
33+
34+
echo "✅ Version bumped to $NEW_VERSION"

scripts/setup.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,23 @@ fi
4141
# Parse arguments
4242
while [[ $# -gt 0 ]]; do
4343
case "$1" in
44+
--max-iterations=*)
45+
VALUE="${1#*=}"
46+
[[ "$VALUE" =~ ^[0-9]+$ ]] || die "Invalid iteration limit: '$VALUE'"
47+
MAX_ITERATIONS="$VALUE"
48+
shift
49+
;;
4450
--max-iterations)
4551
[[ "${2:-}" =~ ^[0-9]+$ ]] || die "Invalid iteration limit: '${2:-}'"
4652
MAX_ITERATIONS="$2"
4753
shift 2
4854
;;
55+
--completion-promise=*)
56+
VALUE="${1#*=}"
57+
[[ -n "$VALUE" ]] || die "Missing promise text."
58+
COMPLETION_PROMISE="$VALUE"
59+
shift
60+
;;
4961
--completion-promise)
5062
[[ -n "${2:-}" ]] || die "Missing promise text."
5163
COMPLETION_PROMISE="$2"

scripts/status.sh

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/bin/bash
2+
# Copyright 2026 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# https://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
STATE_FILE=".gemini/ralph/state.json"
17+
18+
if [[ ! -f "$STATE_FILE" ]]; then
19+
echo "Ralph: I'm not doing anything right now!" >&2
20+
exit 0
21+
fi
22+
23+
echo "🔄 Ralph Loop Status" >&2
24+
echo "===================" >&2
25+
echo "" >&2
26+
27+
ACTIVE=$(jq -r '.active' "$STATE_FILE")
28+
CURRENT=$(jq -r '.current_iteration' "$STATE_FILE")
29+
MAX=$(jq -r '.max_iterations' "$STATE_FILE")
30+
PROMISE=$(jq -r '.completion_promise' "$STATE_FILE")
31+
PROMPT=$(jq -r '.original_prompt' "$STATE_FILE")
32+
STARTED=$(jq -r '.started_at' "$STATE_FILE")
33+
34+
echo "Status: $([ "$ACTIVE" = "true" ] && echo "🟢 Active" || echo "🔴 Inactive")" >&2
35+
echo "Iteration: $CURRENT / $MAX" >&2
36+
echo "Started: $STARTED" >&2
37+
echo "Task: $PROMPT" >&2
38+
39+
if [[ -n "$PROMISE" ]]; then
40+
echo "Completion Promise: $PROMISE" >&2
41+
fi
42+
43+
echo "" >&2

scripts/validate.sh

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/bin/bash
2+
# Copyright 2026 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# https://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
# Validate Ralph prerequisites
17+
18+
echo "🔍 Validating Ralph prerequisites..."
19+
20+
# Check for jq
21+
if ! command -v jq &> /dev/null; then
22+
echo "❌ Error: jq is not installed. Install it with: brew install jq"
23+
exit 1
24+
fi
25+
26+
# Check for bash version (need 4.0+)
27+
if [[ "${BASH_VERSINFO[0]}" -lt 4 ]]; then
28+
echo "⚠️ Warning: Bash version ${BASH_VERSION} detected. Bash 4.0+ recommended."
29+
fi
30+
31+
# Check hooks configuration
32+
SETTINGS_FILE="$HOME/.gemini/settings.json"
33+
if [[ -f "$SETTINGS_FILE" ]]; then
34+
HOOKS_ENABLED=$(jq -r '.hooksConfig.enabled // false' "$SETTINGS_FILE")
35+
if [[ "$HOOKS_ENABLED" != "true" ]]; then
36+
echo "⚠️ Warning: Hooks are not enabled in ~/.gemini/settings.json"
37+
echo " Add: \"hooksConfig\": { \"enabled\": true }"
38+
fi
39+
else
40+
echo "⚠️ Warning: ~/.gemini/settings.json not found"
41+
fi
42+
43+
echo "✅ Validation complete!"

tests/status_test.sh

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/bin/bash
2+
# Copyright 2026 Google LLC
3+
# Licensed under the Apache License, Version 2.0
4+
5+
STATE_FILE=".gemini/ralph/state.json"
6+
STATE_DIR=".gemini/ralph"
7+
STATUS_SCRIPT="./scripts/status.sh"
8+
9+
setup() {
10+
mkdir -p "$STATE_DIR"
11+
}
12+
13+
cleanup() {
14+
rm -f "$STATE_FILE"
15+
if [[ -d "$STATE_DIR" ]]; then
16+
rmdir "$STATE_DIR" 2>/dev/null || true
17+
fi
18+
}
19+
20+
trap cleanup EXIT
21+
22+
echo "Running Test 1: No active loop..."
23+
setup
24+
OUTPUT=$("$STATUS_SCRIPT" 2>&1)
25+
if [[ "$OUTPUT" != *"not doing anything"* ]]; then
26+
echo "FAIL: Expected 'not doing anything' message"
27+
exit 1
28+
fi
29+
30+
echo "Running Test 2: Active loop status..."
31+
setup
32+
jq -n '{
33+
active: true,
34+
current_iteration: 3,
35+
max_iterations: 10,
36+
completion_promise: "DONE",
37+
original_prompt: "Test task",
38+
started_at: "2026-01-27T12:00:00Z"
39+
}' > "$STATE_FILE"
40+
41+
OUTPUT=$("$STATUS_SCRIPT" 2>&1)
42+
if [[ "$OUTPUT" != *"Active"* ]] || [[ "$OUTPUT" != *"3 / 10"* ]]; then
43+
echo "FAIL: Expected active status with iteration count"
44+
exit 1
45+
fi
46+
47+
echo "PASS: All tests passed!"

0 commit comments

Comments
 (0)