@the-bearded-bear/claude-craft 3.0.2 → 3.1.0

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.
Files changed (30) hide show
  1. package/Dev/i18n/de/Common/agents/ralph-conductor.md +146 -0
  2. package/Dev/i18n/de/Common/commands/ralph-run.md +171 -0
  3. package/Dev/i18n/de/Common/commands/setup-project-context.md +286 -0
  4. package/Dev/i18n/en/Common/agents/ralph-conductor.md +146 -0
  5. package/Dev/i18n/en/Common/commands/ralph-run.md +171 -0
  6. package/Dev/i18n/en/Common/commands/setup-project-context.md +286 -0
  7. package/Dev/i18n/es/Common/agents/ralph-conductor.md +146 -0
  8. package/Dev/i18n/es/Common/commands/ralph-run.md +171 -0
  9. package/Dev/i18n/es/Common/commands/setup-project-context.md +286 -0
  10. package/Dev/i18n/fr/Common/agents/ralph-conductor.md +146 -0
  11. package/Dev/i18n/fr/Common/commands/ralph-run.md +171 -0
  12. package/Dev/i18n/fr/Common/commands/setup-project-context.md +286 -0
  13. package/Dev/i18n/pt/Common/agents/ralph-conductor.md +146 -0
  14. package/Dev/i18n/pt/Common/commands/ralph-run.md +171 -0
  15. package/Dev/i18n/pt/Common/commands/setup-project-context.md +286 -0
  16. package/Tools/Ralph/README.md +303 -0
  17. package/Tools/Ralph/lib/checkpoint.sh +238 -0
  18. package/Tools/Ralph/lib/circuit-breaker.sh +172 -0
  19. package/Tools/Ralph/lib/dod-validator.sh +306 -0
  20. package/Tools/Ralph/lib/loop.sh +232 -0
  21. package/Tools/Ralph/lib/session.sh +234 -0
  22. package/Tools/Ralph/ralph.sh +491 -0
  23. package/Tools/Ralph/templates/ralph.yml.template +178 -0
  24. package/Tools/i18n/ralph/de.sh +147 -0
  25. package/Tools/i18n/ralph/en.sh +147 -0
  26. package/Tools/i18n/ralph/es.sh +147 -0
  27. package/Tools/i18n/ralph/fr.sh +147 -0
  28. package/Tools/i18n/ralph/pt.sh +147 -0
  29. package/cli/index.js +90 -0
  30. package/package.json +1 -1
