agentic-loop 3.19.0 → 3.22.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.
- package/.claude/commands/tour.md +11 -7
- package/.claude/commands/vibe-help.md +5 -2
- package/.claude/commands/vibe-list.md +17 -2
- package/.claude/skills/prd/SKILL.md +21 -6
- package/.claude/skills/setup-review/SKILL.md +56 -0
- package/.claude/skills/tour/SKILL.md +11 -7
- package/.claude/skills/vibe-help/SKILL.md +2 -1
- package/.claude/skills/vibe-list/SKILL.md +5 -2
- package/.pre-commit-hooks.yaml +8 -0
- package/README.md +4 -0
- package/bin/agentic-loop.sh +7 -0
- package/bin/ralph.sh +29 -0
- package/dist/checks/check-signs-secrets.d.ts +9 -0
- package/dist/checks/check-signs-secrets.d.ts.map +1 -0
- package/dist/checks/check-signs-secrets.js +57 -0
- package/dist/checks/check-signs-secrets.js.map +1 -0
- package/dist/checks/index.d.ts +2 -5
- package/dist/checks/index.d.ts.map +1 -1
- package/dist/checks/index.js +4 -9
- package/dist/checks/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/ralph/hooks/common.sh +47 -0
- package/ralph/hooks/warn-debug.sh +12 -26
- package/ralph/hooks/warn-empty-catch.sh +21 -34
- package/ralph/hooks/warn-secrets.sh +39 -52
- package/ralph/hooks/warn-urls.sh +25 -45
- package/ralph/init.sh +58 -82
- package/ralph/loop.sh +506 -53
- package/ralph/prd-check.sh +177 -236
- package/ralph/prd.sh +5 -2
- package/ralph/setup/quick-setup.sh +2 -16
- package/ralph/setup.sh +68 -80
- package/ralph/signs.sh +8 -0
- package/ralph/uat.sh +2664 -0
- package/ralph/utils.sh +213 -70
- package/ralph/verify/tests.sh +65 -10
- package/templates/PROMPT.md +10 -4
- package/templates/UAT-PROMPT.md +197 -0
- package/templates/config/elixir.json +0 -2
- package/templates/config/fastmcp.json +0 -2
- package/templates/config/fullstack.json +2 -4
- package/templates/config/go.json +0 -2
- package/templates/config/minimal.json +0 -2
- package/templates/config/node.json +0 -2
- package/templates/config/python.json +0 -2
- package/templates/config/rust.json +0 -2
- package/templates/prd-example.json +6 -8
package/ralph/setup.sh
CHANGED
|
@@ -76,6 +76,48 @@ append_prompt_sections() {
|
|
|
76
76
|
fi
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
# Migrate test credentials from config.json to .env
|
|
80
|
+
_migrate_credentials_to_env() {
|
|
81
|
+
local config=".ralph/config.json"
|
|
82
|
+
[[ ! -f "$config" ]] && return 0
|
|
83
|
+
|
|
84
|
+
local test_user test_password
|
|
85
|
+
test_user=$(jq -r '.auth.testUser // empty' "$config" 2>/dev/null)
|
|
86
|
+
test_password=$(jq -r '.auth.testPassword // empty' "$config" 2>/dev/null)
|
|
87
|
+
|
|
88
|
+
# Nothing to migrate
|
|
89
|
+
[[ -z "$test_user" && -z "$test_password" ]] && return 0
|
|
90
|
+
|
|
91
|
+
echo ""
|
|
92
|
+
print_info "Migrating test credentials from config.json to .env..."
|
|
93
|
+
|
|
94
|
+
# Write to .env
|
|
95
|
+
[[ ! -f ".env" ]] && touch ".env"
|
|
96
|
+
|
|
97
|
+
if grep -q "^RALPH_TEST_USER=" .env 2>/dev/null; then
|
|
98
|
+
local tmp
|
|
99
|
+
tmp=$(mktemp)
|
|
100
|
+
grep -v "^RALPH_TEST_USER=\|^RALPH_TEST_PASSWORD=" .env > "$tmp" && mv "$tmp" .env
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
echo "" >> .env
|
|
104
|
+
echo "# Test credentials (migrated from config.json)" >> .env
|
|
105
|
+
[[ -n "$test_user" ]] && printf 'RALPH_TEST_USER=%s\n' "$test_user" >> .env
|
|
106
|
+
[[ -n "$test_password" ]] && printf 'RALPH_TEST_PASSWORD=%s\n' "$test_password" >> .env
|
|
107
|
+
|
|
108
|
+
# Remove from config.json
|
|
109
|
+
local tmpfile
|
|
110
|
+
tmpfile=$(mktemp)
|
|
111
|
+
if jq 'del(.auth.testUser, .auth.testPassword)' "$config" > "$tmpfile" 2>/dev/null; then
|
|
112
|
+
mv "$tmpfile" "$config"
|
|
113
|
+
print_success "Credentials moved to .env and removed from config.json"
|
|
114
|
+
else
|
|
115
|
+
rm -f "$tmpfile"
|
|
116
|
+
print_warning "Moved to .env but couldn't remove from config.json — edit manually"
|
|
117
|
+
fi
|
|
118
|
+
echo ""
|
|
119
|
+
}
|
|
120
|
+
|
|
79
121
|
ralph_setup() {
|
|
80
122
|
echo ""
|
|
81
123
|
echo " _ _ _ _ "
|
|
@@ -119,6 +161,9 @@ ralph_setup() {
|
|
|
119
161
|
fi
|
|
120
162
|
fi
|
|
121
163
|
|
|
164
|
+
# Migrate credentials from config.json to .env if present
|
|
165
|
+
_migrate_credentials_to_env
|
|
166
|
+
|
|
122
167
|
# Run all setup steps
|
|
123
168
|
setup_ralph_dir "$pkg_root"
|
|
124
169
|
setup_custom_checks
|
|
@@ -156,61 +201,19 @@ setup_ralph_dir() {
|
|
|
156
201
|
|
|
157
202
|
# Copy config template based on detected project type
|
|
158
203
|
if [[ ! -f ".ralph/config.json" ]]; then
|
|
159
|
-
local config_template=""
|
|
160
204
|
local detected_type=""
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
config_template="$pkg_root/templates/config/rust.json"
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
config_template="$pkg_root/templates/config/
|
|
172
|
-
|
|
173
|
-
# Check for Python framework variants (more specific first)
|
|
174
|
-
elif [[ -f "pyproject.toml" ]]; then
|
|
175
|
-
if grep -qiE "(fastmcp|\"fastmcp\"|'fastmcp')" pyproject.toml 2>/dev/null; then
|
|
176
|
-
config_template="$pkg_root/templates/config/fastmcp.json"
|
|
177
|
-
detected_type="fastmcp"
|
|
178
|
-
elif grep -qiE "(fastapi|\"fastapi\"|'fastapi')" pyproject.toml 2>/dev/null; then
|
|
179
|
-
config_template="$pkg_root/templates/config/python.json"
|
|
180
|
-
detected_type="fastapi"
|
|
181
|
-
elif grep -qiE "(django|\"django\"|'django')" pyproject.toml 2>/dev/null || [[ -f "manage.py" ]]; then
|
|
182
|
-
config_template="$pkg_root/templates/config/python.json"
|
|
183
|
-
detected_type="django"
|
|
184
|
-
else
|
|
185
|
-
config_template="$pkg_root/templates/config/python.json"
|
|
186
|
-
detected_type="python"
|
|
187
|
-
fi
|
|
188
|
-
elif [[ -f "requirements.txt" ]]; then
|
|
189
|
-
if grep -qi 'fastmcp' requirements.txt 2>/dev/null; then
|
|
190
|
-
config_template="$pkg_root/templates/config/fastmcp.json"
|
|
191
|
-
detected_type="fastmcp"
|
|
192
|
-
elif grep -qi 'fastapi' requirements.txt 2>/dev/null; then
|
|
193
|
-
config_template="$pkg_root/templates/config/python.json"
|
|
194
|
-
detected_type="fastapi"
|
|
195
|
-
elif grep -qi 'django' requirements.txt 2>/dev/null || [[ -f "manage.py" ]]; then
|
|
196
|
-
config_template="$pkg_root/templates/config/python.json"
|
|
197
|
-
detected_type="django"
|
|
198
|
-
else
|
|
199
|
-
config_template="$pkg_root/templates/config/python.json"
|
|
200
|
-
detected_type="python"
|
|
201
|
-
fi
|
|
202
|
-
elif [[ -f "manage.py" ]]; then
|
|
203
|
-
config_template="$pkg_root/templates/config/python.json"
|
|
204
|
-
detected_type="django"
|
|
205
|
-
# Check for fullstack projects
|
|
206
|
-
elif [[ -d "frontend" ]] && [[ -d "backend" || -d "core" || -d "apps" ]]; then
|
|
207
|
-
config_template="$pkg_root/templates/config/fullstack.json"
|
|
208
|
-
detected_type="fullstack"
|
|
209
|
-
# Check for Node projects
|
|
210
|
-
elif [[ -f "package.json" ]]; then
|
|
211
|
-
config_template="$pkg_root/templates/config/node.json"
|
|
212
|
-
detected_type="node"
|
|
213
|
-
fi
|
|
205
|
+
detected_type=$(detect_project_type)
|
|
206
|
+
|
|
207
|
+
# Map project type to config template
|
|
208
|
+
local config_template=""
|
|
209
|
+
case "$detected_type" in
|
|
210
|
+
go|hugo) config_template="$pkg_root/templates/config/go.json" ;;
|
|
211
|
+
rust) config_template="$pkg_root/templates/config/rust.json" ;;
|
|
212
|
+
fastmcp) config_template="$pkg_root/templates/config/fastmcp.json" ;;
|
|
213
|
+
django|fastapi|python) config_template="$pkg_root/templates/config/python.json" ;;
|
|
214
|
+
fullstack) config_template="$pkg_root/templates/config/fullstack.json" ;;
|
|
215
|
+
node) config_template="$pkg_root/templates/config/node.json" ;;
|
|
216
|
+
esac
|
|
214
217
|
|
|
215
218
|
if [[ -n "$config_template" ]] && [[ -f "$config_template" ]]; then
|
|
216
219
|
cp "$config_template" ".ralph/config.json"
|
|
@@ -492,32 +495,15 @@ setup_claude_md() {
|
|
|
492
495
|
grep -q '"express"' "$pkg" 2>/dev/null && framework="${framework:+$framework + }Express"
|
|
493
496
|
fi
|
|
494
497
|
|
|
495
|
-
# Detect Python frameworks
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
framework="${framework:+$framework + }
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
framework="${framework:+$framework + }Django"
|
|
505
|
-
framework_type="django"
|
|
506
|
-
fi
|
|
507
|
-
elif [[ -f "requirements.txt" ]]; then
|
|
508
|
-
if grep -qi 'fastmcp' requirements.txt 2>/dev/null; then
|
|
509
|
-
framework="${framework:+$framework + }FastMCP"
|
|
510
|
-
framework_type="fastmcp"
|
|
511
|
-
elif grep -qi 'fastapi' requirements.txt 2>/dev/null; then
|
|
512
|
-
framework="${framework:+$framework + }FastAPI"
|
|
513
|
-
framework_type="fastapi"
|
|
514
|
-
elif grep -qi 'django' requirements.txt 2>/dev/null || [[ -f "manage.py" ]]; then
|
|
515
|
-
framework="${framework:+$framework + }Django"
|
|
516
|
-
framework_type="django"
|
|
517
|
-
fi
|
|
518
|
-
elif [[ -f "manage.py" ]]; then
|
|
519
|
-
framework="${framework:+$framework + }Django"
|
|
520
|
-
framework_type="django"
|
|
498
|
+
# Detect Python/MCP frameworks
|
|
499
|
+
framework_type=$(detect_framework_type)
|
|
500
|
+
if [[ -n "$framework_type" ]]; then
|
|
501
|
+
case "$framework_type" in
|
|
502
|
+
fastmcp) framework="${framework:+$framework + }FastMCP" ;;
|
|
503
|
+
fastapi) framework="${framework:+$framework + }FastAPI" ;;
|
|
504
|
+
django) framework="${framework:+$framework + }Django" ;;
|
|
505
|
+
react) ;; # Already detected above from package.json
|
|
506
|
+
esac
|
|
521
507
|
fi
|
|
522
508
|
|
|
523
509
|
# Detect Hugo (Go static site generator)
|
|
@@ -718,6 +704,8 @@ repos:
|
|
|
718
704
|
name: Check for hardcoded URLs
|
|
719
705
|
- id: check-debug
|
|
720
706
|
name: Check for debug statements
|
|
707
|
+
- id: check-signs-secrets
|
|
708
|
+
name: Check signs.json for credentials
|
|
721
709
|
EOF
|
|
722
710
|
echo " Created .pre-commit-config.yaml"
|
|
723
711
|
else
|
package/ralph/signs.sh
CHANGED
|
@@ -25,6 +25,14 @@ ralph_sign() {
|
|
|
25
25
|
return 1
|
|
26
26
|
fi
|
|
27
27
|
|
|
28
|
+
# Reject signs that contain credentials or secrets
|
|
29
|
+
if echo "$pattern" | grep -qiE '([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}|password[[:space:]]*[:=]|[[:space:]][A-Za-z0-9_]*_?(pass|pwd|token|secret|key|api.?key)[[:space:]]*[:=]|sk-[a-zA-Z0-9]{20,}|ghp_[a-zA-Z0-9]{36})'; then
|
|
30
|
+
print_error "Sign contains what looks like credentials (email, password, token, etc.)"
|
|
31
|
+
echo " Signs are saved to .ralph/signs.json which may be committed to git."
|
|
32
|
+
echo " Use environment variables instead of hardcoded credentials."
|
|
33
|
+
return 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
28
36
|
# Ensure signs.json exists
|
|
29
37
|
if [[ ! -f "$RALPH_DIR/signs.json" ]]; then
|
|
30
38
|
echo '{"signs": []}' > "$RALPH_DIR/signs.json"
|