// 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)) }