Claude Code environment backup tool — backs up ~/.claude/ and ~/.claude.json to the cloud.
| Layer | Tech |
|-------|------|
| Monorepo | npm workspaces |
| Web | Next.js 16 (App Router), Supabase (Auth + Storage + Postgres), Tailwind CSS v4 |
| CLI | TypeScript, Commander.js, tsup (CJS bundle), Supabase JS client |
# Root npm run dev # Start web dev server (packages/web) npm run build # Build web npm run cli:build # Build CLI → packages/cli/dist/index.js # CLI dev cd packages/cli npm run dev # Watch mode (tsup --watch) npm run build # One-time build
packages/web/
app/page.tsx Landing (redirects logged-in users to /dashboard)
app/login/page.tsx Email/password login
app/signup/page.tsx Registration
app/dashboard/
page.tsx Server component — fetches user + backups
DashboardClient.tsx Sidebar layout + backup list
app/s/[token]/page.tsx Public share page
app/api/backups/[id]/
download/route.ts Streams zip from storage
components/
BackupCard.tsx 2-panel card: file tree + content viewer
ShareViewer.tsx Share page: file tree + viewer + clone cmd
LandingNav.tsx Sticky nav with mobile menu
RespawnIcon.tsx Logo icon
lib/
supabase/client.ts Browser Supabase client
supabase/server.ts Server Supabase client (cookies)
types.ts Backup, Share, ZipMetadata interfaces
proxy.ts Route protection (Next.js 16 middleware)
packages/cli/src/
index.ts Commander program
constants.ts Supabase URL/key, WEB_URL
lib/
config.ts ~/.respawn/config.json + .respawnrc
supabase.ts Authenticated Supabase client
zip.ts archiver + unzipper
output.ts chalk + ora helpers
profiles.ts File inclusion profiles (essential/standard/full)
commands/
login.ts Local HTTP server + browser OAuth
init.ts Create .respawnrc
push.ts / pull.ts Upload / restore .claude/
global.ts Global ~/.claude/ operations
share.ts Create shareable link
clone.ts Apply shared environmentvar(--font-mono) for code/paths/versions, body is sans-serif (Space Grotesk)#0a0a0a bg, #AAFF00 accent, CSS vars in globals.cssconstants.ts — intentionally publicmiddleware.ts).env*, image-cache/**, __pycache__, node_modules{user_id}/{backup_id}/files/{relPath} (individual files)project_name = "__global__" sentinel — filter in UIid, user_id, backup_id (uuid for storage), name, env_type (global|project),
project_name, project_id, message, version, file_size, platform,
profile (essential|standard|full), metadata (jsonb: files, plugins, totals), created_at
id (8-char), backup_id, user_id, download_url (1-yr signed),
shared_files (jsonb array), backup_meta (jsonb — denormalized for anon access), created_at
1. respawn login starts HTTP server on random port 49200–50000
2. Opens browser → /cli-auth?callback=http://localhost:{port}/callback
3. /cli-auth page sends tokens to callback
4. CLI saves access_token + refresh_token to ~/.respawn/config.json
/cli-auth page needs Suspense wrapper for useSearchParams()__global__ must be filtered before displaying project namessb-{ref}-auth-token=base64-{base64url(JSON)} URL-encoded