vibe-and-thrive 1.7.3 → 1.7.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe-and-thrive",
3
- "version": "1.7.3",
3
+ "version": "1.7.4",
4
4
  "description": "Ship quality code faster with AI - RALPH autonomous loop, Claude Code hooks, and pre-commit checks",
5
5
  "author": "Allie Jones <allie@allthrive.ai>",
6
6
  "license": "MIT",
package/ralph/prd.sh CHANGED
@@ -33,8 +33,9 @@ ralph_prd() {
33
33
  notes=$(cat "$from_file") || { print_error "Failed to read $from_file"; return 1; }
34
34
  fi
35
35
 
36
- # Trim whitespace
37
- notes=$(echo "$notes" | xargs)
36
+ # Trim leading/trailing whitespace (safer than xargs)
37
+ notes="${notes#"${notes%%[![:space:]]*}"}" # trim leading
38
+ notes="${notes%"${notes##*[![:space:]]}"}" # trim trailing
38
39
 
39
40
  if [[ -z "$notes" ]]; then
40
41
  print_error "No notes provided. Usage: ralph prd <description>"
package/ralph/signs.sh CHANGED
@@ -47,7 +47,7 @@ ralph_sign() {
47
47
  local tmpfile
48
48
  tmpfile=$(mktemp)
49
49
 
50
- jq --arg id "$sign_id" \
50
+ if jq --arg id "$sign_id" \
51
51
  --arg pattern "$pattern" \
52
52
  --arg category "$category" \
53
53
  --arg learnedFrom "$learned_from" \
@@ -58,9 +58,7 @@ ralph_sign() {
58
58
  category: $category,
59
59
  learnedFrom: (if $learnedFrom == "" then null else $learnedFrom end),
60
60
  createdAt: $createdAt
61
- }]' "$RALPH_DIR/signs.json" > "$tmpfile"
62
-
63
- if [[ $? -eq 0 ]]; then
61
+ }]' "$RALPH_DIR/signs.json" > "$tmpfile" && jq -e . "$tmpfile" >/dev/null 2>&1; then
64
62
  mv "$tmpfile" "$RALPH_DIR/signs.json"
65
63
  print_success "Added sign: [$category] $pattern"
66
64
  log_progress "SIGN" "ADDED" "$sign_id: $pattern"
package/ralph/utils.sh CHANGED
@@ -235,27 +235,45 @@ trap cleanup EXIT
235
235
 
236
236
  # Validate a command doesn't contain dangerous patterns
237
237
  # Returns 0 if safe, 1 if dangerous
238
+ # Note: This is defense-in-depth. Commands come from user config, so user must trust their own config.
238
239
  validate_command() {
239
240
  local cmd="$1"
240
241
 
241
- # Block dangerous patterns
242
+ # Block obviously dangerous patterns (defense-in-depth, not security boundary)
242
243
  local dangerous_patterns=(
243
- 'rm[[:space:]]+-rf[[:space:]]+/' # rm -rf /
244
- 'rm[[:space:]]+-rf[[:space:]]+\*' # rm -rf *
245
- 'curl.*\|.*bash' # curl | bash
246
- 'curl.*\|.*sh' # curl | sh
247
- 'wget.*\|.*bash' # wget | bash
248
- 'wget.*\|.*sh' # wget | sh
249
- '\$\([^)]*eval' # $(eval ...)
250
- 'eval[[:space:]]+\$' # eval $var
251
- '>[[:space:]]*/dev/sd' # write to disk devices
252
- 'mkfs\.' # format filesystems
253
- 'dd[[:space:]]+if=' # dd commands
244
+ # Destructive file operations
245
+ 'rm[[:space:]]+-rf[[:space:]]+/' # rm -rf /
246
+ 'rm[[:space:]]+-rf[[:space:]]+~' # rm -rf ~ (home dir)
247
+ 'rm[[:space:]]+-rf[[:space:]]+\*' # rm -rf *
248
+ 'rm[[:space:]]+-rf[[:space:]]+\.\.' # rm -rf ..
249
+ 'rm[[:space:]].*--no-preserve-root' # rm with --no-preserve-root
250
+ # Remote code execution
251
+ 'curl.*\|.*bash' # curl | bash
252
+ 'curl.*\|.*sh[[:space:]]*$' # curl | sh
253
+ 'wget.*\|.*bash' # wget | bash
254
+ 'wget.*\|.*sh[[:space:]]*$' # wget | sh
255
+ 'curl.*>[[:space:]]*/tmp/.*&&.*bash' # curl > /tmp/x && bash
256
+ # Code injection
257
+ '\$\([^)]*eval' # $(eval ...)
258
+ 'eval[[:space:]]+\$' # eval $var
259
+ 'eval[[:space:]]+["\x27]' # eval "..." or eval '...'
260
+ # System damage
261
+ '>[[:space:]]*/dev/sd' # write to disk devices
262
+ '>[[:space:]]*/dev/nvme' # write to nvme devices
263
+ 'mkfs\.' # format filesystems
264
+ 'dd[[:space:]]+if=' # dd commands
265
+ ':(){:|:&};:' # fork bomb
266
+ # Credential theft
267
+ 'cat.*\.ssh/id_' # read SSH keys
268
+ 'cat.*/etc/shadow' # read shadow file
269
+ 'cat.*\.aws/credentials' # read AWS creds
270
+ 'cat.*\.env' # read env files (often has secrets)
254
271
  )
255
272
 
256
273
  for pattern in "${dangerous_patterns[@]}"; do
257
274
  if [[ "$cmd" =~ $pattern ]]; then
258
- print_error "Command contains dangerous pattern: $cmd"
275
+ print_error "Command blocked (dangerous pattern): $cmd"
276
+ log_progress "BLOCKED dangerous command: $cmd"
259
277
  return 1
260
278
  fi
261
279
  done