ralph-claude-code/ralph_enable_ci.sh
Frank Bria c7e7a1c6a3
refactor(naming): remove @ prefix from on-disk filenames (#131)
* refactor(naming): remove @ prefix from on-disk filenames

BREAKING CHANGE: Renames @fix_plan.md → fix_plan.md and @AGENT.md → AGENT.md

This change improves POSIX compliance and compatibility with command-line tools.
The @ prefix was originally used to avoid naming conflicts, but with the .ralph/
folder structure introduced in v0.10.0, this convention is no longer necessary.

Changes:
- Update all scripts to use new naming (fix_plan.md, AGENT.md)
- Update migration script to handle both old and new naming conventions
- Update templates to use new naming
- Update all documentation references
- Update all 420 tests to expect new naming (TDD approach)

Migration:
- Existing projects with @-prefixed files will be automatically renamed
  when running ralph-migrate
- Projects already using the new naming will continue to work unchanged

* docs(claude): update file naming conventions section

* fix(migrate): prevent orphaned @-prefixed files during migration

When both root/@fix_plan.md and .ralph/@fix_plan.md exist, the root file
now takes priority and the .ralph/@fix_plan.md is removed (backup exists).
This prevents orphaned legacy files after migration.

---------

Co-authored-by: Test User <test@example.com>
2026-01-26 15:40:27 -07:00

405 lines
12 KiB
Bash
Executable file

#!/bin/bash
# Ralph Enable CI - Non-Interactive Version for Automation
# Adds Ralph configuration with sensible defaults
#
# Usage:
# ralph enable-ci # Auto-detect and enable
# ralph enable-ci --from beads # With specific task source
# ralph enable-ci --json # Output JSON result
#
# Exit codes:
# 0 - Success: Ralph enabled
# 1 - Error: General error
# 2 - Already enabled (use --force to override)
# 3 - Invalid arguments
# 4 - File not found (e.g., PRD file)
# 5 - Dependency missing (e.g., jq for --json)
#
# Version: 0.11.0
set -e
# Get script directory for library loading
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Try to load libraries from global installation first, then local
RALPH_HOME="${RALPH_HOME:-$HOME/.ralph}"
if [[ -f "$RALPH_HOME/lib/enable_core.sh" ]]; then
LIB_DIR="$RALPH_HOME/lib"
elif [[ -f "$SCRIPT_DIR/lib/enable_core.sh" ]]; then
LIB_DIR="$SCRIPT_DIR/lib"
else
echo '{"error": "Cannot find Ralph libraries", "code": 1}' >&2
exit 1
fi
# Disable colors for CI
export ENABLE_USE_COLORS="false"
# Source libraries
source "$LIB_DIR/enable_core.sh"
source "$LIB_DIR/task_sources.sh"
# =============================================================================
# CONFIGURATION
# =============================================================================
# Command line options
FORCE_OVERWRITE=false
TASK_SOURCE=""
PRD_FILE=""
GITHUB_LABEL="ralph-task"
PROJECT_NAME=""
PROJECT_TYPE=""
OUTPUT_JSON=false
QUIET=false
SHOW_HELP=false
# Version
VERSION="0.11.0"
# =============================================================================
# HELP
# =============================================================================
show_help() {
cat << EOF
Ralph Enable CI - Non-Interactive Version for Automation
Usage: ralph enable-ci [OPTIONS]
Options:
--from <source> Import tasks from: beads, github, prd, none
--prd <file> PRD file to convert (when --from prd)
--label <label> GitHub label filter (default: ralph-task)
--project-name <name> Override detected project name
--project-type <type> Override detected type (typescript, python, etc.)
--force Overwrite existing .ralph/ configuration
--json Output result as JSON
--quiet Suppress non-error output
-h, --help Show this help message
-v, --version Show version
Exit Codes:
0 - Success: Ralph enabled
1 - Error: General error
2 - Already enabled: Use --force to override
3 - Invalid arguments
4 - File not found (e.g., PRD file)
5 - Dependency missing (e.g., jq for --json)
Examples:
# Auto-detect and enable with defaults
ralph enable-ci
# Enable with beads tasks
ralph enable-ci --from beads
# Enable with GitHub issues
ralph enable-ci --from github --label "sprint-1"
# Enable with PRD conversion
ralph enable-ci --from prd --prd docs/requirements.md
# Force overwrite and output JSON
ralph enable-ci --force --json
# Override project detection
ralph enable-ci --project-name my-app --project-type typescript
JSON Output Format:
{
"success": true,
"project_name": "my-project",
"project_type": "typescript",
"files_created": [".ralph/PROMPT.md", ...],
"tasks_imported": 15,
"message": "Ralph enabled successfully"
}
EOF
}
# =============================================================================
# ARGUMENT PARSING
# =============================================================================
parse_arguments() {
while [[ $# -gt 0 ]]; do
case "$1" in
--from)
if [[ -n "$2" && ! "$2" =~ ^-- ]]; then
TASK_SOURCE="$2"
shift 2
else
output_error "--from requires a source (beads, github, prd, none)"
exit $ENABLE_INVALID_ARGS
fi
;;
--prd)
if [[ -n "$2" && ! "$2" =~ ^-- ]]; then
PRD_FILE="$2"
shift 2
else
output_error "--prd requires a file path"
exit $ENABLE_INVALID_ARGS
fi
;;
--label)
if [[ -n "$2" && ! "$2" =~ ^-- ]]; then
GITHUB_LABEL="$2"
shift 2
else
output_error "--label requires a label name"
exit $ENABLE_INVALID_ARGS
fi
;;
--project-name)
if [[ -n "$2" && ! "$2" =~ ^-- ]]; then
PROJECT_NAME="$2"
shift 2
else
output_error "--project-name requires a name"
exit $ENABLE_INVALID_ARGS
fi
;;
--project-type)
if [[ -n "$2" && ! "$2" =~ ^-- ]]; then
PROJECT_TYPE="$2"
shift 2
else
output_error "--project-type requires a type"
exit $ENABLE_INVALID_ARGS
fi
;;
--force)
FORCE_OVERWRITE=true
shift
;;
--json)
if ! command -v jq &>/dev/null; then
echo "Error: --json requires jq to be installed" >&2
exit $ENABLE_DEPENDENCY_MISSING
fi
OUTPUT_JSON=true
shift
;;
--quiet)
QUIET=true
shift
;;
-h|--help)
SHOW_HELP=true
shift
;;
-v|--version)
if [[ "$OUTPUT_JSON" == "true" ]]; then
echo "{\"version\": \"$VERSION\"}"
else
echo "ralph enable-ci version $VERSION"
fi
exit 0
;;
*)
output_error "Unknown option: $1"
exit $ENABLE_INVALID_ARGS
;;
esac
done
}
# =============================================================================
# OUTPUT FUNCTIONS
# =============================================================================
# Track created files for JSON output
declare -a CREATED_FILES=()
TASKS_IMPORTED=0
output_message() {
if [[ "$QUIET" != "true" && "$OUTPUT_JSON" != "true" ]]; then
echo "$1"
fi
}
output_error() {
if [[ "$OUTPUT_JSON" == "true" ]]; then
echo "{\"error\": \"$1\", \"code\": 1}" >&2
else
echo "Error: $1" >&2
fi
}
output_success() {
local project_name="$1"
local project_type="$2"
if [[ "$OUTPUT_JSON" == "true" ]]; then
local files_json
files_json=$(printf '%s\n' "${CREATED_FILES[@]}" | jq -R . | jq -s .)
cat << EOF
{
"success": true,
"project_name": "$project_name",
"project_type": "$project_type",
"files_created": $files_json,
"tasks_imported": $TASKS_IMPORTED,
"message": "Ralph enabled successfully"
}
EOF
else
echo "Ralph enabled successfully for: $project_name ($project_type)"
echo "Files created: ${#CREATED_FILES[@]}"
echo "Tasks imported: $TASKS_IMPORTED"
fi
}
output_already_enabled() {
if [[ "$OUTPUT_JSON" == "true" ]]; then
echo '{"success": false, "code": 2, "message": "Ralph already enabled. Use --force to override."}'
else
echo "Ralph is already enabled in this project. Use --force to override."
fi
}
# =============================================================================
# MAIN LOGIC
# =============================================================================
main() {
# Parse arguments
parse_arguments "$@"
# Show help if requested
if [[ "$SHOW_HELP" == "true" ]]; then
show_help
exit 0
fi
output_message "Ralph Enable CI - Non-Interactive Mode"
output_message ""
# Check existing state (use || true to prevent set -e from exiting)
check_existing_ralph || true
if [[ "$RALPH_STATE" == "complete" && "$FORCE_OVERWRITE" != "true" ]]; then
output_already_enabled
exit $ENABLE_ALREADY_ENABLED
fi
# Detect project context
detect_project_context
output_message "Detected: $DETECTED_PROJECT_NAME ($DETECTED_PROJECT_TYPE)"
# Override with CLI options if provided
if [[ -n "$PROJECT_NAME" ]]; then
DETECTED_PROJECT_NAME="$PROJECT_NAME"
fi
if [[ -n "$PROJECT_TYPE" ]]; then
DETECTED_PROJECT_TYPE="$PROJECT_TYPE"
fi
# Auto-detect task source if not specified
if [[ -z "$TASK_SOURCE" ]]; then
detect_task_sources
if [[ "$DETECTED_BEADS_AVAILABLE" == "true" ]]; then
TASK_SOURCE="beads"
output_message "Auto-detected task source: beads"
elif [[ "$DETECTED_GITHUB_AVAILABLE" == "true" ]]; then
TASK_SOURCE="github"
output_message "Auto-detected task source: github"
elif [[ ${#DETECTED_PRD_FILES[@]} -gt 0 ]]; then
TASK_SOURCE="prd"
PRD_FILE="${DETECTED_PRD_FILES[0]}"
output_message "Auto-detected task source: prd ($PRD_FILE)"
else
TASK_SOURCE="none"
output_message "No task sources detected, using defaults"
fi
fi
# Import tasks
local imported_tasks=""
case "$TASK_SOURCE" in
beads)
if beads_tasks=$(fetch_beads_tasks 2>/dev/null); then
imported_tasks="$beads_tasks"
TASKS_IMPORTED=$(echo "$imported_tasks" | grep -c '^\- \[' || echo "0")
output_message "Imported $TASKS_IMPORTED tasks from beads"
fi
;;
github)
if github_tasks=$(fetch_github_tasks "$GITHUB_LABEL" 2>/dev/null); then
imported_tasks="$github_tasks"
TASKS_IMPORTED=$(echo "$imported_tasks" | grep -c '^\- \[' || echo "0")
output_message "Imported $TASKS_IMPORTED tasks from GitHub"
fi
;;
prd)
if [[ -n "$PRD_FILE" && -f "$PRD_FILE" ]]; then
if prd_tasks=$(extract_prd_tasks "$PRD_FILE" 2>/dev/null); then
imported_tasks="$prd_tasks"
TASKS_IMPORTED=$(echo "$imported_tasks" | grep -c '^\- \[' || echo "0")
output_message "Extracted $TASKS_IMPORTED tasks from PRD"
fi
else
output_error "PRD file not found: $PRD_FILE"
exit $ENABLE_FILE_NOT_FOUND
fi
;;
none|"")
output_message "Skipping task import"
;;
*)
output_error "Unknown task source: $TASK_SOURCE"
exit $ENABLE_ERROR
;;
esac
# Set up enable environment
export ENABLE_FORCE="$FORCE_OVERWRITE"
export ENABLE_SKIP_TASKS="false"
export ENABLE_PROJECT_NAME="$DETECTED_PROJECT_NAME"
export ENABLE_PROJECT_TYPE="$DETECTED_PROJECT_TYPE"
export ENABLE_TASK_CONTENT="$imported_tasks"
# Run core enable logic
output_message ""
output_message "Creating Ralph configuration..."
# Suppress enable_ralph_in_directory output when in JSON mode
if [[ "$OUTPUT_JSON" == "true" ]]; then
if ! enable_ralph_in_directory >/dev/null 2>&1; then
output_error "Failed to enable Ralph"
exit $ENABLE_ERROR
fi
else
if ! enable_ralph_in_directory; then
output_error "Failed to enable Ralph"
exit $ENABLE_ERROR
fi
fi
# Track created files
[[ -f ".ralph/PROMPT.md" ]] && CREATED_FILES+=(".ralph/PROMPT.md")
[[ -f ".ralph/fix_plan.md" ]] && CREATED_FILES+=(".ralph/fix_plan.md")
[[ -f ".ralph/AGENT.md" ]] && CREATED_FILES+=(".ralph/AGENT.md")
[[ -f ".ralphrc" ]] && CREATED_FILES+=(".ralphrc")
# Verify required files exist
if [[ ! -f ".ralph/PROMPT.md" ]] || [[ ! -f ".ralph/fix_plan.md" ]]; then
output_error "Required files were not created"
exit $ENABLE_ERROR
fi
# Output success
output_message ""
output_success "$DETECTED_PROJECT_NAME" "$DETECTED_PROJECT_TYPE"
exit $ENABLE_SUCCESS
}
# Run main
main "$@"