fix(import): address code review feedback
- Fix check_claude_version() to use numeric semantic version comparison - Fix detect_response_format() to read first non-whitespace character - Wire PARSED_RESULT into success message output - Wire PARSED_FILES_CREATED into file verification logic - Add --allowedTools flag to CLI invocation using CLAUDE_ALLOWED_TOOLS - Separate stderr to avoid corrupting JSON output file - Clean up stderr file on completion and error - Update README.md version badges to v0.9.8 and 276 tests - Update roadmap section with current test coverage breakdown
This commit is contained in:
parent
4b1ca9bcc7
commit
6dde9cbd26
2 changed files with 89 additions and 35 deletions
21
README.md
21
README.md
|
|
@ -1,8 +1,8 @@
|
||||||
# Ralph for Claude Code
|
# Ralph for Claude Code
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
[](https://github.com/hesreallyhim/awesome-claude-code)
|
[](https://github.com/hesreallyhim/awesome-claude-code)
|
||||||
[](https://x.com/FrankBria18044)
|
[](https://x.com/FrankBria18044)
|
||||||
|
|
@ -15,9 +15,9 @@ Ralph is an implementation of the Geoffrey Huntley's technique for Claude Code t
|
||||||
|
|
||||||
## Project Status
|
## Project Status
|
||||||
|
|
||||||
**Version**: v0.9.3 - Active Development
|
**Version**: v0.9.8 - Active Development
|
||||||
**Core Features**: Working and tested
|
**Core Features**: Working and tested
|
||||||
**Test Coverage**: 165 tests, 100% pass rate
|
**Test Coverage**: 276 tests, 100% pass rate
|
||||||
|
|
||||||
### What's Working Now
|
### What's Working Now
|
||||||
- Autonomous development loops with intelligent exit detection
|
- Autonomous development loops with intelligent exit detection
|
||||||
|
|
@ -609,24 +609,25 @@ tmux attach -t <name> # Reattach to detached session
|
||||||
|
|
||||||
Ralph is under active development with a clear path to v1.0.0. See [IMPLEMENTATION_PLAN.md](IMPLEMENTATION_PLAN.md) for the complete roadmap.
|
Ralph is under active development with a clear path to v1.0.0. See [IMPLEMENTATION_PLAN.md](IMPLEMENTATION_PLAN.md) for the complete roadmap.
|
||||||
|
|
||||||
### Current Status: v0.9.3
|
### Current Status: v0.9.8
|
||||||
|
|
||||||
**What's Delivered:**
|
**What's Delivered:**
|
||||||
- Core loop functionality with intelligent exit detection
|
- Core loop functionality with intelligent exit detection
|
||||||
- Rate limiting (100 calls/hour) and circuit breaker pattern
|
- Rate limiting (100 calls/hour) and circuit breaker pattern
|
||||||
- Response analyzer with semantic understanding
|
- Response analyzer with semantic understanding
|
||||||
- 165 comprehensive tests (100% pass rate)
|
- 276 comprehensive tests (100% pass rate)
|
||||||
- tmux integration and live monitoring
|
- tmux integration and live monitoring
|
||||||
- PRD import functionality
|
- PRD import functionality with modern CLI JSON parsing
|
||||||
- Installation system and project templates
|
- Installation system and project templates
|
||||||
- Modern CLI commands with JSON output support
|
- Modern CLI commands with JSON output support
|
||||||
- CI/CD pipeline with GitHub Actions
|
- CI/CD pipeline with GitHub Actions
|
||||||
- Comprehensive installation test suite
|
- Comprehensive installation test suite
|
||||||
|
- Session lifecycle management with auto-reset triggers
|
||||||
|
|
||||||
**Test Coverage Breakdown:**
|
**Test Coverage Breakdown:**
|
||||||
- Unit Tests: 111 (CLI parsing, JSON, exit detection, rate limiting)
|
- Unit Tests: 154 (CLI parsing, JSON, exit detection, rate limiting, session continuity)
|
||||||
- Integration Tests: 54 (loop execution, edge cases, installation)
|
- Integration Tests: 122 (loop execution, edge cases, installation, project setup, PRD import)
|
||||||
- Test Files: 8
|
- Test Files: 11
|
||||||
|
|
||||||
### Path to v1.0.0 (~4 weeks)
|
### Path to v1.0.0 (~4 weeks)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,8 @@ detect_response_format() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if file starts with { or [ (JSON indicators)
|
# Check if file starts with { or [ (JSON indicators)
|
||||||
local first_char=$(head -c 1 "$output_file" 2>/dev/null | tr -d '[:space:]')
|
# Use grep to find first non-whitespace character (handles leading whitespace)
|
||||||
|
local first_char=$(grep -m1 -o '[^[:space:]]' "$output_file" 2>/dev/null)
|
||||||
|
|
||||||
if [[ "$first_char" != "{" && "$first_char" != "[" ]]; then
|
if [[ "$first_char" != "{" && "$first_char" != "[" ]]; then
|
||||||
echo "text"
|
echo "text"
|
||||||
|
|
@ -125,6 +126,7 @@ parse_conversion_response() {
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check Claude Code CLI version for modern features
|
# Check Claude Code CLI version for modern features
|
||||||
|
# Uses numeric comparison for proper semantic versioning
|
||||||
check_claude_version() {
|
check_claude_version() {
|
||||||
local version
|
local version
|
||||||
version=$($CLAUDE_CODE_CMD --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
|
version=$($CLAUDE_CODE_CMD --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
|
||||||
|
|
@ -134,9 +136,32 @@ check_claude_version() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Simple version comparison (assumes semantic versioning)
|
# Numeric semantic version comparison
|
||||||
# For production use, consider a more robust version comparison
|
# Split versions into major.minor.patch components
|
||||||
if [[ "$version" < "$CLAUDE_MIN_VERSION" ]]; then
|
local ver_major ver_minor ver_patch
|
||||||
|
local min_major min_minor min_patch
|
||||||
|
|
||||||
|
IFS='.' read -r ver_major ver_minor ver_patch <<< "$version"
|
||||||
|
IFS='.' read -r min_major min_minor min_patch <<< "$CLAUDE_MIN_VERSION"
|
||||||
|
|
||||||
|
# Compare major version
|
||||||
|
if [[ $ver_major -lt $min_major ]]; then
|
||||||
|
log "WARN" "Claude Code CLI version $version is below recommended $CLAUDE_MIN_VERSION"
|
||||||
|
return 1
|
||||||
|
elif [[ $ver_major -gt $min_major ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Major equal, compare minor version
|
||||||
|
if [[ $ver_minor -lt $min_minor ]]; then
|
||||||
|
log "WARN" "Claude Code CLI version $version is below recommended $CLAUDE_MIN_VERSION"
|
||||||
|
return 1
|
||||||
|
elif [[ $ver_minor -gt $min_minor ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Minor equal, compare patch version
|
||||||
|
if [[ $ver_patch -lt $min_patch ]]; then
|
||||||
log "WARN" "Claude Code CLI version $version is below recommended $CLAUDE_MIN_VERSION"
|
log "WARN" "Claude Code CLI version $version is below recommended $CLAUDE_MIN_VERSION"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
@ -314,23 +339,31 @@ PROMPTEOF
|
||||||
# Build and execute Claude Code command
|
# Build and execute Claude Code command
|
||||||
# Modern CLI: Use --output-format json and --allowedTools for structured output
|
# Modern CLI: Use --output-format json and --allowedTools for structured output
|
||||||
# Fallback: Standard CLI invocation for older versions
|
# Fallback: Standard CLI invocation for older versions
|
||||||
|
# Note: stderr is written to separate file to avoid corrupting JSON output
|
||||||
|
local stderr_file="${CONVERSION_OUTPUT_FILE}.err"
|
||||||
|
|
||||||
if [[ "$use_modern_cli" == "true" ]]; then
|
if [[ "$use_modern_cli" == "true" ]]; then
|
||||||
# Modern CLI invocation with JSON output and controlled tool permissions
|
# Modern CLI invocation with JSON output and controlled tool permissions
|
||||||
# Note: --allowedTools permits file operations without user prompts
|
# --allowedTools permits file operations without user prompts
|
||||||
if $CLAUDE_CODE_CMD --output-format "$CLAUDE_OUTPUT_FORMAT" < "$CONVERSION_PROMPT_FILE" > "$CONVERSION_OUTPUT_FILE" 2>&1; then
|
if $CLAUDE_CODE_CMD --output-format "$CLAUDE_OUTPUT_FORMAT" --allowedTools $CLAUDE_ALLOWED_TOOLS < "$CONVERSION_PROMPT_FILE" > "$CONVERSION_OUTPUT_FILE" 2> "$stderr_file"; then
|
||||||
cli_exit_code=0
|
cli_exit_code=0
|
||||||
else
|
else
|
||||||
cli_exit_code=$?
|
cli_exit_code=$?
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# Standard CLI invocation (backward compatible)
|
# Standard CLI invocation (backward compatible)
|
||||||
if $CLAUDE_CODE_CMD < "$CONVERSION_PROMPT_FILE" > "$CONVERSION_OUTPUT_FILE" 2>&1; then
|
if $CLAUDE_CODE_CMD < "$CONVERSION_PROMPT_FILE" > "$CONVERSION_OUTPUT_FILE" 2> "$stderr_file"; then
|
||||||
cli_exit_code=0
|
cli_exit_code=0
|
||||||
else
|
else
|
||||||
cli_exit_code=$?
|
cli_exit_code=$?
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Log stderr if there was any (for debugging)
|
||||||
|
if [[ -s "$stderr_file" ]]; then
|
||||||
|
log "WARN" "CLI stderr output detected (see $stderr_file)"
|
||||||
|
fi
|
||||||
|
|
||||||
# Process the response
|
# Process the response
|
||||||
local output_format="text"
|
local output_format="text"
|
||||||
local json_parsed=false
|
local json_parsed=false
|
||||||
|
|
@ -372,36 +405,56 @@ PROMPTEOF
|
||||||
# Check CLI exit code
|
# Check CLI exit code
|
||||||
if [[ $cli_exit_code -ne 0 ]]; then
|
if [[ $cli_exit_code -ne 0 ]]; then
|
||||||
log "ERROR" "PRD conversion failed (exit code: $cli_exit_code)"
|
log "ERROR" "PRD conversion failed (exit code: $cli_exit_code)"
|
||||||
rm -f "$CONVERSION_PROMPT_FILE" "$CONVERSION_OUTPUT_FILE"
|
rm -f "$CONVERSION_PROMPT_FILE" "$CONVERSION_OUTPUT_FILE" "$stderr_file"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Use PARSED_RESULT for success message if available
|
||||||
|
if [[ "$json_parsed" == "true" && -n "$PARSED_RESULT" && "$PARSED_RESULT" != "null" ]]; then
|
||||||
|
log "SUCCESS" "PRD conversion completed: $PARSED_RESULT"
|
||||||
|
else
|
||||||
log "SUCCESS" "PRD conversion completed"
|
log "SUCCESS" "PRD conversion completed"
|
||||||
|
fi
|
||||||
|
|
||||||
# Clean up temp files
|
# Clean up temp files
|
||||||
rm -f "$CONVERSION_PROMPT_FILE" "$CONVERSION_OUTPUT_FILE"
|
rm -f "$CONVERSION_PROMPT_FILE" "$CONVERSION_OUTPUT_FILE" "$stderr_file"
|
||||||
|
|
||||||
# Verify files were created
|
# Verify files were created
|
||||||
|
# Use PARSED_FILES_CREATED from JSON if available, otherwise check filesystem
|
||||||
local missing_files=()
|
local missing_files=()
|
||||||
local created_files=()
|
local created_files=()
|
||||||
|
local expected_files=("PROMPT.md" "@fix_plan.md" "specs/requirements.md")
|
||||||
|
|
||||||
if [[ -f "PROMPT.md" ]]; then
|
# If JSON provided files_created, use that to inform verification
|
||||||
created_files+=("PROMPT.md")
|
if [[ "$json_parsed" == "true" && -n "$PARSED_FILES_CREATED" && "$PARSED_FILES_CREATED" != "[]" ]]; then
|
||||||
|
# Parse JSON array and verify each file exists
|
||||||
|
local json_files
|
||||||
|
json_files=$(echo "$PARSED_FILES_CREATED" | jq -r '.[]' 2>/dev/null)
|
||||||
|
if [[ -n "$json_files" ]]; then
|
||||||
|
while IFS= read -r file; do
|
||||||
|
if [[ -f "$file" ]]; then
|
||||||
|
created_files+=("$file")
|
||||||
else
|
else
|
||||||
missing_files+=("PROMPT.md")
|
missing_files+=("$file")
|
||||||
|
fi
|
||||||
|
done <<< "$json_files"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -f "@fix_plan.md" ]]; then
|
# Always verify expected files exist (filesystem is source of truth)
|
||||||
created_files+=("@fix_plan.md")
|
for file in "${expected_files[@]}"; do
|
||||||
else
|
if [[ -f "$file" ]]; then
|
||||||
missing_files+=("@fix_plan.md")
|
# Add to created_files if not already there
|
||||||
|
if [[ ! " ${created_files[*]} " =~ " ${file} " ]]; then
|
||||||
|
created_files+=("$file")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -f "specs/requirements.md" ]]; then
|
|
||||||
created_files+=("specs/requirements.md")
|
|
||||||
else
|
else
|
||||||
missing_files+=("specs/requirements.md")
|
# Add to missing_files if not already there
|
||||||
|
if [[ ! " ${missing_files[*]} " =~ " ${file} " ]]; then
|
||||||
|
missing_files+=("$file")
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
# Report created files
|
# Report created files
|
||||||
if [[ ${#created_files[@]} -gt 0 ]]; then
|
if [[ ${#created_files[@]} -gt 0 ]]; then
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue