replit-tools 1.2.42 → 1.2.43
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 +1 -1
- package/scripts/setup-claude-code.sh +134 -75
package/package.json
CHANGED
|
@@ -41,9 +41,13 @@ LOCAL_SHARE_CLAUDE="${HOME}/.local/share/claude"
|
|
|
41
41
|
VERSION_FILE="${REPLIT_TOOLS}/.version"
|
|
42
42
|
PACKAGE_NAME="data-remote"
|
|
43
43
|
|
|
44
|
-
#
|
|
44
|
+
# Force Claude re-detection: bash setup-claude-code.sh --refresh OR CLAUDE_FORCE_REFRESH=1
|
|
45
|
+
CLAUDE_FORCE_REFRESH="${CLAUDE_FORCE_REFRESH:-0}"
|
|
46
|
+
[ "${1:-}" = "--refresh" ] && CLAUDE_FORCE_REFRESH=1
|
|
47
|
+
|
|
48
|
+
# Logging helper - prints in interactive shells, or when run manually with --refresh
|
|
45
49
|
log() {
|
|
46
|
-
if [[ $- == *i* ]]; then
|
|
50
|
+
if [[ $- == *i* ]] || [ "${CLAUDE_FORCE_REFRESH:-0}" = "1" ]; then
|
|
47
51
|
echo "$1"
|
|
48
52
|
fi
|
|
49
53
|
}
|
|
@@ -314,97 +318,152 @@ if [ ! -L "${SHARE_VERSIONS}" ] || [ "$(readlink -f "${SHARE_VERSIONS}")" != "${
|
|
|
314
318
|
fi
|
|
315
319
|
|
|
316
320
|
# =============================================================================
|
|
317
|
-
# Step 4:
|
|
321
|
+
# Step 4: Detect newest Claude binary across ALL install locations, promote it
|
|
318
322
|
# =============================================================================
|
|
323
|
+
# Bug history: npm installs claude to node_modules/@anthropic-ai/claude-code/
|
|
324
|
+
# which the old finder never checked, so ~/.local/bin/claude stayed pinned to an
|
|
325
|
+
# old .claude-versions entry while Replit's agent UI launched the newer
|
|
326
|
+
# node_modules binary directly. Now we scan everything, compare by real
|
|
327
|
+
# --version output (not filename), promote the winner, and GC stale copies.
|
|
328
|
+
|
|
329
|
+
CLAUDE_DETECT_CACHE="${CLAUDE_VERSIONS}/.detect-cache"
|
|
330
|
+
|
|
331
|
+
# Get semver by EXECUTING the binary (never trust filenames). Empty if invalid.
|
|
332
|
+
claude_bin_version() {
|
|
333
|
+
local bin="$1"
|
|
334
|
+
[ -f "$bin" ] || return 1
|
|
335
|
+
local v
|
|
336
|
+
v=$("$bin" --version 2>/dev/null | awk '{print $1}')
|
|
337
|
+
if [[ "$v" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
338
|
+
echo "$v"; return 0
|
|
339
|
+
fi
|
|
340
|
+
return 1
|
|
341
|
+
}
|
|
319
342
|
|
|
320
|
-
#
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
343
|
+
# All places a Claude binary might live (npm, bun, official installer, our store)
|
|
344
|
+
claude_candidate_paths() {
|
|
345
|
+
echo "${WORKSPACE}/node_modules/@anthropic-ai/claude-code/bin/claude.exe"
|
|
346
|
+
echo "${WORKSPACE}/node_modules/.bin/claude"
|
|
347
|
+
echo "${HOME}/.npm-global/bin/claude"
|
|
348
|
+
echo "${HOME}/.bun/bin/claude"
|
|
349
|
+
if [ -d "${HOME}/.local/share/claude/versions" ] && [ ! -L "${HOME}/.local/share/claude/versions" ]; then
|
|
350
|
+
find "${HOME}/.local/share/claude/versions" -maxdepth 1 -type f 2>/dev/null
|
|
351
|
+
fi
|
|
326
352
|
if [ -d "${CLAUDE_VERSIONS}" ]; then
|
|
327
|
-
|
|
328
|
-
if [ -n "${ver}" ] && [ -f "${CLAUDE_VERSIONS}/${ver}" ]; then
|
|
329
|
-
found_binary="${CLAUDE_VERSIONS}/${ver}"
|
|
330
|
-
found_version="${ver}"
|
|
331
|
-
fi
|
|
353
|
+
find "${CLAUDE_VERSIONS}" -maxdepth 1 -type f ! -name '.*' 2>/dev/null
|
|
332
354
|
fi
|
|
355
|
+
# command -v claude, but ONLY if it does not resolve to our own managed symlink
|
|
356
|
+
local cmdclaude our_target real
|
|
357
|
+
cmdclaude=$(command -v claude 2>/dev/null)
|
|
358
|
+
our_target=$(readlink -f "${LOCAL_BIN}/claude" 2>/dev/null)
|
|
359
|
+
if [ -n "$cmdclaude" ]; then
|
|
360
|
+
real=$(readlink -f "$cmdclaude" 2>/dev/null)
|
|
361
|
+
[ -n "$real" ] && [ "$real" != "$our_target" ] && echo "$real"
|
|
362
|
+
fi
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
# Cheap fingerprint of candidate paths (mtime+size) to short-circuit unchanged runs
|
|
366
|
+
claude_detect_fingerprint() {
|
|
367
|
+
{
|
|
368
|
+
local rp
|
|
369
|
+
while IFS= read -r c; do
|
|
370
|
+
[ -z "$c" ] && continue
|
|
371
|
+
rp=$(readlink -f "$c" 2>/dev/null)
|
|
372
|
+
[ -f "$rp" ] && stat -c '%n:%Y:%s' "$rp" 2>/dev/null
|
|
373
|
+
done < <(claude_candidate_paths)
|
|
374
|
+
readlink -f "${LOCAL_BIN}/claude" 2>/dev/null
|
|
375
|
+
} | md5sum 2>/dev/null | awk '{print $1}'
|
|
376
|
+
}
|
|
333
377
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
378
|
+
# Detect newest version across all candidates, promote into .claude-versions, relink
|
|
379
|
+
detect_and_promote_claude() {
|
|
380
|
+
local best_ver="" best_path="" seen="" rp v
|
|
381
|
+
while IFS= read -r c; do
|
|
382
|
+
[ -z "$c" ] && continue
|
|
383
|
+
rp=$(readlink -f "$c" 2>/dev/null)
|
|
384
|
+
[ -z "$rp" ] && continue
|
|
385
|
+
[ -f "$rp" ] || continue
|
|
386
|
+
case "$seen" in *"|${rp}|"*) continue ;; esac
|
|
387
|
+
seen="${seen}|${rp}|"
|
|
388
|
+
v=$(claude_bin_version "$rp") || continue
|
|
389
|
+
if [ -z "$best_ver" ] || [ "$(printf '%s\n%s\n' "$best_ver" "$v" | sort -V | tail -n1)" = "$v" ]; then
|
|
390
|
+
if [ "$v" != "$best_ver" ] || [ -z "$best_path" ]; then
|
|
391
|
+
best_ver="$v"; best_path="$rp"
|
|
343
392
|
fi
|
|
344
393
|
fi
|
|
394
|
+
done < <(claude_candidate_paths)
|
|
395
|
+
|
|
396
|
+
[ -z "$best_ver" ] && return 1
|
|
397
|
+
|
|
398
|
+
mkdir -p "${CLAUDE_VERSIONS}"
|
|
399
|
+
if [ ! -f "${CLAUDE_VERSIONS}/${best_ver}" ]; then
|
|
400
|
+
cp -p "${best_path}" "${CLAUDE_VERSIONS}/${best_ver}" 2>/dev/null || true
|
|
401
|
+
chmod 755 "${CLAUDE_VERSIONS}/${best_ver}" 2>/dev/null || true
|
|
345
402
|
fi
|
|
346
403
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
404
|
+
local new_target="${CLAUDE_VERSIONS}/${best_ver}"
|
|
405
|
+
local cur_target
|
|
406
|
+
cur_target=$(readlink -f "${LOCAL_BIN}/claude" 2>/dev/null)
|
|
407
|
+
if [ "$cur_target" != "$new_target" ]; then
|
|
408
|
+
mkdir -p "${LOCAL_BIN}"
|
|
409
|
+
ln -sfn "${new_target}" "${LOCAL_BIN}/claude"
|
|
410
|
+
if [ -n "$cur_target" ] && [ -f "$cur_target" ]; then
|
|
411
|
+
log "✅ Claude $(basename "$cur_target") → ${best_ver}"
|
|
412
|
+
else
|
|
413
|
+
log "✅ Claude ${best_ver} active (~/.local/bin/claude)"
|
|
357
414
|
fi
|
|
358
415
|
fi
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
FOUND_CLAUDE_BINARY="${found_binary}"
|
|
362
|
-
FOUND_CLAUDE_VERSION="${found_version}"
|
|
416
|
+
LATEST_VERSION="${best_ver}"
|
|
417
|
+
return 0
|
|
363
418
|
}
|
|
364
419
|
|
|
365
|
-
#
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
420
|
+
# Keep only the newest 3 versions in our store (each binary is ~230 MB)
|
|
421
|
+
gc_claude_versions() {
|
|
422
|
+
[ -d "${CLAUDE_VERSIONS}" ] || return 0
|
|
423
|
+
local cur_target all count to_delete v p
|
|
424
|
+
cur_target=$(readlink -f "${LOCAL_BIN}/claude" 2>/dev/null)
|
|
425
|
+
all=$(find "${CLAUDE_VERSIONS}" -maxdepth 1 -type f -printf '%f\n' 2>/dev/null | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | sort -V)
|
|
426
|
+
count=$(printf '%s\n' "$all" | grep -c .)
|
|
427
|
+
[ "$count" -le 3 ] && return 0
|
|
428
|
+
to_delete=$(printf '%s\n' "$all" | head -n $((count - 3)))
|
|
429
|
+
for v in $to_delete; do
|
|
430
|
+
p="${CLAUDE_VERSIONS}/${v}"
|
|
431
|
+
[ "$(readlink -f "$p")" = "$cur_target" ] && continue
|
|
432
|
+
rm -f "$p" 2>/dev/null && log "🗑️ Removed old Claude ${v}"
|
|
433
|
+
done
|
|
434
|
+
}
|
|
371
435
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
436
|
+
# Run detection (cheap short-circuit unless paths changed or --refresh given)
|
|
437
|
+
run_claude_detection() {
|
|
438
|
+
local fp cached cur
|
|
439
|
+
fp=$(claude_detect_fingerprint)
|
|
440
|
+
cached=""
|
|
441
|
+
[ -f "${CLAUDE_DETECT_CACHE}" ] && cached=$(cat "${CLAUDE_DETECT_CACHE}" 2>/dev/null)
|
|
442
|
+
|
|
443
|
+
if [ "${CLAUDE_FORCE_REFRESH}" != "1" ] && [ -n "$fp" ] && [ "$fp" = "$cached" ]; then
|
|
444
|
+
cur=$(readlink -f "${LOCAL_BIN}/claude" 2>/dev/null)
|
|
445
|
+
if [ -f "$cur" ]; then
|
|
446
|
+
LATEST_VERSION=$(basename "$cur")
|
|
447
|
+
return 0 # nothing changed since last run
|
|
448
|
+
fi
|
|
378
449
|
fi
|
|
379
450
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
rm -f "${LOCAL_BIN}/claude" 2>/dev/null || true
|
|
383
|
-
ln -sf "${CLAUDE_VERSIONS}/${LATEST_VERSION}" "${LOCAL_BIN}/claude"
|
|
384
|
-
log "✅ Claude binary symlink: ~/.local/bin/claude -> ${CLAUDE_VERSIONS}/${LATEST_VERSION}"
|
|
385
|
-
fi
|
|
386
|
-
else
|
|
387
|
-
# Claude not installed - install it
|
|
388
|
-
log "⚠️ Claude Code not found, installing..."
|
|
389
|
-
|
|
390
|
-
# Install Claude Code using the official installer
|
|
391
|
-
if curl -fsSL https://claude.ai/install.sh | bash 2>/dev/null; then
|
|
392
|
-
# After install, find and sync the binary
|
|
393
|
-
find_claude_binary
|
|
394
|
-
if [ -n "${FOUND_CLAUDE_BINARY}" ]; then
|
|
395
|
-
LATEST_VERSION="${FOUND_CLAUDE_VERSION}"
|
|
396
|
-
if [ ! -f "${CLAUDE_VERSIONS}/${LATEST_VERSION}" ]; then
|
|
397
|
-
cp -p "${FOUND_CLAUDE_BINARY}" "${CLAUDE_VERSIONS}/${LATEST_VERSION}" 2>/dev/null || true
|
|
398
|
-
chmod 755 "${CLAUDE_VERSIONS}/${LATEST_VERSION}" 2>/dev/null || true
|
|
399
|
-
fi
|
|
400
|
-
ln -sf "${CLAUDE_VERSIONS}/${LATEST_VERSION}" "${LOCAL_BIN}/claude"
|
|
401
|
-
log "✅ Claude Code ${LATEST_VERSION} installed"
|
|
402
|
-
fi
|
|
451
|
+
if detect_and_promote_claude; then
|
|
452
|
+
gc_claude_versions
|
|
403
453
|
else
|
|
404
|
-
log "
|
|
405
|
-
|
|
454
|
+
log "⚠️ Claude Code not found, installing..."
|
|
455
|
+
if curl -fsSL https://claude.ai/install.sh | bash 2>/dev/null; then
|
|
456
|
+
detect_and_promote_claude && gc_claude_versions
|
|
457
|
+
else
|
|
458
|
+
log "❌ Failed to install Claude Code"
|
|
459
|
+
log " Try running: curl -fsSL https://claude.ai/install.sh | bash"
|
|
460
|
+
fi
|
|
406
461
|
fi
|
|
407
|
-
|
|
462
|
+
# Persist post-promotion fingerprint so the next shell short-circuits
|
|
463
|
+
claude_detect_fingerprint > "${CLAUDE_DETECT_CACHE}" 2>/dev/null
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
run_claude_detection
|
|
408
467
|
|
|
409
468
|
# =============================================================================
|
|
410
469
|
# Step 5: Ensure PATH includes ~/.local/bin
|