@claude-sync/cli 0.1.0 → 0.1.2
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/dist/bin/claude-sync.js +1 -1
- package/dist/bin/claude-sync.js.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/package.json +18 -5
package/dist/bin/claude-sync.js
CHANGED
|
@@ -1273,7 +1273,7 @@ async function executeCommand(command) {
|
|
|
1273
1273
|
init_config();
|
|
1274
1274
|
function run() {
|
|
1275
1275
|
const program = new Command7();
|
|
1276
|
-
program.name("claude-sync").description("Sync Claude Code sessions across machines").version("0.1.0").option("--menu", "Open interactive menu").action(async (options) => {
|
|
1276
|
+
program.name("claude-sync").description("Sync Claude Code sessions across machines \u2014 claude-sync.com").version("0.1.0").option("--menu", "Open interactive menu").action(async (options) => {
|
|
1277
1277
|
if (options.menu) {
|
|
1278
1278
|
await runTui();
|
|
1279
1279
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/config.ts","../../src/lib/api-client.ts","../../src/lib/auth.ts","../../src/lib/progress.ts","../../src/lib/theme.ts","../../src/commands/login.ts","../../src/commands/logout.ts","../../src/commands/device.ts","../../src/lib/sync-engine.ts","../../src/lib/compress.ts","../../src/commands/sync.ts","../../src/commands/status.ts","../../src/commands/whoami.ts","../../src/index.ts","../../src/commands/tui.ts","../../bin/claude-sync.ts"],"sourcesContent":["import { join, dirname } from 'node:path';\nimport { homedir } from 'node:os';\nimport { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport { CONFIG_DIR, CONFIG_FILE, MANIFEST_FILE, encodePath } from '@claude-sync/utils';\n\nexport interface CliConfig {\n apiUrl: string;\n accessToken: string | null;\n refreshToken: string | null;\n deviceId: string | null;\n deviceName: string | null;\n userId: string | null;\n email: string | null;\n}\n\nconst DEFAULT_CONFIG: CliConfig = {\n apiUrl: 'https://api.claude-sync.com',\n accessToken: null,\n refreshToken: null,\n deviceId: null,\n deviceName: null,\n userId: null,\n email: null,\n};\n\nfunction getConfigDir(): string {\n return join(homedir(), CONFIG_DIR);\n}\n\nfunction getConfigPath(): string {\n return join(getConfigDir(), CONFIG_FILE);\n}\n\nfunction getManifestPath(): string {\n return join(getConfigDir(), MANIFEST_FILE);\n}\n\nexport async function loadConfig(): Promise<CliConfig> {\n try {\n const content = await readFile(getConfigPath(), 'utf-8');\n return { ...DEFAULT_CONFIG, ...JSON.parse(content) };\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n}\n\nexport async function saveConfig(config: Partial<CliConfig>): Promise<void> {\n const existing = await loadConfig();\n const merged = { ...existing, ...config };\n await mkdir(getConfigDir(), { recursive: true });\n await writeFile(getConfigPath(), JSON.stringify(merged, null, 2));\n}\n\nexport async function clearConfig(): Promise<void> {\n await saveConfig(DEFAULT_CONFIG);\n}\n\nexport async function loadManifest(): Promise<import('@claude-sync/types').ManifestEntry[]> {\n try {\n const content = await readFile(getManifestPath(), 'utf-8');\n return JSON.parse(content);\n } catch {\n return [];\n }\n}\n\nexport async function saveManifest(entries: import('@claude-sync/types').ManifestEntry[]): Promise<void> {\n await mkdir(getConfigDir(), { recursive: true });\n await writeFile(getManifestPath(), JSON.stringify(entries, null, 2));\n}\n\nexport async function loadProjectManifest(projectPath: string): Promise<import('@claude-sync/types').ManifestEntry[]> {\n try {\n const encoded = encodePath(projectPath);\n const manifestPath = join(getConfigDir(), 'manifests', `${encoded}.json`);\n const content = await readFile(manifestPath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return [];\n }\n}\n\nexport async function saveProjectManifest(projectPath: string, entries: import('@claude-sync/types').ManifestEntry[]): Promise<void> {\n const encoded = encodePath(projectPath);\n const manifestPath = join(getConfigDir(), 'manifests', `${encoded}.json`);\n await mkdir(dirname(manifestPath), { recursive: true });\n await writeFile(manifestPath, JSON.stringify(entries, null, 2));\n}\n\nexport function isAuthenticated(config: CliConfig): boolean {\n return config.accessToken !== null;\n}\n\nexport interface ProjectLink {\n projectId: string;\n foreignEncodedDir: string;\n linkedAt: string;\n}\n\nexport async function loadProjectLink(projectPath: string): Promise<ProjectLink | null> {\n try {\n const encoded = encodePath(projectPath);\n const linkPath = join(getConfigDir(), 'project-links', `${encoded}.json`);\n const content = await readFile(linkPath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\nexport async function saveProjectLink(projectPath: string, link: ProjectLink): Promise<void> {\n const encoded = encodePath(projectPath);\n const linkPath = join(getConfigDir(), 'project-links', `${encoded}.json`);\n await mkdir(dirname(linkPath), { recursive: true });\n await writeFile(linkPath, JSON.stringify(link, null, 2));\n}\n","import type { ApiErrorResponse } from '@claude-sync/types';\nimport { getValidToken } from './auth.js';\n\nexport class ApiClient {\n private baseUrl: string;\n\n constructor(baseUrl: string) {\n this.baseUrl = baseUrl.replace(/\\/$/, '');\n }\n\n private async rawRequest<T>(path: string, options: RequestInit = {}): Promise<T> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 15000);\n\n let response: Response;\n try {\n response = await fetch(`${this.baseUrl}${path}`, {\n ...options,\n signal: controller.signal,\n });\n } catch (err) {\n clearTimeout(timeout);\n if (err instanceof Error && err.name === 'AbortError') {\n throw new Error('Request timed out. Is the API server running?');\n }\n throw err;\n }\n clearTimeout(timeout);\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error('Session expired. Run `claude-sync login` to re-authenticate.');\n }\n const error: ApiErrorResponse = await response.json().catch(() => ({\n statusCode: response.status,\n message: response.statusText,\n error: 'Request failed',\n }));\n throw new Error(error.message);\n }\n\n const json = await response.json();\n return (json.data !== undefined ? json.data : json) as T;\n }\n\n async request<T>(path: string, options: RequestInit = {}): Promise<T> {\n const token = await getValidToken();\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(options.headers as Record<string, string>),\n };\n\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n return this.rawRequest<T>(path, { ...options, headers });\n }\n\n async requestNoAuth<T>(path: string, options: RequestInit = {}): Promise<T> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(options.headers as Record<string, string>),\n };\n\n return this.rawRequest<T>(path, { ...options, headers });\n }\n\n async get<T>(path: string): Promise<T> {\n return this.request<T>(path, { method: 'GET' });\n }\n\n async post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(path, {\n method: 'POST',\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n async patch<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(path, {\n method: 'PATCH',\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n async delete<T>(path: string): Promise<T> {\n return this.request<T>(path, { method: 'DELETE' });\n }\n}\n","import type { TokenPair } from '@claude-sync/types';\nimport { loadConfig, saveConfig } from './config.js';\nimport { ApiClient } from './api-client.js';\n\nexport async function storeTokens(tokens: TokenPair, userId: string, email: string): Promise<void> {\n await saveConfig({\n accessToken: tokens.accessToken,\n refreshToken: tokens.refreshToken,\n userId,\n email,\n });\n}\n\nexport async function refreshAccessToken(): Promise<string | null> {\n const config = await loadConfig();\n if (!config.refreshToken) return null;\n\n const client = new ApiClient(config.apiUrl);\n try {\n const response = await client.requestNoAuth<TokenPair>('/api/auth/refresh', {\n method: 'POST',\n body: JSON.stringify({ refreshToken: config.refreshToken }),\n });\n await saveConfig({\n accessToken: response.accessToken,\n refreshToken: response.refreshToken,\n });\n return response.accessToken;\n } catch {\n return null;\n }\n}\n\nexport async function getValidToken(): Promise<string | null> {\n const config = await loadConfig();\n if (!config.accessToken) return null;\n\n try {\n const payload = JSON.parse(\n Buffer.from(config.accessToken.split('.')[1], 'base64').toString()\n );\n if (payload.exp * 1000 > Date.now()) {\n return config.accessToken;\n }\n } catch {\n }\n\n return refreshAccessToken();\n}\n","import ora, { type Ora } from 'ora';\nimport chalk from 'chalk';\n\nconst brandColor = chalk.hex('#8a8cdd');\n\nexport function createSpinner(text: string): Ora {\n return ora({ text: brandColor(text), spinner: 'dots', color: 'magenta' });\n}\n\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) return '0 B';\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;\n}\n\nexport function formatProgress(current: number, total: number): string {\n const percentage = total > 0 ? Math.round((current / total) * 100) : 0;\n return `${current}/${total} (${percentage}%)`;\n}\n","import chalk from 'chalk';\n\nconst BRAND_HEX = '#8a8cdd';\nconst BRAND_DIM_HEX = '#6b6db8';\nconst SUCCESS_HEX = '#8adda0';\nconst WARN_HEX = '#ddcc8a';\nconst ERROR_HEX = '#dd8a8a';\n\nexport const brand = chalk.hex(BRAND_HEX);\nexport const brandBold = chalk.hex(BRAND_HEX).bold;\nexport const brandDim = chalk.hex(BRAND_DIM_HEX);\nexport const success = chalk.hex(SUCCESS_HEX);\nexport const successBold = chalk.hex(SUCCESS_HEX).bold;\nexport const warn = chalk.hex(WARN_HEX);\nexport const error = chalk.hex(ERROR_HEX);\nexport const errorBold = chalk.hex(ERROR_HEX).bold;\nexport const dim = chalk.dim;\nexport const bold = chalk.bold;\nexport const white = chalk.white;\n\nexport function printBanner() {\n console.log();\n console.log(` ${brandBold('claude-sync')} ${dim('v0.1.0')}`);\n console.log();\n}\n\nexport function printIntro(title: string) {\n console.log();\n console.log(` ${brandBold(title)}`);\n console.log();\n}\n\nexport function printOutro(message: string) {\n console.log();\n console.log(` ${dim(message)}`);\n console.log();\n}\n\nexport function printSuccess(message: string) {\n console.log(` ${success('✔')} ${message}`);\n}\n\nexport function printError(message: string) {\n console.log(` ${error('✖')} ${message}`);\n}\n\nexport function printWarn(message: string) {\n console.log(` ${warn('▲')} ${message}`);\n}\n\nexport function printInfo(message: string) {\n console.log(` ${brand('●')} ${message}`);\n}\n\nexport function printLabel(label: string, value: string) {\n console.log(` ${dim(label.padEnd(14))} ${white(value)}`);\n}\n\nexport function printDivider() {\n console.log();\n}\n","import { Command } from 'commander';\nimport { text, password as passwordPrompt, select, isCancel } from '@clack/prompts';\nimport type { TokenPair, CliInitiateResponse, CliPollResponse } from '@claude-sync/types';\nimport { loadConfig } from '../lib/config.js';\nimport { storeTokens } from '../lib/auth.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { createSpinner } from '../lib/progress.js';\nimport { printIntro, printOutro, printInfo, printSuccess, printError, brand, brandBold, dim } from '../lib/theme.js';\n\nasync function loginWithBrowser(client: ApiClient): Promise<void> {\n const response = await client.requestNoAuth<CliInitiateResponse>('/api/auth/cli/initiate', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n });\n\n printInfo(`Open this URL in your browser:\\n ${brandBold(response.verifyUrl)}`);\n printInfo(`Code: ${brandBold(response.code)}`);\n\n const spinner = createSpinner('Waiting for browser authorization...').start();\n\n const pollInterval = 2000;\n const maxAttempts = 150;\n let attempts = 0;\n\n while (attempts < maxAttempts) {\n await new Promise((resolve) => setTimeout(resolve, pollInterval));\n attempts++;\n\n try {\n const pollResponse = await client.requestNoAuth<CliPollResponse>('/api/auth/cli/poll', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ code: response.code }),\n });\n\n if (pollResponse.status === 'authorized' && pollResponse.tokenPair && pollResponse.user) {\n spinner.stop();\n await storeTokens(pollResponse.tokenPair, pollResponse.user.id, pollResponse.user.email);\n printSuccess(`Logged in as ${brandBold(pollResponse.user.email)}`);\n return;\n }\n\n if (pollResponse.status === 'expired') {\n spinner.stop();\n printError('Authorization code expired. Please try again.');\n process.exit(1);\n }\n } catch {\n }\n }\n\n spinner.stop();\n printError('Authorization timed out. Please try again.');\n process.exit(1);\n}\n\nasync function loginWithEmail(client: ApiClient): Promise<void> {\n const email = await text({ message: `${brand('Email')}:` });\n if (isCancel(email)) process.exit(0);\n\n const password = await passwordPrompt({ message: `${brand('Password')}:` });\n if (isCancel(password)) process.exit(0);\n\n const spinner = createSpinner('Logging in...').start();\n\n try {\n const response = await client.requestNoAuth<TokenPair & { user: { id: string; email: string } }>(\n '/api/auth/login',\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email, password }),\n },\n );\n spinner.stop();\n await storeTokens(\n { accessToken: response.accessToken, refreshToken: response.refreshToken, expiresIn: 900 },\n response.user.id,\n response.user.email\n );\n printSuccess(`Logged in as ${brandBold(response.user.email)}`);\n } catch (err) {\n spinner.stop();\n printError(`Login failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n}\n\nexport function loginCommand(): Command {\n return new Command('login')\n .description('Authenticate with claude-sync')\n .action(async () => {\n printIntro('Login');\n\n const config = await loadConfig();\n const client = new ApiClient(config.apiUrl);\n\n const method = await select({\n message: `${brand('How would you like to log in?')}`,\n options: [\n { value: 'browser', label: `${brand('○')} Browser ${dim('(recommended)')}` },\n { value: 'email', label: `${brand('○')} Email & password` },\n ],\n });\n\n if (isCancel(method)) process.exit(0);\n\n if (method === 'browser') {\n await loginWithBrowser(client);\n } else {\n await loginWithEmail(client);\n }\n\n printOutro('Authentication complete');\n });\n}\n","import { Command } from 'commander';\nimport { loadConfig, clearConfig } from '../lib/config.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { printIntro, printOutro, printInfo, printSuccess } from '../lib/theme.js';\n\nexport function logoutCommand(): Command {\n return new Command('logout')\n .description('Log out and revoke tokens')\n .action(async () => {\n printIntro('Logout');\n\n const config = await loadConfig();\n if (!config.accessToken) {\n printInfo('Not currently logged in.');\n printOutro('Done');\n return;\n }\n\n try {\n const client = new ApiClient(config.apiUrl);\n await client.post('/api/auth/logout', {\n refreshToken: config.refreshToken,\n });\n } catch {\n }\n\n await clearConfig();\n printSuccess('Logged out successfully.');\n printOutro('Done');\n });\n}\n","import { Command } from 'commander';\nimport { hostname, platform, arch, homedir } from 'node:os';\nimport { text, isCancel } from '@clack/prompts';\nimport type { Device } from '@claude-sync/types';\nimport { loadConfig, saveConfig, isAuthenticated } from '../lib/config.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { createSpinner } from '../lib/progress.js';\nimport { printIntro, printOutro, printSuccess, printError, printInfo, printLabel, printDivider, brand, brandBold, dim, success, error as errorColor, white } from '../lib/theme.js';\n\nfunction requireAuth(config: Awaited<ReturnType<typeof loadConfig>>): void {\n if (!isAuthenticated(config)) {\n printError('Not logged in. Run `claude-sync login` first.');\n process.exit(1);\n }\n}\n\nexport function deviceCommand(): Command {\n const device = new Command('device').description('Manage devices');\n\n device\n .command('add')\n .argument('[name]', 'Device name')\n .description('Register this machine as a device')\n .action(async (name?: string) => {\n printIntro('Device Add');\n\n const config = await loadConfig();\n requireAuth(config);\n\n const deviceName = name || await (async () => {\n const input = await text({ message: `${brand('Device name')}:`, initialValue: hostname() });\n if (isCancel(input)) process.exit(0);\n return input;\n })();\n\n const spinner = createSpinner('Registering device...').start();\n const client = new ApiClient(config.apiUrl);\n\n try {\n const response = await client.post<Device>('/api/devices', {\n name: deviceName,\n hostname: hostname(),\n platform: platform(),\n homeDir: homedir(),\n arch: arch(),\n });\n\n await saveConfig({\n deviceId: response.id,\n deviceName: response.name,\n });\n\n spinner.stop();\n printSuccess(`Device ${brandBold(`\"${response.name}\"`)} registered`);\n printLabel('ID', response.id);\n } catch (err) {\n spinner.stop();\n printError(`Failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n\n printOutro('Done');\n });\n\n device\n .command('list')\n .description('List all registered devices')\n .action(async () => {\n printIntro('Devices');\n\n const config = await loadConfig();\n requireAuth(config);\n\n const client = new ApiClient(config.apiUrl);\n const spinner = createSpinner('Fetching devices...').start();\n\n try {\n const devices = await client.get<Device[]>('/api/devices');\n spinner.stop();\n\n if (devices.length === 0) {\n printInfo('No devices registered.');\n return;\n }\n\n console.log();\n for (const d of devices) {\n const current = d.id === config.deviceId ? ` ${brandBold('(current)')}` : '';\n const active = d.isActive ? success('active') : errorColor('inactive');\n console.log(` ${brand('○')} ${white(d.name)}${current}`);\n console.log(` ${dim(d.platform)} ${dim('·')} ${active} ${dim('·')} ${dim(d.id)}`);\n }\n console.log();\n } catch (err) {\n spinner.stop();\n printError(`Failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n });\n\n device\n .command('remove')\n .argument('<nameOrId>', 'Device name or ID')\n .description('Remove a device')\n .action(async (nameOrId: string) => {\n const config = await loadConfig();\n requireAuth(config);\n\n const client = new ApiClient(config.apiUrl);\n const spinner = createSpinner('Removing device...').start();\n\n try {\n await client.delete(`/api/devices/${nameOrId}`);\n spinner.stop();\n\n if (config.deviceId === nameOrId) {\n await saveConfig({ deviceId: null, deviceName: null });\n }\n\n printSuccess('Device removed.');\n } catch (err) {\n spinner.stop();\n printError(`Failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n });\n\n device\n .command('rename')\n .argument('<name>', 'New name')\n .description('Rename the current device')\n .action(async (name: string) => {\n const config = await loadConfig();\n requireAuth(config);\n\n if (!config.deviceId) {\n printError('No device registered. Run `claude-sync device add` first.');\n process.exit(1);\n }\n\n const client = new ApiClient(config.apiUrl);\n const spinner = createSpinner('Renaming device...').start();\n\n try {\n const response = await client.patch<Device>(`/api/devices/${config.deviceId}`, { name });\n await saveConfig({ deviceName: response.name });\n spinner.stop();\n printSuccess(`Device renamed to ${brandBold(`\"${response.name}\"`)}`);\n } catch (err) {\n spinner.stop();\n printError(`Failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n });\n\n return device;\n}\n","import { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { readdir, stat, lstat, readlink } from 'node:fs/promises';\nimport type { ManifestEntry, ManifestDiff } from '@claude-sync/types';\nimport { hashFile, diffManifests, encodePath, CLAUDE_DIR, PROJECTS_DIR, SYNC_EXCLUDE_PATTERNS } from '@claude-sync/utils';\n\nfunction shouldExclude(name: string): boolean {\n return SYNC_EXCLUDE_PATTERNS.some((pattern) => {\n if (pattern.startsWith('*')) {\n return name.endsWith(pattern.slice(1));\n }\n return name === pattern;\n });\n}\n\nasync function walkDirectory(dir: string, basePath: string = ''): Promise<ManifestEntry[]> {\n const entries: ManifestEntry[] = [];\n const items = await readdir(dir, { withFileTypes: true });\n\n for (const item of items) {\n if (shouldExclude(item.name)) continue;\n\n const fullPath = join(dir, item.name);\n const relativePath = basePath ? `${basePath}/${item.name}` : item.name;\n\n if (item.isDirectory()) {\n const subEntries = await walkDirectory(fullPath, relativePath);\n entries.push(...subEntries);\n } else if (item.isFile()) {\n const fileStat = await stat(fullPath);\n const hash = await hashFile(fullPath);\n const isText = !isBinaryPath(item.name);\n entries.push({\n path: relativePath,\n hash,\n size: fileStat.size,\n modifiedAt: fileStat.mtime.toISOString(),\n isCompressed: isText,\n });\n }\n }\n\n return entries;\n}\n\nfunction isBinaryPath(name: string): boolean {\n const binaryExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.ico', '.pdf', '.zip', '.gz', '.tar'];\n return binaryExtensions.some((ext) => name.endsWith(ext));\n}\n\nexport async function buildManifest(): Promise<ManifestEntry[]> {\n const claudeDir = join(homedir(), CLAUDE_DIR);\n return walkDirectory(claudeDir);\n}\n\nexport type ProjectState = 'none' | 'real' | 'symlink';\n\nexport interface ProjectContext {\n cwd: string;\n encodedPath: string;\n projectDir: string;\n state: ProjectState;\n symlinkTarget?: string;\n}\n\nexport async function resolveProjectState(cwd: string): Promise<ProjectContext> {\n const projectsDir = join(homedir(), CLAUDE_DIR, PROJECTS_DIR);\n const encoded = encodePath(cwd);\n const projectDir = join(projectsDir, encoded);\n\n let state: ProjectState = 'none';\n let symlinkTarget: string | undefined;\n\n try {\n const stats = await lstat(projectDir);\n if (stats.isSymbolicLink()) {\n state = 'symlink';\n symlinkTarget = await readlink(projectDir);\n } else if (stats.isDirectory()) {\n state = 'real';\n }\n } catch {\n state = 'none';\n }\n\n return { cwd, encodedPath: encoded, projectDir, state, symlinkTarget };\n}\n\nexport async function buildProjectManifest(cwd: string): Promise<ManifestEntry[]> {\n const ctx = await resolveProjectState(cwd);\n\n if (ctx.state === 'none') return [];\n\n const projectsDir = join(homedir(), CLAUDE_DIR, PROJECTS_DIR);\n let targetDir = ctx.projectDir;\n\n if (ctx.state === 'symlink' && ctx.symlinkTarget) {\n targetDir = join(projectsDir, ctx.symlinkTarget);\n }\n\n try {\n return await walkDirectory(targetDir);\n } catch {\n return [];\n }\n}\n\nexport function computeDiff(local: ManifestEntry[], remote: ManifestEntry[]): ManifestDiff {\n return diffManifests(local, remote);\n}\n","import { createGzip, createGunzip } from 'node:zlib';\nimport { createReadStream, createWriteStream } from 'node:fs';\nimport { pipeline } from 'node:stream/promises';\n\nexport async function compressFile(inputPath: string, outputPath: string): Promise<void> {\n const source = createReadStream(inputPath);\n const destination = createWriteStream(outputPath);\n const gzip = createGzip();\n await pipeline(source, gzip, destination);\n}\n\nexport async function decompressFile(inputPath: string, outputPath: string): Promise<void> {\n const source = createReadStream(inputPath);\n const destination = createWriteStream(outputPath);\n const gunzip = createGunzip();\n await pipeline(source, gunzip, destination);\n}\n\nexport function compressBuffer(data: Buffer): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const gzip = createGzip();\n const chunks: Buffer[] = [];\n gzip.on('data', (chunk: Buffer) => chunks.push(chunk));\n gzip.on('end', () => resolve(Buffer.concat(chunks)));\n gzip.on('error', reject);\n gzip.end(data);\n });\n}\n\nexport function decompressBuffer(data: Buffer): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const gunzip = createGunzip();\n const chunks: Buffer[] = [];\n gunzip.on('data', (chunk: Buffer) => chunks.push(chunk));\n gunzip.on('end', () => resolve(Buffer.concat(chunks)));\n gunzip.on('error', reject);\n gunzip.end(data);\n });\n}\n","import { Command } from 'commander';\nimport { select, isCancel } from '@clack/prompts';\nimport type { PushPrepareResponse, PullPrepareResponse, PresignedUrlResponse } from '@claude-sync/types';\nimport type { ManifestEntry } from '@claude-sync/types';\nimport { loadConfig, saveProjectManifest, isAuthenticated, loadProjectLink, saveProjectLink } from '../lib/config.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { resolveProjectState, buildProjectManifest } from '../lib/sync-engine.js';\nimport { createSpinner, formatBytes, formatProgress } from '../lib/progress.js';\nimport { compressBuffer, decompressBuffer } from '../lib/compress.js';\nimport { readFile, writeFile, mkdir, lstat, symlink, unlink } from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { homedir } from 'node:os';\nimport { CLAUDE_DIR, PROJECTS_DIR } from '@claude-sync/utils';\nimport { printIntro, printOutro, printInfo, printSuccess, printError, brand, success as successColor, dim } from '../lib/theme.js';\nimport type { CliConfig } from '../lib/config.js';\nimport type { ProjectContext } from '../lib/sync-engine.js';\n\ninterface DeviceProject {\n id: string;\n displayName: string;\n originalPath: string;\n canonicalPath: string;\n encodedDir: string;\n localPath: string;\n}\n\ninterface DeviceInfo {\n id: string;\n name: string;\n hostname: string;\n platform: string;\n}\n\nexport async function runSync(options: { dryRun?: boolean; verbose?: boolean }) {\n printIntro('Sync');\n\n const config = await loadConfig();\n if (!isAuthenticated(config)) {\n printError('Not logged in. Run `claude-sync login` first.');\n return;\n }\n if (!config.deviceId) {\n printError('No device registered. Run `claude-sync device add` first.');\n return;\n }\n\n const cwd = process.cwd();\n const ctx = await resolveProjectState(cwd);\n const client = new ApiClient(config.apiUrl);\n const projectsDir = join(homedir(), CLAUDE_DIR, PROJECTS_DIR);\n const projectLink = await loadProjectLink(cwd);\n\n let projectDir = ctx.projectDir;\n if (ctx.state === 'symlink' && ctx.symlinkTarget) {\n projectDir = join(projectsDir, ctx.symlinkTarget);\n }\n\n printInfo(`Project: ${brand(cwd)}`);\n if (ctx.state === 'symlink') {\n printInfo(`Linked to: ${dim(ctx.symlinkTarget || 'unknown')}`);\n }\n\n const manifest = await buildProjectManifest(cwd);\n\n if (!projectLink) {\n const result = await handleFirstRun(client, config, cwd, ctx, manifest, projectDir, projectsDir, options);\n\n if (result === 'cancelled') {\n printOutro('Cancelled.');\n return;\n }\n\n if (result === 'pulled') {\n const finalManifest = await buildProjectManifest(cwd);\n await saveProjectManifest(cwd, finalManifest);\n printSuccess('Sessions synced from remote device.');\n printOutro('Done');\n return;\n }\n\n if (result === 'pushed') {\n const finalManifest = await buildProjectManifest(cwd);\n await saveProjectManifest(cwd, finalManifest);\n printOutro('Done');\n return;\n }\n\n printOutro('Done');\n return;\n }\n\n let pushResult: PushResult = { uploaded: 0, projectId: projectLink.projectId, failed: false };\n let pullResult: PullResult = { downloaded: 0, failed: false };\n\n if (manifest.length > 0) {\n pushResult = await pushPhase(client, config.deviceId, cwd, manifest, projectDir, projectLink.projectId, options);\n }\n\n if (!pushResult.failed) {\n pullResult = await pullPhase(client, config.deviceId, cwd, projectDir, projectLink.projectId, options);\n }\n\n if (pushResult.failed && pullResult.failed) {\n printOutro('Sync failed.');\n return;\n }\n\n const finalManifest = await buildProjectManifest(cwd);\n await saveProjectManifest(cwd, finalManifest);\n\n if (pushResult.uploaded > 0 || pullResult.downloaded > 0) {\n const parts: string[] = [];\n if (pushResult.uploaded > 0) parts.push(`${successColor(`+${pushResult.uploaded}`)} pushed`);\n if (pullResult.downloaded > 0) parts.push(`${successColor(`+${pullResult.downloaded}`)} pulled`);\n printSuccess(`Synced: ${parts.join(', ')}`);\n } else if (!pushResult.failed && !pullResult.failed) {\n printSuccess('Everything is up to date.');\n }\n\n printOutro('Done');\n}\n\nasync function handleFirstRun(\n client: ApiClient,\n config: CliConfig,\n cwd: string,\n ctx: ProjectContext,\n manifest: ManifestEntry[],\n projectDir: string,\n projectsDir: string,\n options: { dryRun?: boolean; verbose?: boolean },\n): Promise<'pushed' | 'pulled' | 'cancelled'> {\n printInfo(brand('First time syncing this project'));\n\n const hasLocalFiles = ctx.state !== 'none' && manifest.length > 0;\n\n const devicesSpinner = createSpinner('Checking for other devices...').start();\n let devices: DeviceInfo[];\n try {\n devices = await client.get<DeviceInfo[]>('/api/devices');\n } catch {\n devices = [];\n }\n devicesSpinner.stop();\n\n const otherDevices = devices.filter((d) => d.id !== config.deviceId);\n\n type FirstRunChoice = 'push' | 'continue';\n const menuOptions: { value: FirstRunChoice; label: string; hint?: string }[] = [];\n\n if (hasLocalFiles) {\n menuOptions.push({\n value: 'push',\n label: 'Push to cloud',\n hint: dim(`Upload ${manifest.length} local files`),\n });\n }\n\n if (otherDevices.length > 0) {\n menuOptions.push({\n value: 'continue',\n label: 'Continue from another machine',\n hint: dim('Pull sessions from a device'),\n });\n }\n\n if (menuOptions.length === 0) {\n printInfo('No local sessions and no other devices found.');\n printInfo('Use Claude Code in this directory first, then run sync.');\n return 'cancelled';\n }\n\n if (menuOptions.length === 1 && menuOptions[0].value === 'push') {\n printInfo('No other devices found.');\n }\n\n const choice = await select<FirstRunChoice>({\n message: brand('What would you like to do?'),\n options: menuOptions,\n });\n\n if (isCancel(choice)) return 'cancelled';\n\n if (choice === 'push') {\n const result = await pushPhase(client, config.deviceId!, cwd, manifest, projectDir, undefined, options);\n if (result.failed) {\n return 'cancelled';\n }\n if (result.uploaded > 0) {\n printSuccess(`${successColor(`+${result.uploaded}`)} files pushed`);\n }\n await saveProjectLink(cwd, {\n projectId: result.projectId,\n foreignEncodedDir: ctx.encodedPath,\n linkedAt: new Date().toISOString(),\n });\n return 'pushed';\n }\n\n const deviceChoice = await select({\n message: brand('Select device'),\n options: otherDevices.map((d) => ({\n value: d.id,\n label: d.name,\n hint: dim(`${d.hostname} · ${d.platform}`),\n })),\n });\n\n if (isCancel(deviceChoice)) return 'cancelled';\n\n const spinner = createSpinner('Loading projects...').start();\n let projects: DeviceProject[];\n try {\n projects = await client.get<DeviceProject[]>(`/api/devices/${deviceChoice}/projects`);\n } catch {\n spinner.stop();\n printError('Failed to load projects from device.');\n return 'cancelled';\n }\n spinner.stop();\n\n if (projects.length === 0) {\n printInfo('No projects found on that device.');\n return 'cancelled';\n }\n\n const projectChoice = await select({\n message: brand('Select project'),\n options: projects.map((p) => ({\n value: p.id,\n label: p.displayName || p.originalPath,\n hint: dim(p.localPath),\n })),\n });\n\n if (isCancel(projectChoice)) return 'cancelled';\n\n const selectedProject = projects.find((p) => p.id === projectChoice)!;\n\n const downloaded = await crossMachinePull(\n client,\n config.deviceId!,\n cwd,\n deviceChoice as string,\n selectedProject.id,\n selectedProject.encodedDir,\n projectsDir,\n options,\n );\n\n if (downloaded === 0 && !options.dryRun) {\n printInfo('No files to download.');\n return 'cancelled';\n }\n\n if (!options.dryRun) {\n await createProjectSymlink(projectsDir, ctx.encodedPath, selectedProject.encodedDir);\n\n await saveProjectLink(cwd, {\n projectId: selectedProject.id,\n foreignEncodedDir: selectedProject.encodedDir,\n linkedAt: new Date().toISOString(),\n });\n\n printSuccess(`${successColor(`+${downloaded}`)} files pulled`);\n printInfo(`Symlink: ${dim(ctx.encodedPath)} → ${dim(selectedProject.encodedDir)}`);\n }\n\n return 'pulled';\n}\n\nasync function createProjectSymlink(projectsDir: string, localEncoded: string, foreignEncoded: string) {\n const symlinkPath = join(projectsDir, localEncoded);\n\n await mkdir(projectsDir, { recursive: true });\n\n try {\n const stats = await lstat(symlinkPath);\n if (stats.isSymbolicLink()) {\n await unlink(symlinkPath);\n } else if (stats.isDirectory()) {\n printError(`Local session directory already exists. Back it up first:\\n mv \"${symlinkPath}\" \"${symlinkPath}.bak\"`);\n return;\n }\n } catch {\n }\n\n await symlink(foreignEncoded, symlinkPath);\n}\n\nasync function crossMachinePull(\n client: ApiClient,\n deviceId: string,\n projectPath: string,\n fromDeviceId: string,\n projectId: string,\n foreignEncodedDir: string,\n projectsDir: string,\n options: { dryRun?: boolean; verbose?: boolean },\n): Promise<number> {\n const spinner = createSpinner('Preparing pull from remote device...').start();\n\n let prepareResponse: PullPrepareResponse;\n try {\n prepareResponse = await client.post<PullPrepareResponse>('/api/sync/pull/prepare', {\n deviceId,\n projectPath,\n fromDeviceId,\n projectId,\n });\n } catch (err) {\n spinner.stop();\n printError(`Pull failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n return 0;\n }\n spinner.stop();\n\n const filesToDownload = prepareResponse.filesToDownload;\n if (filesToDownload.length === 0) return 0;\n\n printInfo(`${brand(String(filesToDownload.length))} files to pull`);\n\n if (options.dryRun) {\n if (options.verbose) {\n for (const entry of filesToDownload) {\n console.log(` ${brand('○')} ${entry.path} ${dim(`(${formatBytes(entry.size)})`)}`);\n }\n }\n return filesToDownload.length;\n }\n\n const targetDir = join(projectsDir, foreignEncodedDir);\n let downloaded = 0;\n\n for (const entry of filesToDownload) {\n const dlSpinner = createSpinner(\n `${formatProgress(downloaded + 1, filesToDownload.length)} ${entry.path}`,\n ).start();\n\n try {\n const urlResponse = await client.post<PresignedUrlResponse>('/api/sync/pull/download-url', {\n syncEventId: prepareResponse.syncEventId,\n key: entry.path,\n });\n\n const response = await fetch(urlResponse.url);\n let data = Buffer.from(await response.arrayBuffer());\n\n if (entry.isCompressed) {\n data = await decompressBuffer(data);\n }\n\n const outputPath = join(targetDir, entry.path);\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, data);\n\n downloaded++;\n } catch {\n }\n dlSpinner.stop();\n }\n\n try {\n await client.post('/api/sync/pull/complete', {\n syncEventId: prepareResponse.syncEventId,\n manifest: filesToDownload,\n });\n } catch {\n }\n\n return downloaded;\n}\n\ninterface PushResult {\n uploaded: number;\n projectId: string;\n failed: boolean;\n}\n\ninterface PullResult {\n downloaded: number;\n failed: boolean;\n}\n\nasync function pushPhase(\n client: ApiClient,\n deviceId: string,\n projectPath: string,\n manifest: ManifestEntry[],\n projectDir: string,\n projectId: string | undefined,\n options: { dryRun?: boolean; verbose?: boolean },\n): Promise<PushResult> {\n const spinner = createSpinner('Preparing push...').start();\n\n let prepareResponse: PushPrepareResponse;\n try {\n prepareResponse = await client.post<PushPrepareResponse>('/api/sync/push/prepare', {\n deviceId,\n projectPath,\n projectId,\n manifest,\n });\n } catch (err) {\n spinner.stop();\n printError(`Push failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n return { uploaded: 0, projectId: projectId || '', failed: true };\n }\n spinner.stop();\n\n const resolvedProjectId = prepareResponse.projectId;\n const filesToUpload = prepareResponse.filesToUpload;\n if (filesToUpload.length === 0) return { uploaded: 0, projectId: resolvedProjectId, failed: false };\n\n printInfo(`${brand(String(filesToUpload.length))} files to push`);\n\n if (options.dryRun) {\n if (options.verbose) {\n for (const entry of filesToUpload) {\n console.log(` ${successColor('+')} ${entry.path} ${dim(`(${formatBytes(entry.size)})`)}`);\n }\n }\n return { uploaded: filesToUpload.length, projectId: resolvedProjectId, failed: false };\n }\n\n let uploaded = 0;\n for (const entry of filesToUpload) {\n const uploadSpinner = createSpinner(\n `${formatProgress(uploaded + 1, filesToUpload.length)} ${entry.path}`,\n ).start();\n\n try {\n const urlResponse = await client.post<PresignedUrlResponse>('/api/sync/push/upload-url', {\n syncEventId: prepareResponse.syncEventId,\n key: entry.path,\n });\n\n const filePath = join(projectDir, entry.path);\n let body: Buffer = await readFile(filePath);\n\n if (entry.isCompressed) {\n body = await compressBuffer(body);\n }\n\n await fetch(urlResponse.url, {\n method: 'PUT',\n body,\n headers: { 'Content-Type': 'application/octet-stream' },\n });\n\n uploaded++;\n } catch {\n }\n uploadSpinner.stop();\n }\n\n try {\n await client.post('/api/sync/push/complete', {\n syncEventId: prepareResponse.syncEventId,\n manifest,\n });\n } catch {\n }\n\n return { uploaded, projectId: resolvedProjectId, failed: false };\n}\n\nasync function pullPhase(\n client: ApiClient,\n deviceId: string,\n projectPath: string,\n projectDir: string,\n projectId: string | undefined,\n options: { dryRun?: boolean; verbose?: boolean },\n): Promise<PullResult> {\n const spinner = createSpinner('Preparing pull...').start();\n\n let prepareResponse: PullPrepareResponse;\n try {\n prepareResponse = await client.post<PullPrepareResponse>('/api/sync/pull/prepare', {\n deviceId,\n projectPath,\n projectId,\n });\n } catch (err) {\n spinner.stop();\n printError(`Pull failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n return { downloaded: 0, failed: true };\n }\n spinner.stop();\n\n const filesToDownload = prepareResponse.filesToDownload;\n if (filesToDownload.length === 0) return { downloaded: 0, failed: false };\n\n printInfo(`${brand(String(filesToDownload.length))} files to pull`);\n\n if (options.dryRun) {\n if (options.verbose) {\n for (const entry of filesToDownload) {\n console.log(` ${brand('○')} ${entry.path} ${dim(`(${formatBytes(entry.size)})`)}`);\n }\n }\n return { downloaded: filesToDownload.length, failed: false };\n }\n\n let downloaded = 0;\n for (const entry of filesToDownload) {\n const dlSpinner = createSpinner(\n `${formatProgress(downloaded + 1, filesToDownload.length)} ${entry.path}`,\n ).start();\n\n try {\n const urlResponse = await client.post<PresignedUrlResponse>('/api/sync/pull/download-url', {\n syncEventId: prepareResponse.syncEventId,\n key: entry.path,\n });\n\n const response = await fetch(urlResponse.url);\n let data = Buffer.from(await response.arrayBuffer());\n\n if (entry.isCompressed) {\n data = await decompressBuffer(data);\n }\n\n const outputPath = join(projectDir, entry.path);\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, data);\n\n downloaded++;\n } catch {\n }\n dlSpinner.stop();\n }\n\n try {\n await client.post('/api/sync/pull/complete', {\n syncEventId: prepareResponse.syncEventId,\n manifest: filesToDownload,\n });\n } catch {\n }\n\n return { downloaded, failed: false };\n}\n\nexport function syncCommand(): Command {\n return new Command('sync')\n .description('Sync current project sessions with cloud')\n .option('--dry-run', 'Show what would be synced without syncing')\n .option('--verbose', 'Show detailed output')\n .action(async (options) => {\n await runSync(options);\n });\n}\n","import { Command } from 'commander';\nimport { loadConfig, loadProjectManifest, isAuthenticated } from '../lib/config.js';\nimport { buildProjectManifest, computeDiff, resolveProjectState } from '../lib/sync-engine.js';\nimport { createSpinner, formatBytes } from '../lib/progress.js';\nimport { printIntro, printLabel, printDivider, printInfo, brand, success as successColor, warn as warnColor, error as errorColor, dim } from '../lib/theme.js';\n\nexport function statusCommand(): Command {\n return new Command('status')\n .description('Show sync status for current project')\n .action(async () => {\n printIntro('Status');\n\n const config = await loadConfig();\n const cwd = process.cwd();\n\n printLabel('API', config.apiUrl);\n printLabel('Authenticated', isAuthenticated(config) ? successColor('yes') : errorColor('no'));\n printLabel('Device', config.deviceName || dim('none'));\n printLabel('Project', brand(cwd));\n\n const ctx = await resolveProjectState(cwd);\n printLabel('State', ctx.state === 'none' ? dim('no session data') : ctx.state === 'symlink' ? `symlink → ${dim(ctx.symlinkTarget || 'unknown')}` : 'local');\n\n if (!isAuthenticated(config) || ctx.state === 'none') return;\n\n const spinner = createSpinner('Scanning files...').start();\n const savedManifest = await loadProjectManifest(cwd);\n const currentManifest = await buildProjectManifest(cwd);\n const diff = computeDiff(currentManifest, savedManifest);\n spinner.stop();\n\n const totalSize = currentManifest.reduce((sum, e) => sum + e.size, 0);\n\n printDivider();\n printLabel('Local files', `${brand(String(currentManifest.length))} ${dim(`(${formatBytes(totalSize)})`)}`);\n console.log();\n printInfo('Changes since last sync:');\n console.log(` ${successColor(`+${diff.added.length}`)} added ${warnColor(`~${diff.modified.length}`)} modified ${errorColor(`-${diff.deleted.length}`)} deleted`);\n console.log();\n });\n}\n","import { Command } from 'commander';\nimport type { User } from '@claude-sync/types';\nimport { loadConfig, isAuthenticated } from '../lib/config.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { createSpinner } from '../lib/progress.js';\nimport { printIntro, printLabel, printError, printDivider, brand, dim } from '../lib/theme.js';\n\nexport function whoamiCommand(): Command {\n return new Command('whoami')\n .description('Show current user and device info')\n .action(async () => {\n printIntro('Who Am I');\n\n const config = await loadConfig();\n\n if (!isAuthenticated(config)) {\n printError('Not logged in. Run `claude-sync login` first.');\n return;\n }\n\n const client = new ApiClient(config.apiUrl);\n const spinner = createSpinner('Fetching user info...').start();\n\n try {\n const user = await client.get<User>('/api/auth/me');\n spinner.stop();\n printLabel('User', `${user.name} ${dim(`(${user.email})`)}`);\n printLabel('Plan', brand(user.plan));\n printDivider();\n printLabel('Device', config.deviceName || dim('none'));\n printLabel('Device ID', config.deviceId || dim('not registered'));\n } catch {\n spinner.stop();\n printLabel('Email', config.email || dim('unknown'));\n printLabel('Device', config.deviceName || dim('none'));\n }\n\n console.log();\n });\n}\n","import { Command } from 'commander';\n\nimport { loginCommand } from './commands/login.js';\nimport { logoutCommand } from './commands/logout.js';\nimport { deviceCommand } from './commands/device.js';\nimport { syncCommand, runSync } from './commands/sync.js';\nimport { statusCommand } from './commands/status.js';\nimport { whoamiCommand } from './commands/whoami.js';\nimport { runTui } from './commands/tui.js';\nimport { loadConfig, isAuthenticated } from './lib/config.js';\n\nexport function run() {\n const program = new Command();\n\n program\n .name('claude-sync')\n .description('Sync Claude Code sessions across machines')\n .version('0.1.0')\n .option('--menu', 'Open interactive menu')\n .action(async (options) => {\n if (options.menu) {\n await runTui();\n return;\n }\n\n const config = await loadConfig();\n if (isAuthenticated(config) && config.deviceId) {\n await runSync({});\n } else {\n await runTui();\n }\n });\n\n program.addCommand(loginCommand());\n program.addCommand(logoutCommand());\n program.addCommand(deviceCommand());\n program.addCommand(syncCommand());\n program.addCommand(statusCommand());\n program.addCommand(whoamiCommand());\n\n program.parse();\n}\n","import { select, isCancel } from '@clack/prompts';\nimport chalk from 'chalk';\nimport { printBanner, printOutro, brand, dim } from '../lib/theme.js';\nimport { loadConfig, isAuthenticated } from '../lib/config.js';\n\ninterface MenuOption {\n value: string;\n label: string;\n hint?: string;\n}\n\nfunction buildMenu(loggedIn: boolean): MenuOption[] {\n if (!loggedIn) {\n return [\n { value: 'login', label: 'Login', hint: 'Authenticate with claude-sync' },\n ];\n }\n\n return [\n { value: 'sync', label: 'Sync', hint: 'Sync current project' },\n { value: 'status', label: 'Status', hint: 'Show sync state' },\n { value: 'device:add', label: 'Add Device', hint: 'Register this machine' },\n { value: 'device:list', label: 'List Devices', hint: 'Show registered devices' },\n { value: 'device:remove', label: 'Remove Device' },\n { value: 'device:rename', label: 'Rename Device' },\n { value: 'whoami', label: 'Who Am I', hint: 'Current user and device' },\n { value: 'logout', label: 'Logout', hint: 'Sign out' },\n ];\n}\n\nexport async function runTui() {\n printBanner();\n\n const config = await loadConfig();\n const loggedIn = isAuthenticated(config);\n\n if (loggedIn) {\n console.log(` ${dim('user')} ${brand(config.email || 'unknown')}`);\n if (config.deviceName) {\n console.log(` ${dim('device')} ${brand(config.deviceName)}`);\n }\n console.log();\n } else {\n console.log(` ${dim('Not logged in')}`);\n console.log();\n }\n\n while (true) {\n const items = buildMenu(loggedIn);\n\n const options = [\n ...items.map((o) => ({\n value: o.value,\n label: o.label,\n hint: o.hint ? dim(o.hint) : undefined,\n })),\n { value: 'quit', label: chalk.red('Quit') },\n ];\n\n const choice = await select({\n message: brand('What would you like to do?'),\n options,\n });\n\n if (isCancel(choice) || choice === 'quit') {\n printOutro('Goodbye!');\n return;\n }\n\n await executeCommand(choice as string);\n\n console.log();\n }\n}\n\nasync function executeCommand(command: string) {\n const { loginCommand } = await import('./login.js');\n const { logoutCommand } = await import('./logout.js');\n const { deviceCommand } = await import('./device.js');\n const { syncCommand } = await import('./sync.js');\n const { statusCommand } = await import('./status.js');\n const { whoamiCommand } = await import('./whoami.js');\n\n const handlers: Record<string, () => Promise<void>> = {\n login: () => loginCommand().parseAsync(['', '', 'login']),\n logout: () => logoutCommand().parseAsync(['', '', 'logout']),\n sync: () => syncCommand().parseAsync(['', '', 'sync']),\n status: () => statusCommand().parseAsync(['', '', 'status']),\n whoami: () => whoamiCommand().parseAsync(['', '', 'whoami']),\n 'device:add': () => deviceCommand().parseAsync(['', '', 'device', 'add']),\n 'device:list': () => deviceCommand().parseAsync(['', '', 'device', 'list']),\n 'device:remove': () => deviceCommand().parseAsync(['', '', 'device', 'remove']),\n 'device:rename': () => deviceCommand().parseAsync(['', '', 'device', 'rename']),\n };\n\n const handler = handlers[command];\n if (handler) {\n try {\n await handler();\n } catch {\n }\n }\n}\n","#!/usr/bin/env node\nimport { run } from '../src/index.js';\n\nrun();\n"],"mappings":";;;;;;;;;;;;AAAA,SAAS,MAAM,eAAe;AAC9B,SAAS,eAAe;AACxB,SAAS,UAAU,WAAW,aAAa;AAC3C,SAAS,YAAY,aAAa,eAAe,kBAAkB;AAsBnE,SAAS,eAAuB;AAC9B,SAAO,KAAK,QAAQ,GAAG,UAAU;AACnC;AAEA,SAAS,gBAAwB;AAC/B,SAAO,KAAK,aAAa,GAAG,WAAW;AACzC;AAMA,eAAsB,aAAiC;AACrD,MAAI;AACF,UAAM,UAAU,MAAM,SAAS,cAAc,GAAG,OAAO;AACvD,WAAO,EAAE,GAAG,gBAAgB,GAAG,KAAK,MAAM,OAAO,EAAE;AAAA,EACrD,QAAQ;AACN,WAAO,EAAE,GAAG,eAAe;AAAA,EAC7B;AACF;AAEA,eAAsB,WAAW,QAA2C;AAC1E,QAAM,WAAW,MAAM,WAAW;AAClC,QAAM,SAAS,EAAE,GAAG,UAAU,GAAG,OAAO;AACxC,QAAM,MAAM,aAAa,GAAG,EAAE,WAAW,KAAK,CAAC;AAC/C,QAAM,UAAU,cAAc,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAClE;AAEA,eAAsB,cAA6B;AACjD,QAAM,WAAW,cAAc;AACjC;AAgBA,eAAsB,oBAAoB,aAA4E;AACpH,MAAI;AACF,UAAM,UAAU,WAAW,WAAW;AACtC,UAAM,eAAe,KAAK,aAAa,GAAG,aAAa,GAAG,OAAO,OAAO;AACxE,UAAM,UAAU,MAAM,SAAS,cAAc,OAAO;AACpD,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,eAAsB,oBAAoB,aAAqB,SAAsE;AACnI,QAAM,UAAU,WAAW,WAAW;AACtC,QAAM,eAAe,KAAK,aAAa,GAAG,aAAa,GAAG,OAAO,OAAO;AACxE,QAAM,MAAM,QAAQ,YAAY,GAAG,EAAE,WAAW,KAAK,CAAC;AACtD,QAAM,UAAU,cAAc,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAChE;AAEO,SAAS,gBAAgB,QAA4B;AAC1D,SAAO,OAAO,gBAAgB;AAChC;AAQA,eAAsB,gBAAgB,aAAkD;AACtF,MAAI;AACF,UAAM,UAAU,WAAW,WAAW;AACtC,UAAM,WAAW,KAAK,aAAa,GAAG,iBAAiB,GAAG,OAAO,OAAO;AACxE,UAAM,UAAU,MAAM,SAAS,UAAU,OAAO;AAChD,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,gBAAgB,aAAqB,MAAkC;AAC3F,QAAM,UAAU,WAAW,WAAW;AACtC,QAAM,WAAW,KAAK,aAAa,GAAG,iBAAiB,GAAG,OAAO,OAAO;AACxE,QAAM,MAAM,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAClD,QAAM,UAAU,UAAU,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AACzD;AAnHA,IAeM;AAfN;AAAA;AAAA;AAeA,IAAM,iBAA4B;AAAA,MAChC,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,cAAc;AAAA,MACd,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA;AAAA;;;ACvBA,IAGa;AAHb;AAAA;AAAA;AACA;AAEO,IAAM,YAAN,MAAgB;AAAA,MACb;AAAA,MAER,YAAY,SAAiB;AAC3B,aAAK,UAAU,QAAQ,QAAQ,OAAO,EAAE;AAAA,MAC1C;AAAA,MAEA,MAAc,WAAc,MAAc,UAAuB,CAAC,GAAe;AAC/E,cAAM,aAAa,IAAI,gBAAgB;AACvC,cAAM,UAAU,WAAW,MAAM,WAAW,MAAM,GAAG,IAAK;AAE1D,YAAI;AACJ,YAAI;AACF,qBAAW,MAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,YAC/C,GAAG;AAAA,YACH,QAAQ,WAAW;AAAA,UACrB,CAAC;AAAA,QACH,SAAS,KAAK;AACZ,uBAAa,OAAO;AACpB,cAAI,eAAe,SAAS,IAAI,SAAS,cAAc;AACrD,kBAAM,IAAI,MAAM,+CAA+C;AAAA,UACjE;AACA,gBAAM;AAAA,QACR;AACA,qBAAa,OAAO;AAEpB,YAAI,CAAC,SAAS,IAAI;AAChB,cAAI,SAAS,WAAW,KAAK;AAC3B,kBAAM,IAAI,MAAM,8DAA8D;AAAA,UAChF;AACA,gBAAMA,SAA0B,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO;AAAA,YACjE,YAAY,SAAS;AAAA,YACrB,SAAS,SAAS;AAAA,YAClB,OAAO;AAAA,UACT,EAAE;AACF,gBAAM,IAAI,MAAMA,OAAM,OAAO;AAAA,QAC/B;AAEA,cAAM,OAAO,MAAM,SAAS,KAAK;AACjC,eAAQ,KAAK,SAAS,SAAY,KAAK,OAAO;AAAA,MAChD;AAAA,MAEA,MAAM,QAAW,MAAc,UAAuB,CAAC,GAAe;AACpE,cAAM,QAAQ,MAAM,cAAc;AAClC,cAAM,UAAkC;AAAA,UACtC,gBAAgB;AAAA,UAChB,GAAI,QAAQ;AAAA,QACd;AAEA,YAAI,OAAO;AACT,kBAAQ,eAAe,IAAI,UAAU,KAAK;AAAA,QAC5C;AAEA,eAAO,KAAK,WAAc,MAAM,EAAE,GAAG,SAAS,QAAQ,CAAC;AAAA,MACzD;AAAA,MAEA,MAAM,cAAiB,MAAc,UAAuB,CAAC,GAAe;AAC1E,cAAM,UAAkC;AAAA,UACtC,gBAAgB;AAAA,UAChB,GAAI,QAAQ;AAAA,QACd;AAEA,eAAO,KAAK,WAAc,MAAM,EAAE,GAAG,SAAS,QAAQ,CAAC;AAAA,MACzD;AAAA,MAEA,MAAM,IAAO,MAA0B;AACrC,eAAO,KAAK,QAAW,MAAM,EAAE,QAAQ,MAAM,CAAC;AAAA,MAChD;AAAA,MAEA,MAAM,KAAQ,MAAc,MAA4B;AACtD,eAAO,KAAK,QAAW,MAAM;AAAA,UAC3B,QAAQ;AAAA,UACR,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,QACtC,CAAC;AAAA,MACH;AAAA,MAEA,MAAM,MAAS,MAAc,MAA4B;AACvD,eAAO,KAAK,QAAW,MAAM;AAAA,UAC3B,QAAQ;AAAA,UACR,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,QACtC,CAAC;AAAA,MACH;AAAA,MAEA,MAAM,OAAU,MAA0B;AACxC,eAAO,KAAK,QAAW,MAAM,EAAE,QAAQ,SAAS,CAAC;AAAA,MACnD;AAAA,IACF;AAAA;AAAA;;;ACrFA,eAAsB,YAAY,QAAmB,QAAgB,OAA8B;AACjG,QAAM,WAAW;AAAA,IACf,aAAa,OAAO;AAAA,IACpB,cAAc,OAAO;AAAA,IACrB;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAEA,eAAsB,qBAA6C;AACjE,QAAM,SAAS,MAAM,WAAW;AAChC,MAAI,CAAC,OAAO,aAAc,QAAO;AAEjC,QAAM,SAAS,IAAI,UAAU,OAAO,MAAM;AAC1C,MAAI;AACF,UAAM,WAAW,MAAM,OAAO,cAAyB,qBAAqB;AAAA,MAC1E,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,EAAE,cAAc,OAAO,aAAa,CAAC;AAAA,IAC5D,CAAC;AACD,UAAM,WAAW;AAAA,MACf,aAAa,SAAS;AAAA,MACtB,cAAc,SAAS;AAAA,IACzB,CAAC;AACD,WAAO,SAAS;AAAA,EAClB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,gBAAwC;AAC5D,QAAM,SAAS,MAAM,WAAW;AAChC,MAAI,CAAC,OAAO,YAAa,QAAO;AAEhC,MAAI;AACF,UAAM,UAAU,KAAK;AAAA,MACnB,OAAO,KAAK,OAAO,YAAY,MAAM,GAAG,EAAE,CAAC,GAAG,QAAQ,EAAE,SAAS;AAAA,IACnE;AACA,QAAI,QAAQ,MAAM,MAAO,KAAK,IAAI,GAAG;AACnC,aAAO,OAAO;AAAA,IAChB;AAAA,EACF,QAAQ;AAAA,EACR;AAEA,SAAO,mBAAmB;AAC5B;AAhDA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;;;ACFA,OAAO,SAAuB;AAC9B,OAAO,WAAW;AAIX,SAAS,cAAcC,OAAmB;AAC/C,SAAO,IAAI,EAAE,MAAM,WAAWA,KAAI,GAAG,SAAS,QAAQ,OAAO,UAAU,CAAC;AAC1E;AAEO,SAAS,YAAY,OAAuB;AACjD,MAAI,UAAU,EAAG,QAAO;AACxB,QAAM,IAAI;AACV,QAAM,QAAQ,CAAC,KAAK,MAAM,MAAM,IAAI;AACpC,QAAM,IAAI,KAAK,MAAM,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,CAAC;AAClD,SAAO,GAAG,YAAY,QAAQ,KAAK,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC;AACvE;AAEO,SAAS,eAAe,SAAiB,OAAuB;AACrE,QAAM,aAAa,QAAQ,IAAI,KAAK,MAAO,UAAU,QAAS,GAAG,IAAI;AACrE,SAAO,GAAG,OAAO,IAAI,KAAK,KAAK,UAAU;AAC3C;AApBA,IAGM;AAHN;AAAA;AAAA;AAGA,IAAM,aAAa,MAAM,IAAI,SAAS;AAAA;AAAA;;;ACHtC,OAAOC,YAAW;AAoBX,SAAS,cAAc;AAC5B,UAAQ,IAAI;AACZ,UAAQ,IAAI,KAAK,UAAU,aAAa,CAAC,IAAI,IAAI,QAAQ,CAAC,EAAE;AAC5D,UAAQ,IAAI;AACd;AAEO,SAAS,WAAW,OAAe;AACxC,UAAQ,IAAI;AACZ,UAAQ,IAAI,KAAK,UAAU,KAAK,CAAC,EAAE;AACnC,UAAQ,IAAI;AACd;AAEO,SAAS,WAAW,SAAiB;AAC1C,UAAQ,IAAI;AACZ,UAAQ,IAAI,KAAK,IAAI,OAAO,CAAC,EAAE;AAC/B,UAAQ,IAAI;AACd;AAEO,SAAS,aAAa,SAAiB;AAC5C,UAAQ,IAAI,KAAK,QAAQ,QAAG,CAAC,IAAI,OAAO,EAAE;AAC5C;AAEO,SAAS,WAAW,SAAiB;AAC1C,UAAQ,IAAI,KAAK,MAAM,QAAG,CAAC,IAAI,OAAO,EAAE;AAC1C;AAMO,SAAS,UAAU,SAAiB;AACzC,UAAQ,IAAI,KAAK,MAAM,QAAG,CAAC,IAAI,OAAO,EAAE;AAC1C;AAEO,SAAS,WAAW,OAAe,OAAe;AACvD,UAAQ,IAAI,KAAK,IAAI,MAAM,OAAO,EAAE,CAAC,CAAC,IAAI,MAAM,KAAK,CAAC,EAAE;AAC1D;AAEO,SAAS,eAAe;AAC7B,UAAQ,IAAI;AACd;AA5DA,IAEM,WACA,eACA,aACA,UACA,WAEO,OACA,WACA,UACA,SACA,aACA,MACA,OACA,WACA,KACA,MACA;AAlBb;AAAA;AAAA;AAEA,IAAM,YAAY;AAClB,IAAM,gBAAgB;AACtB,IAAM,cAAc;AACpB,IAAM,WAAW;AACjB,IAAM,YAAY;AAEX,IAAM,QAAQA,OAAM,IAAI,SAAS;AACjC,IAAM,YAAYA,OAAM,IAAI,SAAS,EAAE;AACvC,IAAM,WAAWA,OAAM,IAAI,aAAa;AACxC,IAAM,UAAUA,OAAM,IAAI,WAAW;AACrC,IAAM,cAAcA,OAAM,IAAI,WAAW,EAAE;AAC3C,IAAM,OAAOA,OAAM,IAAI,QAAQ;AAC/B,IAAM,QAAQA,OAAM,IAAI,SAAS;AACjC,IAAM,YAAYA,OAAM,IAAI,SAAS,EAAE;AACvC,IAAM,MAAMA,OAAM;AAClB,IAAM,OAAOA,OAAM;AACnB,IAAM,QAAQA,OAAM;AAAA;AAAA;;;AClB3B;AAAA;AAAA;AAAA;AAAA,SAAS,eAAe;AACxB,SAAS,MAAM,YAAY,gBAAgB,QAAQ,gBAAgB;AAQnE,eAAe,iBAAiB,QAAkC;AAChE,QAAM,WAAW,MAAM,OAAO,cAAmC,0BAA0B;AAAA,IACzF,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,EAChD,CAAC;AAED,YAAU;AAAA,OAAwC,UAAU,SAAS,SAAS,CAAC,EAAE;AACjF,YAAU,SAAS,UAAU,SAAS,IAAI,CAAC,EAAE;AAE7C,QAAM,UAAU,cAAc,sCAAsC,EAAE,MAAM;AAE5E,QAAM,eAAe;AACrB,QAAM,cAAc;AACpB,MAAI,WAAW;AAEf,SAAO,WAAW,aAAa;AAC7B,UAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,YAAY,CAAC;AAChE;AAEA,QAAI;AACF,YAAM,eAAe,MAAM,OAAO,cAA+B,sBAAsB;AAAA,QACrF,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,EAAE,MAAM,SAAS,KAAK,CAAC;AAAA,MAC9C,CAAC;AAED,UAAI,aAAa,WAAW,gBAAgB,aAAa,aAAa,aAAa,MAAM;AACvF,gBAAQ,KAAK;AACb,cAAM,YAAY,aAAa,WAAW,aAAa,KAAK,IAAI,aAAa,KAAK,KAAK;AACvF,qBAAa,gBAAgB,UAAU,aAAa,KAAK,KAAK,CAAC,EAAE;AACjE;AAAA,MACF;AAEA,UAAI,aAAa,WAAW,WAAW;AACrC,gBAAQ,KAAK;AACb,mBAAW,+CAA+C;AAC1D,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,QAAQ;AAAA,IACR;AAAA,EACF;AAEA,UAAQ,KAAK;AACb,aAAW,4CAA4C;AACvD,UAAQ,KAAK,CAAC;AAChB;AAEA,eAAe,eAAe,QAAkC;AAC9D,QAAM,QAAQ,MAAM,KAAK,EAAE,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;AAC1D,MAAI,SAAS,KAAK,EAAG,SAAQ,KAAK,CAAC;AAEnC,QAAM,WAAW,MAAM,eAAe,EAAE,SAAS,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC;AAC1E,MAAI,SAAS,QAAQ,EAAG,SAAQ,KAAK,CAAC;AAEtC,QAAM,UAAU,cAAc,eAAe,EAAE,MAAM;AAErD,MAAI;AACF,UAAM,WAAW,MAAM,OAAO;AAAA,MAC5B;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,EAAE,OAAO,SAAS,CAAC;AAAA,MAC1C;AAAA,IACF;AACA,YAAQ,KAAK;AACb,UAAM;AAAA,MACJ,EAAE,aAAa,SAAS,aAAa,cAAc,SAAS,cAAc,WAAW,IAAI;AAAA,MACzF,SAAS,KAAK;AAAA,MACd,SAAS,KAAK;AAAA,IAChB;AACA,iBAAa,gBAAgB,UAAU,SAAS,KAAK,KAAK,CAAC,EAAE;AAAA,EAC/D,SAAS,KAAK;AACZ,YAAQ,KAAK;AACb,eAAW,iBAAiB,eAAe,QAAQ,IAAI,UAAU,eAAe,EAAE;AAClF,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAEO,SAAS,eAAwB;AACtC,SAAO,IAAI,QAAQ,OAAO,EACvB,YAAY,+BAA+B,EAC3C,OAAO,YAAY;AAClB,eAAW,OAAO;AAElB,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,SAAS,IAAI,UAAU,OAAO,MAAM;AAE1C,UAAM,SAAS,MAAM,OAAO;AAAA,MAC1B,SAAS,GAAG,MAAM,+BAA+B,CAAC;AAAA,MAClD,SAAS;AAAA,QACP,EAAE,OAAO,WAAW,OAAO,GAAG,MAAM,QAAG,CAAC,YAAY,IAAI,eAAe,CAAC,GAAG;AAAA,QAC3E,EAAE,OAAO,SAAS,OAAO,GAAG,MAAM,QAAG,CAAC,oBAAoB;AAAA,MAC5D;AAAA,IACF,CAAC;AAED,QAAI,SAAS,MAAM,EAAG,SAAQ,KAAK,CAAC;AAEpC,QAAI,WAAW,WAAW;AACxB,YAAM,iBAAiB,MAAM;AAAA,IAC/B,OAAO;AACL,YAAM,eAAe,MAAM;AAAA,IAC7B;AAEA,eAAW,yBAAyB;AAAA,EACtC,CAAC;AACL;AAnHA;AAAA;AAAA;AAGA;AACA;AACA;AACA;AACA;AAAA;AAAA;;;ACPA;AAAA;AAAA;AAAA;AAAA,SAAS,WAAAC,gBAAe;AAKjB,SAAS,gBAAyB;AACvC,SAAO,IAAIA,SAAQ,QAAQ,EACxB,YAAY,2BAA2B,EACvC,OAAO,YAAY;AAClB,eAAW,QAAQ;AAEnB,UAAM,SAAS,MAAM,WAAW;AAChC,QAAI,CAAC,OAAO,aAAa;AACvB,gBAAU,0BAA0B;AACpC,iBAAW,MAAM;AACjB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,SAAS,IAAI,UAAU,OAAO,MAAM;AAC1C,YAAM,OAAO,KAAK,oBAAoB;AAAA,QACpC,cAAc,OAAO;AAAA,MACvB,CAAC;AAAA,IACH,QAAQ;AAAA,IACR;AAEA,UAAM,YAAY;AAClB,iBAAa,0BAA0B;AACvC,eAAW,MAAM;AAAA,EACnB,CAAC;AACL;AA9BA;AAAA;AAAA;AACA;AACA;AACA;AAAA;AAAA;;;ACHA;AAAA;AAAA;AAAA;AAAA,SAAS,WAAAC,gBAAe;AACxB,SAAS,UAAU,UAAU,MAAM,WAAAC,gBAAe;AAClD,SAAS,QAAAC,OAAM,YAAAC,iBAAgB;AAO/B,SAAS,YAAY,QAAsD;AACzE,MAAI,CAAC,gBAAgB,MAAM,GAAG;AAC5B,eAAW,+CAA+C;AAC1D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAEO,SAAS,gBAAyB;AACvC,QAAM,SAAS,IAAIH,SAAQ,QAAQ,EAAE,YAAY,gBAAgB;AAEjE,SACG,QAAQ,KAAK,EACb,SAAS,UAAU,aAAa,EAChC,YAAY,mCAAmC,EAC/C,OAAO,OAAO,SAAkB;AAC/B,eAAW,YAAY;AAEvB,UAAM,SAAS,MAAM,WAAW;AAChC,gBAAY,MAAM;AAElB,UAAM,aAAa,QAAQ,OAAO,YAAY;AAC5C,YAAM,QAAQ,MAAME,MAAK,EAAE,SAAS,GAAG,MAAM,aAAa,CAAC,KAAK,cAAc,SAAS,EAAE,CAAC;AAC1F,UAAIC,UAAS,KAAK,EAAG,SAAQ,KAAK,CAAC;AACnC,aAAO;AAAA,IACT,GAAG;AAEH,UAAM,UAAU,cAAc,uBAAuB,EAAE,MAAM;AAC7D,UAAM,SAAS,IAAI,UAAU,OAAO,MAAM;AAE1C,QAAI;AACF,YAAM,WAAW,MAAM,OAAO,KAAa,gBAAgB;AAAA,QACzD,MAAM;AAAA,QACN,UAAU,SAAS;AAAA,QACnB,UAAU,SAAS;AAAA,QACnB,SAASF,SAAQ;AAAA,QACjB,MAAM,KAAK;AAAA,MACb,CAAC;AAED,YAAM,WAAW;AAAA,QACf,UAAU,SAAS;AAAA,QACnB,YAAY,SAAS;AAAA,MACvB,CAAC;AAED,cAAQ,KAAK;AACb,mBAAa,UAAU,UAAU,IAAI,SAAS,IAAI,GAAG,CAAC,aAAa;AACnE,iBAAW,MAAM,SAAS,EAAE;AAAA,IAC9B,SAAS,KAAK;AACZ,cAAQ,KAAK;AACb,iBAAW,WAAW,eAAe,QAAQ,IAAI,UAAU,eAAe,EAAE;AAC5E,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,eAAW,MAAM;AAAA,EACnB,CAAC;AAEH,SACG,QAAQ,MAAM,EACd,YAAY,6BAA6B,EACzC,OAAO,YAAY;AAClB,eAAW,SAAS;AAEpB,UAAM,SAAS,MAAM,WAAW;AAChC,gBAAY,MAAM;AAElB,UAAM,SAAS,IAAI,UAAU,OAAO,MAAM;AAC1C,UAAM,UAAU,cAAc,qBAAqB,EAAE,MAAM;AAE3D,QAAI;AACF,YAAM,UAAU,MAAM,OAAO,IAAc,cAAc;AACzD,cAAQ,KAAK;AAEb,UAAI,QAAQ,WAAW,GAAG;AACxB,kBAAU,wBAAwB;AAClC;AAAA,MACF;AAEA,cAAQ,IAAI;AACZ,iBAAW,KAAK,SAAS;AACvB,cAAM,UAAU,EAAE,OAAO,OAAO,WAAW,IAAI,UAAU,WAAW,CAAC,KAAK;AAC1E,cAAM,SAAS,EAAE,WAAW,QAAQ,QAAQ,IAAI,MAAW,UAAU;AACrE,gBAAQ,IAAI,KAAK,MAAM,QAAG,CAAC,IAAI,MAAM,EAAE,IAAI,CAAC,GAAG,OAAO,EAAE;AACxD,gBAAQ,IAAI,OAAO,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,MAAG,CAAC,IAAI,MAAM,IAAI,IAAI,MAAG,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,EAAE;AAAA,MACrF;AACA,cAAQ,IAAI;AAAA,IACd,SAAS,KAAK;AACZ,cAAQ,KAAK;AACb,iBAAW,WAAW,eAAe,QAAQ,IAAI,UAAU,eAAe,EAAE;AAC5E,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,SACG,QAAQ,QAAQ,EAChB,SAAS,cAAc,mBAAmB,EAC1C,YAAY,iBAAiB,EAC7B,OAAO,OAAO,aAAqB;AAClC,UAAM,SAAS,MAAM,WAAW;AAChC,gBAAY,MAAM;AAElB,UAAM,SAAS,IAAI,UAAU,OAAO,MAAM;AAC1C,UAAM,UAAU,cAAc,oBAAoB,EAAE,MAAM;AAE1D,QAAI;AACF,YAAM,OAAO,OAAO,gBAAgB,QAAQ,EAAE;AAC9C,cAAQ,KAAK;AAEb,UAAI,OAAO,aAAa,UAAU;AAChC,cAAM,WAAW,EAAE,UAAU,MAAM,YAAY,KAAK,CAAC;AAAA,MACvD;AAEA,mBAAa,iBAAiB;AAAA,IAChC,SAAS,KAAK;AACZ,cAAQ,KAAK;AACb,iBAAW,WAAW,eAAe,QAAQ,IAAI,UAAU,eAAe,EAAE;AAC5E,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,SACG,QAAQ,QAAQ,EAChB,SAAS,UAAU,UAAU,EAC7B,YAAY,2BAA2B,EACvC,OAAO,OAAO,SAAiB;AAC9B,UAAM,SAAS,MAAM,WAAW;AAChC,gBAAY,MAAM;AAElB,QAAI,CAAC,OAAO,UAAU;AACpB,iBAAW,2DAA2D;AACtE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,SAAS,IAAI,UAAU,OAAO,MAAM;AAC1C,UAAM,UAAU,cAAc,oBAAoB,EAAE,MAAM;AAE1D,QAAI;AACF,YAAM,WAAW,MAAM,OAAO,MAAc,gBAAgB,OAAO,QAAQ,IAAI,EAAE,KAAK,CAAC;AACvF,YAAM,WAAW,EAAE,YAAY,SAAS,KAAK,CAAC;AAC9C,cAAQ,KAAK;AACb,mBAAa,qBAAqB,UAAU,IAAI,SAAS,IAAI,GAAG,CAAC,EAAE;AAAA,IACrE,SAAS,KAAK;AACZ,cAAQ,KAAK;AACb,iBAAW,WAAW,eAAe,QAAQ,IAAI,UAAU,eAAe,EAAE;AAC5E,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,SAAO;AACT;AA5JA;AAAA;AAAA;AAIA;AACA;AACA;AACA;AAAA;AAAA;;;ACPA,SAAS,QAAAG,aAAY;AACrB,SAAS,WAAAC,gBAAe;AACxB,SAAS,SAAS,MAAM,OAAO,gBAAgB;AAE/C,SAAS,UAAU,eAAe,cAAAC,aAAY,YAAY,cAAc,6BAA6B;AAErG,SAAS,cAAc,MAAuB;AAC5C,SAAO,sBAAsB,KAAK,CAAC,YAAY;AAC7C,QAAI,QAAQ,WAAW,GAAG,GAAG;AAC3B,aAAO,KAAK,SAAS,QAAQ,MAAM,CAAC,CAAC;AAAA,IACvC;AACA,WAAO,SAAS;AAAA,EAClB,CAAC;AACH;AAEA,eAAe,cAAc,KAAa,WAAmB,IAA8B;AACzF,QAAM,UAA2B,CAAC;AAClC,QAAM,QAAQ,MAAM,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;AAExD,aAAW,QAAQ,OAAO;AACxB,QAAI,cAAc,KAAK,IAAI,EAAG;AAE9B,UAAM,WAAWF,MAAK,KAAK,KAAK,IAAI;AACpC,UAAM,eAAe,WAAW,GAAG,QAAQ,IAAI,KAAK,IAAI,KAAK,KAAK;AAElE,QAAI,KAAK,YAAY,GAAG;AACtB,YAAM,aAAa,MAAM,cAAc,UAAU,YAAY;AAC7D,cAAQ,KAAK,GAAG,UAAU;AAAA,IAC5B,WAAW,KAAK,OAAO,GAAG;AACxB,YAAM,WAAW,MAAM,KAAK,QAAQ;AACpC,YAAM,OAAO,MAAM,SAAS,QAAQ;AACpC,YAAM,SAAS,CAAC,aAAa,KAAK,IAAI;AACtC,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN;AAAA,QACA,MAAM,SAAS;AAAA,QACf,YAAY,SAAS,MAAM,YAAY;AAAA,QACvC,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,aAAa,MAAuB;AAC3C,QAAM,mBAAmB,CAAC,QAAQ,QAAQ,SAAS,QAAQ,SAAS,QAAQ,QAAQ,QAAQ,OAAO,MAAM;AACzG,SAAO,iBAAiB,KAAK,CAAC,QAAQ,KAAK,SAAS,GAAG,CAAC;AAC1D;AAiBA,eAAsB,oBAAoB,KAAsC;AAC9E,QAAM,cAAcA,MAAKC,SAAQ,GAAG,YAAY,YAAY;AAC5D,QAAM,UAAUC,YAAW,GAAG;AAC9B,QAAM,aAAaF,MAAK,aAAa,OAAO;AAE5C,MAAI,QAAsB;AAC1B,MAAI;AAEJ,MAAI;AACF,UAAM,QAAQ,MAAM,MAAM,UAAU;AACpC,QAAI,MAAM,eAAe,GAAG;AAC1B,cAAQ;AACR,sBAAgB,MAAM,SAAS,UAAU;AAAA,IAC3C,WAAW,MAAM,YAAY,GAAG;AAC9B,cAAQ;AAAA,IACV;AAAA,EACF,QAAQ;AACN,YAAQ;AAAA,EACV;AAEA,SAAO,EAAE,KAAK,aAAa,SAAS,YAAY,OAAO,cAAc;AACvE;AAEA,eAAsB,qBAAqB,KAAuC;AAChF,QAAM,MAAM,MAAM,oBAAoB,GAAG;AAEzC,MAAI,IAAI,UAAU,OAAQ,QAAO,CAAC;AAElC,QAAM,cAAcA,MAAKC,SAAQ,GAAG,YAAY,YAAY;AAC5D,MAAI,YAAY,IAAI;AAEpB,MAAI,IAAI,UAAU,aAAa,IAAI,eAAe;AAChD,gBAAYD,MAAK,aAAa,IAAI,aAAa;AAAA,EACjD;AAEA,MAAI;AACF,WAAO,MAAM,cAAc,SAAS;AAAA,EACtC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEO,SAAS,YAAY,OAAwB,QAAuC;AACzF,SAAO,cAAc,OAAO,MAAM;AACpC;AA7GA;AAAA;AAAA;AAAA;AAAA;;;ACAA,SAAS,YAAY,oBAAoB;AACzC,SAAS,kBAAkB,yBAAyB;AACpD,SAAS,gBAAgB;AAgBlB,SAAS,eAAe,MAA+B;AAC5D,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,OAAO,WAAW;AACxB,UAAM,SAAmB,CAAC;AAC1B,SAAK,GAAG,QAAQ,CAAC,UAAkB,OAAO,KAAK,KAAK,CAAC;AACrD,SAAK,GAAG,OAAO,MAAM,QAAQ,OAAO,OAAO,MAAM,CAAC,CAAC;AACnD,SAAK,GAAG,SAAS,MAAM;AACvB,SAAK,IAAI,IAAI;AAAA,EACf,CAAC;AACH;AAEO,SAAS,iBAAiB,MAA+B;AAC9D,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,SAAS,aAAa;AAC5B,UAAM,SAAmB,CAAC;AAC1B,WAAO,GAAG,QAAQ,CAAC,UAAkB,OAAO,KAAK,KAAK,CAAC;AACvD,WAAO,GAAG,OAAO,MAAM,QAAQ,OAAO,OAAO,MAAM,CAAC,CAAC;AACrD,WAAO,GAAG,SAAS,MAAM;AACzB,WAAO,IAAI,IAAI;AAAA,EACjB,CAAC;AACH;AAtCA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAS,WAAAG,gBAAe;AACxB,SAAS,UAAAC,SAAQ,YAAAC,iBAAgB;AAQjC,SAAS,YAAAC,WAAU,aAAAC,YAAW,SAAAC,QAAO,SAAAC,QAAO,SAAS,cAAc;AACnE,SAAS,QAAAC,OAAM,WAAAC,gBAAe;AAC9B,SAAS,WAAAC,gBAAe;AACxB,SAAS,cAAAC,aAAY,gBAAAC,qBAAoB;AAqBzC,eAAsB,QAAQ,SAAkD;AAC9E,aAAW,MAAM;AAEjB,QAAM,SAAS,MAAM,WAAW;AAChC,MAAI,CAAC,gBAAgB,MAAM,GAAG;AAC5B,eAAW,+CAA+C;AAC1D;AAAA,EACF;AACA,MAAI,CAAC,OAAO,UAAU;AACpB,eAAW,2DAA2D;AACtE;AAAA,EACF;AAEA,QAAM,MAAM,QAAQ,IAAI;AACxB,QAAM,MAAM,MAAM,oBAAoB,GAAG;AACzC,QAAM,SAAS,IAAI,UAAU,OAAO,MAAM;AAC1C,QAAM,cAAcJ,MAAKE,SAAQ,GAAGC,aAAYC,aAAY;AAC5D,QAAM,cAAc,MAAM,gBAAgB,GAAG;AAE7C,MAAI,aAAa,IAAI;AACrB,MAAI,IAAI,UAAU,aAAa,IAAI,eAAe;AAChD,iBAAaJ,MAAK,aAAa,IAAI,aAAa;AAAA,EAClD;AAEA,YAAU,YAAY,MAAM,GAAG,CAAC,EAAE;AAClC,MAAI,IAAI,UAAU,WAAW;AAC3B,cAAU,cAAc,IAAI,IAAI,iBAAiB,SAAS,CAAC,EAAE;AAAA,EAC/D;AAEA,QAAM,WAAW,MAAM,qBAAqB,GAAG;AAE/C,MAAI,CAAC,aAAa;AAChB,UAAM,SAAS,MAAM,eAAe,QAAQ,QAAQ,KAAK,KAAK,UAAU,YAAY,aAAa,OAAO;AAExG,QAAI,WAAW,aAAa;AAC1B,iBAAW,YAAY;AACvB;AAAA,IACF;AAEA,QAAI,WAAW,UAAU;AACvB,YAAMK,iBAAgB,MAAM,qBAAqB,GAAG;AACpD,YAAM,oBAAoB,KAAKA,cAAa;AAC5C,mBAAa,qCAAqC;AAClD,iBAAW,MAAM;AACjB;AAAA,IACF;AAEA,QAAI,WAAW,UAAU;AACvB,YAAMA,iBAAgB,MAAM,qBAAqB,GAAG;AACpD,YAAM,oBAAoB,KAAKA,cAAa;AAC5C,iBAAW,MAAM;AACjB;AAAA,IACF;AAEA,eAAW,MAAM;AACjB;AAAA,EACF;AAEA,MAAI,aAAyB,EAAE,UAAU,GAAG,WAAW,YAAY,WAAW,QAAQ,MAAM;AAC5F,MAAI,aAAyB,EAAE,YAAY,GAAG,QAAQ,MAAM;AAE5D,MAAI,SAAS,SAAS,GAAG;AACvB,iBAAa,MAAM,UAAU,QAAQ,OAAO,UAAU,KAAK,UAAU,YAAY,YAAY,WAAW,OAAO;AAAA,EACjH;AAEA,MAAI,CAAC,WAAW,QAAQ;AACtB,iBAAa,MAAM,UAAU,QAAQ,OAAO,UAAU,KAAK,YAAY,YAAY,WAAW,OAAO;AAAA,EACvG;AAEA,MAAI,WAAW,UAAU,WAAW,QAAQ;AAC1C,eAAW,cAAc;AACzB;AAAA,EACF;AAEA,QAAM,gBAAgB,MAAM,qBAAqB,GAAG;AACpD,QAAM,oBAAoB,KAAK,aAAa;AAE5C,MAAI,WAAW,WAAW,KAAK,WAAW,aAAa,GAAG;AACxD,UAAM,QAAkB,CAAC;AACzB,QAAI,WAAW,WAAW,EAAG,OAAM,KAAK,GAAG,QAAa,IAAI,WAAW,QAAQ,EAAE,CAAC,SAAS;AAC3F,QAAI,WAAW,aAAa,EAAG,OAAM,KAAK,GAAG,QAAa,IAAI,WAAW,UAAU,EAAE,CAAC,SAAS;AAC/F,iBAAa,WAAW,MAAM,KAAK,IAAI,CAAC,EAAE;AAAA,EAC5C,WAAW,CAAC,WAAW,UAAU,CAAC,WAAW,QAAQ;AACnD,iBAAa,2BAA2B;AAAA,EAC1C;AAEA,aAAW,MAAM;AACnB;AAEA,eAAe,eACb,QACA,QACA,KACA,KACA,UACA,YACA,aACA,SAC4C;AAC5C,YAAU,MAAM,iCAAiC,CAAC;AAElD,QAAM,gBAAgB,IAAI,UAAU,UAAU,SAAS,SAAS;AAEhE,QAAM,iBAAiB,cAAc,+BAA+B,EAAE,MAAM;AAC5E,MAAI;AACJ,MAAI;AACF,cAAU,MAAM,OAAO,IAAkB,cAAc;AAAA,EACzD,QAAQ;AACN,cAAU,CAAC;AAAA,EACb;AACA,iBAAe,KAAK;AAEpB,QAAM,eAAe,QAAQ,OAAO,CAAC,MAAM,EAAE,OAAO,OAAO,QAAQ;AAGnE,QAAM,cAAyE,CAAC;AAEhF,MAAI,eAAe;AACjB,gBAAY,KAAK;AAAA,MACf,OAAO;AAAA,MACP,OAAO;AAAA,MACP,MAAM,IAAI,UAAU,SAAS,MAAM,cAAc;AAAA,IACnD,CAAC;AAAA,EACH;AAEA,MAAI,aAAa,SAAS,GAAG;AAC3B,gBAAY,KAAK;AAAA,MACf,OAAO;AAAA,MACP,OAAO;AAAA,MACP,MAAM,IAAI,6BAA6B;AAAA,IACzC,CAAC;AAAA,EACH;AAEA,MAAI,YAAY,WAAW,GAAG;AAC5B,cAAU,+CAA+C;AACzD,cAAU,yDAAyD;AACnE,WAAO;AAAA,EACT;AAEA,MAAI,YAAY,WAAW,KAAK,YAAY,CAAC,EAAE,UAAU,QAAQ;AAC/D,cAAU,yBAAyB;AAAA,EACrC;AAEA,QAAM,SAAS,MAAMX,QAAuB;AAAA,IAC1C,SAAS,MAAM,4BAA4B;AAAA,IAC3C,SAAS;AAAA,EACX,CAAC;AAED,MAAIC,UAAS,MAAM,EAAG,QAAO;AAE7B,MAAI,WAAW,QAAQ;AACrB,UAAM,SAAS,MAAM,UAAU,QAAQ,OAAO,UAAW,KAAK,UAAU,YAAY,QAAW,OAAO;AACtG,QAAI,OAAO,QAAQ;AACjB,aAAO;AAAA,IACT;AACA,QAAI,OAAO,WAAW,GAAG;AACvB,mBAAa,GAAG,QAAa,IAAI,OAAO,QAAQ,EAAE,CAAC,eAAe;AAAA,IACpE;AACA,UAAM,gBAAgB,KAAK;AAAA,MACzB,WAAW,OAAO;AAAA,MAClB,mBAAmB,IAAI;AAAA,MACvB,WAAU,oBAAI,KAAK,GAAE,YAAY;AAAA,IACnC,CAAC;AACD,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,MAAMD,QAAO;AAAA,IAChC,SAAS,MAAM,eAAe;AAAA,IAC9B,SAAS,aAAa,IAAI,CAAC,OAAO;AAAA,MAChC,OAAO,EAAE;AAAA,MACT,OAAO,EAAE;AAAA,MACT,MAAM,IAAI,GAAG,EAAE,QAAQ,SAAM,EAAE,QAAQ,EAAE;AAAA,IAC3C,EAAE;AAAA,EACJ,CAAC;AAED,MAAIC,UAAS,YAAY,EAAG,QAAO;AAEnC,QAAM,UAAU,cAAc,qBAAqB,EAAE,MAAM;AAC3D,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,OAAO,IAAqB,gBAAgB,YAAY,WAAW;AAAA,EACtF,QAAQ;AACN,YAAQ,KAAK;AACb,eAAW,sCAAsC;AACjD,WAAO;AAAA,EACT;AACA,UAAQ,KAAK;AAEb,MAAI,SAAS,WAAW,GAAG;AACzB,cAAU,mCAAmC;AAC7C,WAAO;AAAA,EACT;AAEA,QAAM,gBAAgB,MAAMD,QAAO;AAAA,IACjC,SAAS,MAAM,gBAAgB;AAAA,IAC/B,SAAS,SAAS,IAAI,CAAC,OAAO;AAAA,MAC5B,OAAO,EAAE;AAAA,MACT,OAAO,EAAE,eAAe,EAAE;AAAA,MAC1B,MAAM,IAAI,EAAE,SAAS;AAAA,IACvB,EAAE;AAAA,EACJ,CAAC;AAED,MAAIC,UAAS,aAAa,EAAG,QAAO;AAEpC,QAAM,kBAAkB,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,aAAa;AAEnE,QAAM,aAAa,MAAM;AAAA,IACvB;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB;AAAA,IACA;AAAA,EACF;AAEA,MAAI,eAAe,KAAK,CAAC,QAAQ,QAAQ;AACvC,cAAU,uBAAuB;AACjC,WAAO;AAAA,EACT;AAEA,MAAI,CAAC,QAAQ,QAAQ;AACnB,UAAM,qBAAqB,aAAa,IAAI,aAAa,gBAAgB,UAAU;AAEnF,UAAM,gBAAgB,KAAK;AAAA,MACzB,WAAW,gBAAgB;AAAA,MAC3B,mBAAmB,gBAAgB;AAAA,MACnC,WAAU,oBAAI,KAAK,GAAE,YAAY;AAAA,IACnC,CAAC;AAED,iBAAa,GAAG,QAAa,IAAI,UAAU,EAAE,CAAC,eAAe;AAC7D,cAAU,YAAY,IAAI,IAAI,WAAW,CAAC,WAAM,IAAI,gBAAgB,UAAU,CAAC,EAAE;AAAA,EACnF;AAEA,SAAO;AACT;AAEA,eAAe,qBAAqB,aAAqB,cAAsB,gBAAwB;AACrG,QAAM,cAAcK,MAAK,aAAa,YAAY;AAElD,QAAMF,OAAM,aAAa,EAAE,WAAW,KAAK,CAAC;AAE5C,MAAI;AACF,UAAM,QAAQ,MAAMC,OAAM,WAAW;AACrC,QAAI,MAAM,eAAe,GAAG;AAC1B,YAAM,OAAO,WAAW;AAAA,IAC1B,WAAW,MAAM,YAAY,GAAG;AAC9B,iBAAW;AAAA,QAAoE,WAAW,MAAM,WAAW,OAAO;AAClH;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EACR;AAEA,QAAM,QAAQ,gBAAgB,WAAW;AAC3C;AAEA,eAAe,iBACb,QACA,UACA,aACA,cACA,WACA,mBACA,aACA,SACiB;AACjB,QAAM,UAAU,cAAc,sCAAsC,EAAE,MAAM;AAE5E,MAAI;AACJ,MAAI;AACF,sBAAkB,MAAM,OAAO,KAA0B,0BAA0B;AAAA,MACjF;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,YAAQ,KAAK;AACb,eAAW,gBAAgB,eAAe,QAAQ,IAAI,UAAU,eAAe,EAAE;AACjF,WAAO;AAAA,EACT;AACA,UAAQ,KAAK;AAEb,QAAM,kBAAkB,gBAAgB;AACxC,MAAI,gBAAgB,WAAW,EAAG,QAAO;AAEzC,YAAU,GAAG,MAAM,OAAO,gBAAgB,MAAM,CAAC,CAAC,gBAAgB;AAElE,MAAI,QAAQ,QAAQ;AAClB,QAAI,QAAQ,SAAS;AACnB,iBAAW,SAAS,iBAAiB;AACnC,gBAAQ,IAAI,OAAO,MAAM,QAAG,CAAC,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI,YAAY,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE;AAAA,MACtF;AAAA,IACF;AACA,WAAO,gBAAgB;AAAA,EACzB;AAEA,QAAM,YAAYC,MAAK,aAAa,iBAAiB;AACrD,MAAI,aAAa;AAEjB,aAAW,SAAS,iBAAiB;AACnC,UAAM,YAAY;AAAA,MAChB,GAAG,eAAe,aAAa,GAAG,gBAAgB,MAAM,CAAC,IAAI,MAAM,IAAI;AAAA,IACzE,EAAE,MAAM;AAER,QAAI;AACF,YAAM,cAAc,MAAM,OAAO,KAA2B,+BAA+B;AAAA,QACzF,aAAa,gBAAgB;AAAA,QAC7B,KAAK,MAAM;AAAA,MACb,CAAC;AAED,YAAM,WAAW,MAAM,MAAM,YAAY,GAAG;AAC5C,UAAI,OAAO,OAAO,KAAK,MAAM,SAAS,YAAY,CAAC;AAEnD,UAAI,MAAM,cAAc;AACtB,eAAO,MAAM,iBAAiB,IAAI;AAAA,MACpC;AAEA,YAAM,aAAaA,MAAK,WAAW,MAAM,IAAI;AAC7C,YAAMF,OAAMG,SAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AACpD,YAAMJ,WAAU,YAAY,IAAI;AAEhC;AAAA,IACF,QAAQ;AAAA,IACR;AACA,cAAU,KAAK;AAAA,EACjB;AAEA,MAAI;AACF,UAAM,OAAO,KAAK,2BAA2B;AAAA,MAC3C,aAAa,gBAAgB;AAAA,MAC7B,UAAU;AAAA,IACZ,CAAC;AAAA,EACH,QAAQ;AAAA,EACR;AAEA,SAAO;AACT;AAaA,eAAe,UACb,QACA,UACA,aACA,UACA,YACA,WACA,SACqB;AACrB,QAAM,UAAU,cAAc,mBAAmB,EAAE,MAAM;AAEzD,MAAI;AACJ,MAAI;AACF,sBAAkB,MAAM,OAAO,KAA0B,0BAA0B;AAAA,MACjF;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,YAAQ,KAAK;AACb,eAAW,gBAAgB,eAAe,QAAQ,IAAI,UAAU,eAAe,EAAE;AACjF,WAAO,EAAE,UAAU,GAAG,WAAW,aAAa,IAAI,QAAQ,KAAK;AAAA,EACjE;AACA,UAAQ,KAAK;AAEb,QAAM,oBAAoB,gBAAgB;AAC1C,QAAM,gBAAgB,gBAAgB;AACtC,MAAI,cAAc,WAAW,EAAG,QAAO,EAAE,UAAU,GAAG,WAAW,mBAAmB,QAAQ,MAAM;AAElG,YAAU,GAAG,MAAM,OAAO,cAAc,MAAM,CAAC,CAAC,gBAAgB;AAEhE,MAAI,QAAQ,QAAQ;AAClB,QAAI,QAAQ,SAAS;AACnB,iBAAW,SAAS,eAAe;AACjC,gBAAQ,IAAI,OAAO,QAAa,GAAG,CAAC,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI,YAAY,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE;AAAA,MAC7F;AAAA,IACF;AACA,WAAO,EAAE,UAAU,cAAc,QAAQ,WAAW,mBAAmB,QAAQ,MAAM;AAAA,EACvF;AAEA,MAAI,WAAW;AACf,aAAW,SAAS,eAAe;AACjC,UAAM,gBAAgB;AAAA,MACpB,GAAG,eAAe,WAAW,GAAG,cAAc,MAAM,CAAC,IAAI,MAAM,IAAI;AAAA,IACrE,EAAE,MAAM;AAER,QAAI;AACF,YAAM,cAAc,MAAM,OAAO,KAA2B,6BAA6B;AAAA,QACvF,aAAa,gBAAgB;AAAA,QAC7B,KAAK,MAAM;AAAA,MACb,CAAC;AAED,YAAM,WAAWG,MAAK,YAAY,MAAM,IAAI;AAC5C,UAAI,OAAe,MAAMJ,UAAS,QAAQ;AAE1C,UAAI,MAAM,cAAc;AACtB,eAAO,MAAM,eAAe,IAAI;AAAA,MAClC;AAEA,YAAM,MAAM,YAAY,KAAK;AAAA,QAC3B,QAAQ;AAAA,QACR;AAAA,QACA,SAAS,EAAE,gBAAgB,2BAA2B;AAAA,MACxD,CAAC;AAED;AAAA,IACF,QAAQ;AAAA,IACR;AACA,kBAAc,KAAK;AAAA,EACrB;AAEA,MAAI;AACF,UAAM,OAAO,KAAK,2BAA2B;AAAA,MAC3C,aAAa,gBAAgB;AAAA,MAC7B;AAAA,IACF,CAAC;AAAA,EACH,QAAQ;AAAA,EACR;AAEA,SAAO,EAAE,UAAU,WAAW,mBAAmB,QAAQ,MAAM;AACjE;AAEA,eAAe,UACb,QACA,UACA,aACA,YACA,WACA,SACqB;AACrB,QAAM,UAAU,cAAc,mBAAmB,EAAE,MAAM;AAEzD,MAAI;AACJ,MAAI;AACF,sBAAkB,MAAM,OAAO,KAA0B,0BAA0B;AAAA,MACjF;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,YAAQ,KAAK;AACb,eAAW,gBAAgB,eAAe,QAAQ,IAAI,UAAU,eAAe,EAAE;AACjF,WAAO,EAAE,YAAY,GAAG,QAAQ,KAAK;AAAA,EACvC;AACA,UAAQ,KAAK;AAEb,QAAM,kBAAkB,gBAAgB;AACxC,MAAI,gBAAgB,WAAW,EAAG,QAAO,EAAE,YAAY,GAAG,QAAQ,MAAM;AAExE,YAAU,GAAG,MAAM,OAAO,gBAAgB,MAAM,CAAC,CAAC,gBAAgB;AAElE,MAAI,QAAQ,QAAQ;AAClB,QAAI,QAAQ,SAAS;AACnB,iBAAW,SAAS,iBAAiB;AACnC,gBAAQ,IAAI,OAAO,MAAM,QAAG,CAAC,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI,YAAY,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE;AAAA,MACtF;AAAA,IACF;AACA,WAAO,EAAE,YAAY,gBAAgB,QAAQ,QAAQ,MAAM;AAAA,EAC7D;AAEA,MAAI,aAAa;AACjB,aAAW,SAAS,iBAAiB;AACnC,UAAM,YAAY;AAAA,MAChB,GAAG,eAAe,aAAa,GAAG,gBAAgB,MAAM,CAAC,IAAI,MAAM,IAAI;AAAA,IACzE,EAAE,MAAM;AAER,QAAI;AACF,YAAM,cAAc,MAAM,OAAO,KAA2B,+BAA+B;AAAA,QACzF,aAAa,gBAAgB;AAAA,QAC7B,KAAK,MAAM;AAAA,MACb,CAAC;AAED,YAAM,WAAW,MAAM,MAAM,YAAY,GAAG;AAC5C,UAAI,OAAO,OAAO,KAAK,MAAM,SAAS,YAAY,CAAC;AAEnD,UAAI,MAAM,cAAc;AACtB,eAAO,MAAM,iBAAiB,IAAI;AAAA,MACpC;AAEA,YAAM,aAAaI,MAAK,YAAY,MAAM,IAAI;AAC9C,YAAMF,OAAMG,SAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AACpD,YAAMJ,WAAU,YAAY,IAAI;AAEhC;AAAA,IACF,QAAQ;AAAA,IACR;AACA,cAAU,KAAK;AAAA,EACjB;AAEA,MAAI;AACF,UAAM,OAAO,KAAK,2BAA2B;AAAA,MAC3C,aAAa,gBAAgB;AAAA,MAC7B,UAAU;AAAA,IACZ,CAAC;AAAA,EACH,QAAQ;AAAA,EACR;AAEA,SAAO,EAAE,YAAY,QAAQ,MAAM;AACrC;AAEO,SAAS,cAAuB;AACrC,SAAO,IAAIJ,SAAQ,MAAM,EACtB,YAAY,0CAA0C,EACtD,OAAO,aAAa,2CAA2C,EAC/D,OAAO,aAAa,sBAAsB,EAC1C,OAAO,OAAO,YAAY;AACzB,UAAM,QAAQ,OAAO;AAAA,EACvB,CAAC;AACL;AAziBA;AAAA;AAAA;AAIA;AACA;AACA;AACA;AACA;AAKA;AAAA;AAAA;;;ACbA;AAAA;AAAA;AAAA;AAAA,SAAS,WAAAa,gBAAe;AAMjB,SAAS,gBAAyB;AACvC,SAAO,IAAIA,SAAQ,QAAQ,EACxB,YAAY,sCAAsC,EAClD,OAAO,YAAY;AAClB,eAAW,QAAQ;AAEnB,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,MAAM,QAAQ,IAAI;AAExB,eAAW,OAAO,OAAO,MAAM;AAC/B,eAAW,iBAAiB,gBAAgB,MAAM,IAAI,QAAa,KAAK,IAAI,MAAW,IAAI,CAAC;AAC5F,eAAW,UAAU,OAAO,cAAc,IAAI,MAAM,CAAC;AACrD,eAAW,WAAW,MAAM,GAAG,CAAC;AAEhC,UAAM,MAAM,MAAM,oBAAoB,GAAG;AACzC,eAAW,SAAS,IAAI,UAAU,SAAS,IAAI,iBAAiB,IAAI,IAAI,UAAU,YAAY,kBAAa,IAAI,IAAI,iBAAiB,SAAS,CAAC,KAAK,OAAO;AAE1J,QAAI,CAAC,gBAAgB,MAAM,KAAK,IAAI,UAAU,OAAQ;AAEtD,UAAM,UAAU,cAAc,mBAAmB,EAAE,MAAM;AACzD,UAAM,gBAAgB,MAAM,oBAAoB,GAAG;AACnD,UAAM,kBAAkB,MAAM,qBAAqB,GAAG;AACtD,UAAM,OAAO,YAAY,iBAAiB,aAAa;AACvD,YAAQ,KAAK;AAEb,UAAM,YAAY,gBAAgB,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,MAAM,CAAC;AAEpE,iBAAa;AACb,eAAW,eAAe,GAAG,MAAM,OAAO,gBAAgB,MAAM,CAAC,CAAC,IAAI,IAAI,IAAI,YAAY,SAAS,CAAC,GAAG,CAAC,EAAE;AAC1G,YAAQ,IAAI;AACZ,cAAU,0BAA0B;AACpC,YAAQ,IAAI,OAAO,QAAa,IAAI,KAAK,MAAM,MAAM,EAAE,CAAC,WAAW,KAAU,IAAI,KAAK,SAAS,MAAM,EAAE,CAAC,cAAc,MAAW,IAAI,KAAK,QAAQ,MAAM,EAAE,CAAC,UAAU;AACrK,YAAQ,IAAI;AAAA,EACd,CAAC;AACL;AAxCA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAAA;AAAA;;;ACJA;AAAA;AAAA;AAAA;AAAA,SAAS,WAAAC,gBAAe;AAOjB,SAAS,gBAAyB;AACvC,SAAO,IAAIA,SAAQ,QAAQ,EACxB,YAAY,mCAAmC,EAC/C,OAAO,YAAY;AAClB,eAAW,UAAU;AAErB,UAAM,SAAS,MAAM,WAAW;AAEhC,QAAI,CAAC,gBAAgB,MAAM,GAAG;AAC5B,iBAAW,+CAA+C;AAC1D;AAAA,IACF;AAEA,UAAM,SAAS,IAAI,UAAU,OAAO,MAAM;AAC1C,UAAM,UAAU,cAAc,uBAAuB,EAAE,MAAM;AAE7D,QAAI;AACF,YAAM,OAAO,MAAM,OAAO,IAAU,cAAc;AAClD,cAAQ,KAAK;AACb,iBAAW,QAAQ,GAAG,KAAK,IAAI,IAAI,IAAI,IAAI,KAAK,KAAK,GAAG,CAAC,EAAE;AAC3D,iBAAW,QAAQ,MAAM,KAAK,IAAI,CAAC;AACnC,mBAAa;AACb,iBAAW,UAAU,OAAO,cAAc,IAAI,MAAM,CAAC;AACrD,iBAAW,aAAa,OAAO,YAAY,IAAI,gBAAgB,CAAC;AAAA,IAClE,QAAQ;AACN,cAAQ,KAAK;AACb,iBAAW,SAAS,OAAO,SAAS,IAAI,SAAS,CAAC;AAClD,iBAAW,UAAU,OAAO,cAAc,IAAI,MAAM,CAAC;AAAA,IACvD;AAEA,YAAQ,IAAI;AAAA,EACd,CAAC;AACL;AAvCA;AAAA;AAAA;AAEA;AACA;AACA;AACA;AAAA;AAAA;;;ACHA;AACA;AACA;AACA;AACA;AACA;AAPA,SAAS,WAAAC,gBAAe;;;ACExB;AACA;AAHA,SAAS,UAAAC,SAAQ,YAAAC,iBAAgB;AACjC,OAAOC,YAAW;AAUlB,SAAS,UAAU,UAAiC;AAClD,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,MACL,EAAE,OAAO,SAAS,OAAO,SAAS,MAAM,gCAAgC;AAAA,IAC1E;AAAA,EACF;AAEA,SAAO;AAAA,IACL,EAAE,OAAO,QAAQ,OAAO,QAAQ,MAAM,uBAAuB;AAAA,IAC7D,EAAE,OAAO,UAAU,OAAO,UAAU,MAAM,kBAAkB;AAAA,IAC5D,EAAE,OAAO,cAAc,OAAO,cAAc,MAAM,wBAAwB;AAAA,IAC1E,EAAE,OAAO,eAAe,OAAO,gBAAgB,MAAM,0BAA0B;AAAA,IAC/E,EAAE,OAAO,iBAAiB,OAAO,gBAAgB;AAAA,IACjD,EAAE,OAAO,iBAAiB,OAAO,gBAAgB;AAAA,IACjD,EAAE,OAAO,UAAU,OAAO,YAAY,MAAM,0BAA0B;AAAA,IACtE,EAAE,OAAO,UAAU,OAAO,UAAU,MAAM,WAAW;AAAA,EACvD;AACF;AAEA,eAAsB,SAAS;AAC7B,cAAY;AAEZ,QAAM,SAAS,MAAM,WAAW;AAChC,QAAM,WAAW,gBAAgB,MAAM;AAEvC,MAAI,UAAU;AACZ,YAAQ,IAAI,KAAK,IAAI,MAAM,CAAC,MAAM,MAAM,OAAO,SAAS,SAAS,CAAC,EAAE;AACpE,QAAI,OAAO,YAAY;AACrB,cAAQ,IAAI,KAAK,IAAI,QAAQ,CAAC,IAAI,MAAM,OAAO,UAAU,CAAC,EAAE;AAAA,IAC9D;AACA,YAAQ,IAAI;AAAA,EACd,OAAO;AACL,YAAQ,IAAI,KAAK,IAAI,eAAe,CAAC,EAAE;AACvC,YAAQ,IAAI;AAAA,EACd;AAEA,SAAO,MAAM;AACX,UAAM,QAAQ,UAAU,QAAQ;AAEhC,UAAM,UAAU;AAAA,MACd,GAAG,MAAM,IAAI,CAAC,OAAO;AAAA,QACnB,OAAO,EAAE;AAAA,QACT,OAAO,EAAE;AAAA,QACT,MAAM,EAAE,OAAO,IAAI,EAAE,IAAI,IAAI;AAAA,MAC/B,EAAE;AAAA,MACF,EAAE,OAAO,QAAQ,OAAOA,OAAM,IAAI,MAAM,EAAE;AAAA,IAC5C;AAEA,UAAM,SAAS,MAAMF,QAAO;AAAA,MAC1B,SAAS,MAAM,4BAA4B;AAAA,MAC3C;AAAA,IACF,CAAC;AAED,QAAIC,UAAS,MAAM,KAAK,WAAW,QAAQ;AACzC,iBAAW,UAAU;AACrB;AAAA,IACF;AAEA,UAAM,eAAe,MAAgB;AAErC,YAAQ,IAAI;AAAA,EACd;AACF;AAEA,eAAe,eAAe,SAAiB;AAC7C,QAAM,EAAE,cAAAE,cAAa,IAAI,MAAM;AAC/B,QAAM,EAAE,eAAAC,eAAc,IAAI,MAAM;AAChC,QAAM,EAAE,eAAAC,eAAc,IAAI,MAAM;AAChC,QAAM,EAAE,aAAAC,aAAY,IAAI,MAAM;AAC9B,QAAM,EAAE,eAAAC,eAAc,IAAI,MAAM;AAChC,QAAM,EAAE,eAAAC,eAAc,IAAI,MAAM;AAEhC,QAAM,WAAgD;AAAA,IACpD,OAAO,MAAML,cAAa,EAAE,WAAW,CAAC,IAAI,IAAI,OAAO,CAAC;AAAA,IACxD,QAAQ,MAAMC,eAAc,EAAE,WAAW,CAAC,IAAI,IAAI,QAAQ,CAAC;AAAA,IAC3D,MAAM,MAAME,aAAY,EAAE,WAAW,CAAC,IAAI,IAAI,MAAM,CAAC;AAAA,IACrD,QAAQ,MAAMC,eAAc,EAAE,WAAW,CAAC,IAAI,IAAI,QAAQ,CAAC;AAAA,IAC3D,QAAQ,MAAMC,eAAc,EAAE,WAAW,CAAC,IAAI,IAAI,QAAQ,CAAC;AAAA,IAC3D,cAAc,MAAMH,eAAc,EAAE,WAAW,CAAC,IAAI,IAAI,UAAU,KAAK,CAAC;AAAA,IACxE,eAAe,MAAMA,eAAc,EAAE,WAAW,CAAC,IAAI,IAAI,UAAU,MAAM,CAAC;AAAA,IAC1E,iBAAiB,MAAMA,eAAc,EAAE,WAAW,CAAC,IAAI,IAAI,UAAU,QAAQ,CAAC;AAAA,IAC9E,iBAAiB,MAAMA,eAAc,EAAE,WAAW,CAAC,IAAI,IAAI,UAAU,QAAQ,CAAC;AAAA,EAChF;AAEA,QAAM,UAAU,SAAS,OAAO;AAChC,MAAI,SAAS;AACX,QAAI;AACF,YAAM,QAAQ;AAAA,IAChB,QAAQ;AAAA,IACR;AAAA,EACF;AACF;;;AD7FA;AAEO,SAAS,MAAM;AACpB,QAAM,UAAU,IAAII,SAAQ;AAE5B,UACG,KAAK,aAAa,EAClB,YAAY,2CAA2C,EACvD,QAAQ,OAAO,EACf,OAAO,UAAU,uBAAuB,EACxC,OAAO,OAAO,YAAY;AACzB,QAAI,QAAQ,MAAM;AAChB,YAAM,OAAO;AACb;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,WAAW;AAChC,QAAI,gBAAgB,MAAM,KAAK,OAAO,UAAU;AAC9C,YAAM,QAAQ,CAAC,CAAC;AAAA,IAClB,OAAO;AACL,YAAM,OAAO;AAAA,IACf;AAAA,EACF,CAAC;AAEH,UAAQ,WAAW,aAAa,CAAC;AACjC,UAAQ,WAAW,cAAc,CAAC;AAClC,UAAQ,WAAW,cAAc,CAAC;AAClC,UAAQ,WAAW,YAAY,CAAC;AAChC,UAAQ,WAAW,cAAc,CAAC;AAClC,UAAQ,WAAW,cAAc,CAAC;AAElC,UAAQ,MAAM;AAChB;;;AEtCA,IAAI;","names":["error","text","chalk","Command","Command","homedir","text","isCancel","join","homedir","encodePath","Command","select","isCancel","readFile","writeFile","mkdir","lstat","join","dirname","homedir","CLAUDE_DIR","PROJECTS_DIR","finalManifest","Command","Command","Command","select","isCancel","chalk","loginCommand","logoutCommand","deviceCommand","syncCommand","statusCommand","whoamiCommand","Command"]}
|
|
1
|
+
{"version":3,"sources":["../../src/lib/config.ts","../../src/lib/api-client.ts","../../src/lib/auth.ts","../../src/lib/progress.ts","../../src/lib/theme.ts","../../src/commands/login.ts","../../src/commands/logout.ts","../../src/commands/device.ts","../../src/lib/sync-engine.ts","../../src/lib/compress.ts","../../src/commands/sync.ts","../../src/commands/status.ts","../../src/commands/whoami.ts","../../src/index.ts","../../src/commands/tui.ts","../../bin/claude-sync.ts"],"sourcesContent":["import { join, dirname } from 'node:path';\nimport { homedir } from 'node:os';\nimport { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport { CONFIG_DIR, CONFIG_FILE, MANIFEST_FILE, encodePath } from '@claude-sync/utils';\n\nexport interface CliConfig {\n apiUrl: string;\n accessToken: string | null;\n refreshToken: string | null;\n deviceId: string | null;\n deviceName: string | null;\n userId: string | null;\n email: string | null;\n}\n\nconst DEFAULT_CONFIG: CliConfig = {\n apiUrl: 'https://api.claude-sync.com',\n accessToken: null,\n refreshToken: null,\n deviceId: null,\n deviceName: null,\n userId: null,\n email: null,\n};\n\nfunction getConfigDir(): string {\n return join(homedir(), CONFIG_DIR);\n}\n\nfunction getConfigPath(): string {\n return join(getConfigDir(), CONFIG_FILE);\n}\n\nfunction getManifestPath(): string {\n return join(getConfigDir(), MANIFEST_FILE);\n}\n\nexport async function loadConfig(): Promise<CliConfig> {\n try {\n const content = await readFile(getConfigPath(), 'utf-8');\n return { ...DEFAULT_CONFIG, ...JSON.parse(content) };\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n}\n\nexport async function saveConfig(config: Partial<CliConfig>): Promise<void> {\n const existing = await loadConfig();\n const merged = { ...existing, ...config };\n await mkdir(getConfigDir(), { recursive: true });\n await writeFile(getConfigPath(), JSON.stringify(merged, null, 2));\n}\n\nexport async function clearConfig(): Promise<void> {\n await saveConfig(DEFAULT_CONFIG);\n}\n\nexport async function loadManifest(): Promise<import('@claude-sync/types').ManifestEntry[]> {\n try {\n const content = await readFile(getManifestPath(), 'utf-8');\n return JSON.parse(content);\n } catch {\n return [];\n }\n}\n\nexport async function saveManifest(entries: import('@claude-sync/types').ManifestEntry[]): Promise<void> {\n await mkdir(getConfigDir(), { recursive: true });\n await writeFile(getManifestPath(), JSON.stringify(entries, null, 2));\n}\n\nexport async function loadProjectManifest(projectPath: string): Promise<import('@claude-sync/types').ManifestEntry[]> {\n try {\n const encoded = encodePath(projectPath);\n const manifestPath = join(getConfigDir(), 'manifests', `${encoded}.json`);\n const content = await readFile(manifestPath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return [];\n }\n}\n\nexport async function saveProjectManifest(projectPath: string, entries: import('@claude-sync/types').ManifestEntry[]): Promise<void> {\n const encoded = encodePath(projectPath);\n const manifestPath = join(getConfigDir(), 'manifests', `${encoded}.json`);\n await mkdir(dirname(manifestPath), { recursive: true });\n await writeFile(manifestPath, JSON.stringify(entries, null, 2));\n}\n\nexport function isAuthenticated(config: CliConfig): boolean {\n return config.accessToken !== null;\n}\n\nexport interface ProjectLink {\n projectId: string;\n foreignEncodedDir: string;\n linkedAt: string;\n}\n\nexport async function loadProjectLink(projectPath: string): Promise<ProjectLink | null> {\n try {\n const encoded = encodePath(projectPath);\n const linkPath = join(getConfigDir(), 'project-links', `${encoded}.json`);\n const content = await readFile(linkPath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\nexport async function saveProjectLink(projectPath: string, link: ProjectLink): Promise<void> {\n const encoded = encodePath(projectPath);\n const linkPath = join(getConfigDir(), 'project-links', `${encoded}.json`);\n await mkdir(dirname(linkPath), { recursive: true });\n await writeFile(linkPath, JSON.stringify(link, null, 2));\n}\n","import type { ApiErrorResponse } from '@claude-sync/types';\nimport { getValidToken } from './auth.js';\n\nexport class ApiClient {\n private baseUrl: string;\n\n constructor(baseUrl: string) {\n this.baseUrl = baseUrl.replace(/\\/$/, '');\n }\n\n private async rawRequest<T>(path: string, options: RequestInit = {}): Promise<T> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 15000);\n\n let response: Response;\n try {\n response = await fetch(`${this.baseUrl}${path}`, {\n ...options,\n signal: controller.signal,\n });\n } catch (err) {\n clearTimeout(timeout);\n if (err instanceof Error && err.name === 'AbortError') {\n throw new Error('Request timed out. Is the API server running?');\n }\n throw err;\n }\n clearTimeout(timeout);\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error('Session expired. Run `claude-sync login` to re-authenticate.');\n }\n const error: ApiErrorResponse = await response.json().catch(() => ({\n statusCode: response.status,\n message: response.statusText,\n error: 'Request failed',\n }));\n throw new Error(error.message);\n }\n\n const json = await response.json();\n return (json.data !== undefined ? json.data : json) as T;\n }\n\n async request<T>(path: string, options: RequestInit = {}): Promise<T> {\n const token = await getValidToken();\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(options.headers as Record<string, string>),\n };\n\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n return this.rawRequest<T>(path, { ...options, headers });\n }\n\n async requestNoAuth<T>(path: string, options: RequestInit = {}): Promise<T> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(options.headers as Record<string, string>),\n };\n\n return this.rawRequest<T>(path, { ...options, headers });\n }\n\n async get<T>(path: string): Promise<T> {\n return this.request<T>(path, { method: 'GET' });\n }\n\n async post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(path, {\n method: 'POST',\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n async patch<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(path, {\n method: 'PATCH',\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n async delete<T>(path: string): Promise<T> {\n return this.request<T>(path, { method: 'DELETE' });\n }\n}\n","import type { TokenPair } from '@claude-sync/types';\nimport { loadConfig, saveConfig } from './config.js';\nimport { ApiClient } from './api-client.js';\n\nexport async function storeTokens(tokens: TokenPair, userId: string, email: string): Promise<void> {\n await saveConfig({\n accessToken: tokens.accessToken,\n refreshToken: tokens.refreshToken,\n userId,\n email,\n });\n}\n\nexport async function refreshAccessToken(): Promise<string | null> {\n const config = await loadConfig();\n if (!config.refreshToken) return null;\n\n const client = new ApiClient(config.apiUrl);\n try {\n const response = await client.requestNoAuth<TokenPair>('/api/auth/refresh', {\n method: 'POST',\n body: JSON.stringify({ refreshToken: config.refreshToken }),\n });\n await saveConfig({\n accessToken: response.accessToken,\n refreshToken: response.refreshToken,\n });\n return response.accessToken;\n } catch {\n return null;\n }\n}\n\nexport async function getValidToken(): Promise<string | null> {\n const config = await loadConfig();\n if (!config.accessToken) return null;\n\n try {\n const payload = JSON.parse(\n Buffer.from(config.accessToken.split('.')[1], 'base64').toString()\n );\n if (payload.exp * 1000 > Date.now()) {\n return config.accessToken;\n }\n } catch {\n }\n\n return refreshAccessToken();\n}\n","import ora, { type Ora } from 'ora';\nimport chalk from 'chalk';\n\nconst brandColor = chalk.hex('#8a8cdd');\n\nexport function createSpinner(text: string): Ora {\n return ora({ text: brandColor(text), spinner: 'dots', color: 'magenta' });\n}\n\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) return '0 B';\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;\n}\n\nexport function formatProgress(current: number, total: number): string {\n const percentage = total > 0 ? Math.round((current / total) * 100) : 0;\n return `${current}/${total} (${percentage}%)`;\n}\n","import chalk from 'chalk';\n\nconst BRAND_HEX = '#8a8cdd';\nconst BRAND_DIM_HEX = '#6b6db8';\nconst SUCCESS_HEX = '#8adda0';\nconst WARN_HEX = '#ddcc8a';\nconst ERROR_HEX = '#dd8a8a';\n\nexport const brand = chalk.hex(BRAND_HEX);\nexport const brandBold = chalk.hex(BRAND_HEX).bold;\nexport const brandDim = chalk.hex(BRAND_DIM_HEX);\nexport const success = chalk.hex(SUCCESS_HEX);\nexport const successBold = chalk.hex(SUCCESS_HEX).bold;\nexport const warn = chalk.hex(WARN_HEX);\nexport const error = chalk.hex(ERROR_HEX);\nexport const errorBold = chalk.hex(ERROR_HEX).bold;\nexport const dim = chalk.dim;\nexport const bold = chalk.bold;\nexport const white = chalk.white;\n\nexport function printBanner() {\n console.log();\n console.log(` ${brandBold('claude-sync')} ${dim('v0.1.0')}`);\n console.log();\n}\n\nexport function printIntro(title: string) {\n console.log();\n console.log(` ${brandBold(title)}`);\n console.log();\n}\n\nexport function printOutro(message: string) {\n console.log();\n console.log(` ${dim(message)}`);\n console.log();\n}\n\nexport function printSuccess(message: string) {\n console.log(` ${success('✔')} ${message}`);\n}\n\nexport function printError(message: string) {\n console.log(` ${error('✖')} ${message}`);\n}\n\nexport function printWarn(message: string) {\n console.log(` ${warn('▲')} ${message}`);\n}\n\nexport function printInfo(message: string) {\n console.log(` ${brand('●')} ${message}`);\n}\n\nexport function printLabel(label: string, value: string) {\n console.log(` ${dim(label.padEnd(14))} ${white(value)}`);\n}\n\nexport function printDivider() {\n console.log();\n}\n","import { Command } from 'commander';\nimport { text, password as passwordPrompt, select, isCancel } from '@clack/prompts';\nimport type { TokenPair, CliInitiateResponse, CliPollResponse } from '@claude-sync/types';\nimport { loadConfig } from '../lib/config.js';\nimport { storeTokens } from '../lib/auth.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { createSpinner } from '../lib/progress.js';\nimport { printIntro, printOutro, printInfo, printSuccess, printError, brand, brandBold, dim } from '../lib/theme.js';\n\nasync function loginWithBrowser(client: ApiClient): Promise<void> {\n const response = await client.requestNoAuth<CliInitiateResponse>('/api/auth/cli/initiate', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n });\n\n printInfo(`Open this URL in your browser:\\n ${brandBold(response.verifyUrl)}`);\n printInfo(`Code: ${brandBold(response.code)}`);\n\n const spinner = createSpinner('Waiting for browser authorization...').start();\n\n const pollInterval = 2000;\n const maxAttempts = 150;\n let attempts = 0;\n\n while (attempts < maxAttempts) {\n await new Promise((resolve) => setTimeout(resolve, pollInterval));\n attempts++;\n\n try {\n const pollResponse = await client.requestNoAuth<CliPollResponse>('/api/auth/cli/poll', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ code: response.code }),\n });\n\n if (pollResponse.status === 'authorized' && pollResponse.tokenPair && pollResponse.user) {\n spinner.stop();\n await storeTokens(pollResponse.tokenPair, pollResponse.user.id, pollResponse.user.email);\n printSuccess(`Logged in as ${brandBold(pollResponse.user.email)}`);\n return;\n }\n\n if (pollResponse.status === 'expired') {\n spinner.stop();\n printError('Authorization code expired. Please try again.');\n process.exit(1);\n }\n } catch {\n }\n }\n\n spinner.stop();\n printError('Authorization timed out. Please try again.');\n process.exit(1);\n}\n\nasync function loginWithEmail(client: ApiClient): Promise<void> {\n const email = await text({ message: `${brand('Email')}:` });\n if (isCancel(email)) process.exit(0);\n\n const password = await passwordPrompt({ message: `${brand('Password')}:` });\n if (isCancel(password)) process.exit(0);\n\n const spinner = createSpinner('Logging in...').start();\n\n try {\n const response = await client.requestNoAuth<TokenPair & { user: { id: string; email: string } }>(\n '/api/auth/login',\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email, password }),\n },\n );\n spinner.stop();\n await storeTokens(\n { accessToken: response.accessToken, refreshToken: response.refreshToken, expiresIn: 900 },\n response.user.id,\n response.user.email\n );\n printSuccess(`Logged in as ${brandBold(response.user.email)}`);\n } catch (err) {\n spinner.stop();\n printError(`Login failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n}\n\nexport function loginCommand(): Command {\n return new Command('login')\n .description('Authenticate with claude-sync')\n .action(async () => {\n printIntro('Login');\n\n const config = await loadConfig();\n const client = new ApiClient(config.apiUrl);\n\n const method = await select({\n message: `${brand('How would you like to log in?')}`,\n options: [\n { value: 'browser', label: `${brand('○')} Browser ${dim('(recommended)')}` },\n { value: 'email', label: `${brand('○')} Email & password` },\n ],\n });\n\n if (isCancel(method)) process.exit(0);\n\n if (method === 'browser') {\n await loginWithBrowser(client);\n } else {\n await loginWithEmail(client);\n }\n\n printOutro('Authentication complete');\n });\n}\n","import { Command } from 'commander';\nimport { loadConfig, clearConfig } from '../lib/config.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { printIntro, printOutro, printInfo, printSuccess } from '../lib/theme.js';\n\nexport function logoutCommand(): Command {\n return new Command('logout')\n .description('Log out and revoke tokens')\n .action(async () => {\n printIntro('Logout');\n\n const config = await loadConfig();\n if (!config.accessToken) {\n printInfo('Not currently logged in.');\n printOutro('Done');\n return;\n }\n\n try {\n const client = new ApiClient(config.apiUrl);\n await client.post('/api/auth/logout', {\n refreshToken: config.refreshToken,\n });\n } catch {\n }\n\n await clearConfig();\n printSuccess('Logged out successfully.');\n printOutro('Done');\n });\n}\n","import { Command } from 'commander';\nimport { hostname, platform, arch, homedir } from 'node:os';\nimport { text, isCancel } from '@clack/prompts';\nimport type { Device } from '@claude-sync/types';\nimport { loadConfig, saveConfig, isAuthenticated } from '../lib/config.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { createSpinner } from '../lib/progress.js';\nimport { printIntro, printOutro, printSuccess, printError, printInfo, printLabel, printDivider, brand, brandBold, dim, success, error as errorColor, white } from '../lib/theme.js';\n\nfunction requireAuth(config: Awaited<ReturnType<typeof loadConfig>>): void {\n if (!isAuthenticated(config)) {\n printError('Not logged in. Run `claude-sync login` first.');\n process.exit(1);\n }\n}\n\nexport function deviceCommand(): Command {\n const device = new Command('device').description('Manage devices');\n\n device\n .command('add')\n .argument('[name]', 'Device name')\n .description('Register this machine as a device')\n .action(async (name?: string) => {\n printIntro('Device Add');\n\n const config = await loadConfig();\n requireAuth(config);\n\n const deviceName = name || await (async () => {\n const input = await text({ message: `${brand('Device name')}:`, initialValue: hostname() });\n if (isCancel(input)) process.exit(0);\n return input;\n })();\n\n const spinner = createSpinner('Registering device...').start();\n const client = new ApiClient(config.apiUrl);\n\n try {\n const response = await client.post<Device>('/api/devices', {\n name: deviceName,\n hostname: hostname(),\n platform: platform(),\n homeDir: homedir(),\n arch: arch(),\n });\n\n await saveConfig({\n deviceId: response.id,\n deviceName: response.name,\n });\n\n spinner.stop();\n printSuccess(`Device ${brandBold(`\"${response.name}\"`)} registered`);\n printLabel('ID', response.id);\n } catch (err) {\n spinner.stop();\n printError(`Failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n\n printOutro('Done');\n });\n\n device\n .command('list')\n .description('List all registered devices')\n .action(async () => {\n printIntro('Devices');\n\n const config = await loadConfig();\n requireAuth(config);\n\n const client = new ApiClient(config.apiUrl);\n const spinner = createSpinner('Fetching devices...').start();\n\n try {\n const devices = await client.get<Device[]>('/api/devices');\n spinner.stop();\n\n if (devices.length === 0) {\n printInfo('No devices registered.');\n return;\n }\n\n console.log();\n for (const d of devices) {\n const current = d.id === config.deviceId ? ` ${brandBold('(current)')}` : '';\n const active = d.isActive ? success('active') : errorColor('inactive');\n console.log(` ${brand('○')} ${white(d.name)}${current}`);\n console.log(` ${dim(d.platform)} ${dim('·')} ${active} ${dim('·')} ${dim(d.id)}`);\n }\n console.log();\n } catch (err) {\n spinner.stop();\n printError(`Failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n });\n\n device\n .command('remove')\n .argument('<nameOrId>', 'Device name or ID')\n .description('Remove a device')\n .action(async (nameOrId: string) => {\n const config = await loadConfig();\n requireAuth(config);\n\n const client = new ApiClient(config.apiUrl);\n const spinner = createSpinner('Removing device...').start();\n\n try {\n await client.delete(`/api/devices/${nameOrId}`);\n spinner.stop();\n\n if (config.deviceId === nameOrId) {\n await saveConfig({ deviceId: null, deviceName: null });\n }\n\n printSuccess('Device removed.');\n } catch (err) {\n spinner.stop();\n printError(`Failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n });\n\n device\n .command('rename')\n .argument('<name>', 'New name')\n .description('Rename the current device')\n .action(async (name: string) => {\n const config = await loadConfig();\n requireAuth(config);\n\n if (!config.deviceId) {\n printError('No device registered. Run `claude-sync device add` first.');\n process.exit(1);\n }\n\n const client = new ApiClient(config.apiUrl);\n const spinner = createSpinner('Renaming device...').start();\n\n try {\n const response = await client.patch<Device>(`/api/devices/${config.deviceId}`, { name });\n await saveConfig({ deviceName: response.name });\n spinner.stop();\n printSuccess(`Device renamed to ${brandBold(`\"${response.name}\"`)}`);\n } catch (err) {\n spinner.stop();\n printError(`Failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n });\n\n return device;\n}\n","import { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { readdir, stat, lstat, readlink } from 'node:fs/promises';\nimport type { ManifestEntry, ManifestDiff } from '@claude-sync/types';\nimport { hashFile, diffManifests, encodePath, CLAUDE_DIR, PROJECTS_DIR, SYNC_EXCLUDE_PATTERNS } from '@claude-sync/utils';\n\nfunction shouldExclude(name: string): boolean {\n return SYNC_EXCLUDE_PATTERNS.some((pattern) => {\n if (pattern.startsWith('*')) {\n return name.endsWith(pattern.slice(1));\n }\n return name === pattern;\n });\n}\n\nasync function walkDirectory(dir: string, basePath: string = ''): Promise<ManifestEntry[]> {\n const entries: ManifestEntry[] = [];\n const items = await readdir(dir, { withFileTypes: true });\n\n for (const item of items) {\n if (shouldExclude(item.name)) continue;\n\n const fullPath = join(dir, item.name);\n const relativePath = basePath ? `${basePath}/${item.name}` : item.name;\n\n if (item.isDirectory()) {\n const subEntries = await walkDirectory(fullPath, relativePath);\n entries.push(...subEntries);\n } else if (item.isFile()) {\n const fileStat = await stat(fullPath);\n const hash = await hashFile(fullPath);\n const isText = !isBinaryPath(item.name);\n entries.push({\n path: relativePath,\n hash,\n size: fileStat.size,\n modifiedAt: fileStat.mtime.toISOString(),\n isCompressed: isText,\n });\n }\n }\n\n return entries;\n}\n\nfunction isBinaryPath(name: string): boolean {\n const binaryExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.ico', '.pdf', '.zip', '.gz', '.tar'];\n return binaryExtensions.some((ext) => name.endsWith(ext));\n}\n\nexport async function buildManifest(): Promise<ManifestEntry[]> {\n const claudeDir = join(homedir(), CLAUDE_DIR);\n return walkDirectory(claudeDir);\n}\n\nexport type ProjectState = 'none' | 'real' | 'symlink';\n\nexport interface ProjectContext {\n cwd: string;\n encodedPath: string;\n projectDir: string;\n state: ProjectState;\n symlinkTarget?: string;\n}\n\nexport async function resolveProjectState(cwd: string): Promise<ProjectContext> {\n const projectsDir = join(homedir(), CLAUDE_DIR, PROJECTS_DIR);\n const encoded = encodePath(cwd);\n const projectDir = join(projectsDir, encoded);\n\n let state: ProjectState = 'none';\n let symlinkTarget: string | undefined;\n\n try {\n const stats = await lstat(projectDir);\n if (stats.isSymbolicLink()) {\n state = 'symlink';\n symlinkTarget = await readlink(projectDir);\n } else if (stats.isDirectory()) {\n state = 'real';\n }\n } catch {\n state = 'none';\n }\n\n return { cwd, encodedPath: encoded, projectDir, state, symlinkTarget };\n}\n\nexport async function buildProjectManifest(cwd: string): Promise<ManifestEntry[]> {\n const ctx = await resolveProjectState(cwd);\n\n if (ctx.state === 'none') return [];\n\n const projectsDir = join(homedir(), CLAUDE_DIR, PROJECTS_DIR);\n let targetDir = ctx.projectDir;\n\n if (ctx.state === 'symlink' && ctx.symlinkTarget) {\n targetDir = join(projectsDir, ctx.symlinkTarget);\n }\n\n try {\n return await walkDirectory(targetDir);\n } catch {\n return [];\n }\n}\n\nexport function computeDiff(local: ManifestEntry[], remote: ManifestEntry[]): ManifestDiff {\n return diffManifests(local, remote);\n}\n","import { createGzip, createGunzip } from 'node:zlib';\nimport { createReadStream, createWriteStream } from 'node:fs';\nimport { pipeline } from 'node:stream/promises';\n\nexport async function compressFile(inputPath: string, outputPath: string): Promise<void> {\n const source = createReadStream(inputPath);\n const destination = createWriteStream(outputPath);\n const gzip = createGzip();\n await pipeline(source, gzip, destination);\n}\n\nexport async function decompressFile(inputPath: string, outputPath: string): Promise<void> {\n const source = createReadStream(inputPath);\n const destination = createWriteStream(outputPath);\n const gunzip = createGunzip();\n await pipeline(source, gunzip, destination);\n}\n\nexport function compressBuffer(data: Buffer): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const gzip = createGzip();\n const chunks: Buffer[] = [];\n gzip.on('data', (chunk: Buffer) => chunks.push(chunk));\n gzip.on('end', () => resolve(Buffer.concat(chunks)));\n gzip.on('error', reject);\n gzip.end(data);\n });\n}\n\nexport function decompressBuffer(data: Buffer): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const gunzip = createGunzip();\n const chunks: Buffer[] = [];\n gunzip.on('data', (chunk: Buffer) => chunks.push(chunk));\n gunzip.on('end', () => resolve(Buffer.concat(chunks)));\n gunzip.on('error', reject);\n gunzip.end(data);\n });\n}\n","import { Command } from 'commander';\nimport { select, isCancel } from '@clack/prompts';\nimport type { PushPrepareResponse, PullPrepareResponse, PresignedUrlResponse } from '@claude-sync/types';\nimport type { ManifestEntry } from '@claude-sync/types';\nimport { loadConfig, saveProjectManifest, isAuthenticated, loadProjectLink, saveProjectLink } from '../lib/config.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { resolveProjectState, buildProjectManifest } from '../lib/sync-engine.js';\nimport { createSpinner, formatBytes, formatProgress } from '../lib/progress.js';\nimport { compressBuffer, decompressBuffer } from '../lib/compress.js';\nimport { readFile, writeFile, mkdir, lstat, symlink, unlink } from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { homedir } from 'node:os';\nimport { CLAUDE_DIR, PROJECTS_DIR } from '@claude-sync/utils';\nimport { printIntro, printOutro, printInfo, printSuccess, printError, brand, success as successColor, dim } from '../lib/theme.js';\nimport type { CliConfig } from '../lib/config.js';\nimport type { ProjectContext } from '../lib/sync-engine.js';\n\ninterface DeviceProject {\n id: string;\n displayName: string;\n originalPath: string;\n canonicalPath: string;\n encodedDir: string;\n localPath: string;\n}\n\ninterface DeviceInfo {\n id: string;\n name: string;\n hostname: string;\n platform: string;\n}\n\nexport async function runSync(options: { dryRun?: boolean; verbose?: boolean }) {\n printIntro('Sync');\n\n const config = await loadConfig();\n if (!isAuthenticated(config)) {\n printError('Not logged in. Run `claude-sync login` first.');\n return;\n }\n if (!config.deviceId) {\n printError('No device registered. Run `claude-sync device add` first.');\n return;\n }\n\n const cwd = process.cwd();\n const ctx = await resolveProjectState(cwd);\n const client = new ApiClient(config.apiUrl);\n const projectsDir = join(homedir(), CLAUDE_DIR, PROJECTS_DIR);\n const projectLink = await loadProjectLink(cwd);\n\n let projectDir = ctx.projectDir;\n if (ctx.state === 'symlink' && ctx.symlinkTarget) {\n projectDir = join(projectsDir, ctx.symlinkTarget);\n }\n\n printInfo(`Project: ${brand(cwd)}`);\n if (ctx.state === 'symlink') {\n printInfo(`Linked to: ${dim(ctx.symlinkTarget || 'unknown')}`);\n }\n\n const manifest = await buildProjectManifest(cwd);\n\n if (!projectLink) {\n const result = await handleFirstRun(client, config, cwd, ctx, manifest, projectDir, projectsDir, options);\n\n if (result === 'cancelled') {\n printOutro('Cancelled.');\n return;\n }\n\n if (result === 'pulled') {\n const finalManifest = await buildProjectManifest(cwd);\n await saveProjectManifest(cwd, finalManifest);\n printSuccess('Sessions synced from remote device.');\n printOutro('Done');\n return;\n }\n\n if (result === 'pushed') {\n const finalManifest = await buildProjectManifest(cwd);\n await saveProjectManifest(cwd, finalManifest);\n printOutro('Done');\n return;\n }\n\n printOutro('Done');\n return;\n }\n\n let pushResult: PushResult = { uploaded: 0, projectId: projectLink.projectId, failed: false };\n let pullResult: PullResult = { downloaded: 0, failed: false };\n\n if (manifest.length > 0) {\n pushResult = await pushPhase(client, config.deviceId, cwd, manifest, projectDir, projectLink.projectId, options);\n }\n\n if (!pushResult.failed) {\n pullResult = await pullPhase(client, config.deviceId, cwd, projectDir, projectLink.projectId, options);\n }\n\n if (pushResult.failed && pullResult.failed) {\n printOutro('Sync failed.');\n return;\n }\n\n const finalManifest = await buildProjectManifest(cwd);\n await saveProjectManifest(cwd, finalManifest);\n\n if (pushResult.uploaded > 0 || pullResult.downloaded > 0) {\n const parts: string[] = [];\n if (pushResult.uploaded > 0) parts.push(`${successColor(`+${pushResult.uploaded}`)} pushed`);\n if (pullResult.downloaded > 0) parts.push(`${successColor(`+${pullResult.downloaded}`)} pulled`);\n printSuccess(`Synced: ${parts.join(', ')}`);\n } else if (!pushResult.failed && !pullResult.failed) {\n printSuccess('Everything is up to date.');\n }\n\n printOutro('Done');\n}\n\nasync function handleFirstRun(\n client: ApiClient,\n config: CliConfig,\n cwd: string,\n ctx: ProjectContext,\n manifest: ManifestEntry[],\n projectDir: string,\n projectsDir: string,\n options: { dryRun?: boolean; verbose?: boolean },\n): Promise<'pushed' | 'pulled' | 'cancelled'> {\n printInfo(brand('First time syncing this project'));\n\n const hasLocalFiles = ctx.state !== 'none' && manifest.length > 0;\n\n const devicesSpinner = createSpinner('Checking for other devices...').start();\n let devices: DeviceInfo[];\n try {\n devices = await client.get<DeviceInfo[]>('/api/devices');\n } catch {\n devices = [];\n }\n devicesSpinner.stop();\n\n const otherDevices = devices.filter((d) => d.id !== config.deviceId);\n\n type FirstRunChoice = 'push' | 'continue';\n const menuOptions: { value: FirstRunChoice; label: string; hint?: string }[] = [];\n\n if (hasLocalFiles) {\n menuOptions.push({\n value: 'push',\n label: 'Push to cloud',\n hint: dim(`Upload ${manifest.length} local files`),\n });\n }\n\n if (otherDevices.length > 0) {\n menuOptions.push({\n value: 'continue',\n label: 'Continue from another machine',\n hint: dim('Pull sessions from a device'),\n });\n }\n\n if (menuOptions.length === 0) {\n printInfo('No local sessions and no other devices found.');\n printInfo('Use Claude Code in this directory first, then run sync.');\n return 'cancelled';\n }\n\n if (menuOptions.length === 1 && menuOptions[0].value === 'push') {\n printInfo('No other devices found.');\n }\n\n const choice = await select<FirstRunChoice>({\n message: brand('What would you like to do?'),\n options: menuOptions,\n });\n\n if (isCancel(choice)) return 'cancelled';\n\n if (choice === 'push') {\n const result = await pushPhase(client, config.deviceId!, cwd, manifest, projectDir, undefined, options);\n if (result.failed) {\n return 'cancelled';\n }\n if (result.uploaded > 0) {\n printSuccess(`${successColor(`+${result.uploaded}`)} files pushed`);\n }\n await saveProjectLink(cwd, {\n projectId: result.projectId,\n foreignEncodedDir: ctx.encodedPath,\n linkedAt: new Date().toISOString(),\n });\n return 'pushed';\n }\n\n const deviceChoice = await select({\n message: brand('Select device'),\n options: otherDevices.map((d) => ({\n value: d.id,\n label: d.name,\n hint: dim(`${d.hostname} · ${d.platform}`),\n })),\n });\n\n if (isCancel(deviceChoice)) return 'cancelled';\n\n const spinner = createSpinner('Loading projects...').start();\n let projects: DeviceProject[];\n try {\n projects = await client.get<DeviceProject[]>(`/api/devices/${deviceChoice}/projects`);\n } catch {\n spinner.stop();\n printError('Failed to load projects from device.');\n return 'cancelled';\n }\n spinner.stop();\n\n if (projects.length === 0) {\n printInfo('No projects found on that device.');\n return 'cancelled';\n }\n\n const projectChoice = await select({\n message: brand('Select project'),\n options: projects.map((p) => ({\n value: p.id,\n label: p.displayName || p.originalPath,\n hint: dim(p.localPath),\n })),\n });\n\n if (isCancel(projectChoice)) return 'cancelled';\n\n const selectedProject = projects.find((p) => p.id === projectChoice)!;\n\n const downloaded = await crossMachinePull(\n client,\n config.deviceId!,\n cwd,\n deviceChoice as string,\n selectedProject.id,\n selectedProject.encodedDir,\n projectsDir,\n options,\n );\n\n if (downloaded === 0 && !options.dryRun) {\n printInfo('No files to download.');\n return 'cancelled';\n }\n\n if (!options.dryRun) {\n await createProjectSymlink(projectsDir, ctx.encodedPath, selectedProject.encodedDir);\n\n await saveProjectLink(cwd, {\n projectId: selectedProject.id,\n foreignEncodedDir: selectedProject.encodedDir,\n linkedAt: new Date().toISOString(),\n });\n\n printSuccess(`${successColor(`+${downloaded}`)} files pulled`);\n printInfo(`Symlink: ${dim(ctx.encodedPath)} → ${dim(selectedProject.encodedDir)}`);\n }\n\n return 'pulled';\n}\n\nasync function createProjectSymlink(projectsDir: string, localEncoded: string, foreignEncoded: string) {\n const symlinkPath = join(projectsDir, localEncoded);\n\n await mkdir(projectsDir, { recursive: true });\n\n try {\n const stats = await lstat(symlinkPath);\n if (stats.isSymbolicLink()) {\n await unlink(symlinkPath);\n } else if (stats.isDirectory()) {\n printError(`Local session directory already exists. Back it up first:\\n mv \"${symlinkPath}\" \"${symlinkPath}.bak\"`);\n return;\n }\n } catch {\n }\n\n await symlink(foreignEncoded, symlinkPath);\n}\n\nasync function crossMachinePull(\n client: ApiClient,\n deviceId: string,\n projectPath: string,\n fromDeviceId: string,\n projectId: string,\n foreignEncodedDir: string,\n projectsDir: string,\n options: { dryRun?: boolean; verbose?: boolean },\n): Promise<number> {\n const spinner = createSpinner('Preparing pull from remote device...').start();\n\n let prepareResponse: PullPrepareResponse;\n try {\n prepareResponse = await client.post<PullPrepareResponse>('/api/sync/pull/prepare', {\n deviceId,\n projectPath,\n fromDeviceId,\n projectId,\n });\n } catch (err) {\n spinner.stop();\n printError(`Pull failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n return 0;\n }\n spinner.stop();\n\n const filesToDownload = prepareResponse.filesToDownload;\n if (filesToDownload.length === 0) return 0;\n\n printInfo(`${brand(String(filesToDownload.length))} files to pull`);\n\n if (options.dryRun) {\n if (options.verbose) {\n for (const entry of filesToDownload) {\n console.log(` ${brand('○')} ${entry.path} ${dim(`(${formatBytes(entry.size)})`)}`);\n }\n }\n return filesToDownload.length;\n }\n\n const targetDir = join(projectsDir, foreignEncodedDir);\n let downloaded = 0;\n\n for (const entry of filesToDownload) {\n const dlSpinner = createSpinner(\n `${formatProgress(downloaded + 1, filesToDownload.length)} ${entry.path}`,\n ).start();\n\n try {\n const urlResponse = await client.post<PresignedUrlResponse>('/api/sync/pull/download-url', {\n syncEventId: prepareResponse.syncEventId,\n key: entry.path,\n });\n\n const response = await fetch(urlResponse.url);\n let data = Buffer.from(await response.arrayBuffer());\n\n if (entry.isCompressed) {\n data = await decompressBuffer(data);\n }\n\n const outputPath = join(targetDir, entry.path);\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, data);\n\n downloaded++;\n } catch {\n }\n dlSpinner.stop();\n }\n\n try {\n await client.post('/api/sync/pull/complete', {\n syncEventId: prepareResponse.syncEventId,\n manifest: filesToDownload,\n });\n } catch {\n }\n\n return downloaded;\n}\n\ninterface PushResult {\n uploaded: number;\n projectId: string;\n failed: boolean;\n}\n\ninterface PullResult {\n downloaded: number;\n failed: boolean;\n}\n\nasync function pushPhase(\n client: ApiClient,\n deviceId: string,\n projectPath: string,\n manifest: ManifestEntry[],\n projectDir: string,\n projectId: string | undefined,\n options: { dryRun?: boolean; verbose?: boolean },\n): Promise<PushResult> {\n const spinner = createSpinner('Preparing push...').start();\n\n let prepareResponse: PushPrepareResponse;\n try {\n prepareResponse = await client.post<PushPrepareResponse>('/api/sync/push/prepare', {\n deviceId,\n projectPath,\n projectId,\n manifest,\n });\n } catch (err) {\n spinner.stop();\n printError(`Push failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n return { uploaded: 0, projectId: projectId || '', failed: true };\n }\n spinner.stop();\n\n const resolvedProjectId = prepareResponse.projectId;\n const filesToUpload = prepareResponse.filesToUpload;\n if (filesToUpload.length === 0) return { uploaded: 0, projectId: resolvedProjectId, failed: false };\n\n printInfo(`${brand(String(filesToUpload.length))} files to push`);\n\n if (options.dryRun) {\n if (options.verbose) {\n for (const entry of filesToUpload) {\n console.log(` ${successColor('+')} ${entry.path} ${dim(`(${formatBytes(entry.size)})`)}`);\n }\n }\n return { uploaded: filesToUpload.length, projectId: resolvedProjectId, failed: false };\n }\n\n let uploaded = 0;\n for (const entry of filesToUpload) {\n const uploadSpinner = createSpinner(\n `${formatProgress(uploaded + 1, filesToUpload.length)} ${entry.path}`,\n ).start();\n\n try {\n const urlResponse = await client.post<PresignedUrlResponse>('/api/sync/push/upload-url', {\n syncEventId: prepareResponse.syncEventId,\n key: entry.path,\n });\n\n const filePath = join(projectDir, entry.path);\n let body: Buffer = await readFile(filePath);\n\n if (entry.isCompressed) {\n body = await compressBuffer(body);\n }\n\n await fetch(urlResponse.url, {\n method: 'PUT',\n body,\n headers: { 'Content-Type': 'application/octet-stream' },\n });\n\n uploaded++;\n } catch {\n }\n uploadSpinner.stop();\n }\n\n try {\n await client.post('/api/sync/push/complete', {\n syncEventId: prepareResponse.syncEventId,\n manifest,\n });\n } catch {\n }\n\n return { uploaded, projectId: resolvedProjectId, failed: false };\n}\n\nasync function pullPhase(\n client: ApiClient,\n deviceId: string,\n projectPath: string,\n projectDir: string,\n projectId: string | undefined,\n options: { dryRun?: boolean; verbose?: boolean },\n): Promise<PullResult> {\n const spinner = createSpinner('Preparing pull...').start();\n\n let prepareResponse: PullPrepareResponse;\n try {\n prepareResponse = await client.post<PullPrepareResponse>('/api/sync/pull/prepare', {\n deviceId,\n projectPath,\n projectId,\n });\n } catch (err) {\n spinner.stop();\n printError(`Pull failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n return { downloaded: 0, failed: true };\n }\n spinner.stop();\n\n const filesToDownload = prepareResponse.filesToDownload;\n if (filesToDownload.length === 0) return { downloaded: 0, failed: false };\n\n printInfo(`${brand(String(filesToDownload.length))} files to pull`);\n\n if (options.dryRun) {\n if (options.verbose) {\n for (const entry of filesToDownload) {\n console.log(` ${brand('○')} ${entry.path} ${dim(`(${formatBytes(entry.size)})`)}`);\n }\n }\n return { downloaded: filesToDownload.length, failed: false };\n }\n\n let downloaded = 0;\n for (const entry of filesToDownload) {\n const dlSpinner = createSpinner(\n `${formatProgress(downloaded + 1, filesToDownload.length)} ${entry.path}`,\n ).start();\n\n try {\n const urlResponse = await client.post<PresignedUrlResponse>('/api/sync/pull/download-url', {\n syncEventId: prepareResponse.syncEventId,\n key: entry.path,\n });\n\n const response = await fetch(urlResponse.url);\n let data = Buffer.from(await response.arrayBuffer());\n\n if (entry.isCompressed) {\n data = await decompressBuffer(data);\n }\n\n const outputPath = join(projectDir, entry.path);\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, data);\n\n downloaded++;\n } catch {\n }\n dlSpinner.stop();\n }\n\n try {\n await client.post('/api/sync/pull/complete', {\n syncEventId: prepareResponse.syncEventId,\n manifest: filesToDownload,\n });\n } catch {\n }\n\n return { downloaded, failed: false };\n}\n\nexport function syncCommand(): Command {\n return new Command('sync')\n .description('Sync current project sessions with cloud')\n .option('--dry-run', 'Show what would be synced without syncing')\n .option('--verbose', 'Show detailed output')\n .action(async (options) => {\n await runSync(options);\n });\n}\n","import { Command } from 'commander';\nimport { loadConfig, loadProjectManifest, isAuthenticated } from '../lib/config.js';\nimport { buildProjectManifest, computeDiff, resolveProjectState } from '../lib/sync-engine.js';\nimport { createSpinner, formatBytes } from '../lib/progress.js';\nimport { printIntro, printLabel, printDivider, printInfo, brand, success as successColor, warn as warnColor, error as errorColor, dim } from '../lib/theme.js';\n\nexport function statusCommand(): Command {\n return new Command('status')\n .description('Show sync status for current project')\n .action(async () => {\n printIntro('Status');\n\n const config = await loadConfig();\n const cwd = process.cwd();\n\n printLabel('API', config.apiUrl);\n printLabel('Authenticated', isAuthenticated(config) ? successColor('yes') : errorColor('no'));\n printLabel('Device', config.deviceName || dim('none'));\n printLabel('Project', brand(cwd));\n\n const ctx = await resolveProjectState(cwd);\n printLabel('State', ctx.state === 'none' ? dim('no session data') : ctx.state === 'symlink' ? `symlink → ${dim(ctx.symlinkTarget || 'unknown')}` : 'local');\n\n if (!isAuthenticated(config) || ctx.state === 'none') return;\n\n const spinner = createSpinner('Scanning files...').start();\n const savedManifest = await loadProjectManifest(cwd);\n const currentManifest = await buildProjectManifest(cwd);\n const diff = computeDiff(currentManifest, savedManifest);\n spinner.stop();\n\n const totalSize = currentManifest.reduce((sum, e) => sum + e.size, 0);\n\n printDivider();\n printLabel('Local files', `${brand(String(currentManifest.length))} ${dim(`(${formatBytes(totalSize)})`)}`);\n console.log();\n printInfo('Changes since last sync:');\n console.log(` ${successColor(`+${diff.added.length}`)} added ${warnColor(`~${diff.modified.length}`)} modified ${errorColor(`-${diff.deleted.length}`)} deleted`);\n console.log();\n });\n}\n","import { Command } from 'commander';\nimport type { User } from '@claude-sync/types';\nimport { loadConfig, isAuthenticated } from '../lib/config.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { createSpinner } from '../lib/progress.js';\nimport { printIntro, printLabel, printError, printDivider, brand, dim } from '../lib/theme.js';\n\nexport function whoamiCommand(): Command {\n return new Command('whoami')\n .description('Show current user and device info')\n .action(async () => {\n printIntro('Who Am I');\n\n const config = await loadConfig();\n\n if (!isAuthenticated(config)) {\n printError('Not logged in. Run `claude-sync login` first.');\n return;\n }\n\n const client = new ApiClient(config.apiUrl);\n const spinner = createSpinner('Fetching user info...').start();\n\n try {\n const user = await client.get<User>('/api/auth/me');\n spinner.stop();\n printLabel('User', `${user.name} ${dim(`(${user.email})`)}`);\n printLabel('Plan', brand(user.plan));\n printDivider();\n printLabel('Device', config.deviceName || dim('none'));\n printLabel('Device ID', config.deviceId || dim('not registered'));\n } catch {\n spinner.stop();\n printLabel('Email', config.email || dim('unknown'));\n printLabel('Device', config.deviceName || dim('none'));\n }\n\n console.log();\n });\n}\n","import { Command } from 'commander';\n\nimport { loginCommand } from './commands/login.js';\nimport { logoutCommand } from './commands/logout.js';\nimport { deviceCommand } from './commands/device.js';\nimport { syncCommand, runSync } from './commands/sync.js';\nimport { statusCommand } from './commands/status.js';\nimport { whoamiCommand } from './commands/whoami.js';\nimport { runTui } from './commands/tui.js';\nimport { loadConfig, isAuthenticated } from './lib/config.js';\n\nexport function run() {\n const program = new Command();\n\n program\n .name('claude-sync')\n .description('Sync Claude Code sessions across machines — claude-sync.com')\n .version('0.1.0')\n .option('--menu', 'Open interactive menu')\n .action(async (options) => {\n if (options.menu) {\n await runTui();\n return;\n }\n\n const config = await loadConfig();\n if (isAuthenticated(config) && config.deviceId) {\n await runSync({});\n } else {\n await runTui();\n }\n });\n\n program.addCommand(loginCommand());\n program.addCommand(logoutCommand());\n program.addCommand(deviceCommand());\n program.addCommand(syncCommand());\n program.addCommand(statusCommand());\n program.addCommand(whoamiCommand());\n\n program.parse();\n}\n","import { select, isCancel } from '@clack/prompts';\nimport chalk from 'chalk';\nimport { printBanner, printOutro, brand, dim } from '../lib/theme.js';\nimport { loadConfig, isAuthenticated } from '../lib/config.js';\n\ninterface MenuOption {\n value: string;\n label: string;\n hint?: string;\n}\n\nfunction buildMenu(loggedIn: boolean): MenuOption[] {\n if (!loggedIn) {\n return [\n { value: 'login', label: 'Login', hint: 'Authenticate with claude-sync' },\n ];\n }\n\n return [\n { value: 'sync', label: 'Sync', hint: 'Sync current project' },\n { value: 'status', label: 'Status', hint: 'Show sync state' },\n { value: 'device:add', label: 'Add Device', hint: 'Register this machine' },\n { value: 'device:list', label: 'List Devices', hint: 'Show registered devices' },\n { value: 'device:remove', label: 'Remove Device' },\n { value: 'device:rename', label: 'Rename Device' },\n { value: 'whoami', label: 'Who Am I', hint: 'Current user and device' },\n { value: 'logout', label: 'Logout', hint: 'Sign out' },\n ];\n}\n\nexport async function runTui() {\n printBanner();\n\n const config = await loadConfig();\n const loggedIn = isAuthenticated(config);\n\n if (loggedIn) {\n console.log(` ${dim('user')} ${brand(config.email || 'unknown')}`);\n if (config.deviceName) {\n console.log(` ${dim('device')} ${brand(config.deviceName)}`);\n }\n console.log();\n } else {\n console.log(` ${dim('Not logged in')}`);\n console.log();\n }\n\n while (true) {\n const items = buildMenu(loggedIn);\n\n const options = [\n ...items.map((o) => ({\n value: o.value,\n label: o.label,\n hint: o.hint ? dim(o.hint) : undefined,\n })),\n { value: 'quit', label: chalk.red('Quit') },\n ];\n\n const choice = await select({\n message: brand('What would you like to do?'),\n options,\n });\n\n if (isCancel(choice) || choice === 'quit') {\n printOutro('Goodbye!');\n return;\n }\n\n await executeCommand(choice as string);\n\n console.log();\n }\n}\n\nasync function executeCommand(command: string) {\n const { loginCommand } = await import('./login.js');\n const { logoutCommand } = await import('./logout.js');\n const { deviceCommand } = await import('./device.js');\n const { syncCommand } = await import('./sync.js');\n const { statusCommand } = await import('./status.js');\n const { whoamiCommand } = await import('./whoami.js');\n\n const handlers: Record<string, () => Promise<void>> = {\n login: () => loginCommand().parseAsync(['', '', 'login']),\n logout: () => logoutCommand().parseAsync(['', '', 'logout']),\n sync: () => syncCommand().parseAsync(['', '', 'sync']),\n status: () => statusCommand().parseAsync(['', '', 'status']),\n whoami: () => whoamiCommand().parseAsync(['', '', 'whoami']),\n 'device:add': () => deviceCommand().parseAsync(['', '', 'device', 'add']),\n 'device:list': () => deviceCommand().parseAsync(['', '', 'device', 'list']),\n 'device:remove': () => deviceCommand().parseAsync(['', '', 'device', 'remove']),\n 'device:rename': () => deviceCommand().parseAsync(['', '', 'device', 'rename']),\n };\n\n const handler = handlers[command];\n if (handler) {\n try {\n await handler();\n } catch {\n }\n }\n}\n","#!/usr/bin/env node\nimport { run } from '../src/index.js';\n\nrun();\n"],"mappings":"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","names":["error","text","chalk","Command","Command","homedir","text","isCancel","join","homedir","encodePath","Command","select","isCancel","readFile","writeFile","mkdir","lstat","join","dirname","homedir","CLAUDE_DIR","PROJECTS_DIR","finalManifest","Command","Command","Command","select","isCancel","chalk","loginCommand","logoutCommand","deviceCommand","syncCommand","statusCommand","whoamiCommand","Command"]}
|
package/dist/src/index.js
CHANGED
|
@@ -1272,7 +1272,7 @@ async function executeCommand(command) {
|
|
|
1272
1272
|
init_config();
|
|
1273
1273
|
function run() {
|
|
1274
1274
|
const program = new Command7();
|
|
1275
|
-
program.name("claude-sync").description("Sync Claude Code sessions across machines").version("0.1.0").option("--menu", "Open interactive menu").action(async (options) => {
|
|
1275
|
+
program.name("claude-sync").description("Sync Claude Code sessions across machines \u2014 claude-sync.com").version("0.1.0").option("--menu", "Open interactive menu").action(async (options) => {
|
|
1276
1276
|
if (options.menu) {
|
|
1277
1277
|
await runTui();
|
|
1278
1278
|
return;
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/config.ts","../../src/lib/api-client.ts","../../src/lib/auth.ts","../../src/lib/progress.ts","../../src/lib/theme.ts","../../src/commands/login.ts","../../src/commands/logout.ts","../../src/commands/device.ts","../../src/lib/sync-engine.ts","../../src/lib/compress.ts","../../src/commands/sync.ts","../../src/commands/status.ts","../../src/commands/whoami.ts","../../src/index.ts","../../src/commands/tui.ts"],"sourcesContent":["import { join, dirname } from 'node:path';\nimport { homedir } from 'node:os';\nimport { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport { CONFIG_DIR, CONFIG_FILE, MANIFEST_FILE, encodePath } from '@claude-sync/utils';\n\nexport interface CliConfig {\n apiUrl: string;\n accessToken: string | null;\n refreshToken: string | null;\n deviceId: string | null;\n deviceName: string | null;\n userId: string | null;\n email: string | null;\n}\n\nconst DEFAULT_CONFIG: CliConfig = {\n apiUrl: 'https://api.claude-sync.com',\n accessToken: null,\n refreshToken: null,\n deviceId: null,\n deviceName: null,\n userId: null,\n email: null,\n};\n\nfunction getConfigDir(): string {\n return join(homedir(), CONFIG_DIR);\n}\n\nfunction getConfigPath(): string {\n return join(getConfigDir(), CONFIG_FILE);\n}\n\nfunction getManifestPath(): string {\n return join(getConfigDir(), MANIFEST_FILE);\n}\n\nexport async function loadConfig(): Promise<CliConfig> {\n try {\n const content = await readFile(getConfigPath(), 'utf-8');\n return { ...DEFAULT_CONFIG, ...JSON.parse(content) };\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n}\n\nexport async function saveConfig(config: Partial<CliConfig>): Promise<void> {\n const existing = await loadConfig();\n const merged = { ...existing, ...config };\n await mkdir(getConfigDir(), { recursive: true });\n await writeFile(getConfigPath(), JSON.stringify(merged, null, 2));\n}\n\nexport async function clearConfig(): Promise<void> {\n await saveConfig(DEFAULT_CONFIG);\n}\n\nexport async function loadManifest(): Promise<import('@claude-sync/types').ManifestEntry[]> {\n try {\n const content = await readFile(getManifestPath(), 'utf-8');\n return JSON.parse(content);\n } catch {\n return [];\n }\n}\n\nexport async function saveManifest(entries: import('@claude-sync/types').ManifestEntry[]): Promise<void> {\n await mkdir(getConfigDir(), { recursive: true });\n await writeFile(getManifestPath(), JSON.stringify(entries, null, 2));\n}\n\nexport async function loadProjectManifest(projectPath: string): Promise<import('@claude-sync/types').ManifestEntry[]> {\n try {\n const encoded = encodePath(projectPath);\n const manifestPath = join(getConfigDir(), 'manifests', `${encoded}.json`);\n const content = await readFile(manifestPath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return [];\n }\n}\n\nexport async function saveProjectManifest(projectPath: string, entries: import('@claude-sync/types').ManifestEntry[]): Promise<void> {\n const encoded = encodePath(projectPath);\n const manifestPath = join(getConfigDir(), 'manifests', `${encoded}.json`);\n await mkdir(dirname(manifestPath), { recursive: true });\n await writeFile(manifestPath, JSON.stringify(entries, null, 2));\n}\n\nexport function isAuthenticated(config: CliConfig): boolean {\n return config.accessToken !== null;\n}\n\nexport interface ProjectLink {\n projectId: string;\n foreignEncodedDir: string;\n linkedAt: string;\n}\n\nexport async function loadProjectLink(projectPath: string): Promise<ProjectLink | null> {\n try {\n const encoded = encodePath(projectPath);\n const linkPath = join(getConfigDir(), 'project-links', `${encoded}.json`);\n const content = await readFile(linkPath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\nexport async function saveProjectLink(projectPath: string, link: ProjectLink): Promise<void> {\n const encoded = encodePath(projectPath);\n const linkPath = join(getConfigDir(), 'project-links', `${encoded}.json`);\n await mkdir(dirname(linkPath), { recursive: true });\n await writeFile(linkPath, JSON.stringify(link, null, 2));\n}\n","import type { ApiErrorResponse } from '@claude-sync/types';\nimport { getValidToken } from './auth.js';\n\nexport class ApiClient {\n private baseUrl: string;\n\n constructor(baseUrl: string) {\n this.baseUrl = baseUrl.replace(/\\/$/, '');\n }\n\n private async rawRequest<T>(path: string, options: RequestInit = {}): Promise<T> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 15000);\n\n let response: Response;\n try {\n response = await fetch(`${this.baseUrl}${path}`, {\n ...options,\n signal: controller.signal,\n });\n } catch (err) {\n clearTimeout(timeout);\n if (err instanceof Error && err.name === 'AbortError') {\n throw new Error('Request timed out. Is the API server running?');\n }\n throw err;\n }\n clearTimeout(timeout);\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error('Session expired. Run `claude-sync login` to re-authenticate.');\n }\n const error: ApiErrorResponse = await response.json().catch(() => ({\n statusCode: response.status,\n message: response.statusText,\n error: 'Request failed',\n }));\n throw new Error(error.message);\n }\n\n const json = await response.json();\n return (json.data !== undefined ? json.data : json) as T;\n }\n\n async request<T>(path: string, options: RequestInit = {}): Promise<T> {\n const token = await getValidToken();\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(options.headers as Record<string, string>),\n };\n\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n return this.rawRequest<T>(path, { ...options, headers });\n }\n\n async requestNoAuth<T>(path: string, options: RequestInit = {}): Promise<T> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(options.headers as Record<string, string>),\n };\n\n return this.rawRequest<T>(path, { ...options, headers });\n }\n\n async get<T>(path: string): Promise<T> {\n return this.request<T>(path, { method: 'GET' });\n }\n\n async post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(path, {\n method: 'POST',\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n async patch<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(path, {\n method: 'PATCH',\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n async delete<T>(path: string): Promise<T> {\n return this.request<T>(path, { method: 'DELETE' });\n }\n}\n","import type { TokenPair } from '@claude-sync/types';\nimport { loadConfig, saveConfig } from './config.js';\nimport { ApiClient } from './api-client.js';\n\nexport async function storeTokens(tokens: TokenPair, userId: string, email: string): Promise<void> {\n await saveConfig({\n accessToken: tokens.accessToken,\n refreshToken: tokens.refreshToken,\n userId,\n email,\n });\n}\n\nexport async function refreshAccessToken(): Promise<string | null> {\n const config = await loadConfig();\n if (!config.refreshToken) return null;\n\n const client = new ApiClient(config.apiUrl);\n try {\n const response = await client.requestNoAuth<TokenPair>('/api/auth/refresh', {\n method: 'POST',\n body: JSON.stringify({ refreshToken: config.refreshToken }),\n });\n await saveConfig({\n accessToken: response.accessToken,\n refreshToken: response.refreshToken,\n });\n return response.accessToken;\n } catch {\n return null;\n }\n}\n\nexport async function getValidToken(): Promise<string | null> {\n const config = await loadConfig();\n if (!config.accessToken) return null;\n\n try {\n const payload = JSON.parse(\n Buffer.from(config.accessToken.split('.')[1], 'base64').toString()\n );\n if (payload.exp * 1000 > Date.now()) {\n return config.accessToken;\n }\n } catch {\n }\n\n return refreshAccessToken();\n}\n","import ora, { type Ora } from 'ora';\nimport chalk from 'chalk';\n\nconst brandColor = chalk.hex('#8a8cdd');\n\nexport function createSpinner(text: string): Ora {\n return ora({ text: brandColor(text), spinner: 'dots', color: 'magenta' });\n}\n\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) return '0 B';\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;\n}\n\nexport function formatProgress(current: number, total: number): string {\n const percentage = total > 0 ? Math.round((current / total) * 100) : 0;\n return `${current}/${total} (${percentage}%)`;\n}\n","import chalk from 'chalk';\n\nconst BRAND_HEX = '#8a8cdd';\nconst BRAND_DIM_HEX = '#6b6db8';\nconst SUCCESS_HEX = '#8adda0';\nconst WARN_HEX = '#ddcc8a';\nconst ERROR_HEX = '#dd8a8a';\n\nexport const brand = chalk.hex(BRAND_HEX);\nexport const brandBold = chalk.hex(BRAND_HEX).bold;\nexport const brandDim = chalk.hex(BRAND_DIM_HEX);\nexport const success = chalk.hex(SUCCESS_HEX);\nexport const successBold = chalk.hex(SUCCESS_HEX).bold;\nexport const warn = chalk.hex(WARN_HEX);\nexport const error = chalk.hex(ERROR_HEX);\nexport const errorBold = chalk.hex(ERROR_HEX).bold;\nexport const dim = chalk.dim;\nexport const bold = chalk.bold;\nexport const white = chalk.white;\n\nexport function printBanner() {\n console.log();\n console.log(` ${brandBold('claude-sync')} ${dim('v0.1.0')}`);\n console.log();\n}\n\nexport function printIntro(title: string) {\n console.log();\n console.log(` ${brandBold(title)}`);\n console.log();\n}\n\nexport function printOutro(message: string) {\n console.log();\n console.log(` ${dim(message)}`);\n console.log();\n}\n\nexport function printSuccess(message: string) {\n console.log(` ${success('✔')} ${message}`);\n}\n\nexport function printError(message: string) {\n console.log(` ${error('✖')} ${message}`);\n}\n\nexport function printWarn(message: string) {\n console.log(` ${warn('▲')} ${message}`);\n}\n\nexport function printInfo(message: string) {\n console.log(` ${brand('●')} ${message}`);\n}\n\nexport function printLabel(label: string, value: string) {\n console.log(` ${dim(label.padEnd(14))} ${white(value)}`);\n}\n\nexport function printDivider() {\n console.log();\n}\n","import { Command } from 'commander';\nimport { text, password as passwordPrompt, select, isCancel } from '@clack/prompts';\nimport type { TokenPair, CliInitiateResponse, CliPollResponse } from '@claude-sync/types';\nimport { loadConfig } from '../lib/config.js';\nimport { storeTokens } from '../lib/auth.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { createSpinner } from '../lib/progress.js';\nimport { printIntro, printOutro, printInfo, printSuccess, printError, brand, brandBold, dim } from '../lib/theme.js';\n\nasync function loginWithBrowser(client: ApiClient): Promise<void> {\n const response = await client.requestNoAuth<CliInitiateResponse>('/api/auth/cli/initiate', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n });\n\n printInfo(`Open this URL in your browser:\\n ${brandBold(response.verifyUrl)}`);\n printInfo(`Code: ${brandBold(response.code)}`);\n\n const spinner = createSpinner('Waiting for browser authorization...').start();\n\n const pollInterval = 2000;\n const maxAttempts = 150;\n let attempts = 0;\n\n while (attempts < maxAttempts) {\n await new Promise((resolve) => setTimeout(resolve, pollInterval));\n attempts++;\n\n try {\n const pollResponse = await client.requestNoAuth<CliPollResponse>('/api/auth/cli/poll', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ code: response.code }),\n });\n\n if (pollResponse.status === 'authorized' && pollResponse.tokenPair && pollResponse.user) {\n spinner.stop();\n await storeTokens(pollResponse.tokenPair, pollResponse.user.id, pollResponse.user.email);\n printSuccess(`Logged in as ${brandBold(pollResponse.user.email)}`);\n return;\n }\n\n if (pollResponse.status === 'expired') {\n spinner.stop();\n printError('Authorization code expired. Please try again.');\n process.exit(1);\n }\n } catch {\n }\n }\n\n spinner.stop();\n printError('Authorization timed out. Please try again.');\n process.exit(1);\n}\n\nasync function loginWithEmail(client: ApiClient): Promise<void> {\n const email = await text({ message: `${brand('Email')}:` });\n if (isCancel(email)) process.exit(0);\n\n const password = await passwordPrompt({ message: `${brand('Password')}:` });\n if (isCancel(password)) process.exit(0);\n\n const spinner = createSpinner('Logging in...').start();\n\n try {\n const response = await client.requestNoAuth<TokenPair & { user: { id: string; email: string } }>(\n '/api/auth/login',\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email, password }),\n },\n );\n spinner.stop();\n await storeTokens(\n { accessToken: response.accessToken, refreshToken: response.refreshToken, expiresIn: 900 },\n response.user.id,\n response.user.email\n );\n printSuccess(`Logged in as ${brandBold(response.user.email)}`);\n } catch (err) {\n spinner.stop();\n printError(`Login failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n}\n\nexport function loginCommand(): Command {\n return new Command('login')\n .description('Authenticate with claude-sync')\n .action(async () => {\n printIntro('Login');\n\n const config = await loadConfig();\n const client = new ApiClient(config.apiUrl);\n\n const method = await select({\n message: `${brand('How would you like to log in?')}`,\n options: [\n { value: 'browser', label: `${brand('○')} Browser ${dim('(recommended)')}` },\n { value: 'email', label: `${brand('○')} Email & password` },\n ],\n });\n\n if (isCancel(method)) process.exit(0);\n\n if (method === 'browser') {\n await loginWithBrowser(client);\n } else {\n await loginWithEmail(client);\n }\n\n printOutro('Authentication complete');\n });\n}\n","import { Command } from 'commander';\nimport { loadConfig, clearConfig } from '../lib/config.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { printIntro, printOutro, printInfo, printSuccess } from '../lib/theme.js';\n\nexport function logoutCommand(): Command {\n return new Command('logout')\n .description('Log out and revoke tokens')\n .action(async () => {\n printIntro('Logout');\n\n const config = await loadConfig();\n if (!config.accessToken) {\n printInfo('Not currently logged in.');\n printOutro('Done');\n return;\n }\n\n try {\n const client = new ApiClient(config.apiUrl);\n await client.post('/api/auth/logout', {\n refreshToken: config.refreshToken,\n });\n } catch {\n }\n\n await clearConfig();\n printSuccess('Logged out successfully.');\n printOutro('Done');\n });\n}\n","import { Command } from 'commander';\nimport { hostname, platform, arch, homedir } from 'node:os';\nimport { text, isCancel } from '@clack/prompts';\nimport type { Device } from '@claude-sync/types';\nimport { loadConfig, saveConfig, isAuthenticated } from '../lib/config.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { createSpinner } from '../lib/progress.js';\nimport { printIntro, printOutro, printSuccess, printError, printInfo, printLabel, printDivider, brand, brandBold, dim, success, error as errorColor, white } from '../lib/theme.js';\n\nfunction requireAuth(config: Awaited<ReturnType<typeof loadConfig>>): void {\n if (!isAuthenticated(config)) {\n printError('Not logged in. Run `claude-sync login` first.');\n process.exit(1);\n }\n}\n\nexport function deviceCommand(): Command {\n const device = new Command('device').description('Manage devices');\n\n device\n .command('add')\n .argument('[name]', 'Device name')\n .description('Register this machine as a device')\n .action(async (name?: string) => {\n printIntro('Device Add');\n\n const config = await loadConfig();\n requireAuth(config);\n\n const deviceName = name || await (async () => {\n const input = await text({ message: `${brand('Device name')}:`, initialValue: hostname() });\n if (isCancel(input)) process.exit(0);\n return input;\n })();\n\n const spinner = createSpinner('Registering device...').start();\n const client = new ApiClient(config.apiUrl);\n\n try {\n const response = await client.post<Device>('/api/devices', {\n name: deviceName,\n hostname: hostname(),\n platform: platform(),\n homeDir: homedir(),\n arch: arch(),\n });\n\n await saveConfig({\n deviceId: response.id,\n deviceName: response.name,\n });\n\n spinner.stop();\n printSuccess(`Device ${brandBold(`\"${response.name}\"`)} registered`);\n printLabel('ID', response.id);\n } catch (err) {\n spinner.stop();\n printError(`Failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n\n printOutro('Done');\n });\n\n device\n .command('list')\n .description('List all registered devices')\n .action(async () => {\n printIntro('Devices');\n\n const config = await loadConfig();\n requireAuth(config);\n\n const client = new ApiClient(config.apiUrl);\n const spinner = createSpinner('Fetching devices...').start();\n\n try {\n const devices = await client.get<Device[]>('/api/devices');\n spinner.stop();\n\n if (devices.length === 0) {\n printInfo('No devices registered.');\n return;\n }\n\n console.log();\n for (const d of devices) {\n const current = d.id === config.deviceId ? ` ${brandBold('(current)')}` : '';\n const active = d.isActive ? success('active') : errorColor('inactive');\n console.log(` ${brand('○')} ${white(d.name)}${current}`);\n console.log(` ${dim(d.platform)} ${dim('·')} ${active} ${dim('·')} ${dim(d.id)}`);\n }\n console.log();\n } catch (err) {\n spinner.stop();\n printError(`Failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n });\n\n device\n .command('remove')\n .argument('<nameOrId>', 'Device name or ID')\n .description('Remove a device')\n .action(async (nameOrId: string) => {\n const config = await loadConfig();\n requireAuth(config);\n\n const client = new ApiClient(config.apiUrl);\n const spinner = createSpinner('Removing device...').start();\n\n try {\n await client.delete(`/api/devices/${nameOrId}`);\n spinner.stop();\n\n if (config.deviceId === nameOrId) {\n await saveConfig({ deviceId: null, deviceName: null });\n }\n\n printSuccess('Device removed.');\n } catch (err) {\n spinner.stop();\n printError(`Failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n });\n\n device\n .command('rename')\n .argument('<name>', 'New name')\n .description('Rename the current device')\n .action(async (name: string) => {\n const config = await loadConfig();\n requireAuth(config);\n\n if (!config.deviceId) {\n printError('No device registered. Run `claude-sync device add` first.');\n process.exit(1);\n }\n\n const client = new ApiClient(config.apiUrl);\n const spinner = createSpinner('Renaming device...').start();\n\n try {\n const response = await client.patch<Device>(`/api/devices/${config.deviceId}`, { name });\n await saveConfig({ deviceName: response.name });\n spinner.stop();\n printSuccess(`Device renamed to ${brandBold(`\"${response.name}\"`)}`);\n } catch (err) {\n spinner.stop();\n printError(`Failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n });\n\n return device;\n}\n","import { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { readdir, stat, lstat, readlink } from 'node:fs/promises';\nimport type { ManifestEntry, ManifestDiff } from '@claude-sync/types';\nimport { hashFile, diffManifests, encodePath, CLAUDE_DIR, PROJECTS_DIR, SYNC_EXCLUDE_PATTERNS } from '@claude-sync/utils';\n\nfunction shouldExclude(name: string): boolean {\n return SYNC_EXCLUDE_PATTERNS.some((pattern) => {\n if (pattern.startsWith('*')) {\n return name.endsWith(pattern.slice(1));\n }\n return name === pattern;\n });\n}\n\nasync function walkDirectory(dir: string, basePath: string = ''): Promise<ManifestEntry[]> {\n const entries: ManifestEntry[] = [];\n const items = await readdir(dir, { withFileTypes: true });\n\n for (const item of items) {\n if (shouldExclude(item.name)) continue;\n\n const fullPath = join(dir, item.name);\n const relativePath = basePath ? `${basePath}/${item.name}` : item.name;\n\n if (item.isDirectory()) {\n const subEntries = await walkDirectory(fullPath, relativePath);\n entries.push(...subEntries);\n } else if (item.isFile()) {\n const fileStat = await stat(fullPath);\n const hash = await hashFile(fullPath);\n const isText = !isBinaryPath(item.name);\n entries.push({\n path: relativePath,\n hash,\n size: fileStat.size,\n modifiedAt: fileStat.mtime.toISOString(),\n isCompressed: isText,\n });\n }\n }\n\n return entries;\n}\n\nfunction isBinaryPath(name: string): boolean {\n const binaryExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.ico', '.pdf', '.zip', '.gz', '.tar'];\n return binaryExtensions.some((ext) => name.endsWith(ext));\n}\n\nexport async function buildManifest(): Promise<ManifestEntry[]> {\n const claudeDir = join(homedir(), CLAUDE_DIR);\n return walkDirectory(claudeDir);\n}\n\nexport type ProjectState = 'none' | 'real' | 'symlink';\n\nexport interface ProjectContext {\n cwd: string;\n encodedPath: string;\n projectDir: string;\n state: ProjectState;\n symlinkTarget?: string;\n}\n\nexport async function resolveProjectState(cwd: string): Promise<ProjectContext> {\n const projectsDir = join(homedir(), CLAUDE_DIR, PROJECTS_DIR);\n const encoded = encodePath(cwd);\n const projectDir = join(projectsDir, encoded);\n\n let state: ProjectState = 'none';\n let symlinkTarget: string | undefined;\n\n try {\n const stats = await lstat(projectDir);\n if (stats.isSymbolicLink()) {\n state = 'symlink';\n symlinkTarget = await readlink(projectDir);\n } else if (stats.isDirectory()) {\n state = 'real';\n }\n } catch {\n state = 'none';\n }\n\n return { cwd, encodedPath: encoded, projectDir, state, symlinkTarget };\n}\n\nexport async function buildProjectManifest(cwd: string): Promise<ManifestEntry[]> {\n const ctx = await resolveProjectState(cwd);\n\n if (ctx.state === 'none') return [];\n\n const projectsDir = join(homedir(), CLAUDE_DIR, PROJECTS_DIR);\n let targetDir = ctx.projectDir;\n\n if (ctx.state === 'symlink' && ctx.symlinkTarget) {\n targetDir = join(projectsDir, ctx.symlinkTarget);\n }\n\n try {\n return await walkDirectory(targetDir);\n } catch {\n return [];\n }\n}\n\nexport function computeDiff(local: ManifestEntry[], remote: ManifestEntry[]): ManifestDiff {\n return diffManifests(local, remote);\n}\n","import { createGzip, createGunzip } from 'node:zlib';\nimport { createReadStream, createWriteStream } from 'node:fs';\nimport { pipeline } from 'node:stream/promises';\n\nexport async function compressFile(inputPath: string, outputPath: string): Promise<void> {\n const source = createReadStream(inputPath);\n const destination = createWriteStream(outputPath);\n const gzip = createGzip();\n await pipeline(source, gzip, destination);\n}\n\nexport async function decompressFile(inputPath: string, outputPath: string): Promise<void> {\n const source = createReadStream(inputPath);\n const destination = createWriteStream(outputPath);\n const gunzip = createGunzip();\n await pipeline(source, gunzip, destination);\n}\n\nexport function compressBuffer(data: Buffer): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const gzip = createGzip();\n const chunks: Buffer[] = [];\n gzip.on('data', (chunk: Buffer) => chunks.push(chunk));\n gzip.on('end', () => resolve(Buffer.concat(chunks)));\n gzip.on('error', reject);\n gzip.end(data);\n });\n}\n\nexport function decompressBuffer(data: Buffer): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const gunzip = createGunzip();\n const chunks: Buffer[] = [];\n gunzip.on('data', (chunk: Buffer) => chunks.push(chunk));\n gunzip.on('end', () => resolve(Buffer.concat(chunks)));\n gunzip.on('error', reject);\n gunzip.end(data);\n });\n}\n","import { Command } from 'commander';\nimport { select, isCancel } from '@clack/prompts';\nimport type { PushPrepareResponse, PullPrepareResponse, PresignedUrlResponse } from '@claude-sync/types';\nimport type { ManifestEntry } from '@claude-sync/types';\nimport { loadConfig, saveProjectManifest, isAuthenticated, loadProjectLink, saveProjectLink } from '../lib/config.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { resolveProjectState, buildProjectManifest } from '../lib/sync-engine.js';\nimport { createSpinner, formatBytes, formatProgress } from '../lib/progress.js';\nimport { compressBuffer, decompressBuffer } from '../lib/compress.js';\nimport { readFile, writeFile, mkdir, lstat, symlink, unlink } from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { homedir } from 'node:os';\nimport { CLAUDE_DIR, PROJECTS_DIR } from '@claude-sync/utils';\nimport { printIntro, printOutro, printInfo, printSuccess, printError, brand, success as successColor, dim } from '../lib/theme.js';\nimport type { CliConfig } from '../lib/config.js';\nimport type { ProjectContext } from '../lib/sync-engine.js';\n\ninterface DeviceProject {\n id: string;\n displayName: string;\n originalPath: string;\n canonicalPath: string;\n encodedDir: string;\n localPath: string;\n}\n\ninterface DeviceInfo {\n id: string;\n name: string;\n hostname: string;\n platform: string;\n}\n\nexport async function runSync(options: { dryRun?: boolean; verbose?: boolean }) {\n printIntro('Sync');\n\n const config = await loadConfig();\n if (!isAuthenticated(config)) {\n printError('Not logged in. Run `claude-sync login` first.');\n return;\n }\n if (!config.deviceId) {\n printError('No device registered. Run `claude-sync device add` first.');\n return;\n }\n\n const cwd = process.cwd();\n const ctx = await resolveProjectState(cwd);\n const client = new ApiClient(config.apiUrl);\n const projectsDir = join(homedir(), CLAUDE_DIR, PROJECTS_DIR);\n const projectLink = await loadProjectLink(cwd);\n\n let projectDir = ctx.projectDir;\n if (ctx.state === 'symlink' && ctx.symlinkTarget) {\n projectDir = join(projectsDir, ctx.symlinkTarget);\n }\n\n printInfo(`Project: ${brand(cwd)}`);\n if (ctx.state === 'symlink') {\n printInfo(`Linked to: ${dim(ctx.symlinkTarget || 'unknown')}`);\n }\n\n const manifest = await buildProjectManifest(cwd);\n\n if (!projectLink) {\n const result = await handleFirstRun(client, config, cwd, ctx, manifest, projectDir, projectsDir, options);\n\n if (result === 'cancelled') {\n printOutro('Cancelled.');\n return;\n }\n\n if (result === 'pulled') {\n const finalManifest = await buildProjectManifest(cwd);\n await saveProjectManifest(cwd, finalManifest);\n printSuccess('Sessions synced from remote device.');\n printOutro('Done');\n return;\n }\n\n if (result === 'pushed') {\n const finalManifest = await buildProjectManifest(cwd);\n await saveProjectManifest(cwd, finalManifest);\n printOutro('Done');\n return;\n }\n\n printOutro('Done');\n return;\n }\n\n let pushResult: PushResult = { uploaded: 0, projectId: projectLink.projectId, failed: false };\n let pullResult: PullResult = { downloaded: 0, failed: false };\n\n if (manifest.length > 0) {\n pushResult = await pushPhase(client, config.deviceId, cwd, manifest, projectDir, projectLink.projectId, options);\n }\n\n if (!pushResult.failed) {\n pullResult = await pullPhase(client, config.deviceId, cwd, projectDir, projectLink.projectId, options);\n }\n\n if (pushResult.failed && pullResult.failed) {\n printOutro('Sync failed.');\n return;\n }\n\n const finalManifest = await buildProjectManifest(cwd);\n await saveProjectManifest(cwd, finalManifest);\n\n if (pushResult.uploaded > 0 || pullResult.downloaded > 0) {\n const parts: string[] = [];\n if (pushResult.uploaded > 0) parts.push(`${successColor(`+${pushResult.uploaded}`)} pushed`);\n if (pullResult.downloaded > 0) parts.push(`${successColor(`+${pullResult.downloaded}`)} pulled`);\n printSuccess(`Synced: ${parts.join(', ')}`);\n } else if (!pushResult.failed && !pullResult.failed) {\n printSuccess('Everything is up to date.');\n }\n\n printOutro('Done');\n}\n\nasync function handleFirstRun(\n client: ApiClient,\n config: CliConfig,\n cwd: string,\n ctx: ProjectContext,\n manifest: ManifestEntry[],\n projectDir: string,\n projectsDir: string,\n options: { dryRun?: boolean; verbose?: boolean },\n): Promise<'pushed' | 'pulled' | 'cancelled'> {\n printInfo(brand('First time syncing this project'));\n\n const hasLocalFiles = ctx.state !== 'none' && manifest.length > 0;\n\n const devicesSpinner = createSpinner('Checking for other devices...').start();\n let devices: DeviceInfo[];\n try {\n devices = await client.get<DeviceInfo[]>('/api/devices');\n } catch {\n devices = [];\n }\n devicesSpinner.stop();\n\n const otherDevices = devices.filter((d) => d.id !== config.deviceId);\n\n type FirstRunChoice = 'push' | 'continue';\n const menuOptions: { value: FirstRunChoice; label: string; hint?: string }[] = [];\n\n if (hasLocalFiles) {\n menuOptions.push({\n value: 'push',\n label: 'Push to cloud',\n hint: dim(`Upload ${manifest.length} local files`),\n });\n }\n\n if (otherDevices.length > 0) {\n menuOptions.push({\n value: 'continue',\n label: 'Continue from another machine',\n hint: dim('Pull sessions from a device'),\n });\n }\n\n if (menuOptions.length === 0) {\n printInfo('No local sessions and no other devices found.');\n printInfo('Use Claude Code in this directory first, then run sync.');\n return 'cancelled';\n }\n\n if (menuOptions.length === 1 && menuOptions[0].value === 'push') {\n printInfo('No other devices found.');\n }\n\n const choice = await select<FirstRunChoice>({\n message: brand('What would you like to do?'),\n options: menuOptions,\n });\n\n if (isCancel(choice)) return 'cancelled';\n\n if (choice === 'push') {\n const result = await pushPhase(client, config.deviceId!, cwd, manifest, projectDir, undefined, options);\n if (result.failed) {\n return 'cancelled';\n }\n if (result.uploaded > 0) {\n printSuccess(`${successColor(`+${result.uploaded}`)} files pushed`);\n }\n await saveProjectLink(cwd, {\n projectId: result.projectId,\n foreignEncodedDir: ctx.encodedPath,\n linkedAt: new Date().toISOString(),\n });\n return 'pushed';\n }\n\n const deviceChoice = await select({\n message: brand('Select device'),\n options: otherDevices.map((d) => ({\n value: d.id,\n label: d.name,\n hint: dim(`${d.hostname} · ${d.platform}`),\n })),\n });\n\n if (isCancel(deviceChoice)) return 'cancelled';\n\n const spinner = createSpinner('Loading projects...').start();\n let projects: DeviceProject[];\n try {\n projects = await client.get<DeviceProject[]>(`/api/devices/${deviceChoice}/projects`);\n } catch {\n spinner.stop();\n printError('Failed to load projects from device.');\n return 'cancelled';\n }\n spinner.stop();\n\n if (projects.length === 0) {\n printInfo('No projects found on that device.');\n return 'cancelled';\n }\n\n const projectChoice = await select({\n message: brand('Select project'),\n options: projects.map((p) => ({\n value: p.id,\n label: p.displayName || p.originalPath,\n hint: dim(p.localPath),\n })),\n });\n\n if (isCancel(projectChoice)) return 'cancelled';\n\n const selectedProject = projects.find((p) => p.id === projectChoice)!;\n\n const downloaded = await crossMachinePull(\n client,\n config.deviceId!,\n cwd,\n deviceChoice as string,\n selectedProject.id,\n selectedProject.encodedDir,\n projectsDir,\n options,\n );\n\n if (downloaded === 0 && !options.dryRun) {\n printInfo('No files to download.');\n return 'cancelled';\n }\n\n if (!options.dryRun) {\n await createProjectSymlink(projectsDir, ctx.encodedPath, selectedProject.encodedDir);\n\n await saveProjectLink(cwd, {\n projectId: selectedProject.id,\n foreignEncodedDir: selectedProject.encodedDir,\n linkedAt: new Date().toISOString(),\n });\n\n printSuccess(`${successColor(`+${downloaded}`)} files pulled`);\n printInfo(`Symlink: ${dim(ctx.encodedPath)} → ${dim(selectedProject.encodedDir)}`);\n }\n\n return 'pulled';\n}\n\nasync function createProjectSymlink(projectsDir: string, localEncoded: string, foreignEncoded: string) {\n const symlinkPath = join(projectsDir, localEncoded);\n\n await mkdir(projectsDir, { recursive: true });\n\n try {\n const stats = await lstat(symlinkPath);\n if (stats.isSymbolicLink()) {\n await unlink(symlinkPath);\n } else if (stats.isDirectory()) {\n printError(`Local session directory already exists. Back it up first:\\n mv \"${symlinkPath}\" \"${symlinkPath}.bak\"`);\n return;\n }\n } catch {\n }\n\n await symlink(foreignEncoded, symlinkPath);\n}\n\nasync function crossMachinePull(\n client: ApiClient,\n deviceId: string,\n projectPath: string,\n fromDeviceId: string,\n projectId: string,\n foreignEncodedDir: string,\n projectsDir: string,\n options: { dryRun?: boolean; verbose?: boolean },\n): Promise<number> {\n const spinner = createSpinner('Preparing pull from remote device...').start();\n\n let prepareResponse: PullPrepareResponse;\n try {\n prepareResponse = await client.post<PullPrepareResponse>('/api/sync/pull/prepare', {\n deviceId,\n projectPath,\n fromDeviceId,\n projectId,\n });\n } catch (err) {\n spinner.stop();\n printError(`Pull failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n return 0;\n }\n spinner.stop();\n\n const filesToDownload = prepareResponse.filesToDownload;\n if (filesToDownload.length === 0) return 0;\n\n printInfo(`${brand(String(filesToDownload.length))} files to pull`);\n\n if (options.dryRun) {\n if (options.verbose) {\n for (const entry of filesToDownload) {\n console.log(` ${brand('○')} ${entry.path} ${dim(`(${formatBytes(entry.size)})`)}`);\n }\n }\n return filesToDownload.length;\n }\n\n const targetDir = join(projectsDir, foreignEncodedDir);\n let downloaded = 0;\n\n for (const entry of filesToDownload) {\n const dlSpinner = createSpinner(\n `${formatProgress(downloaded + 1, filesToDownload.length)} ${entry.path}`,\n ).start();\n\n try {\n const urlResponse = await client.post<PresignedUrlResponse>('/api/sync/pull/download-url', {\n syncEventId: prepareResponse.syncEventId,\n key: entry.path,\n });\n\n const response = await fetch(urlResponse.url);\n let data = Buffer.from(await response.arrayBuffer());\n\n if (entry.isCompressed) {\n data = await decompressBuffer(data);\n }\n\n const outputPath = join(targetDir, entry.path);\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, data);\n\n downloaded++;\n } catch {\n }\n dlSpinner.stop();\n }\n\n try {\n await client.post('/api/sync/pull/complete', {\n syncEventId: prepareResponse.syncEventId,\n manifest: filesToDownload,\n });\n } catch {\n }\n\n return downloaded;\n}\n\ninterface PushResult {\n uploaded: number;\n projectId: string;\n failed: boolean;\n}\n\ninterface PullResult {\n downloaded: number;\n failed: boolean;\n}\n\nasync function pushPhase(\n client: ApiClient,\n deviceId: string,\n projectPath: string,\n manifest: ManifestEntry[],\n projectDir: string,\n projectId: string | undefined,\n options: { dryRun?: boolean; verbose?: boolean },\n): Promise<PushResult> {\n const spinner = createSpinner('Preparing push...').start();\n\n let prepareResponse: PushPrepareResponse;\n try {\n prepareResponse = await client.post<PushPrepareResponse>('/api/sync/push/prepare', {\n deviceId,\n projectPath,\n projectId,\n manifest,\n });\n } catch (err) {\n spinner.stop();\n printError(`Push failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n return { uploaded: 0, projectId: projectId || '', failed: true };\n }\n spinner.stop();\n\n const resolvedProjectId = prepareResponse.projectId;\n const filesToUpload = prepareResponse.filesToUpload;\n if (filesToUpload.length === 0) return { uploaded: 0, projectId: resolvedProjectId, failed: false };\n\n printInfo(`${brand(String(filesToUpload.length))} files to push`);\n\n if (options.dryRun) {\n if (options.verbose) {\n for (const entry of filesToUpload) {\n console.log(` ${successColor('+')} ${entry.path} ${dim(`(${formatBytes(entry.size)})`)}`);\n }\n }\n return { uploaded: filesToUpload.length, projectId: resolvedProjectId, failed: false };\n }\n\n let uploaded = 0;\n for (const entry of filesToUpload) {\n const uploadSpinner = createSpinner(\n `${formatProgress(uploaded + 1, filesToUpload.length)} ${entry.path}`,\n ).start();\n\n try {\n const urlResponse = await client.post<PresignedUrlResponse>('/api/sync/push/upload-url', {\n syncEventId: prepareResponse.syncEventId,\n key: entry.path,\n });\n\n const filePath = join(projectDir, entry.path);\n let body: Buffer = await readFile(filePath);\n\n if (entry.isCompressed) {\n body = await compressBuffer(body);\n }\n\n await fetch(urlResponse.url, {\n method: 'PUT',\n body,\n headers: { 'Content-Type': 'application/octet-stream' },\n });\n\n uploaded++;\n } catch {\n }\n uploadSpinner.stop();\n }\n\n try {\n await client.post('/api/sync/push/complete', {\n syncEventId: prepareResponse.syncEventId,\n manifest,\n });\n } catch {\n }\n\n return { uploaded, projectId: resolvedProjectId, failed: false };\n}\n\nasync function pullPhase(\n client: ApiClient,\n deviceId: string,\n projectPath: string,\n projectDir: string,\n projectId: string | undefined,\n options: { dryRun?: boolean; verbose?: boolean },\n): Promise<PullResult> {\n const spinner = createSpinner('Preparing pull...').start();\n\n let prepareResponse: PullPrepareResponse;\n try {\n prepareResponse = await client.post<PullPrepareResponse>('/api/sync/pull/prepare', {\n deviceId,\n projectPath,\n projectId,\n });\n } catch (err) {\n spinner.stop();\n printError(`Pull failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n return { downloaded: 0, failed: true };\n }\n spinner.stop();\n\n const filesToDownload = prepareResponse.filesToDownload;\n if (filesToDownload.length === 0) return { downloaded: 0, failed: false };\n\n printInfo(`${brand(String(filesToDownload.length))} files to pull`);\n\n if (options.dryRun) {\n if (options.verbose) {\n for (const entry of filesToDownload) {\n console.log(` ${brand('○')} ${entry.path} ${dim(`(${formatBytes(entry.size)})`)}`);\n }\n }\n return { downloaded: filesToDownload.length, failed: false };\n }\n\n let downloaded = 0;\n for (const entry of filesToDownload) {\n const dlSpinner = createSpinner(\n `${formatProgress(downloaded + 1, filesToDownload.length)} ${entry.path}`,\n ).start();\n\n try {\n const urlResponse = await client.post<PresignedUrlResponse>('/api/sync/pull/download-url', {\n syncEventId: prepareResponse.syncEventId,\n key: entry.path,\n });\n\n const response = await fetch(urlResponse.url);\n let data = Buffer.from(await response.arrayBuffer());\n\n if (entry.isCompressed) {\n data = await decompressBuffer(data);\n }\n\n const outputPath = join(projectDir, entry.path);\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, data);\n\n downloaded++;\n } catch {\n }\n dlSpinner.stop();\n }\n\n try {\n await client.post('/api/sync/pull/complete', {\n syncEventId: prepareResponse.syncEventId,\n manifest: filesToDownload,\n });\n } catch {\n }\n\n return { downloaded, failed: false };\n}\n\nexport function syncCommand(): Command {\n return new Command('sync')\n .description('Sync current project sessions with cloud')\n .option('--dry-run', 'Show what would be synced without syncing')\n .option('--verbose', 'Show detailed output')\n .action(async (options) => {\n await runSync(options);\n });\n}\n","import { Command } from 'commander';\nimport { loadConfig, loadProjectManifest, isAuthenticated } from '../lib/config.js';\nimport { buildProjectManifest, computeDiff, resolveProjectState } from '../lib/sync-engine.js';\nimport { createSpinner, formatBytes } from '../lib/progress.js';\nimport { printIntro, printLabel, printDivider, printInfo, brand, success as successColor, warn as warnColor, error as errorColor, dim } from '../lib/theme.js';\n\nexport function statusCommand(): Command {\n return new Command('status')\n .description('Show sync status for current project')\n .action(async () => {\n printIntro('Status');\n\n const config = await loadConfig();\n const cwd = process.cwd();\n\n printLabel('API', config.apiUrl);\n printLabel('Authenticated', isAuthenticated(config) ? successColor('yes') : errorColor('no'));\n printLabel('Device', config.deviceName || dim('none'));\n printLabel('Project', brand(cwd));\n\n const ctx = await resolveProjectState(cwd);\n printLabel('State', ctx.state === 'none' ? dim('no session data') : ctx.state === 'symlink' ? `symlink → ${dim(ctx.symlinkTarget || 'unknown')}` : 'local');\n\n if (!isAuthenticated(config) || ctx.state === 'none') return;\n\n const spinner = createSpinner('Scanning files...').start();\n const savedManifest = await loadProjectManifest(cwd);\n const currentManifest = await buildProjectManifest(cwd);\n const diff = computeDiff(currentManifest, savedManifest);\n spinner.stop();\n\n const totalSize = currentManifest.reduce((sum, e) => sum + e.size, 0);\n\n printDivider();\n printLabel('Local files', `${brand(String(currentManifest.length))} ${dim(`(${formatBytes(totalSize)})`)}`);\n console.log();\n printInfo('Changes since last sync:');\n console.log(` ${successColor(`+${diff.added.length}`)} added ${warnColor(`~${diff.modified.length}`)} modified ${errorColor(`-${diff.deleted.length}`)} deleted`);\n console.log();\n });\n}\n","import { Command } from 'commander';\nimport type { User } from '@claude-sync/types';\nimport { loadConfig, isAuthenticated } from '../lib/config.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { createSpinner } from '../lib/progress.js';\nimport { printIntro, printLabel, printError, printDivider, brand, dim } from '../lib/theme.js';\n\nexport function whoamiCommand(): Command {\n return new Command('whoami')\n .description('Show current user and device info')\n .action(async () => {\n printIntro('Who Am I');\n\n const config = await loadConfig();\n\n if (!isAuthenticated(config)) {\n printError('Not logged in. Run `claude-sync login` first.');\n return;\n }\n\n const client = new ApiClient(config.apiUrl);\n const spinner = createSpinner('Fetching user info...').start();\n\n try {\n const user = await client.get<User>('/api/auth/me');\n spinner.stop();\n printLabel('User', `${user.name} ${dim(`(${user.email})`)}`);\n printLabel('Plan', brand(user.plan));\n printDivider();\n printLabel('Device', config.deviceName || dim('none'));\n printLabel('Device ID', config.deviceId || dim('not registered'));\n } catch {\n spinner.stop();\n printLabel('Email', config.email || dim('unknown'));\n printLabel('Device', config.deviceName || dim('none'));\n }\n\n console.log();\n });\n}\n","import { Command } from 'commander';\n\nimport { loginCommand } from './commands/login.js';\nimport { logoutCommand } from './commands/logout.js';\nimport { deviceCommand } from './commands/device.js';\nimport { syncCommand, runSync } from './commands/sync.js';\nimport { statusCommand } from './commands/status.js';\nimport { whoamiCommand } from './commands/whoami.js';\nimport { runTui } from './commands/tui.js';\nimport { loadConfig, isAuthenticated } from './lib/config.js';\n\nexport function run() {\n const program = new Command();\n\n program\n .name('claude-sync')\n .description('Sync Claude Code sessions across machines')\n .version('0.1.0')\n .option('--menu', 'Open interactive menu')\n .action(async (options) => {\n if (options.menu) {\n await runTui();\n return;\n }\n\n const config = await loadConfig();\n if (isAuthenticated(config) && config.deviceId) {\n await runSync({});\n } else {\n await runTui();\n }\n });\n\n program.addCommand(loginCommand());\n program.addCommand(logoutCommand());\n program.addCommand(deviceCommand());\n program.addCommand(syncCommand());\n program.addCommand(statusCommand());\n program.addCommand(whoamiCommand());\n\n program.parse();\n}\n","import { select, isCancel } from '@clack/prompts';\nimport chalk from 'chalk';\nimport { printBanner, printOutro, brand, dim } from '../lib/theme.js';\nimport { loadConfig, isAuthenticated } from '../lib/config.js';\n\ninterface MenuOption {\n value: string;\n label: string;\n hint?: string;\n}\n\nfunction buildMenu(loggedIn: boolean): MenuOption[] {\n if (!loggedIn) {\n return [\n { value: 'login', label: 'Login', hint: 'Authenticate with claude-sync' },\n ];\n }\n\n return [\n { value: 'sync', label: 'Sync', hint: 'Sync current project' },\n { value: 'status', label: 'Status', hint: 'Show sync state' },\n { value: 'device:add', label: 'Add Device', hint: 'Register this machine' },\n { value: 'device:list', label: 'List Devices', hint: 'Show registered devices' },\n { value: 'device:remove', label: 'Remove Device' },\n { value: 'device:rename', label: 'Rename Device' },\n { value: 'whoami', label: 'Who Am I', hint: 'Current user and device' },\n { value: 'logout', label: 'Logout', hint: 'Sign out' },\n ];\n}\n\nexport async function runTui() {\n printBanner();\n\n const config = await loadConfig();\n const loggedIn = isAuthenticated(config);\n\n if (loggedIn) {\n console.log(` ${dim('user')} ${brand(config.email || 'unknown')}`);\n if (config.deviceName) {\n console.log(` ${dim('device')} ${brand(config.deviceName)}`);\n }\n console.log();\n } else {\n console.log(` ${dim('Not logged in')}`);\n console.log();\n }\n\n while (true) {\n const items = buildMenu(loggedIn);\n\n const options = [\n ...items.map((o) => ({\n value: o.value,\n label: o.label,\n hint: o.hint ? dim(o.hint) : undefined,\n })),\n { value: 'quit', label: chalk.red('Quit') },\n ];\n\n const choice = await select({\n message: brand('What would you like to do?'),\n options,\n });\n\n if (isCancel(choice) || choice === 'quit') {\n printOutro('Goodbye!');\n return;\n }\n\n await executeCommand(choice as string);\n\n console.log();\n }\n}\n\nasync function executeCommand(command: string) {\n const { loginCommand } = await import('./login.js');\n const { logoutCommand } = await import('./logout.js');\n const { deviceCommand } = await import('./device.js');\n const { syncCommand } = await import('./sync.js');\n const { statusCommand } = await import('./status.js');\n const { whoamiCommand } = await import('./whoami.js');\n\n const handlers: Record<string, () => Promise<void>> = {\n login: () => loginCommand().parseAsync(['', '', 'login']),\n logout: () => logoutCommand().parseAsync(['', '', 'logout']),\n sync: () => syncCommand().parseAsync(['', '', 'sync']),\n status: () => statusCommand().parseAsync(['', '', 'status']),\n whoami: () => whoamiCommand().parseAsync(['', '', 'whoami']),\n 'device:add': () => deviceCommand().parseAsync(['', '', 'device', 'add']),\n 'device:list': () => deviceCommand().parseAsync(['', '', 'device', 'list']),\n 'device:remove': () => deviceCommand().parseAsync(['', '', 'device', 'remove']),\n 'device:rename': () => deviceCommand().parseAsync(['', '', 'device', 'rename']),\n };\n\n const handler = handlers[command];\n if (handler) {\n try {\n await handler();\n } catch {\n }\n }\n}\n"],"mappings":"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","names":["error","text","chalk","Command","Command","homedir","text","isCancel","join","homedir","encodePath","Command","select","isCancel","readFile","writeFile","mkdir","lstat","join","dirname","homedir","CLAUDE_DIR","PROJECTS_DIR","finalManifest","Command","Command","Command","select","isCancel","chalk","loginCommand","logoutCommand","deviceCommand","syncCommand","statusCommand","whoamiCommand","Command"]}
|
|
1
|
+
{"version":3,"sources":["../../src/lib/config.ts","../../src/lib/api-client.ts","../../src/lib/auth.ts","../../src/lib/progress.ts","../../src/lib/theme.ts","../../src/commands/login.ts","../../src/commands/logout.ts","../../src/commands/device.ts","../../src/lib/sync-engine.ts","../../src/lib/compress.ts","../../src/commands/sync.ts","../../src/commands/status.ts","../../src/commands/whoami.ts","../../src/index.ts","../../src/commands/tui.ts"],"sourcesContent":["import { join, dirname } from 'node:path';\nimport { homedir } from 'node:os';\nimport { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport { CONFIG_DIR, CONFIG_FILE, MANIFEST_FILE, encodePath } from '@claude-sync/utils';\n\nexport interface CliConfig {\n apiUrl: string;\n accessToken: string | null;\n refreshToken: string | null;\n deviceId: string | null;\n deviceName: string | null;\n userId: string | null;\n email: string | null;\n}\n\nconst DEFAULT_CONFIG: CliConfig = {\n apiUrl: 'https://api.claude-sync.com',\n accessToken: null,\n refreshToken: null,\n deviceId: null,\n deviceName: null,\n userId: null,\n email: null,\n};\n\nfunction getConfigDir(): string {\n return join(homedir(), CONFIG_DIR);\n}\n\nfunction getConfigPath(): string {\n return join(getConfigDir(), CONFIG_FILE);\n}\n\nfunction getManifestPath(): string {\n return join(getConfigDir(), MANIFEST_FILE);\n}\n\nexport async function loadConfig(): Promise<CliConfig> {\n try {\n const content = await readFile(getConfigPath(), 'utf-8');\n return { ...DEFAULT_CONFIG, ...JSON.parse(content) };\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n}\n\nexport async function saveConfig(config: Partial<CliConfig>): Promise<void> {\n const existing = await loadConfig();\n const merged = { ...existing, ...config };\n await mkdir(getConfigDir(), { recursive: true });\n await writeFile(getConfigPath(), JSON.stringify(merged, null, 2));\n}\n\nexport async function clearConfig(): Promise<void> {\n await saveConfig(DEFAULT_CONFIG);\n}\n\nexport async function loadManifest(): Promise<import('@claude-sync/types').ManifestEntry[]> {\n try {\n const content = await readFile(getManifestPath(), 'utf-8');\n return JSON.parse(content);\n } catch {\n return [];\n }\n}\n\nexport async function saveManifest(entries: import('@claude-sync/types').ManifestEntry[]): Promise<void> {\n await mkdir(getConfigDir(), { recursive: true });\n await writeFile(getManifestPath(), JSON.stringify(entries, null, 2));\n}\n\nexport async function loadProjectManifest(projectPath: string): Promise<import('@claude-sync/types').ManifestEntry[]> {\n try {\n const encoded = encodePath(projectPath);\n const manifestPath = join(getConfigDir(), 'manifests', `${encoded}.json`);\n const content = await readFile(manifestPath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return [];\n }\n}\n\nexport async function saveProjectManifest(projectPath: string, entries: import('@claude-sync/types').ManifestEntry[]): Promise<void> {\n const encoded = encodePath(projectPath);\n const manifestPath = join(getConfigDir(), 'manifests', `${encoded}.json`);\n await mkdir(dirname(manifestPath), { recursive: true });\n await writeFile(manifestPath, JSON.stringify(entries, null, 2));\n}\n\nexport function isAuthenticated(config: CliConfig): boolean {\n return config.accessToken !== null;\n}\n\nexport interface ProjectLink {\n projectId: string;\n foreignEncodedDir: string;\n linkedAt: string;\n}\n\nexport async function loadProjectLink(projectPath: string): Promise<ProjectLink | null> {\n try {\n const encoded = encodePath(projectPath);\n const linkPath = join(getConfigDir(), 'project-links', `${encoded}.json`);\n const content = await readFile(linkPath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\nexport async function saveProjectLink(projectPath: string, link: ProjectLink): Promise<void> {\n const encoded = encodePath(projectPath);\n const linkPath = join(getConfigDir(), 'project-links', `${encoded}.json`);\n await mkdir(dirname(linkPath), { recursive: true });\n await writeFile(linkPath, JSON.stringify(link, null, 2));\n}\n","import type { ApiErrorResponse } from '@claude-sync/types';\nimport { getValidToken } from './auth.js';\n\nexport class ApiClient {\n private baseUrl: string;\n\n constructor(baseUrl: string) {\n this.baseUrl = baseUrl.replace(/\\/$/, '');\n }\n\n private async rawRequest<T>(path: string, options: RequestInit = {}): Promise<T> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 15000);\n\n let response: Response;\n try {\n response = await fetch(`${this.baseUrl}${path}`, {\n ...options,\n signal: controller.signal,\n });\n } catch (err) {\n clearTimeout(timeout);\n if (err instanceof Error && err.name === 'AbortError') {\n throw new Error('Request timed out. Is the API server running?');\n }\n throw err;\n }\n clearTimeout(timeout);\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new Error('Session expired. Run `claude-sync login` to re-authenticate.');\n }\n const error: ApiErrorResponse = await response.json().catch(() => ({\n statusCode: response.status,\n message: response.statusText,\n error: 'Request failed',\n }));\n throw new Error(error.message);\n }\n\n const json = await response.json();\n return (json.data !== undefined ? json.data : json) as T;\n }\n\n async request<T>(path: string, options: RequestInit = {}): Promise<T> {\n const token = await getValidToken();\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(options.headers as Record<string, string>),\n };\n\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n return this.rawRequest<T>(path, { ...options, headers });\n }\n\n async requestNoAuth<T>(path: string, options: RequestInit = {}): Promise<T> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...(options.headers as Record<string, string>),\n };\n\n return this.rawRequest<T>(path, { ...options, headers });\n }\n\n async get<T>(path: string): Promise<T> {\n return this.request<T>(path, { method: 'GET' });\n }\n\n async post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(path, {\n method: 'POST',\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n async patch<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(path, {\n method: 'PATCH',\n body: body ? JSON.stringify(body) : undefined,\n });\n }\n\n async delete<T>(path: string): Promise<T> {\n return this.request<T>(path, { method: 'DELETE' });\n }\n}\n","import type { TokenPair } from '@claude-sync/types';\nimport { loadConfig, saveConfig } from './config.js';\nimport { ApiClient } from './api-client.js';\n\nexport async function storeTokens(tokens: TokenPair, userId: string, email: string): Promise<void> {\n await saveConfig({\n accessToken: tokens.accessToken,\n refreshToken: tokens.refreshToken,\n userId,\n email,\n });\n}\n\nexport async function refreshAccessToken(): Promise<string | null> {\n const config = await loadConfig();\n if (!config.refreshToken) return null;\n\n const client = new ApiClient(config.apiUrl);\n try {\n const response = await client.requestNoAuth<TokenPair>('/api/auth/refresh', {\n method: 'POST',\n body: JSON.stringify({ refreshToken: config.refreshToken }),\n });\n await saveConfig({\n accessToken: response.accessToken,\n refreshToken: response.refreshToken,\n });\n return response.accessToken;\n } catch {\n return null;\n }\n}\n\nexport async function getValidToken(): Promise<string | null> {\n const config = await loadConfig();\n if (!config.accessToken) return null;\n\n try {\n const payload = JSON.parse(\n Buffer.from(config.accessToken.split('.')[1], 'base64').toString()\n );\n if (payload.exp * 1000 > Date.now()) {\n return config.accessToken;\n }\n } catch {\n }\n\n return refreshAccessToken();\n}\n","import ora, { type Ora } from 'ora';\nimport chalk from 'chalk';\n\nconst brandColor = chalk.hex('#8a8cdd');\n\nexport function createSpinner(text: string): Ora {\n return ora({ text: brandColor(text), spinner: 'dots', color: 'magenta' });\n}\n\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) return '0 B';\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;\n}\n\nexport function formatProgress(current: number, total: number): string {\n const percentage = total > 0 ? Math.round((current / total) * 100) : 0;\n return `${current}/${total} (${percentage}%)`;\n}\n","import chalk from 'chalk';\n\nconst BRAND_HEX = '#8a8cdd';\nconst BRAND_DIM_HEX = '#6b6db8';\nconst SUCCESS_HEX = '#8adda0';\nconst WARN_HEX = '#ddcc8a';\nconst ERROR_HEX = '#dd8a8a';\n\nexport const brand = chalk.hex(BRAND_HEX);\nexport const brandBold = chalk.hex(BRAND_HEX).bold;\nexport const brandDim = chalk.hex(BRAND_DIM_HEX);\nexport const success = chalk.hex(SUCCESS_HEX);\nexport const successBold = chalk.hex(SUCCESS_HEX).bold;\nexport const warn = chalk.hex(WARN_HEX);\nexport const error = chalk.hex(ERROR_HEX);\nexport const errorBold = chalk.hex(ERROR_HEX).bold;\nexport const dim = chalk.dim;\nexport const bold = chalk.bold;\nexport const white = chalk.white;\n\nexport function printBanner() {\n console.log();\n console.log(` ${brandBold('claude-sync')} ${dim('v0.1.0')}`);\n console.log();\n}\n\nexport function printIntro(title: string) {\n console.log();\n console.log(` ${brandBold(title)}`);\n console.log();\n}\n\nexport function printOutro(message: string) {\n console.log();\n console.log(` ${dim(message)}`);\n console.log();\n}\n\nexport function printSuccess(message: string) {\n console.log(` ${success('✔')} ${message}`);\n}\n\nexport function printError(message: string) {\n console.log(` ${error('✖')} ${message}`);\n}\n\nexport function printWarn(message: string) {\n console.log(` ${warn('▲')} ${message}`);\n}\n\nexport function printInfo(message: string) {\n console.log(` ${brand('●')} ${message}`);\n}\n\nexport function printLabel(label: string, value: string) {\n console.log(` ${dim(label.padEnd(14))} ${white(value)}`);\n}\n\nexport function printDivider() {\n console.log();\n}\n","import { Command } from 'commander';\nimport { text, password as passwordPrompt, select, isCancel } from '@clack/prompts';\nimport type { TokenPair, CliInitiateResponse, CliPollResponse } from '@claude-sync/types';\nimport { loadConfig } from '../lib/config.js';\nimport { storeTokens } from '../lib/auth.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { createSpinner } from '../lib/progress.js';\nimport { printIntro, printOutro, printInfo, printSuccess, printError, brand, brandBold, dim } from '../lib/theme.js';\n\nasync function loginWithBrowser(client: ApiClient): Promise<void> {\n const response = await client.requestNoAuth<CliInitiateResponse>('/api/auth/cli/initiate', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n });\n\n printInfo(`Open this URL in your browser:\\n ${brandBold(response.verifyUrl)}`);\n printInfo(`Code: ${brandBold(response.code)}`);\n\n const spinner = createSpinner('Waiting for browser authorization...').start();\n\n const pollInterval = 2000;\n const maxAttempts = 150;\n let attempts = 0;\n\n while (attempts < maxAttempts) {\n await new Promise((resolve) => setTimeout(resolve, pollInterval));\n attempts++;\n\n try {\n const pollResponse = await client.requestNoAuth<CliPollResponse>('/api/auth/cli/poll', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ code: response.code }),\n });\n\n if (pollResponse.status === 'authorized' && pollResponse.tokenPair && pollResponse.user) {\n spinner.stop();\n await storeTokens(pollResponse.tokenPair, pollResponse.user.id, pollResponse.user.email);\n printSuccess(`Logged in as ${brandBold(pollResponse.user.email)}`);\n return;\n }\n\n if (pollResponse.status === 'expired') {\n spinner.stop();\n printError('Authorization code expired. Please try again.');\n process.exit(1);\n }\n } catch {\n }\n }\n\n spinner.stop();\n printError('Authorization timed out. Please try again.');\n process.exit(1);\n}\n\nasync function loginWithEmail(client: ApiClient): Promise<void> {\n const email = await text({ message: `${brand('Email')}:` });\n if (isCancel(email)) process.exit(0);\n\n const password = await passwordPrompt({ message: `${brand('Password')}:` });\n if (isCancel(password)) process.exit(0);\n\n const spinner = createSpinner('Logging in...').start();\n\n try {\n const response = await client.requestNoAuth<TokenPair & { user: { id: string; email: string } }>(\n '/api/auth/login',\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email, password }),\n },\n );\n spinner.stop();\n await storeTokens(\n { accessToken: response.accessToken, refreshToken: response.refreshToken, expiresIn: 900 },\n response.user.id,\n response.user.email\n );\n printSuccess(`Logged in as ${brandBold(response.user.email)}`);\n } catch (err) {\n spinner.stop();\n printError(`Login failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n}\n\nexport function loginCommand(): Command {\n return new Command('login')\n .description('Authenticate with claude-sync')\n .action(async () => {\n printIntro('Login');\n\n const config = await loadConfig();\n const client = new ApiClient(config.apiUrl);\n\n const method = await select({\n message: `${brand('How would you like to log in?')}`,\n options: [\n { value: 'browser', label: `${brand('○')} Browser ${dim('(recommended)')}` },\n { value: 'email', label: `${brand('○')} Email & password` },\n ],\n });\n\n if (isCancel(method)) process.exit(0);\n\n if (method === 'browser') {\n await loginWithBrowser(client);\n } else {\n await loginWithEmail(client);\n }\n\n printOutro('Authentication complete');\n });\n}\n","import { Command } from 'commander';\nimport { loadConfig, clearConfig } from '../lib/config.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { printIntro, printOutro, printInfo, printSuccess } from '../lib/theme.js';\n\nexport function logoutCommand(): Command {\n return new Command('logout')\n .description('Log out and revoke tokens')\n .action(async () => {\n printIntro('Logout');\n\n const config = await loadConfig();\n if (!config.accessToken) {\n printInfo('Not currently logged in.');\n printOutro('Done');\n return;\n }\n\n try {\n const client = new ApiClient(config.apiUrl);\n await client.post('/api/auth/logout', {\n refreshToken: config.refreshToken,\n });\n } catch {\n }\n\n await clearConfig();\n printSuccess('Logged out successfully.');\n printOutro('Done');\n });\n}\n","import { Command } from 'commander';\nimport { hostname, platform, arch, homedir } from 'node:os';\nimport { text, isCancel } from '@clack/prompts';\nimport type { Device } from '@claude-sync/types';\nimport { loadConfig, saveConfig, isAuthenticated } from '../lib/config.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { createSpinner } from '../lib/progress.js';\nimport { printIntro, printOutro, printSuccess, printError, printInfo, printLabel, printDivider, brand, brandBold, dim, success, error as errorColor, white } from '../lib/theme.js';\n\nfunction requireAuth(config: Awaited<ReturnType<typeof loadConfig>>): void {\n if (!isAuthenticated(config)) {\n printError('Not logged in. Run `claude-sync login` first.');\n process.exit(1);\n }\n}\n\nexport function deviceCommand(): Command {\n const device = new Command('device').description('Manage devices');\n\n device\n .command('add')\n .argument('[name]', 'Device name')\n .description('Register this machine as a device')\n .action(async (name?: string) => {\n printIntro('Device Add');\n\n const config = await loadConfig();\n requireAuth(config);\n\n const deviceName = name || await (async () => {\n const input = await text({ message: `${brand('Device name')}:`, initialValue: hostname() });\n if (isCancel(input)) process.exit(0);\n return input;\n })();\n\n const spinner = createSpinner('Registering device...').start();\n const client = new ApiClient(config.apiUrl);\n\n try {\n const response = await client.post<Device>('/api/devices', {\n name: deviceName,\n hostname: hostname(),\n platform: platform(),\n homeDir: homedir(),\n arch: arch(),\n });\n\n await saveConfig({\n deviceId: response.id,\n deviceName: response.name,\n });\n\n spinner.stop();\n printSuccess(`Device ${brandBold(`\"${response.name}\"`)} registered`);\n printLabel('ID', response.id);\n } catch (err) {\n spinner.stop();\n printError(`Failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n\n printOutro('Done');\n });\n\n device\n .command('list')\n .description('List all registered devices')\n .action(async () => {\n printIntro('Devices');\n\n const config = await loadConfig();\n requireAuth(config);\n\n const client = new ApiClient(config.apiUrl);\n const spinner = createSpinner('Fetching devices...').start();\n\n try {\n const devices = await client.get<Device[]>('/api/devices');\n spinner.stop();\n\n if (devices.length === 0) {\n printInfo('No devices registered.');\n return;\n }\n\n console.log();\n for (const d of devices) {\n const current = d.id === config.deviceId ? ` ${brandBold('(current)')}` : '';\n const active = d.isActive ? success('active') : errorColor('inactive');\n console.log(` ${brand('○')} ${white(d.name)}${current}`);\n console.log(` ${dim(d.platform)} ${dim('·')} ${active} ${dim('·')} ${dim(d.id)}`);\n }\n console.log();\n } catch (err) {\n spinner.stop();\n printError(`Failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n });\n\n device\n .command('remove')\n .argument('<nameOrId>', 'Device name or ID')\n .description('Remove a device')\n .action(async (nameOrId: string) => {\n const config = await loadConfig();\n requireAuth(config);\n\n const client = new ApiClient(config.apiUrl);\n const spinner = createSpinner('Removing device...').start();\n\n try {\n await client.delete(`/api/devices/${nameOrId}`);\n spinner.stop();\n\n if (config.deviceId === nameOrId) {\n await saveConfig({ deviceId: null, deviceName: null });\n }\n\n printSuccess('Device removed.');\n } catch (err) {\n spinner.stop();\n printError(`Failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n });\n\n device\n .command('rename')\n .argument('<name>', 'New name')\n .description('Rename the current device')\n .action(async (name: string) => {\n const config = await loadConfig();\n requireAuth(config);\n\n if (!config.deviceId) {\n printError('No device registered. Run `claude-sync device add` first.');\n process.exit(1);\n }\n\n const client = new ApiClient(config.apiUrl);\n const spinner = createSpinner('Renaming device...').start();\n\n try {\n const response = await client.patch<Device>(`/api/devices/${config.deviceId}`, { name });\n await saveConfig({ deviceName: response.name });\n spinner.stop();\n printSuccess(`Device renamed to ${brandBold(`\"${response.name}\"`)}`);\n } catch (err) {\n spinner.stop();\n printError(`Failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n process.exit(1);\n }\n });\n\n return device;\n}\n","import { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { readdir, stat, lstat, readlink } from 'node:fs/promises';\nimport type { ManifestEntry, ManifestDiff } from '@claude-sync/types';\nimport { hashFile, diffManifests, encodePath, CLAUDE_DIR, PROJECTS_DIR, SYNC_EXCLUDE_PATTERNS } from '@claude-sync/utils';\n\nfunction shouldExclude(name: string): boolean {\n return SYNC_EXCLUDE_PATTERNS.some((pattern) => {\n if (pattern.startsWith('*')) {\n return name.endsWith(pattern.slice(1));\n }\n return name === pattern;\n });\n}\n\nasync function walkDirectory(dir: string, basePath: string = ''): Promise<ManifestEntry[]> {\n const entries: ManifestEntry[] = [];\n const items = await readdir(dir, { withFileTypes: true });\n\n for (const item of items) {\n if (shouldExclude(item.name)) continue;\n\n const fullPath = join(dir, item.name);\n const relativePath = basePath ? `${basePath}/${item.name}` : item.name;\n\n if (item.isDirectory()) {\n const subEntries = await walkDirectory(fullPath, relativePath);\n entries.push(...subEntries);\n } else if (item.isFile()) {\n const fileStat = await stat(fullPath);\n const hash = await hashFile(fullPath);\n const isText = !isBinaryPath(item.name);\n entries.push({\n path: relativePath,\n hash,\n size: fileStat.size,\n modifiedAt: fileStat.mtime.toISOString(),\n isCompressed: isText,\n });\n }\n }\n\n return entries;\n}\n\nfunction isBinaryPath(name: string): boolean {\n const binaryExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.ico', '.pdf', '.zip', '.gz', '.tar'];\n return binaryExtensions.some((ext) => name.endsWith(ext));\n}\n\nexport async function buildManifest(): Promise<ManifestEntry[]> {\n const claudeDir = join(homedir(), CLAUDE_DIR);\n return walkDirectory(claudeDir);\n}\n\nexport type ProjectState = 'none' | 'real' | 'symlink';\n\nexport interface ProjectContext {\n cwd: string;\n encodedPath: string;\n projectDir: string;\n state: ProjectState;\n symlinkTarget?: string;\n}\n\nexport async function resolveProjectState(cwd: string): Promise<ProjectContext> {\n const projectsDir = join(homedir(), CLAUDE_DIR, PROJECTS_DIR);\n const encoded = encodePath(cwd);\n const projectDir = join(projectsDir, encoded);\n\n let state: ProjectState = 'none';\n let symlinkTarget: string | undefined;\n\n try {\n const stats = await lstat(projectDir);\n if (stats.isSymbolicLink()) {\n state = 'symlink';\n symlinkTarget = await readlink(projectDir);\n } else if (stats.isDirectory()) {\n state = 'real';\n }\n } catch {\n state = 'none';\n }\n\n return { cwd, encodedPath: encoded, projectDir, state, symlinkTarget };\n}\n\nexport async function buildProjectManifest(cwd: string): Promise<ManifestEntry[]> {\n const ctx = await resolveProjectState(cwd);\n\n if (ctx.state === 'none') return [];\n\n const projectsDir = join(homedir(), CLAUDE_DIR, PROJECTS_DIR);\n let targetDir = ctx.projectDir;\n\n if (ctx.state === 'symlink' && ctx.symlinkTarget) {\n targetDir = join(projectsDir, ctx.symlinkTarget);\n }\n\n try {\n return await walkDirectory(targetDir);\n } catch {\n return [];\n }\n}\n\nexport function computeDiff(local: ManifestEntry[], remote: ManifestEntry[]): ManifestDiff {\n return diffManifests(local, remote);\n}\n","import { createGzip, createGunzip } from 'node:zlib';\nimport { createReadStream, createWriteStream } from 'node:fs';\nimport { pipeline } from 'node:stream/promises';\n\nexport async function compressFile(inputPath: string, outputPath: string): Promise<void> {\n const source = createReadStream(inputPath);\n const destination = createWriteStream(outputPath);\n const gzip = createGzip();\n await pipeline(source, gzip, destination);\n}\n\nexport async function decompressFile(inputPath: string, outputPath: string): Promise<void> {\n const source = createReadStream(inputPath);\n const destination = createWriteStream(outputPath);\n const gunzip = createGunzip();\n await pipeline(source, gunzip, destination);\n}\n\nexport function compressBuffer(data: Buffer): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const gzip = createGzip();\n const chunks: Buffer[] = [];\n gzip.on('data', (chunk: Buffer) => chunks.push(chunk));\n gzip.on('end', () => resolve(Buffer.concat(chunks)));\n gzip.on('error', reject);\n gzip.end(data);\n });\n}\n\nexport function decompressBuffer(data: Buffer): Promise<Buffer> {\n return new Promise((resolve, reject) => {\n const gunzip = createGunzip();\n const chunks: Buffer[] = [];\n gunzip.on('data', (chunk: Buffer) => chunks.push(chunk));\n gunzip.on('end', () => resolve(Buffer.concat(chunks)));\n gunzip.on('error', reject);\n gunzip.end(data);\n });\n}\n","import { Command } from 'commander';\nimport { select, isCancel } from '@clack/prompts';\nimport type { PushPrepareResponse, PullPrepareResponse, PresignedUrlResponse } from '@claude-sync/types';\nimport type { ManifestEntry } from '@claude-sync/types';\nimport { loadConfig, saveProjectManifest, isAuthenticated, loadProjectLink, saveProjectLink } from '../lib/config.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { resolveProjectState, buildProjectManifest } from '../lib/sync-engine.js';\nimport { createSpinner, formatBytes, formatProgress } from '../lib/progress.js';\nimport { compressBuffer, decompressBuffer } from '../lib/compress.js';\nimport { readFile, writeFile, mkdir, lstat, symlink, unlink } from 'node:fs/promises';\nimport { join, dirname } from 'node:path';\nimport { homedir } from 'node:os';\nimport { CLAUDE_DIR, PROJECTS_DIR } from '@claude-sync/utils';\nimport { printIntro, printOutro, printInfo, printSuccess, printError, brand, success as successColor, dim } from '../lib/theme.js';\nimport type { CliConfig } from '../lib/config.js';\nimport type { ProjectContext } from '../lib/sync-engine.js';\n\ninterface DeviceProject {\n id: string;\n displayName: string;\n originalPath: string;\n canonicalPath: string;\n encodedDir: string;\n localPath: string;\n}\n\ninterface DeviceInfo {\n id: string;\n name: string;\n hostname: string;\n platform: string;\n}\n\nexport async function runSync(options: { dryRun?: boolean; verbose?: boolean }) {\n printIntro('Sync');\n\n const config = await loadConfig();\n if (!isAuthenticated(config)) {\n printError('Not logged in. Run `claude-sync login` first.');\n return;\n }\n if (!config.deviceId) {\n printError('No device registered. Run `claude-sync device add` first.');\n return;\n }\n\n const cwd = process.cwd();\n const ctx = await resolveProjectState(cwd);\n const client = new ApiClient(config.apiUrl);\n const projectsDir = join(homedir(), CLAUDE_DIR, PROJECTS_DIR);\n const projectLink = await loadProjectLink(cwd);\n\n let projectDir = ctx.projectDir;\n if (ctx.state === 'symlink' && ctx.symlinkTarget) {\n projectDir = join(projectsDir, ctx.symlinkTarget);\n }\n\n printInfo(`Project: ${brand(cwd)}`);\n if (ctx.state === 'symlink') {\n printInfo(`Linked to: ${dim(ctx.symlinkTarget || 'unknown')}`);\n }\n\n const manifest = await buildProjectManifest(cwd);\n\n if (!projectLink) {\n const result = await handleFirstRun(client, config, cwd, ctx, manifest, projectDir, projectsDir, options);\n\n if (result === 'cancelled') {\n printOutro('Cancelled.');\n return;\n }\n\n if (result === 'pulled') {\n const finalManifest = await buildProjectManifest(cwd);\n await saveProjectManifest(cwd, finalManifest);\n printSuccess('Sessions synced from remote device.');\n printOutro('Done');\n return;\n }\n\n if (result === 'pushed') {\n const finalManifest = await buildProjectManifest(cwd);\n await saveProjectManifest(cwd, finalManifest);\n printOutro('Done');\n return;\n }\n\n printOutro('Done');\n return;\n }\n\n let pushResult: PushResult = { uploaded: 0, projectId: projectLink.projectId, failed: false };\n let pullResult: PullResult = { downloaded: 0, failed: false };\n\n if (manifest.length > 0) {\n pushResult = await pushPhase(client, config.deviceId, cwd, manifest, projectDir, projectLink.projectId, options);\n }\n\n if (!pushResult.failed) {\n pullResult = await pullPhase(client, config.deviceId, cwd, projectDir, projectLink.projectId, options);\n }\n\n if (pushResult.failed && pullResult.failed) {\n printOutro('Sync failed.');\n return;\n }\n\n const finalManifest = await buildProjectManifest(cwd);\n await saveProjectManifest(cwd, finalManifest);\n\n if (pushResult.uploaded > 0 || pullResult.downloaded > 0) {\n const parts: string[] = [];\n if (pushResult.uploaded > 0) parts.push(`${successColor(`+${pushResult.uploaded}`)} pushed`);\n if (pullResult.downloaded > 0) parts.push(`${successColor(`+${pullResult.downloaded}`)} pulled`);\n printSuccess(`Synced: ${parts.join(', ')}`);\n } else if (!pushResult.failed && !pullResult.failed) {\n printSuccess('Everything is up to date.');\n }\n\n printOutro('Done');\n}\n\nasync function handleFirstRun(\n client: ApiClient,\n config: CliConfig,\n cwd: string,\n ctx: ProjectContext,\n manifest: ManifestEntry[],\n projectDir: string,\n projectsDir: string,\n options: { dryRun?: boolean; verbose?: boolean },\n): Promise<'pushed' | 'pulled' | 'cancelled'> {\n printInfo(brand('First time syncing this project'));\n\n const hasLocalFiles = ctx.state !== 'none' && manifest.length > 0;\n\n const devicesSpinner = createSpinner('Checking for other devices...').start();\n let devices: DeviceInfo[];\n try {\n devices = await client.get<DeviceInfo[]>('/api/devices');\n } catch {\n devices = [];\n }\n devicesSpinner.stop();\n\n const otherDevices = devices.filter((d) => d.id !== config.deviceId);\n\n type FirstRunChoice = 'push' | 'continue';\n const menuOptions: { value: FirstRunChoice; label: string; hint?: string }[] = [];\n\n if (hasLocalFiles) {\n menuOptions.push({\n value: 'push',\n label: 'Push to cloud',\n hint: dim(`Upload ${manifest.length} local files`),\n });\n }\n\n if (otherDevices.length > 0) {\n menuOptions.push({\n value: 'continue',\n label: 'Continue from another machine',\n hint: dim('Pull sessions from a device'),\n });\n }\n\n if (menuOptions.length === 0) {\n printInfo('No local sessions and no other devices found.');\n printInfo('Use Claude Code in this directory first, then run sync.');\n return 'cancelled';\n }\n\n if (menuOptions.length === 1 && menuOptions[0].value === 'push') {\n printInfo('No other devices found.');\n }\n\n const choice = await select<FirstRunChoice>({\n message: brand('What would you like to do?'),\n options: menuOptions,\n });\n\n if (isCancel(choice)) return 'cancelled';\n\n if (choice === 'push') {\n const result = await pushPhase(client, config.deviceId!, cwd, manifest, projectDir, undefined, options);\n if (result.failed) {\n return 'cancelled';\n }\n if (result.uploaded > 0) {\n printSuccess(`${successColor(`+${result.uploaded}`)} files pushed`);\n }\n await saveProjectLink(cwd, {\n projectId: result.projectId,\n foreignEncodedDir: ctx.encodedPath,\n linkedAt: new Date().toISOString(),\n });\n return 'pushed';\n }\n\n const deviceChoice = await select({\n message: brand('Select device'),\n options: otherDevices.map((d) => ({\n value: d.id,\n label: d.name,\n hint: dim(`${d.hostname} · ${d.platform}`),\n })),\n });\n\n if (isCancel(deviceChoice)) return 'cancelled';\n\n const spinner = createSpinner('Loading projects...').start();\n let projects: DeviceProject[];\n try {\n projects = await client.get<DeviceProject[]>(`/api/devices/${deviceChoice}/projects`);\n } catch {\n spinner.stop();\n printError('Failed to load projects from device.');\n return 'cancelled';\n }\n spinner.stop();\n\n if (projects.length === 0) {\n printInfo('No projects found on that device.');\n return 'cancelled';\n }\n\n const projectChoice = await select({\n message: brand('Select project'),\n options: projects.map((p) => ({\n value: p.id,\n label: p.displayName || p.originalPath,\n hint: dim(p.localPath),\n })),\n });\n\n if (isCancel(projectChoice)) return 'cancelled';\n\n const selectedProject = projects.find((p) => p.id === projectChoice)!;\n\n const downloaded = await crossMachinePull(\n client,\n config.deviceId!,\n cwd,\n deviceChoice as string,\n selectedProject.id,\n selectedProject.encodedDir,\n projectsDir,\n options,\n );\n\n if (downloaded === 0 && !options.dryRun) {\n printInfo('No files to download.');\n return 'cancelled';\n }\n\n if (!options.dryRun) {\n await createProjectSymlink(projectsDir, ctx.encodedPath, selectedProject.encodedDir);\n\n await saveProjectLink(cwd, {\n projectId: selectedProject.id,\n foreignEncodedDir: selectedProject.encodedDir,\n linkedAt: new Date().toISOString(),\n });\n\n printSuccess(`${successColor(`+${downloaded}`)} files pulled`);\n printInfo(`Symlink: ${dim(ctx.encodedPath)} → ${dim(selectedProject.encodedDir)}`);\n }\n\n return 'pulled';\n}\n\nasync function createProjectSymlink(projectsDir: string, localEncoded: string, foreignEncoded: string) {\n const symlinkPath = join(projectsDir, localEncoded);\n\n await mkdir(projectsDir, { recursive: true });\n\n try {\n const stats = await lstat(symlinkPath);\n if (stats.isSymbolicLink()) {\n await unlink(symlinkPath);\n } else if (stats.isDirectory()) {\n printError(`Local session directory already exists. Back it up first:\\n mv \"${symlinkPath}\" \"${symlinkPath}.bak\"`);\n return;\n }\n } catch {\n }\n\n await symlink(foreignEncoded, symlinkPath);\n}\n\nasync function crossMachinePull(\n client: ApiClient,\n deviceId: string,\n projectPath: string,\n fromDeviceId: string,\n projectId: string,\n foreignEncodedDir: string,\n projectsDir: string,\n options: { dryRun?: boolean; verbose?: boolean },\n): Promise<number> {\n const spinner = createSpinner('Preparing pull from remote device...').start();\n\n let prepareResponse: PullPrepareResponse;\n try {\n prepareResponse = await client.post<PullPrepareResponse>('/api/sync/pull/prepare', {\n deviceId,\n projectPath,\n fromDeviceId,\n projectId,\n });\n } catch (err) {\n spinner.stop();\n printError(`Pull failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n return 0;\n }\n spinner.stop();\n\n const filesToDownload = prepareResponse.filesToDownload;\n if (filesToDownload.length === 0) return 0;\n\n printInfo(`${brand(String(filesToDownload.length))} files to pull`);\n\n if (options.dryRun) {\n if (options.verbose) {\n for (const entry of filesToDownload) {\n console.log(` ${brand('○')} ${entry.path} ${dim(`(${formatBytes(entry.size)})`)}`);\n }\n }\n return filesToDownload.length;\n }\n\n const targetDir = join(projectsDir, foreignEncodedDir);\n let downloaded = 0;\n\n for (const entry of filesToDownload) {\n const dlSpinner = createSpinner(\n `${formatProgress(downloaded + 1, filesToDownload.length)} ${entry.path}`,\n ).start();\n\n try {\n const urlResponse = await client.post<PresignedUrlResponse>('/api/sync/pull/download-url', {\n syncEventId: prepareResponse.syncEventId,\n key: entry.path,\n });\n\n const response = await fetch(urlResponse.url);\n let data = Buffer.from(await response.arrayBuffer());\n\n if (entry.isCompressed) {\n data = await decompressBuffer(data);\n }\n\n const outputPath = join(targetDir, entry.path);\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, data);\n\n downloaded++;\n } catch {\n }\n dlSpinner.stop();\n }\n\n try {\n await client.post('/api/sync/pull/complete', {\n syncEventId: prepareResponse.syncEventId,\n manifest: filesToDownload,\n });\n } catch {\n }\n\n return downloaded;\n}\n\ninterface PushResult {\n uploaded: number;\n projectId: string;\n failed: boolean;\n}\n\ninterface PullResult {\n downloaded: number;\n failed: boolean;\n}\n\nasync function pushPhase(\n client: ApiClient,\n deviceId: string,\n projectPath: string,\n manifest: ManifestEntry[],\n projectDir: string,\n projectId: string | undefined,\n options: { dryRun?: boolean; verbose?: boolean },\n): Promise<PushResult> {\n const spinner = createSpinner('Preparing push...').start();\n\n let prepareResponse: PushPrepareResponse;\n try {\n prepareResponse = await client.post<PushPrepareResponse>('/api/sync/push/prepare', {\n deviceId,\n projectPath,\n projectId,\n manifest,\n });\n } catch (err) {\n spinner.stop();\n printError(`Push failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n return { uploaded: 0, projectId: projectId || '', failed: true };\n }\n spinner.stop();\n\n const resolvedProjectId = prepareResponse.projectId;\n const filesToUpload = prepareResponse.filesToUpload;\n if (filesToUpload.length === 0) return { uploaded: 0, projectId: resolvedProjectId, failed: false };\n\n printInfo(`${brand(String(filesToUpload.length))} files to push`);\n\n if (options.dryRun) {\n if (options.verbose) {\n for (const entry of filesToUpload) {\n console.log(` ${successColor('+')} ${entry.path} ${dim(`(${formatBytes(entry.size)})`)}`);\n }\n }\n return { uploaded: filesToUpload.length, projectId: resolvedProjectId, failed: false };\n }\n\n let uploaded = 0;\n for (const entry of filesToUpload) {\n const uploadSpinner = createSpinner(\n `${formatProgress(uploaded + 1, filesToUpload.length)} ${entry.path}`,\n ).start();\n\n try {\n const urlResponse = await client.post<PresignedUrlResponse>('/api/sync/push/upload-url', {\n syncEventId: prepareResponse.syncEventId,\n key: entry.path,\n });\n\n const filePath = join(projectDir, entry.path);\n let body: Buffer = await readFile(filePath);\n\n if (entry.isCompressed) {\n body = await compressBuffer(body);\n }\n\n await fetch(urlResponse.url, {\n method: 'PUT',\n body,\n headers: { 'Content-Type': 'application/octet-stream' },\n });\n\n uploaded++;\n } catch {\n }\n uploadSpinner.stop();\n }\n\n try {\n await client.post('/api/sync/push/complete', {\n syncEventId: prepareResponse.syncEventId,\n manifest,\n });\n } catch {\n }\n\n return { uploaded, projectId: resolvedProjectId, failed: false };\n}\n\nasync function pullPhase(\n client: ApiClient,\n deviceId: string,\n projectPath: string,\n projectDir: string,\n projectId: string | undefined,\n options: { dryRun?: boolean; verbose?: boolean },\n): Promise<PullResult> {\n const spinner = createSpinner('Preparing pull...').start();\n\n let prepareResponse: PullPrepareResponse;\n try {\n prepareResponse = await client.post<PullPrepareResponse>('/api/sync/pull/prepare', {\n deviceId,\n projectPath,\n projectId,\n });\n } catch (err) {\n spinner.stop();\n printError(`Pull failed: ${err instanceof Error ? err.message : 'Unknown error'}`);\n return { downloaded: 0, failed: true };\n }\n spinner.stop();\n\n const filesToDownload = prepareResponse.filesToDownload;\n if (filesToDownload.length === 0) return { downloaded: 0, failed: false };\n\n printInfo(`${brand(String(filesToDownload.length))} files to pull`);\n\n if (options.dryRun) {\n if (options.verbose) {\n for (const entry of filesToDownload) {\n console.log(` ${brand('○')} ${entry.path} ${dim(`(${formatBytes(entry.size)})`)}`);\n }\n }\n return { downloaded: filesToDownload.length, failed: false };\n }\n\n let downloaded = 0;\n for (const entry of filesToDownload) {\n const dlSpinner = createSpinner(\n `${formatProgress(downloaded + 1, filesToDownload.length)} ${entry.path}`,\n ).start();\n\n try {\n const urlResponse = await client.post<PresignedUrlResponse>('/api/sync/pull/download-url', {\n syncEventId: prepareResponse.syncEventId,\n key: entry.path,\n });\n\n const response = await fetch(urlResponse.url);\n let data = Buffer.from(await response.arrayBuffer());\n\n if (entry.isCompressed) {\n data = await decompressBuffer(data);\n }\n\n const outputPath = join(projectDir, entry.path);\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, data);\n\n downloaded++;\n } catch {\n }\n dlSpinner.stop();\n }\n\n try {\n await client.post('/api/sync/pull/complete', {\n syncEventId: prepareResponse.syncEventId,\n manifest: filesToDownload,\n });\n } catch {\n }\n\n return { downloaded, failed: false };\n}\n\nexport function syncCommand(): Command {\n return new Command('sync')\n .description('Sync current project sessions with cloud')\n .option('--dry-run', 'Show what would be synced without syncing')\n .option('--verbose', 'Show detailed output')\n .action(async (options) => {\n await runSync(options);\n });\n}\n","import { Command } from 'commander';\nimport { loadConfig, loadProjectManifest, isAuthenticated } from '../lib/config.js';\nimport { buildProjectManifest, computeDiff, resolveProjectState } from '../lib/sync-engine.js';\nimport { createSpinner, formatBytes } from '../lib/progress.js';\nimport { printIntro, printLabel, printDivider, printInfo, brand, success as successColor, warn as warnColor, error as errorColor, dim } from '../lib/theme.js';\n\nexport function statusCommand(): Command {\n return new Command('status')\n .description('Show sync status for current project')\n .action(async () => {\n printIntro('Status');\n\n const config = await loadConfig();\n const cwd = process.cwd();\n\n printLabel('API', config.apiUrl);\n printLabel('Authenticated', isAuthenticated(config) ? successColor('yes') : errorColor('no'));\n printLabel('Device', config.deviceName || dim('none'));\n printLabel('Project', brand(cwd));\n\n const ctx = await resolveProjectState(cwd);\n printLabel('State', ctx.state === 'none' ? dim('no session data') : ctx.state === 'symlink' ? `symlink → ${dim(ctx.symlinkTarget || 'unknown')}` : 'local');\n\n if (!isAuthenticated(config) || ctx.state === 'none') return;\n\n const spinner = createSpinner('Scanning files...').start();\n const savedManifest = await loadProjectManifest(cwd);\n const currentManifest = await buildProjectManifest(cwd);\n const diff = computeDiff(currentManifest, savedManifest);\n spinner.stop();\n\n const totalSize = currentManifest.reduce((sum, e) => sum + e.size, 0);\n\n printDivider();\n printLabel('Local files', `${brand(String(currentManifest.length))} ${dim(`(${formatBytes(totalSize)})`)}`);\n console.log();\n printInfo('Changes since last sync:');\n console.log(` ${successColor(`+${diff.added.length}`)} added ${warnColor(`~${diff.modified.length}`)} modified ${errorColor(`-${diff.deleted.length}`)} deleted`);\n console.log();\n });\n}\n","import { Command } from 'commander';\nimport type { User } from '@claude-sync/types';\nimport { loadConfig, isAuthenticated } from '../lib/config.js';\nimport { ApiClient } from '../lib/api-client.js';\nimport { createSpinner } from '../lib/progress.js';\nimport { printIntro, printLabel, printError, printDivider, brand, dim } from '../lib/theme.js';\n\nexport function whoamiCommand(): Command {\n return new Command('whoami')\n .description('Show current user and device info')\n .action(async () => {\n printIntro('Who Am I');\n\n const config = await loadConfig();\n\n if (!isAuthenticated(config)) {\n printError('Not logged in. Run `claude-sync login` first.');\n return;\n }\n\n const client = new ApiClient(config.apiUrl);\n const spinner = createSpinner('Fetching user info...').start();\n\n try {\n const user = await client.get<User>('/api/auth/me');\n spinner.stop();\n printLabel('User', `${user.name} ${dim(`(${user.email})`)}`);\n printLabel('Plan', brand(user.plan));\n printDivider();\n printLabel('Device', config.deviceName || dim('none'));\n printLabel('Device ID', config.deviceId || dim('not registered'));\n } catch {\n spinner.stop();\n printLabel('Email', config.email || dim('unknown'));\n printLabel('Device', config.deviceName || dim('none'));\n }\n\n console.log();\n });\n}\n","import { Command } from 'commander';\n\nimport { loginCommand } from './commands/login.js';\nimport { logoutCommand } from './commands/logout.js';\nimport { deviceCommand } from './commands/device.js';\nimport { syncCommand, runSync } from './commands/sync.js';\nimport { statusCommand } from './commands/status.js';\nimport { whoamiCommand } from './commands/whoami.js';\nimport { runTui } from './commands/tui.js';\nimport { loadConfig, isAuthenticated } from './lib/config.js';\n\nexport function run() {\n const program = new Command();\n\n program\n .name('claude-sync')\n .description('Sync Claude Code sessions across machines — claude-sync.com')\n .version('0.1.0')\n .option('--menu', 'Open interactive menu')\n .action(async (options) => {\n if (options.menu) {\n await runTui();\n return;\n }\n\n const config = await loadConfig();\n if (isAuthenticated(config) && config.deviceId) {\n await runSync({});\n } else {\n await runTui();\n }\n });\n\n program.addCommand(loginCommand());\n program.addCommand(logoutCommand());\n program.addCommand(deviceCommand());\n program.addCommand(syncCommand());\n program.addCommand(statusCommand());\n program.addCommand(whoamiCommand());\n\n program.parse();\n}\n","import { select, isCancel } from '@clack/prompts';\nimport chalk from 'chalk';\nimport { printBanner, printOutro, brand, dim } from '../lib/theme.js';\nimport { loadConfig, isAuthenticated } from '../lib/config.js';\n\ninterface MenuOption {\n value: string;\n label: string;\n hint?: string;\n}\n\nfunction buildMenu(loggedIn: boolean): MenuOption[] {\n if (!loggedIn) {\n return [\n { value: 'login', label: 'Login', hint: 'Authenticate with claude-sync' },\n ];\n }\n\n return [\n { value: 'sync', label: 'Sync', hint: 'Sync current project' },\n { value: 'status', label: 'Status', hint: 'Show sync state' },\n { value: 'device:add', label: 'Add Device', hint: 'Register this machine' },\n { value: 'device:list', label: 'List Devices', hint: 'Show registered devices' },\n { value: 'device:remove', label: 'Remove Device' },\n { value: 'device:rename', label: 'Rename Device' },\n { value: 'whoami', label: 'Who Am I', hint: 'Current user and device' },\n { value: 'logout', label: 'Logout', hint: 'Sign out' },\n ];\n}\n\nexport async function runTui() {\n printBanner();\n\n const config = await loadConfig();\n const loggedIn = isAuthenticated(config);\n\n if (loggedIn) {\n console.log(` ${dim('user')} ${brand(config.email || 'unknown')}`);\n if (config.deviceName) {\n console.log(` ${dim('device')} ${brand(config.deviceName)}`);\n }\n console.log();\n } else {\n console.log(` ${dim('Not logged in')}`);\n console.log();\n }\n\n while (true) {\n const items = buildMenu(loggedIn);\n\n const options = [\n ...items.map((o) => ({\n value: o.value,\n label: o.label,\n hint: o.hint ? dim(o.hint) : undefined,\n })),\n { value: 'quit', label: chalk.red('Quit') },\n ];\n\n const choice = await select({\n message: brand('What would you like to do?'),\n options,\n });\n\n if (isCancel(choice) || choice === 'quit') {\n printOutro('Goodbye!');\n return;\n }\n\n await executeCommand(choice as string);\n\n console.log();\n }\n}\n\nasync function executeCommand(command: string) {\n const { loginCommand } = await import('./login.js');\n const { logoutCommand } = await import('./logout.js');\n const { deviceCommand } = await import('./device.js');\n const { syncCommand } = await import('./sync.js');\n const { statusCommand } = await import('./status.js');\n const { whoamiCommand } = await import('./whoami.js');\n\n const handlers: Record<string, () => Promise<void>> = {\n login: () => loginCommand().parseAsync(['', '', 'login']),\n logout: () => logoutCommand().parseAsync(['', '', 'logout']),\n sync: () => syncCommand().parseAsync(['', '', 'sync']),\n status: () => statusCommand().parseAsync(['', '', 'status']),\n whoami: () => whoamiCommand().parseAsync(['', '', 'whoami']),\n 'device:add': () => deviceCommand().parseAsync(['', '', 'device', 'add']),\n 'device:list': () => deviceCommand().parseAsync(['', '', 'device', 'list']),\n 'device:remove': () => deviceCommand().parseAsync(['', '', 'device', 'remove']),\n 'device:rename': () => deviceCommand().parseAsync(['', '', 'device', 'rename']),\n };\n\n const handler = handlers[command];\n if (handler) {\n try {\n await handler();\n } catch {\n }\n }\n}\n"],"mappings":"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","names":["error","text","chalk","Command","Command","homedir","text","isCancel","join","homedir","encodePath","Command","select","isCancel","readFile","writeFile","mkdir","lstat","join","dirname","homedir","CLAUDE_DIR","PROJECTS_DIR","finalManifest","Command","Command","Command","select","isCancel","chalk","loginCommand","logoutCommand","deviceCommand","syncCommand","statusCommand","whoamiCommand","Command"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claude-sync/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Sync Claude Code sessions across machines",
|
|
6
6
|
"license": "MIT",
|
|
@@ -9,11 +9,19 @@
|
|
|
9
9
|
"url": "https://github.com/mudrik-ai/product-claude-sync-monorepo",
|
|
10
10
|
"directory": "apps/cli"
|
|
11
11
|
},
|
|
12
|
-
"keywords": [
|
|
12
|
+
"keywords": [
|
|
13
|
+
"claude",
|
|
14
|
+
"claude-code",
|
|
15
|
+
"sync",
|
|
16
|
+
"cli",
|
|
17
|
+
"developer-tools"
|
|
18
|
+
],
|
|
13
19
|
"bin": {
|
|
14
20
|
"claude-sync": "./dist/bin/claude-sync.js"
|
|
15
21
|
},
|
|
16
|
-
"files": [
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
17
25
|
"publishConfig": {
|
|
18
26
|
"access": "public"
|
|
19
27
|
},
|
|
@@ -38,8 +46,13 @@
|
|
|
38
46
|
"@types/node": "^22.0.0"
|
|
39
47
|
},
|
|
40
48
|
"tsup": {
|
|
41
|
-
"entry": [
|
|
42
|
-
|
|
49
|
+
"entry": [
|
|
50
|
+
"src/index.ts",
|
|
51
|
+
"bin/claude-sync.ts"
|
|
52
|
+
],
|
|
53
|
+
"format": [
|
|
54
|
+
"esm"
|
|
55
|
+
],
|
|
43
56
|
"dts": true,
|
|
44
57
|
"splitting": false,
|
|
45
58
|
"sourcemap": true,
|