@@ -0,0 +1,491 @@
1
+ #!/bin/bash
2
+ # =============================================================================
3
+ # Ralph Wiggum - Continuous AI Agent Loop
4
+ # Run Claude in a continuous loop until task completion
5
+ # =============================================================================
6
+
7
+ set -e
8
+
9
+ # Version
10
+ RALPH_VERSION="1.0.0"
11
+
12
+ # Script paths
13
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
14
+ LIB_DIR="$SCRIPT_DIR/lib"
15
+ I18N_DIR="$(dirname "$SCRIPT_DIR")/i18n/ralph"
16
+ TEMPLATES_DIR="$SCRIPT_DIR/templates"
17
+
18
+ # Configuration defaults
19
+ DEFAULT_MAX_ITERATIONS=25
20
+ DEFAULT_TIMEOUT=600000
21
+ DEFAULT_DELAY=1000
22
+ DEFAULT_SESSION_DIR=".ralph"
23
+ DEFAULT_CONFIG_FILE="ralph.yml"
24
+ DEFAULT_COMPLETION_MARKER="<promise>COMPLETE</promise>"
25
+
26
+ # i18n Configuration
27
+ VALID_LANGS=("en" "fr" "es" "de" "pt")
28
+ DEFAULT_LANG="en"
29
+
30
+ # Colors
31
+ C_RESET='\033[0m'
32
+ C_BOLD='\033[1m'
33
+ C_DIM='\033[2m'
34
+ C_RED='\033[0;31m'
35
+ C_GREEN='\033[0;32m'
36
+ C_YELLOW='\033[0;33m'
37
+ C_BLUE='\033[0;34m'
38
+ C_MAGENTA='\033[0;35m'
39
+ C_CYAN='\033[0;36m'
40
+
41
+ # Global state
42
+ LANG_ARG=""
43
+ PROMPT=""
44
+ CONFIG_FILE=""
45
+ SESSION_ID=""
46
+ MAX_ITERATIONS=$DEFAULT_MAX_ITERATIONS
47
+ TIMEOUT=$DEFAULT_TIMEOUT
48
+ DELAY=$DEFAULT_DELAY
49
+ VERBOSE=false
50
+ DRY_RUN=false
51
+ CONTINUE_SESSION=""
52
+
53
+ # =============================================================================
54
+ # i18n - Load messages
55
+ # =============================================================================
56
+
57
+ load_messages() {
58
+ local lang="${LANG_ARG:-$DEFAULT_LANG}"
59
+ local msg_file="$I18N_DIR/${lang}.sh"
60
+
61
+ if [[ -f "$msg_file" ]]; then
62
+ # shellcheck source=/dev/null
63
+ source "$msg_file"
64
+ else
65
+ # Fallback to English
66
+ local fallback="$I18N_DIR/en.sh"
67
+ if [[ -f "$fallback" ]]; then
68
+ # shellcheck source=/dev/null
69
+ source "$fallback"
70
+ else
71
+ # Minimal embedded defaults
72
+ MSG_HEADER="Ralph Wiggum - Continuous AI Agent Loop"
73
+ MSG_ERROR="Error"
74
+ MSG_GOODBYE="Goodbye!"
75
+ fi
76
+ fi
77
+ }
78
+
79
+ # =============================================================================
80
+ # Utilities
81
+ # =============================================================================
82
+
83
+ print_header() {
84
+ echo -e "\n${C_CYAN}╔════════════════════════════════════════════════════════════╗${C_RESET}"
85
+ echo -e "${C_CYAN}║${C_RESET} ${C_BOLD}🔁 ${MSG_HEADER}${C_RESET} ${C_CYAN}║${C_RESET}"
86
+ echo -e "${C_CYAN}║${C_RESET} ${C_DIM}${MSG_VERSION} ${RALPH_VERSION}${C_RESET} ${C_CYAN}║${C_RESET}"
87
+ echo -e "${C_CYAN}╚════════════════════════════════════════════════════════════╝${C_RESET}\n"
88
+ }
89
+
90
+ print_success() {
91
+ echo -e "${C_GREEN}✓${C_RESET} $1"
92
+ }
93
+
94
+ print_error() {
95
+ echo -e "${C_RED}✗${C_RESET} $1" >&2
96
+ }
97
+
98
+ print_info() {
99
+ echo -e "${C_BLUE}ℹ${C_RESET} $1"
100
+ }
101
+
102
+ print_warning() {
103
+ echo -e "${C_YELLOW}⚠${C_RESET} $1"
104
+ }
105
+
106
+ print_verbose() {
107
+ if [[ "$VERBOSE" == "true" ]]; then
108
+ echo -e "${C_DIM} $1${C_RESET}"
109
+ fi
110
+ }
111
+
112
+ print_iteration() {
113
+ local current=$1
114
+ local max=$2
115
+ echo -e "\n${C_CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C_RESET}"
116
+ echo -e "${C_BOLD}${MSG_ITERATION} ${current} ${MSG_OF} ${max}${C_RESET}"
117
+ echo -e "${C_CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${C_RESET}\n"
118
+ }
119
+
120
+ # =============================================================================
121
+ # Dependency checks
122
+ # =============================================================================
123
+
124
+ check_dependencies() {
125
+ local missing=()
126
+
127
+ # Check for claude command
128
+ if ! command -v claude &> /dev/null; then
129
+ missing+=("claude")
130
+ fi
131
+
132
+ # Check for jq (JSON parsing)
133
+ if ! command -v jq &> /dev/null; then
134
+ missing+=("jq")
135
+ fi
136
+
137
+ # Check for git (optional but recommended for checkpointing)
138
+ if ! command -v git &> /dev/null; then
139
+ print_warning "${MSG_ERROR_GIT_NOT_FOUND}"
140
+ fi
141
+
142
+ # Check for yq (YAML parsing - optional)
143
+ if ! command -v yq &> /dev/null; then
144
+ print_verbose "${MSG_ERROR_YQ_NOT_FOUND}"
145
+ fi
146
+
147
+ if [[ ${#missing[@]} -gt 0 ]]; then
148
+ print_error "${MSG_ERROR}: Missing required dependencies: ${missing[*]}"
149
+ exit 1
150
+ fi
151
+ }
152
+
153
+ # =============================================================================
154
+ # Load library modules
155
+ # =============================================================================
156
+
157
+ load_modules() {
158
+ local modules=("session" "loop" "dod-validator" "circuit-breaker" "checkpoint")
159
+
160
+ for module in "${modules[@]}"; do
161
+ local module_file="$LIB_DIR/${module}.sh"
162
+ if [[ -f "$module_file" ]]; then
163
+ # shellcheck source=/dev/null
164
+ source "$module_file"
165
+ print_verbose "Loaded module: $module"
166
+ else
167
+ print_warning "Module not found: $module_file"
168
+ fi
169
+ done
170
+ }
171
+
172
+ # =============================================================================
173
+ # Configuration loading
174
+ # =============================================================================
175
+
176
+ load_config() {
177
+ local config_path="${CONFIG_FILE:-$DEFAULT_CONFIG_FILE}"
178
+
179
+ # Check multiple locations
180
+ local search_paths=(
181
+ "$config_path"
182
+ ".claude/$config_path"
183
+ "$PWD/$config_path"
184
+ )
185
+
186
+ for path in "${search_paths[@]}"; do
187
+ if [[ -f "$path" ]]; then
188
+ print_info "${MSG_CONFIG_LOADING}"
189
+
190
+ # Parse YAML config if yq is available
191
+ if command -v yq &> /dev/null; then
192
+ # Session settings
193
+ local max_iter=$(yq e '.session.max_iterations // ""' "$path" 2>/dev/null)
194
+ [[ -n "$max_iter" ]] && MAX_ITERATIONS=$max_iter
195
+
196
+ local timeout=$(yq e '.session.timeout // ""' "$path" 2>/dev/null)
197
+ [[ -n "$timeout" ]] && TIMEOUT=$timeout
198
+
199
+ local delay=$(yq e '.session.delay_between_iterations // ""' "$path" 2>/dev/null)
200
+ [[ -n "$delay" ]] && DELAY=$delay
201
+
202
+ # Circuit breaker settings are loaded in circuit-breaker.sh
203
+ # DoD settings are loaded in dod-validator.sh
204
+
205
+ print_success "${MSG_CONFIG_LOADED}: $path"
206
+ else
207
+ print_warning "${MSG_ERROR_YQ_NOT_FOUND} - Using CLI arguments only"
208
+ fi
209
+
210
+ CONFIG_FILE="$path"
211
+ return 0
212
+ fi
213
+ done
214
+
215
+ print_verbose "${MSG_CONFIG_NOT_FOUND}, ${MSG_CONFIG_USING_DEFAULTS}"
216
+ return 0
217
+ }
218
+
219
+ # =============================================================================
220
+ # Help
221
+ # =============================================================================
222
+
223
+ show_help() {
224
+ echo -e "${C_BOLD}${MSG_HELP_USAGE}:${C_RESET}"
225
+ echo " ralph.sh [options] <prompt>"
226
+ echo ""
227
+ echo -e "${C_BOLD}${MSG_HELP_DESCRIPTION}${C_RESET}"
228
+ echo ""
229
+ echo -e "${C_BOLD}${MSG_HELP_OPTIONS}:${C_RESET}"
230
+ echo " <prompt> ${MSG_HELP_PROMPT}"
231
+ echo " --config=<file> ${MSG_HELP_CONFIG}"
232
+ echo " --continue=<id> ${MSG_HELP_CONTINUE}"
233
+ echo " --max-iterations=<n> ${MSG_HELP_MAX_ITER}"
234
+ echo " --verbose ${MSG_HELP_VERBOSE}"
235
+ echo " --dry-run ${MSG_HELP_DRY_RUN}"
236
+ echo " --lang=<code> ${MSG_HELP_LANG}"
237
+ echo " --help ${MSG_HELP_HELP}"
238
+ echo ""
239
+ echo -e "${C_BOLD}${MSG_HELP_EXAMPLES}:${C_RESET}"
240
+ echo ""
241
+ echo " # ${MSG_HELP_EXAMPLE_BASIC}"
242
+ echo " ralph.sh \"Implement user authentication\""
243
+ echo ""
244
+ echo " # ${MSG_HELP_EXAMPLE_CONFIG}"
245
+ echo " ralph.sh --config=ralph.yml \"Fix the login bug\""
246
+ echo ""
247
+ echo " # ${MSG_HELP_EXAMPLE_RESUME}"
248
+ echo " ralph.sh --continue=abc123"
249
+ echo ""
250
+ }
251
+
252
+ # =============================================================================
253
+ # Argument parsing
254
+ # =============================================================================
255
+
256
+ parse_args() {
257
+ while [[ $# -gt 0 ]]; do
258
+ case "$1" in
259
+ --lang=*)
260
+ LANG_ARG="${1#--lang=}"
261
+ # Validate language
262
+ local valid=false
263
+ for l in "${VALID_LANGS[@]}"; do
264
+ [[ "$LANG_ARG" == "$l" ]] && valid=true
265
+ done
266
+ if ! $valid; then
267
+ echo -e "${C_RED}Invalid language: $LANG_ARG${C_RESET}"
268
+ echo "Valid languages: ${VALID_LANGS[*]}"
269
+ exit 1
270
+ fi
271
+ ;;
272
+ --config=*)
273
+ CONFIG_FILE="${1#--config=}"
274
+ ;;
275
+ --continue=*)
276
+ CONTINUE_SESSION="${1#--continue=}"
277
+ ;;
278
+ --max-iterations=*)
279
+ MAX_ITERATIONS="${1#--max-iterations=}"
280
+ ;;
281
+ --timeout=*)
282
+ TIMEOUT="${1#--timeout=}"
283
+ ;;
284
+ --delay=*)
285
+ DELAY="${1#--delay=}"
286
+ ;;
287
+ --verbose)
288
+ VERBOSE=true
289
+ ;;
290
+ --dry-run)
291
+ DRY_RUN=true
292
+ ;;
293
+ --help|-h)
294
+ load_messages
295
+ show_help
296
+ exit 0
297
+ ;;
298
+ -*)
299
+ echo "Unknown option: $1"
300
+ exit 1
301
+ ;;
302
+ *)
303
+ # Positional argument = prompt
304
+ PROMPT="$1"
305
+ ;;
306
+ esac
307
+ shift
308
+ done
309
+ }
310
+
311
+ # =============================================================================
312
+ # Main Ralph loop
313
+ # =============================================================================
314
+
315
+ run_ralph() {
316
+ local iteration=0
317
+ local exit_reason=""
318
+ local dod_passed=false
319
+ local start_time=$(date +%s)
320
+
321
+ # Initialize or resume session
322
+ if [[ -n "$CONTINUE_SESSION" ]]; then
323
+ SESSION_ID="$CONTINUE_SESSION"
324
+ resume_session "$SESSION_ID" || {
325
+ print_error "${MSG_SESSION_NOT_FOUND}: $SESSION_ID"
326
+ exit 1
327
+ }
328
+ print_success "${MSG_SESSION_RESUMED}: $SESSION_ID"
329
+ else
330
+ SESSION_ID=$(create_session "$PROMPT")
331
+ print_success "${MSG_SESSION_CREATED}: $SESSION_ID"
332
+ fi
333
+
334
+ # Initialize circuit breaker
335
+ init_circuit_breaker
336
+
337
+ print_info "${MSG_STARTING_LOOP}..."
338
+ print_verbose "${MSG_SESSION_ID}: $SESSION_ID"
339
+ print_verbose "Max iterations: $MAX_ITERATIONS"
340
+ print_verbose "Timeout: ${TIMEOUT}ms"
341
+
342
+ # Main loop
343
+ while [[ $iteration -lt $MAX_ITERATIONS ]]; do
344
+ iteration=$((iteration + 1))
345
+ print_iteration $iteration $MAX_ITERATIONS
346
+
347
+ # Check circuit breaker
348
+ if check_circuit_breaker; then
349
+ exit_reason="circuit_breaker"
350
+ break
351
+ fi
352
+
353
+ # Dry run mode
354
+ if [[ "$DRY_RUN" == "true" ]]; then
355
+ print_info "[DRY-RUN] Would invoke Claude with session $SESSION_ID"
356
+ continue
357
+ fi
358
+
359
+ # Invoke Claude
360
+ print_info "${MSG_INVOKING_CLAUDE}"
361
+ local response
362
+ response=$(invoke_claude "$SESSION_ID" "$PROMPT" "$TIMEOUT")
363
+ local invoke_status=$?
364
+
365
+ if [[ $invoke_status -ne 0 ]]; then
366
+ print_error "${MSG_ERROR}: Claude invocation failed"
367
+ update_circuit_breaker "error" "$response"
368
+ continue
369
+ fi
370
+
371
+ # Update metrics
372
+ update_session_metrics "$SESSION_ID" "$iteration" "$response"
373
+
374
+ # Create checkpoint (async if configured)
375
+ create_checkpoint "$SESSION_ID" "$iteration"
376
+
377
+ # Check Definition of Done
378
+ print_info "${MSG_DOD_CHECKING}"
379
+ if validate_dod "$response" "$CONFIG_FILE"; then
380
+ dod_passed=true
381
+ exit_reason="dod_complete"
382
+ print_success "${MSG_DOD_PASSED}"
383
+ break
384
+ else
385
+ print_warning "${MSG_DOD_FAILED}"
386
+ update_circuit_breaker "no_progress" ""
387
+ fi
388
+
389
+ # Feed response back as prompt for next iteration
390
+ PROMPT="$response"
391
+
392
+ # Rate limiting delay
393
+ if [[ $DELAY -gt 0 ]]; then
394
+ local delay_sec=$((DELAY / 1000))
395
+ print_verbose "${MSG_WAITING} ${delay_sec} ${MSG_SECONDS}..."
396
+ sleep "$delay_sec"
397
+ fi
398
+ done
399
+
400
+ # Check if max iterations reached
401
+ if [[ $iteration -ge $MAX_ITERATIONS && "$dod_passed" != "true" ]]; then
402
+ exit_reason="max_iterations"
403
+ print_warning "${MSG_CB_MAX_REACHED}"
404
+ fi
405
+
406
+ # Calculate duration
407
+ local end_time=$(date +%s)
408
+ local duration=$((end_time - start_time))
409
+
410
+ # Print summary
411
+ print_summary "$SESSION_ID" "$iteration" "$duration" "$dod_passed" "$exit_reason"
412
+
413
+ # Save final state
414
+ save_session "$SESSION_ID" "$exit_reason"
415
+
416
+ # Return appropriate exit code
417
+ if [[ "$dod_passed" == "true" ]]; then
418
+ return 0
419
+ else
420
+ return 1
421
+ fi
422
+ }
423
+
424
+ # =============================================================================
425
+ # Summary
426
+ # =============================================================================
427
+
428
+ print_summary() {
429
+ local session_id="$1"
430
+ local iterations="$2"
431
+ local duration="$3"
432
+ local dod_passed="$4"
433
+ local exit_reason="$5"
434
+
435
+ echo -e "\n${C_CYAN}╔════════════════════════════════════════════════════════════╗${C_RESET}"
436
+ echo -e "${C_CYAN}║${C_RESET} ${C_BOLD}📊 ${MSG_SUMMARY_TITLE}${C_RESET} ${C_CYAN}║${C_RESET}"
437
+ echo -e "${C_CYAN}╚════════════════════════════════════════════════════════════╝${C_RESET}\n"
438
+
439
+ echo -e " ${C_BOLD}${MSG_SESSION_ID}:${C_RESET} $session_id"
440
+ echo -e " ${C_BOLD}${MSG_SUMMARY_ITERATIONS}:${C_RESET} $iterations"
441
+ echo -e " ${C_BOLD}${MSG_SUMMARY_DURATION}:${C_RESET} ${duration}s"
442
+
443
+ if [[ "$dod_passed" == "true" ]]; then
444
+ echo -e " ${C_BOLD}${MSG_SUMMARY_DOD_STATUS}:${C_RESET} ${C_GREEN}${MSG_DOD_PASSED}${C_RESET}"
445
+ else
446
+ echo -e " ${C_BOLD}${MSG_SUMMARY_DOD_STATUS}:${C_RESET} ${C_RED}${MSG_DOD_FAILED}${C_RESET}"
447
+ fi
448
+
449
+ echo -e " ${C_BOLD}${MSG_SUMMARY_EXIT_REASON}:${C_RESET} $exit_reason"
450
+ echo ""
451
+ }
452
+
453
+ # =============================================================================
454
+ # Main
455
+ # =============================================================================
456
+
457
+ main() {
458
+ # Parse arguments first (before loading messages for --lang)
459
+ parse_args "$@"
460
+
461
+ # Load i18n messages
462
+ load_messages
463
+
464
+ # Print header
465
+ print_header
466
+
467
+ # Check dependencies
468
+ check_dependencies
469
+
470
+ # Load library modules
471
+ load_modules
472
+
473
+ # Load configuration
474
+ load_config
475
+
476
+ # Validate we have a prompt or are resuming
477
+ if [[ -z "$PROMPT" && -z "$CONTINUE_SESSION" ]]; then
478
+ print_error "${MSG_ERROR_NO_PROMPT}"
479
+ echo ""
480
+ show_help
481
+ exit 1
482
+ fi
483
+
484
+ # Run the main loop
485
+ run_ralph
486
+ }
487
+
488
+ # Run if executed directly (not sourced)
489
+ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
490
+ main "$@"
491
+ fi
@@ -0,0 +1,178 @@
1
+ # =============================================================================
2
+ # Ralph Wiggum Configuration
3
+ # Continuous AI Agent Loop Configuration
4
+ # =============================================================================
5
+ #
6
+ # Copy this file to your project root as `ralph.yml` or `.claude/ralph.yml`
7
+ # and customize according to your needs.
8
+ #
9
+ # Documentation: https://github.com/TheBeardedBearSAS/claude-craft
10
+ # =============================================================================
11
+
12
+ version: "1.0"
13
+
14
+ # =============================================================================
15
+ # Session Settings
16
+ # =============================================================================
17
+ session:
18
+ # Session ID: "auto" generates a unique ID, or specify a fixed ID
19
+ id: auto
20
+
21
+ # Timeout per Claude invocation (milliseconds)
22
+ # Default: 600000 (10 minutes)
23
+ timeout: 600000
24
+
25
+ # Maximum number of iterations before stopping
26
+ # Default: 25
27
+ max_iterations: 25
28
+
29
+ # Delay between iterations (milliseconds) - rate limiting
30
+ # Default: 1000 (1 second)
31
+ delay_between_iterations: 1000
32
+
33
+ # =============================================================================
34
+ # Circuit Breaker - Safety Mechanism
35
+ # =============================================================================
36
+ # The circuit breaker prevents infinite loops and detects stalls
37
+ circuit_breaker:
38
+ # Enable/disable circuit breaker
39
+ enabled: true
40
+
41
+ # Stop if no file changes detected for N iterations
42
+ no_file_changes_threshold: 3
43
+
44
+ # Stop if same error repeats N times
45
+ repeated_error_threshold: 5
46
+
47
+ # Stop if output length declines by N% from peak
48
+ output_decline_threshold: 70
49
+
50
+ # =============================================================================
51
+ # Git Checkpointing
52
+ # =============================================================================
53
+ # Automatically creates git commits for recovery and history tracking
54
+ checkpointing:
55
+ # Enable/disable checkpointing
56
+ enabled: true
57
+
58
+ # Run checkpointing asynchronously (non-blocking)
59
+ async: true
60
+
61
+ # Branch prefix for Ralph sessions
62
+ branch_prefix: "ralph/"
63
+
64
+ # Commit message template
65
+ # Variables: {iteration}, {session_id}
66
+ commit_message_template: "checkpoint: Ralph iteration {iteration}"
67
+
68
+ # =============================================================================
69
+ # Agent Settings
70
+ # =============================================================================
71
+ # Configure which AI agent to use
72
+ agent:
73
+ # Agent name: claude, kiro, q, gemini
74
+ name: claude
75
+
76
+ # Command to invoke the agent
77
+ command: claude
78
+
79
+ # Additional arguments
80
+ args:
81
+ - "--continue"
82
+ - "${SESSION_ID}"
83
+ - "-p"
84
+ - "${PROMPT}"
85
+
86
+ # =============================================================================
87
+ # Definition of Done (DoD)
88
+ # =============================================================================
89
+ # Criteria that must be met for the task to be considered complete
90
+ definition_of_done:
91
+ # Simple mode: completion marker string
92
+ # If Claude outputs this exact string, task is complete
93
+ completion_marker: "<promise>COMPLETE</promise>"
94
+
95
+ # Advanced mode: checklist of validation criteria
96
+ # Uncomment and customize the checklist below for structured DoD
97
+ #
98
+ # checklist:
99
+ # # -------------------------------------------------------------------------
100
+ # # Validator type: command
101
+ # # Runs a shell command and checks exit code (0 = pass)
102
+ # # -------------------------------------------------------------------------
103
+ # - id: tests
104
+ # name: "All tests pass"
105
+ # type: command
106
+ # command: "docker compose exec app npm test"
107
+ # required: true
108
+ #
109
+ # - id: lint
110
+ # name: "No lint errors"
111
+ # type: command
112
+ # command: "docker compose exec app npm run lint"
113
+ # required: true
114
+ #
115
+ # - id: typecheck
116
+ # name: "TypeScript compiles"
117
+ # type: command
118
+ # command: "docker compose exec app npx tsc --noEmit"
119
+ # required: true
120
+ #
121
+ # - id: build
122
+ # name: "Build succeeds"
123
+ # type: command
124
+ # command: "docker compose exec app npm run build"
125
+ # required: false # Warning only, not blocking
126
+ #
127
+ # # -------------------------------------------------------------------------
128
+ # # Validator type: output_contains
129
+ # # Checks if Claude's output contains a pattern (regex)
130
+ # # -------------------------------------------------------------------------
131
+ # - id: completion
132
+ # name: "Claude signals completion"
133
+ # type: output_contains
134
+ # pattern: "<promise>COMPLETE</promise>"
135
+ # required: true
136
+ #
137
+ # # -------------------------------------------------------------------------
138
+ # # Validator type: file_changed
139
+ # # Checks if files matching pattern were modified
140
+ # # -------------------------------------------------------------------------
141
+ # - id: docs
142
+ # name: "Documentation updated"
143
+ # type: file_changed
144
+ # pattern: "*.md"
145
+ # required: false
146
+ #
147
+ # # -------------------------------------------------------------------------
148
+ # # Validator type: hook
149
+ # # Runs an existing Claude hook script
150
+ # # -------------------------------------------------------------------------
151
+ # - id: quality_gate
152
+ # name: "Quality gate passes"
153
+ # type: hook
154
+ # script: ".claude/hooks/quality-gate.sh"
155
+ # required: true
156
+ #
157
+ # # -------------------------------------------------------------------------
158
+ # # Validator type: human
159
+ # # Prompts for human confirmation (interactive)
160
+ # # -------------------------------------------------------------------------
161
+ # - id: manual_review
162
+ # name: "Manual review approved"
163
+ # type: human
164
+ # prompt: "Does the implementation look correct? (y/n):"
165
+ # required: false
166
+
167
+ # =============================================================================
168
+ # Output Settings
169
+ # =============================================================================
170
+ output:
171
+ # Log file path (relative to session directory)
172
+ log_file: ".ralph/session.log"
173
+
174
+ # Metrics file path (JSON format)
175
+ metrics_file: ".ralph/metrics.json"
176
+
177
+ # Enable verbose output
178
+ verbose: false