@the-bearded-bear/claude-craft 3.0.2 → 3.1.0-next.a356bbd
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.
- package/Dev/i18n/de/Common/agents/ralph-conductor.md +146 -0
- package/Dev/i18n/de/Common/commands/ralph-run.md +171 -0
- package/Dev/i18n/de/Common/commands/setup-project-context.md +286 -0
- package/Dev/i18n/en/Common/agents/ralph-conductor.md +146 -0
- package/Dev/i18n/en/Common/commands/ralph-run.md +171 -0
- package/Dev/i18n/en/Common/commands/setup-project-context.md +286 -0
- package/Dev/i18n/es/Common/agents/ralph-conductor.md +146 -0
- package/Dev/i18n/es/Common/commands/ralph-run.md +171 -0
- package/Dev/i18n/es/Common/commands/setup-project-context.md +286 -0
- package/Dev/i18n/fr/Common/agents/ralph-conductor.md +146 -0
- package/Dev/i18n/fr/Common/commands/ralph-run.md +171 -0
- package/Dev/i18n/fr/Common/commands/setup-project-context.md +286 -0
- package/Dev/i18n/pt/Common/agents/ralph-conductor.md +146 -0
- package/Dev/i18n/pt/Common/commands/ralph-run.md +171 -0
- package/Dev/i18n/pt/Common/commands/setup-project-context.md +286 -0
- package/Tools/Ralph/README.md +303 -0
- package/Tools/Ralph/lib/checkpoint.sh +238 -0
- package/Tools/Ralph/lib/circuit-breaker.sh +172 -0
- package/Tools/Ralph/lib/dod-validator.sh +306 -0
- package/Tools/Ralph/lib/loop.sh +232 -0
- package/Tools/Ralph/lib/session.sh +234 -0
- package/Tools/Ralph/ralph.sh +491 -0
- package/Tools/Ralph/templates/ralph.yml.template +178 -0
- package/Tools/i18n/ralph/de.sh +147 -0
- package/Tools/i18n/ralph/en.sh +147 -0
- package/Tools/i18n/ralph/es.sh +147 -0
- package/Tools/i18n/ralph/fr.sh +147 -0
- package/Tools/i18n/ralph/pt.sh +147 -0
- package/cli/index.js +90 -0
- package/package.json +1 -1
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
# Ralph Wiggum - Continuous AI Agent Loop
|
|
2
|
+
|
|
3
|
+
Ralph Wiggum is a methodology and tool for running Claude in a continuous loop until a task is complete. It provides structured completion detection through Definition of Done (DoD) validation, safety mechanisms via circuit breakers, and progress tracking through git checkpoints.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
9
|
+
│ RALPH LOOP │
|
|
10
|
+
│ │
|
|
11
|
+
│ while (iterations < max && !complete) { │
|
|
12
|
+
│ response = claude("--continue", session_id, prompt) │
|
|
13
|
+
│ complete = checkDoD(response) │
|
|
14
|
+
│ if (circuitBreaker.triggered()) break │
|
|
15
|
+
│ createCheckpoint(iteration) │
|
|
16
|
+
│ prompt = response // feedback loop │
|
|
17
|
+
│ } │
|
|
18
|
+
└─────────────────────────────────────────────────────────────┘
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
### Via CLI
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Basic usage
|
|
27
|
+
npx @the-bearded-bear/claude-craft ralph "Implement user authentication"
|
|
28
|
+
|
|
29
|
+
# With configuration
|
|
30
|
+
npx @the-bearded-bear/claude-craft ralph --config=ralph.yml "Fix the login bug"
|
|
31
|
+
|
|
32
|
+
# Resume session
|
|
33
|
+
npx @the-bearded-bear/claude-craft ralph --continue=ralph-1704067200-a1b2
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Via Command in Claude Code
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
/common:ralph-run "Implement user authentication"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Direct Script
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
./Tools/Ralph/ralph.sh "Implement user authentication"
|
|
46
|
+
./Tools/Ralph/ralph.sh --lang=fr --verbose "Corriger le bug de connexion"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Configuration
|
|
50
|
+
|
|
51
|
+
Create `ralph.yml` in your project root or `.claude/ralph.yml`:
|
|
52
|
+
|
|
53
|
+
```yaml
|
|
54
|
+
version: "1.0"
|
|
55
|
+
|
|
56
|
+
session:
|
|
57
|
+
max_iterations: 25
|
|
58
|
+
timeout: 600000 # 10 minutes per iteration
|
|
59
|
+
delay_between_iterations: 1000
|
|
60
|
+
|
|
61
|
+
circuit_breaker:
|
|
62
|
+
enabled: true
|
|
63
|
+
no_file_changes_threshold: 3
|
|
64
|
+
repeated_error_threshold: 5
|
|
65
|
+
output_decline_threshold: 70
|
|
66
|
+
|
|
67
|
+
checkpointing:
|
|
68
|
+
enabled: true
|
|
69
|
+
async: true
|
|
70
|
+
branch_prefix: "ralph/"
|
|
71
|
+
|
|
72
|
+
definition_of_done:
|
|
73
|
+
checklist:
|
|
74
|
+
- id: tests
|
|
75
|
+
name: "All tests pass"
|
|
76
|
+
type: command
|
|
77
|
+
command: "docker compose exec app npm test"
|
|
78
|
+
required: true
|
|
79
|
+
|
|
80
|
+
- id: lint
|
|
81
|
+
name: "No lint errors"
|
|
82
|
+
type: command
|
|
83
|
+
command: "docker compose exec app npm run lint"
|
|
84
|
+
required: true
|
|
85
|
+
|
|
86
|
+
- id: completion
|
|
87
|
+
name: "Claude signals completion"
|
|
88
|
+
type: output_contains
|
|
89
|
+
pattern: "<promise>COMPLETE</promise>"
|
|
90
|
+
required: true
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Definition of Done (DoD)
|
|
94
|
+
|
|
95
|
+
The key improvement over simple completion markers. DoD validates task completion through multiple criteria:
|
|
96
|
+
|
|
97
|
+
### Validator Types
|
|
98
|
+
|
|
99
|
+
| Type | Description | Example |
|
|
100
|
+
|------|-------------|---------|
|
|
101
|
+
| `command` | Run shell command, check exit code | `npm test` |
|
|
102
|
+
| `output_contains` | Check Claude output for pattern | `<promise>COMPLETE</promise>` |
|
|
103
|
+
| `file_changed` | Check if files matching pattern changed | `*.md` |
|
|
104
|
+
| `hook` | Run existing Claude hook script | `quality-gate.sh` |
|
|
105
|
+
| `human` | Prompt user for confirmation | Interactive gate |
|
|
106
|
+
|
|
107
|
+
### Example Checklist
|
|
108
|
+
|
|
109
|
+
```yaml
|
|
110
|
+
definition_of_done:
|
|
111
|
+
checklist:
|
|
112
|
+
# Automated tests
|
|
113
|
+
- id: tests
|
|
114
|
+
name: "All tests pass"
|
|
115
|
+
type: command
|
|
116
|
+
command: "docker compose exec app npm test"
|
|
117
|
+
required: true
|
|
118
|
+
|
|
119
|
+
# Code quality
|
|
120
|
+
- id: lint
|
|
121
|
+
name: "No lint errors"
|
|
122
|
+
type: command
|
|
123
|
+
command: "docker compose exec app npm run lint"
|
|
124
|
+
required: true
|
|
125
|
+
|
|
126
|
+
# Completion signal
|
|
127
|
+
- id: completion
|
|
128
|
+
name: "Claude signals completion"
|
|
129
|
+
type: output_contains
|
|
130
|
+
pattern: "<promise>COMPLETE</promise>"
|
|
131
|
+
required: true
|
|
132
|
+
|
|
133
|
+
# Integration with existing hooks
|
|
134
|
+
- id: quality_gate
|
|
135
|
+
name: "Quality gate passes"
|
|
136
|
+
type: hook
|
|
137
|
+
script: ".claude/hooks/quality-gate.sh"
|
|
138
|
+
required: true
|
|
139
|
+
|
|
140
|
+
# Documentation (optional)
|
|
141
|
+
- id: docs
|
|
142
|
+
name: "Documentation updated"
|
|
143
|
+
type: file_changed
|
|
144
|
+
pattern: "*.md"
|
|
145
|
+
required: false
|
|
146
|
+
|
|
147
|
+
# Human approval (optional)
|
|
148
|
+
- id: review
|
|
149
|
+
name: "Manual review approved"
|
|
150
|
+
type: human
|
|
151
|
+
prompt: "Does the implementation look correct? (y/n):"
|
|
152
|
+
required: false
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Circuit Breaker
|
|
156
|
+
|
|
157
|
+
Safety mechanism to prevent infinite loops:
|
|
158
|
+
|
|
159
|
+
| Trigger | Default Threshold | Description |
|
|
160
|
+
|---------|-------------------|-------------|
|
|
161
|
+
| No file changes | 3 iterations | Stops if no files modified |
|
|
162
|
+
| Repeated errors | 5 iterations | Stops on error loops |
|
|
163
|
+
| Output decline | 70% | Stops if output shrinks significantly |
|
|
164
|
+
| Max iterations | 25 | Hard limit |
|
|
165
|
+
|
|
166
|
+
## Git Checkpointing
|
|
167
|
+
|
|
168
|
+
Automatic git commits after each iteration:
|
|
169
|
+
|
|
170
|
+
- **Recovery**: Restore to previous state if needed
|
|
171
|
+
- **History**: Track progress through iterations
|
|
172
|
+
- **Review**: Inspect what changed at each step
|
|
173
|
+
|
|
174
|
+
Configuration:
|
|
175
|
+
|
|
176
|
+
```yaml
|
|
177
|
+
checkpointing:
|
|
178
|
+
enabled: true
|
|
179
|
+
async: true # Non-blocking
|
|
180
|
+
branch_prefix: "ralph/"
|
|
181
|
+
commit_message_template: "checkpoint: Ralph iteration {iteration}"
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## File Structure
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
Tools/Ralph/
|
|
188
|
+
├── ralph.sh # Main entry point
|
|
189
|
+
├── lib/
|
|
190
|
+
│ ├── session.sh # Session management
|
|
191
|
+
│ ├── loop.sh # Core iteration loop
|
|
192
|
+
│ ├── dod-validator.sh # DoD validation
|
|
193
|
+
│ ├── circuit-breaker.sh # Safety mechanism
|
|
194
|
+
│ └── checkpoint.sh # Git checkpointing
|
|
195
|
+
├── templates/
|
|
196
|
+
│ └── ralph.yml.template # Default configuration
|
|
197
|
+
└── README.md # This file
|
|
198
|
+
|
|
199
|
+
Tools/i18n/ralph/
|
|
200
|
+
├── en.sh # English messages
|
|
201
|
+
├── fr.sh # French messages
|
|
202
|
+
├── es.sh # Spanish messages
|
|
203
|
+
├── de.sh # German messages
|
|
204
|
+
└── pt.sh # Portuguese messages
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## CLI Options
|
|
208
|
+
|
|
209
|
+
```
|
|
210
|
+
ralph.sh [options] <prompt>
|
|
211
|
+
|
|
212
|
+
Options:
|
|
213
|
+
--config=<file> Path to ralph.yml configuration
|
|
214
|
+
--continue=<id> Resume existing session
|
|
215
|
+
--max-iterations=<n> Maximum iterations (default: 25)
|
|
216
|
+
--timeout=<ms> Timeout per iteration (default: 600000)
|
|
217
|
+
--verbose Enable verbose output
|
|
218
|
+
--dry-run Show what would be done without executing
|
|
219
|
+
--lang=<code> Language (en, fr, es, de, pt)
|
|
220
|
+
--help Show help message
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Integration
|
|
224
|
+
|
|
225
|
+
### With Existing Hooks
|
|
226
|
+
|
|
227
|
+
Ralph can leverage existing Claude hooks:
|
|
228
|
+
|
|
229
|
+
```yaml
|
|
230
|
+
definition_of_done:
|
|
231
|
+
checklist:
|
|
232
|
+
- id: quality_gate
|
|
233
|
+
type: hook
|
|
234
|
+
script: ".claude/hooks/quality-gate.sh"
|
|
235
|
+
required: true
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### With Sprint Development
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
# In sprint workflow
|
|
242
|
+
/project:sprint-dev 1
|
|
243
|
+
# Ralph handles each task until DoD passes
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### With TDD Coach
|
|
247
|
+
|
|
248
|
+
Ralph follows TDD principles:
|
|
249
|
+
1. Write failing test (RED)
|
|
250
|
+
2. Implement minimum code to pass (GREEN)
|
|
251
|
+
3. Refactor while keeping tests green (REFACTOR)
|
|
252
|
+
|
|
253
|
+
## Session Files
|
|
254
|
+
|
|
255
|
+
Ralph creates a `.ralph/` directory in your project:
|
|
256
|
+
|
|
257
|
+
```
|
|
258
|
+
.ralph/
|
|
259
|
+
├── sessions/
|
|
260
|
+
│ └── ralph-1704067200-a1b2/
|
|
261
|
+
│ ├── state.json # Session state
|
|
262
|
+
│ ├── metrics.json # Iteration metrics
|
|
263
|
+
│ ├── session.log # Execution log
|
|
264
|
+
│ └── last_output.txt # Last Claude response
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Best Practices
|
|
268
|
+
|
|
269
|
+
1. **Clear task description**: Provide specific, actionable tasks
|
|
270
|
+
2. **Configure DoD**: Define completion criteria in `ralph.yml`
|
|
271
|
+
3. **Use TDD**: Write tests first, let Ralph implement
|
|
272
|
+
4. **Monitor progress**: Watch iteration output for issues
|
|
273
|
+
5. **Set reasonable limits**: Adjust max_iterations for task complexity
|
|
274
|
+
6. **Use Docker**: Run commands in Docker for consistency
|
|
275
|
+
|
|
276
|
+
## Troubleshooting
|
|
277
|
+
|
|
278
|
+
### Ralph stops immediately
|
|
279
|
+
- Check if prompt is provided
|
|
280
|
+
- Verify `ralph.yml` is valid YAML
|
|
281
|
+
|
|
282
|
+
### Circuit breaker triggers too early
|
|
283
|
+
- Increase thresholds in configuration
|
|
284
|
+
- Check if task is making actual progress
|
|
285
|
+
|
|
286
|
+
### DoD never passes
|
|
287
|
+
- Verify commands work manually
|
|
288
|
+
- Check required vs optional criteria
|
|
289
|
+
- Ensure completion marker is output by Claude
|
|
290
|
+
|
|
291
|
+
## Related
|
|
292
|
+
|
|
293
|
+
- `/common:ralph-run` - Command to start Ralph from Claude Code
|
|
294
|
+
- `@ralph-conductor` - Agent for Ralph orchestration
|
|
295
|
+
- `/common:fix-bug-tdd` - TDD-based bug fixing
|
|
296
|
+
- `/project:sprint-dev` - Sprint development with TDD
|
|
297
|
+
|
|
298
|
+
## Credits
|
|
299
|
+
|
|
300
|
+
Inspired by:
|
|
301
|
+
- [anthropics/claude-code/plugins/ralph-wiggum](https://github.com/anthropics/claude-code)
|
|
302
|
+
- [frankbria/ralph-claude-code](https://github.com/frankbria/ralph-claude-code)
|
|
303
|
+
- [mikeyobrien/ralph-orchestrator](https://github.com/mikeyobrien/ralph-orchestrator)
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# Ralph Wiggum - Git Checkpointing Module
|
|
4
|
+
# Creates git checkpoints for recovery and history tracking
|
|
5
|
+
# =============================================================================
|
|
6
|
+
|
|
7
|
+
# Checkpointing configuration
|
|
8
|
+
CP_ENABLED="${CP_ENABLED:-true}"
|
|
9
|
+
CP_ASYNC="${CP_ASYNC:-true}"
|
|
10
|
+
CP_BRANCH_PREFIX="${CP_BRANCH_PREFIX:-ralph/}"
|
|
11
|
+
CP_COMMIT_TEMPLATE="${CP_COMMIT_TEMPLATE:-checkpoint: Ralph iteration {iteration}}"
|
|
12
|
+
|
|
13
|
+
# =============================================================================
|
|
14
|
+
# Initialization
|
|
15
|
+
# =============================================================================
|
|
16
|
+
|
|
17
|
+
init_checkpointing() {
|
|
18
|
+
# Check if git is available
|
|
19
|
+
if ! command -v git &> /dev/null; then
|
|
20
|
+
CP_ENABLED=false
|
|
21
|
+
print_verbose "Git not found, checkpointing disabled"
|
|
22
|
+
return 1
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# Check if we're in a git repository
|
|
26
|
+
if ! git rev-parse --git-dir &> /dev/null; then
|
|
27
|
+
CP_ENABLED=false
|
|
28
|
+
print_verbose "Not in a git repository, checkpointing disabled"
|
|
29
|
+
return 1
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# Load config if available
|
|
33
|
+
if [[ -n "$CONFIG_FILE" && -f "$CONFIG_FILE" ]] && command -v yq &> /dev/null; then
|
|
34
|
+
local enabled=$(yq e '.checkpointing.enabled // ""' "$CONFIG_FILE" 2>/dev/null)
|
|
35
|
+
[[ "$enabled" == "false" ]] && CP_ENABLED=false
|
|
36
|
+
|
|
37
|
+
local async=$(yq e '.checkpointing.async // ""' "$CONFIG_FILE" 2>/dev/null)
|
|
38
|
+
[[ "$async" == "false" ]] && CP_ASYNC=false
|
|
39
|
+
|
|
40
|
+
local prefix=$(yq e '.checkpointing.branch_prefix // ""' "$CONFIG_FILE" 2>/dev/null)
|
|
41
|
+
[[ -n "$prefix" ]] && CP_BRANCH_PREFIX="$prefix"
|
|
42
|
+
|
|
43
|
+
local template=$(yq e '.checkpointing.commit_message_template // ""' "$CONFIG_FILE" 2>/dev/null)
|
|
44
|
+
[[ -n "$template" ]] && CP_COMMIT_TEMPLATE="$template"
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
print_verbose "Checkpointing initialized:"
|
|
48
|
+
print_verbose " - Enabled: $CP_ENABLED"
|
|
49
|
+
print_verbose " - Async: $CP_ASYNC"
|
|
50
|
+
print_verbose " - Branch prefix: $CP_BRANCH_PREFIX"
|
|
51
|
+
|
|
52
|
+
return 0
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
# =============================================================================
|
|
56
|
+
# Create Checkpoint
|
|
57
|
+
# =============================================================================
|
|
58
|
+
|
|
59
|
+
create_checkpoint() {
|
|
60
|
+
local session_id="$1"
|
|
61
|
+
local iteration="$2"
|
|
62
|
+
|
|
63
|
+
if [[ "$CP_ENABLED" != "true" ]]; then
|
|
64
|
+
return 0
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
# Check for changes to commit
|
|
68
|
+
if [[ -z "$(git status --porcelain 2>/dev/null)" ]]; then
|
|
69
|
+
print_verbose "No changes to checkpoint"
|
|
70
|
+
return 0
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
# Generate commit message
|
|
74
|
+
local commit_msg="${CP_COMMIT_TEMPLATE/\{iteration\}/$iteration}"
|
|
75
|
+
commit_msg="${commit_msg/\{session_id\}/$session_id}"
|
|
76
|
+
|
|
77
|
+
if [[ "$CP_ASYNC" == "true" ]]; then
|
|
78
|
+
# Run checkpoint in background
|
|
79
|
+
_create_checkpoint_async "$session_id" "$iteration" "$commit_msg" &
|
|
80
|
+
print_verbose "${MSG_CHECKPOINT_CREATING} (async)"
|
|
81
|
+
else
|
|
82
|
+
# Run checkpoint synchronously
|
|
83
|
+
_create_checkpoint_sync "$session_id" "$iteration" "$commit_msg"
|
|
84
|
+
fi
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
# =============================================================================
|
|
88
|
+
# Synchronous Checkpoint
|
|
89
|
+
# =============================================================================
|
|
90
|
+
|
|
91
|
+
_create_checkpoint_sync() {
|
|
92
|
+
local session_id="$1"
|
|
93
|
+
local iteration="$2"
|
|
94
|
+
local commit_msg="$3"
|
|
95
|
+
|
|
96
|
+
print_verbose "${MSG_CHECKPOINT_CREATING}"
|
|
97
|
+
|
|
98
|
+
# Stage all changes
|
|
99
|
+
git add -A 2>/dev/null
|
|
100
|
+
|
|
101
|
+
# Create commit
|
|
102
|
+
local commit_hash
|
|
103
|
+
commit_hash=$(git commit -m "$commit_msg" 2>/dev/null && git rev-parse --short HEAD)
|
|
104
|
+
|
|
105
|
+
if [[ -n "$commit_hash" ]]; then
|
|
106
|
+
print_verbose "${MSG_CHECKPOINT_CREATED}: $commit_hash"
|
|
107
|
+
log_session "$session_id" "INFO" "Checkpoint created: $commit_hash"
|
|
108
|
+
else
|
|
109
|
+
print_verbose "${MSG_CHECKPOINT_FAILED}"
|
|
110
|
+
log_session "$session_id" "WARN" "Checkpoint failed"
|
|
111
|
+
fi
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
# =============================================================================
|
|
115
|
+
# Asynchronous Checkpoint
|
|
116
|
+
# =============================================================================
|
|
117
|
+
|
|
118
|
+
_create_checkpoint_async() {
|
|
119
|
+
local session_id="$1"
|
|
120
|
+
local iteration="$2"
|
|
121
|
+
local commit_msg="$3"
|
|
122
|
+
|
|
123
|
+
# Create a lock file to prevent concurrent checkpoints
|
|
124
|
+
local lock_file="/tmp/ralph-checkpoint-$session_id.lock"
|
|
125
|
+
|
|
126
|
+
# Try to acquire lock
|
|
127
|
+
if ! mkdir "$lock_file" 2>/dev/null; then
|
|
128
|
+
# Another checkpoint is in progress
|
|
129
|
+
return 0
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
# Cleanup function
|
|
133
|
+
cleanup() {
|
|
134
|
+
rmdir "$lock_file" 2>/dev/null
|
|
135
|
+
}
|
|
136
|
+
trap cleanup EXIT
|
|
137
|
+
|
|
138
|
+
# Stage all changes
|
|
139
|
+
git add -A 2>/dev/null
|
|
140
|
+
|
|
141
|
+
# Create commit
|
|
142
|
+
git commit -m "$commit_msg" 2>/dev/null
|
|
143
|
+
|
|
144
|
+
# Log result
|
|
145
|
+
if [[ $? -eq 0 ]]; then
|
|
146
|
+
local commit_hash=$(git rev-parse --short HEAD 2>/dev/null)
|
|
147
|
+
log_session "$session_id" "INFO" "Async checkpoint created: $commit_hash"
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
cleanup
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
# =============================================================================
|
|
154
|
+
# Restore from Checkpoint
|
|
155
|
+
# =============================================================================
|
|
156
|
+
|
|
157
|
+
restore_checkpoint() {
|
|
158
|
+
local session_id="$1"
|
|
159
|
+
local commit_hash="$2"
|
|
160
|
+
|
|
161
|
+
if [[ "$CP_ENABLED" != "true" ]]; then
|
|
162
|
+
print_error "Checkpointing is disabled"
|
|
163
|
+
return 1
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
print_info "${MSG_CHECKPOINT_RESTORING}"
|
|
167
|
+
|
|
168
|
+
# Verify commit exists
|
|
169
|
+
if ! git cat-file -e "$commit_hash" 2>/dev/null; then
|
|
170
|
+
print_error "Commit not found: $commit_hash"
|
|
171
|
+
return 1
|
|
172
|
+
fi
|
|
173
|
+
|
|
174
|
+
# Create a backup branch of current state
|
|
175
|
+
local backup_branch="ralph-backup-$(date +%s)"
|
|
176
|
+
git branch "$backup_branch" 2>/dev/null
|
|
177
|
+
|
|
178
|
+
# Reset to the checkpoint
|
|
179
|
+
if git reset --hard "$commit_hash" 2>/dev/null; then
|
|
180
|
+
print_success "${MSG_CHECKPOINT_RESTORED}"
|
|
181
|
+
log_session "$session_id" "INFO" "Restored to checkpoint: $commit_hash (backup: $backup_branch)"
|
|
182
|
+
return 0
|
|
183
|
+
else
|
|
184
|
+
print_error "${MSG_CHECKPOINT_FAILED}"
|
|
185
|
+
return 1
|
|
186
|
+
fi
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
# =============================================================================
|
|
190
|
+
# List Checkpoints
|
|
191
|
+
# =============================================================================
|
|
192
|
+
|
|
193
|
+
list_checkpoints() {
|
|
194
|
+
local session_id="$1"
|
|
195
|
+
|
|
196
|
+
if [[ "$CP_ENABLED" != "true" ]]; then
|
|
197
|
+
echo "[]"
|
|
198
|
+
return
|
|
199
|
+
fi
|
|
200
|
+
|
|
201
|
+
# Find commits matching the checkpoint pattern
|
|
202
|
+
local commits
|
|
203
|
+
commits=$(git log --oneline --grep="checkpoint: Ralph" 2>/dev/null | head -20)
|
|
204
|
+
|
|
205
|
+
if [[ -n "$commits" ]]; then
|
|
206
|
+
echo "$commits" | while read -r line; do
|
|
207
|
+
local hash=$(echo "$line" | cut -d' ' -f1)
|
|
208
|
+
local msg=$(echo "$line" | cut -d' ' -f2-)
|
|
209
|
+
echo "{\"hash\":\"$hash\",\"message\":\"$msg\"}"
|
|
210
|
+
done | jq -s '.'
|
|
211
|
+
else
|
|
212
|
+
echo "[]"
|
|
213
|
+
fi
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
# =============================================================================
|
|
217
|
+
# Create Branch for Session
|
|
218
|
+
# =============================================================================
|
|
219
|
+
|
|
220
|
+
create_session_branch() {
|
|
221
|
+
local session_id="$1"
|
|
222
|
+
local branch_name="${CP_BRANCH_PREFIX}${session_id}"
|
|
223
|
+
|
|
224
|
+
if [[ "$CP_ENABLED" != "true" ]]; then
|
|
225
|
+
return 1
|
|
226
|
+
fi
|
|
227
|
+
|
|
228
|
+
# Check if branch already exists
|
|
229
|
+
if git show-ref --verify --quiet "refs/heads/$branch_name" 2>/dev/null; then
|
|
230
|
+
# Switch to existing branch
|
|
231
|
+
git checkout "$branch_name" 2>/dev/null
|
|
232
|
+
else
|
|
233
|
+
# Create new branch
|
|
234
|
+
git checkout -b "$branch_name" 2>/dev/null
|
|
235
|
+
fi
|
|
236
|
+
|
|
237
|
+
print_verbose "${MSG_CHECKPOINT_BRANCH}: $branch_name"
|
|
238
|
+
}
|