anvil-dev-framework 0.1.6
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/README.md +719 -0
- package/VERSION +1 -0
- package/docs/ANVIL-REPO-IMPLEMENTATION-PLAN.md +441 -0
- package/docs/FIRST-SKILL-TUTORIAL.md +408 -0
- package/docs/INSTALLATION-RETRO-NOTES.md +458 -0
- package/docs/INSTALLATION.md +984 -0
- package/docs/anvil-hud.md +469 -0
- package/docs/anvil-init.md +255 -0
- package/docs/anvil-state.md +210 -0
- package/docs/boris-cherny-ralph-wiggum-insights.md +608 -0
- package/docs/command-reference.md +2022 -0
- package/docs/hooks-tts.md +368 -0
- package/docs/implementation-guide.md +810 -0
- package/docs/linear-github-integration.md +247 -0
- package/docs/local-issues.md +677 -0
- package/docs/patterns/README.md +419 -0
- package/docs/planning-responsibilities.md +139 -0
- package/docs/session-workflow.md +573 -0
- package/docs/simplification-plan-template.md +297 -0
- package/docs/simplification-principles.md +129 -0
- package/docs/specifications/CCS-RALPH-INTEGRATION-DESIGN.md +633 -0
- package/docs/specifications/CCS-RESEARCH-REPORT.md +169 -0
- package/docs/specifications/PLAN-ANV-verification-ralph-wiggum.md +403 -0
- package/docs/specifications/PLAN-parallel-tracks-anvil-memory-ccs.md +494 -0
- package/docs/specifications/SPEC-ANV-VRW/component-01-verify.md +208 -0
- package/docs/specifications/SPEC-ANV-VRW/component-02-stop-gate.md +226 -0
- package/docs/specifications/SPEC-ANV-VRW/component-03-posttooluse.md +209 -0
- package/docs/specifications/SPEC-ANV-VRW/component-04-ralph-wiggum.md +604 -0
- package/docs/specifications/SPEC-ANV-VRW/component-05-atomic-actions.md +311 -0
- package/docs/specifications/SPEC-ANV-VRW/component-06-verify-subagent.md +264 -0
- package/docs/specifications/SPEC-ANV-VRW/component-07-claude-md.md +363 -0
- package/docs/specifications/SPEC-ANV-VRW/index.md +182 -0
- package/docs/specifications/SPEC-ANV-anvil-memory.md +573 -0
- package/docs/specifications/SPEC-ANV-context-checkpoints.md +781 -0
- package/docs/specifications/SPEC-ANV-verification-ralph-wiggum.md +789 -0
- package/docs/sync.md +122 -0
- package/global/CLAUDE.md +140 -0
- package/global/agents/verify-app.md +164 -0
- package/global/commands/anvil-settings.md +527 -0
- package/global/commands/anvil-sync.md +121 -0
- package/global/commands/change.md +197 -0
- package/global/commands/clarify.md +252 -0
- package/global/commands/cleanup.md +292 -0
- package/global/commands/commit-push-pr.md +207 -0
- package/global/commands/decay-review.md +127 -0
- package/global/commands/discover.md +158 -0
- package/global/commands/doc-coverage.md +122 -0
- package/global/commands/evidence.md +307 -0
- package/global/commands/explore.md +121 -0
- package/global/commands/force-exit.md +135 -0
- package/global/commands/handoff.md +191 -0
- package/global/commands/healthcheck.md +302 -0
- package/global/commands/hud.md +84 -0
- package/global/commands/insights.md +319 -0
- package/global/commands/linear-setup.md +184 -0
- package/global/commands/lint-fix.md +198 -0
- package/global/commands/orient.md +510 -0
- package/global/commands/plan.md +228 -0
- package/global/commands/ralph.md +346 -0
- package/global/commands/ready.md +182 -0
- package/global/commands/release.md +305 -0
- package/global/commands/retro.md +96 -0
- package/global/commands/shard.md +166 -0
- package/global/commands/spec.md +227 -0
- package/global/commands/sprint.md +184 -0
- package/global/commands/tasks.md +228 -0
- package/global/commands/test-and-commit.md +151 -0
- package/global/commands/validate.md +132 -0
- package/global/commands/verify.md +251 -0
- package/global/commands/weekly-review.md +156 -0
- package/global/hooks/__pycache__/ralph_context_monitor.cpython-314.pyc +0 -0
- package/global/hooks/__pycache__/statusline_agent_sync.cpython-314.pyc +0 -0
- package/global/hooks/anvil_memory_observe.ts +322 -0
- package/global/hooks/anvil_memory_session.ts +166 -0
- package/global/hooks/anvil_memory_stop.ts +187 -0
- package/global/hooks/parse_transcript.py +116 -0
- package/global/hooks/post_merge_cleanup.sh +132 -0
- package/global/hooks/post_tool_format.sh +215 -0
- package/global/hooks/ralph_context_monitor.py +240 -0
- package/global/hooks/ralph_stop.sh +502 -0
- package/global/hooks/statusline.sh +1110 -0
- package/global/hooks/statusline_agent_sync.py +224 -0
- package/global/hooks/stop_gate.sh +250 -0
- package/global/lib/.claude/anvil-state.json +21 -0
- package/global/lib/__pycache__/agent_registry.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/claim_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/coderabbit_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/config_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/coordination_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/doc_coverage_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/gate_logger.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/github_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/hygiene_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/issue_models.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/issue_provider.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/linear_data_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/linear_provider.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/local_provider.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/quality_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/ralph_state.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/state_manager.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/transcript_parser.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/verification_runner.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/verify_iteration.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/verify_subagent.cpython-314.pyc +0 -0
- package/global/lib/agent_registry.py +995 -0
- package/global/lib/anvil-state.sh +435 -0
- package/global/lib/claim_service.py +515 -0
- package/global/lib/coderabbit_service.py +314 -0
- package/global/lib/config_service.py +423 -0
- package/global/lib/coordination_service.py +331 -0
- package/global/lib/doc_coverage_service.py +1305 -0
- package/global/lib/gate_logger.py +316 -0
- package/global/lib/github_service.py +310 -0
- package/global/lib/handoff_generator.py +775 -0
- package/global/lib/hygiene_service.py +712 -0
- package/global/lib/issue_models.py +257 -0
- package/global/lib/issue_provider.py +339 -0
- package/global/lib/linear_data_service.py +210 -0
- package/global/lib/linear_provider.py +987 -0
- package/global/lib/linear_provider.py.backup +671 -0
- package/global/lib/local_provider.py +486 -0
- package/global/lib/orient_fast.py +457 -0
- package/global/lib/quality_service.py +470 -0
- package/global/lib/ralph_prompt_generator.py +563 -0
- package/global/lib/ralph_state.py +1202 -0
- package/global/lib/state_manager.py +417 -0
- package/global/lib/transcript_parser.py +597 -0
- package/global/lib/verification_runner.py +557 -0
- package/global/lib/verify_iteration.py +490 -0
- package/global/lib/verify_subagent.py +250 -0
- package/global/skills/README.md +155 -0
- package/global/skills/quality-gates/SKILL.md +252 -0
- package/global/skills/skill-template/SKILL.md +109 -0
- package/global/skills/testing-strategies/SKILL.md +337 -0
- package/global/templates/CHANGE-template.md +105 -0
- package/global/templates/HANDOFF-template.md +63 -0
- package/global/templates/PLAN-template.md +111 -0
- package/global/templates/SPEC-template.md +93 -0
- package/global/templates/ralph/PROMPT.md.template +89 -0
- package/global/templates/ralph/fix_plan.md.template +31 -0
- package/global/templates/ralph/progress.txt.template +23 -0
- package/global/tests/__pycache__/test_doc_coverage.cpython-314.pyc +0 -0
- package/global/tests/test_doc_coverage.py +520 -0
- package/global/tests/test_issue_models.py +299 -0
- package/global/tests/test_local_provider.py +323 -0
- package/global/tools/README.md +178 -0
- package/global/tools/__pycache__/anvil-hud.cpython-314.pyc +0 -0
- package/global/tools/anvil-hud.py +3622 -0
- package/global/tools/anvil-hud.py.bak +3318 -0
- package/global/tools/anvil-issue.py +432 -0
- package/global/tools/anvil-memory/CLAUDE.md +49 -0
- package/global/tools/anvil-memory/README.md +42 -0
- package/global/tools/anvil-memory/bun.lock +25 -0
- package/global/tools/anvil-memory/bunfig.toml +9 -0
- package/global/tools/anvil-memory/package.json +23 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/context-monitor.test.ts +535 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/edge-cases.test.ts +645 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/fixtures.ts +363 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/index.ts +8 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/integration.test.ts +417 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/prompt-generator.test.ts +571 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/ralph-stop.test.ts +440 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/test-utils.ts +252 -0
- package/global/tools/anvil-memory/src/__tests__/commands.test.ts +657 -0
- package/global/tools/anvil-memory/src/__tests__/db.test.ts +641 -0
- package/global/tools/anvil-memory/src/__tests__/hooks.test.ts +272 -0
- package/global/tools/anvil-memory/src/__tests__/performance.test.ts +427 -0
- package/global/tools/anvil-memory/src/__tests__/test-utils.ts +113 -0
- package/global/tools/anvil-memory/src/commands/checkpoint.ts +197 -0
- package/global/tools/anvil-memory/src/commands/get.ts +115 -0
- package/global/tools/anvil-memory/src/commands/init.ts +94 -0
- package/global/tools/anvil-memory/src/commands/observe.ts +163 -0
- package/global/tools/anvil-memory/src/commands/search.ts +112 -0
- package/global/tools/anvil-memory/src/db.ts +638 -0
- package/global/tools/anvil-memory/src/index.ts +205 -0
- package/global/tools/anvil-memory/src/types.ts +122 -0
- package/global/tools/anvil-memory/tsconfig.json +29 -0
- package/global/tools/ralph-loop.sh +359 -0
- package/package.json +45 -0
- package/scripts/anvil +822 -0
- package/scripts/extract_patterns.py +222 -0
- package/scripts/init-project.sh +541 -0
- package/scripts/install.sh +229 -0
- package/scripts/postinstall.js +41 -0
- package/scripts/rollback.sh +188 -0
- package/scripts/sync.sh +623 -0
- package/scripts/test-statusline.sh +248 -0
- package/scripts/update_claude_md.py +224 -0
- package/scripts/verify.sh +255 -0
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# ralph-loop.sh - Ralph Wiggum Execution Loop (ANV-163)
|
|
4
|
+
# =============================================================================
|
|
5
|
+
#
|
|
6
|
+
# External loop that runs Claude Code in print mode, feeding PROMPT.md each
|
|
7
|
+
# iteration. The ralph_stop.sh hook handles continuation/exit decisions.
|
|
8
|
+
#
|
|
9
|
+
# Usage:
|
|
10
|
+
# ./ralph-loop.sh [options]
|
|
11
|
+
#
|
|
12
|
+
# Options:
|
|
13
|
+
# --prompt FILE Path to prompt file (default: PROMPT.md)
|
|
14
|
+
# --max-iterations N Override max iterations (default: env or 50)
|
|
15
|
+
# --completion TEXT Override completion promise (default: env or COMPLETE)
|
|
16
|
+
# --dry-run Show what would run without executing
|
|
17
|
+
# --verbose Enable verbose output
|
|
18
|
+
#
|
|
19
|
+
# Environment Variables:
|
|
20
|
+
# RALPH_MAX_ITERATIONS Max iterations (default: 50)
|
|
21
|
+
# RALPH_COMPLETION_PROMISE Completion text (default: COMPLETE)
|
|
22
|
+
# RALPH_STATE_FILE State file path (default: .claude/ralph-state.json)
|
|
23
|
+
# RALPH_ENABLE_LOGGING Enable logging (default: false)
|
|
24
|
+
#
|
|
25
|
+
# Exit Codes:
|
|
26
|
+
# 0 - Task completed successfully (promise detected)
|
|
27
|
+
# 1 - Error or circuit breaker triggered
|
|
28
|
+
# 2 - Manual interruption (Ctrl+C)
|
|
29
|
+
#
|
|
30
|
+
# Dependencies:
|
|
31
|
+
# - Claude Code CLI (@anthropic/claude-code)
|
|
32
|
+
# - jq (for state management)
|
|
33
|
+
#
|
|
34
|
+
# =============================================================================
|
|
35
|
+
|
|
36
|
+
set -euo pipefail
|
|
37
|
+
|
|
38
|
+
# =============================================================================
|
|
39
|
+
# Configuration
|
|
40
|
+
# =============================================================================
|
|
41
|
+
|
|
42
|
+
PROMPT_FILE="PROMPT.md" # Default, may be overridden by --prompt
|
|
43
|
+
MAX_ITERATIONS="${RALPH_MAX_ITERATIONS:-50}"
|
|
44
|
+
COMPLETION_PROMISE="${RALPH_COMPLETION_PROMISE:-COMPLETE}"
|
|
45
|
+
STATE_FILE="${RALPH_STATE_FILE:-.claude/ralph-state.json}"
|
|
46
|
+
ENABLE_LOGGING="${RALPH_ENABLE_LOGGING:-false}"
|
|
47
|
+
LOG_FILE=".claude/logs/ralph-loop.log"
|
|
48
|
+
|
|
49
|
+
DRY_RUN=false
|
|
50
|
+
VERBOSE=false
|
|
51
|
+
|
|
52
|
+
# Parse arguments
|
|
53
|
+
while [[ $# -gt 0 ]]; do
|
|
54
|
+
case $1 in
|
|
55
|
+
--prompt)
|
|
56
|
+
PROMPT_FILE="$2"
|
|
57
|
+
shift 2
|
|
58
|
+
;;
|
|
59
|
+
--max-iterations)
|
|
60
|
+
MAX_ITERATIONS="$2"
|
|
61
|
+
shift 2
|
|
62
|
+
;;
|
|
63
|
+
--completion)
|
|
64
|
+
COMPLETION_PROMISE="$2"
|
|
65
|
+
shift 2
|
|
66
|
+
;;
|
|
67
|
+
--dry-run)
|
|
68
|
+
DRY_RUN=true
|
|
69
|
+
shift
|
|
70
|
+
;;
|
|
71
|
+
--verbose)
|
|
72
|
+
VERBOSE=true
|
|
73
|
+
shift
|
|
74
|
+
;;
|
|
75
|
+
--help|-h)
|
|
76
|
+
head -50 "$0" | grep -E "^#" | sed 's/^# //' | sed 's/^#//'
|
|
77
|
+
exit 0
|
|
78
|
+
;;
|
|
79
|
+
*)
|
|
80
|
+
# First positional arg is prompt file
|
|
81
|
+
if [[ ! "$1" =~ ^-- ]]; then
|
|
82
|
+
PROMPT_FILE="$1"
|
|
83
|
+
fi
|
|
84
|
+
shift
|
|
85
|
+
;;
|
|
86
|
+
esac
|
|
87
|
+
done
|
|
88
|
+
|
|
89
|
+
# Export for child processes (hooks)
|
|
90
|
+
export RALPH_MAX_ITERATIONS="$MAX_ITERATIONS"
|
|
91
|
+
export RALPH_COMPLETION_PROMISE="$COMPLETION_PROMISE"
|
|
92
|
+
export RALPH_STATE_FILE="$STATE_FILE"
|
|
93
|
+
export RALPH_ENABLE_LOGGING="$ENABLE_LOGGING"
|
|
94
|
+
|
|
95
|
+
# =============================================================================
|
|
96
|
+
# Utilities
|
|
97
|
+
# =============================================================================
|
|
98
|
+
|
|
99
|
+
log() {
|
|
100
|
+
local level="$1"
|
|
101
|
+
local message="$2"
|
|
102
|
+
local timestamp
|
|
103
|
+
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
104
|
+
|
|
105
|
+
if [[ "$ENABLE_LOGGING" == "true" ]]; then
|
|
106
|
+
mkdir -p "$(dirname "$LOG_FILE")"
|
|
107
|
+
echo "[$timestamp] [$level] $message" >> "$LOG_FILE"
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
if [[ "$VERBOSE" == "true" ]] || [[ "$level" == "ERROR" ]]; then
|
|
111
|
+
case "$level" in
|
|
112
|
+
ERROR) echo "❌ Ralph Loop: $message" >&2 ;;
|
|
113
|
+
WARN) echo "⚠️ Ralph Loop: $message" >&2 ;;
|
|
114
|
+
INFO) echo "🔄 Ralph Loop: $message" ;;
|
|
115
|
+
OK) echo "✅ Ralph Loop: $message" ;;
|
|
116
|
+
esac
|
|
117
|
+
fi
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
check_dependencies() {
|
|
121
|
+
local missing=()
|
|
122
|
+
|
|
123
|
+
if ! command -v npx &> /dev/null; then
|
|
124
|
+
missing+=("npx (Node.js)")
|
|
125
|
+
fi
|
|
126
|
+
|
|
127
|
+
if ! command -v jq &> /dev/null; then
|
|
128
|
+
missing+=("jq")
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
if [[ ${#missing[@]} -gt 0 ]]; then
|
|
132
|
+
log "ERROR" "Missing dependencies: ${missing[*]}"
|
|
133
|
+
echo "Install missing dependencies:" >&2
|
|
134
|
+
echo " - npx: Install Node.js (https://nodejs.org)" >&2
|
|
135
|
+
echo " - jq: apt install jq (Linux) or brew install jq (macOS)" >&2
|
|
136
|
+
exit 1
|
|
137
|
+
fi
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
check_prompt_file() {
|
|
141
|
+
if [[ ! -f "$PROMPT_FILE" ]]; then
|
|
142
|
+
log "ERROR" "Prompt file not found: $PROMPT_FILE"
|
|
143
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
144
|
+
echo "⚠️ Prompt file not found: $PROMPT_FILE (dry-run mode, continuing)" >&2
|
|
145
|
+
else
|
|
146
|
+
echo "Create the prompt file first:" >&2
|
|
147
|
+
echo " 1. Run /ralph start to set up files" >&2
|
|
148
|
+
echo " 2. Or create $PROMPT_FILE manually" >&2
|
|
149
|
+
exit 1
|
|
150
|
+
fi
|
|
151
|
+
fi
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
# =============================================================================
|
|
155
|
+
# State Management
|
|
156
|
+
# =============================================================================
|
|
157
|
+
|
|
158
|
+
init_state() {
|
|
159
|
+
if [[ ! -f "$STATE_FILE" ]]; then
|
|
160
|
+
mkdir -p "$(dirname "$STATE_FILE")"
|
|
161
|
+
local timestamp
|
|
162
|
+
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
163
|
+
cat > "$STATE_FILE" << EOF
|
|
164
|
+
{
|
|
165
|
+
"task_name": "ralph-task",
|
|
166
|
+
"objective": "Complete the task defined in PROMPT.md",
|
|
167
|
+
"iteration": 0,
|
|
168
|
+
"started_at": "$timestamp",
|
|
169
|
+
"status": "running",
|
|
170
|
+
"no_change_count": 0,
|
|
171
|
+
"last_diff_hash": "",
|
|
172
|
+
"error_hashes": []
|
|
173
|
+
}
|
|
174
|
+
EOF
|
|
175
|
+
log "INFO" "Initialized state file: $STATE_FILE"
|
|
176
|
+
fi
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
read_state() {
|
|
180
|
+
local key="$1"
|
|
181
|
+
local default="${2:-}"
|
|
182
|
+
jq -r ".$key // \"$default\"" "$STATE_FILE" 2>/dev/null || echo "$default"
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
get_iteration() {
|
|
186
|
+
read_state "iteration" "0"
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
get_status() {
|
|
190
|
+
read_state "status" "unknown"
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
# =============================================================================
|
|
194
|
+
# Signal Handling
|
|
195
|
+
# =============================================================================
|
|
196
|
+
|
|
197
|
+
cleanup() {
|
|
198
|
+
log "WARN" "Interrupted! Cleaning up..."
|
|
199
|
+
|
|
200
|
+
# Update state to reflect interruption
|
|
201
|
+
if [[ -f "$STATE_FILE" ]]; then
|
|
202
|
+
jq '.status = "interrupted"' "$STATE_FILE" > tmp.$$ && mv tmp.$$ "$STATE_FILE"
|
|
203
|
+
fi
|
|
204
|
+
|
|
205
|
+
echo ""
|
|
206
|
+
echo "╔══════════════════════════════════════════════════════════════╗"
|
|
207
|
+
echo "║ RALPH LOOP INTERRUPTED ║"
|
|
208
|
+
echo "╠══════════════════════════════════════════════════════════════╣"
|
|
209
|
+
echo "║ The loop was interrupted by user (Ctrl+C). ║"
|
|
210
|
+
echo "║ ║"
|
|
211
|
+
echo "║ Current iteration: $(printf '%-3s' "$(get_iteration)")" "║"
|
|
212
|
+
echo "║ State file: $STATE_FILE"
|
|
213
|
+
echo "║ ║"
|
|
214
|
+
echo "║ To resume: ./ralph-loop.sh ║"
|
|
215
|
+
echo "║ To stop: rm $STATE_FILE ║"
|
|
216
|
+
echo "╚══════════════════════════════════════════════════════════════╝"
|
|
217
|
+
|
|
218
|
+
exit 2
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
trap cleanup SIGINT SIGTERM
|
|
222
|
+
|
|
223
|
+
# =============================================================================
|
|
224
|
+
# Main Loop
|
|
225
|
+
# =============================================================================
|
|
226
|
+
|
|
227
|
+
run_iteration() {
|
|
228
|
+
local iteration="$1"
|
|
229
|
+
|
|
230
|
+
log "INFO" "Starting iteration $iteration"
|
|
231
|
+
|
|
232
|
+
if [[ "$DRY_RUN" == "true" ]]; then
|
|
233
|
+
echo "[DRY RUN] Would execute: cat $PROMPT_FILE | npx --yes @anthropic-ai/claude-code --print"
|
|
234
|
+
return 0
|
|
235
|
+
fi
|
|
236
|
+
|
|
237
|
+
# Run Claude Code with the prompt
|
|
238
|
+
# The --print flag runs in non-interactive mode
|
|
239
|
+
# Exit code from Claude Code is handled by the stop hook
|
|
240
|
+
local exit_code=0
|
|
241
|
+
cat "$PROMPT_FILE" | npx --yes @anthropic-ai/claude-code --print || exit_code=$?
|
|
242
|
+
|
|
243
|
+
return $exit_code
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
main() {
|
|
247
|
+
echo "╔══════════════════════════════════════════════════════════════╗"
|
|
248
|
+
echo "║ RALPH WIGGUM LOOP ║"
|
|
249
|
+
echo "╠══════════════════════════════════════════════════════════════╣"
|
|
250
|
+
echo "║ Starting autonomous execution loop. ║"
|
|
251
|
+
echo "║ ║"
|
|
252
|
+
echo "║ Prompt file: $PROMPT_FILE"
|
|
253
|
+
echo "║ Max iterations: $MAX_ITERATIONS"
|
|
254
|
+
echo "║ Completion text: $COMPLETION_PROMISE"
|
|
255
|
+
echo "║ ║"
|
|
256
|
+
echo "║ Press Ctrl+C to interrupt safely. ║"
|
|
257
|
+
echo "╚══════════════════════════════════════════════════════════════╝"
|
|
258
|
+
echo ""
|
|
259
|
+
|
|
260
|
+
check_dependencies
|
|
261
|
+
check_prompt_file
|
|
262
|
+
init_state
|
|
263
|
+
|
|
264
|
+
local iteration=0
|
|
265
|
+
local start_iteration
|
|
266
|
+
start_iteration=$(get_iteration)
|
|
267
|
+
|
|
268
|
+
if [[ $start_iteration -gt 0 ]]; then
|
|
269
|
+
iteration=$start_iteration
|
|
270
|
+
log "INFO" "Resuming from iteration $iteration"
|
|
271
|
+
fi
|
|
272
|
+
|
|
273
|
+
while true; do
|
|
274
|
+
iteration=$((iteration + 1))
|
|
275
|
+
|
|
276
|
+
# Check max iterations before running
|
|
277
|
+
if [[ $iteration -gt $MAX_ITERATIONS ]]; then
|
|
278
|
+
log "WARN" "Maximum iterations ($MAX_ITERATIONS) reached"
|
|
279
|
+
echo ""
|
|
280
|
+
echo "══════════════════════════════════════════════════════════════"
|
|
281
|
+
echo " RALPH LOOP STOPPED: Maximum iterations reached"
|
|
282
|
+
echo "══════════════════════════════════════════════════════════════"
|
|
283
|
+
exit 1
|
|
284
|
+
fi
|
|
285
|
+
|
|
286
|
+
echo ""
|
|
287
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
288
|
+
echo " ITERATION $iteration of $MAX_ITERATIONS"
|
|
289
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
290
|
+
echo ""
|
|
291
|
+
|
|
292
|
+
# Run the iteration
|
|
293
|
+
local result=0
|
|
294
|
+
run_iteration "$iteration" || result=$?
|
|
295
|
+
|
|
296
|
+
# Check status after iteration
|
|
297
|
+
local status
|
|
298
|
+
status=$(get_status)
|
|
299
|
+
|
|
300
|
+
case "$status" in
|
|
301
|
+
"completed")
|
|
302
|
+
log "OK" "Task completed successfully!"
|
|
303
|
+
echo ""
|
|
304
|
+
echo "╔══════════════════════════════════════════════════════════════╗"
|
|
305
|
+
echo "║ TASK COMPLETE ║"
|
|
306
|
+
echo "╠══════════════════════════════════════════════════════════════╣"
|
|
307
|
+
echo "║ The completion promise was detected. ║"
|
|
308
|
+
echo "║ Total iterations: $iteration"
|
|
309
|
+
echo "╚══════════════════════════════════════════════════════════════╝"
|
|
310
|
+
exit 0
|
|
311
|
+
;;
|
|
312
|
+
"fatal_error")
|
|
313
|
+
log "ERROR" "Fatal error detected - stopping"
|
|
314
|
+
echo ""
|
|
315
|
+
echo "╔══════════════════════════════════════════════════════════════╗"
|
|
316
|
+
echo "║ FATAL ERROR ║"
|
|
317
|
+
echo "╠══════════════════════════════════════════════════════════════╣"
|
|
318
|
+
echo "║ Claude reported a fatal/unrecoverable error. ║"
|
|
319
|
+
echo "║ Check progress.txt for details. ║"
|
|
320
|
+
echo "╚══════════════════════════════════════════════════════════════╝"
|
|
321
|
+
exit 1
|
|
322
|
+
;;
|
|
323
|
+
"circuit_breaker")
|
|
324
|
+
log "ERROR" "Circuit breaker triggered - stopping"
|
|
325
|
+
echo ""
|
|
326
|
+
echo "╔══════════════════════════════════════════════════════════════╗"
|
|
327
|
+
echo "║ CIRCUIT BREAKER ║"
|
|
328
|
+
echo "╠══════════════════════════════════════════════════════════════╣"
|
|
329
|
+
echo "║ Loop appears stuck (no changes across multiple iterations). ║"
|
|
330
|
+
echo "║ Review progress.txt and fix_plan.md for issues. ║"
|
|
331
|
+
echo "╚══════════════════════════════════════════════════════════════╝"
|
|
332
|
+
exit 1
|
|
333
|
+
;;
|
|
334
|
+
"max_iterations")
|
|
335
|
+
log "WARN" "Maximum iterations reached"
|
|
336
|
+
exit 1
|
|
337
|
+
;;
|
|
338
|
+
"stopped")
|
|
339
|
+
log "INFO" "Manually stopped"
|
|
340
|
+
exit 0
|
|
341
|
+
;;
|
|
342
|
+
*)
|
|
343
|
+
# Status is "running" or unknown - continue loop
|
|
344
|
+
if [[ $result -ne 0 ]]; then
|
|
345
|
+
log "INFO" "Iteration $iteration complete, continuing..."
|
|
346
|
+
fi
|
|
347
|
+
;;
|
|
348
|
+
esac
|
|
349
|
+
|
|
350
|
+
# Small delay between iterations for rate limiting
|
|
351
|
+
sleep 1
|
|
352
|
+
done
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
# =============================================================================
|
|
356
|
+
# Entry Point
|
|
357
|
+
# =============================================================================
|
|
358
|
+
|
|
359
|
+
main "$@"
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "anvil-dev-framework",
|
|
3
|
+
"version": "0.1.6",
|
|
4
|
+
"description": "AI-powered development framework for Claude Code - multi-agent coordination, specifications, and quality gates",
|
|
5
|
+
"author": "Alexander Cahiz",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://github.com/alexandercahiz/anvil-dev-framework",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/alexandercahiz/anvil-dev-framework.git"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"claude",
|
|
14
|
+
"claude-code",
|
|
15
|
+
"ai",
|
|
16
|
+
"development",
|
|
17
|
+
"framework",
|
|
18
|
+
"multi-agent",
|
|
19
|
+
"specifications",
|
|
20
|
+
"quality-gates"
|
|
21
|
+
],
|
|
22
|
+
"bin": {
|
|
23
|
+
"anvil": "./scripts/anvil"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"scripts/",
|
|
27
|
+
"global/",
|
|
28
|
+
"docs/",
|
|
29
|
+
"VERSION",
|
|
30
|
+
"README.md",
|
|
31
|
+
"LICENSE"
|
|
32
|
+
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"postinstall": "node scripts/postinstall.js || true"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=18.0.0",
|
|
38
|
+
"bun": ">=1.0.0"
|
|
39
|
+
},
|
|
40
|
+
"os": [
|
|
41
|
+
"darwin",
|
|
42
|
+
"linux"
|
|
43
|
+
],
|
|
44
|
+
"preferGlobal": true
|
|
45
|
+
}
|