thrivekit 2.0.18 → 2.0.19

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 CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  A toolkit for implementing [RALPH](https://ghuntley.com/ralph/) with [Claude Code](https://docs.anthropic.com/en/docs/claude-code) that helps you go from idea to shipped code.
6
6
 
7
- > **Optimized for:** Python, TypeScript, React, and Docker projects. Auto-detects ports from `docker-compose.yml`, Vite, Next.js, and FastAPI.
7
+ > **Optimized for:** Python, TypeScript, React, Go/Hugo, and Docker projects. Auto-detects ports from `docker-compose.yml`, Vite, Next.js, Hugo, FastAPI, and more.
8
8
 
9
9
  > You focus on what matters: your ideas. Brainstorm with `/idea`, then let Ralph handle the rest - coding, testing, and committing in an iterative loop until everything passes.
10
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thrivekit",
3
- "version": "2.0.18",
3
+ "version": "2.0.19",
4
4
  "description": "Tools to thrive with agentic coding - RALPH autonomous loop, Claude Code hooks, PRD-driven development",
5
5
  "author": "Allie Jones <allie@allthrive.ai>",
6
6
  "license": "MIT",
package/ralph/init.sh CHANGED
@@ -188,64 +188,66 @@ auto_configure_project() {
188
188
 
189
189
  # 2. Detect testUrlBase from common patterns
190
190
  local base_url=""
191
+ local detected_framework=""
191
192
 
192
- # Check docker-compose.yml for frontend/web service port mappings
193
+ # Check docker-compose.yml for frontend/web service port mappings (highest priority)
193
194
  for compose_file in "docker-compose.yml" "docker-compose.yaml" "compose.yml" "compose.yaml"; do
194
195
  if [[ -f "$compose_file" && -z "$base_url" ]]; then
195
- # Look for web/frontend service port mapping
196
196
  local web_port
197
197
  web_port=$(grep -A 20 -E '^\s*(web|frontend|client|ui):' "$compose_file" 2>/dev/null | \
198
198
  grep -E '^\s*-\s*"?[0-9]+:[0-9]+"?' | head -1 | \
199
199
  grep -oE '[0-9]+:' | head -1 | tr -d ':')
200
200
  if [[ -n "$web_port" ]]; then
201
201
  base_url="http://localhost:$web_port"
202
+ detected_framework="docker"
202
203
  fi
203
204
  fi
204
205
  done
205
206
 
206
- # Check for Vite config (uses port 5173 by default)
207
+ # Detect framework and use default port from constants
207
208
  if [[ -z "$base_url" ]]; then
209
+ # Vite
208
210
  for vite_config in "vite.config.ts" "vite.config.js" "apps/web/vite.config.ts" "apps/web/vite.config.js" \
209
211
  "apps/frontend/vite.config.ts" "frontend/vite.config.ts"; do
210
212
  if [[ -f "$vite_config" ]]; then
211
- base_url="http://localhost:5173"
213
+ detected_framework="vite"
214
+ base_url="http://localhost:${DEFAULT_PORTS[vite]}"
212
215
  break
213
216
  fi
214
217
  done
215
218
  fi
216
219
 
217
- # Check for Next.js (uses port 3000 by default)
218
220
  if [[ -z "$base_url" ]]; then
221
+ # Next.js
219
222
  for next_config in "next.config.js" "next.config.ts" "next.config.mjs" \
220
223
  "apps/web/next.config.js" "apps/web/next.config.mjs"; do
221
224
  if [[ -f "$next_config" ]]; then
222
- base_url="http://localhost:3000"
225
+ detected_framework="nextjs"
226
+ base_url="http://localhost:${DEFAULT_PORTS[nextjs]}"
223
227
  break
224
228
  fi
225
229
  done
226
230
  fi
227
231
 
228
- # Fallback: Check package.json scripts for dev server port
229
- if [[ -z "$base_url" && -f "package.json" ]]; then
230
- if grep -q '"dev".*:3000' package.json 2>/dev/null; then
231
- base_url="http://localhost:3000"
232
- elif grep -q '"dev".*:5173' package.json 2>/dev/null; then
233
- base_url="http://localhost:5173"
234
- elif grep -q '"dev".*:8080' package.json 2>/dev/null; then
235
- base_url="http://localhost:8080"
236
- fi
232
+ if [[ -z "$base_url" ]]; then
233
+ # Hugo
234
+ for hugo_config in "hugo.toml" "hugo.yaml" "hugo.json" "config.toml"; do
235
+ if [[ -f "$hugo_config" ]] && [[ -d "content" || -d "layouts" || -d "themes" ]]; then
236
+ detected_framework="hugo"
237
+ base_url="http://localhost:${DEFAULT_PORTS[hugo]}"
238
+ break
239
+ fi
240
+ done
237
241
  fi
238
242
 
239
- # Check for monorepo frontend
240
- for fe_pkg in "apps/web/package.json" "apps/frontend/package.json" "frontend/package.json"; do
241
- if [[ -f "$fe_pkg" && -z "$base_url" ]]; then
242
- if grep -q ':3000' "$fe_pkg" 2>/dev/null; then
243
- base_url="http://localhost:3000"
244
- elif grep -q ':5173' "$fe_pkg" 2>/dev/null; then
245
- base_url="http://localhost:5173"
246
- fi
243
+ # Fallback: Check package.json for port hints
244
+ if [[ -z "$base_url" && -f "package.json" ]]; then
245
+ local pkg_port
246
+ pkg_port=$(grep -oE ':[0-9]{4}' package.json 2>/dev/null | head -1 | tr -d ':')
247
+ if [[ -n "$pkg_port" ]]; then
248
+ base_url="http://localhost:$pkg_port"
247
249
  fi
248
- done
250
+ fi
249
251
 
250
252
  if [[ -n "$base_url" ]]; then
251
253
  if jq -e '.testUrlBase' "$tmpfile" >/dev/null 2>&1 && [[ "$(jq -r '.testUrlBase' "$tmpfile")" != "" ]]; then
@@ -294,17 +296,18 @@ auto_configure_project() {
294
296
 
295
297
  # 4. Detect API baseUrl based on backend type
296
298
  local api_url=""
299
+ local api_framework=""
297
300
 
298
- # Check docker-compose.yml for API service port mappings (most common)
301
+ # Check docker-compose.yml for API service port mappings (highest priority)
299
302
  for compose_file in "docker-compose.yml" "docker-compose.yaml" "compose.yml" "compose.yaml"; do
300
303
  if [[ -f "$compose_file" && -z "$api_url" ]]; then
301
- # Look for api/backend service port mapping like "8000:8000" or "3001:3000"
302
304
  local api_port
303
305
  api_port=$(grep -A 20 -E '^\s*(api|backend|server|app):' "$compose_file" 2>/dev/null | \
304
306
  grep -E '^\s*-\s*"?[0-9]+:[0-9]+"?' | head -1 | \
305
307
  grep -oE '[0-9]+:' | head -1 | tr -d ':')
306
308
  if [[ -n "$api_port" ]]; then
307
309
  api_url="http://localhost:$api_port"
310
+ api_framework="docker"
308
311
  fi
309
312
  fi
310
313
  done
@@ -316,20 +319,27 @@ auto_configure_project() {
316
319
  docker_port=$(grep -i "^EXPOSE" "$backend_dir/Dockerfile" 2>/dev/null | head -1 | grep -oE '[0-9]+' | head -1)
317
320
  if [[ -n "$docker_port" ]]; then
318
321
  api_url="http://localhost:$docker_port"
322
+ api_framework="docker"
319
323
  fi
320
324
  fi
321
- # Python backends (FastAPI/Django) typically use port 8000
325
+ # Python backends - detect framework and use default port
322
326
  if [[ -z "$api_url" ]] && { [[ -f "$backend_dir/pyproject.toml" ]] || [[ -f "$backend_dir/requirements.txt" ]] || [[ -f "$backend_dir/main.py" ]]; }; then
323
- api_url="http://localhost:8000"
324
- # Node backends - check for port in package.json or default to 3001
325
- elif [[ -z "$api_url" && -f "$backend_dir/package.json" ]]; then
326
- if grep -q ':3001' "$backend_dir/package.json" 2>/dev/null; then
327
- api_url="http://localhost:3001"
328
- elif grep -q ':4000' "$backend_dir/package.json" 2>/dev/null; then
329
- api_url="http://localhost:4000"
327
+ if grep -q "fastapi\|FastAPI" "$backend_dir"/*.py "$backend_dir/pyproject.toml" 2>/dev/null; then
328
+ api_framework="fastapi"
329
+ elif grep -q "django\|Django" "$backend_dir"/*.py "$backend_dir/pyproject.toml" 2>/dev/null; then
330
+ api_framework="django"
331
+ elif grep -q "flask\|Flask" "$backend_dir"/*.py "$backend_dir/pyproject.toml" 2>/dev/null; then
332
+ api_framework="flask"
330
333
  else
331
- api_url="http://localhost:3001"
334
+ api_framework="fastapi" # Default for Python
332
335
  fi
336
+ api_url="http://localhost:${DEFAULT_PORTS[$api_framework]}"
337
+ # Node backends - check for port in package.json
338
+ elif [[ -z "$api_url" && -f "$backend_dir/package.json" ]]; then
339
+ local node_port
340
+ node_port=$(grep -oE ':[0-9]{4}' "$backend_dir/package.json" 2>/dev/null | head -1 | tr -d ':')
341
+ api_url="http://localhost:${node_port:-${DEFAULT_PORTS[express]}}"
342
+ api_framework="express"
333
343
  fi
334
344
  fi
335
345
 
package/ralph/setup.sh CHANGED
@@ -257,6 +257,15 @@ setup_claude_md() {
257
257
  fi
258
258
  [[ -f "manage.py" ]] && framework="${framework:+$framework + }Django"
259
259
 
260
+ # Detect Hugo (Go static site generator)
261
+ for hugo_config in "hugo.toml" "hugo.yaml" "hugo.json" "config.toml"; do
262
+ if [[ -f "$hugo_config" ]] && [[ -d "content" || -d "layouts" || -d "themes" ]]; then
263
+ framework="${framework:+$framework + }Hugo"
264
+ [[ -z "$runtime" ]] && runtime="Go"
265
+ break
266
+ fi
267
+ done
268
+
260
269
  # Detect TypeScript
261
270
  [[ -f "tsconfig.json" || -f "${fe_dir}/tsconfig.json" ]] && language="TypeScript"
262
271
 
package/ralph/utils.sh CHANGED
@@ -24,6 +24,20 @@ readonly CURL_TIMEOUT_SECONDS=10
24
24
  readonly FRONTEND_DIRS=("apps/web" "frontend" "client" "web")
25
25
  readonly BACKEND_DIRS=("apps/api" "api" "backend" "server")
26
26
 
27
+ # Default ports by framework (used only during detection, then stored in config)
28
+ declare -A DEFAULT_PORTS=(
29
+ ["vite"]=5173
30
+ ["nextjs"]=3000
31
+ ["hugo"]=1313
32
+ ["react"]=3000
33
+ ["vue"]=5173
34
+ ["express"]=3001
35
+ ["fastapi"]=8000
36
+ ["django"]=8000
37
+ ["flask"]=5000
38
+ ["rails"]=3000
39
+ )
40
+
27
41
  # Track temp files for safe cleanup
28
42
  RALPH_TEMP_FILES=()
29
43