data-remote
v1.2.44
Published
DATA Tools - One command to set up Claude Code and Codex CLI on Replit with full persistence
Maintainers
Readme
DATA Tools
One command to set up Claude Code and Codex CLI on Replit with full persistence and automatic token refresh.
When Replit containers restart, everything outside /home/runner/workspace/ is wiped - including installed CLIs, conversations, auth tokens, and command history. DATA Tools fixes all of that.
Quick Start
npx -y data-remote(The -y skips the "Ok to proceed?" prompt)
That's it. The installer will:
- Install Claude Code (if not already installed)
- Install OpenAI Codex CLI (if not already installed)
- Detect existing config and preserve your data
- Set up persistence so everything survives restarts
- Auto-refresh OAuth tokens before they expire
- Launch the session picker so you can start working immediately
What Gets Installed
| Tool | Source | Purpose |
|------|--------|---------|
| Claude Code | curl https://claude.ai/install.sh | Anthropic's CLI for Claude |
| Codex CLI | npm i -g @openai/codex | OpenAI's coding assistant |
Both are installed only if not already present. Existing installations are preserved.
What Gets Persisted
Everything is stored in a single .replit-tools/ directory:
| Data | Location | Survives Restart? |
|------|----------|-------------------|
| Claude conversations | .replit-tools/.claude-persistent/ | Yes |
| Claude credentials | .replit-tools/.claude-persistent/.credentials.json | Yes |
| Claude binary | .replit-tools/.claude-versions/ | Yes |
| Codex data | .replit-tools/.codex-persistent/ | Yes |
| SSH keys & known_hosts | .replit-tools/.ssh-persistent/ | Yes |
| Bash history | .replit-tools/.persistent-home/ | Yes |
| Per-terminal sessions | .replit-tools/.claude-sessions/ | Yes |
| Append-only session mirror | .replit-tools/.session-archive/ | Yes |
| Auth logs | .replit-tools/.logs/ | Yes |
| Scripts | .replit-tools/scripts/ | Yes |
SSH persistence
~/.ssh is symlinked into .replit-tools/.ssh-persistent/ (mode 700). Any new private keys, known_hosts entries, or config you add will survive container restarts automatically. If you generate a new key with ssh-keygen, drop it straight into ~/.ssh/ (the symlink) — it lands in the persistent dir.
Claude credentials
The canonical credentials file is:
/home/runner/workspace/.replit-tools/.claude-persistent/.credentials.jsonOAuth tokens, refresh tokens, and any claude setup-token API token are stored there. Treat it like a password file — it grants full account access.
Automatic Token Refresh
Claude OAuth tokens expire every 8-12 hours. DATA Tools automatically refreshes them:
- On every shell start: Checks token expiry and refreshes if < 2 hours remaining
- When expired: Attempts automatic refresh using the stored refresh token
- Transparent: You'll see
🔄 Token expires in 1h, refreshing...then✅ Token refreshed (11h remaining)
This means you can leave overnight and come back to a working session - no more claude login every morning.
Manual Token Commands
# Check token status
/home/runner/workspace/.replit-tools/scripts/claude-auth-refresh.sh --status
# Force refresh now
/home/runner/workspace/.replit-tools/scripts/claude-auth-refresh.sh --force
# Or use a permanent API token (never expires)
claude setup-tokenThe Session Picker
After installation (and on every new shell), you'll see:
✅ Claude authentication: valid (11h remaining)
✅ Claude Code ready: 2.0.71 (Claude Code)
Recent (last 48h):
[1] cld 2m "Can you help me fix this bug..."
[2] cdx 18m "explain this stack trace"
[3] cld 3h "draft a migration plan"
┌─────────────────────────────┐
│ DATA Session Manager │
└─────────────────────────────┘
(1 claude, 1 codex running)
[c] Continue last session (Enter = c)
└─ claude:b3dcb95c...
[1-9] Resume numbered above
[r] Resume (full list)
[n] New Claude session
[m] New Codex session
[j] Login to Claude
[k] Login to Codex
[s] Skip - just shell
Choice: _Session Details
Press r to see full session metadata:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[1]
ID: b3dcb95c-cebb-4082-b671-988c8d36578e
Messages: 237 | Size: 912.1KB
Active: 2m ago
Started: 2026-01-18 18:22:12 UTC
First: "Can you help me fix this bug..."
Latest: "Thanks, that worked!"Each session shows:
- Full UUID
- Message count and file size
- Time since last activity
- Start and last activity timestamps
- First and latest prompts (truncated)
Multi-Terminal Support
Each terminal tracks its own session independently:
Terminal pts/0 → Session abc123... (your migration work)
Terminal pts/1 → Session def456... (your docs work)
Terminal pts/2 → Session ghi789... (your debugging)Press c (or just hit Enter) to continue YOUR terminal's last session. Other terminals are unaffected.
How It Works
The installer creates symlinks from ephemeral locations to persistent .replit-tools/ storage:
~/.claude → .replit-tools/.claude-persistent/
~/.codex → .replit-tools/.codex-persistent/
~/.ssh → .replit-tools/.ssh-persistent/
~/.local/share/claude/versions/ → .replit-tools/.claude-versions/
~/.local/bin/claude → .replit-tools/.claude-versions/X.X.XThree layers ensure setup runs on every restart:
.replitonBoot hook (runs at container boot).config/bashrc(runs on every shell start)- Scripts in
.replit-tools/scripts/(called by above)
The bashrc managed block
DATA Tools writes its .config/bashrc config inside a sentinel-wrapped block:
# >>> data-remote >>>
# DATA Tools — Replit Claude & Codex Persistence
# Managed by data-remote. Hand-edits inside this block will be overwritten
# on the next install. Edit outside the sentinels to add your own config.
...
# <<< data-remote <<<You can freely add your own exports, aliases, and functions above or below those sentinel lines — re-running the installer (and data-remote uninstall) only ever touches content between them. Edits made inside the block are clobbered on the next install. If you want a permanent customization, put it outside the sentinels.
Smart Detection
The installer checks for:
CLAUDE_CONFIG_DIR- Respects custom Claude config directory if set in Replit SecretsCODEX_HOME- Respects custom Codex config directory- Existing persistent config - Uses your existing config if present (won't migrate if custom dir set)
- Replit Secrets - Detects
ANTHROPIC_API_KEYandOPENAI_API_KEY - Existing installations - Won't reinstall Claude or Codex if already present
- Existing data in ~/.claude - Moves it to persistent storage instead of overwriting
Supported Environment Variables
Only the two canonical env vars below are read by every downstream tool. We also accept a couple of historical aliases (CLAUDE_WORKSPACE_DIR, etc.) at first install only as a courtesy — after install, the canonical names are what flow through to Claude and Codex. If you want a custom path, set the canonical name.
Claude Code:
| Variable | Purpose |
|----------|---------|
| CLAUDE_CONFIG_DIR | Custom directory for Claude config/data (canonical) |
| ANTHROPIC_API_KEY | Claude API authentication |
OpenAI Codex CLI:
| Variable | Purpose |
|----------|---------|
| CODEX_HOME | Custom directory for Codex config/data (canonical, official) |
| OPENAI_API_KEY | Codex API authentication |
If you set CLAUDE_CONFIG_DIR / CODEX_HOME in your Replit Secrets to paths inside /home/runner/workspace/, DATA Tools will use those directories for persistence instead of the defaults. Your custom directories will NOT be migrated - we respect your configuration.
CLI Flags
npx -y data-remote is the canonical entrypoint. The CLI supports:
| Command / Flag | Description |
|----------------|-------------|
| data-remote | Run the installer (default — idempotent, safe to re-run) |
| data-remote -v, data-remote --version | Print the installed version and exit |
| data-remote -h, data-remote --help | Show usage and exit |
| data-remote --refresh | Exec setup-claude-code.sh --refresh (re-detects Claude binaries, repromotes the latest into .claude-versions/, reapplies symlinks). Exit code is propagated from the script. |
| data-remote uninstall | Remove the three managed symlinks (~/.claude, ~/.codex, ~/.local/bin/claude), strip the sentinel-wrapped bashrc block, and strip the managed onBoot line from .replit. Persistent data in .replit-tools/ is preserved. |
| data-remote uninstall --purge | Same as uninstall, then rm -rf .replit-tools/. Destructive — deletes all DATA Tools state (conversations, credentials, SSH keys, bash history, session mirror). |
Any unknown argument exits with code 2 and prints usage.
Commands
After installation, these aliases are available:
| Command | Runs | Description |
|---------|------|-------------|
| cr | claude -c --dangerously-skip-permissions | Continue last Claude session |
| claude-resume | claude -c --dangerously-skip-permissions | Same as cr |
| claude-new | claude --dangerously-skip-permissions | Start a new Claude session |
| claude-pick | claude -r --dangerously-skip-permissions | Claude's built-in session picker |
| cm | claude_menu | Show the DATA session manager menu |
| claude-menu | claude_menu | Same as cm |
| j | claude /login --dangerously-skip-permissions | Login to Claude (authenticate) |
| claude-login | claude /login --dangerously-skip-permissions | Same as j |
| k | codex login --device-auth | Login to Codex (device-auth flow) |
| codex-login | codex login --device-auth | Same as k |
| codex-new | codex --dangerously-bypass-approvals-and-sandbox | Start a new Codex session |
| codex-resume | codex --dangerously-bypass-approvals-and-sandbox resume | Resume a Codex session |
These aliases work from any shell, even without the session manager loop running.
Why we skip permissions
The Claude aliases pass --dangerously-skip-permissions because:
- You already authorized DATA Tools to manage your Claude session when you installed it. Re-prompting on every
cris hostile UX in a single-user Replit container, and most usersythrough the prompt anyway. - Replit is a single-user sandbox scoped to your workspace. Tool calls are already bounded by container isolation — there is no other human to protect.
- Codex is the same:
codex-new/codex-resumeuse--dangerously-bypass-approvals-and-sandboxfor the same reason.
If you'd rather gate per-tool inside Claude, just unalias and run the bare binary:
unalias cr claude-resume claude-new claude-pick j claude-login
claude -c # prompts per toolConfiguration
config.json
DATA Tools reads runtime preferences from ${REPLIT_TOOLS}/config.json (i.e. /home/runner/workspace/.replit-tools/config.json). Missing keys fall back to the defaults below.
| Key | Default | Purpose |
|-----|---------|---------|
| recentWindowHours | 48 | How far back the session picker's Recent list looks |
| persistenceDays | 365250 | Claude cleanupPeriodDays + Codex history retention cap (effectively forever) |
| autoUpdateHours | 24 | How often to auto-update claude and codex binaries (0 disables) |
| mirror.enabled | true | Keep an append-only mirror of every session under .replit-tools/.session-archive/ (files only grow, never shrink — survives upstream deletes) |
Example:
{
"recentWindowHours": 72,
"persistenceDays": 365250,
"autoUpdateHours": 0,
"mirror": { "enabled": true }
}Runtime environment toggles
| Variable | Effect |
|----------|--------|
| CLAUDE_NO_PROMPT=true | Disable the session picker on shell start (the menu also requires a real TTY on both stdin and stdout, so non-interactive ssh host bash -c '...' invocations are silent regardless) |
| AUTO_UPDATE=false | Skip the per-shell auto-update check for claude + codex (overrides autoUpdateHours). Also accepted: AUTO_UPDATE=0, no, off, or DATA_REMOTE_NO_AUTO_UPDATE=1 |
| AUTO_UPDATE_MAX_TARBALL_MB | Override the 5 MB size cap on the npm tarball fetched during self-update (default 5) |
| AUTORESUME_DEBUG=1 | Verbose logging in claude_prompt / session resume — surfaces why an auto-resume candidate was rejected (boot mismatch, dead owner pid, claimed by another shell, etc.) |
| DEBUG=1 | Verbose logging in data-remote itself — surfaces the npm view exit code and stderr when the "update available" check silently fails, instead of swallowing it |
Add any of these to .config/bashrc (outside the sentinel block) to make them permanent.
Use a permanent API token
claude setup-tokenCreates a long-lived API token that never expires (recommended for unattended use).
Files Created
workspace/
├── .replit-tools/ # All DATA Tools data (gitignored)
│ ├── config.json # Runtime preferences (see Configuration)
│ ├── .version # Installed data-remote version
│ ├── .claude-persistent/ # Claude conversations & credentials
│ │ └── .credentials.json # OAuth + refresh tokens
│ ├── .codex-persistent/ # Codex CLI data (auth.json, history, sessions/)
│ ├── .ssh-persistent/ # SSH keys, known_hosts, config (mode 700)
│ ├── .claude-sessions/ # Per-terminal session tracking
│ ├── .claude-versions/ # Claude binary versions
│ ├── .session-archive/ # Append-only mirror of every session
│ ├── .persistent-home/ # Bash history
│ ├── .logs/ # Auth refresh logs
│ └── scripts/ # Setup & management scripts
│ ├── setup-claude-code.sh
│ ├── claude-session-manager.sh
│ └── claude-auth-refresh.sh
├── .config/bashrc # Shell startup config (sources scripts)
└── .gitignore # Updated to ignore .replit-tools/Upgrading from v1.x
If you used DATA Tools v1.x (before the .replit-tools/ consolidation), your data will be automatically migrated:
Old Location → New Location
.claude-persistent/ → .replit-tools/.claude-persistent/
.codex-persistent/ → .replit-tools/.codex-persistent/
.claude-sessions/ → .replit-tools/.claude-sessions/
.persistent-home/ → .replit-tools/.persistent-home/
.local/share/claude/versions/ → .replit-tools/.claude-versions/Migration only happens if:
- Old location exists AND new location doesn't
- You don't have custom
CLAUDE_CONFIG_DIRorCODEX_HOMEset
Your original data is copied (not moved), so nothing is lost.
Uninstall
npx data-remote uninstallThis removes exactly the things the installer added to your environment, and nothing else:
- The three managed symlinks:
~/.claude,~/.codex, and~/.local/bin/claude. If any of those paths is a real directory (i.e. you replaced the symlink with real data), it is left alone and reported as skipped. - The managed bashrc block, identified by the sentinels
# >>> data-remote >>>…# <<< data-remote <<<in.config/bashrc. Any user content above or below the block is preserved byte-for-byte. If stripping the block empties the file, the file itself is removed. - The managed
onBoot = "...setup-claude-code.sh..."line in.replit, plus the marker comment we wrote next to it.
It deliberately does not touch:
.replit-tools/itself — all conversations, credentials, SSH keys, bash history, the append-only session mirror, the managed Claude binaries, and the installed scripts stay on disk.~/.sshand~/.local/share/claude/versions/— those symlinks are left in place so you don't lose access to SSH or to the binary discovery layer if you're only temporarily unwiring the shell hooks.
If you want everything gone, pass --purge:
npx data-remote uninstall --purge--purge runs the same uninstall as above and then rm -rf .replit-tools/. This is destructive — your Claude conversations, refresh tokens, SSH keys, and bash history all go with it. There is no confirmation prompt.
Troubleshooting
Claude or Codex not found after restart
source /home/runner/workspace/.replit-tools/scripts/setup-claude-code.shSession picker not appearing
source /home/runner/workspace/.config/bashrcAuth keeps expiring
The auto-refresh should handle this, but if it fails:
# Check why refresh failed
cat /home/runner/workspace/.replit-tools/.logs/auth-refresh.log
# Manual refresh
/home/runner/workspace/.replit-tools/scripts/claude-auth-refresh.sh --force
# Or use permanent token (recommended)
claude setup-tokenSymlinks broken
npx -y data-remote --refreshRunning the installer again is safe - it preserves existing data.
Security
The installer adds .replit-tools/ to .gitignore, which protects:
| Path | Contains | Why Protected |
|------|----------|---------------|
| .replit-tools/.claude-persistent/.credentials.json | OAuth tokens, refresh tokens | Critical - full account access |
| .replit-tools/.claude-persistent/ | Conversations | May contain sensitive prompts/output |
| .replit-tools/.codex-persistent/ | API keys in auth.json, conversations | Critical - full account access |
| .replit-tools/.ssh-persistent/ | SSH private keys, known_hosts | Critical - server access |
| .replit-tools/.claude-sessions/ | Session UUIDs, terminal mappings | Session metadata |
| .replit-tools/.session-archive/ | Append-only mirror of every session | Same sensitivity as .claude-persistent/ |
| .replit-tools/.persistent-home/ | Bash history | May contain typed secrets |
| .replit-tools/.logs/ | Token refresh timestamps | Auth timing info |
Your API keys, OAuth tokens, SSH keys, and conversation history won't be committed to git.
Why "DATA Tools"?
Developer Assistant Tool Automation - everything you need to run AI coding assistants on Replit, persisted and ready to go.
Repository
GitHub: stevemoraco/DATAtools
License
MIT
