replit-tools 1.1.6 → 1.1.7

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": "replit-tools",
3
- "version": "1.1.6",
3
+ "version": "1.1.7",
4
4
  "description": "DATA Tools - One command to set up Claude Code and Codex CLI on Replit with full persistence",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -240,85 +240,95 @@ if [[ ":$PATH:" != *":${LOCAL_BIN}:"* ]]; then
240
240
  fi
241
241
 
242
242
  # =============================================================================
243
- # Step 6: Auto-refresh OAuth token if needed
243
+ # Step 6: Auto-refresh OAuth token if needed (with loop prevention)
244
244
  # =============================================================================
245
245
  CREDENTIALS_FILE="${CLAUDE_PERSISTENT}/.credentials.json"
246
- if [ -f "${CREDENTIALS_FILE}" ] && [ -f "${AUTH_REFRESH_SCRIPT}" ]; then
247
- # Source the auth refresh script to get the function
248
- source "${AUTH_REFRESH_SCRIPT}"
249
-
250
- # Check and refresh if needed (this handles all the logic)
251
- if command -v node &> /dev/null; then
252
- AUTH_INFO=$(node -e "
253
- try {
254
- const creds = require('${CREDENTIALS_FILE}');
255
- const oauth = creds.claudeAiOauth;
256
- const apiKey = creds.primaryApiKey;
257
- if (apiKey) {
258
- console.log('apikey:permanent');
259
- } else if (oauth && oauth.expiresAt) {
260
- const now = Date.now();
261
- const remaining = Math.floor((oauth.expiresAt - now) / 1000 / 60 / 60);
262
- const hasRefresh = oauth.refreshToken ? 'yes' : 'no';
263
- console.log('oauth:' + remaining + ':' + hasRefresh);
264
- }
265
- } catch(e) { console.log('error'); }
266
- " 2>/dev/null)
267
-
268
- IFS=':' read -r auth_type remaining has_refresh <<< "${AUTH_INFO}"
269
-
270
- if [ "${auth_type}" = "apikey" ]; then
271
- log "✅ Claude authentication: API key (permanent)"
272
- elif [ "${auth_type}" = "oauth" ]; then
273
- if [ "${remaining}" -le 0 ]; then
274
- # Token expired - try to refresh
275
- if [ "${has_refresh}" = "yes" ]; then
276
- log "⚠️ Token expired, attempting refresh..."
277
- if refresh_token 2>/dev/null; then
278
- # Re-check the new expiry
279
- NEW_REMAINING=$(node -e "
280
- try {
281
- const creds = require('${CREDENTIALS_FILE}');
282
- const remaining = Math.floor((creds.claudeAiOauth.expiresAt - Date.now()) / 1000 / 60 / 60);
283
- console.log(remaining);
284
- } catch(e) { console.log('0'); }
285
- " 2>/dev/null)
286
- log "✅ Claude authentication: refreshed (${NEW_REMAINING}h remaining)"
246
+
247
+ # Prevent infinite refresh loops - only try once per shell session
248
+ if [ -z "${_REPLIT_TOOLS_AUTH_CHECKED}" ]; then
249
+ export _REPLIT_TOOLS_AUTH_CHECKED=1
250
+
251
+ if [ -f "${CREDENTIALS_FILE}" ] && [ -f "${AUTH_REFRESH_SCRIPT}" ]; then
252
+ # Source the auth refresh script to get the function
253
+ source "${AUTH_REFRESH_SCRIPT}"
254
+
255
+ # Check and refresh if needed (this handles all the logic)
256
+ if command -v node &> /dev/null; then
257
+ AUTH_INFO=$(node -e "
258
+ try {
259
+ const creds = require('${CREDENTIALS_FILE}');
260
+ const oauth = creds.claudeAiOauth;
261
+ const apiKey = creds.primaryApiKey;
262
+ if (apiKey) {
263
+ console.log('apikey:permanent');
264
+ } else if (oauth && oauth.expiresAt) {
265
+ const now = Date.now();
266
+ const remaining = Math.floor((oauth.expiresAt - now) / 1000 / 60 / 60);
267
+ const hasRefresh = oauth.refreshToken ? 'yes' : 'no';
268
+ console.log('oauth:' + remaining + ':' + hasRefresh);
269
+ } else {
270
+ console.log('none');
271
+ }
272
+ } catch(e) { console.log('error'); }
273
+ " 2>/dev/null)
274
+
275
+ IFS=':' read -r auth_type remaining has_refresh <<< "${AUTH_INFO}"
276
+
277
+ if [ "${auth_type}" = "apikey" ]; then
278
+ log "✅ Claude authentication: API key (permanent)"
279
+ elif [ "${auth_type}" = "oauth" ]; then
280
+ if [ "${remaining}" -le 0 ]; then
281
+ # Token expired - try to refresh once
282
+ if [ "${has_refresh}" = "yes" ]; then
283
+ log "⚠️ Token expired, attempting refresh..."
284
+ if refresh_token 2>/dev/null; then
285
+ NEW_REMAINING=$(node -e "
286
+ try {
287
+ const creds = require('${CREDENTIALS_FILE}');
288
+ const remaining = Math.floor((creds.claudeAiOauth.expiresAt - Date.now()) / 1000 / 60 / 60);
289
+ console.log(remaining);
290
+ } catch(e) { console.log('0'); }
291
+ " 2>/dev/null)
292
+ log "✅ Claude authentication: refreshed (${NEW_REMAINING}h remaining)"
293
+ else
294
+ log "❌ Token refresh failed - will use --dangerously-skip-permissions"
295
+ export CLAUDE_SKIP_AUTH=1
296
+ fi
287
297
  else
288
- log "❌ Token refresh failed - run: claude login"
298
+ log "❌ Token expired (no refresh token) - will use --dangerously-skip-permissions"
299
+ export CLAUDE_SKIP_AUTH=1
289
300
  fi
290
- else
291
- log "❌ Token expired (no refresh token) - run: claude login"
292
- fi
293
- elif [ "${remaining}" -lt 2 ]; then
294
- # Less than 2 hours - refresh proactively
295
- if [ "${has_refresh}" = "yes" ]; then
296
- log "🔄 Token expires in ${remaining}h, refreshing..."
297
- if refresh_token 2>/dev/null; then
298
- NEW_REMAINING=$(node -e "
299
- try {
300
- const creds = require('${CREDENTIALS_FILE}');
301
- const remaining = Math.floor((creds.claudeAiOauth.expiresAt - Date.now()) / 1000 / 60 / 60);
302
- console.log(remaining);
303
- } catch(e) { console.log('0'); }
304
- " 2>/dev/null)
305
- log "✅ Claude authentication: refreshed (${NEW_REMAINING}h remaining)"
301
+ elif [ "${remaining}" -lt 2 ]; then
302
+ # Less than 2 hours - refresh proactively
303
+ if [ "${has_refresh}" = "yes" ]; then
304
+ log "🔄 Token expires in ${remaining}h, refreshing..."
305
+ if refresh_token 2>/dev/null; then
306
+ NEW_REMAINING=$(node -e "
307
+ try {
308
+ const creds = require('${CREDENTIALS_FILE}');
309
+ const remaining = Math.floor((creds.claudeAiOauth.expiresAt - Date.now()) / 1000 / 60 / 60);
310
+ console.log(remaining);
311
+ } catch(e) { console.log('0'); }
312
+ " 2>/dev/null)
313
+ log "✅ Claude authentication: refreshed (${NEW_REMAINING}h remaining)"
314
+ else
315
+ log "⚠️ Refresh failed, ${remaining}h remaining"
316
+ fi
306
317
  else
307
- log "⚠️ Refresh failed, ${remaining}h remaining"
318
+ log "⚠️ Claude authentication: ${remaining}h remaining (no refresh token)"
308
319
  fi
309
320
  else
310
- log "⚠️ Claude authentication: ${remaining}h remaining (no refresh token)"
321
+ log "Claude authentication: valid (${remaining}h remaining)"
311
322
  fi
312
- else
313
- log " Claude authentication: valid (${remaining}h remaining)"
323
+ elif [ "${auth_type}" = "none" ] || [ "${auth_type}" = "error" ]; then
324
+ log "⚠️ No valid auth found - will use --dangerously-skip-permissions"
325
+ export CLAUDE_SKIP_AUTH=1
314
326
  fi
315
- elif [ "${auth_type}" = "error" ]; then
316
- log "⚠️ Could not read credentials"
317
327
  fi
328
+ elif [ ! -f "${CREDENTIALS_FILE}" ]; then
329
+ log "⚠️ No credentials - will use --dangerously-skip-permissions"
330
+ export CLAUDE_SKIP_AUTH=1
318
331
  fi
319
- elif [ ! -f "${CREDENTIALS_FILE}" ]; then
320
- log "⚠️ No Claude credentials found. Run 'claude login' to authenticate"
321
- log " 💡 Tip: Run 'claude setup-token' for a long-lived token"
322
332
  fi
323
333
 
324
334
  # =============================================================================