// Manages per-clone state stored in
/.lattex-cli.json
// and the global auth credential at ~/.config/lattex/auth.json
import { join } from 'path'
import { readFile, writeFile, mkdir, chmod } from 'fs/promises'
import { existsSync } from 'fs'
import { homedir } from 'os'
const CONFIG_DIR = join(homedir(), '.config', 'lattex')
const AUTH_PATH = join(CONFIG_DIR, 'auth.json')
const STATE_FILE = '.lattex-cli.json'
// ── Global auth ──
export async function saveCookie(cookie: string): Promise {
await mkdir(CONFIG_DIR, { recursive: true })
await writeFile(AUTH_PATH, JSON.stringify({ cookie }), { mode: 0o600 })
// Ensure directory and file are user-only
await chmod(CONFIG_DIR, 0o700).catch(() => {})
await chmod(AUTH_PATH, 0o600).catch(() => {})
}
export async function loadCookie(): Promise {
try {
const data = JSON.parse(await readFile(AUTH_PATH, 'utf-8'))
return data.cookie || null
} catch {
return null
}
}
// ── Per-clone state ──
export interface CloneState {
projectId: string
projectName: string
/** docId → relPath */
docPathMap: Record
/** relPath → docId */
pathDocMap: Record
/** fileRefId → relPath */
fileRefPathMap: Record
/** relPath → fileRefId */
pathFileRefMap: Record
/** folderId → relDirPath */
folderMap: Record
/** relDirPath → folderId */
pathFolderMap: Record
rootFolderId: string
rootDocId: string
/** ISO timestamp of last pull */
lastPull: string
/** sha256 hash of each file at last pull (relPath → hash) */
fileHashes: Record
}
export function statePath(dir: string): string {
return join(dir, STATE_FILE)
}
export async function loadState(dir: string): Promise {
const p = statePath(dir)
try {
return JSON.parse(await readFile(p, 'utf-8'))
} catch {
return null
}
}
export async function saveState(dir: string, state: CloneState): Promise {
await writeFile(statePath(dir), JSON.stringify(state, null, 2))
}
export function hasState(dir: string): boolean {
return existsSync(statePath(dir))
}