@prnv/tuck 1.1.0 → 1.2.0
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/README.md +4 -0
- package/dist/index.js +3751 -3278
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ui/banner.ts","../src/ui/logger.ts","../src/ui/prompts.ts","../src/ui/spinner.ts","../src/ui/table.ts","../src/ui/index.ts","../src/constants.ts","../src/lib/paths.ts","../src/schemas/config.schema.ts","../src/errors.ts","../src/lib/config.ts","../src/schemas/manifest.schema.ts","../src/lib/manifest.ts","../src/lib/files.ts","../src/commands/add.ts","../src/index.ts","../src/commands/init.ts","../src/lib/git.ts","../src/lib/github.ts","../src/commands/index.ts","../src/commands/remove.ts","../src/commands/sync.ts","../src/lib/hooks.ts","../src/commands/push.ts","../src/commands/pull.ts","../src/commands/restore.ts","../src/lib/backup.ts","../src/commands/status.ts","../src/commands/list.ts","../src/commands/diff.ts","../src/commands/config.ts","../src/commands/apply.ts","../src/lib/timemachine.ts","../src/lib/merge.ts","../src/commands/undo.ts","../src/commands/scan.ts","../src/lib/detect.ts"],"sourcesContent":["import chalk from 'chalk';\nimport boxen from 'boxen';\n\nexport const banner = (): void => {\n const art = `\n ████████╗██╗ ██╗ ██████╗██╗ ██╗\n ╚══██╔══╝██║ ██║██╔════╝██║ ██╔╝\n ██║ ██║ ██║██║ █████╔╝\n ██║ ██║ ██║██║ ██╔═██╗\n ██║ ╚██████╔╝╚██████╗██║ ██╗\n ╚═╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝`;\n\n console.log(chalk.cyan(art));\n console.log(chalk.dim(' Modern Dotfiles Manager\\n'));\n};\n\nexport const miniBanner = (): void => {\n console.log(\n boxen(chalk.cyan.bold('tuck') + chalk.dim(' · Modern Dotfiles Manager'), {\n padding: { top: 0, bottom: 0, left: 1, right: 1 },\n borderStyle: 'round',\n borderColor: 'cyan',\n })\n );\n console.log();\n};\n\nexport const customHelp = (version: string): string => {\n const title = boxen(chalk.cyan.bold('tuck') + chalk.dim(` v${version}`), {\n padding: { top: 0, bottom: 0, left: 1, right: 1 },\n borderStyle: 'round',\n borderColor: 'cyan',\n });\n\n const quickStart = `\n${chalk.bold.cyan('Quick Start:')}\n ${chalk.cyan('tuck init')} Set up tuck (auto-creates GitHub repo)\n ${chalk.cyan('tuck add <file>')} Start tracking a dotfile\n ${chalk.cyan('tuck sync')} Commit your changes\n ${chalk.cyan('tuck push')} Push to GitHub\n\n${chalk.bold.cyan('On a New Machine:')}\n ${chalk.cyan('tuck apply <user>')} Apply dotfiles from GitHub\n`;\n\n const commands = `\n${chalk.bold.cyan('Commands:')}\n ${chalk.cyan('Getting Started')}\n init Initialize tuck repository\n scan Auto-detect and select dotfiles to track\n apply <source> Apply dotfiles from a repository\n\n ${chalk.cyan('Managing Files')}\n add <paths...> Track dotfile(s)\n remove <paths...> Stop tracking dotfile(s)\n list List all tracked files\n status Show repository status\n\n ${chalk.cyan('Syncing')}\n sync Sync changes to repository\n push Push to remote\n pull Pull from remote\n diff Show pending changes\n\n ${chalk.cyan('Restoring')}\n restore Restore dotfiles to system\n undo Undo last apply (Time Machine backup)\n\n ${chalk.cyan('Configuration')}\n config Manage tuck configuration\n`;\n\n const footer = `\n${chalk.dim('Run')} ${chalk.cyan('tuck <command> --help')} ${chalk.dim('for detailed command info')}\n${chalk.dim('Documentation:')} ${chalk.cyan('https://github.com/Pranav-Karra-3301/tuck')}\n`;\n\n return `${title}\\n${quickStart}${commands}${footer}`;\n};\n\nexport const welcomeBox = (message: string, title?: string): void => {\n console.log(\n boxen(message, {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'cyan',\n title,\n titleAlignment: 'center',\n })\n );\n};\n\nexport const successBox = (message: string, title?: string): void => {\n console.log(\n boxen(message, {\n padding: 1,\n margin: { top: 1, bottom: 1, left: 0, right: 0 },\n borderStyle: 'round',\n borderColor: 'green',\n title: title || 'Success',\n titleAlignment: 'center',\n })\n );\n};\n\nexport const errorBox = (message: string, title?: string): void => {\n console.log(\n boxen(message, {\n padding: 1,\n margin: { top: 1, bottom: 1, left: 0, right: 0 },\n borderStyle: 'round',\n borderColor: 'red',\n title: title || 'Error',\n titleAlignment: 'center',\n })\n );\n};\n\nexport const infoBox = (message: string, title?: string): void => {\n console.log(\n boxen(message, {\n padding: 1,\n margin: { top: 1, bottom: 1, left: 0, right: 0 },\n borderStyle: 'round',\n borderColor: 'blue',\n title,\n titleAlignment: 'center',\n })\n );\n};\n\nexport const nextSteps = (steps: string[]): void => {\n const content = steps.map((step, i) => `${chalk.cyan(`${i + 1}.`)} ${step}`).join('\\n');\n\n console.log(\n boxen(content, {\n padding: 1,\n margin: { top: 1, bottom: 0, left: 0, right: 0 },\n borderStyle: 'round',\n borderColor: 'cyan',\n title: 'Next Steps',\n titleAlignment: 'left',\n })\n );\n};\n","import chalk from 'chalk';\n\nexport interface Logger {\n info: (msg: string) => void;\n success: (msg: string) => void;\n warning: (msg: string) => void;\n error: (msg: string) => void;\n debug: (msg: string) => void;\n step: (current: number, total: number, msg: string) => void;\n file: (action: 'add' | 'modify' | 'delete' | 'sync' | 'merge', path: string) => void;\n tree: (items: TreeItem[]) => void;\n blank: () => void;\n dim: (msg: string) => void;\n heading: (msg: string) => void;\n}\n\nexport interface TreeItem {\n name: string;\n isLast: boolean;\n indent?: number;\n}\n\nexport const logger: Logger = {\n info: (msg: string) => {\n console.log(chalk.blue('i'), msg);\n },\n\n success: (msg: string) => {\n console.log(chalk.green('ok'), msg);\n },\n\n warning: (msg: string) => {\n console.log(chalk.yellow('!'), msg);\n },\n\n error: (msg: string) => {\n console.log(chalk.red('x'), msg);\n },\n\n debug: (msg: string) => {\n if (process.env.DEBUG) {\n console.log(chalk.gray('*'), chalk.gray(msg));\n }\n },\n\n step: (current: number, total: number, msg: string) => {\n console.log(chalk.dim(`[${current}/${total}]`), msg);\n },\n\n file: (action: 'add' | 'modify' | 'delete' | 'sync' | 'merge', path: string) => {\n const icons = {\n add: chalk.green('+'),\n modify: chalk.yellow('~'),\n delete: chalk.red('-'),\n sync: chalk.blue('<>'),\n merge: chalk.magenta('+'),\n };\n console.log(` ${icons[action]} ${path}`);\n },\n\n tree: (items: TreeItem[]) => {\n items.forEach(({ name, isLast, indent = 0 }) => {\n const indentation = ' '.repeat(indent);\n const prefix = isLast ? '└── ' : '├── ';\n console.log(chalk.dim(indentation + prefix) + name);\n });\n },\n\n blank: () => {\n console.log();\n },\n\n dim: (msg: string) => {\n console.log(chalk.dim(msg));\n },\n\n heading: (msg: string) => {\n console.log(chalk.bold.cyan(msg));\n },\n};\n\nexport const formatPath = (path: string): string => {\n return chalk.cyan(path);\n};\n\nexport const formatCategory = (category: string, icon?: string): string => {\n return icon ? `${icon} ${chalk.bold(category)}` : chalk.bold(category);\n};\n\nexport const formatCount = (count: number, singular: string, plural?: string): string => {\n const word = count === 1 ? singular : (plural || `${singular}s`);\n return `${chalk.bold(count.toString())} ${word}`;\n};\n\nexport const formatStatus = (status: string): string => {\n switch (status) {\n case 'modified':\n return chalk.yellow('modified');\n case 'added':\n return chalk.green('added');\n case 'deleted':\n return chalk.red('deleted');\n case 'untracked':\n return chalk.gray('untracked');\n default:\n return status;\n }\n};\n","import * as p from '@clack/prompts';\nimport chalk from 'chalk';\n\nexport interface SelectOption<T> {\n value: T;\n label: string;\n hint?: string;\n}\n\nexport const prompts = {\n intro: (title: string): void => {\n p.intro(chalk.bgCyan(chalk.black(` ${title} `)));\n },\n\n outro: (message: string): void => {\n p.outro(chalk.green(message));\n },\n\n confirm: async (message: string, initial = false): Promise<boolean> => {\n const result = await p.confirm({ message, initialValue: initial });\n if (p.isCancel(result)) {\n prompts.cancel();\n }\n return result as boolean;\n },\n\n select: async <T>(message: string, options: SelectOption<T>[]): Promise<T> => {\n const result = await p.select({\n message,\n options: options.map((opt) => ({\n value: opt.value,\n label: opt.label,\n hint: opt.hint,\n })),\n });\n if (p.isCancel(result)) {\n prompts.cancel();\n }\n return result as T;\n },\n\n multiselect: async <T>(\n message: string,\n options: SelectOption<T>[],\n required = false\n ): Promise<T[]> => {\n const result = await p.multiselect({\n message,\n options: options.map((opt) => ({\n value: opt.value,\n label: opt.label,\n hint: opt.hint,\n })),\n required,\n });\n if (p.isCancel(result)) {\n prompts.cancel();\n }\n return result as T[];\n },\n\n text: async (\n message: string,\n options?: {\n placeholder?: string;\n defaultValue?: string;\n validate?: (value: string) => string | undefined;\n }\n ): Promise<string> => {\n const result = await p.text({\n message,\n placeholder: options?.placeholder,\n defaultValue: options?.defaultValue,\n validate: options?.validate,\n });\n if (p.isCancel(result)) {\n prompts.cancel();\n }\n return result as string;\n },\n\n password: async (message: string): Promise<string> => {\n const result = await p.password({ message });\n if (p.isCancel(result)) {\n prompts.cancel();\n }\n return result as string;\n },\n\n spinner: () => p.spinner(),\n\n note: (message: string, title?: string): void => {\n p.note(message, title);\n },\n\n cancel: (message = 'Operation cancelled'): never => {\n p.cancel(message);\n process.exit(0);\n },\n\n log: {\n info: (message: string): void => {\n p.log.info(message);\n },\n success: (message: string): void => {\n p.log.success(message);\n },\n warning: (message: string): void => {\n p.log.warning(message);\n },\n error: (message: string): void => {\n p.log.error(message);\n },\n step: (message: string): void => {\n p.log.step(message);\n },\n message: (message: string): void => {\n p.log.message(message);\n },\n },\n\n group: async <T>(\n steps: Record<string, () => Promise<T | symbol>>,\n options?: { onCancel?: () => void }\n ): Promise<Record<string, T>> => {\n const results = await p.group(steps, {\n onCancel: () => {\n if (options?.onCancel) {\n options.onCancel();\n } else {\n prompts.cancel();\n }\n },\n });\n return results as Record<string, T>;\n },\n};\n\nexport const isCancel = p.isCancel;\n","import ora, { Ora } from 'ora';\nimport chalk from 'chalk';\n\nexport interface SpinnerInstance {\n start: (text?: string) => void;\n stop: () => void;\n succeed: (text?: string) => void;\n fail: (text?: string) => void;\n warn: (text?: string) => void;\n info: (text?: string) => void;\n text: (text: string) => void;\n}\n\nexport const createSpinner = (initialText?: string): SpinnerInstance => {\n const spinner: Ora = ora({\n text: initialText,\n color: 'cyan',\n spinner: 'dots',\n });\n\n return {\n start: (text?: string) => {\n if (text) spinner.text = text;\n spinner.start();\n },\n stop: () => {\n spinner.stop();\n },\n succeed: (text?: string) => {\n spinner.succeed(text ? chalk.green(text) : undefined);\n },\n fail: (text?: string) => {\n spinner.fail(text ? chalk.red(text) : undefined);\n },\n warn: (text?: string) => {\n spinner.warn(text ? chalk.yellow(text) : undefined);\n },\n info: (text?: string) => {\n spinner.info(text ? chalk.blue(text) : undefined);\n },\n text: (text: string) => {\n spinner.text = text;\n },\n };\n};\n\nexport const withSpinner = async <T>(\n text: string,\n fn: () => Promise<T>,\n options?: {\n successText?: string;\n failText?: string;\n }\n): Promise<T> => {\n const spinner = createSpinner(text);\n spinner.start();\n\n try {\n const result = await fn();\n spinner.succeed(options?.successText || text);\n return result;\n } catch (error) {\n spinner.fail(options?.failText || text);\n throw error;\n }\n};\n","import chalk from 'chalk';\n\nexport interface TableColumn {\n header: string;\n key: string;\n width?: number;\n align?: 'left' | 'right' | 'center';\n format?: (value: unknown) => string;\n}\n\nexport interface TableOptions {\n columns: TableColumn[];\n border?: boolean;\n padding?: number;\n}\n\nconst padString = (str: string, width: number, align: 'left' | 'right' | 'center' = 'left'): string => {\n // eslint-disable-next-line no-control-regex\n const visibleLength = str.replace(/\\x1b\\[[0-9;]*m/g, '').length;\n const padding = Math.max(0, width - visibleLength);\n\n switch (align) {\n case 'right':\n return ' '.repeat(padding) + str;\n case 'center': {\n const leftPad = Math.floor(padding / 2);\n const rightPad = padding - leftPad;\n return ' '.repeat(leftPad) + str + ' '.repeat(rightPad);\n }\n default:\n return str + ' '.repeat(padding);\n }\n};\n\nexport const createTable = (\n data: Record<string, unknown>[],\n options: TableOptions\n): string => {\n const { columns, border = false, padding = 2 } = options;\n\n // Calculate column widths\n const widths = columns.map((col) => {\n const headerWidth = col.header.length;\n const maxDataWidth = data.reduce((max, row) => {\n const value = col.format ? col.format(row[col.key]) : String(row[col.key] ?? '');\n // eslint-disable-next-line no-control-regex\n const visibleLength = value.replace(/\\x1b\\[[0-9;]*m/g, '').length;\n return Math.max(max, visibleLength);\n }, 0);\n return col.width || Math.max(headerWidth, maxDataWidth);\n });\n\n const lines: string[] = [];\n const pad = ' '.repeat(padding);\n\n // Header\n const headerRow = columns\n .map((col, i) => chalk.bold(padString(col.header, widths[i], col.align)))\n .join(pad);\n\n if (border) {\n const borderLine = widths.map((w) => '─'.repeat(w)).join(pad);\n lines.push(chalk.dim(borderLine));\n lines.push(headerRow);\n lines.push(chalk.dim(borderLine));\n } else {\n lines.push(headerRow);\n lines.push(chalk.dim(widths.map((w) => '─'.repeat(w)).join(pad)));\n }\n\n // Data rows\n data.forEach((row) => {\n const dataRow = columns\n .map((col, i) => {\n const value = col.format ? col.format(row[col.key]) : String(row[col.key] ?? '');\n return padString(value, widths[i], col.align);\n })\n .join(pad);\n lines.push(dataRow);\n });\n\n if (border) {\n lines.push(chalk.dim(widths.map((w) => '─'.repeat(w)).join(pad)));\n }\n\n return lines.join('\\n');\n};\n\nexport const printTable = (data: Record<string, unknown>[], options: TableOptions): void => {\n console.log(createTable(data, options));\n};\n","export * from './banner.js';\nexport * from './logger.js';\nexport * from './prompts.js';\nexport * from './spinner.js';\nexport * from './table.js';\n","import { homedir } from 'os';\nimport { join } from 'path';\n\nexport const VERSION = '0.1.0';\nexport const DESCRIPTION = 'Modern dotfiles manager with a beautiful CLI';\nexport const APP_NAME = 'tuck';\n\nexport const HOME_DIR = homedir();\nexport const DEFAULT_TUCK_DIR = join(HOME_DIR, '.tuck');\nexport const MANIFEST_FILE = '.tuckmanifest.json';\nexport const CONFIG_FILE = '.tuckrc.json';\nexport const BACKUP_DIR = join(HOME_DIR, '.tuck-backups');\nexport const FILES_DIR = 'files';\n\nexport const MANIFEST_VERSION = '1.0.0';\n\nexport interface CategoryConfig {\n patterns: string[];\n icon: string;\n}\n\nexport const CATEGORIES: Record<string, CategoryConfig> = {\n shell: {\n patterns: [\n '.zshrc',\n '.bashrc',\n '.bash_profile',\n '.zprofile',\n '.profile',\n '.aliases',\n '.zshenv',\n '.bash_aliases',\n '.inputrc',\n ],\n icon: '$',\n },\n git: {\n patterns: ['.gitconfig', '.gitignore_global', '.gitmessage', '.gitattributes'],\n icon: '*',\n },\n editors: {\n patterns: [\n '.vimrc',\n '.config/nvim',\n '.emacs',\n '.emacs.d',\n '.config/Code',\n '.ideavimrc',\n '.nanorc',\n ],\n icon: '>',\n },\n terminal: {\n patterns: [\n '.tmux.conf',\n '.config/alacritty',\n '.config/kitty',\n '.wezterm.lua',\n '.config/wezterm',\n '.config/hyper',\n '.config/starship.toml',\n ],\n icon: '#',\n },\n ssh: {\n patterns: ['.ssh/config'],\n icon: '!',\n },\n misc: {\n patterns: [],\n icon: '-',\n },\n};\n\nexport const COMMON_DOTFILES = [\n { path: '~/.zshrc', category: 'shell' },\n { path: '~/.bashrc', category: 'shell' },\n { path: '~/.bash_profile', category: 'shell' },\n { path: '~/.gitconfig', category: 'git' },\n { path: '~/.config/nvim', category: 'editors' },\n { path: '~/.vimrc', category: 'editors' },\n { path: '~/.tmux.conf', category: 'terminal' },\n { path: '~/.ssh/config', category: 'ssh' },\n { path: '~/.config/starship.toml', category: 'terminal' },\n];\n","import { homedir } from 'os';\nimport { join, basename, dirname, relative, isAbsolute, resolve } from 'path';\nimport { stat, access } from 'fs/promises';\nimport { constants } from 'fs';\nimport { DEFAULT_TUCK_DIR, FILES_DIR, MANIFEST_FILE, CONFIG_FILE, CATEGORIES } from '../constants.js';\n\nexport const expandPath = (path: string): string => {\n if (path.startsWith('~/')) {\n return join(homedir(), path.slice(2));\n }\n if (path.startsWith('$HOME/')) {\n return join(homedir(), path.slice(6));\n }\n return isAbsolute(path) ? path : resolve(path);\n};\n\nexport const collapsePath = (path: string): string => {\n const home = homedir();\n if (path.startsWith(home)) {\n return '~' + path.slice(home.length);\n }\n return path;\n};\n\nexport const getTuckDir = (customDir?: string): string => {\n return expandPath(customDir || DEFAULT_TUCK_DIR);\n};\n\nexport const getManifestPath = (tuckDir: string): string => {\n return join(tuckDir, MANIFEST_FILE);\n};\n\nexport const getConfigPath = (tuckDir: string): string => {\n return join(tuckDir, CONFIG_FILE);\n};\n\nexport const getFilesDir = (tuckDir: string): string => {\n return join(tuckDir, FILES_DIR);\n};\n\nexport const getCategoryDir = (tuckDir: string, category: string): string => {\n return join(getFilesDir(tuckDir), category);\n};\n\nexport const getDestinationPath = (tuckDir: string, category: string, filename: string): string => {\n return join(getCategoryDir(tuckDir, category), filename);\n};\n\nexport const getRelativeDestination = (category: string, filename: string): string => {\n return join(FILES_DIR, category, filename);\n};\n\nexport const sanitizeFilename = (filepath: string): string => {\n const base = basename(filepath);\n // Remove leading dot for storage, but keep track that it was a dotfile\n return base.startsWith('.') ? base.slice(1) : base;\n};\n\nexport const detectCategory = (filepath: string): string => {\n const expandedPath = expandPath(filepath);\n const relativePath = collapsePath(expandedPath);\n\n for (const [category, config] of Object.entries(CATEGORIES)) {\n for (const pattern of config.patterns) {\n // Check if the pattern matches the path\n if (relativePath.endsWith(pattern) || relativePath.includes(pattern)) {\n return category;\n }\n // Check just the filename\n const filename = basename(expandedPath);\n if (filename === pattern || filename === basename(pattern)) {\n return category;\n }\n }\n }\n\n return 'misc';\n};\n\nexport const pathExists = async (path: string): Promise<boolean> => {\n try {\n await access(path, constants.F_OK);\n return true;\n } catch {\n return false;\n }\n};\n\nexport const isDirectory = async (path: string): Promise<boolean> => {\n try {\n const stats = await stat(path);\n return stats.isDirectory();\n } catch {\n return false;\n }\n};\n\nexport const isFile = async (path: string): Promise<boolean> => {\n try {\n const stats = await stat(path);\n return stats.isFile();\n } catch {\n return false;\n }\n};\n\nexport const isSymlink = async (path: string): Promise<boolean> => {\n try {\n const stats = await stat(path);\n return stats.isSymbolicLink();\n } catch {\n return false;\n }\n};\n\nexport const isReadable = async (path: string): Promise<boolean> => {\n try {\n await access(path, constants.R_OK);\n return true;\n } catch {\n return false;\n }\n};\n\nexport const isWritable = async (path: string): Promise<boolean> => {\n try {\n await access(path, constants.W_OK);\n return true;\n } catch {\n return false;\n }\n};\n\nexport const getRelativePath = (from: string, to: string): string => {\n return relative(dirname(from), to);\n};\n\n/**\n * Validate that a path is safely within the user's home directory.\n * Prevents path traversal attacks from malicious manifests.\n * @returns true if the path is within home directory, false otherwise\n */\nexport const isPathWithinHome = (path: string): boolean => {\n const home = homedir();\n const expandedPath = expandPath(path);\n const normalizedPath = resolve(expandedPath);\n const normalizedHome = resolve(home);\n\n // Check if the normalized path starts with the home directory\n return normalizedPath.startsWith(normalizedHome + '/') || normalizedPath === normalizedHome;\n};\n\n/**\n * Validate that a source path from a manifest is safe to use.\n * Throws an error if the path is unsafe (path traversal attempt).\n */\nexport const validateSafeSourcePath = (source: string): void => {\n // Reject absolute paths that don't start with home-relative prefixes\n if (isAbsolute(source) && !source.startsWith(homedir())) {\n throw new Error(`Unsafe path detected: ${source} - absolute paths outside home directory are not allowed`);\n }\n\n // Reject obvious path traversal attempts\n if (source.includes('../') || source.includes('..\\\\')) {\n throw new Error(`Unsafe path detected: ${source} - path traversal is not allowed`);\n }\n\n // Validate the expanded path is within home\n if (!isPathWithinHome(source)) {\n throw new Error(`Unsafe path detected: ${source} - paths must be within home directory`);\n }\n};\n\nexport const generateFileId = (source: string): string => {\n // Create a unique ID from the source path\n const collapsed = collapsePath(source);\n // Remove special characters and create a readable ID\n return collapsed\n .replace(/^~\\//, '')\n .replace(/\\//g, '_')\n .replace(/\\./g, '-')\n .replace(/^-/, '');\n};\n","import { z } from 'zod';\n\nexport const fileStrategySchema = z.enum(['copy', 'symlink']);\n\nexport const categoryConfigSchema = z.object({\n patterns: z.array(z.string()),\n icon: z.string().optional(),\n});\n\nexport const tuckConfigSchema = z.object({\n repository: z\n .object({\n path: z.string(),\n defaultBranch: z.string().default('main'),\n autoCommit: z.boolean().default(true),\n autoPush: z.boolean().default(false),\n })\n .partial()\n .default({}),\n\n files: z\n .object({\n strategy: fileStrategySchema.default('copy'),\n backupOnRestore: z.boolean().default(true),\n backupDir: z.string().optional(),\n })\n .partial()\n .default({}),\n\n categories: z.record(categoryConfigSchema).optional().default({}),\n\n ignore: z.array(z.string()).optional().default([]),\n\n hooks: z\n .object({\n preSync: z.string().optional(),\n postSync: z.string().optional(),\n preRestore: z.string().optional(),\n postRestore: z.string().optional(),\n })\n .partial()\n .default({}),\n\n templates: z\n .object({\n enabled: z.boolean().default(false),\n variables: z.record(z.string()).default({}),\n })\n .partial()\n .default({}),\n\n encryption: z\n .object({\n enabled: z.boolean().default(false),\n gpgKey: z.string().optional(),\n files: z.array(z.string()).default([]),\n })\n .partial()\n .default({}),\n\n ui: z\n .object({\n colors: z.boolean().default(true),\n emoji: z.boolean().default(true),\n verbose: z.boolean().default(false),\n })\n .partial()\n .default({}),\n});\n\nexport type TuckConfigInput = z.input<typeof tuckConfigSchema>;\nexport type TuckConfigOutput = z.output<typeof tuckConfigSchema>;\n\nexport const defaultConfig: TuckConfigOutput = {\n repository: {\n defaultBranch: 'main',\n autoCommit: true,\n autoPush: false,\n },\n files: {\n strategy: 'copy',\n backupOnRestore: true,\n },\n categories: {},\n ignore: [],\n hooks: {},\n templates: {\n enabled: false,\n variables: {},\n },\n encryption: {\n enabled: false,\n files: [],\n },\n ui: {\n colors: true,\n emoji: true,\n verbose: false,\n },\n};\n","import chalk from 'chalk';\n\nexport class TuckError extends Error {\n constructor(\n message: string,\n public code: string,\n public suggestions?: string[]\n ) {\n super(message);\n this.name = 'TuckError';\n }\n}\n\nexport class NotInitializedError extends TuckError {\n constructor() {\n super('Tuck is not initialized in this system', 'NOT_INITIALIZED', [\n 'Run `tuck init` to get started',\n ]);\n }\n}\n\nexport class AlreadyInitializedError extends TuckError {\n constructor(path: string) {\n super(`Tuck is already initialized at ${path}`, 'ALREADY_INITIALIZED', [\n 'Use `tuck status` to see current state',\n `Remove ${path} to reinitialize`,\n ]);\n }\n}\n\nexport class FileNotFoundError extends TuckError {\n constructor(path: string) {\n super(`File not found: ${path}`, 'FILE_NOT_FOUND', [\n 'Check that the path is correct',\n 'Use absolute paths or paths relative to home directory',\n ]);\n }\n}\n\nexport class FileNotTrackedError extends TuckError {\n constructor(path: string) {\n super(`File is not tracked: ${path}`, 'FILE_NOT_TRACKED', [\n `Run \\`tuck add ${path}\\` to track this file`,\n 'Run `tuck list` to see all tracked files',\n ]);\n }\n}\n\nexport class FileAlreadyTrackedError extends TuckError {\n constructor(path: string) {\n super(`File is already tracked: ${path}`, 'FILE_ALREADY_TRACKED', [\n 'Run `tuck sync` to update it',\n `Run \\`tuck remove ${path}\\` to untrack`,\n ]);\n }\n}\n\nexport class GitError extends TuckError {\n constructor(message: string, gitError?: string) {\n super(`Git operation failed: ${message}`, 'GIT_ERROR', gitError ? [gitError] : undefined);\n }\n}\n\nexport class ConfigError extends TuckError {\n constructor(message: string) {\n super(`Configuration error: ${message}`, 'CONFIG_ERROR', [\n 'Run `tuck config edit` to fix configuration',\n 'Run `tuck config reset` to restore defaults',\n ]);\n }\n}\n\nexport class ManifestError extends TuckError {\n constructor(message: string) {\n super(`Manifest error: ${message}`, 'MANIFEST_ERROR', [\n 'The manifest file may be corrupted',\n 'Run `tuck init --from <remote>` to restore from remote',\n ]);\n }\n}\n\nexport class PermissionError extends TuckError {\n constructor(path: string, operation: string) {\n super(`Permission denied: cannot ${operation} ${path}`, 'PERMISSION_ERROR', [\n 'Check file permissions',\n 'Try running with appropriate permissions',\n ]);\n }\n}\n\nexport class GitHubCliError extends TuckError {\n constructor(message: string, suggestions?: string[]) {\n super(\n `GitHub CLI error: ${message}`,\n 'GITHUB_CLI_ERROR',\n suggestions || ['Install GitHub CLI: https://cli.github.com/', 'Run `gh auth login` to authenticate']\n );\n }\n}\n\nexport class BackupError extends TuckError {\n constructor(message: string, suggestions?: string[]) {\n super(`Backup error: ${message}`, 'BACKUP_ERROR', suggestions || ['Check available disk space']);\n }\n}\n\nexport const handleError = (error: unknown): never => {\n if (error instanceof TuckError) {\n console.error(chalk.red('x'), error.message);\n if (error.suggestions && error.suggestions.length > 0) {\n console.error();\n console.error(chalk.dim('Suggestions:'));\n error.suggestions.forEach((s) => console.error(chalk.dim(` → ${s}`)));\n }\n process.exit(1);\n }\n\n if (error instanceof Error) {\n console.error(chalk.red('x'), 'An unexpected error occurred:', error.message);\n if (process.env.DEBUG) {\n console.error(error.stack);\n }\n process.exit(1);\n }\n\n console.error(chalk.red('x'), 'An unknown error occurred');\n process.exit(1);\n};\n","import { readFile, writeFile } from 'fs/promises';\nimport { cosmiconfig } from 'cosmiconfig';\nimport { tuckConfigSchema, defaultConfig, type TuckConfigOutput } from '../schemas/config.schema.js';\nimport { getConfigPath, pathExists, getTuckDir } from './paths.js';\nimport { ConfigError } from '../errors.js';\nimport { BACKUP_DIR } from '../constants.js';\n\nlet cachedConfig: TuckConfigOutput | null = null;\nlet cachedTuckDir: string | null = null;\n\nexport const loadConfig = async (tuckDir?: string): Promise<TuckConfigOutput> => {\n const dir = tuckDir || getTuckDir();\n\n // Return cached config if same directory\n if (cachedConfig && cachedTuckDir === dir) {\n return cachedConfig;\n }\n\n const configPath = getConfigPath(dir);\n\n if (!(await pathExists(configPath))) {\n // Return default config if no config file exists\n cachedConfig = { ...defaultConfig, repository: { ...defaultConfig.repository, path: dir } };\n cachedTuckDir = dir;\n return cachedConfig;\n }\n\n try {\n const content = await readFile(configPath, 'utf-8');\n const rawConfig = JSON.parse(content);\n const result = tuckConfigSchema.safeParse(rawConfig);\n\n if (!result.success) {\n throw new ConfigError(`Invalid configuration: ${result.error.message}`);\n }\n\n // Merge with defaults\n cachedConfig = {\n ...defaultConfig,\n ...result.data,\n repository: {\n ...defaultConfig.repository,\n ...result.data.repository,\n path: dir,\n },\n files: {\n ...defaultConfig.files,\n ...result.data.files,\n backupDir: result.data.files?.backupDir || BACKUP_DIR,\n },\n };\n cachedTuckDir = dir;\n\n return cachedConfig;\n } catch (error) {\n if (error instanceof ConfigError) {\n throw error;\n }\n if (error instanceof SyntaxError) {\n throw new ConfigError('Configuration file contains invalid JSON');\n }\n throw new ConfigError(`Failed to load configuration: ${error}`);\n }\n};\n\nexport const saveConfig = async (\n config: Partial<TuckConfigOutput>,\n tuckDir?: string\n): Promise<void> => {\n const dir = tuckDir || getTuckDir();\n const configPath = getConfigPath(dir);\n\n // Load existing config and merge\n const existing = await loadConfig(dir);\n const merged = {\n ...existing,\n ...config,\n repository: {\n ...existing.repository,\n ...config.repository,\n },\n files: {\n ...existing.files,\n ...config.files,\n },\n hooks: {\n ...existing.hooks,\n ...config.hooks,\n },\n templates: {\n ...existing.templates,\n ...config.templates,\n },\n encryption: {\n ...existing.encryption,\n ...config.encryption,\n },\n ui: {\n ...existing.ui,\n ...config.ui,\n },\n };\n\n // Validate before saving\n const result = tuckConfigSchema.safeParse(merged);\n if (!result.success) {\n throw new ConfigError(`Invalid configuration: ${result.error.message}`);\n }\n\n try {\n await writeFile(configPath, JSON.stringify(result.data, null, 2) + '\\n', 'utf-8');\n // Update cache\n cachedConfig = result.data;\n cachedTuckDir = dir;\n } catch (error) {\n throw new ConfigError(`Failed to save configuration: ${error}`);\n }\n};\n\nexport const getConfigValue = async <K extends keyof TuckConfigOutput>(\n key: K,\n tuckDir?: string\n): Promise<TuckConfigOutput[K]> => {\n const config = await loadConfig(tuckDir);\n return config[key];\n};\n\nexport const setConfigValue = async <K extends keyof TuckConfigOutput>(\n key: K,\n value: TuckConfigOutput[K],\n tuckDir?: string\n): Promise<void> => {\n await saveConfig({ [key]: value } as Partial<TuckConfigOutput>, tuckDir);\n};\n\nexport const resetConfig = async (tuckDir?: string): Promise<void> => {\n const dir = tuckDir || getTuckDir();\n const configPath = getConfigPath(dir);\n\n const resetTo = { ...defaultConfig, repository: { ...defaultConfig.repository, path: dir } };\n\n try {\n await writeFile(configPath, JSON.stringify(resetTo, null, 2) + '\\n', 'utf-8');\n cachedConfig = resetTo;\n cachedTuckDir = dir;\n } catch (error) {\n throw new ConfigError(`Failed to reset configuration: ${error}`);\n }\n};\n\nexport const clearConfigCache = (): void => {\n cachedConfig = null;\n cachedTuckDir = null;\n};\n\nexport const findTuckDir = async (): Promise<string | null> => {\n // First check default location\n const defaultDir = getTuckDir();\n if (await pathExists(getConfigPath(defaultDir))) {\n return defaultDir;\n }\n\n // Try cosmiconfig to find config in current directory or parents\n const explorer = cosmiconfig('tuck', {\n searchPlaces: [\n '.tuckrc',\n '.tuckrc.json',\n '.tuckrc.yaml',\n '.tuckrc.yml',\n 'tuck.config.js',\n 'tuck.config.cjs',\n ],\n });\n\n try {\n const result = await explorer.search();\n if (result?.filepath) {\n return result.filepath;\n }\n } catch {\n // Ignore search errors\n }\n\n return null;\n};\n","import { z } from 'zod';\n\nexport const fileStrategySchema = z.enum(['copy', 'symlink']);\n\nexport const trackedFileSchema = z.object({\n source: z.string(),\n destination: z.string(),\n category: z.string(),\n strategy: fileStrategySchema,\n encrypted: z.boolean().default(false),\n template: z.boolean().default(false),\n permissions: z.string().optional(),\n added: z.string(),\n modified: z.string(),\n checksum: z.string(),\n});\n\nexport const tuckManifestSchema = z.object({\n version: z.string(),\n created: z.string(),\n updated: z.string(),\n machine: z.string().optional(),\n files: z.record(trackedFileSchema),\n});\n\nexport type TrackedFileInput = z.input<typeof trackedFileSchema>;\nexport type TrackedFileOutput = z.output<typeof trackedFileSchema>;\nexport type TuckManifestInput = z.input<typeof tuckManifestSchema>;\nexport type TuckManifestOutput = z.output<typeof tuckManifestSchema>;\n\nexport const createEmptyManifest = (machine?: string): TuckManifestOutput => {\n const now = new Date().toISOString();\n return {\n version: '1.0.0',\n created: now,\n updated: now,\n machine,\n files: {},\n };\n};\n","import { readFile, writeFile } from 'fs/promises';\nimport {\n tuckManifestSchema,\n createEmptyManifest,\n type TuckManifestOutput,\n type TrackedFileOutput,\n} from '../schemas/manifest.schema.js';\nimport { getManifestPath, pathExists } from './paths.js';\nimport { ManifestError } from '../errors.js';\n\nlet cachedManifest: TuckManifestOutput | null = null;\nlet cachedManifestDir: string | null = null;\n\nexport const loadManifest = async (tuckDir: string): Promise<TuckManifestOutput> => {\n // Return cached manifest if same directory\n if (cachedManifest && cachedManifestDir === tuckDir) {\n return cachedManifest;\n }\n\n const manifestPath = getManifestPath(tuckDir);\n\n if (!(await pathExists(manifestPath))) {\n throw new ManifestError('Manifest file not found. Is tuck initialized?');\n }\n\n try {\n const content = await readFile(manifestPath, 'utf-8');\n const rawManifest = JSON.parse(content);\n const result = tuckManifestSchema.safeParse(rawManifest);\n\n if (!result.success) {\n throw new ManifestError(`Invalid manifest: ${result.error.message}`);\n }\n\n cachedManifest = result.data;\n cachedManifestDir = tuckDir;\n\n return cachedManifest;\n } catch (error) {\n if (error instanceof ManifestError) {\n throw error;\n }\n if (error instanceof SyntaxError) {\n throw new ManifestError('Manifest file contains invalid JSON');\n }\n throw new ManifestError(`Failed to load manifest: ${error}`);\n }\n};\n\nexport const saveManifest = async (\n manifest: TuckManifestOutput,\n tuckDir: string\n): Promise<void> => {\n const manifestPath = getManifestPath(tuckDir);\n\n // Update the updated timestamp\n manifest.updated = new Date().toISOString();\n\n // Validate before saving\n const result = tuckManifestSchema.safeParse(manifest);\n if (!result.success) {\n throw new ManifestError(`Invalid manifest: ${result.error.message}`);\n }\n\n try {\n await writeFile(manifestPath, JSON.stringify(result.data, null, 2) + '\\n', 'utf-8');\n cachedManifest = result.data;\n cachedManifestDir = tuckDir;\n } catch (error) {\n throw new ManifestError(`Failed to save manifest: ${error}`);\n }\n};\n\nexport const createManifest = async (\n tuckDir: string,\n machine?: string\n): Promise<TuckManifestOutput> => {\n const manifestPath = getManifestPath(tuckDir);\n\n if (await pathExists(manifestPath)) {\n throw new ManifestError('Manifest already exists');\n }\n\n const manifest = createEmptyManifest(machine);\n\n try {\n await writeFile(manifestPath, JSON.stringify(manifest, null, 2) + '\\n', 'utf-8');\n cachedManifest = manifest;\n cachedManifestDir = tuckDir;\n return manifest;\n } catch (error) {\n throw new ManifestError(`Failed to create manifest: ${error}`);\n }\n};\n\nexport const addFileToManifest = async (\n tuckDir: string,\n id: string,\n file: TrackedFileOutput\n): Promise<void> => {\n const manifest = await loadManifest(tuckDir);\n\n if (manifest.files[id]) {\n throw new ManifestError(`File already tracked with ID: ${id}`);\n }\n\n manifest.files[id] = file;\n await saveManifest(manifest, tuckDir);\n};\n\nexport const updateFileInManifest = async (\n tuckDir: string,\n id: string,\n updates: Partial<TrackedFileOutput>\n): Promise<void> => {\n const manifest = await loadManifest(tuckDir);\n\n if (!manifest.files[id]) {\n throw new ManifestError(`File not found in manifest: ${id}`);\n }\n\n manifest.files[id] = {\n ...manifest.files[id],\n ...updates,\n modified: new Date().toISOString(),\n };\n\n await saveManifest(manifest, tuckDir);\n};\n\nexport const removeFileFromManifest = async (tuckDir: string, id: string): Promise<void> => {\n const manifest = await loadManifest(tuckDir);\n\n if (!manifest.files[id]) {\n throw new ManifestError(`File not found in manifest: ${id}`);\n }\n\n delete manifest.files[id];\n await saveManifest(manifest, tuckDir);\n};\n\nexport const getTrackedFile = async (\n tuckDir: string,\n id: string\n): Promise<TrackedFileOutput | null> => {\n const manifest = await loadManifest(tuckDir);\n return manifest.files[id] || null;\n};\n\nexport const getTrackedFileBySource = async (\n tuckDir: string,\n source: string\n): Promise<{ id: string; file: TrackedFileOutput } | null> => {\n const manifest = await loadManifest(tuckDir);\n\n for (const [id, file] of Object.entries(manifest.files)) {\n if (file.source === source) {\n return { id, file };\n }\n }\n\n return null;\n};\n\nexport const getAllTrackedFiles = async (\n tuckDir: string\n): Promise<Record<string, TrackedFileOutput>> => {\n const manifest = await loadManifest(tuckDir);\n return manifest.files;\n};\n\nexport const getTrackedFilesByCategory = async (\n tuckDir: string,\n category: string\n): Promise<Record<string, TrackedFileOutput>> => {\n const manifest = await loadManifest(tuckDir);\n const filtered: Record<string, TrackedFileOutput> = {};\n\n for (const [id, file] of Object.entries(manifest.files)) {\n if (file.category === category) {\n filtered[id] = file;\n }\n }\n\n return filtered;\n};\n\nexport const isFileTracked = async (tuckDir: string, source: string): Promise<boolean> => {\n const result = await getTrackedFileBySource(tuckDir, source);\n return result !== null;\n};\n\nexport const getFileCount = async (tuckDir: string): Promise<number> => {\n const manifest = await loadManifest(tuckDir);\n return Object.keys(manifest.files).length;\n};\n\nexport const getCategories = async (tuckDir: string): Promise<string[]> => {\n const manifest = await loadManifest(tuckDir);\n const categories = new Set<string>();\n\n for (const file of Object.values(manifest.files)) {\n categories.add(file.category);\n }\n\n return Array.from(categories).sort();\n};\n\nexport const clearManifestCache = (): void => {\n cachedManifest = null;\n cachedManifestDir = null;\n};\n","import { createHash } from 'crypto';\nimport { readFile, stat, readdir, copyFile, symlink, unlink, rm } from 'fs/promises';\nimport { copy, ensureDir } from 'fs-extra';\nimport { join, dirname } from 'path';\nimport { FileNotFoundError, PermissionError } from '../errors.js';\nimport { expandPath, pathExists, isDirectory } from './paths.js';\n\nexport interface FileInfo {\n path: string;\n isDirectory: boolean;\n isSymlink: boolean;\n size: number;\n permissions: string;\n modified: Date;\n}\n\nexport interface CopyResult {\n source: string;\n destination: string;\n fileCount: number;\n totalSize: number;\n}\n\nexport const getFileChecksum = async (filepath: string): Promise<string> => {\n const expandedPath = expandPath(filepath);\n\n if (await isDirectory(expandedPath)) {\n // For directories, create a hash of all file checksums\n const files = await getDirectoryFiles(expandedPath);\n const hashes: string[] = [];\n\n for (const file of files) {\n const content = await readFile(file);\n hashes.push(createHash('sha256').update(content).digest('hex'));\n }\n\n return createHash('sha256').update(hashes.join('')).digest('hex');\n }\n\n const content = await readFile(expandedPath);\n return createHash('sha256').update(content).digest('hex');\n};\n\nexport const getFileInfo = async (filepath: string): Promise<FileInfo> => {\n const expandedPath = expandPath(filepath);\n\n if (!(await pathExists(expandedPath))) {\n throw new FileNotFoundError(filepath);\n }\n\n try {\n const stats = await stat(expandedPath);\n const permissions = (stats.mode & 0o777).toString(8).padStart(3, '0');\n\n return {\n path: expandedPath,\n isDirectory: stats.isDirectory(),\n isSymlink: stats.isSymbolicLink(),\n size: stats.size,\n permissions,\n modified: stats.mtime,\n };\n } catch (error) {\n throw new PermissionError(filepath, 'read');\n }\n};\n\nexport const getDirectoryFiles = async (dirpath: string): Promise<string[]> => {\n const expandedPath = expandPath(dirpath);\n const files: string[] = [];\n\n const entries = await readdir(expandedPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const entryPath = join(expandedPath, entry.name);\n\n if (entry.isDirectory()) {\n const subFiles = await getDirectoryFiles(entryPath);\n files.push(...subFiles);\n } else if (entry.isFile()) {\n files.push(entryPath);\n }\n }\n\n return files.sort();\n};\n\nexport const getDirectoryFileCount = async (dirpath: string): Promise<number> => {\n const files = await getDirectoryFiles(dirpath);\n return files.length;\n};\n\nexport const copyFileOrDir = async (\n source: string,\n destination: string,\n options?: { overwrite?: boolean }\n): Promise<CopyResult> => {\n const expandedSource = expandPath(source);\n const expandedDest = expandPath(destination);\n\n if (!(await pathExists(expandedSource))) {\n throw new FileNotFoundError(source);\n }\n\n // Ensure destination directory exists\n await ensureDir(dirname(expandedDest));\n\n const sourceIsDir = await isDirectory(expandedSource);\n\n try {\n if (sourceIsDir) {\n await copy(expandedSource, expandedDest, { overwrite: options?.overwrite ?? true });\n const fileCount = await getDirectoryFileCount(expandedDest);\n const files = await getDirectoryFiles(expandedDest);\n let totalSize = 0;\n for (const file of files) {\n const stats = await stat(file);\n totalSize += stats.size;\n }\n return { source: expandedSource, destination: expandedDest, fileCount, totalSize };\n } else {\n await copyFile(expandedSource, expandedDest);\n const stats = await stat(expandedDest);\n return { source: expandedSource, destination: expandedDest, fileCount: 1, totalSize: stats.size };\n }\n } catch (error) {\n throw new PermissionError(destination, 'write');\n }\n};\n\nexport const createSymlink = async (\n target: string,\n linkPath: string,\n options?: { overwrite?: boolean }\n): Promise<void> => {\n const expandedTarget = expandPath(target);\n const expandedLink = expandPath(linkPath);\n\n if (!(await pathExists(expandedTarget))) {\n throw new FileNotFoundError(target);\n }\n\n // Ensure link parent directory exists\n await ensureDir(dirname(expandedLink));\n\n // Remove existing file/symlink if overwrite is true\n if (options?.overwrite && (await pathExists(expandedLink))) {\n await unlink(expandedLink);\n }\n\n try {\n await symlink(expandedTarget, expandedLink);\n } catch (error) {\n throw new PermissionError(linkPath, 'create symlink');\n }\n};\n\nexport const deleteFileOrDir = async (filepath: string): Promise<void> => {\n const expandedPath = expandPath(filepath);\n\n if (!(await pathExists(expandedPath))) {\n return; // Already deleted\n }\n\n try {\n if (await isDirectory(expandedPath)) {\n await rm(expandedPath, { recursive: true });\n } else {\n await unlink(expandedPath);\n }\n } catch (error) {\n throw new PermissionError(filepath, 'delete');\n }\n};\n\nexport const ensureDirectory = async (dirpath: string): Promise<void> => {\n const expandedPath = expandPath(dirpath);\n await ensureDir(expandedPath);\n};\n\nexport const moveFile = async (\n source: string,\n destination: string,\n options?: { overwrite?: boolean }\n): Promise<void> => {\n await copyFileOrDir(source, destination, options);\n await deleteFileOrDir(source);\n};\n\nexport const hasFileChanged = async (\n file1: string,\n file2: string\n): Promise<boolean> => {\n const expandedFile1 = expandPath(file1);\n const expandedFile2 = expandPath(file2);\n\n // If either doesn't exist, they're different\n if (!(await pathExists(expandedFile1)) || !(await pathExists(expandedFile2))) {\n return true;\n }\n\n const checksum1 = await getFileChecksum(expandedFile1);\n const checksum2 = await getFileChecksum(expandedFile2);\n\n return checksum1 !== checksum2;\n};\n\nexport const getFilePermissions = async (filepath: string): Promise<string> => {\n const expandedPath = expandPath(filepath);\n const stats = await stat(expandedPath);\n return (stats.mode & 0o777).toString(8).padStart(3, '0');\n};\n\nexport const setFilePermissions = async (filepath: string, mode: string): Promise<void> => {\n const expandedPath = expandPath(filepath);\n const { chmod } = await import('fs/promises');\n await chmod(expandedPath, parseInt(mode, 8));\n};\n\nexport const 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(1))} ${sizes[i]}`;\n};\n","import { Command } from 'commander';\nimport { basename } from 'path';\nimport chalk from 'chalk';\nimport { prompts, logger, withSpinner } from '../ui/index.js';\nimport {\n getTuckDir,\n expandPath,\n collapsePath,\n pathExists,\n isDirectory,\n detectCategory,\n sanitizeFilename,\n getDestinationPath,\n getRelativeDestination,\n generateFileId,\n} from '../lib/paths.js';\nimport { loadConfig } from '../lib/config.js';\nimport {\n addFileToManifest,\n isFileTracked,\n loadManifest,\n} from '../lib/manifest.js';\nimport { copyFileOrDir, getFileChecksum, getDirectoryFileCount, getFileInfo } from '../lib/files.js';\nimport { NotInitializedError, FileNotFoundError, FileAlreadyTrackedError } from '../errors.js';\nimport { CATEGORIES } from '../constants.js';\nimport type { AddOptions } from '../types.js';\n\n// SSH private key patterns - NEVER allow these\nconst PRIVATE_KEY_PATTERNS = [\n /^id_rsa$/,\n /^id_dsa$/,\n /^id_ecdsa$/,\n /^id_ed25519$/,\n /^id_.*$/, // Any id_ file without .pub\n /\\.pem$/,\n /\\.key$/,\n /^.*_key$/, // aws_key, github_key, etc.\n];\n\n// Files that should trigger a warning\nconst SENSITIVE_FILE_PATTERNS = [\n /^\\.netrc$/,\n /^\\.aws\\/credentials$/,\n /^\\.docker\\/config\\.json$/,\n /^\\.npmrc$/, // May contain tokens\n /^\\.pypirc$/,\n /^\\.kube\\/config$/,\n /^\\.ssh\\/config$/,\n /^\\.gnupg\\//,\n /credentials/i,\n /secrets?/i,\n /tokens?\\.json$/i,\n /\\.env$/,\n /\\.env\\./,\n];\n\n/**\n * Check if a path is a private key (should never be tracked)\n */\nconst isPrivateKey = (path: string): boolean => {\n const name = basename(path);\n\n // SSH private keys (without .pub extension)\n if (path.includes('.ssh/') && !name.endsWith('.pub')) {\n for (const pattern of PRIVATE_KEY_PATTERNS) {\n if (pattern.test(name)) {\n return true;\n }\n }\n }\n\n // Other private key patterns\n if (name.endsWith('.pem') || name.endsWith('.key')) {\n return true;\n }\n\n return false;\n};\n\n/**\n * Check if a path contains potentially sensitive data\n */\nconst isSensitiveFile = (path: string): boolean => {\n // Strip ~/ prefix if present, since patterns with ^ anchor expect paths without it\n // e.g., ~/.netrc should match /^\\.netrc$/ pattern\n const pathToTest = path.startsWith('~/') ? path.slice(2) : path;\n\n for (const pattern of SENSITIVE_FILE_PATTERNS) {\n if (pattern.test(pathToTest)) {\n return true;\n }\n }\n return false;\n};\n\ninterface FileToAdd {\n source: string;\n destination: string;\n category: string;\n filename: string;\n isDir: boolean;\n fileCount: number;\n sensitive: boolean;\n}\n\nconst validateAndPrepareFiles = async (\n paths: string[],\n tuckDir: string,\n options: AddOptions\n): Promise<FileToAdd[]> => {\n const filesToAdd: FileToAdd[] = [];\n\n for (const path of paths) {\n const expandedPath = expandPath(path);\n const collapsedPath = collapsePath(expandedPath);\n\n // SECURITY: Block private keys\n if (isPrivateKey(collapsedPath)) {\n throw new Error(\n `Cannot track private key: ${path}\\n` +\n `Private keys should NEVER be committed to a repository.\\n` +\n `If you need to backup SSH keys, use a secure password manager.`\n );\n }\n\n // Check if file exists\n if (!(await pathExists(expandedPath))) {\n throw new FileNotFoundError(path);\n }\n\n // Check if already tracked\n if (await isFileTracked(tuckDir, collapsedPath)) {\n throw new FileAlreadyTrackedError(path);\n }\n\n // Determine if it's a directory\n const isDir = await isDirectory(expandedPath);\n const fileCount = isDir ? await getDirectoryFileCount(expandedPath) : 1;\n\n // Determine category\n const category = options.category || detectCategory(expandedPath);\n\n // Generate filename for storage\n const filename = options.name || sanitizeFilename(expandedPath);\n\n // Determine destination path\n const destination = getDestinationPath(tuckDir, category, filename);\n\n // Check if sensitive\n const sensitive = isSensitiveFile(collapsedPath);\n\n filesToAdd.push({\n source: collapsedPath,\n destination,\n category,\n filename,\n isDir,\n fileCount,\n sensitive,\n });\n }\n\n return filesToAdd;\n};\n\nconst addFiles = async (\n filesToAdd: FileToAdd[],\n tuckDir: string,\n options: AddOptions\n): Promise<void> => {\n const config = await loadConfig(tuckDir);\n const strategy = options.symlink ? 'symlink' : (config.files.strategy || 'copy');\n\n for (const file of filesToAdd) {\n const expandedSource = expandPath(file.source);\n\n // Copy file to repository\n await withSpinner(`Copying ${file.source}...`, async () => {\n await copyFileOrDir(expandedSource, file.destination, { overwrite: true });\n });\n\n // Get file info\n const checksum = await getFileChecksum(file.destination);\n const info = await getFileInfo(expandedSource);\n const now = new Date().toISOString();\n\n // Generate unique ID\n const id = generateFileId(file.source);\n\n // Add to manifest\n await addFileToManifest(tuckDir, id, {\n source: file.source,\n destination: getRelativeDestination(file.category, file.filename),\n category: file.category,\n strategy,\n encrypted: options.encrypt || false,\n template: options.template || false,\n permissions: info.permissions,\n added: now,\n modified: now,\n checksum,\n });\n\n // Log result\n const categoryInfo = CATEGORIES[file.category];\n const icon = categoryInfo?.icon || '-';\n logger.success(`Added ${file.source}`);\n logger.dim(` ${icon} Category: ${file.category}`);\n if (file.isDir) {\n logger.dim(` [dir] Directory with ${file.fileCount} files`);\n }\n\n // Warn about sensitive files\n if (file.sensitive) {\n console.log(chalk.yellow(` [!] Warning: This file may contain sensitive data`));\n console.log(chalk.dim(` Make sure your repository is private!`));\n }\n }\n};\n\nconst runInteractiveAdd = async (tuckDir: string): Promise<void> => {\n prompts.intro('tuck add');\n\n // Ask for paths\n const pathsInput = await prompts.text('Enter file paths to track (space-separated):', {\n placeholder: '~/.zshrc ~/.gitconfig',\n validate: (value) => {\n if (!value.trim()) return 'At least one path is required';\n return undefined;\n },\n });\n\n const paths = pathsInput.split(/\\s+/).filter(Boolean);\n\n // Validate and prepare\n let filesToAdd: FileToAdd[];\n try {\n filesToAdd = await validateAndPrepareFiles(paths, tuckDir, {});\n } catch (error) {\n if (error instanceof Error) {\n prompts.log.error(error.message);\n }\n prompts.cancel();\n return;\n }\n\n // Show what will be added and ask for category confirmation\n for (const file of filesToAdd) {\n prompts.log.step(`${file.source}`);\n\n const categoryOptions = Object.entries(CATEGORIES).map(([name, config]) => ({\n value: name,\n label: `${config.icon} ${name}`,\n hint: file.category === name ? '(auto-detected)' : undefined,\n }));\n\n // Move detected category to top\n categoryOptions.sort((a, b) => {\n if (a.value === file.category) return -1;\n if (b.value === file.category) return 1;\n return 0;\n });\n\n const selectedCategory = await prompts.select('Category:', categoryOptions);\n file.category = selectedCategory as string;\n\n // Update destination with new category\n file.destination = getDestinationPath(tuckDir, file.category, file.filename);\n }\n\n // Confirm\n const confirm = await prompts.confirm(\n `Add ${filesToAdd.length} ${filesToAdd.length === 1 ? 'file' : 'files'}?`,\n true\n );\n\n if (!confirm) {\n prompts.cancel('Operation cancelled');\n return;\n }\n\n // Add files\n await addFiles(filesToAdd, tuckDir, {});\n\n prompts.outro(`Added ${filesToAdd.length} ${filesToAdd.length === 1 ? 'file' : 'files'}`);\n logger.info(\"Run 'tuck sync' to commit changes\");\n};\n\n/**\n * Add files programmatically (used by scan command)\n */\nexport const addFilesFromPaths = async (paths: string[], options: AddOptions = {}): Promise<number> => {\n const tuckDir = getTuckDir();\n\n // Verify tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n // Validate and prepare files\n const filesToAdd = await validateAndPrepareFiles(paths, tuckDir, options);\n\n // Add files\n await addFiles(filesToAdd, tuckDir, options);\n\n return filesToAdd.length;\n};\n\nconst runAdd = async (paths: string[], options: AddOptions): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Verify tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n if (paths.length === 0) {\n await runInteractiveAdd(tuckDir);\n return;\n }\n\n // Validate and prepare files\n const filesToAdd = await validateAndPrepareFiles(paths, tuckDir, options);\n\n // Add files\n await addFiles(filesToAdd, tuckDir, options);\n\n logger.blank();\n logger.success(`Added ${filesToAdd.length} ${filesToAdd.length === 1 ? 'item' : 'items'}`);\n logger.info(\"Run 'tuck sync' to commit changes\");\n};\n\nexport const addCommand = new Command('add')\n .description('Track new dotfiles')\n .argument('[paths...]', 'Paths to dotfiles to track')\n .option('-c, --category <name>', 'Category to organize under')\n .option('-n, --name <name>', 'Custom name for the file in manifest')\n .option('--symlink', 'Create symlink instead of copy')\n .option('--encrypt', 'Encrypt this file (requires GPG setup)')\n .option('--template', 'Treat as template with variable substitution')\n .action(async (paths: string[], options: AddOptions) => {\n await runAdd(paths, options);\n });\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport {\n initCommand,\n addCommand,\n removeCommand,\n syncCommand,\n pushCommand,\n pullCommand,\n restoreCommand,\n statusCommand,\n listCommand,\n diffCommand,\n configCommand,\n applyCommand,\n undoCommand,\n scanCommand,\n} from './commands/index.js';\nimport { handleError } from './errors.js';\nimport { VERSION, DESCRIPTION } from './constants.js';\nimport { customHelp, miniBanner } from './ui/banner.js';\nimport { getTuckDir, pathExists } from './lib/paths.js';\nimport { loadManifest } from './lib/manifest.js';\nimport { getStatus } from './lib/git.js';\n\nconst program = new Command();\n\nprogram\n .name('tuck')\n .description(DESCRIPTION)\n .version(VERSION, '-v, --version', 'Display version number')\n .configureOutput({\n outputError: (str, write) => write(chalk.red(str)),\n })\n .addHelpText('beforeAll', customHelp(VERSION))\n .helpOption('-h, --help', 'Display this help message')\n .showHelpAfterError(false);\n\n// Override default help to use our custom version\nprogram.configureHelp({\n formatHelp: () => '',\n});\n\n// Register commands\nprogram.addCommand(initCommand);\nprogram.addCommand(addCommand);\nprogram.addCommand(removeCommand);\nprogram.addCommand(syncCommand);\nprogram.addCommand(pushCommand);\nprogram.addCommand(pullCommand);\nprogram.addCommand(restoreCommand);\nprogram.addCommand(statusCommand);\nprogram.addCommand(listCommand);\nprogram.addCommand(diffCommand);\nprogram.addCommand(configCommand);\nprogram.addCommand(applyCommand);\nprogram.addCommand(undoCommand);\nprogram.addCommand(scanCommand);\n\n// Default action when no command is provided\nconst runDefaultAction = async (): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Check if tuck is initialized\n if (!(await pathExists(tuckDir))) {\n miniBanner();\n console.log(chalk.bold('Get started with tuck:\\n'));\n console.log(chalk.cyan(' tuck init') + chalk.dim(' - Set up tuck and create a GitHub repo'));\n console.log(chalk.cyan(' tuck scan') + chalk.dim(' - Find dotfiles to track'));\n console.log();\n console.log(chalk.dim('On a new machine:'));\n console.log(chalk.cyan(' tuck apply <username>') + chalk.dim(' - Apply your dotfiles'));\n console.log();\n return;\n }\n\n // Load manifest to check status\n try {\n const manifest = await loadManifest(tuckDir);\n const trackedCount = Object.keys(manifest.files).length;\n const gitStatus = await getStatus(tuckDir);\n\n miniBanner();\n console.log(chalk.bold('Status:\\n'));\n\n // Show tracked files count\n console.log(` Tracked files: ${chalk.cyan(trackedCount.toString())}`);\n\n // Show git status\n const pendingChanges = gitStatus.modified.length + gitStatus.staged.length;\n if (pendingChanges > 0) {\n console.log(` Pending changes: ${chalk.yellow(pendingChanges.toString())}`);\n } else {\n console.log(` Pending changes: ${chalk.dim('none')}`);\n }\n\n // Show remote status\n if (gitStatus.ahead > 0) {\n console.log(` Commits to push: ${chalk.yellow(gitStatus.ahead.toString())}`);\n }\n\n console.log();\n\n // Show what to do next\n console.log(chalk.bold('Next steps:\\n'));\n\n if (trackedCount === 0) {\n console.log(chalk.cyan(' tuck scan') + chalk.dim(' - Find dotfiles to track'));\n console.log(chalk.cyan(' tuck add <file>') + chalk.dim(' - Track a specific file'));\n } else if (pendingChanges > 0) {\n console.log(chalk.cyan(' tuck sync') + chalk.dim(' - Commit and push your changes'));\n console.log(chalk.cyan(' tuck diff') + chalk.dim(' - Preview what changed'));\n } else if (gitStatus.ahead > 0) {\n console.log(chalk.cyan(' tuck push') + chalk.dim(' - Push commits to GitHub'));\n } else {\n console.log(chalk.dim(' All synced! Your dotfiles are up to date.'));\n console.log();\n console.log(chalk.cyan(' tuck scan') + chalk.dim(' - Find more dotfiles to track'));\n console.log(chalk.cyan(' tuck list') + chalk.dim(' - See tracked files'));\n }\n\n console.log();\n } catch {\n // Manifest load failed, treat as not initialized\n miniBanner();\n console.log(chalk.yellow('Tuck directory exists but may be corrupted.'));\n console.log(chalk.dim('Run `tuck init` to reinitialize.'));\n console.log();\n }\n};\n\n// Check if no command provided\nconst hasCommand = process.argv.slice(2).some(\n (arg) => !arg.startsWith('-') && arg !== '--help' && arg !== '-h'\n);\n\n// Global error handling\nprocess.on('uncaughtException', handleError);\nprocess.on('unhandledRejection', (reason) => {\n handleError(reason instanceof Error ? reason : new Error(String(reason)));\n});\n\n// Parse and execute\nif (!hasCommand && !process.argv.includes('--help') && !process.argv.includes('-h') && !process.argv.includes('--version') && !process.argv.includes('-v')) {\n runDefaultAction().catch(handleError);\n} else {\n program.parseAsync(process.argv).catch(handleError);\n}\n","import { Command } from 'commander';\nimport { join } from 'path';\nimport { writeFile } from 'fs/promises';\nimport { ensureDir } from 'fs-extra';\nimport { banner, nextSteps, prompts, withSpinner, logger } from '../ui/index.js';\nimport {\n getTuckDir,\n getManifestPath,\n getConfigPath,\n getFilesDir,\n getCategoryDir,\n pathExists,\n expandPath,\n collapsePath,\n} from '../lib/paths.js';\nimport { saveConfig } from '../lib/config.js';\nimport { createManifest } from '../lib/manifest.js';\nimport { initRepo, addRemote, cloneRepo, setDefaultBranch, stageAll, commit, push } from '../lib/git.js';\nimport {\n isGhInstalled,\n isGhAuthenticated,\n getAuthenticatedUser,\n createRepo,\n getPreferredRepoUrl,\n} from '../lib/github.js';\nimport { AlreadyInitializedError } from '../errors.js';\nimport { CATEGORIES, COMMON_DOTFILES } from '../constants.js';\nimport { defaultConfig } from '../schemas/config.schema.js';\nimport type { InitOptions } from '../types.js';\n\nconst GITIGNORE_TEMPLATE = `# OS generated files\n.DS_Store\n.DS_Store?\n._*\n.Spotlight-V100\n.Trashes\nehthumbs.db\nThumbs.db\n\n# Backup files\n*.bak\n*.backup\n*~\n\n# Secret files (add patterns for files you want to exclude)\n# *.secret\n# .env.local\n`;\n\nconst README_TEMPLATE = (machine?: string) => `# Dotfiles\n\nManaged with [tuck](https://github.com/Pranav-Karra-3301/tuck) - Modern Dotfiles Manager\n\n${machine ? `## Machine: ${machine}\\n` : ''}\n\n## Quick Start\n\n\\`\\`\\`bash\n# Restore dotfiles to a new machine\ntuck init --from <this-repo-url>\n\n# Or clone and restore manually\ngit clone <this-repo-url> ~/.tuck\ntuck restore --all\n\\`\\`\\`\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| \\`tuck add <paths>\\` | Track new dotfiles |\n| \\`tuck sync\\` | Sync changes to repository |\n| \\`tuck push\\` | Push to remote |\n| \\`tuck pull\\` | Pull from remote |\n| \\`tuck restore\\` | Restore dotfiles to system |\n| \\`tuck status\\` | Show tracking status |\n| \\`tuck list\\` | List tracked files |\n\n## Structure\n\n\\`\\`\\`\n.tuck/\n├── files/ # Tracked dotfiles organized by category\n│ ├── shell/ # Shell configs (.zshrc, .bashrc, etc.)\n│ ├── git/ # Git configs (.gitconfig, etc.)\n│ ├── editors/ # Editor configs (nvim, vim, etc.)\n│ ├── terminal/ # Terminal configs (tmux, alacritty, etc.)\n│ └── misc/ # Other dotfiles\n├── .tuckmanifest.json # Tracks all managed files\n└── .tuckrc.json # Tuck configuration\n\\`\\`\\`\n`;\n\nconst createDirectoryStructure = async (tuckDir: string): Promise<void> => {\n // Create main directories\n await ensureDir(tuckDir);\n await ensureDir(getFilesDir(tuckDir));\n\n // Create category directories\n for (const category of Object.keys(CATEGORIES)) {\n await ensureDir(getCategoryDir(tuckDir, category));\n }\n};\n\nconst createDefaultFiles = async (tuckDir: string, machine?: string): Promise<void> => {\n // Create .gitignore\n const gitignorePath = join(tuckDir, '.gitignore');\n await writeFile(gitignorePath, GITIGNORE_TEMPLATE, 'utf-8');\n\n // Create README.md\n const readmePath = join(tuckDir, 'README.md');\n await writeFile(readmePath, README_TEMPLATE(machine), 'utf-8');\n};\n\nconst initFromScratch = async (\n tuckDir: string,\n options: { remote?: string; bare?: boolean }\n): Promise<void> => {\n // Check if already initialized\n if (await pathExists(getManifestPath(tuckDir))) {\n throw new AlreadyInitializedError(tuckDir);\n }\n\n // Create directory structure\n await withSpinner('Creating directory structure...', async () => {\n await createDirectoryStructure(tuckDir);\n });\n\n // Initialize git repository\n await withSpinner('Initializing git repository...', async () => {\n await initRepo(tuckDir);\n await setDefaultBranch(tuckDir, 'main');\n });\n\n // Create manifest\n await withSpinner('Creating manifest...', async () => {\n const hostname = (await import('os')).hostname();\n await createManifest(tuckDir, hostname);\n });\n\n // Create config\n await withSpinner('Creating configuration...', async () => {\n await saveConfig(\n {\n ...defaultConfig,\n repository: { ...defaultConfig.repository, path: tuckDir },\n },\n tuckDir\n );\n });\n\n // Create default files unless --bare\n if (!options.bare) {\n await withSpinner('Creating default files...', async () => {\n const hostname = (await import('os')).hostname();\n await createDefaultFiles(tuckDir, hostname);\n });\n }\n\n // Add remote if provided\n if (options.remote) {\n await withSpinner('Adding remote...', async () => {\n await addRemote(tuckDir, 'origin', options.remote!);\n });\n }\n};\n\ninterface GitHubSetupResult {\n remoteUrl: string | null;\n pushed: boolean;\n}\n\nconst setupGitHubRepo = async (tuckDir: string): Promise<GitHubSetupResult> => {\n // Check if GitHub CLI is available\n const ghInstalled = await isGhInstalled();\n if (!ghInstalled) {\n prompts.log.info('GitHub CLI (gh) is not installed');\n prompts.log.info('Install it from https://cli.github.com/ for auto-setup');\n return { remoteUrl: null, pushed: false };\n }\n\n const ghAuth = await isGhAuthenticated();\n if (!ghAuth) {\n prompts.log.info('GitHub CLI is not authenticated');\n prompts.log.info('Run `gh auth login` to enable auto-setup');\n return { remoteUrl: null, pushed: false };\n }\n\n // Get authenticated user\n const user = await getAuthenticatedUser();\n prompts.log.success(`Detected GitHub account: ${user.login}`);\n\n // Ask if they want to auto-create repo\n const createGhRepo = await prompts.confirm('Create a GitHub repository automatically?', true);\n\n if (!createGhRepo) {\n return { remoteUrl: null, pushed: false };\n }\n\n // Ask for repo name\n const repoName = await prompts.text('Repository name:', {\n defaultValue: 'dotfiles',\n placeholder: 'dotfiles',\n validate: (value) => {\n if (!value) return 'Repository name is required';\n if (!/^[a-zA-Z0-9._-]+$/.test(value)) {\n return 'Invalid repository name';\n }\n return undefined;\n },\n });\n\n // Ask for visibility\n const visibility = await prompts.select('Repository visibility:', [\n { value: 'private', label: 'Private (recommended)', hint: 'Only you can see it' },\n { value: 'public', label: 'Public', hint: 'Anyone can see it' },\n ]);\n\n // Create the repository\n let repo;\n try {\n const spinner = prompts.spinner();\n spinner.start(`Creating repository ${user.login}/${repoName}...`);\n\n repo = await createRepo({\n name: repoName,\n description: 'My dotfiles managed with tuck',\n isPrivate: visibility === 'private',\n });\n\n spinner.stop(`Repository created: ${repo.fullName}`);\n } catch (error) {\n prompts.log.error(`Failed to create repository: ${error instanceof Error ? error.message : String(error)}`);\n return { remoteUrl: null, pushed: false };\n }\n\n // Get the remote URL in preferred format\n const remoteUrl = await getPreferredRepoUrl(repo);\n\n // Add as remote\n await addRemote(tuckDir, 'origin', remoteUrl);\n prompts.log.success('Remote origin configured');\n\n // Ask to push initial commit\n const shouldPush = await prompts.confirm('Push initial commit to GitHub?', true);\n\n if (shouldPush) {\n try {\n const spinner = prompts.spinner();\n spinner.start('Creating initial commit...');\n\n await stageAll(tuckDir);\n await commit(tuckDir, 'Initial commit: tuck dotfiles setup');\n\n spinner.stop('Initial commit created');\n\n spinner.start('Pushing to GitHub...');\n await push(tuckDir, { remote: 'origin', branch: 'main', setUpstream: true });\n spinner.stop('Pushed to GitHub');\n\n prompts.note(\n `Your dotfiles are now at:\\n${repo.url}\\n\\nOn a new machine, run:\\ntuck apply ${user.login}`,\n 'Success'\n );\n\n return { remoteUrl, pushed: true };\n } catch (error) {\n prompts.log.error(`Failed to push: ${error instanceof Error ? error.message : String(error)}`);\n return { remoteUrl, pushed: false };\n }\n }\n\n return { remoteUrl, pushed: false };\n};\n\nconst initFromRemote = async (tuckDir: string, remoteUrl: string): Promise<void> => {\n // Clone the repository\n await withSpinner(`Cloning from ${remoteUrl}...`, async () => {\n await cloneRepo(remoteUrl, tuckDir);\n });\n\n // Verify manifest exists\n if (!(await pathExists(getManifestPath(tuckDir)))) {\n logger.warning('No manifest found in cloned repository. Creating new manifest...');\n const hostname = (await import('os')).hostname();\n await createManifest(tuckDir, hostname);\n }\n\n // Verify config exists\n if (!(await pathExists(getConfigPath(tuckDir)))) {\n logger.warning('No config found in cloned repository. Creating default config...');\n await saveConfig(\n {\n ...defaultConfig,\n repository: { ...defaultConfig.repository, path: tuckDir },\n },\n tuckDir\n );\n }\n};\n\nconst runInteractiveInit = async (): Promise<void> => {\n banner();\n prompts.intro('tuck init');\n\n // Ask for tuck directory\n const dirInput = await prompts.text('Where should tuck store your dotfiles?', {\n defaultValue: '~/.tuck',\n });\n const tuckDir = getTuckDir(dirInput);\n\n // Check if already initialized\n if (await pathExists(getManifestPath(tuckDir))) {\n prompts.log.error(`Tuck is already initialized at ${collapsePath(tuckDir)}`);\n prompts.outro('Use `tuck status` to see current state');\n return;\n }\n\n // Ask about existing repo\n const hasExisting = await prompts.select('Do you have an existing dotfiles repository?', [\n { value: 'no', label: 'No, start fresh' },\n { value: 'yes', label: 'Yes, clone from URL' },\n ]);\n\n if (hasExisting === 'yes') {\n const repoUrl = await prompts.text('Enter repository URL:', {\n placeholder: 'git@github.com:user/dotfiles.git',\n validate: (value) => {\n if (!value) return 'Repository URL is required';\n if (!value.includes('github.com') && !value.includes('gitlab.com') && !value.includes('git@')) {\n return 'Please enter a valid git URL';\n }\n return undefined;\n },\n });\n\n await initFromRemote(tuckDir, repoUrl);\n\n prompts.log.success('Repository cloned successfully!');\n\n const shouldRestore = await prompts.confirm('Would you like to restore dotfiles now?', true);\n\n if (shouldRestore) {\n prompts.log.info('Run `tuck restore --all` to restore all dotfiles');\n }\n } else {\n // Check for common dotfiles that exist\n const existingDotfiles: { path: string; label: string }[] = [];\n\n for (const df of COMMON_DOTFILES) {\n const fullPath = expandPath(df.path);\n if (await pathExists(fullPath)) {\n existingDotfiles.push({\n path: df.path,\n label: `${df.path} (${df.category})`,\n });\n }\n }\n\n await initFromScratch(tuckDir, {});\n\n // Ask to add common dotfiles if any exist\n if (existingDotfiles.length > 0) {\n const selectedFiles = await prompts.multiselect(\n 'Would you like to track some common dotfiles?',\n existingDotfiles.map((f) => ({\n value: f.path,\n label: f.label,\n }))\n );\n\n if (selectedFiles.length > 0) {\n prompts.log.step(\n `Run the following to track these files:\\n tuck add ${selectedFiles.join(' ')}`\n );\n }\n }\n\n // Ask about remote - try GitHub auto-setup first\n const wantsRemote = await prompts.confirm('Would you like to set up a remote repository?');\n\n if (wantsRemote) {\n // Try GitHub auto-setup\n const ghResult = await setupGitHubRepo(tuckDir);\n\n // If GitHub setup didn't add a remote, fall back to manual entry\n if (!ghResult.remoteUrl) {\n const useManual = await prompts.confirm('Enter a remote URL manually?');\n\n if (useManual) {\n const remoteUrl = await prompts.text('Enter remote URL:', {\n placeholder: 'git@github.com:user/dotfiles.git',\n });\n\n if (remoteUrl) {\n await addRemote(tuckDir, 'origin', remoteUrl);\n prompts.log.success('Remote added successfully');\n }\n }\n }\n }\n }\n\n prompts.outro('Tuck initialized successfully!');\n\n nextSteps([\n `Add files: tuck add ~/.zshrc`,\n `Sync changes: tuck sync`,\n `Push remote: tuck push`,\n ]);\n};\n\nconst runInit = async (options: InitOptions): Promise<void> => {\n const tuckDir = getTuckDir(options.dir);\n\n // If --from is provided, clone from remote\n if (options.from) {\n await initFromRemote(tuckDir, options.from);\n logger.success(`Tuck initialized from ${options.from}`);\n logger.info('Run `tuck restore --all` to restore dotfiles');\n return;\n }\n\n // Initialize from scratch\n await initFromScratch(tuckDir, {\n remote: options.remote,\n bare: options.bare,\n });\n\n logger.success(`Tuck initialized at ${collapsePath(tuckDir)}`);\n\n nextSteps([\n `Add files: tuck add ~/.zshrc`,\n `Sync changes: tuck sync`,\n `Push remote: tuck push`,\n ]);\n};\n\nexport const initCommand = new Command('init')\n .description('Initialize tuck repository')\n .option('-d, --dir <path>', 'Directory for tuck repository', '~/.tuck')\n .option('-r, --remote <url>', 'Git remote URL to set up')\n .option('--bare', 'Initialize without any default files')\n .option('--from <url>', 'Clone from existing tuck repository')\n .action(async (options: InitOptions) => {\n // If no options provided, run interactive mode\n if (!options.remote && !options.bare && !options.from && options.dir === '~/.tuck') {\n await runInteractiveInit();\n } else {\n await runInit(options);\n }\n });\n","import simpleGit, { SimpleGit, StatusResult } from 'simple-git';\nimport { GitError } from '../errors.js';\nimport { pathExists } from './paths.js';\nimport { join } from 'path';\n\nexport interface GitStatus {\n isRepo: boolean;\n branch: string;\n tracking?: string;\n ahead: number;\n behind: number;\n staged: string[];\n modified: string[];\n untracked: string[];\n deleted: string[];\n hasChanges: boolean;\n}\n\nexport interface GitCommit {\n hash: string;\n date: string;\n message: string;\n author: string;\n}\n\nconst createGit = (dir: string): SimpleGit => {\n return simpleGit(dir, {\n binary: 'git',\n maxConcurrentProcesses: 6,\n trimmed: true,\n });\n};\n\nexport const isGitRepo = async (dir: string): Promise<boolean> => {\n const gitDir = join(dir, '.git');\n return pathExists(gitDir);\n};\n\nexport const initRepo = async (dir: string): Promise<void> => {\n try {\n const git = createGit(dir);\n await git.init();\n } catch (error) {\n throw new GitError('Failed to initialize repository', String(error));\n }\n};\n\nexport const cloneRepo = async (url: string, dir: string): Promise<void> => {\n try {\n const git = simpleGit();\n await git.clone(url, dir);\n } catch (error) {\n throw new GitError(`Failed to clone repository from ${url}`, String(error));\n }\n};\n\nexport const addRemote = async (dir: string, name: string, url: string): Promise<void> => {\n try {\n const git = createGit(dir);\n await git.addRemote(name, url);\n } catch (error) {\n throw new GitError('Failed to add remote', String(error));\n }\n};\n\nexport const getRemotes = async (dir: string): Promise<{ name: string; url: string }[]> => {\n try {\n const git = createGit(dir);\n const remotes = await git.getRemotes(true);\n return remotes.map((r) => ({ name: r.name, url: r.refs.fetch || r.refs.push || '' }));\n } catch (error) {\n throw new GitError('Failed to get remotes', String(error));\n }\n};\n\nexport const getStatus = async (dir: string): Promise<GitStatus> => {\n try {\n const git = createGit(dir);\n const status: StatusResult = await git.status();\n\n return {\n isRepo: true,\n branch: status.current || 'main',\n tracking: status.tracking || undefined,\n ahead: status.ahead,\n behind: status.behind,\n staged: status.staged,\n modified: status.modified,\n untracked: status.not_added,\n deleted: status.deleted,\n hasChanges: !status.isClean(),\n };\n } catch (error) {\n throw new GitError('Failed to get status', String(error));\n }\n};\n\nexport const stageFiles = async (dir: string, files: string[]): Promise<void> => {\n try {\n const git = createGit(dir);\n await git.add(files);\n } catch (error) {\n throw new GitError('Failed to stage files', String(error));\n }\n};\n\nexport const stageAll = async (dir: string): Promise<void> => {\n try {\n const git = createGit(dir);\n await git.add('.');\n } catch (error) {\n throw new GitError('Failed to stage all files', String(error));\n }\n};\n\nexport const commit = async (dir: string, message: string): Promise<string> => {\n try {\n const git = createGit(dir);\n const result = await git.commit(message);\n return result.commit;\n } catch (error) {\n throw new GitError('Failed to commit', String(error));\n }\n};\n\nexport const push = async (\n dir: string,\n options?: { remote?: string; branch?: string; force?: boolean; setUpstream?: boolean }\n): Promise<void> => {\n try {\n const git = createGit(dir);\n const args: string[] = [];\n\n if (options?.setUpstream) {\n args.push('-u');\n }\n if (options?.force) {\n args.push('--force');\n }\n\n const remote = options?.remote || 'origin';\n const branch = options?.branch;\n\n if (branch) {\n await git.push([remote, branch, ...args]);\n } else {\n await git.push([remote, ...args]);\n }\n } catch (error) {\n throw new GitError('Failed to push', String(error));\n }\n};\n\nexport const pull = async (\n dir: string,\n options?: { remote?: string; branch?: string; rebase?: boolean }\n): Promise<void> => {\n try {\n const git = createGit(dir);\n const args: string[] = [];\n\n if (options?.rebase) {\n args.push('--rebase');\n }\n\n const remote = options?.remote || 'origin';\n const branch = options?.branch;\n\n if (branch) {\n await git.pull(remote, branch, args);\n } else {\n await git.pull(remote, undefined, args);\n }\n } catch (error) {\n throw new GitError('Failed to pull', String(error));\n }\n};\n\nexport const fetch = async (dir: string, remote = 'origin'): Promise<void> => {\n try {\n const git = createGit(dir);\n await git.fetch(remote);\n } catch (error) {\n throw new GitError('Failed to fetch', String(error));\n }\n};\n\nexport const getLog = async (\n dir: string,\n options?: { maxCount?: number }\n): Promise<GitCommit[]> => {\n try {\n const git = createGit(dir);\n const log = await git.log({\n maxCount: options?.maxCount || 10,\n });\n\n return log.all.map((entry) => ({\n hash: entry.hash,\n date: entry.date,\n message: entry.message,\n author: entry.author_name || 'Unknown',\n }));\n } catch (error) {\n throw new GitError('Failed to get log', String(error));\n }\n};\n\nexport const getDiff = async (\n dir: string,\n options?: { staged?: boolean; stat?: boolean; files?: string[] }\n): Promise<string> => {\n try {\n const git = createGit(dir);\n const args: string[] = [];\n\n if (options?.staged) {\n args.push('--staged');\n }\n if (options?.stat) {\n args.push('--stat');\n }\n if (options?.files) {\n args.push('--');\n args.push(...options.files);\n }\n\n const result = await git.diff(args);\n return result;\n } catch (error) {\n throw new GitError('Failed to get diff', String(error));\n }\n};\n\nexport const getCurrentBranch = async (dir: string): Promise<string> => {\n try {\n const git = createGit(dir);\n const branch = await git.revparse(['--abbrev-ref', 'HEAD']);\n return branch;\n } catch (error) {\n throw new GitError('Failed to get current branch', String(error));\n }\n};\n\nexport const hasRemote = async (dir: string, name = 'origin'): Promise<boolean> => {\n try {\n const remotes = await getRemotes(dir);\n return remotes.some((r) => r.name === name);\n } catch {\n return false;\n }\n};\n\nexport const getRemoteUrl = async (dir: string, name = 'origin'): Promise<string | null> => {\n try {\n const remotes = await getRemotes(dir);\n const remote = remotes.find((r) => r.name === name);\n return remote?.url || null;\n } catch {\n return null;\n }\n};\n\nexport const setDefaultBranch = async (dir: string, branch: string): Promise<void> => {\n try {\n const git = createGit(dir);\n await git.branch(['-M', branch]);\n } catch (error) {\n throw new GitError('Failed to set default branch', String(error));\n }\n};\n","import { exec, execFile } from 'child_process';\nimport { promisify } from 'util';\nimport { GitHubCliError } from '../errors.js';\n\nconst execAsync = promisify(exec);\nconst execFileAsync = promisify(execFile);\n\n/**\n * Validate repository name/identifier to prevent command injection.\n * Valid formats: \"owner/repo\", \"repo\", or full URLs\n */\nconst validateRepoName = (repoName: string): void => {\n // Allow full URLs (https:// or git@)\n if (repoName.includes('://') || repoName.startsWith('git@')) {\n // Basic URL validation - must not contain shell metacharacters\n if (/[;&|`$(){}[\\]<>!#*?]/.test(repoName.replace(/[/:@.]/g, ''))) {\n throw new GitHubCliError(`Invalid repository URL: ${repoName}`);\n }\n return;\n }\n\n // For owner/repo or repo format, validate strictly\n // Valid: alphanumeric, hyphens, underscores, dots, and single forward slash\n const validPattern = /^[a-zA-Z0-9._-]+(?:\\/[a-zA-Z0-9._-]+)?$/;\n if (!validPattern.test(repoName)) {\n throw new GitHubCliError(`Invalid repository name: ${repoName}`, [\n 'Repository names can only contain alphanumeric characters, hyphens, underscores, and dots',\n 'Format: \"owner/repo\" or \"repo\"',\n ]);\n }\n};\n\nexport interface GitHubUser {\n login: string;\n name: string | null;\n email: string | null;\n}\n\nexport interface GitHubRepo {\n name: string;\n fullName: string;\n url: string;\n sshUrl: string;\n httpsUrl: string;\n isPrivate: boolean;\n}\n\nexport interface CreateRepoOptions {\n name: string;\n description?: string;\n isPrivate?: boolean;\n homepage?: string;\n}\n\n/**\n * Check if the GitHub CLI (gh) is installed\n */\nexport const isGhInstalled = async (): Promise<boolean> => {\n try {\n await execAsync('gh --version');\n return true;\n } catch {\n return false;\n }\n};\n\n/**\n * Check if the user is authenticated with GitHub CLI\n */\nexport const isGhAuthenticated = async (): Promise<boolean> => {\n try {\n // gh auth status outputs to stderr, not stdout\n // execAsync provides both stdout and stderr even on success\n const { stdout, stderr } = await execAsync('gh auth status');\n // Check stderr (where gh auth status outputs) and stdout (as fallback)\n const output = (stderr || stdout || '').trim();\n // Only return true if we can definitively confirm authentication\n // Check for positive indicator, not absence of negative indicator\n return output.includes('Logged in');\n } catch (error) {\n // gh auth status returns exit code 1 when not authenticated\n // and outputs error message to stderr\n if (error instanceof Error && 'stderr' in error) {\n const stderr = (error as { stderr: string }).stderr;\n // Only return true if stderr explicitly confirms authentication\n return stderr.includes('Logged in');\n }\n return false;\n }\n};\n\n/**\n * Get the authenticated GitHub user's information\n */\nexport const getAuthenticatedUser = async (): Promise<GitHubUser> => {\n if (!(await isGhInstalled())) {\n throw new GitHubCliError('GitHub CLI is not installed');\n }\n\n if (!(await isGhAuthenticated())) {\n throw new GitHubCliError('Not authenticated with GitHub CLI', [\n 'Run `gh auth login` to authenticate',\n ]);\n }\n\n try {\n const { stdout } = await execAsync('gh api user --jq \".login, .name, .email\"');\n const lines = stdout.trim().split('\\n');\n return {\n login: lines[0] || '',\n name: lines[1] !== 'null' ? lines[1] : null,\n email: lines[2] !== 'null' ? lines[2] : null,\n };\n } catch (error) {\n throw new GitHubCliError('Failed to get user information', [\n String(error),\n 'Check your GitHub CLI authentication',\n ]);\n }\n};\n\n/**\n * Check if a repository exists on GitHub\n */\nexport const repoExists = async (repoName: string): Promise<boolean> => {\n try {\n validateRepoName(repoName);\n await execFileAsync('gh', ['repo', 'view', repoName, '--json', 'name']);\n return true;\n } catch {\n return false;\n }\n};\n\n/**\n * Create a new GitHub repository\n */\nexport const createRepo = async (options: CreateRepoOptions): Promise<GitHubRepo> => {\n if (!(await isGhInstalled())) {\n throw new GitHubCliError('GitHub CLI is not installed');\n }\n\n if (!(await isGhAuthenticated())) {\n throw new GitHubCliError('Not authenticated with GitHub CLI', [\n 'Run `gh auth login` to authenticate',\n ]);\n }\n\n // Check if repo already exists\n const user = await getAuthenticatedUser();\n const fullName = `${user.login}/${options.name}`;\n\n if (await repoExists(fullName)) {\n throw new GitHubCliError(`Repository \"${fullName}\" already exists`, [\n `Use a different name or run \\`tuck init --remote ${fullName}\\``,\n ]);\n }\n\n // Validate inputs to prevent command injection\n validateRepoName(options.name);\n \n if (options.description && /[;&|`$(){}[\\]<>!#*?]/.test(options.description)) {\n throw new GitHubCliError('Invalid description: contains unsafe characters');\n }\n \n if (options.homepage && /[;&|`$(){}[\\]<>!#*?]/.test(options.homepage)) {\n throw new GitHubCliError('Invalid homepage: contains unsafe characters');\n }\n\n try {\n // Build command arguments array to prevent command injection\n const args: string[] = ['repo', 'create', options.name];\n \n if (options.isPrivate !== false) {\n args.push('--private');\n } else {\n args.push('--public');\n }\n \n if (options.description) {\n args.push('--description', options.description);\n }\n \n if (options.homepage) {\n args.push('--homepage', options.homepage);\n }\n \n args.push('--confirm', '--json', 'name,url,sshUrl');\n \n const { stdout } = await execFileAsync('gh', args);\n const result = JSON.parse(stdout);\n\n return {\n name: result.name,\n fullName: `${user.login}/${result.name}`,\n url: result.url,\n sshUrl: result.sshUrl,\n httpsUrl: result.url.replace('github.com', 'github.com').replace(/^https?:\\/\\//, 'https://'),\n isPrivate: options.isPrivate !== false,\n };\n } catch (error) {\n throw new GitHubCliError(`Failed to create repository \"${options.name}\"`, [\n String(error),\n 'Check your GitHub permissions',\n ]);\n }\n};\n\n/**\n * Get the preferred remote URL format (SSH or HTTPS)\n */\nexport const getPreferredRemoteProtocol = async (): Promise<'ssh' | 'https'> => {\n try {\n const { stdout } = await execAsync('gh config get git_protocol');\n const protocol = stdout.trim().toLowerCase();\n return protocol === 'ssh' ? 'ssh' : 'https';\n } catch {\n // Default to HTTPS if we can't determine preference\n return 'https';\n }\n};\n\n/**\n * Get repository information from GitHub\n */\nexport const getRepoInfo = async (repoName: string): Promise<GitHubRepo | null> => {\n try {\n validateRepoName(repoName);\n const { stdout } = await execFileAsync('gh', [\n 'repo',\n 'view',\n repoName,\n '--json',\n 'name,url,sshUrl,isPrivate,owner',\n ]);\n const result = JSON.parse(stdout);\n\n return {\n name: result.name,\n fullName: `${result.owner.login}/${result.name}`,\n url: result.url,\n sshUrl: result.sshUrl,\n httpsUrl: result.url,\n isPrivate: result.isPrivate,\n };\n } catch {\n return null;\n }\n};\n\n/**\n * Clone a repository to a specific directory using gh CLI\n */\nexport const ghCloneRepo = async (repoName: string, targetDir: string): Promise<void> => {\n if (!(await isGhInstalled())) {\n throw new GitHubCliError('GitHub CLI is not installed');\n }\n\n validateRepoName(repoName);\n\n try {\n await execFileAsync('gh', ['repo', 'clone', repoName, targetDir]);\n } catch (error) {\n throw new GitHubCliError(`Failed to clone repository \"${repoName}\"`, [\n String(error),\n 'Check that the repository exists and you have access',\n ]);\n }\n};\n\n/**\n * Find a user's dotfiles repository (checks common names)\n */\nexport const findDotfilesRepo = async (username?: string): Promise<string | null> => {\n const user = username || (await getAuthenticatedUser()).login;\n const commonNames = ['dotfiles', 'tuck', '.dotfiles', 'dot-files', 'dots'];\n\n for (const name of commonNames) {\n const repoName = `${user}/${name}`;\n if (await repoExists(repoName)) {\n return repoName;\n }\n }\n\n return null;\n};\n\n/**\n * Get the remote URL in the user's preferred format (SSH or HTTPS)\n */\nexport const getPreferredRepoUrl = async (repo: GitHubRepo): Promise<string> => {\n const protocol = await getPreferredRemoteProtocol();\n return protocol === 'ssh' ? repo.sshUrl : repo.httpsUrl;\n};\n","export { initCommand } from './init.js';\nexport { addCommand } from './add.js';\nexport { removeCommand } from './remove.js';\nexport { syncCommand } from './sync.js';\nexport { pushCommand } from './push.js';\nexport { pullCommand } from './pull.js';\nexport { restoreCommand } from './restore.js';\nexport { statusCommand } from './status.js';\nexport { listCommand } from './list.js';\nexport { diffCommand } from './diff.js';\nexport { configCommand } from './config.js';\nexport { applyCommand } from './apply.js';\nexport { undoCommand } from './undo.js';\nexport { scanCommand } from './scan.js';\n","import { Command } from 'commander';\nimport { prompts, logger, withSpinner } from '../ui/index.js';\nimport {\n getTuckDir,\n expandPath,\n collapsePath,\n pathExists,\n} from '../lib/paths.js';\nimport { loadManifest, removeFileFromManifest, getTrackedFileBySource, getAllTrackedFiles } from '../lib/manifest.js';\nimport { deleteFileOrDir } from '../lib/files.js';\nimport { NotInitializedError, FileNotTrackedError } from '../errors.js';\nimport type { RemoveOptions } from '../types.js';\nimport { join } from 'path';\n\ninterface FileToRemove {\n id: string;\n source: string;\n destination: string;\n}\n\nconst validateAndPrepareFiles = async (\n paths: string[],\n tuckDir: string\n): Promise<FileToRemove[]> => {\n const filesToRemove: FileToRemove[] = [];\n\n for (const path of paths) {\n const expandedPath = expandPath(path);\n const collapsedPath = collapsePath(expandedPath);\n\n // Check if tracked\n const tracked = await getTrackedFileBySource(tuckDir, collapsedPath);\n if (!tracked) {\n throw new FileNotTrackedError(path);\n }\n\n filesToRemove.push({\n id: tracked.id,\n source: tracked.file.source,\n destination: join(tuckDir, tracked.file.destination),\n });\n }\n\n return filesToRemove;\n};\n\nconst removeFiles = async (\n filesToRemove: FileToRemove[],\n tuckDir: string,\n options: RemoveOptions\n): Promise<void> => {\n for (const file of filesToRemove) {\n // Remove from manifest\n await removeFileFromManifest(tuckDir, file.id);\n\n // Delete from repository if requested\n if (options.delete) {\n if (await pathExists(file.destination)) {\n await withSpinner(`Deleting ${file.source} from repository...`, async () => {\n await deleteFileOrDir(file.destination);\n });\n }\n }\n\n logger.success(`Removed ${file.source} from tracking`);\n if (options.delete) {\n logger.dim(' Also deleted from repository');\n }\n }\n};\n\nconst runInteractiveRemove = async (tuckDir: string): Promise<void> => {\n prompts.intro('tuck remove');\n\n // Get all tracked files\n const trackedFiles = await getAllTrackedFiles(tuckDir);\n const fileEntries = Object.entries(trackedFiles);\n\n if (fileEntries.length === 0) {\n prompts.log.warning('No files are currently tracked');\n prompts.outro('');\n return;\n }\n\n // Let user select files to remove\n const selectedFiles = await prompts.multiselect(\n 'Select files to stop tracking:',\n fileEntries.map(([id, file]) => ({\n value: id,\n label: file.source,\n hint: file.category,\n })),\n true\n );\n\n if (selectedFiles.length === 0) {\n prompts.cancel('No files selected');\n return;\n }\n\n // Ask if they want to delete from repo\n const shouldDelete = await prompts.confirm('Also delete files from repository?');\n\n // Confirm\n const confirm = await prompts.confirm(\n `Remove ${selectedFiles.length} ${selectedFiles.length === 1 ? 'file' : 'files'} from tracking?`,\n true\n );\n\n if (!confirm) {\n prompts.cancel('Operation cancelled');\n return;\n }\n\n // Prepare files to remove\n const filesToRemove: FileToRemove[] = selectedFiles.map((id) => {\n const file = trackedFiles[id as string];\n return {\n id: id as string,\n source: file.source,\n destination: join(tuckDir, file.destination),\n };\n });\n\n // Remove files\n await removeFiles(filesToRemove, tuckDir, { delete: shouldDelete });\n\n prompts.outro(`Removed ${selectedFiles.length} ${selectedFiles.length === 1 ? 'file' : 'files'}`);\n logger.info(\"Run 'tuck sync' to commit changes\");\n};\n\nconst runRemove = async (paths: string[], options: RemoveOptions): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Verify tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n if (paths.length === 0) {\n await runInteractiveRemove(tuckDir);\n return;\n }\n\n // Validate and prepare files\n const filesToRemove = await validateAndPrepareFiles(paths, tuckDir);\n\n // Remove files\n await removeFiles(filesToRemove, tuckDir, options);\n\n logger.blank();\n logger.success(`Removed ${filesToRemove.length} ${filesToRemove.length === 1 ? 'item' : 'items'} from tracking`);\n logger.info(\"Run 'tuck sync' to commit changes\");\n};\n\nexport const removeCommand = new Command('remove')\n .description('Stop tracking dotfiles')\n .argument('[paths...]', 'Paths to dotfiles to untrack')\n .option('--delete', 'Also delete from tuck repository')\n .option('--keep-original', \"Don't restore symlinks to regular files\")\n .action(async (paths: string[], options: RemoveOptions) => {\n await runRemove(paths, options);\n });\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { join } from 'path';\nimport { prompts, logger, withSpinner } from '../ui/index.js';\nimport { getTuckDir, expandPath, pathExists } from '../lib/paths.js';\nimport { loadManifest, getAllTrackedFiles, updateFileInManifest } from '../lib/manifest.js';\nimport { stageAll, commit, getStatus, push, hasRemote } from '../lib/git.js';\nimport { copyFileOrDir, getFileChecksum } from '../lib/files.js';\nimport { runPreSyncHook, runPostSyncHook, type HookOptions } from '../lib/hooks.js';\nimport { NotInitializedError } from '../errors.js';\nimport type { SyncOptions, FileChange } from '../types.js';\n\ninterface SyncResult {\n modified: string[];\n added: string[];\n deleted: string[];\n commitHash?: string;\n}\n\nconst detectChanges = async (tuckDir: string): Promise<FileChange[]> => {\n const files = await getAllTrackedFiles(tuckDir);\n const changes: FileChange[] = [];\n\n for (const [, file] of Object.entries(files)) {\n const sourcePath = expandPath(file.source);\n\n // Check if source still exists\n if (!(await pathExists(sourcePath))) {\n changes.push({\n path: file.source,\n status: 'deleted',\n source: file.source,\n destination: file.destination,\n });\n continue;\n }\n\n // Check if file has changed compared to stored checksum\n try {\n const sourceChecksum = await getFileChecksum(sourcePath);\n if (sourceChecksum !== file.checksum) {\n changes.push({\n path: file.source,\n status: 'modified',\n source: file.source,\n destination: file.destination,\n });\n }\n } catch {\n changes.push({\n path: file.source,\n status: 'modified',\n source: file.source,\n destination: file.destination,\n });\n }\n }\n\n return changes;\n};\n\nconst generateCommitMessage = (result: SyncResult): string => {\n const parts: string[] = [];\n\n if (result.added.length > 0) {\n parts.push(`Add: ${result.added.join(', ')}`);\n }\n if (result.modified.length > 0) {\n parts.push(`Update: ${result.modified.join(', ')}`);\n }\n if (result.deleted.length > 0) {\n parts.push(`Remove: ${result.deleted.join(', ')}`);\n }\n\n if (parts.length === 0) {\n return 'Sync dotfiles';\n }\n\n const totalCount =\n result.added.length + result.modified.length + result.deleted.length;\n\n if (parts.length === 1 && totalCount <= 3) {\n return parts[0];\n }\n\n return `Sync: ${totalCount} file${totalCount > 1 ? 's' : ''} changed`;\n};\n\nconst syncFiles = async (\n tuckDir: string,\n changes: FileChange[],\n options: SyncOptions\n): Promise<SyncResult> => {\n const result: SyncResult = {\n modified: [],\n added: [],\n deleted: [],\n };\n\n // Prepare hook options\n const hookOptions: HookOptions = {\n skipHooks: options.noHooks,\n trustHooks: options.trustHooks,\n };\n\n // Run pre-sync hook\n await runPreSyncHook(tuckDir, hookOptions);\n\n // Process each change\n for (const change of changes) {\n const sourcePath = expandPath(change.source);\n const destPath = join(tuckDir, change.destination!);\n\n if (change.status === 'modified') {\n await withSpinner(`Syncing ${change.path}...`, async () => {\n await copyFileOrDir(sourcePath, destPath, { overwrite: true });\n\n // Update checksum in manifest\n const newChecksum = await getFileChecksum(destPath);\n const files = await getAllTrackedFiles(tuckDir);\n const fileId = Object.entries(files).find(([, f]) => f.source === change.source)?.[0];\n\n if (fileId) {\n await updateFileInManifest(tuckDir, fileId, {\n checksum: newChecksum,\n modified: new Date().toISOString(),\n });\n }\n });\n result.modified.push(change.path.split('/').pop() || change.path);\n } else if (change.status === 'deleted') {\n logger.warning(`Source file deleted: ${change.path}`);\n result.deleted.push(change.path.split('/').pop() || change.path);\n }\n }\n\n // Stage and commit if not --no-commit\n if (!options.noCommit && (result.modified.length > 0 || result.deleted.length > 0)) {\n await withSpinner('Staging changes...', async () => {\n await stageAll(tuckDir);\n });\n\n const message = options.message || generateCommitMessage(result);\n\n await withSpinner('Committing...', async () => {\n result.commitHash = await commit(tuckDir, message);\n });\n }\n\n // Run post-sync hook\n await runPostSyncHook(tuckDir, hookOptions);\n\n return result;\n};\n\nconst runInteractiveSync = async (tuckDir: string, options: SyncOptions = {}): Promise<void> => {\n prompts.intro('tuck sync');\n\n // Detect changes\n const spinner = prompts.spinner();\n spinner.start('Detecting changes...');\n const changes = await detectChanges(tuckDir);\n spinner.stop('Changes detected');\n\n if (changes.length === 0) {\n // Check for git changes\n const gitStatus = await getStatus(tuckDir);\n if (gitStatus.hasChanges) {\n prompts.log.info('No dotfile changes, but repository has uncommitted changes');\n\n const commitAnyway = await prompts.confirm('Commit repository changes?');\n if (commitAnyway) {\n const message = await prompts.text('Commit message:', {\n defaultValue: 'Update dotfiles',\n });\n\n await stageAll(tuckDir);\n const hash = await commit(tuckDir, message);\n prompts.log.success(`Committed: ${hash.slice(0, 7)}`);\n }\n } else {\n prompts.log.success('Everything is up to date');\n }\n return;\n }\n\n // Show changes\n console.log();\n console.log(chalk.bold('Changes detected:'));\n for (const change of changes) {\n if (change.status === 'modified') {\n console.log(chalk.yellow(` ~ ${change.path}`));\n } else if (change.status === 'deleted') {\n console.log(chalk.red(` - ${change.path}`));\n }\n }\n console.log();\n\n // Confirm\n const confirm = await prompts.confirm('Sync these changes?', true);\n if (!confirm) {\n prompts.cancel('Operation cancelled');\n return;\n }\n\n // Get commit message\n const autoMessage = generateCommitMessage({\n modified: changes.filter((c) => c.status === 'modified').map((c) => c.path),\n added: [],\n deleted: changes.filter((c) => c.status === 'deleted').map((c) => c.path),\n });\n\n const message = await prompts.text('Commit message:', {\n defaultValue: autoMessage,\n });\n\n // Sync\n const result = await syncFiles(tuckDir, changes, { message });\n\n console.log();\n if (result.commitHash) {\n prompts.log.success(`Committed: ${result.commitHash.slice(0, 7)}`);\n\n // Push by default if remote exists (unless --no-push specified)\n // Commander converts --no-push to push: false, default is push: true\n if (options.push !== false && (await hasRemote(tuckDir))) {\n const spinner2 = prompts.spinner();\n spinner2.start('Pushing to remote...');\n try {\n await push(tuckDir);\n spinner2.stop('Pushed to remote');\n } catch {\n spinner2.stop('Push failed (will retry on next sync)');\n }\n } else if (options.push === false) {\n prompts.log.info(\"Run 'tuck push' when ready to upload\");\n }\n }\n\n prompts.outro('Synced successfully!');\n};\n\nconst runSync = async (messageArg: string | undefined, options: SyncOptions): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Verify tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n // If no options (except --no-push), run interactive\n if (!messageArg && !options.message && !options.all && !options.noCommit && !options.amend) {\n await runInteractiveSync(tuckDir, options);\n return;\n }\n\n // Detect changes\n const changes = await detectChanges(tuckDir);\n\n if (changes.length === 0) {\n logger.info('No changes detected');\n return;\n }\n\n // Show changes\n logger.heading('Changes detected:');\n for (const change of changes) {\n logger.file(change.status === 'modified' ? 'modify' : 'delete', change.path);\n }\n logger.blank();\n\n // Sync\n const message = messageArg || options.message;\n const result = await syncFiles(tuckDir, changes, { ...options, message });\n\n logger.blank();\n logger.success(`Synced ${changes.length} file${changes.length > 1 ? 's' : ''}`);\n\n if (result.commitHash) {\n logger.info(`Commit: ${result.commitHash.slice(0, 7)}`);\n\n // Push by default unless --no-push\n // Commander converts --no-push to push: false, default is push: true\n if (options.push !== false && (await hasRemote(tuckDir))) {\n await withSpinner('Pushing to remote...', async () => {\n await push(tuckDir);\n });\n logger.success('Pushed to remote');\n } else if (options.push === false) {\n logger.info(\"Run 'tuck push' when ready to upload\");\n }\n }\n};\n\nexport const syncCommand = new Command('sync')\n .description('Sync changes to repository (commits and pushes)')\n .argument('[message]', 'Commit message')\n .option('-m, --message <msg>', 'Commit message')\n .option('-a, --all', 'Sync all tracked files, not just changed')\n .option('--no-commit', \"Stage changes but don't commit\")\n .option('--no-push', \"Commit but don't push to remote\")\n .option('--amend', 'Amend previous commit')\n .option('--no-hooks', 'Skip execution of pre/post sync hooks')\n .option('--trust-hooks', 'Trust and run hooks without confirmation (use with caution)')\n .action(async (messageArg: string | undefined, options: SyncOptions) => {\n await runSync(messageArg, options);\n });\n","import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport chalk from 'chalk';\nimport { loadConfig } from './config.js';\nimport { logger } from '../ui/logger.js';\nimport { prompts } from '../ui/prompts.js';\n\nconst execAsync = promisify(exec);\n\nexport type HookType = 'preSync' | 'postSync' | 'preRestore' | 'postRestore';\n\nexport interface HookResult {\n success: boolean;\n output?: string;\n error?: string;\n skipped?: boolean;\n}\n\nexport interface HookOptions {\n silent?: boolean;\n skipHooks?: boolean;\n trustHooks?: boolean;\n}\n\n/**\n * SECURITY: This function executes shell commands from the configuration file.\n * When cloning from untrusted repositories, hooks could contain malicious commands.\n * We require explicit user confirmation before executing any hooks.\n */\nexport const runHook = async (\n hookType: HookType,\n tuckDir: string,\n options?: HookOptions\n): Promise<HookResult> => {\n // If hooks are explicitly disabled, skip execution\n if (options?.skipHooks) {\n return { success: true, skipped: true };\n }\n\n const config = await loadConfig(tuckDir);\n const command = config.hooks[hookType];\n\n if (!command) {\n return { success: true };\n }\n\n // SECURITY: Always show the hook command and require confirmation\n // unless trustHooks is explicitly set (for non-interactive/scripted use)\n if (!options?.trustHooks) {\n console.log();\n console.log(chalk.yellow.bold('WARNING: Hook Execution'));\n console.log(chalk.dim('─'.repeat(50)));\n console.log(chalk.white(`Hook type: ${chalk.cyan(hookType)}`));\n console.log(chalk.white('Command:'));\n console.log(chalk.red(` ${command}`));\n console.log(chalk.dim('─'.repeat(50)));\n console.log(\n chalk.yellow(\n 'SECURITY: Hooks can execute arbitrary commands on your system.'\n )\n );\n console.log(\n chalk.yellow(\n 'Only proceed if you trust the source of this configuration.'\n )\n );\n console.log();\n\n const confirmed = await prompts.confirm(\n 'Execute this hook?',\n false // Default to NO for safety\n );\n\n if (!confirmed) {\n logger.warning(`Hook ${hookType} skipped by user`);\n return { success: true, skipped: true };\n }\n }\n\n if (!options?.silent) {\n logger.dim(`Running ${hookType} hook...`);\n }\n\n try {\n const { stdout, stderr } = await execAsync(command, {\n cwd: tuckDir,\n timeout: 30000, // 30 second timeout\n env: {\n ...process.env,\n TUCK_DIR: tuckDir,\n TUCK_HOOK: hookType,\n },\n });\n\n if (stdout && !options?.silent) {\n logger.dim(stdout.trim());\n }\n\n if (stderr && !options?.silent) {\n logger.warning(stderr.trim());\n }\n\n return { success: true, output: stdout };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n if (!options?.silent) {\n logger.error(`Hook ${hookType} failed: ${errorMessage}`);\n }\n\n return { success: false, error: errorMessage };\n }\n};\n\nexport const runPreSyncHook = async (\n tuckDir: string,\n options?: HookOptions\n): Promise<HookResult> => {\n return runHook('preSync', tuckDir, options);\n};\n\nexport const runPostSyncHook = async (\n tuckDir: string,\n options?: HookOptions\n): Promise<HookResult> => {\n return runHook('postSync', tuckDir, options);\n};\n\nexport const runPreRestoreHook = async (\n tuckDir: string,\n options?: HookOptions\n): Promise<HookResult> => {\n return runHook('preRestore', tuckDir, options);\n};\n\nexport const runPostRestoreHook = async (\n tuckDir: string,\n options?: HookOptions\n): Promise<HookResult> => {\n return runHook('postRestore', tuckDir, options);\n};\n\nexport const hasHook = async (hookType: HookType, tuckDir: string): Promise<boolean> => {\n const config = await loadConfig(tuckDir);\n return Boolean(config.hooks[hookType]);\n};\n\nexport const getHookCommand = async (\n hookType: HookType,\n tuckDir: string\n): Promise<string | undefined> => {\n const config = await loadConfig(tuckDir);\n return config.hooks[hookType];\n};\n\n/**\n * Check if any hooks are configured\n */\nexport const hasAnyHooks = async (tuckDir: string): Promise<boolean> => {\n const config = await loadConfig(tuckDir);\n return Boolean(\n config.hooks.preSync ||\n config.hooks.postSync ||\n config.hooks.preRestore ||\n config.hooks.postRestore\n );\n};\n\n/**\n * Get all configured hooks for display\n */\nexport const getAllHooks = async (\n tuckDir: string\n): Promise<Record<HookType, string | undefined>> => {\n const config = await loadConfig(tuckDir);\n return {\n preSync: config.hooks.preSync,\n postSync: config.hooks.postSync,\n preRestore: config.hooks.preRestore,\n postRestore: config.hooks.postRestore,\n };\n};\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { prompts, logger, withSpinner } from '../ui/index.js';\nimport { getTuckDir } from '../lib/paths.js';\nimport { loadManifest } from '../lib/manifest.js';\nimport {\n push,\n hasRemote,\n getRemoteUrl,\n getStatus,\n getCurrentBranch,\n addRemote,\n} from '../lib/git.js';\nimport { NotInitializedError, GitError } from '../errors.js';\nimport type { PushOptions } from '../types.js';\n\nconst runInteractivePush = async (tuckDir: string): Promise<void> => {\n prompts.intro('tuck push');\n\n // Check if remote exists\n const hasRemoteRepo = await hasRemote(tuckDir);\n\n if (!hasRemoteRepo) {\n prompts.log.warning('No remote configured');\n\n const addRemoteNow = await prompts.confirm('Would you like to add a remote?');\n if (!addRemoteNow) {\n prompts.cancel('No remote to push to');\n return;\n }\n\n const remoteUrl = await prompts.text('Enter remote URL:', {\n placeholder: 'git@github.com:user/dotfiles.git',\n validate: (value) => {\n if (!value) return 'Remote URL is required';\n return undefined;\n },\n });\n\n await addRemote(tuckDir, 'origin', remoteUrl);\n prompts.log.success('Remote added');\n }\n\n // Get current status\n const status = await getStatus(tuckDir);\n const branch = await getCurrentBranch(tuckDir);\n const remoteUrl = await getRemoteUrl(tuckDir);\n\n if (status.ahead === 0 && status.tracking) {\n prompts.log.success('Already up to date with remote');\n return;\n }\n\n // Show what will be pushed\n console.log();\n console.log(chalk.dim('Remote:'), remoteUrl);\n console.log(chalk.dim('Branch:'), branch);\n\n if (status.ahead > 0) {\n console.log(chalk.dim('Commits:'), chalk.green(`↑ ${status.ahead} to push`));\n }\n\n if (status.behind > 0) {\n console.log(chalk.dim('Warning:'), chalk.yellow(`↓ ${status.behind} commits behind remote`));\n\n const pullFirst = await prompts.confirm('Pull changes first?', true);\n if (pullFirst) {\n prompts.log.info(\"Run 'tuck pull' first, then push\");\n return;\n }\n }\n\n console.log();\n\n // Confirm\n const confirm = await prompts.confirm('Push to remote?', true);\n if (!confirm) {\n prompts.cancel('Operation cancelled');\n return;\n }\n\n // Push\n const needsUpstream = !status.tracking;\n\n await withSpinner('Pushing...', async () => {\n await push(tuckDir, {\n setUpstream: needsUpstream,\n branch: needsUpstream ? branch : undefined,\n });\n });\n\n prompts.log.success('Pushed successfully!');\n\n if (remoteUrl) {\n // Extract repo URL for display\n let viewUrl = remoteUrl;\n if (remoteUrl.startsWith('git@github.com:')) {\n viewUrl = remoteUrl\n .replace('git@github.com:', 'https://github.com/')\n .replace('.git', '');\n }\n console.log();\n console.log(chalk.dim('View at:'), chalk.cyan(viewUrl));\n }\n\n prompts.outro('');\n};\n\nconst runPush = async (options: PushOptions): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Verify tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n // If no options, run interactive\n if (!options.force && !options.setUpstream) {\n await runInteractivePush(tuckDir);\n return;\n }\n\n // Check if remote exists\n const hasRemoteRepo = await hasRemote(tuckDir);\n if (!hasRemoteRepo) {\n throw new GitError('No remote configured', \"Run 'tuck init -r <url>' or add a remote manually\");\n }\n\n const branch = await getCurrentBranch(tuckDir);\n\n await withSpinner('Pushing...', async () => {\n await push(tuckDir, {\n force: options.force,\n setUpstream: Boolean(options.setUpstream),\n branch: options.setUpstream || branch,\n });\n });\n\n logger.success('Pushed successfully!');\n};\n\nexport const pushCommand = new Command('push')\n .description('Push changes to remote repository')\n .option('-f, --force', 'Force push')\n .option('--set-upstream <name>', 'Set upstream branch')\n .action(async (options: PushOptions) => {\n await runPush(options);\n });\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { prompts, logger, withSpinner } from '../ui/index.js';\nimport { getTuckDir } from '../lib/paths.js';\nimport { loadManifest } from '../lib/manifest.js';\nimport {\n pull,\n fetch,\n hasRemote,\n getRemoteUrl,\n getStatus,\n getCurrentBranch,\n} from '../lib/git.js';\nimport { NotInitializedError, GitError } from '../errors.js';\nimport type { PullOptions } from '../types.js';\n\nconst runInteractivePull = async (tuckDir: string): Promise<void> => {\n prompts.intro('tuck pull');\n\n // Check if remote exists\n const hasRemoteRepo = await hasRemote(tuckDir);\n if (!hasRemoteRepo) {\n prompts.log.error('No remote configured');\n prompts.note(\"Run 'tuck init -r <url>' or add a remote manually\", 'Tip');\n return;\n }\n\n // Fetch first to get latest remote status\n await withSpinner('Fetching...', async () => {\n await fetch(tuckDir);\n });\n\n // Get current status\n const status = await getStatus(tuckDir);\n const branch = await getCurrentBranch(tuckDir);\n const remoteUrl = await getRemoteUrl(tuckDir);\n\n // Show status\n console.log();\n console.log(chalk.dim('Remote:'), remoteUrl);\n console.log(chalk.dim('Branch:'), branch);\n\n if (status.behind === 0) {\n prompts.log.success('Already up to date');\n return;\n }\n\n console.log(chalk.dim('Commits:'), chalk.yellow(`↓ ${status.behind} to pull`));\n\n if (status.ahead > 0) {\n console.log(\n chalk.dim('Note:'),\n chalk.yellow(`You also have ${status.ahead} local commit${status.ahead > 1 ? 's' : ''} to push`)\n );\n }\n\n // Check for local changes\n if (status.modified.length > 0 || status.staged.length > 0) {\n console.log();\n prompts.log.warning('You have uncommitted changes');\n console.log(chalk.dim('Modified:'), status.modified.join(', '));\n\n const continueAnyway = await prompts.confirm('Pull anyway? (may cause merge conflicts)');\n if (!continueAnyway) {\n prompts.cancel(\"Commit or stash your changes first with 'tuck sync'\");\n return;\n }\n }\n\n console.log();\n\n // Ask about rebase\n const useRebase = await prompts.confirm('Use rebase instead of merge?');\n\n // Pull\n await withSpinner('Pulling...', async () => {\n await pull(tuckDir, { rebase: useRebase });\n });\n\n prompts.log.success('Pulled successfully!');\n\n // Ask about restore\n const shouldRestore = await prompts.confirm('Restore updated dotfiles to system?', true);\n if (shouldRestore) {\n prompts.note(\"Run 'tuck restore --all' to restore all dotfiles\", 'Next step');\n }\n\n prompts.outro('');\n};\n\nconst runPull = async (options: PullOptions): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Verify tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n // If no options, run interactive\n if (!options.rebase && !options.restore) {\n await runInteractivePull(tuckDir);\n return;\n }\n\n // Check if remote exists\n const hasRemoteRepo = await hasRemote(tuckDir);\n if (!hasRemoteRepo) {\n throw new GitError('No remote configured', \"Run 'tuck init -r <url>' or add a remote manually\");\n }\n\n // Fetch first\n await withSpinner('Fetching...', async () => {\n await fetch(tuckDir);\n });\n\n // Pull\n await withSpinner('Pulling...', async () => {\n await pull(tuckDir, { rebase: options.rebase });\n });\n\n logger.success('Pulled successfully!');\n\n if (options.restore) {\n logger.info(\"Run 'tuck restore --all' to restore dotfiles\");\n }\n};\n\nexport const pullCommand = new Command('pull')\n .description('Pull changes from remote')\n .option('--rebase', 'Pull with rebase')\n .option('--restore', 'Also restore files to system after pull')\n .action(async (options: PullOptions) => {\n await runPull(options);\n });\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { join } from 'path';\nimport { chmod, stat } from 'fs/promises';\nimport { prompts, logger, withSpinner } from '../ui/index.js';\nimport { getTuckDir, expandPath, pathExists, collapsePath } from '../lib/paths.js';\nimport { loadManifest, getAllTrackedFiles, getTrackedFileBySource } from '../lib/manifest.js';\nimport { loadConfig } from '../lib/config.js';\nimport { copyFileOrDir, createSymlink } from '../lib/files.js';\nimport { createBackup } from '../lib/backup.js';\nimport { runPreRestoreHook, runPostRestoreHook, type HookOptions } from '../lib/hooks.js';\nimport { NotInitializedError, FileNotFoundError } from '../errors.js';\nimport { CATEGORIES } from '../constants.js';\nimport type { RestoreOptions } from '../types.js';\n\n/**\n * Fix permissions for SSH files after restore\n * SSH requires strict permissions: 700 for directories, 600 for private files\n */\nconst fixSSHPermissions = async (path: string): Promise<void> => {\n const expandedPath = expandPath(path);\n\n // Only fix permissions for SSH files\n // Check for files inside .ssh/ directory or the .ssh directory itself\n if (!path.includes('.ssh/') && !path.endsWith('.ssh')) {\n return;\n }\n\n try {\n const stats = await stat(expandedPath);\n\n if (stats.isDirectory()) {\n // Directories should be 700\n await chmod(expandedPath, 0o700);\n } else {\n // Files should be 600\n await chmod(expandedPath, 0o600);\n }\n } catch {\n // Ignore permission errors (might be on Windows)\n }\n};\n\n/**\n * Fix GPG permissions after restore\n */\nconst fixGPGPermissions = async (path: string): Promise<void> => {\n const expandedPath = expandPath(path);\n\n // Only fix permissions for GPG files\n // Check for files inside .gnupg/ directory or the .gnupg directory itself\n if (!path.includes('.gnupg/') && !path.endsWith('.gnupg')) {\n return;\n }\n\n try {\n const stats = await stat(expandedPath);\n\n if (stats.isDirectory()) {\n await chmod(expandedPath, 0o700);\n } else {\n await chmod(expandedPath, 0o600);\n }\n } catch {\n // Ignore permission errors\n }\n};\n\ninterface FileToRestore {\n id: string;\n source: string;\n destination: string;\n category: string;\n existsAtTarget: boolean;\n}\n\nconst prepareFilesToRestore = async (\n tuckDir: string,\n paths?: string[]\n): Promise<FileToRestore[]> => {\n const allFiles = await getAllTrackedFiles(tuckDir);\n const filesToRestore: FileToRestore[] = [];\n\n if (paths && paths.length > 0) {\n // Restore specific files\n for (const path of paths) {\n const expandedPath = expandPath(path);\n const collapsedPath = collapsePath(expandedPath);\n\n const tracked = await getTrackedFileBySource(tuckDir, collapsedPath);\n if (!tracked) {\n throw new FileNotFoundError(`Not tracked: ${path}`);\n }\n\n filesToRestore.push({\n id: tracked.id,\n source: tracked.file.source,\n destination: join(tuckDir, tracked.file.destination),\n category: tracked.file.category,\n existsAtTarget: await pathExists(expandedPath),\n });\n }\n } else {\n // Restore all files\n for (const [id, file] of Object.entries(allFiles)) {\n const targetPath = expandPath(file.source);\n filesToRestore.push({\n id,\n source: file.source,\n destination: join(tuckDir, file.destination),\n category: file.category,\n existsAtTarget: await pathExists(targetPath),\n });\n }\n }\n\n return filesToRestore;\n};\n\nconst restoreFiles = async (\n tuckDir: string,\n files: FileToRestore[],\n options: RestoreOptions\n): Promise<number> => {\n const config = await loadConfig(tuckDir);\n const useSymlink = options.symlink || config.files.strategy === 'symlink';\n const shouldBackup = options.backup ?? config.files.backupOnRestore;\n\n // Prepare hook options\n const hookOptions: HookOptions = {\n skipHooks: options.noHooks,\n trustHooks: options.trustHooks,\n };\n\n // Run pre-restore hook\n await runPreRestoreHook(tuckDir, hookOptions);\n\n let restoredCount = 0;\n\n for (const file of files) {\n const targetPath = expandPath(file.source);\n\n // Check if source exists in repository\n if (!(await pathExists(file.destination))) {\n logger.warning(`Source not found in repository: ${file.source}`);\n continue;\n }\n\n // Dry run - just show what would happen\n if (options.dryRun) {\n if (file.existsAtTarget) {\n logger.file('modify', `${file.source} (would overwrite)`);\n } else {\n logger.file('add', `${file.source} (would create)`);\n }\n continue;\n }\n\n // Create backup if needed\n if (shouldBackup && file.existsAtTarget) {\n await withSpinner(`Backing up ${file.source}...`, async () => {\n await createBackup(targetPath);\n });\n }\n\n // Restore file\n await withSpinner(`Restoring ${file.source}...`, async () => {\n if (useSymlink) {\n await createSymlink(file.destination, targetPath, { overwrite: true });\n } else {\n await copyFileOrDir(file.destination, targetPath, { overwrite: true });\n }\n\n // Fix permissions for sensitive files\n await fixSSHPermissions(file.source);\n await fixGPGPermissions(file.source);\n });\n\n restoredCount++;\n }\n\n // Run post-restore hook\n await runPostRestoreHook(tuckDir, hookOptions);\n\n return restoredCount;\n};\n\nconst runInteractiveRestore = async (tuckDir: string): Promise<void> => {\n prompts.intro('tuck restore');\n\n // Get all tracked files\n const files = await prepareFilesToRestore(tuckDir);\n\n if (files.length === 0) {\n prompts.log.warning('No files to restore');\n prompts.note(\"Run 'tuck add <path>' to track files first\", 'Tip');\n return;\n }\n\n // Let user select files to restore\n const fileOptions = files.map((file) => {\n const categoryConfig = CATEGORIES[file.category] || { icon: '📄' };\n const status = file.existsAtTarget ? chalk.yellow('(exists, will backup)') : '';\n\n return {\n value: file.id,\n label: `${categoryConfig.icon} ${file.source} ${status}`,\n hint: file.category,\n };\n });\n\n const selectedIds = await prompts.multiselect('Select files to restore:', fileOptions, true);\n\n if (selectedIds.length === 0) {\n prompts.cancel('No files selected');\n return;\n }\n\n const selectedFiles = files.filter((f) => selectedIds.includes(f.id));\n\n // Check for files that exist\n const existingFiles = selectedFiles.filter((f) => f.existsAtTarget);\n if (existingFiles.length > 0) {\n console.log();\n prompts.log.warning(\n `${existingFiles.length} file${existingFiles.length > 1 ? 's' : ''} will be backed up:`\n );\n existingFiles.forEach((f) => console.log(chalk.dim(` ${f.source}`)));\n console.log();\n }\n\n // Ask about strategy\n const useSymlink = await prompts.select('Restore method:', [\n { value: false, label: 'Copy files', hint: 'Recommended' },\n { value: true, label: 'Create symlinks', hint: 'Files stay in tuck repo' },\n ]);\n\n // Confirm\n const confirm = await prompts.confirm(\n `Restore ${selectedFiles.length} file${selectedFiles.length > 1 ? 's' : ''}?`,\n true\n );\n\n if (!confirm) {\n prompts.cancel('Operation cancelled');\n return;\n }\n\n // Restore\n const restoredCount = await restoreFiles(tuckDir, selectedFiles, {\n symlink: useSymlink as boolean,\n backup: true,\n });\n\n console.log();\n prompts.outro(`Restored ${restoredCount} file${restoredCount > 1 ? 's' : ''}`);\n};\n\nconst runRestore = async (paths: string[], options: RestoreOptions): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Verify tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n // If no paths and no --all, run interactive\n if (paths.length === 0 && !options.all) {\n await runInteractiveRestore(tuckDir);\n return;\n }\n\n // Prepare files to restore\n const files = await prepareFilesToRestore(tuckDir, options.all ? undefined : paths);\n\n if (files.length === 0) {\n logger.warning('No files to restore');\n return;\n }\n\n // Show what will be restored\n if (options.dryRun) {\n logger.heading('Dry run - would restore:');\n } else {\n logger.heading('Restoring:');\n }\n\n // Restore files\n const restoredCount = await restoreFiles(tuckDir, files, options);\n\n logger.blank();\n\n if (options.dryRun) {\n logger.info(`Would restore ${files.length} file${files.length > 1 ? 's' : ''}`);\n } else {\n logger.success(`Restored ${restoredCount} file${restoredCount > 1 ? 's' : ''}`);\n }\n};\n\nexport const restoreCommand = new Command('restore')\n .description('Restore dotfiles to the system')\n .argument('[paths...]', 'Paths to restore (or use --all)')\n .option('-a, --all', 'Restore all tracked files')\n .option('--symlink', 'Create symlinks instead of copies')\n .option('--backup', 'Backup existing files before restore')\n .option('--no-backup', 'Skip backup of existing files')\n .option('--dry-run', 'Show what would be done')\n .option('--no-hooks', 'Skip execution of pre/post restore hooks')\n .option('--trust-hooks', 'Trust and run hooks without confirmation (use with caution)')\n .action(async (paths: string[], options: RestoreOptions) => {\n await runRestore(paths, options);\n });\n","import { join } from 'path';\nimport { readdir, rm } from 'fs/promises';\nimport { copy, ensureDir, pathExists } from 'fs-extra';\nimport { BACKUP_DIR } from '../constants.js';\nimport { expandPath, collapsePath, pathExists as checkPathExists } from './paths.js';\n\nexport interface BackupInfo {\n path: string;\n date: Date;\n files: string[];\n}\n\nexport interface BackupResult {\n originalPath: string;\n backupPath: string;\n date: Date;\n}\n\nconst getBackupDir = (): string => {\n return expandPath(BACKUP_DIR);\n};\n\nconst formatDateForBackup = (date: Date): string => {\n return date.toISOString().slice(0, 10); // YYYY-MM-DD\n};\n\nconst getTimestampedBackupDir = (date: Date): string => {\n const backupRoot = getBackupDir();\n const timestamp = formatDateForBackup(date);\n return join(backupRoot, timestamp);\n};\n\nexport const createBackup = async (\n sourcePath: string,\n customBackupDir?: string\n): Promise<BackupResult> => {\n const expandedSource = expandPath(sourcePath);\n const date = new Date();\n\n if (!(await checkPathExists(expandedSource))) {\n throw new Error(`Source path does not exist: ${sourcePath}`);\n }\n\n // Create backup directory with date\n const backupRoot = customBackupDir\n ? expandPath(customBackupDir)\n : getTimestampedBackupDir(date);\n await ensureDir(backupRoot);\n\n // Generate backup filename that preserves structure\n const collapsed = collapsePath(expandedSource);\n const backupName = collapsed\n .replace(/^~\\//, '')\n .replace(/\\//g, '_')\n .replace(/^\\./, 'dot-');\n\n // Add timestamp to handle multiple backups of same file in a day\n const timestamp = date.toISOString().replace(/[:.]/g, '-').slice(11, 19);\n const backupPath = join(backupRoot, `${backupName}_${timestamp}`);\n\n await copy(expandedSource, backupPath, { overwrite: true });\n\n return {\n originalPath: expandedSource,\n backupPath,\n date,\n };\n};\n\nexport const createMultipleBackups = async (\n sourcePaths: string[],\n customBackupDir?: string\n): Promise<BackupResult[]> => {\n const results: BackupResult[] = [];\n\n for (const path of sourcePaths) {\n const result = await createBackup(path, customBackupDir);\n results.push(result);\n }\n\n return results;\n};\n\nexport const listBackups = async (): Promise<BackupInfo[]> => {\n const backupRoot = getBackupDir();\n\n if (!(await pathExists(backupRoot))) {\n return [];\n }\n\n const backups: BackupInfo[] = [];\n const dateDirs = await readdir(backupRoot, { withFileTypes: true });\n\n for (const dateDir of dateDirs) {\n if (!dateDir.isDirectory()) continue;\n\n const datePath = join(backupRoot, dateDir.name);\n const files = await readdir(datePath);\n\n // Parse date from directory name\n const dateMatch = dateDir.name.match(/^(\\d{4})-(\\d{2})-(\\d{2})$/);\n if (!dateMatch) continue;\n\n const date = new Date(`${dateMatch[1]}-${dateMatch[2]}-${dateMatch[3]}`);\n\n backups.push({\n path: datePath,\n date,\n files: files.map((f) => join(datePath, f)),\n });\n }\n\n // Sort by date, newest first\n return backups.sort((a, b) => b.date.getTime() - a.date.getTime());\n};\n\nexport const getBackupsByDate = async (date: Date): Promise<string[]> => {\n const backupDir = getTimestampedBackupDir(date);\n\n if (!(await pathExists(backupDir))) {\n return [];\n }\n\n const files = await readdir(backupDir);\n return files.map((f) => join(backupDir, f));\n};\n\nexport const restoreBackup = async (backupPath: string, targetPath: string): Promise<void> => {\n const expandedBackup = expandPath(backupPath);\n const expandedTarget = expandPath(targetPath);\n\n if (!(await checkPathExists(expandedBackup))) {\n throw new Error(`Backup not found: ${backupPath}`);\n }\n\n // Create backup of current state before restoring\n if (await checkPathExists(expandedTarget)) {\n await createBackup(expandedTarget);\n }\n\n await copy(expandedBackup, expandedTarget, { overwrite: true });\n};\n\nexport const deleteBackup = async (backupPath: string): Promise<void> => {\n const expandedPath = expandPath(backupPath);\n\n if (await checkPathExists(expandedPath)) {\n await rm(expandedPath, { recursive: true });\n }\n};\n\nexport const cleanOldBackups = async (daysToKeep: number): Promise<number> => {\n const backups = await listBackups();\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - daysToKeep);\n\n let deletedCount = 0;\n\n for (const backup of backups) {\n if (backup.date < cutoffDate) {\n await rm(backup.path, { recursive: true });\n deletedCount++;\n }\n }\n\n return deletedCount;\n};\n\nexport const getBackupSize = async (): Promise<number> => {\n const backups = await listBackups();\n let totalSize = 0;\n\n for (const backup of backups) {\n for (const file of backup.files) {\n const { stat } = await import('fs/promises');\n try {\n const stats = await stat(file);\n totalSize += stats.size;\n } catch {\n // Ignore errors\n }\n }\n }\n\n return totalSize;\n};\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { prompts, formatStatus } from '../ui/index.js';\nimport { getTuckDir, collapsePath, expandPath, pathExists } from '../lib/paths.js';\nimport { loadManifest, getAllTrackedFiles } from '../lib/manifest.js';\nimport { getStatus, hasRemote, getRemoteUrl, getCurrentBranch } from '../lib/git.js';\nimport { getFileChecksum } from '../lib/files.js';\nimport { NotInitializedError } from '../errors.js';\nimport type { StatusOptions, FileChange } from '../types.js';\n\ninterface TuckStatus {\n tuckDir: string;\n branch: string;\n remote?: string;\n remoteStatus: 'up-to-date' | 'ahead' | 'behind' | 'diverged' | 'no-remote';\n ahead: number;\n behind: number;\n trackedCount: number;\n changes: FileChange[];\n gitChanges: {\n staged: string[];\n modified: string[];\n untracked: string[];\n };\n}\n\nconst detectFileChanges = async (tuckDir: string): Promise<FileChange[]> => {\n const files = await getAllTrackedFiles(tuckDir);\n const changes: FileChange[] = [];\n\n for (const [, file] of Object.entries(files)) {\n const sourcePath = expandPath(file.source);\n\n // Check if source still exists\n if (!(await pathExists(sourcePath))) {\n changes.push({\n path: file.source,\n status: 'deleted',\n source: file.source,\n destination: file.destination,\n });\n continue;\n }\n\n // Check if file has changed\n try {\n const sourceChecksum = await getFileChecksum(sourcePath);\n if (sourceChecksum !== file.checksum) {\n changes.push({\n path: file.source,\n status: 'modified',\n source: file.source,\n destination: file.destination,\n });\n }\n } catch {\n // Error reading file, mark as modified\n changes.push({\n path: file.source,\n status: 'modified',\n source: file.source,\n destination: file.destination,\n });\n }\n }\n\n return changes;\n};\n\nconst getFullStatus = async (tuckDir: string): Promise<TuckStatus> => {\n const manifest = await loadManifest(tuckDir);\n const gitStatus = await getStatus(tuckDir);\n const branch = await getCurrentBranch(tuckDir);\n const hasRemoteRepo = await hasRemote(tuckDir);\n const remoteUrl = hasRemoteRepo ? await getRemoteUrl(tuckDir) : undefined;\n\n let remoteStatus: TuckStatus['remoteStatus'] = 'no-remote';\n if (hasRemoteRepo) {\n if (gitStatus.ahead > 0 && gitStatus.behind > 0) {\n remoteStatus = 'diverged';\n } else if (gitStatus.ahead > 0) {\n remoteStatus = 'ahead';\n } else if (gitStatus.behind > 0) {\n remoteStatus = 'behind';\n } else {\n remoteStatus = 'up-to-date';\n }\n }\n\n const fileChanges = await detectFileChanges(tuckDir);\n\n return {\n tuckDir,\n branch,\n remote: remoteUrl || undefined,\n remoteStatus,\n ahead: gitStatus.ahead,\n behind: gitStatus.behind,\n trackedCount: Object.keys(manifest.files).length,\n changes: fileChanges,\n gitChanges: {\n staged: gitStatus.staged,\n modified: gitStatus.modified,\n untracked: gitStatus.untracked,\n },\n };\n};\n\nconst printStatus = (status: TuckStatus): void => {\n prompts.intro('tuck status');\n\n // Repository info\n console.log();\n console.log(chalk.dim('Repository:'), collapsePath(status.tuckDir));\n console.log(chalk.dim('Branch:'), chalk.cyan(status.branch));\n\n if (status.remote) {\n console.log(chalk.dim('Remote:'), status.remote);\n\n let remoteInfo = '';\n switch (status.remoteStatus) {\n case 'up-to-date':\n remoteInfo = chalk.green('up to date');\n break;\n case 'ahead':\n remoteInfo = chalk.yellow(`${status.ahead} commit${status.ahead > 1 ? 's' : ''} ahead`);\n break;\n case 'behind':\n remoteInfo = chalk.yellow(`${status.behind} commit${status.behind > 1 ? 's' : ''} behind`);\n break;\n case 'diverged':\n remoteInfo = chalk.red(`diverged (${status.ahead} ahead, ${status.behind} behind)`);\n break;\n }\n console.log(chalk.dim('Status:'), remoteInfo);\n } else {\n console.log(chalk.dim('Remote:'), chalk.yellow('not configured'));\n }\n\n console.log();\n console.log(chalk.dim('Tracked files:'), status.trackedCount);\n\n // File changes\n if (status.changes.length > 0) {\n console.log();\n console.log(chalk.bold('Changes detected:'));\n for (const change of status.changes) {\n const statusText = formatStatus(change.status);\n console.log(` ${statusText}: ${chalk.cyan(change.path)}`);\n }\n }\n\n // Git changes in repository\n const hasGitChanges =\n status.gitChanges.staged.length > 0 ||\n status.gitChanges.modified.length > 0 ||\n status.gitChanges.untracked.length > 0;\n\n if (hasGitChanges) {\n console.log();\n console.log(chalk.bold('Repository changes:'));\n\n if (status.gitChanges.staged.length > 0) {\n console.log(chalk.green(' Staged:'));\n status.gitChanges.staged.forEach((f) => console.log(chalk.green(` + ${f}`)));\n }\n\n if (status.gitChanges.modified.length > 0) {\n console.log(chalk.yellow(' Modified:'));\n status.gitChanges.modified.forEach((f) => console.log(chalk.yellow(` ~ ${f}`)));\n }\n\n if (status.gitChanges.untracked.length > 0) {\n console.log(chalk.dim(' Untracked:'));\n status.gitChanges.untracked.forEach((f) => console.log(chalk.dim(` ? ${f}`)));\n }\n }\n\n console.log();\n\n // Suggestions\n if (status.changes.length > 0) {\n prompts.note(\"Run 'tuck sync' to commit changes\", 'Next step');\n } else if (status.remoteStatus === 'ahead') {\n prompts.note(\"Run 'tuck push' to push changes to remote\", 'Next step');\n } else if (status.remoteStatus === 'behind') {\n prompts.note(\"Run 'tuck pull' to pull changes from remote\", 'Next step');\n } else if (status.trackedCount === 0) {\n prompts.note(\"Run 'tuck add <path>' to start tracking files\", 'Next step');\n } else {\n prompts.outro('Everything is up to date');\n }\n};\n\nconst printShortStatus = (status: TuckStatus): void => {\n const parts: string[] = [];\n\n parts.push(`[${status.branch}]`);\n\n if (status.remoteStatus === 'ahead') {\n parts.push(`↑${status.ahead}`);\n } else if (status.remoteStatus === 'behind') {\n parts.push(`↓${status.behind}`);\n } else if (status.remoteStatus === 'diverged') {\n parts.push(`↑${status.ahead}↓${status.behind}`);\n }\n\n if (status.changes.length > 0) {\n const modified = status.changes.filter((c) => c.status === 'modified').length;\n const deleted = status.changes.filter((c) => c.status === 'deleted').length;\n if (modified > 0) parts.push(`~${modified}`);\n if (deleted > 0) parts.push(`-${deleted}`);\n }\n\n parts.push(`(${status.trackedCount} tracked)`);\n\n console.log(parts.join(' '));\n};\n\nconst printJsonStatus = (status: TuckStatus): void => {\n console.log(JSON.stringify(status, null, 2));\n};\n\nconst runStatus = async (options: StatusOptions): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Verify tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n const status = await getFullStatus(tuckDir);\n\n if (options.json) {\n printJsonStatus(status);\n } else if (options.short) {\n printShortStatus(status);\n } else {\n printStatus(status);\n }\n};\n\nexport const statusCommand = new Command('status')\n .description('Show current tracking status')\n .option('--short', 'Short format')\n .option('--json', 'Output as JSON')\n .action(async (options: StatusOptions) => {\n await runStatus(options);\n });\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { prompts, logger, formatCount } from '../ui/index.js';\nimport { getTuckDir } from '../lib/paths.js';\nimport { loadManifest, getAllTrackedFiles } from '../lib/manifest.js';\nimport { NotInitializedError } from '../errors.js';\nimport { CATEGORIES } from '../constants.js';\nimport type { ListOptions } from '../types.js';\n\ninterface CategoryGroup {\n name: string;\n icon: string;\n files: { id: string; source: string; destination: string; isDir: boolean }[];\n}\n\nconst groupByCategory = async (tuckDir: string): Promise<CategoryGroup[]> => {\n const files = await getAllTrackedFiles(tuckDir);\n const groups: Map<string, CategoryGroup> = new Map();\n\n for (const [id, file] of Object.entries(files)) {\n const category = file.category;\n const categoryConfig = CATEGORIES[category] || { icon: '📄' };\n\n if (!groups.has(category)) {\n groups.set(category, {\n name: category,\n icon: categoryConfig.icon,\n files: [],\n });\n }\n\n groups.get(category)!.files.push({\n id,\n source: file.source,\n destination: file.destination,\n isDir: file.destination.endsWith('/') || file.destination.includes('nvim'),\n });\n }\n\n // Sort groups by name and files within each group\n return Array.from(groups.values())\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((group) => ({\n ...group,\n files: group.files.sort((a, b) => a.source.localeCompare(b.source)),\n }));\n};\n\nconst printList = (groups: CategoryGroup[]): void => {\n prompts.intro('tuck list');\n\n if (groups.length === 0) {\n prompts.log.warning('No files are currently tracked');\n prompts.note(\"Run 'tuck add <path>' to start tracking files\", 'Tip');\n return;\n }\n\n let totalFiles = 0;\n\n for (const group of groups) {\n const fileCount = group.files.length;\n totalFiles += fileCount;\n\n console.log();\n console.log(\n chalk.bold(`${group.icon} ${group.name}`) +\n chalk.dim(` (${formatCount(fileCount, 'file')})`)\n );\n\n group.files.forEach((file, index) => {\n const isLast = index === group.files.length - 1;\n const prefix = isLast ? '└── ' : '├── ';\n const name = file.source.split('/').pop() || file.source;\n const arrow = chalk.dim(' → ');\n const dest = chalk.dim(file.source);\n\n console.log(chalk.dim(prefix) + chalk.cyan(name) + arrow + dest);\n });\n }\n\n console.log();\n prompts.outro(`Total: ${formatCount(totalFiles, 'tracked item')}`);\n};\n\nconst printPathsOnly = (groups: CategoryGroup[]): void => {\n for (const group of groups) {\n for (const file of group.files) {\n console.log(file.source);\n }\n }\n};\n\nconst printJson = (groups: CategoryGroup[]): void => {\n const output = groups.reduce(\n (acc, group) => {\n acc[group.name] = group.files.map((f) => ({\n source: f.source,\n destination: f.destination,\n }));\n return acc;\n },\n {} as Record<string, { source: string; destination: string }[]>\n );\n\n console.log(JSON.stringify(output, null, 2));\n};\n\nconst runList = async (options: ListOptions): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Verify tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n let groups = await groupByCategory(tuckDir);\n\n // Filter by category if specified\n if (options.category) {\n groups = groups.filter((g) => g.name === options.category);\n if (groups.length === 0) {\n logger.warning(`No files found in category: ${options.category}`);\n return;\n }\n }\n\n // Output based on format\n if (options.json) {\n printJson(groups);\n } else if (options.paths) {\n printPathsOnly(groups);\n } else {\n printList(groups);\n }\n};\n\nexport const listCommand = new Command('list')\n .description('List all tracked files')\n .option('-c, --category <name>', 'Filter by category')\n .option('--paths', 'Show only paths')\n .option('--json', 'Output as JSON')\n .action(async (options: ListOptions) => {\n await runList(options);\n });\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { join } from 'path';\nimport { prompts, logger } from '../ui/index.js';\nimport { getTuckDir, expandPath, pathExists, collapsePath } from '../lib/paths.js';\nimport { loadManifest, getAllTrackedFiles, getTrackedFileBySource } from '../lib/manifest.js';\nimport { getDiff } from '../lib/git.js';\nimport { getFileChecksum } from '../lib/files.js';\nimport { NotInitializedError, FileNotFoundError } from '../errors.js';\nimport type { DiffOptions } from '../types.js';\nimport { readFile } from 'fs/promises';\n\ninterface FileDiff {\n source: string;\n destination: string;\n hasChanges: boolean;\n systemContent?: string;\n repoContent?: string;\n}\n\nconst getFileDiff = async (tuckDir: string, source: string): Promise<FileDiff> => {\n const tracked = await getTrackedFileBySource(tuckDir, source);\n if (!tracked) {\n throw new FileNotFoundError(`Not tracked: ${source}`);\n }\n\n const systemPath = expandPath(source);\n const repoPath = join(tuckDir, tracked.file.destination);\n\n const diff: FileDiff = {\n source,\n destination: tracked.file.destination,\n hasChanges: false,\n };\n\n // Check if system file exists\n if (!(await pathExists(systemPath))) {\n diff.hasChanges = true;\n if (await pathExists(repoPath)) {\n diff.repoContent = await readFile(repoPath, 'utf-8');\n }\n return diff;\n }\n\n // Check if repo file exists\n if (!(await pathExists(repoPath))) {\n diff.hasChanges = true;\n diff.systemContent = await readFile(systemPath, 'utf-8');\n return diff;\n }\n\n // Compare checksums\n const systemChecksum = await getFileChecksum(systemPath);\n const repoChecksum = await getFileChecksum(repoPath);\n\n if (systemChecksum !== repoChecksum) {\n diff.hasChanges = true;\n diff.systemContent = await readFile(systemPath, 'utf-8');\n diff.repoContent = await readFile(repoPath, 'utf-8');\n }\n\n return diff;\n};\n\nconst formatUnifiedDiff = (\n source: string,\n systemContent?: string,\n repoContent?: string\n): string => {\n const lines: string[] = [];\n\n lines.push(chalk.bold(`--- a/${source} (system)`));\n lines.push(chalk.bold(`+++ b/${source} (repository)`));\n\n if (!systemContent && repoContent) {\n // File only in repo\n lines.push(chalk.red('File missing on system'));\n lines.push(chalk.dim('Repository content:'));\n repoContent.split('\\n').forEach((line) => {\n lines.push(chalk.green(`+ ${line}`));\n });\n } else if (systemContent && !repoContent) {\n // File only on system\n lines.push(chalk.yellow('File not yet synced to repository'));\n lines.push(chalk.dim('System content:'));\n systemContent.split('\\n').forEach((line) => {\n lines.push(chalk.red(`- ${line}`));\n });\n } else if (systemContent && repoContent) {\n // Simple line-by-line diff\n const systemLines = systemContent.split('\\n');\n const repoLines = repoContent.split('\\n');\n\n const maxLines = Math.max(systemLines.length, repoLines.length);\n\n let inDiff = false;\n let diffStart = 0;\n\n for (let i = 0; i < maxLines; i++) {\n const sysLine = systemLines[i];\n const repoLine = repoLines[i];\n\n if (sysLine !== repoLine) {\n if (!inDiff) {\n inDiff = true;\n diffStart = i;\n lines.push(chalk.cyan(`@@ -${i + 1} +${i + 1} @@`));\n }\n\n if (sysLine !== undefined) {\n lines.push(chalk.red(`- ${sysLine}`));\n }\n if (repoLine !== undefined) {\n lines.push(chalk.green(`+ ${repoLine}`));\n }\n } else if (inDiff) {\n // Show a bit of context then stop\n lines.push(chalk.dim(` ${sysLine || ''}`));\n if (i - diffStart > 3) {\n inDiff = false;\n }\n }\n }\n }\n\n return lines.join('\\n');\n};\n\nconst runDiff = async (paths: string[], options: DiffOptions): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Verify tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n // If --staged, show git diff\n if (options.staged) {\n const diff = await getDiff(tuckDir, { staged: true, stat: options.stat });\n if (diff) {\n console.log(diff);\n } else {\n logger.info('No staged changes');\n }\n return;\n }\n\n // If no paths, show all changed files\n if (paths.length === 0) {\n const allFiles = await getAllTrackedFiles(tuckDir);\n const changedFiles: FileDiff[] = [];\n\n for (const [, file] of Object.entries(allFiles)) {\n const diff = await getFileDiff(tuckDir, file.source);\n if (diff.hasChanges) {\n changedFiles.push(diff);\n }\n }\n\n if (changedFiles.length === 0) {\n logger.success('No differences found');\n return;\n }\n\n if (options.stat) {\n // Show summary only\n prompts.intro('tuck diff');\n console.log();\n console.log(chalk.bold(`${changedFiles.length} file${changedFiles.length > 1 ? 's' : ''} changed:`));\n console.log();\n\n for (const diff of changedFiles) {\n console.log(chalk.yellow(` ~ ${diff.source}`));\n }\n\n console.log();\n return;\n }\n\n // Show full diff for each file\n for (const diff of changedFiles) {\n console.log();\n console.log(formatUnifiedDiff(diff.source, diff.systemContent, diff.repoContent));\n console.log();\n }\n\n return;\n }\n\n // Show diff for specific files\n for (const path of paths) {\n const expandedPath = expandPath(path);\n const collapsedPath = collapsePath(expandedPath);\n\n const diff = await getFileDiff(tuckDir, collapsedPath);\n\n if (!diff.hasChanges) {\n logger.info(`No changes: ${path}`);\n continue;\n }\n\n if (options.stat) {\n console.log(chalk.yellow(`~ ${path}`));\n } else {\n console.log(formatUnifiedDiff(path, diff.systemContent, diff.repoContent));\n console.log();\n }\n }\n};\n\nexport const diffCommand = new Command('diff')\n .description('Show differences between system and repository')\n .argument('[paths...]', 'Specific files to diff')\n .option('--staged', 'Show staged git changes')\n .option('--stat', 'Show diffstat only')\n .action(async (paths: string[], options: DiffOptions) => {\n await runDiff(paths, options);\n });\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { spawn } from 'child_process';\nimport { prompts, logger } from '../ui/index.js';\nimport { getTuckDir, getConfigPath, collapsePath } from '../lib/paths.js';\nimport { loadConfig, saveConfig, resetConfig } from '../lib/config.js';\nimport { loadManifest } from '../lib/manifest.js';\nimport { NotInitializedError, ConfigError } from '../errors.js';\nimport type { TuckConfigOutput } from '../schemas/config.schema.js';\n\nconst printConfig = (config: TuckConfigOutput): void => {\n console.log(JSON.stringify(config, null, 2));\n};\n\nconst getNestedValue = (obj: Record<string, unknown>, path: string): unknown => {\n const keys = path.split('.');\n let current: unknown = obj;\n\n for (const key of keys) {\n if (current === null || current === undefined) {\n return undefined;\n }\n if (typeof current !== 'object') {\n return undefined;\n }\n current = (current as Record<string, unknown>)[key];\n }\n\n return current;\n};\n\nconst setNestedValue = (\n obj: Record<string, unknown>,\n path: string,\n value: unknown\n): void => {\n const keys = path.split('.');\n let current = obj;\n\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n if (!(key in current) || typeof current[key] !== 'object') {\n current[key] = {};\n }\n current = current[key] as Record<string, unknown>;\n }\n\n current[keys[keys.length - 1]] = value;\n};\n\nconst parseValue = (value: string): unknown => {\n // Try to parse as JSON\n try {\n return JSON.parse(value);\n } catch {\n // Return as string if not valid JSON\n return value;\n }\n};\n\nconst runConfigGet = async (key: string): Promise<void> => {\n const tuckDir = getTuckDir();\n const config = await loadConfig(tuckDir);\n\n const value = getNestedValue(config as unknown as Record<string, unknown>, key);\n\n if (value === undefined) {\n logger.error(`Key not found: ${key}`);\n return;\n }\n\n if (typeof value === 'object') {\n console.log(JSON.stringify(value, null, 2));\n } else {\n console.log(value);\n }\n};\n\nconst runConfigSet = async (key: string, value: string): Promise<void> => {\n const tuckDir = getTuckDir();\n const config = await loadConfig(tuckDir);\n\n const parsedValue = parseValue(value);\n const configObj = config as unknown as Record<string, unknown>;\n\n setNestedValue(configObj, key, parsedValue);\n\n await saveConfig(config, tuckDir);\n logger.success(`Set ${key} = ${JSON.stringify(parsedValue)}`);\n};\n\nconst runConfigList = async (): Promise<void> => {\n const tuckDir = getTuckDir();\n const config = await loadConfig(tuckDir);\n\n prompts.intro('tuck config');\n console.log();\n console.log(chalk.dim('Configuration file:'), collapsePath(getConfigPath(tuckDir)));\n console.log();\n\n printConfig(config);\n};\n\nconst runConfigEdit = async (): Promise<void> => {\n const tuckDir = getTuckDir();\n const configPath = getConfigPath(tuckDir);\n\n const editor = process.env.EDITOR || process.env.VISUAL || 'vim';\n\n logger.info(`Opening ${collapsePath(configPath)} in ${editor}...`);\n\n return new Promise((resolve, reject) => {\n const child = spawn(editor, [configPath], {\n stdio: 'inherit',\n });\n\n child.on('exit', (code) => {\n if (code === 0) {\n logger.success('Configuration updated');\n resolve();\n } else {\n reject(new ConfigError(`Editor exited with code ${code}`));\n }\n });\n\n child.on('error', (err) => {\n reject(new ConfigError(`Failed to open editor: ${err.message}`));\n });\n });\n};\n\nconst runConfigReset = async (): Promise<void> => {\n const tuckDir = getTuckDir();\n\n const confirm = await prompts.confirm('Reset configuration to defaults? This cannot be undone.', false);\n\n if (!confirm) {\n prompts.cancel('Operation cancelled');\n return;\n }\n\n await resetConfig(tuckDir);\n logger.success('Configuration reset to defaults');\n};\n\nexport const configCommand = new Command('config')\n .description('Manage tuck configuration')\n .addCommand(\n new Command('get')\n .description('Get a config value')\n .argument('<key>', 'Config key (e.g., \"repository.autoCommit\")')\n .action(async (key: string) => {\n const tuckDir = getTuckDir();\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n await runConfigGet(key);\n })\n )\n .addCommand(\n new Command('set')\n .description('Set a config value')\n .argument('<key>', 'Config key')\n .argument('<value>', 'Value to set (JSON or string)')\n .action(async (key: string, value: string) => {\n const tuckDir = getTuckDir();\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n await runConfigSet(key, value);\n })\n )\n .addCommand(\n new Command('list')\n .description('List all config')\n .action(async () => {\n const tuckDir = getTuckDir();\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n await runConfigList();\n })\n )\n .addCommand(\n new Command('edit')\n .description('Open config in editor')\n .action(async () => {\n const tuckDir = getTuckDir();\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n await runConfigEdit();\n })\n )\n .addCommand(\n new Command('reset')\n .description('Reset to defaults')\n .action(async () => {\n const tuckDir = getTuckDir();\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n await runConfigReset();\n })\n );\n","import { Command } from 'commander';\nimport { join } from 'path';\nimport { readFile, rm, chmod, stat } from 'fs/promises';\nimport { ensureDir, pathExists as fsPathExists } from 'fs-extra';\nimport { tmpdir } from 'os';\nimport chalk from 'chalk';\nimport { banner, prompts, logger } from '../ui/index.js';\nimport { expandPath, pathExists, collapsePath, validateSafeSourcePath } from '../lib/paths.js';\nimport { cloneRepo } from '../lib/git.js';\nimport {\n isGhInstalled,\n findDotfilesRepo,\n ghCloneRepo,\n repoExists,\n} from '../lib/github.js';\nimport { createPreApplySnapshot } from '../lib/timemachine.js';\nimport { smartMerge, isShellFile, generateMergePreview } from '../lib/merge.js';\nimport { copyFileOrDir } from '../lib/files.js';\nimport { CATEGORIES } from '../constants.js';\nimport type { TuckManifest } from '../types.js';\n\n/**\n * Fix permissions for SSH/GPG files after apply\n */\nconst fixSecurePermissions = async (path: string): Promise<void> => {\n const collapsedPath = collapsePath(path);\n\n // Only fix permissions for SSH and GPG files\n if (!collapsedPath.includes('.ssh/') && !collapsedPath.includes('.gnupg/')) {\n return;\n }\n\n try {\n const stats = await stat(path);\n\n if (stats.isDirectory()) {\n await chmod(path, 0o700);\n } else {\n await chmod(path, 0o600);\n }\n } catch {\n // Ignore permission errors (might be on Windows)\n }\n};\n\nexport interface ApplyOptions {\n merge?: boolean;\n replace?: boolean;\n dryRun?: boolean;\n force?: boolean;\n yes?: boolean;\n}\n\ninterface ApplyFile {\n source: string;\n destination: string;\n category: string;\n repoPath: string;\n}\n\n/**\n * Resolve a source (username or repo URL) to a full repository identifier\n */\nconst resolveSource = async (source: string): Promise<{ repoId: string; isUrl: boolean }> => {\n // Check if it's a full URL\n if (source.includes('://') || source.startsWith('git@')) {\n return { repoId: source, isUrl: true };\n }\n\n // Check if it's a GitHub repo identifier (user/repo)\n if (source.includes('/')) {\n return { repoId: source, isUrl: false };\n }\n\n // Assume it's a username, try to find their dotfiles repo\n logger.info(`Looking for dotfiles repository for ${source}...`);\n\n if (await isGhInstalled()) {\n const dotfilesRepo = await findDotfilesRepo(source);\n if (dotfilesRepo) {\n logger.success(`Found repository: ${dotfilesRepo}`);\n return { repoId: dotfilesRepo, isUrl: false };\n }\n }\n\n // Try common repo names\n const commonNames = ['dotfiles', 'tuck', '.dotfiles'];\n for (const name of commonNames) {\n const repoId = `${source}/${name}`;\n if (await repoExists(repoId)) {\n logger.success(`Found repository: ${repoId}`);\n return { repoId, isUrl: false };\n }\n }\n\n throw new Error(\n `Could not find a dotfiles repository for \"${source}\". ` +\n 'Try specifying the full repository name (e.g., username/dotfiles)'\n );\n};\n\n/**\n * Clone the source repository to a temporary directory\n */\nconst cloneSource = async (repoId: string, isUrl: boolean): Promise<string> => {\n const tempDir = join(tmpdir(), `tuck-apply-${Date.now()}`);\n await ensureDir(tempDir);\n\n if (isUrl) {\n await cloneRepo(repoId, tempDir);\n } else {\n // Use gh CLI to clone if available, otherwise construct URL\n if (await isGhInstalled()) {\n await ghCloneRepo(repoId, tempDir);\n } else {\n const url = `https://github.com/${repoId}.git`;\n await cloneRepo(url, tempDir);\n }\n }\n\n return tempDir;\n};\n\n/**\n * Read the manifest from a cloned repository\n */\nconst readClonedManifest = async (repoDir: string): Promise<TuckManifest | null> => {\n const manifestPath = join(repoDir, '.tuckmanifest.json');\n\n if (!(await fsPathExists(manifestPath))) {\n return null;\n }\n\n try {\n const content = await readFile(manifestPath, 'utf-8');\n return JSON.parse(content) as TuckManifest;\n } catch {\n return null;\n }\n};\n\n/**\n * Prepare the list of files to apply\n */\nconst prepareFilesToApply = async (\n repoDir: string,\n manifest: TuckManifest\n): Promise<ApplyFile[]> => {\n const files: ApplyFile[] = [];\n\n for (const [_id, file] of Object.entries(manifest.files)) {\n const repoFilePath = join(repoDir, file.destination);\n\n if (await fsPathExists(repoFilePath)) {\n // Validate that the source path is safe (within home directory)\n // This prevents malicious manifests from writing to arbitrary locations\n try {\n validateSafeSourcePath(file.source);\n } catch (error) {\n logger.warning(`Skipping unsafe path from manifest: ${file.source}`);\n continue;\n }\n\n files.push({\n source: file.source,\n destination: expandPath(file.source),\n category: file.category,\n repoPath: repoFilePath,\n });\n }\n }\n\n return files;\n};\n\n/**\n * Apply files with merge strategy\n */\nconst applyWithMerge = async (files: ApplyFile[], dryRun: boolean): Promise<number> => {\n let appliedCount = 0;\n\n for (const file of files) {\n const fileContent = await readFile(file.repoPath, 'utf-8');\n\n if (isShellFile(file.source) && (await pathExists(file.destination))) {\n // Use smart merge for shell files\n const mergeResult = await smartMerge(file.destination, fileContent);\n\n if (dryRun) {\n logger.file('merge', `${collapsePath(file.destination)} (${mergeResult.preservedBlocks} blocks preserved)`);\n } else {\n const { writeFile } = await import('fs/promises');\n const { ensureDir } = await import('fs-extra');\n const { dirname } = await import('path');\n\n await ensureDir(dirname(file.destination));\n await writeFile(file.destination, mergeResult.content, 'utf-8');\n logger.file('merge', collapsePath(file.destination));\n }\n } else {\n // Copy non-shell files directly\n if (dryRun) {\n if (await pathExists(file.destination)) {\n logger.file('modify', collapsePath(file.destination));\n } else {\n logger.file('add', collapsePath(file.destination));\n }\n } else {\n const fileExists = await pathExists(file.destination);\n await copyFileOrDir(file.repoPath, file.destination, { overwrite: true });\n await fixSecurePermissions(file.destination);\n logger.file(\n fileExists ? 'modify' : 'add',\n collapsePath(file.destination)\n );\n }\n }\n\n appliedCount++;\n }\n\n return appliedCount;\n};\n\n/**\n * Apply files with replace strategy\n */\nconst applyWithReplace = async (files: ApplyFile[], dryRun: boolean): Promise<number> => {\n let appliedCount = 0;\n\n for (const file of files) {\n if (dryRun) {\n if (await pathExists(file.destination)) {\n logger.file('modify', `${collapsePath(file.destination)} (replace)`);\n } else {\n logger.file('add', collapsePath(file.destination));\n }\n } else {\n const fileExists = await pathExists(file.destination);\n await copyFileOrDir(file.repoPath, file.destination, { overwrite: true });\n await fixSecurePermissions(file.destination);\n logger.file(\n fileExists ? 'modify' : 'add',\n collapsePath(file.destination)\n );\n }\n\n appliedCount++;\n }\n\n return appliedCount;\n};\n\n/**\n * Run interactive apply flow\n */\nconst runInteractiveApply = async (source: string, options: ApplyOptions): Promise<void> => {\n banner();\n prompts.intro('tuck apply');\n\n // Resolve the source\n let repoId: string;\n let isUrl: boolean;\n\n try {\n const resolved = await resolveSource(source);\n repoId = resolved.repoId;\n isUrl = resolved.isUrl;\n } catch (error) {\n prompts.log.error(error instanceof Error ? error.message : String(error));\n return;\n }\n\n // Clone the repository\n let repoDir: string;\n try {\n const spinner = prompts.spinner();\n spinner.start('Cloning repository...');\n repoDir = await cloneSource(repoId, isUrl);\n spinner.stop('Repository cloned');\n } catch (error) {\n prompts.log.error(`Failed to clone: ${error instanceof Error ? error.message : String(error)}`);\n return;\n }\n\n try {\n // Read the manifest\n const manifest = await readClonedManifest(repoDir);\n\n if (!manifest) {\n prompts.log.error('No tuck manifest found in repository');\n prompts.note(\n 'This repository may not be managed by tuck.\\nLook for a .tuckmanifest.json file.',\n 'Tip'\n );\n return;\n }\n\n // Prepare files to apply\n const files = await prepareFilesToApply(repoDir, manifest);\n\n if (files.length === 0) {\n prompts.log.warning('No files to apply');\n return;\n }\n\n // Show what will be applied\n prompts.log.info(`Found ${files.length} file(s) to apply:`);\n console.log();\n\n // Group by category\n const byCategory: Record<string, ApplyFile[]> = {};\n for (const file of files) {\n if (!byCategory[file.category]) {\n byCategory[file.category] = [];\n }\n byCategory[file.category].push(file);\n }\n\n for (const [category, categoryFiles] of Object.entries(byCategory)) {\n const categoryConfig = CATEGORIES[category] || { icon: '📄' };\n console.log(chalk.bold(` ${categoryConfig.icon} ${category}`));\n for (const file of categoryFiles) {\n const exists = await pathExists(file.destination);\n const status = exists ? chalk.yellow('(will update)') : chalk.green('(new)');\n console.log(chalk.dim(` ${collapsePath(file.destination)} ${status}`));\n }\n }\n console.log();\n\n // Ask for merge strategy\n let strategy: 'merge' | 'replace';\n\n if (options.merge) {\n strategy = 'merge';\n } else if (options.replace) {\n strategy = 'replace';\n } else {\n strategy = await prompts.select('How should conflicts be handled?', [\n {\n value: 'merge',\n label: 'Merge (recommended)',\n hint: 'Preserve local customizations marked with # local or # tuck:preserve',\n },\n {\n value: 'replace',\n label: 'Replace',\n hint: 'Overwrite all files completely',\n },\n ]);\n }\n\n // Show merge preview for shell files if using merge strategy\n if (strategy === 'merge') {\n const shellFiles = files.filter((f) => isShellFile(f.source));\n if (shellFiles.length > 0) {\n console.log();\n for (const file of shellFiles.slice(0, 3)) {\n if (await pathExists(file.destination)) {\n const fileContent = await readFile(file.repoPath, 'utf-8');\n const preview = await generateMergePreview(file.destination, fileContent);\n prompts.note(preview, collapsePath(file.destination));\n }\n }\n if (shellFiles.length > 3) {\n prompts.log.info(`... and ${shellFiles.length - 3} more shell files`);\n }\n }\n }\n\n // Confirm\n if (!options.yes && !options.force) {\n console.log();\n const confirmed = await prompts.confirm(\n `Apply ${files.length} files using ${strategy} strategy?`,\n true\n );\n\n if (!confirmed) {\n prompts.cancel('Apply cancelled');\n return;\n }\n }\n\n // Create Time Machine backup before applying\n // Note: We need to properly await async checks - Array.filter doesn't await promises\n const existingPaths = [];\n for (const file of files) {\n if (await pathExists(file.destination)) {\n existingPaths.push(file.destination);\n }\n }\n\n if (existingPaths.length > 0 && !options.dryRun) {\n const spinner = prompts.spinner();\n spinner.start('Creating backup snapshot...');\n const snapshot = await createPreApplySnapshot(existingPaths, repoId);\n spinner.stop(`Backup created: ${snapshot.id}`);\n console.log();\n }\n\n // Apply files\n if (options.dryRun) {\n prompts.log.info('Dry run - no changes will be made:');\n } else {\n prompts.log.info('Applying files...');\n }\n console.log();\n\n let appliedCount: number;\n if (strategy === 'merge') {\n appliedCount = await applyWithMerge(files, options.dryRun || false);\n } else {\n appliedCount = await applyWithReplace(files, options.dryRun || false);\n }\n\n console.log();\n\n if (options.dryRun) {\n prompts.log.info(`Would apply ${appliedCount} files`);\n } else {\n prompts.log.success(`Applied ${appliedCount} files`);\n console.log();\n prompts.note(\n 'To undo this apply, run:\\n tuck restore --latest\\n\\nTo see all backups:\\n tuck restore --list',\n 'Undo'\n );\n }\n\n prompts.outro('Done!');\n } finally {\n // Clean up temp directory\n try {\n await rm(repoDir, { recursive: true, force: true });\n } catch {\n // Ignore cleanup errors\n }\n }\n};\n\n/**\n * Run non-interactive apply\n */\nconst runApply = async (source: string, options: ApplyOptions): Promise<void> => {\n // Resolve the source\n const { repoId, isUrl } = await resolveSource(source);\n\n // Clone the repository\n logger.info('Cloning repository...');\n const repoDir = await cloneSource(repoId, isUrl);\n\n try {\n // Read the manifest\n const manifest = await readClonedManifest(repoDir);\n\n if (!manifest) {\n throw new Error('No tuck manifest found in repository');\n }\n\n // Prepare files to apply\n const files = await prepareFilesToApply(repoDir, manifest);\n\n if (files.length === 0) {\n logger.warning('No files to apply');\n return;\n }\n\n // Determine strategy\n const strategy = options.replace ? 'replace' : 'merge';\n\n // Create backup if not dry run\n if (!options.dryRun) {\n const existingPaths = [];\n for (const file of files) {\n if (await pathExists(file.destination)) {\n existingPaths.push(file.destination);\n }\n }\n\n if (existingPaths.length > 0) {\n logger.info('Creating backup snapshot...');\n const snapshot = await createPreApplySnapshot(existingPaths, repoId);\n logger.success(`Backup created: ${snapshot.id}`);\n }\n }\n\n // Apply files\n if (options.dryRun) {\n logger.heading('Dry run - would apply:');\n } else {\n logger.heading('Applying:');\n }\n\n let appliedCount: number;\n if (strategy === 'merge') {\n appliedCount = await applyWithMerge(files, options.dryRun || false);\n } else {\n appliedCount = await applyWithReplace(files, options.dryRun || false);\n }\n\n logger.blank();\n\n if (options.dryRun) {\n logger.info(`Would apply ${appliedCount} files`);\n } else {\n logger.success(`Applied ${appliedCount} files`);\n logger.info('To undo: tuck restore --latest');\n }\n } finally {\n // Clean up temp directory\n try {\n await rm(repoDir, { recursive: true, force: true });\n } catch {\n // Ignore cleanup errors\n }\n }\n};\n\nexport const applyCommand = new Command('apply')\n .description('Apply dotfiles from a repository to this machine')\n .argument('<source>', 'GitHub username, user/repo, or full repository URL')\n .option('-m, --merge', 'Merge with existing files (preserve local customizations)')\n .option('-r, --replace', 'Replace existing files completely')\n .option('--dry-run', 'Show what would be applied without making changes')\n .option('-f, --force', 'Apply without confirmation prompts')\n .option('-y, --yes', 'Assume yes to all prompts')\n .action(async (source: string, options: ApplyOptions) => {\n // Determine if we should run interactive mode\n const isInteractive = !options.force && !options.yes && process.stdout.isTTY;\n\n if (isInteractive) {\n await runInteractiveApply(source, options);\n } else {\n await runApply(source, options);\n }\n });\n","import { join, dirname } from 'path';\nimport { readdir, readFile, writeFile, rm, stat } from 'fs/promises';\nimport { copy, ensureDir, pathExists } from 'fs-extra';\nimport { homedir } from 'os';\nimport { expandPath, collapsePath, pathExists as checkPathExists } from './paths.js';\nimport { BackupError } from '../errors.js';\n\nconst TIMEMACHINE_DIR = join(homedir(), '.tuck', 'backups');\n\nexport interface SnapshotMetadata {\n id: string;\n timestamp: string;\n reason: string;\n files: SnapshotFile[];\n machine: string;\n profile?: string;\n}\n\nexport interface SnapshotFile {\n originalPath: string;\n backupPath: string;\n existed: boolean;\n}\n\nexport interface Snapshot {\n id: string;\n path: string;\n timestamp: Date;\n reason: string;\n files: SnapshotFile[];\n machine: string;\n profile?: string;\n}\n\n/**\n * Generate a unique snapshot ID (YYYY-MM-DD-HHMMSS)\n */\nconst generateSnapshotId = (): string => {\n const now = new Date();\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, '0');\n const day = String(now.getDate()).padStart(2, '0');\n const hours = String(now.getHours()).padStart(2, '0');\n const minutes = String(now.getMinutes()).padStart(2, '0');\n const seconds = String(now.getSeconds()).padStart(2, '0');\n return `${year}-${month}-${day}-${hours}${minutes}${seconds}`;\n};\n\n/**\n * Get the path to a snapshot directory\n */\nconst getSnapshotPath = (snapshotId: string): string => {\n return join(TIMEMACHINE_DIR, snapshotId);\n};\n\n/**\n * Convert original path to a safe backup path, preserving directory structure\n * to prevent filename collisions. The path is relative to the backup files directory.\n * e.g., ~/.zshrc -> .zshrc\n * e.g., ~/.config/nvim -> .config/nvim\n * e.g., ~/.foo.bar -> .foo.bar (distinct from ~/.foo-bar -> .foo-bar)\n */\nconst toBackupPath = (originalPath: string): string => {\n const collapsed = collapsePath(originalPath);\n // Remove ~/ prefix to get a path relative to home directory\n // This preserves the full directory structure, preventing collisions\n return collapsed.replace(/^~\\//, '');\n};\n\n/**\n * Create a Time Machine snapshot of multiple files\n * This is the main entry point for creating backups before apply operations\n */\nexport const createSnapshot = async (\n filePaths: string[],\n reason: string,\n profile?: string\n): Promise<Snapshot> => {\n const snapshotId = generateSnapshotId();\n const snapshotPath = getSnapshotPath(snapshotId);\n\n await ensureDir(snapshotPath);\n\n const files: SnapshotFile[] = [];\n const machine = (await import('os')).hostname();\n\n for (const filePath of filePaths) {\n const expandedPath = expandPath(filePath);\n const backupRelativePath = toBackupPath(expandedPath);\n const backupPath = join(snapshotPath, 'files', backupRelativePath);\n\n const existed = await checkPathExists(expandedPath);\n\n if (existed) {\n await ensureDir(dirname(backupPath));\n await copy(expandedPath, backupPath, { overwrite: true, preserveTimestamps: true });\n }\n\n files.push({\n originalPath: expandedPath,\n backupPath,\n existed,\n });\n }\n\n // Save metadata\n const metadata: SnapshotMetadata = {\n id: snapshotId,\n timestamp: new Date().toISOString(),\n reason,\n files,\n machine,\n profile,\n };\n\n await writeFile(\n join(snapshotPath, 'metadata.json'),\n JSON.stringify(metadata, null, 2),\n 'utf-8'\n );\n\n return {\n id: snapshotId,\n path: snapshotPath,\n timestamp: new Date(metadata.timestamp),\n reason,\n files,\n machine,\n profile,\n };\n};\n\n/**\n * Create a snapshot of the user's current dotfiles before applying new ones\n */\nexport const createPreApplySnapshot = async (\n targetPaths: string[],\n sourceRepo?: string\n): Promise<Snapshot> => {\n const reason = sourceRepo\n ? `Pre-apply backup before applying from ${sourceRepo}`\n : 'Pre-apply backup';\n\n return createSnapshot(targetPaths, reason);\n};\n\n/**\n * List all available snapshots\n */\nexport const listSnapshots = async (): Promise<Snapshot[]> => {\n if (!(await pathExists(TIMEMACHINE_DIR))) {\n return [];\n }\n\n const entries = await readdir(TIMEMACHINE_DIR, { withFileTypes: true });\n const snapshots: Snapshot[] = [];\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n const snapshotPath = join(TIMEMACHINE_DIR, entry.name);\n const metadataPath = join(snapshotPath, 'metadata.json');\n\n if (!(await pathExists(metadataPath))) continue;\n\n try {\n const content = await readFile(metadataPath, 'utf-8');\n const metadata: SnapshotMetadata = JSON.parse(content);\n\n snapshots.push({\n id: metadata.id,\n path: snapshotPath,\n timestamp: new Date(metadata.timestamp),\n reason: metadata.reason,\n files: metadata.files,\n machine: metadata.machine,\n profile: metadata.profile,\n });\n } catch {\n // Skip invalid snapshots\n }\n }\n\n // Sort by timestamp, newest first\n return snapshots.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());\n};\n\n/**\n * Get a specific snapshot by ID\n */\nexport const getSnapshot = async (snapshotId: string): Promise<Snapshot | null> => {\n const snapshotPath = getSnapshotPath(snapshotId);\n\n if (!(await pathExists(snapshotPath))) {\n return null;\n }\n\n const metadataPath = join(snapshotPath, 'metadata.json');\n\n if (!(await pathExists(metadataPath))) {\n return null;\n }\n\n try {\n const content = await readFile(metadataPath, 'utf-8');\n const metadata: SnapshotMetadata = JSON.parse(content);\n\n return {\n id: metadata.id,\n path: snapshotPath,\n timestamp: new Date(metadata.timestamp),\n reason: metadata.reason,\n files: metadata.files,\n machine: metadata.machine,\n profile: metadata.profile,\n };\n } catch {\n return null;\n }\n};\n\n/**\n * Get the latest snapshot\n */\nexport const getLatestSnapshot = async (): Promise<Snapshot | null> => {\n const snapshots = await listSnapshots();\n return snapshots.length > 0 ? snapshots[0] : null;\n};\n\n/**\n * Restore all files from a snapshot\n */\nexport const restoreSnapshot = async (snapshotId: string): Promise<string[]> => {\n const snapshot = await getSnapshot(snapshotId);\n\n if (!snapshot) {\n throw new BackupError(`Snapshot not found: ${snapshotId}`, [\n 'Run `tuck restore --list` to see available snapshots',\n ]);\n }\n\n const restoredFiles: string[] = [];\n\n for (const file of snapshot.files) {\n if (!file.existed) {\n // File didn't exist before, delete it if it exists now\n if (await checkPathExists(file.originalPath)) {\n await rm(file.originalPath, { recursive: true });\n }\n continue;\n }\n\n // Restore the backup\n if (await pathExists(file.backupPath)) {\n await ensureDir(dirname(file.originalPath));\n await copy(file.backupPath, file.originalPath, { overwrite: true, preserveTimestamps: true });\n restoredFiles.push(file.originalPath);\n }\n }\n\n return restoredFiles;\n};\n\n/**\n * Restore a single file from a snapshot\n */\nexport const restoreFileFromSnapshot = async (\n snapshotId: string,\n filePath: string\n): Promise<boolean> => {\n const snapshot = await getSnapshot(snapshotId);\n\n if (!snapshot) {\n throw new BackupError(`Snapshot not found: ${snapshotId}`);\n }\n\n const expandedPath = expandPath(filePath);\n const file = snapshot.files.find((f) => f.originalPath === expandedPath);\n\n if (!file) {\n throw new BackupError(`File not found in snapshot: ${filePath}`, [\n 'This file was not included in the snapshot',\n ]);\n }\n\n if (!file.existed) {\n // File didn't exist before, delete it if it exists now\n if (await checkPathExists(file.originalPath)) {\n await rm(file.originalPath, { recursive: true });\n }\n return true;\n }\n\n if (!(await pathExists(file.backupPath))) {\n throw new BackupError(`Backup file is missing: ${file.backupPath}`);\n }\n\n await ensureDir(dirname(file.originalPath));\n await copy(file.backupPath, file.originalPath, { overwrite: true, preserveTimestamps: true });\n return true;\n};\n\n/**\n * Delete a snapshot\n */\nexport const deleteSnapshot = async (snapshotId: string): Promise<void> => {\n const snapshotPath = getSnapshotPath(snapshotId);\n\n if (await pathExists(snapshotPath)) {\n await rm(snapshotPath, { recursive: true });\n }\n};\n\n/**\n * Clean up old snapshots, keeping only the specified number\n */\nexport const cleanOldSnapshots = async (keepCount: number): Promise<number> => {\n const snapshots = await listSnapshots();\n\n if (snapshots.length <= keepCount) {\n return 0;\n }\n\n const toDelete = snapshots.slice(keepCount);\n let deletedCount = 0;\n\n for (const snapshot of toDelete) {\n await deleteSnapshot(snapshot.id);\n deletedCount++;\n }\n\n return deletedCount;\n};\n\n/**\n * Get the total size of all snapshots in bytes\n */\nexport const getSnapshotsSize = async (): Promise<number> => {\n if (!(await pathExists(TIMEMACHINE_DIR))) {\n return 0;\n }\n\n let totalSize = 0;\n\n const calculateDirSize = async (dirPath: string): Promise<number> => {\n let size = 0;\n const entries = await readdir(dirPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const entryPath = join(dirPath, entry.name);\n if (entry.isDirectory()) {\n size += await calculateDirSize(entryPath);\n } else {\n const stats = await stat(entryPath);\n size += stats.size;\n }\n }\n\n return size;\n };\n\n totalSize = await calculateDirSize(TIMEMACHINE_DIR);\n return totalSize;\n};\n\n/**\n * Format bytes to human readable string\n */\nexport const formatSnapshotSize = (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\n/**\n * Format a snapshot ID to a human-readable date string\n */\nexport const formatSnapshotDate = (snapshotId: string): string => {\n // Parse YYYY-MM-DD-HHMMSS format\n const match = snapshotId.match(/^(\\d{4})-(\\d{2})-(\\d{2})-(\\d{2})(\\d{2})(\\d{2})$/);\n if (!match) return snapshotId;\n\n const [, year, month, day, hours, minutes, seconds] = match;\n const date = new Date(\n parseInt(year),\n parseInt(month) - 1,\n parseInt(day),\n parseInt(hours),\n parseInt(minutes),\n parseInt(seconds)\n );\n\n return date.toLocaleString();\n};\n","import { readFile } from 'fs/promises';\nimport { expandPath, pathExists } from './paths.js';\n\n/**\n * Markers that indicate content should be preserved during merge\n */\nconst PRESERVE_MARKERS = [\n '# local',\n '# LOCAL',\n '# machine-specific',\n '# MACHINE-SPECIFIC',\n '# machine specific',\n '# do not sync',\n '# DO NOT SYNC',\n '# keep',\n '# KEEP',\n '# private',\n '# PRIVATE',\n '# tuck:preserve',\n '# tuck:keep',\n '# tuck:local',\n];\n\n/**\n * Shell file patterns that are known to be shell configuration\n */\nconst SHELL_FILE_PATTERNS = [\n '.zshrc',\n '.bashrc',\n '.bash_profile',\n '.profile',\n '.zprofile',\n '.zshenv',\n '.bash_aliases',\n '.aliases',\n '.functions',\n];\n\nexport interface MergeBlock {\n type: 'preserved' | 'incoming' | 'local';\n content: string;\n marker?: string;\n lineStart: number;\n lineEnd: number;\n}\n\nexport interface MergeResult {\n content: string;\n preservedBlocks: number;\n incomingBlocks: number;\n conflicts: MergeConflict[];\n}\n\nexport interface MergeConflict {\n type: 'duplicate_export' | 'duplicate_alias' | 'duplicate_function';\n name: string;\n localLine: number;\n incomingLine: number;\n}\n\nexport interface ParsedExport {\n name: string;\n value: string;\n line: number;\n fullLine: string;\n}\n\nexport interface ParsedAlias {\n name: string;\n value: string;\n line: number;\n fullLine: string;\n}\n\nexport interface ParsedFunction {\n name: string;\n content: string;\n lineStart: number;\n lineEnd: number;\n}\n\n/**\n * Check if a file is a shell configuration file\n */\nexport const isShellFile = (filePath: string): boolean => {\n const fileName = filePath.split('/').pop() || '';\n return SHELL_FILE_PATTERNS.some(\n (pattern) => fileName === pattern || fileName.endsWith(pattern)\n );\n};\n\n/**\n * Parse export statements from shell content\n * Handles: export FOO=bar, export FOO=\"bar\", FOO=bar\n */\nexport const parseExports = (content: string): ParsedExport[] => {\n const exports: ParsedExport[] = [];\n const lines = content.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n\n // Skip comments and empty lines\n if (line.startsWith('#') || !line) continue;\n\n // Match export statements\n const exportMatch = line.match(/^(?:export\\s+)?([A-Za-z_][A-Za-z0-9_]*)=(.*)$/);\n if (exportMatch) {\n exports.push({\n name: exportMatch[1],\n value: exportMatch[2],\n line: i + 1,\n fullLine: lines[i],\n });\n }\n }\n\n return exports;\n};\n\n/**\n * Parse alias definitions from shell content\n * Handles: alias foo='bar', alias foo=\"bar\"\n */\nexport const parseAliases = (content: string): ParsedAlias[] => {\n const aliases: ParsedAlias[] = [];\n const lines = content.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n\n // Skip comments and empty lines\n if (line.startsWith('#') || !line) continue;\n\n // Match alias statements\n const aliasMatch = line.match(/^alias\\s+([a-zA-Z_][a-zA-Z0-9_-]*)=(['\"]?)(.+?)\\2\\s*$/);\n if (aliasMatch) {\n aliases.push({\n name: aliasMatch[1],\n value: aliasMatch[3],\n line: i + 1,\n fullLine: lines[i],\n });\n }\n }\n\n return aliases;\n};\n\n/**\n * Find blocks that should be preserved during merge\n * A preserved block starts with a preserve marker and ends at:\n * - The next non-indented non-comment line\n * - The end of file\n * - Another preserve marker\n */\nexport const findPreservedBlocks = (content: string): MergeBlock[] => {\n const blocks: MergeBlock[] = [];\n const lines = content.split('\\n');\n let currentBlock: MergeBlock | null = null;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmedLine = line.trim();\n\n // Check if this line has a preserve marker\n const marker = PRESERVE_MARKERS.find((m) => trimmedLine.includes(m));\n\n if (marker) {\n // Save previous block if exists\n if (currentBlock) {\n currentBlock.lineEnd = i;\n currentBlock.content = lines.slice(currentBlock.lineStart - 1, i).join('\\n');\n blocks.push(currentBlock);\n }\n\n // Start new preserved block\n currentBlock = {\n type: 'preserved',\n content: '',\n marker,\n lineStart: i + 1,\n lineEnd: i + 1,\n };\n } else if (currentBlock) {\n // Check if we should end the current block\n // End if: empty line followed by non-indented content, or end of file\n const isEndOfBlock =\n (trimmedLine === '' && i + 1 < lines.length && !lines[i + 1].startsWith(' ') && !lines[i + 1].startsWith('\\t') && lines[i + 1].trim() !== '' && !lines[i + 1].trim().startsWith('#')) ||\n i === lines.length - 1;\n\n if (isEndOfBlock) {\n currentBlock.lineEnd = i + 1;\n currentBlock.content = lines.slice(currentBlock.lineStart - 1, i + 1).join('\\n');\n blocks.push(currentBlock);\n currentBlock = null;\n }\n }\n }\n\n // Handle block that extends to end of file\n if (currentBlock) {\n currentBlock.lineEnd = lines.length;\n currentBlock.content = lines.slice(currentBlock.lineStart - 1).join('\\n');\n blocks.push(currentBlock);\n }\n\n return blocks;\n};\n\n/**\n * Extract PATH modifications from content\n */\nexport const extractPathModifications = (content: string): string[] => {\n const paths: string[] = [];\n const lines = content.split('\\n');\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed.startsWith('#')) continue;\n\n // Match PATH exports\n if (trimmed.includes('PATH') && (trimmed.includes('export') || trimmed.includes('='))) {\n paths.push(line);\n }\n }\n\n return paths;\n};\n\n/**\n * Smart merge of shell configuration files\n * Preserves local customizations while applying incoming changes\n */\nexport const smartMerge = async (\n localPath: string,\n incomingContent: string\n): Promise<MergeResult> => {\n const expandedPath = expandPath(localPath);\n\n // If local file doesn't exist, just return incoming content\n if (!(await pathExists(expandedPath))) {\n return {\n content: incomingContent,\n preservedBlocks: 0,\n incomingBlocks: 1,\n conflicts: [],\n };\n }\n\n const localContent = await readFile(expandedPath, 'utf-8');\n\n // Find blocks to preserve from local content\n const preservedBlocks = findPreservedBlocks(localContent);\n\n // Parse exports and aliases from both files\n const localExports = parseExports(localContent);\n const incomingExports = parseExports(incomingContent);\n const localAliases = parseAliases(localContent);\n const incomingAliases = parseAliases(incomingContent);\n\n // Find conflicts\n const conflicts: MergeConflict[] = [];\n\n // Check for duplicate exports\n for (const local of localExports) {\n const duplicate = incomingExports.find((e) => e.name === local.name);\n if (duplicate && local.value !== duplicate.value) {\n conflicts.push({\n type: 'duplicate_export',\n name: local.name,\n localLine: local.line,\n incomingLine: duplicate.line,\n });\n }\n }\n\n // Check for duplicate aliases\n for (const local of localAliases) {\n const duplicate = incomingAliases.find((a) => a.name === local.name);\n if (duplicate && local.value !== duplicate.value) {\n conflicts.push({\n type: 'duplicate_alias',\n name: local.name,\n localLine: local.line,\n incomingLine: duplicate.line,\n });\n }\n }\n\n // Build merged content\n let mergedContent = incomingContent;\n\n // Append preserved blocks at the end\n if (preservedBlocks.length > 0) {\n mergedContent += '\\n\\n';\n mergedContent += '# ============================================\\n';\n mergedContent += '# LOCAL CUSTOMIZATIONS (preserved by tuck)\\n';\n mergedContent += '# ============================================\\n\\n';\n\n for (const block of preservedBlocks) {\n mergedContent += block.content + '\\n\\n';\n }\n }\n\n return {\n content: mergedContent.trim() + '\\n',\n preservedBlocks: preservedBlocks.length,\n incomingBlocks: 1,\n conflicts,\n };\n};\n\n/**\n * Generate a diff-like preview of what will change\n */\nexport const generateMergePreview = async (\n localPath: string,\n incomingContent: string\n): Promise<string> => {\n const expandedPath = expandPath(localPath);\n\n if (!(await pathExists(expandedPath))) {\n return `New file will be created:\\n${incomingContent.slice(0, 500)}${incomingContent.length > 500 ? '...' : ''}`;\n }\n\n const localContent = await readFile(expandedPath, 'utf-8');\n const preservedBlocks = findPreservedBlocks(localContent);\n const localExports = parseExports(localContent);\n const incomingExports = parseExports(incomingContent);\n\n const lines: string[] = [];\n\n lines.push('=== Merge Preview ===');\n lines.push('');\n\n // Show preserved blocks\n if (preservedBlocks.length > 0) {\n lines.push(`📌 ${preservedBlocks.length} block(s) will be preserved:`);\n for (const block of preservedBlocks) {\n lines.push(` - Lines ${block.lineStart}-${block.lineEnd} (${block.marker})`);\n }\n lines.push('');\n }\n\n // Show export changes\n const newExports = incomingExports.filter(\n (e) => !localExports.find((l) => l.name === e.name)\n );\n const changedExports = incomingExports.filter((e) => {\n const local = localExports.find((l) => l.name === e.name);\n return local && local.value !== e.value;\n });\n\n if (newExports.length > 0) {\n lines.push(`➕ ${newExports.length} new export(s):`);\n for (const exp of newExports.slice(0, 5)) {\n lines.push(` + ${exp.name}=${exp.value.slice(0, 50)}`);\n }\n if (newExports.length > 5) {\n lines.push(` ... and ${newExports.length - 5} more`);\n }\n lines.push('');\n }\n\n if (changedExports.length > 0) {\n lines.push(`🔄 ${changedExports.length} export(s) will be updated:`);\n for (const exp of changedExports.slice(0, 5)) {\n const local = localExports.find((l) => l.name === exp.name);\n lines.push(` ~ ${exp.name}: \"${local?.value.slice(0, 20)}...\" → \"${exp.value.slice(0, 20)}...\"`);\n }\n if (changedExports.length > 5) {\n lines.push(` ... and ${changedExports.length - 5} more`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n};\n\n/**\n * Check if content has any preserve markers\n */\nexport const hasPreserveMarkers = (content: string): boolean => {\n return PRESERVE_MARKERS.some((marker) => content.includes(marker));\n};\n\n/**\n * Add a preserve marker to content\n */\nexport const addPreserveMarker = (content: string, marker = '# tuck:preserve'): string => {\n return `${marker}\\n${content}`;\n};\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { prompts, logger } from '../ui/index.js';\nimport { collapsePath } from '../lib/paths.js';\nimport {\n listSnapshots,\n getSnapshot,\n getLatestSnapshot,\n restoreSnapshot,\n restoreFileFromSnapshot,\n deleteSnapshot,\n getSnapshotsSize,\n formatSnapshotSize,\n formatSnapshotDate,\n Snapshot,\n} from '../lib/timemachine.js';\n\nexport interface UndoOptions {\n list?: boolean;\n latest?: boolean;\n file?: string;\n delete?: string;\n force?: boolean;\n dryRun?: boolean;\n}\n\n/**\n * Display a list of available snapshots\n */\nconst showSnapshotList = async (): Promise<void> => {\n const snapshots = await listSnapshots();\n\n if (snapshots.length === 0) {\n logger.warning('No backup snapshots found');\n logger.dim('Snapshots are created automatically when using `tuck apply`');\n return;\n }\n\n logger.heading('Backup Snapshots:');\n logger.blank();\n\n for (const snapshot of snapshots) {\n const date = formatSnapshotDate(snapshot.id);\n const fileCount = snapshot.files.filter((f) => f.existed).length;\n\n console.log(chalk.cyan(` ${snapshot.id}`));\n console.log(chalk.dim(` Date: ${date}`));\n console.log(chalk.dim(` Reason: ${snapshot.reason}`));\n console.log(chalk.dim(` Files: ${fileCount} file(s) backed up`));\n console.log(chalk.dim(` Machine: ${snapshot.machine}`));\n console.log();\n }\n\n const totalSize = await getSnapshotsSize();\n logger.dim(`Total backup size: ${formatSnapshotSize(totalSize)}`);\n logger.blank();\n logger.info('To restore a snapshot: tuck undo <snapshot-id>');\n logger.info('To restore the latest: tuck undo --latest');\n};\n\n/**\n * Display details of a specific snapshot\n */\nconst showSnapshotDetails = (snapshot: Snapshot): void => {\n console.log();\n console.log(chalk.bold('Snapshot Details:'));\n console.log(chalk.dim(` ID: ${snapshot.id}`));\n console.log(chalk.dim(` Date: ${formatSnapshotDate(snapshot.id)}`));\n console.log(chalk.dim(` Reason: ${snapshot.reason}`));\n console.log(chalk.dim(` Machine: ${snapshot.machine}`));\n console.log();\n console.log(chalk.bold('Files in snapshot:'));\n\n for (const file of snapshot.files) {\n if (file.existed) {\n console.log(chalk.dim(` ok ${collapsePath(file.originalPath)}`));\n } else {\n console.log(chalk.dim(` - ${collapsePath(file.originalPath)} (did not exist)`));\n }\n }\n console.log();\n};\n\n/**\n * Restore from a specific snapshot\n */\nconst restoreFromSnapshot = async (\n snapshotId: string,\n options: UndoOptions\n): Promise<void> => {\n const snapshot = await getSnapshot(snapshotId);\n\n if (!snapshot) {\n logger.error(`Snapshot not found: ${snapshotId}`);\n const snapshots = await listSnapshots();\n if (snapshots.length > 0) {\n logger.info('Available snapshots:');\n for (const s of snapshots.slice(0, 5)) {\n logger.dim(` ${s.id} - ${formatSnapshotDate(s.id)}`);\n }\n if (snapshots.length > 5) {\n logger.dim(` ... and ${snapshots.length - 5} more`);\n }\n }\n return;\n }\n\n // Show snapshot details\n showSnapshotDetails(snapshot);\n\n // Confirm unless --force or dry-run\n if (!options.force && !options.dryRun) {\n const backedUpCount = snapshot.files.filter((f) => f.existed).length;\n const confirmed = await prompts.confirm(\n `Restore ${backedUpCount} file(s) from this snapshot?`,\n true\n );\n\n if (!confirmed) {\n logger.info('Restore cancelled');\n return;\n }\n }\n\n // Dry run\n if (options.dryRun) {\n logger.heading('Dry run - would restore:');\n for (const file of snapshot.files) {\n if (file.existed) {\n logger.file('modify', collapsePath(file.originalPath));\n } else {\n logger.file('delete', `${collapsePath(file.originalPath)} (would remove)`);\n }\n }\n return;\n }\n\n // Restore\n logger.info('Restoring files...');\n const restoredFiles = await restoreSnapshot(snapshotId);\n\n logger.blank();\n logger.success(`Restored ${restoredFiles.length} file(s)`);\n\n for (const file of restoredFiles) {\n logger.dim(` ok ${collapsePath(file)}`);\n }\n};\n\n/**\n * Restore a single file from a snapshot\n */\nconst restoreSingleFile = async (\n snapshotId: string,\n filePath: string,\n options: UndoOptions\n): Promise<void> => {\n const snapshot = await getSnapshot(snapshotId);\n\n if (!snapshot) {\n logger.error(`Snapshot not found: ${snapshotId}`);\n return;\n }\n\n // Dry run\n if (options.dryRun) {\n logger.info(`Would restore ${filePath} from snapshot ${snapshotId}`);\n return;\n }\n\n // Restore the file\n await restoreFileFromSnapshot(snapshotId, filePath);\n logger.success(`Restored ${filePath}`);\n};\n\n/**\n * Delete a snapshot\n */\nconst removeSnapshot = async (snapshotId: string, options: UndoOptions): Promise<void> => {\n const snapshot = await getSnapshot(snapshotId);\n\n if (!snapshot) {\n logger.error(`Snapshot not found: ${snapshotId}`);\n return;\n }\n\n // Confirm unless --force\n if (!options.force) {\n showSnapshotDetails(snapshot);\n const confirmed = await prompts.confirm('Delete this snapshot permanently?', false);\n\n if (!confirmed) {\n logger.info('Deletion cancelled');\n return;\n }\n }\n\n await deleteSnapshot(snapshotId);\n logger.success(`Deleted snapshot: ${snapshotId}`);\n};\n\n/**\n * Interactive undo selection\n */\nconst runInteractiveUndo = async (): Promise<void> => {\n prompts.intro('tuck undo');\n\n const snapshots = await listSnapshots();\n\n if (snapshots.length === 0) {\n prompts.log.warning('No backup snapshots available');\n prompts.note('Snapshots are created when using `tuck apply`', 'Info');\n return;\n }\n\n // Let user select a snapshot\n const snapshotOptions = snapshots.map((s) => ({\n value: s.id,\n label: `${s.id} - ${s.reason.slice(0, 40)}${s.reason.length > 40 ? '...' : ''}`,\n hint: `${s.files.filter((f) => f.existed).length} files`,\n }));\n\n const selectedId = await prompts.select(\n 'Select a snapshot to restore:',\n snapshotOptions\n );\n\n const snapshot = await getSnapshot(selectedId);\n if (!snapshot) {\n prompts.log.error('Snapshot not found');\n return;\n }\n\n // Show what will be restored\n console.log();\n prompts.log.info('Files in this snapshot:');\n for (const file of snapshot.files.slice(0, 10)) {\n if (file.existed) {\n console.log(chalk.dim(` ${collapsePath(file.originalPath)}`));\n }\n }\n if (snapshot.files.length > 10) {\n console.log(chalk.dim(` ... and ${snapshot.files.length - 10} more`));\n }\n console.log();\n\n // Confirm\n const confirmed = await prompts.confirm('Restore these files?', true);\n\n if (!confirmed) {\n prompts.cancel('Restore cancelled');\n return;\n }\n\n // Restore\n const spinner = prompts.spinner();\n spinner.start('Restoring files...');\n\n const restoredFiles = await restoreSnapshot(selectedId);\n\n spinner.stop(`Restored ${restoredFiles.length} files`);\n\n prompts.outro('Done!');\n};\n\n/**\n * Main undo command handler\n */\nconst runUndo = async (snapshotId: string | undefined, options: UndoOptions): Promise<void> => {\n // Handle --list\n if (options.list) {\n await showSnapshotList();\n return;\n }\n\n // Handle --delete\n if (options.delete) {\n await removeSnapshot(options.delete, options);\n return;\n }\n\n // Handle --latest\n if (options.latest) {\n const latest = await getLatestSnapshot();\n if (!latest) {\n logger.warning('No backup snapshots available');\n return;\n }\n await restoreFromSnapshot(latest.id, options);\n return;\n }\n\n // Handle specific snapshot ID\n if (snapshotId) {\n // Check if we're restoring a single file\n if (options.file) {\n await restoreSingleFile(snapshotId, options.file, options);\n } else {\n await restoreFromSnapshot(snapshotId, options);\n }\n return;\n }\n\n // No arguments - run interactive mode\n await runInteractiveUndo();\n};\n\nexport const undoCommand = new Command('undo')\n .description('Restore files from a Time Machine backup snapshot')\n .argument('[snapshot-id]', 'Snapshot ID to restore (format: YYYY-MM-DD-HHMMSS)')\n .option('-l, --list', 'List all available backup snapshots')\n .option('--latest', 'Restore the most recent snapshot')\n .option('--file <path>', 'Restore a single file from the snapshot')\n .option('--delete <id>', 'Delete a specific snapshot')\n .option('-f, --force', 'Skip confirmation prompts')\n .option('--dry-run', 'Show what would be restored without making changes')\n .action(async (snapshotId: string | undefined, options: UndoOptions) => {\n await runUndo(snapshotId, options);\n });\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { prompts, logger, banner } from '../ui/index.js';\nimport { getTuckDir } from '../lib/paths.js';\nimport { loadManifest, getTrackedFileBySource } from '../lib/manifest.js';\nimport {\n detectDotfiles,\n DETECTION_CATEGORIES,\n DetectedFile,\n} from '../lib/detect.js';\nimport { NotInitializedError } from '../errors.js';\n\nexport interface ScanOptions {\n all?: boolean;\n category?: string;\n json?: boolean;\n quick?: boolean;\n}\n\ninterface SelectableFile extends DetectedFile {\n selected: boolean;\n alreadyTracked: boolean;\n}\n\n/**\n * Group selectable files by category\n */\nconst groupSelectableByCategory = (\n files: SelectableFile[]\n): Record<string, SelectableFile[]> => {\n const grouped: Record<string, SelectableFile[]> = {};\n\n for (const file of files) {\n if (!grouped[file.category]) {\n grouped[file.category] = [];\n }\n grouped[file.category].push(file);\n }\n\n return grouped;\n};\n\n/**\n * Display detected files grouped by category\n */\nconst displayGroupedFiles = (\n files: SelectableFile[],\n showAll: boolean\n): void => {\n const grouped = groupSelectableByCategory(files);\n const categories = Object.keys(grouped).sort((a, b) => {\n // Sort by category order in DETECTION_CATEGORIES\n const order = Object.keys(DETECTION_CATEGORIES);\n return order.indexOf(a) - order.indexOf(b);\n });\n\n for (const category of categories) {\n const categoryFiles = grouped[category];\n const config = DETECTION_CATEGORIES[category] || { icon: '-', name: category };\n const newFiles = categoryFiles.filter((f) => !f.alreadyTracked);\n const trackedFiles = categoryFiles.filter((f) => f.alreadyTracked);\n\n console.log();\n console.log(\n chalk.bold(`${config.icon} ${config.name}`) +\n chalk.dim(` (${newFiles.length} new, ${trackedFiles.length} tracked)`)\n );\n console.log(chalk.dim('─'.repeat(50)));\n\n for (const file of categoryFiles) {\n if (!showAll && file.alreadyTracked) continue;\n\n const status = file.selected ? chalk.green('[x]') : chalk.dim('[ ]');\n const name = file.path;\n const tracked = file.alreadyTracked ? chalk.dim(' (tracked)') : '';\n const sensitive = file.sensitive ? chalk.yellow(' [!]') : '';\n const dir = file.isDirectory ? chalk.cyan(' [dir]') : '';\n\n console.log(` ${status} ${name}${dir}${sensitive}${tracked}`);\n console.log(chalk.dim(` ${file.description}`));\n }\n }\n};\n\n/**\n * Interactive file selection\n */\nconst runInteractiveSelection = async (\n files: SelectableFile[]\n): Promise<SelectableFile[]> => {\n const newFiles = files.filter((f) => !f.alreadyTracked);\n\n if (newFiles.length === 0) {\n prompts.log.success('All detected dotfiles are already being tracked!');\n return [];\n }\n\n // Group files for selection\n const grouped = groupSelectableByCategory(newFiles);\n const selectedFiles: SelectableFile[] = [];\n\n // Ask for each category\n for (const [category, categoryFiles] of Object.entries(grouped)) {\n const config = DETECTION_CATEGORIES[category] || { icon: '-', name: category };\n\n console.log();\n console.log(chalk.bold(`${config.icon} ${config.name}`));\n console.log(chalk.dim(config.description || ''));\n console.log();\n\n // Create options for multiselect\n const options = categoryFiles.map((file: SelectableFile) => {\n let label = file.path;\n if (file.sensitive) {\n label += chalk.yellow(' [!]');\n }\n if (file.isDirectory) {\n label += chalk.cyan(' [dir]');\n }\n\n return {\n value: file.path,\n label,\n hint: file.description,\n };\n });\n\n // All selected by default\n const selected = await prompts.multiselect(\n `Select files to track from ${config.name}:`,\n options.map((opt: { value: string; label: string; hint: string }) => ({ ...opt, selected: true }))\n );\n\n // Mark selected files\n for (const file of categoryFiles) {\n if (selected.includes(file.path)) {\n file.selected = true;\n selectedFiles.push(file);\n }\n }\n }\n\n return selectedFiles;\n};\n\n/**\n * Quick display mode - just show what's detected\n */\nconst runQuickScan = async (files: SelectableFile[]): Promise<void> => {\n const newFiles = files.filter((f) => !f.alreadyTracked);\n const trackedFiles = files.filter((f) => f.alreadyTracked);\n\n console.log();\n console.log(\n chalk.bold.cyan('Detected Dotfiles: ') +\n chalk.white(`${newFiles.length} new, ${trackedFiles.length} already tracked`)\n );\n\n displayGroupedFiles(files, false);\n\n console.log();\n console.log(chalk.dim('─'.repeat(60)));\n console.log();\n\n if (newFiles.length > 0) {\n logger.info(`Found ${newFiles.length} new dotfiles to track`);\n logger.dim('Run `tuck scan` (without --quick) to interactively select files');\n logger.dim('Or run `tuck add <path>` to add specific files');\n } else {\n logger.success('All detected dotfiles are already being tracked!');\n }\n};\n\n/**\n * Summary display after selection\n */\nconst showSummary = (selected: SelectableFile[]): void => {\n if (selected.length === 0) {\n logger.info('No files selected');\n return;\n }\n\n console.log();\n console.log(chalk.bold.green(`Selected ${selected.length} files to track:`));\n console.log();\n\n const grouped = groupSelectableByCategory(selected);\n\n for (const [category, files] of Object.entries(grouped)) {\n const config = DETECTION_CATEGORIES[category] || { icon: '-', name: category };\n console.log(chalk.bold(`${config.icon} ${config.name}`));\n\n for (const file of files) {\n const sensitive = file.sensitive ? chalk.yellow(' [!]') : '';\n console.log(chalk.dim(` • ${file.path}${sensitive}`));\n }\n }\n\n console.log();\n\n // Show warnings for sensitive files\n const sensitiveFiles = selected.filter((f) => f.sensitive);\n if (sensitiveFiles.length > 0) {\n console.log(chalk.yellow('Warning: Some selected files may contain sensitive data:'));\n for (const file of sensitiveFiles) {\n console.log(chalk.yellow(` • ${file.path}`));\n }\n console.log(chalk.dim(' Make sure your repository is private!'));\n console.log();\n }\n\n // Show command to add files\n const paths = selected.map((f) => f.path).join(' ');\n console.log(chalk.bold('Run this command to add the selected files:'));\n console.log();\n console.log(chalk.cyan(` tuck add ${paths}`));\n console.log();\n};\n\n/**\n * Main scan function\n */\nconst runScan = async (options: ScanOptions): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Check if tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n // Detect dotfiles\n const spinner = prompts.spinner();\n spinner.start('Scanning for dotfiles...');\n\n const detected = await detectDotfiles();\n\n spinner.stop(`Found ${detected.length} dotfiles on this system`);\n\n if (detected.length === 0) {\n logger.warning('No common dotfiles detected on this system');\n return;\n }\n\n // Check which files are already tracked\n const selectableFiles: SelectableFile[] = [];\n\n for (const file of detected) {\n const tracked = await getTrackedFileBySource(tuckDir, file.path);\n\n selectableFiles.push({\n ...file,\n selected: true, // All selected by default\n alreadyTracked: tracked !== null,\n });\n }\n\n // Filter by category if specified\n let filesToShow = selectableFiles;\n if (options.category) {\n filesToShow = selectableFiles.filter((f) => f.category === options.category);\n if (filesToShow.length === 0) {\n logger.warning(`No dotfiles found in category: ${options.category}`);\n logger.info('Available categories:');\n for (const [key, config] of Object.entries(DETECTION_CATEGORIES)) {\n console.log(chalk.dim(` ${config.icon} ${key} - ${config.name}`));\n }\n return;\n }\n }\n\n // JSON output\n if (options.json) {\n console.log(JSON.stringify(filesToShow, null, 2));\n return;\n }\n\n // Quick mode - just display\n if (options.quick) {\n await runQuickScan(filesToShow);\n return;\n }\n\n // Interactive mode\n banner();\n prompts.intro('tuck scan');\n\n const newFiles = filesToShow.filter((f) => !f.alreadyTracked);\n const trackedCount = filesToShow.filter((f) => f.alreadyTracked).length;\n\n prompts.log.info(\n `Found ${filesToShow.length} dotfiles (${newFiles.length} new, ${trackedCount} tracked)`\n );\n\n if (newFiles.length === 0) {\n prompts.log.success('All detected dotfiles are already being tracked!');\n prompts.outro('Nothing to do');\n return;\n }\n\n // Ask how to proceed\n const action = await prompts.select('How would you like to proceed?', [\n {\n value: 'all',\n label: 'Track all new files',\n hint: `Add all ${newFiles.length} files`,\n },\n {\n value: 'select',\n label: 'Select files to track',\n hint: 'Choose which files to add',\n },\n {\n value: 'preview',\n label: 'Just show me what was found',\n hint: 'Display files without tracking',\n },\n ]);\n\n if (action === 'preview') {\n displayGroupedFiles(filesToShow, options.all || false);\n prompts.outro('Run `tuck scan` again to select files');\n return;\n }\n\n let selected: SelectableFile[];\n\n if (action === 'all') {\n selected = newFiles.map((f) => ({ ...f, selected: true }));\n } else {\n selected = await runInteractiveSelection(filesToShow);\n }\n\n if (selected.length === 0) {\n prompts.cancel('No files selected');\n return;\n }\n\n // Confirm selection\n showSummary(selected);\n\n const confirmed = await prompts.confirm(\n `Add ${selected.length} files to tuck?`,\n true\n );\n\n if (!confirmed) {\n prompts.cancel('Operation cancelled');\n return;\n }\n\n // Add the files\n const { addFilesFromPaths } = await import('./add.js');\n const paths = selected.map((f) => f.path);\n\n await addFilesFromPaths(paths, {});\n\n prompts.outro(`Added ${selected.length} files to tuck!`);\n};\n\nexport const scanCommand = new Command('scan')\n .description('Scan system for dotfiles and select which to track')\n .option('-a, --all', 'Show all files including already tracked ones')\n .option('-c, --category <name>', 'Filter by category (shell, git, editors, etc.)')\n .option('-q, --quick', 'Quick scan - just show detected files without interactive selection')\n .option('--json', 'Output results as JSON')\n .action(async (options: ScanOptions) => {\n await runScan(options);\n });\n","import { join, basename } from 'path';\nimport { readdir, stat } from 'fs/promises';\nimport { platform } from 'os';\nimport { pathExists, expandPath } from './paths.js';\n\nconst IS_MACOS = platform() === 'darwin';\nconst IS_LINUX = platform() === 'linux';\n\nexport interface DetectedFile {\n path: string;\n name: string;\n category: string;\n description: string;\n isDirectory: boolean;\n size?: number;\n sensitive?: boolean;\n exclude?: string[]; // Patterns to exclude within directories\n}\n\nexport interface DetectionCategory {\n name: string;\n icon: string;\n description: string;\n}\n\nexport const DETECTION_CATEGORIES: Record<string, DetectionCategory> = {\n shell: {\n name: 'Shell',\n icon: '$',\n description: 'Shell configs, aliases, functions, and environment',\n },\n git: {\n name: 'Git',\n icon: '*',\n description: 'Git settings, aliases, and global ignores',\n },\n editors: {\n name: 'Editors',\n icon: '>',\n description: 'Editor configurations and settings',\n },\n terminal: {\n name: 'Terminal',\n icon: '#',\n description: 'Terminal emulators and tmux/screen',\n },\n prompt: {\n name: 'Prompt & Theme',\n icon: '~',\n description: 'Shell prompts, themes, and color schemes',\n },\n cli: {\n name: 'CLI Tools',\n icon: '%',\n description: 'Command-line tool configurations',\n },\n languages: {\n name: 'Languages',\n icon: '@',\n description: 'Programming language and package manager configs',\n },\n ssh: {\n name: 'SSH & Security',\n icon: '!',\n description: 'SSH config and GPG settings (no private keys)',\n },\n xdg: {\n name: 'XDG Apps',\n icon: '.',\n description: 'Applications using ~/.config standard',\n },\n desktop: {\n name: 'Desktop & WM',\n icon: '+',\n description: 'Window managers and desktop environment configs',\n },\n scripts: {\n name: 'Scripts',\n icon: '/',\n description: 'Custom scripts and local binaries',\n },\n macos: {\n name: 'macOS',\n icon: '^',\n description: 'macOS-specific configurations',\n },\n misc: {\n name: 'Other',\n icon: '-',\n description: 'Other configuration files',\n },\n};\n\n/**\n * Comprehensive list of dotfiles to detect\n */\nconst DOTFILE_PATTERNS: Array<{\n path: string;\n category: string;\n description: string;\n sensitive?: boolean;\n exclude?: string[];\n platform?: 'darwin' | 'linux' | 'all';\n}> = [\n // ==================== SHELL CONFIGURATION ====================\n // Bash\n { path: '~/.bashrc', category: 'shell', description: 'Bash interactive shell config' },\n { path: '~/.bash_profile', category: 'shell', description: 'Bash login shell config' },\n { path: '~/.bash_aliases', category: 'shell', description: 'Bash aliases' },\n { path: '~/.bash_functions', category: 'shell', description: 'Bash functions' },\n { path: '~/.bash_logout', category: 'shell', description: 'Bash logout script' },\n\n // Zsh\n { path: '~/.zshrc', category: 'shell', description: 'Zsh interactive shell config' },\n { path: '~/.zprofile', category: 'shell', description: 'Zsh login shell config' },\n { path: '~/.zshenv', category: 'shell', description: 'Zsh environment variables' },\n { path: '~/.zlogin', category: 'shell', description: 'Zsh login script' },\n { path: '~/.zlogout', category: 'shell', description: 'Zsh logout script' },\n { path: '~/.zsh', category: 'shell', description: 'Zsh configuration directory' },\n\n // Fish\n { path: '~/.config/fish/config.fish', category: 'shell', description: 'Fish shell config' },\n { path: '~/.config/fish/functions', category: 'shell', description: 'Fish functions' },\n { path: '~/.config/fish/completions', category: 'shell', description: 'Fish completions' },\n { path: '~/.config/fish/conf.d', category: 'shell', description: 'Fish config snippets' },\n\n // Generic shell\n { path: '~/.profile', category: 'shell', description: 'Generic shell profile' },\n { path: '~/.aliases', category: 'shell', description: 'Shell aliases' },\n { path: '~/.functions', category: 'shell', description: 'Shell functions' },\n { path: '~/.exports', category: 'shell', description: 'Environment exports' },\n { path: '~/.inputrc', category: 'shell', description: 'Readline configuration' },\n { path: '~/.hushlogin', category: 'shell', description: 'Suppress login message' },\n\n // ==================== GIT CONFIGURATION ====================\n { path: '~/.gitconfig', category: 'git', description: 'Git global configuration' },\n { path: '~/.gitignore_global', category: 'git', description: 'Global gitignore patterns' },\n { path: '~/.gitignore', category: 'git', description: 'Global gitignore (alt location)' },\n { path: '~/.gitmessage', category: 'git', description: 'Git commit message template' },\n { path: '~/.gitattributes', category: 'git', description: 'Git attributes' },\n { path: '~/.config/git/config', category: 'git', description: 'Git XDG config' },\n { path: '~/.config/git/ignore', category: 'git', description: 'Git XDG ignore' },\n { path: '~/.config/gh', category: 'git', description: 'GitHub CLI config' },\n { path: '~/.config/hub', category: 'git', description: 'Hub CLI config' },\n\n // ==================== EDITORS & IDES ====================\n // Vim/Neovim\n { path: '~/.vimrc', category: 'editors', description: 'Vim configuration' },\n { path: '~/.vim', category: 'editors', description: 'Vim directory', exclude: ['plugged', 'bundle', '.netrwhist'] },\n { path: '~/.config/nvim', category: 'editors', description: 'Neovim configuration' },\n { path: '~/.ideavimrc', category: 'editors', description: 'IdeaVim (JetBrains) config' },\n\n // Emacs\n { path: '~/.emacs', category: 'editors', description: 'Emacs configuration' },\n { path: '~/.emacs.d/init.el', category: 'editors', description: 'Emacs init file' },\n { path: '~/.doom.d', category: 'editors', description: 'Doom Emacs config' },\n { path: '~/.spacemacs', category: 'editors', description: 'Spacemacs config' },\n\n // VS Code\n { path: '~/.config/Code/User/settings.json', category: 'editors', description: 'VS Code settings', platform: 'linux' },\n { path: '~/.config/Code/User/keybindings.json', category: 'editors', description: 'VS Code keybindings', platform: 'linux' },\n { path: '~/.config/Code/User/snippets', category: 'editors', description: 'VS Code snippets', platform: 'linux' },\n { path: '~/Library/Application Support/Code/User/settings.json', category: 'editors', description: 'VS Code settings', platform: 'darwin' },\n { path: '~/Library/Application Support/Code/User/keybindings.json', category: 'editors', description: 'VS Code keybindings', platform: 'darwin' },\n { path: '~/Library/Application Support/Code/User/snippets', category: 'editors', description: 'VS Code snippets', platform: 'darwin' },\n\n // Cursor (VS Code fork)\n { path: '~/.config/Cursor/User/settings.json', category: 'editors', description: 'Cursor settings', platform: 'linux' },\n { path: '~/Library/Application Support/Cursor/User/settings.json', category: 'editors', description: 'Cursor settings', platform: 'darwin' },\n\n // Other editors\n { path: '~/.nanorc', category: 'editors', description: 'Nano configuration' },\n { path: '~/.config/micro', category: 'editors', description: 'Micro editor config' },\n { path: '~/.config/helix', category: 'editors', description: 'Helix editor config' },\n { path: '~/.sublime-text/Packages/User', category: 'editors', description: 'Sublime Text settings' },\n\n // ==================== TERMINAL & MULTIPLEXERS ====================\n // Tmux\n { path: '~/.tmux.conf', category: 'terminal', description: 'Tmux configuration' },\n { path: '~/.tmux', category: 'terminal', description: 'Tmux directory' },\n { path: '~/.config/tmux/tmux.conf', category: 'terminal', description: 'Tmux XDG config' },\n\n // Screen\n { path: '~/.screenrc', category: 'terminal', description: 'GNU Screen configuration' },\n\n // Terminal emulators\n { path: '~/.config/alacritty', category: 'terminal', description: 'Alacritty terminal config' },\n { path: '~/.config/kitty', category: 'terminal', description: 'Kitty terminal config' },\n { path: '~/.config/wezterm', category: 'terminal', description: 'WezTerm config' },\n { path: '~/.wezterm.lua', category: 'terminal', description: 'WezTerm config (alt)' },\n { path: '~/.config/hyper', category: 'terminal', description: 'Hyper terminal config' },\n { path: '~/.hyper.js', category: 'terminal', description: 'Hyper terminal config (alt)' },\n { path: '~/.config/foot', category: 'terminal', description: 'Foot terminal config' },\n { path: '~/.config/terminator', category: 'terminal', description: 'Terminator config' },\n { path: '~/.config/tilix', category: 'terminal', description: 'Tilix terminal config' },\n { path: '~/Library/Preferences/com.googlecode.iterm2.plist', category: 'terminal', description: 'iTerm2 preferences', platform: 'darwin' },\n\n // ==================== PROMPT & THEMES ====================\n { path: '~/.config/starship.toml', category: 'prompt', description: 'Starship prompt config' },\n { path: '~/.p10k.zsh', category: 'prompt', description: 'Powerlevel10k config' },\n { path: '~/.oh-my-zsh/custom', category: 'prompt', description: 'Oh My Zsh customizations' },\n { path: '~/.config/powerline', category: 'prompt', description: 'Powerline config' },\n { path: '~/.dir_colors', category: 'prompt', description: 'Directory colors' },\n { path: '~/.dircolors', category: 'prompt', description: 'Directory colors (alt)' },\n\n // ==================== CLI TOOLS ====================\n // Search & navigation\n { path: '~/.config/ripgrep', category: 'cli', description: 'Ripgrep config' },\n { path: '~/.ripgreprc', category: 'cli', description: 'Ripgrep config (alt)' },\n { path: '~/.rgrc', category: 'cli', description: 'Ripgrep config (short)' },\n { path: '~/.config/fd', category: 'cli', description: 'fd find config' },\n { path: '~/.fdignore', category: 'cli', description: 'fd ignore patterns' },\n { path: '~/.config/bat', category: 'cli', description: 'bat (better cat) config' },\n { path: '~/.config/lsd', category: 'cli', description: 'lsd (better ls) config' },\n { path: '~/.config/exa', category: 'cli', description: 'exa config' },\n { path: '~/.config/eza', category: 'cli', description: 'eza config' },\n\n // Fuzzy finders\n { path: '~/.fzf.zsh', category: 'cli', description: 'fzf Zsh integration' },\n { path: '~/.fzf.bash', category: 'cli', description: 'fzf Bash integration' },\n { path: '~/.config/fzf', category: 'cli', description: 'fzf config directory' },\n\n // Network tools\n { path: '~/.curlrc', category: 'cli', description: 'curl configuration' },\n { path: '~/.wgetrc', category: 'cli', description: 'wget configuration' },\n { path: '~/.netrc', category: 'cli', description: 'Network credentials', sensitive: true },\n { path: '~/.config/aria2', category: 'cli', description: 'aria2 download manager' },\n\n // System monitoring\n { path: '~/.config/htop', category: 'cli', description: 'htop config' },\n { path: '~/.config/btop', category: 'cli', description: 'btop config' },\n { path: '~/.config/bottom', category: 'cli', description: 'bottom config' },\n { path: '~/.config/glances', category: 'cli', description: 'Glances config' },\n\n // Other CLI tools\n { path: '~/.config/lazygit', category: 'cli', description: 'Lazygit config' },\n { path: '~/.config/lazydocker', category: 'cli', description: 'Lazydocker config' },\n { path: '~/.config/ranger', category: 'cli', description: 'Ranger file manager' },\n { path: '~/.config/lf', category: 'cli', description: 'lf file manager' },\n { path: '~/.config/yazi', category: 'cli', description: 'Yazi file manager' },\n { path: '~/.config/nnn', category: 'cli', description: 'nnn file manager' },\n { path: '~/.config/zoxide', category: 'cli', description: 'zoxide (smart cd)' },\n { path: '~/.config/atuin', category: 'cli', description: 'Atuin shell history' },\n { path: '~/.config/thefuck', category: 'cli', description: 'thefuck config' },\n { path: '~/.config/direnv', category: 'cli', description: 'direnv config' },\n { path: '~/.direnvrc', category: 'cli', description: 'direnv config (alt)' },\n { path: '~/.ackrc', category: 'cli', description: 'ack search config' },\n { path: '~/.agignore', category: 'cli', description: 'silver searcher ignore' },\n { path: '~/.editorconfig', category: 'cli', description: 'EditorConfig' },\n\n // ==================== LANGUAGES & PACKAGE MANAGERS ====================\n // Node.js\n { path: '~/.npmrc', category: 'languages', description: 'npm configuration' },\n { path: '~/.yarnrc', category: 'languages', description: 'Yarn configuration' },\n { path: '~/.config/yarn', category: 'languages', description: 'Yarn config directory' },\n { path: '~/.bunfig.toml', category: 'languages', description: 'Bun configuration' },\n { path: '~/.nvmrc', category: 'languages', description: 'nvm default version' },\n { path: '~/.node-version', category: 'languages', description: 'Node version file' },\n\n // Python\n { path: '~/.config/pip', category: 'languages', description: 'pip configuration' },\n { path: '~/.pip', category: 'languages', description: 'pip config (legacy)' },\n { path: '~/.pypirc', category: 'languages', description: 'PyPI configuration', sensitive: true },\n { path: '~/.python-version', category: 'languages', description: 'pyenv version' },\n { path: '~/.config/flake8', category: 'languages', description: 'Flake8 config' },\n { path: '~/.config/black', category: 'languages', description: 'Black formatter' },\n { path: '~/.config/ruff', category: 'languages', description: 'Ruff linter' },\n { path: '~/.pylintrc', category: 'languages', description: 'Pylint config' },\n { path: '~/.config/pypoetry', category: 'languages', description: 'Poetry config' },\n { path: '~/.config/pdm', category: 'languages', description: 'PDM config' },\n\n // Ruby\n { path: '~/.gemrc', category: 'languages', description: 'RubyGems configuration' },\n { path: '~/.irbrc', category: 'languages', description: 'IRB configuration' },\n { path: '~/.pryrc', category: 'languages', description: 'Pry configuration' },\n { path: '~/.ruby-version', category: 'languages', description: 'Ruby version file' },\n { path: '~/.bundle/config', category: 'languages', description: 'Bundler config' },\n\n // Rust\n { path: '~/.cargo/config.toml', category: 'languages', description: 'Cargo configuration' },\n { path: '~/.cargo/config', category: 'languages', description: 'Cargo config (legacy)' },\n { path: '~/.rustfmt.toml', category: 'languages', description: 'rustfmt config' },\n\n // Go\n { path: '~/.config/go', category: 'languages', description: 'Go configuration' },\n\n // Java/JVM\n { path: '~/.gradle/gradle.properties', category: 'languages', description: 'Gradle properties' },\n { path: '~/.m2/settings.xml', category: 'languages', description: 'Maven settings' },\n { path: '~/.sbt', category: 'languages', description: 'SBT config' },\n\n // Docker\n { path: '~/.docker/config.json', category: 'languages', description: 'Docker config' },\n\n // Kubernetes\n { path: '~/.kube/config', category: 'languages', description: 'kubectl config', sensitive: true },\n\n // Cloud\n { path: '~/.aws/config', category: 'languages', description: 'AWS CLI config' },\n { path: '~/.config/gcloud', category: 'languages', description: 'Google Cloud config' },\n\n // ==================== SSH & SECURITY ====================\n {\n path: '~/.ssh/config',\n category: 'ssh',\n description: 'SSH client configuration',\n sensitive: true,\n },\n {\n path: '~/.ssh/known_hosts',\n category: 'ssh',\n description: 'SSH known hosts',\n },\n {\n path: '~/.ssh/authorized_keys',\n category: 'ssh',\n description: 'Authorized SSH keys',\n },\n {\n path: '~/.ssh/rc',\n category: 'ssh',\n description: 'SSH connection script',\n },\n {\n path: '~/.gnupg/gpg.conf',\n category: 'ssh',\n description: 'GPG configuration',\n sensitive: true,\n },\n {\n path: '~/.gnupg/gpg-agent.conf',\n category: 'ssh',\n description: 'GPG agent configuration',\n },\n\n // ==================== XDG CONFIG APPS ====================\n { path: '~/.config/fontconfig', category: 'xdg', description: 'Font configuration' },\n { path: '~/.config/gtk-3.0', category: 'xdg', description: 'GTK3 settings' },\n { path: '~/.config/gtk-4.0', category: 'xdg', description: 'GTK4 settings' },\n { path: '~/.config/qt5ct', category: 'xdg', description: 'Qt5 settings' },\n { path: '~/.config/mimeapps.list', category: 'xdg', description: 'Default applications' },\n { path: '~/.config/user-dirs.dirs', category: 'xdg', description: 'XDG user directories' },\n { path: '~/.config/autostart', category: 'xdg', description: 'Autostart applications' },\n { path: '~/.config/environment.d', category: 'xdg', description: 'Environment variables' },\n { path: '~/.config/systemd/user', category: 'xdg', description: 'User systemd services', platform: 'linux' },\n { path: '~/.config/dunst', category: 'xdg', description: 'Dunst notifications', platform: 'linux' },\n { path: '~/.config/rofi', category: 'xdg', description: 'Rofi launcher', platform: 'linux' },\n { path: '~/.config/wofi', category: 'xdg', description: 'Wofi launcher', platform: 'linux' },\n\n // ==================== DESKTOP & WINDOW MANAGERS ====================\n // i3/sway\n { path: '~/.config/i3', category: 'desktop', description: 'i3 window manager', platform: 'linux' },\n { path: '~/.config/sway', category: 'desktop', description: 'Sway (Wayland i3)', platform: 'linux' },\n { path: '~/.config/i3status', category: 'desktop', description: 'i3status bar', platform: 'linux' },\n { path: '~/.config/i3status-rust', category: 'desktop', description: 'i3status-rust bar', platform: 'linux' },\n { path: '~/.config/waybar', category: 'desktop', description: 'Waybar', platform: 'linux' },\n { path: '~/.config/polybar', category: 'desktop', description: 'Polybar', platform: 'linux' },\n\n // Hyprland\n { path: '~/.config/hypr', category: 'desktop', description: 'Hyprland config', platform: 'linux' },\n\n // Other WMs\n { path: '~/.config/bspwm', category: 'desktop', description: 'bspwm config', platform: 'linux' },\n { path: '~/.config/sxhkd', category: 'desktop', description: 'sxhkd hotkeys', platform: 'linux' },\n { path: '~/.config/awesome', category: 'desktop', description: 'AwesomeWM config', platform: 'linux' },\n { path: '~/.config/openbox', category: 'desktop', description: 'Openbox config', platform: 'linux' },\n { path: '~/.config/qtile', category: 'desktop', description: 'Qtile config', platform: 'linux' },\n { path: '~/.config/herbstluftwm', category: 'desktop', description: 'herbstluftwm config', platform: 'linux' },\n\n // macOS window managers\n { path: '~/.yabairc', category: 'desktop', description: 'yabai config', platform: 'darwin' },\n { path: '~/.config/yabai', category: 'desktop', description: 'yabai config (XDG)', platform: 'darwin' },\n { path: '~/.skhdrc', category: 'desktop', description: 'skhd hotkeys', platform: 'darwin' },\n { path: '~/.config/skhd', category: 'desktop', description: 'skhd config (XDG)', platform: 'darwin' },\n { path: '~/.config/spacebar', category: 'desktop', description: 'spacebar config', platform: 'darwin' },\n { path: '~/.config/borders', category: 'desktop', description: 'borders config', platform: 'darwin' },\n { path: '~/.aerospace.toml', category: 'desktop', description: 'AeroSpace config', platform: 'darwin' },\n\n // Picom/Compton\n { path: '~/.config/picom', category: 'desktop', description: 'Picom compositor', platform: 'linux' },\n { path: '~/.config/picom.conf', category: 'desktop', description: 'Picom config (alt)', platform: 'linux' },\n\n // ==================== SCRIPTS & BINS ====================\n { path: '~/.local/bin', category: 'scripts', description: 'Local scripts and binaries' },\n { path: '~/bin', category: 'scripts', description: 'User bin directory' },\n { path: '~/.scripts', category: 'scripts', description: 'Custom scripts' },\n\n // ==================== MACOS SPECIFIC ====================\n { path: '~/.finicky.js', category: 'macos', description: 'Finicky browser picker', platform: 'darwin' },\n { path: '~/.config/karabiner', category: 'macos', description: 'Karabiner key remapping', platform: 'darwin' },\n { path: '~/.hammerspoon', category: 'macos', description: 'Hammerspoon automation', platform: 'darwin' },\n { path: '~/.config/raycast', category: 'macos', description: 'Raycast config', platform: 'darwin' },\n\n // ==================== MISCELLANEOUS ====================\n { path: '~/.config/neofetch', category: 'misc', description: 'Neofetch config' },\n { path: '~/.config/fastfetch', category: 'misc', description: 'Fastfetch config' },\n { path: '~/.config/onefetch', category: 'misc', description: 'Onefetch config' },\n { path: '~/.config/topgrade.toml', category: 'misc', description: 'Topgrade updater' },\n { path: '~/.config/youtube-dl', category: 'misc', description: 'youtube-dl config' },\n { path: '~/.config/yt-dlp', category: 'misc', description: 'yt-dlp config' },\n { path: '~/.config/mpv', category: 'misc', description: 'MPV media player' },\n { path: '~/.config/newsboat', category: 'misc', description: 'Newsboat RSS reader' },\n { path: '~/.config/cmus', category: 'misc', description: 'cmus music player' },\n { path: '~/.config/spotify-tui', category: 'misc', description: 'Spotify TUI' },\n { path: '~/.mailcap', category: 'misc', description: 'MIME type handlers' },\n { path: '~/.muttrc', category: 'misc', description: 'Mutt email client' },\n { path: '~/.config/mutt', category: 'misc', description: 'Mutt config directory' },\n { path: '~/.config/neomutt', category: 'misc', description: 'Neomutt config' },\n { path: '~/.Xresources', category: 'misc', description: 'X11 resources', platform: 'linux' },\n { path: '~/.Xmodmap', category: 'misc', description: 'X11 keymap', platform: 'linux' },\n { path: '~/.xinitrc', category: 'misc', description: 'X11 init script', platform: 'linux' },\n { path: '~/.xprofile', category: 'misc', description: 'X11 profile', platform: 'linux' },\n];\n\n/**\n * Check if a path should be included for current platform\n */\nconst shouldIncludeForPlatform = (item: { platform?: string }): boolean => {\n if (!item.platform || item.platform === 'all') return true;\n if (item.platform === 'darwin' && IS_MACOS) return true;\n if (item.platform === 'linux' && IS_LINUX) return true;\n return false;\n};\n\n/**\n * Get file/directory size\n */\nconst getSize = async (path: string): Promise<number | undefined> => {\n try {\n const stats = await stat(path);\n return stats.size;\n } catch {\n return undefined;\n }\n};\n\n/**\n * Check if path is a directory\n */\nconst isDirectory = async (path: string): Promise<boolean> => {\n try {\n const stats = await stat(path);\n return stats.isDirectory();\n } catch {\n return false;\n }\n};\n\n/**\n * Scan system for existing dotfiles\n */\nexport const detectDotfiles = async (): Promise<DetectedFile[]> => {\n const detected: DetectedFile[] = [];\n\n for (const pattern of DOTFILE_PATTERNS) {\n // Skip if not for current platform\n if (!shouldIncludeForPlatform(pattern)) continue;\n\n const fullPath = expandPath(pattern.path);\n\n if (await pathExists(fullPath)) {\n const isDir = await isDirectory(fullPath);\n const size = await getSize(fullPath);\n\n detected.push({\n path: pattern.path,\n name: basename(pattern.path),\n category: pattern.category,\n description: pattern.description,\n isDirectory: isDir,\n size,\n sensitive: pattern.sensitive,\n exclude: pattern.exclude,\n });\n }\n }\n\n return detected;\n};\n\n/**\n * Group detected files by category\n */\nexport const groupByCategory = (\n files: DetectedFile[]\n): Record<string, DetectedFile[]> => {\n const grouped: Record<string, DetectedFile[]> = {};\n\n for (const file of files) {\n if (!grouped[file.category]) {\n grouped[file.category] = [];\n }\n grouped[file.category].push(file);\n }\n\n return grouped;\n};\n\n/**\n * Get SSH files that are safe to backup (no private keys)\n */\nexport const getSafeSSHFiles = async (): Promise<string[]> => {\n const sshDir = expandPath('~/.ssh');\n const safeFiles: string[] = [];\n\n if (!(await pathExists(sshDir))) {\n return safeFiles;\n }\n\n try {\n const entries = await readdir(sshDir);\n\n for (const entry of entries) {\n // Skip private keys and other sensitive files\n if (\n entry.endsWith('.pub') ||\n entry === 'config' ||\n entry === 'known_hosts' ||\n entry === 'authorized_keys' ||\n entry === 'rc' ||\n entry === 'environment'\n ) {\n safeFiles.push(join('~/.ssh', entry));\n }\n }\n } catch {\n // Ignore errors\n }\n\n return safeFiles;\n};\n\n/**\n * Format file size for display\n */\nexport const formatSize = (bytes: number | undefined): string => {\n if (bytes === undefined) return '';\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(1))} ${sizes[i]}`;\n};\n\n/**\n * Get count of files in each category\n */\nexport const getCategoryCounts = (\n files: DetectedFile[]\n): Record<string, number> => {\n const counts: Record<string, number> = {};\n\n for (const file of files) {\n counts[file.category] = (counts[file.category] || 0) + 1;\n }\n\n return counts;\n};\n"],"mappings":"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","names":["chalk","chalk","chalk","spinner","text","chalk","homedir","join","chalk","z","fileStrategySchema","readFile","writeFile","readFile","stat","ensureDir","join","dirname","content","Command","basename","chalk","confirm","Command","chalk","join","writeFile","join","writeFile","spinner","Command","join","validateAndPrepareFiles","confirm","Command","chalk","join","exec","promisify","chalk","execAsync","join","spinner","message","chalk","confirm","spinner2","Command","Command","chalk","remoteUrl","chalk","confirm","Command","Command","chalk","chalk","Command","Command","chalk","join","stat","join","copy","ensureDir","pathExists","join","stat","join","chalk","confirm","Command","Command","chalk","chalk","Command","Command","chalk","group","Command","chalk","join","readFile","join","chalk","Command","Command","chalk","resolve","confirm","Command","join","readFile","rm","chmod","stat","ensureDir","chalk","join","dirname","readdir","readFile","writeFile","rm","stat","copy","ensureDir","pathExists","homedir","pathExists","readdir","join","stat","readFile","readFile","stat","chmod","join","ensureDir","readFile","writeFile","dirname","spinner","chalk","rm","Command","Command","chalk","chalk","spinner","Command","Command","chalk","join","basename","readdir","stat","isDirectory","chalk","spinner","addFilesFromPaths","Command","Command","chalk"]}
|
|
1
|
+
{"version":3,"sources":["../src/ui/banner.ts","../src/ui/logger.ts","../src/ui/prompts.ts","../src/ui/spinner.ts","../src/ui/table.ts","../src/ui/index.ts","../src/constants.ts","../src/lib/paths.ts","../src/schemas/config.schema.ts","../src/errors.ts","../src/lib/config.ts","../src/schemas/manifest.schema.ts","../src/lib/manifest.ts","../src/lib/git.ts","../src/lib/github.ts","../src/lib/files.ts","../src/commands/add.ts","../src/index.ts","../src/commands/init.ts","../src/lib/detect.ts","../src/lib/timemachine.ts","../src/commands/index.ts","../src/commands/remove.ts","../src/commands/sync.ts","../src/lib/hooks.ts","../src/commands/push.ts","../src/commands/pull.ts","../src/commands/restore.ts","../src/lib/backup.ts","../src/commands/status.ts","../src/commands/list.ts","../src/commands/diff.ts","../src/commands/config.ts","../src/commands/apply.ts","../src/lib/merge.ts","../src/commands/undo.ts","../src/commands/scan.ts"],"sourcesContent":["import chalk from 'chalk';\nimport boxen from 'boxen';\n\nexport const banner = (): void => {\n const art = `\n ████████╗██╗ ██╗ ██████╗██╗ ██╗\n ╚══██╔══╝██║ ██║██╔════╝██║ ██╔╝\n ██║ ██║ ██║██║ █████╔╝\n ██║ ██║ ██║██║ ██╔═██╗\n ██║ ╚██████╔╝╚██████╗██║ ██╗\n ╚═╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝`;\n\n console.log(chalk.cyan(art));\n console.log(chalk.dim(' Modern Dotfiles Manager\\n'));\n};\n\nexport const miniBanner = (): void => {\n console.log(\n boxen(chalk.cyan.bold('tuck') + chalk.dim(' · Modern Dotfiles Manager'), {\n padding: { top: 0, bottom: 0, left: 1, right: 1 },\n borderStyle: 'round',\n borderColor: 'cyan',\n })\n );\n console.log();\n};\n\nexport const customHelp = (version: string): string => {\n const title = boxen(chalk.cyan.bold('tuck') + chalk.dim(` v${version}`), {\n padding: { top: 0, bottom: 0, left: 1, right: 1 },\n borderStyle: 'round',\n borderColor: 'cyan',\n });\n\n const quickStart = `\n${chalk.bold.cyan('Quick Start:')}\n ${chalk.cyan('tuck init')} Set up tuck (auto-creates GitHub repo)\n ${chalk.cyan('tuck add <file>')} Start tracking a dotfile\n ${chalk.cyan('tuck sync')} Commit your changes\n ${chalk.cyan('tuck push')} Push to GitHub\n\n${chalk.bold.cyan('On a New Machine:')}\n ${chalk.cyan('tuck apply <user>')} Apply dotfiles from GitHub\n`;\n\n const commands = `\n${chalk.bold.cyan('Commands:')}\n ${chalk.cyan('Getting Started')}\n init Initialize tuck repository\n scan Auto-detect and select dotfiles to track\n apply <source> Apply dotfiles from a repository\n\n ${chalk.cyan('Managing Files')}\n add <paths...> Track dotfile(s)\n remove <paths...> Stop tracking dotfile(s)\n list List all tracked files\n status Show repository status\n\n ${chalk.cyan('Syncing')}\n sync Sync changes to repository\n push Push to remote\n pull Pull from remote\n diff Show pending changes\n\n ${chalk.cyan('Restoring')}\n restore Restore dotfiles to system\n undo Undo last apply (Time Machine backup)\n\n ${chalk.cyan('Configuration')}\n config Manage tuck configuration\n`;\n\n const footer = `\n${chalk.dim('Run')} ${chalk.cyan('tuck <command> --help')} ${chalk.dim('for detailed command info')}\n${chalk.dim('Documentation:')} ${chalk.cyan('https://github.com/Pranav-Karra-3301/tuck')}\n`;\n\n return `${title}\\n${quickStart}${commands}${footer}`;\n};\n\nexport const welcomeBox = (message: string, title?: string): void => {\n console.log(\n boxen(message, {\n padding: 1,\n margin: 1,\n borderStyle: 'round',\n borderColor: 'cyan',\n title,\n titleAlignment: 'center',\n })\n );\n};\n\nexport const successBox = (message: string, title?: string): void => {\n console.log(\n boxen(message, {\n padding: 1,\n margin: { top: 1, bottom: 1, left: 0, right: 0 },\n borderStyle: 'round',\n borderColor: 'green',\n title: title || 'Success',\n titleAlignment: 'center',\n })\n );\n};\n\nexport const errorBox = (message: string, title?: string): void => {\n console.log(\n boxen(message, {\n padding: 1,\n margin: { top: 1, bottom: 1, left: 0, right: 0 },\n borderStyle: 'round',\n borderColor: 'red',\n title: title || 'Error',\n titleAlignment: 'center',\n })\n );\n};\n\nexport const infoBox = (message: string, title?: string): void => {\n console.log(\n boxen(message, {\n padding: 1,\n margin: { top: 1, bottom: 1, left: 0, right: 0 },\n borderStyle: 'round',\n borderColor: 'blue',\n title,\n titleAlignment: 'center',\n })\n );\n};\n\nexport const nextSteps = (steps: string[]): void => {\n const content = steps.map((step, i) => `${chalk.cyan(`${i + 1}.`)} ${step}`).join('\\n');\n\n console.log(\n boxen(content, {\n padding: 1,\n margin: { top: 1, bottom: 0, left: 0, right: 0 },\n borderStyle: 'round',\n borderColor: 'cyan',\n title: 'Next Steps',\n titleAlignment: 'left',\n })\n );\n};\n","import chalk from 'chalk';\n\nexport interface Logger {\n info: (msg: string) => void;\n success: (msg: string) => void;\n warning: (msg: string) => void;\n error: (msg: string) => void;\n debug: (msg: string) => void;\n step: (current: number, total: number, msg: string) => void;\n file: (action: 'add' | 'modify' | 'delete' | 'sync' | 'merge', path: string) => void;\n tree: (items: TreeItem[]) => void;\n blank: () => void;\n dim: (msg: string) => void;\n heading: (msg: string) => void;\n}\n\nexport interface TreeItem {\n name: string;\n isLast: boolean;\n indent?: number;\n}\n\nexport const logger: Logger = {\n info: (msg: string) => {\n console.log(chalk.blue('i'), msg);\n },\n\n success: (msg: string) => {\n console.log(chalk.green('ok'), msg);\n },\n\n warning: (msg: string) => {\n console.log(chalk.yellow('!'), msg);\n },\n\n error: (msg: string) => {\n console.log(chalk.red('x'), msg);\n },\n\n debug: (msg: string) => {\n if (process.env.DEBUG) {\n console.log(chalk.gray('*'), chalk.gray(msg));\n }\n },\n\n step: (current: number, total: number, msg: string) => {\n console.log(chalk.dim(`[${current}/${total}]`), msg);\n },\n\n file: (action: 'add' | 'modify' | 'delete' | 'sync' | 'merge', path: string) => {\n const icons = {\n add: chalk.green('+'),\n modify: chalk.yellow('~'),\n delete: chalk.red('-'),\n sync: chalk.blue('<>'),\n merge: chalk.magenta('+'),\n };\n console.log(` ${icons[action]} ${path}`);\n },\n\n tree: (items: TreeItem[]) => {\n items.forEach(({ name, isLast, indent = 0 }) => {\n const indentation = ' '.repeat(indent);\n const prefix = isLast ? '└── ' : '├── ';\n console.log(chalk.dim(indentation + prefix) + name);\n });\n },\n\n blank: () => {\n console.log();\n },\n\n dim: (msg: string) => {\n console.log(chalk.dim(msg));\n },\n\n heading: (msg: string) => {\n console.log(chalk.bold.cyan(msg));\n },\n};\n\nexport const formatPath = (path: string): string => {\n return chalk.cyan(path);\n};\n\nexport const formatCategory = (category: string, icon?: string): string => {\n return icon ? `${icon} ${chalk.bold(category)}` : chalk.bold(category);\n};\n\nexport const formatCount = (count: number, singular: string, plural?: string): string => {\n const word = count === 1 ? singular : (plural || `${singular}s`);\n return `${chalk.bold(count.toString())} ${word}`;\n};\n\nexport const formatStatus = (status: string): string => {\n switch (status) {\n case 'modified':\n return chalk.yellow('modified');\n case 'added':\n return chalk.green('added');\n case 'deleted':\n return chalk.red('deleted');\n case 'untracked':\n return chalk.gray('untracked');\n default:\n return status;\n }\n};\n","import * as p from '@clack/prompts';\nimport chalk from 'chalk';\n\nexport interface SelectOption<T> {\n value: T;\n label: string;\n hint?: string;\n}\n\nexport const prompts = {\n intro: (title: string): void => {\n p.intro(chalk.bgCyan(chalk.black(` ${title} `)));\n },\n\n outro: (message: string): void => {\n p.outro(chalk.green(message));\n },\n\n confirm: async (message: string, initial = false): Promise<boolean> => {\n const result = await p.confirm({ message, initialValue: initial });\n if (p.isCancel(result)) {\n prompts.cancel();\n }\n return result as boolean;\n },\n\n select: async <T>(message: string, options: SelectOption<T>[]): Promise<T> => {\n const result = await p.select({\n message,\n options: options.map((opt) => ({\n value: opt.value,\n label: opt.label,\n hint: opt.hint,\n })),\n });\n if (p.isCancel(result)) {\n prompts.cancel();\n }\n return result as T;\n },\n\n multiselect: async <T>(\n message: string,\n options: SelectOption<T>[],\n required = false\n ): Promise<T[]> => {\n const result = await p.multiselect({\n message,\n options: options.map((opt) => ({\n value: opt.value,\n label: opt.label,\n hint: opt.hint,\n })),\n required,\n });\n if (p.isCancel(result)) {\n prompts.cancel();\n }\n return result as T[];\n },\n\n text: async (\n message: string,\n options?: {\n placeholder?: string;\n defaultValue?: string;\n validate?: (value: string) => string | undefined;\n }\n ): Promise<string> => {\n const result = await p.text({\n message,\n placeholder: options?.placeholder,\n defaultValue: options?.defaultValue,\n validate: options?.validate,\n });\n if (p.isCancel(result)) {\n prompts.cancel();\n }\n return result as string;\n },\n\n password: async (message: string): Promise<string> => {\n const result = await p.password({ message });\n if (p.isCancel(result)) {\n prompts.cancel();\n }\n return result as string;\n },\n\n spinner: () => p.spinner(),\n\n note: (message: string, title?: string): void => {\n p.note(message, title);\n },\n\n cancel: (message = 'Operation cancelled'): never => {\n p.cancel(message);\n process.exit(0);\n },\n\n log: {\n info: (message: string): void => {\n p.log.info(message);\n },\n success: (message: string): void => {\n p.log.success(message);\n },\n warning: (message: string): void => {\n p.log.warning(message);\n },\n error: (message: string): void => {\n p.log.error(message);\n },\n step: (message: string): void => {\n p.log.step(message);\n },\n message: (message: string): void => {\n p.log.message(message);\n },\n },\n\n group: async <T>(\n steps: Record<string, () => Promise<T | symbol>>,\n options?: { onCancel?: () => void }\n ): Promise<Record<string, T>> => {\n const results = await p.group(steps, {\n onCancel: () => {\n if (options?.onCancel) {\n options.onCancel();\n } else {\n prompts.cancel();\n }\n },\n });\n return results as Record<string, T>;\n },\n};\n\nexport const isCancel = p.isCancel;\n","import ora, { Ora } from 'ora';\nimport chalk from 'chalk';\n\nexport interface SpinnerInstance {\n start: (text?: string) => void;\n stop: () => void;\n succeed: (text?: string) => void;\n fail: (text?: string) => void;\n warn: (text?: string) => void;\n info: (text?: string) => void;\n text: (text: string) => void;\n}\n\nexport const createSpinner = (initialText?: string): SpinnerInstance => {\n const spinner: Ora = ora({\n text: initialText,\n color: 'cyan',\n spinner: 'dots',\n });\n\n return {\n start: (text?: string) => {\n if (text) spinner.text = text;\n spinner.start();\n },\n stop: () => {\n spinner.stop();\n },\n succeed: (text?: string) => {\n spinner.succeed(text ? chalk.green(text) : undefined);\n },\n fail: (text?: string) => {\n spinner.fail(text ? chalk.red(text) : undefined);\n },\n warn: (text?: string) => {\n spinner.warn(text ? chalk.yellow(text) : undefined);\n },\n info: (text?: string) => {\n spinner.info(text ? chalk.blue(text) : undefined);\n },\n text: (text: string) => {\n spinner.text = text;\n },\n };\n};\n\nexport const withSpinner = async <T>(\n text: string,\n fn: () => Promise<T>,\n options?: {\n successText?: string;\n failText?: string;\n }\n): Promise<T> => {\n const spinner = createSpinner(text);\n spinner.start();\n\n try {\n const result = await fn();\n spinner.succeed(options?.successText || text);\n return result;\n } catch (error) {\n spinner.fail(options?.failText || text);\n throw error;\n }\n};\n","import chalk from 'chalk';\n\nexport interface TableColumn {\n header: string;\n key: string;\n width?: number;\n align?: 'left' | 'right' | 'center';\n format?: (value: unknown) => string;\n}\n\nexport interface TableOptions {\n columns: TableColumn[];\n border?: boolean;\n padding?: number;\n}\n\nconst padString = (str: string, width: number, align: 'left' | 'right' | 'center' = 'left'): string => {\n // eslint-disable-next-line no-control-regex\n const visibleLength = str.replace(/\\x1b\\[[0-9;]*m/g, '').length;\n const padding = Math.max(0, width - visibleLength);\n\n switch (align) {\n case 'right':\n return ' '.repeat(padding) + str;\n case 'center': {\n const leftPad = Math.floor(padding / 2);\n const rightPad = padding - leftPad;\n return ' '.repeat(leftPad) + str + ' '.repeat(rightPad);\n }\n default:\n return str + ' '.repeat(padding);\n }\n};\n\nexport const createTable = (\n data: Record<string, unknown>[],\n options: TableOptions\n): string => {\n const { columns, border = false, padding = 2 } = options;\n\n // Calculate column widths\n const widths = columns.map((col) => {\n const headerWidth = col.header.length;\n const maxDataWidth = data.reduce((max, row) => {\n const value = col.format ? col.format(row[col.key]) : String(row[col.key] ?? '');\n // eslint-disable-next-line no-control-regex\n const visibleLength = value.replace(/\\x1b\\[[0-9;]*m/g, '').length;\n return Math.max(max, visibleLength);\n }, 0);\n return col.width || Math.max(headerWidth, maxDataWidth);\n });\n\n const lines: string[] = [];\n const pad = ' '.repeat(padding);\n\n // Header\n const headerRow = columns\n .map((col, i) => chalk.bold(padString(col.header, widths[i], col.align)))\n .join(pad);\n\n if (border) {\n const borderLine = widths.map((w) => '─'.repeat(w)).join(pad);\n lines.push(chalk.dim(borderLine));\n lines.push(headerRow);\n lines.push(chalk.dim(borderLine));\n } else {\n lines.push(headerRow);\n lines.push(chalk.dim(widths.map((w) => '─'.repeat(w)).join(pad)));\n }\n\n // Data rows\n data.forEach((row) => {\n const dataRow = columns\n .map((col, i) => {\n const value = col.format ? col.format(row[col.key]) : String(row[col.key] ?? '');\n return padString(value, widths[i], col.align);\n })\n .join(pad);\n lines.push(dataRow);\n });\n\n if (border) {\n lines.push(chalk.dim(widths.map((w) => '─'.repeat(w)).join(pad)));\n }\n\n return lines.join('\\n');\n};\n\nexport const printTable = (data: Record<string, unknown>[], options: TableOptions): void => {\n console.log(createTable(data, options));\n};\n","export * from './banner.js';\nexport * from './logger.js';\nexport * from './prompts.js';\nexport * from './spinner.js';\nexport * from './table.js';\n","import { homedir } from 'os';\nimport { join } from 'path';\n\nexport const VERSION = '0.1.0';\nexport const DESCRIPTION = 'Modern dotfiles manager with a beautiful CLI';\nexport const APP_NAME = 'tuck';\n\nexport const HOME_DIR = homedir();\nexport const DEFAULT_TUCK_DIR = join(HOME_DIR, '.tuck');\nexport const MANIFEST_FILE = '.tuckmanifest.json';\nexport const CONFIG_FILE = '.tuckrc.json';\nexport const BACKUP_DIR = join(HOME_DIR, '.tuck-backups');\nexport const FILES_DIR = 'files';\n\nexport const MANIFEST_VERSION = '1.0.0';\n\nexport interface CategoryConfig {\n patterns: string[];\n icon: string;\n}\n\nexport const CATEGORIES: Record<string, CategoryConfig> = {\n shell: {\n patterns: [\n '.zshrc',\n '.bashrc',\n '.bash_profile',\n '.zprofile',\n '.profile',\n '.aliases',\n '.zshenv',\n '.bash_aliases',\n '.inputrc',\n ],\n icon: '$',\n },\n git: {\n patterns: ['.gitconfig', '.gitignore_global', '.gitmessage', '.gitattributes'],\n icon: '*',\n },\n editors: {\n patterns: [\n '.vimrc',\n '.config/nvim',\n '.emacs',\n '.emacs.d',\n '.config/Code',\n '.ideavimrc',\n '.nanorc',\n ],\n icon: '>',\n },\n terminal: {\n patterns: [\n '.tmux.conf',\n '.config/alacritty',\n '.config/kitty',\n '.wezterm.lua',\n '.config/wezterm',\n '.config/hyper',\n '.config/starship.toml',\n ],\n icon: '#',\n },\n ssh: {\n patterns: ['.ssh/config'],\n icon: '!',\n },\n misc: {\n patterns: [],\n icon: '-',\n },\n};\n\nexport const COMMON_DOTFILES = [\n { path: '~/.zshrc', category: 'shell' },\n { path: '~/.bashrc', category: 'shell' },\n { path: '~/.bash_profile', category: 'shell' },\n { path: '~/.gitconfig', category: 'git' },\n { path: '~/.config/nvim', category: 'editors' },\n { path: '~/.vimrc', category: 'editors' },\n { path: '~/.tmux.conf', category: 'terminal' },\n { path: '~/.ssh/config', category: 'ssh' },\n { path: '~/.config/starship.toml', category: 'terminal' },\n];\n","import { homedir } from 'os';\nimport { join, basename, dirname, relative, isAbsolute, resolve } from 'path';\nimport { stat, access } from 'fs/promises';\nimport { constants } from 'fs';\nimport { DEFAULT_TUCK_DIR, FILES_DIR, MANIFEST_FILE, CONFIG_FILE, CATEGORIES } from '../constants.js';\n\nexport const expandPath = (path: string): string => {\n if (path.startsWith('~/')) {\n return join(homedir(), path.slice(2));\n }\n if (path.startsWith('$HOME/')) {\n return join(homedir(), path.slice(6));\n }\n return isAbsolute(path) ? path : resolve(path);\n};\n\nexport const collapsePath = (path: string): string => {\n const home = homedir();\n if (path.startsWith(home)) {\n return '~' + path.slice(home.length);\n }\n return path;\n};\n\nexport const getTuckDir = (customDir?: string): string => {\n return expandPath(customDir || DEFAULT_TUCK_DIR);\n};\n\nexport const getManifestPath = (tuckDir: string): string => {\n return join(tuckDir, MANIFEST_FILE);\n};\n\nexport const getConfigPath = (tuckDir: string): string => {\n return join(tuckDir, CONFIG_FILE);\n};\n\nexport const getFilesDir = (tuckDir: string): string => {\n return join(tuckDir, FILES_DIR);\n};\n\nexport const getCategoryDir = (tuckDir: string, category: string): string => {\n return join(getFilesDir(tuckDir), category);\n};\n\nexport const getDestinationPath = (tuckDir: string, category: string, filename: string): string => {\n return join(getCategoryDir(tuckDir, category), filename);\n};\n\nexport const getRelativeDestination = (category: string, filename: string): string => {\n return join(FILES_DIR, category, filename);\n};\n\nexport const sanitizeFilename = (filepath: string): string => {\n const base = basename(filepath);\n // Remove leading dot for storage, but keep track that it was a dotfile\n return base.startsWith('.') ? base.slice(1) : base;\n};\n\nexport const detectCategory = (filepath: string): string => {\n const expandedPath = expandPath(filepath);\n const relativePath = collapsePath(expandedPath);\n\n for (const [category, config] of Object.entries(CATEGORIES)) {\n for (const pattern of config.patterns) {\n // Check if the pattern matches the path\n if (relativePath.endsWith(pattern) || relativePath.includes(pattern)) {\n return category;\n }\n // Check just the filename\n const filename = basename(expandedPath);\n if (filename === pattern || filename === basename(pattern)) {\n return category;\n }\n }\n }\n\n return 'misc';\n};\n\nexport const pathExists = async (path: string): Promise<boolean> => {\n try {\n await access(path, constants.F_OK);\n return true;\n } catch {\n return false;\n }\n};\n\nexport const isDirectory = async (path: string): Promise<boolean> => {\n try {\n const stats = await stat(path);\n return stats.isDirectory();\n } catch {\n return false;\n }\n};\n\nexport const isFile = async (path: string): Promise<boolean> => {\n try {\n const stats = await stat(path);\n return stats.isFile();\n } catch {\n return false;\n }\n};\n\nexport const isSymlink = async (path: string): Promise<boolean> => {\n try {\n const stats = await stat(path);\n return stats.isSymbolicLink();\n } catch {\n return false;\n }\n};\n\nexport const isReadable = async (path: string): Promise<boolean> => {\n try {\n await access(path, constants.R_OK);\n return true;\n } catch {\n return false;\n }\n};\n\nexport const isWritable = async (path: string): Promise<boolean> => {\n try {\n await access(path, constants.W_OK);\n return true;\n } catch {\n return false;\n }\n};\n\nexport const getRelativePath = (from: string, to: string): string => {\n return relative(dirname(from), to);\n};\n\n/**\n * Validate that a path is safely within the user's home directory.\n * Prevents path traversal attacks from malicious manifests.\n * @returns true if the path is within home directory, false otherwise\n */\nexport const isPathWithinHome = (path: string): boolean => {\n const home = homedir();\n const expandedPath = expandPath(path);\n const normalizedPath = resolve(expandedPath);\n const normalizedHome = resolve(home);\n\n // Check if the normalized path starts with the home directory\n return normalizedPath.startsWith(normalizedHome + '/') || normalizedPath === normalizedHome;\n};\n\n/**\n * Validate that a source path from a manifest is safe to use.\n * Throws an error if the path is unsafe (path traversal attempt).\n */\nexport const validateSafeSourcePath = (source: string): void => {\n // Reject absolute paths that don't start with home-relative prefixes\n if (isAbsolute(source) && !source.startsWith(homedir())) {\n throw new Error(`Unsafe path detected: ${source} - absolute paths outside home directory are not allowed`);\n }\n\n // Reject obvious path traversal attempts\n if (source.includes('../') || source.includes('..\\\\')) {\n throw new Error(`Unsafe path detected: ${source} - path traversal is not allowed`);\n }\n\n // Validate the expanded path is within home\n if (!isPathWithinHome(source)) {\n throw new Error(`Unsafe path detected: ${source} - paths must be within home directory`);\n }\n};\n\nexport const generateFileId = (source: string): string => {\n // Create a unique ID from the source path\n const collapsed = collapsePath(source);\n // Remove special characters and create a readable ID\n return collapsed\n .replace(/^~\\//, '')\n .replace(/\\//g, '_')\n .replace(/\\./g, '-')\n .replace(/^-/, '');\n};\n","import { z } from 'zod';\n\nexport const fileStrategySchema = z.enum(['copy', 'symlink']);\n\nexport const categoryConfigSchema = z.object({\n patterns: z.array(z.string()),\n icon: z.string().optional(),\n});\n\nexport const tuckConfigSchema = z.object({\n repository: z\n .object({\n path: z.string(),\n defaultBranch: z.string().default('main'),\n autoCommit: z.boolean().default(true),\n autoPush: z.boolean().default(false),\n })\n .partial()\n .default({}),\n\n files: z\n .object({\n strategy: fileStrategySchema.default('copy'),\n backupOnRestore: z.boolean().default(true),\n backupDir: z.string().optional(),\n })\n .partial()\n .default({}),\n\n categories: z.record(categoryConfigSchema).optional().default({}),\n\n ignore: z.array(z.string()).optional().default([]),\n\n hooks: z\n .object({\n preSync: z.string().optional(),\n postSync: z.string().optional(),\n preRestore: z.string().optional(),\n postRestore: z.string().optional(),\n })\n .partial()\n .default({}),\n\n templates: z\n .object({\n enabled: z.boolean().default(false),\n variables: z.record(z.string()).default({}),\n })\n .partial()\n .default({}),\n\n encryption: z\n .object({\n enabled: z.boolean().default(false),\n gpgKey: z.string().optional(),\n files: z.array(z.string()).default([]),\n })\n .partial()\n .default({}),\n\n ui: z\n .object({\n colors: z.boolean().default(true),\n emoji: z.boolean().default(true),\n verbose: z.boolean().default(false),\n })\n .partial()\n .default({}),\n});\n\nexport type TuckConfigInput = z.input<typeof tuckConfigSchema>;\nexport type TuckConfigOutput = z.output<typeof tuckConfigSchema>;\n\nexport const defaultConfig: TuckConfigOutput = {\n repository: {\n defaultBranch: 'main',\n autoCommit: true,\n autoPush: false,\n },\n files: {\n strategy: 'copy',\n backupOnRestore: true,\n },\n categories: {},\n ignore: [],\n hooks: {},\n templates: {\n enabled: false,\n variables: {},\n },\n encryption: {\n enabled: false,\n files: [],\n },\n ui: {\n colors: true,\n emoji: true,\n verbose: false,\n },\n};\n","import chalk from 'chalk';\n\nexport class TuckError extends Error {\n constructor(\n message: string,\n public code: string,\n public suggestions?: string[]\n ) {\n super(message);\n this.name = 'TuckError';\n }\n}\n\nexport class NotInitializedError extends TuckError {\n constructor() {\n super('Tuck is not initialized in this system', 'NOT_INITIALIZED', [\n 'Run `tuck init` to get started',\n ]);\n }\n}\n\nexport class AlreadyInitializedError extends TuckError {\n constructor(path: string) {\n super(`Tuck is already initialized at ${path}`, 'ALREADY_INITIALIZED', [\n 'Use `tuck status` to see current state',\n `Remove ${path} to reinitialize`,\n ]);\n }\n}\n\nexport class FileNotFoundError extends TuckError {\n constructor(path: string) {\n super(`File not found: ${path}`, 'FILE_NOT_FOUND', [\n 'Check that the path is correct',\n 'Use absolute paths or paths relative to home directory',\n ]);\n }\n}\n\nexport class FileNotTrackedError extends TuckError {\n constructor(path: string) {\n super(`File is not tracked: ${path}`, 'FILE_NOT_TRACKED', [\n `Run \\`tuck add ${path}\\` to track this file`,\n 'Run `tuck list` to see all tracked files',\n ]);\n }\n}\n\nexport class FileAlreadyTrackedError extends TuckError {\n constructor(path: string) {\n super(`File is already tracked: ${path}`, 'FILE_ALREADY_TRACKED', [\n 'Run `tuck sync` to update it',\n `Run \\`tuck remove ${path}\\` to untrack`,\n ]);\n }\n}\n\nexport class GitError extends TuckError {\n constructor(message: string, gitError?: string) {\n super(`Git operation failed: ${message}`, 'GIT_ERROR', gitError ? [gitError] : undefined);\n }\n}\n\nexport class ConfigError extends TuckError {\n constructor(message: string) {\n super(`Configuration error: ${message}`, 'CONFIG_ERROR', [\n 'Run `tuck config edit` to fix configuration',\n 'Run `tuck config reset` to restore defaults',\n ]);\n }\n}\n\nexport class ManifestError extends TuckError {\n constructor(message: string) {\n super(`Manifest error: ${message}`, 'MANIFEST_ERROR', [\n 'The manifest file may be corrupted',\n 'Run `tuck init --from <remote>` to restore from remote',\n ]);\n }\n}\n\nexport class PermissionError extends TuckError {\n constructor(path: string, operation: string) {\n super(`Permission denied: cannot ${operation} ${path}`, 'PERMISSION_ERROR', [\n 'Check file permissions',\n 'Try running with appropriate permissions',\n ]);\n }\n}\n\nexport class GitHubCliError extends TuckError {\n constructor(message: string, suggestions?: string[]) {\n super(\n `GitHub CLI error: ${message}`,\n 'GITHUB_CLI_ERROR',\n suggestions || ['Install GitHub CLI: https://cli.github.com/', 'Run `gh auth login` to authenticate']\n );\n }\n}\n\nexport class BackupError extends TuckError {\n constructor(message: string, suggestions?: string[]) {\n super(`Backup error: ${message}`, 'BACKUP_ERROR', suggestions || ['Check available disk space']);\n }\n}\n\nexport const handleError = (error: unknown): never => {\n if (error instanceof TuckError) {\n console.error(chalk.red('x'), error.message);\n if (error.suggestions && error.suggestions.length > 0) {\n console.error();\n console.error(chalk.dim('Suggestions:'));\n error.suggestions.forEach((s) => console.error(chalk.dim(` → ${s}`)));\n }\n process.exit(1);\n }\n\n if (error instanceof Error) {\n console.error(chalk.red('x'), 'An unexpected error occurred:', error.message);\n if (process.env.DEBUG) {\n console.error(error.stack);\n }\n process.exit(1);\n }\n\n console.error(chalk.red('x'), 'An unknown error occurred');\n process.exit(1);\n};\n","import { readFile, writeFile } from 'fs/promises';\nimport { cosmiconfig } from 'cosmiconfig';\nimport { tuckConfigSchema, defaultConfig, type TuckConfigOutput } from '../schemas/config.schema.js';\nimport { getConfigPath, pathExists, getTuckDir } from './paths.js';\nimport { ConfigError } from '../errors.js';\nimport { BACKUP_DIR } from '../constants.js';\n\nlet cachedConfig: TuckConfigOutput | null = null;\nlet cachedTuckDir: string | null = null;\n\nexport const loadConfig = async (tuckDir?: string): Promise<TuckConfigOutput> => {\n const dir = tuckDir || getTuckDir();\n\n // Return cached config if same directory\n if (cachedConfig && cachedTuckDir === dir) {\n return cachedConfig;\n }\n\n const configPath = getConfigPath(dir);\n\n if (!(await pathExists(configPath))) {\n // Return default config if no config file exists\n cachedConfig = { ...defaultConfig, repository: { ...defaultConfig.repository, path: dir } };\n cachedTuckDir = dir;\n return cachedConfig;\n }\n\n try {\n const content = await readFile(configPath, 'utf-8');\n const rawConfig = JSON.parse(content);\n const result = tuckConfigSchema.safeParse(rawConfig);\n\n if (!result.success) {\n throw new ConfigError(`Invalid configuration: ${result.error.message}`);\n }\n\n // Merge with defaults\n cachedConfig = {\n ...defaultConfig,\n ...result.data,\n repository: {\n ...defaultConfig.repository,\n ...result.data.repository,\n path: dir,\n },\n files: {\n ...defaultConfig.files,\n ...result.data.files,\n backupDir: result.data.files?.backupDir || BACKUP_DIR,\n },\n };\n cachedTuckDir = dir;\n\n return cachedConfig;\n } catch (error) {\n if (error instanceof ConfigError) {\n throw error;\n }\n if (error instanceof SyntaxError) {\n throw new ConfigError('Configuration file contains invalid JSON');\n }\n throw new ConfigError(`Failed to load configuration: ${error}`);\n }\n};\n\nexport const saveConfig = async (\n config: Partial<TuckConfigOutput>,\n tuckDir?: string\n): Promise<void> => {\n const dir = tuckDir || getTuckDir();\n const configPath = getConfigPath(dir);\n\n // Load existing config and merge\n const existing = await loadConfig(dir);\n const merged = {\n ...existing,\n ...config,\n repository: {\n ...existing.repository,\n ...config.repository,\n },\n files: {\n ...existing.files,\n ...config.files,\n },\n hooks: {\n ...existing.hooks,\n ...config.hooks,\n },\n templates: {\n ...existing.templates,\n ...config.templates,\n },\n encryption: {\n ...existing.encryption,\n ...config.encryption,\n },\n ui: {\n ...existing.ui,\n ...config.ui,\n },\n };\n\n // Validate before saving\n const result = tuckConfigSchema.safeParse(merged);\n if (!result.success) {\n throw new ConfigError(`Invalid configuration: ${result.error.message}`);\n }\n\n try {\n await writeFile(configPath, JSON.stringify(result.data, null, 2) + '\\n', 'utf-8');\n // Update cache\n cachedConfig = result.data;\n cachedTuckDir = dir;\n } catch (error) {\n throw new ConfigError(`Failed to save configuration: ${error}`);\n }\n};\n\nexport const getConfigValue = async <K extends keyof TuckConfigOutput>(\n key: K,\n tuckDir?: string\n): Promise<TuckConfigOutput[K]> => {\n const config = await loadConfig(tuckDir);\n return config[key];\n};\n\nexport const setConfigValue = async <K extends keyof TuckConfigOutput>(\n key: K,\n value: TuckConfigOutput[K],\n tuckDir?: string\n): Promise<void> => {\n await saveConfig({ [key]: value } as Partial<TuckConfigOutput>, tuckDir);\n};\n\nexport const resetConfig = async (tuckDir?: string): Promise<void> => {\n const dir = tuckDir || getTuckDir();\n const configPath = getConfigPath(dir);\n\n const resetTo = { ...defaultConfig, repository: { ...defaultConfig.repository, path: dir } };\n\n try {\n await writeFile(configPath, JSON.stringify(resetTo, null, 2) + '\\n', 'utf-8');\n cachedConfig = resetTo;\n cachedTuckDir = dir;\n } catch (error) {\n throw new ConfigError(`Failed to reset configuration: ${error}`);\n }\n};\n\nexport const clearConfigCache = (): void => {\n cachedConfig = null;\n cachedTuckDir = null;\n};\n\nexport const findTuckDir = async (): Promise<string | null> => {\n // First check default location\n const defaultDir = getTuckDir();\n if (await pathExists(getConfigPath(defaultDir))) {\n return defaultDir;\n }\n\n // Try cosmiconfig to find config in current directory or parents\n const explorer = cosmiconfig('tuck', {\n searchPlaces: [\n '.tuckrc',\n '.tuckrc.json',\n '.tuckrc.yaml',\n '.tuckrc.yml',\n 'tuck.config.js',\n 'tuck.config.cjs',\n ],\n });\n\n try {\n const result = await explorer.search();\n if (result?.filepath) {\n return result.filepath;\n }\n } catch {\n // Ignore search errors\n }\n\n return null;\n};\n","import { z } from 'zod';\n\nexport const fileStrategySchema = z.enum(['copy', 'symlink']);\n\nexport const trackedFileSchema = z.object({\n source: z.string(),\n destination: z.string(),\n category: z.string(),\n strategy: fileStrategySchema,\n encrypted: z.boolean().default(false),\n template: z.boolean().default(false),\n permissions: z.string().optional(),\n added: z.string(),\n modified: z.string(),\n checksum: z.string(),\n});\n\nexport const tuckManifestSchema = z.object({\n version: z.string(),\n created: z.string(),\n updated: z.string(),\n machine: z.string().optional(),\n files: z.record(trackedFileSchema),\n});\n\nexport type TrackedFileInput = z.input<typeof trackedFileSchema>;\nexport type TrackedFileOutput = z.output<typeof trackedFileSchema>;\nexport type TuckManifestInput = z.input<typeof tuckManifestSchema>;\nexport type TuckManifestOutput = z.output<typeof tuckManifestSchema>;\n\nexport const createEmptyManifest = (machine?: string): TuckManifestOutput => {\n const now = new Date().toISOString();\n return {\n version: '1.0.0',\n created: now,\n updated: now,\n machine,\n files: {},\n };\n};\n","import { readFile, writeFile } from 'fs/promises';\nimport {\n tuckManifestSchema,\n createEmptyManifest,\n type TuckManifestOutput,\n type TrackedFileOutput,\n} from '../schemas/manifest.schema.js';\nimport { getManifestPath, pathExists } from './paths.js';\nimport { ManifestError } from '../errors.js';\n\nlet cachedManifest: TuckManifestOutput | null = null;\nlet cachedManifestDir: string | null = null;\n\nexport const loadManifest = async (tuckDir: string): Promise<TuckManifestOutput> => {\n // Return cached manifest if same directory\n if (cachedManifest && cachedManifestDir === tuckDir) {\n return cachedManifest;\n }\n\n const manifestPath = getManifestPath(tuckDir);\n\n if (!(await pathExists(manifestPath))) {\n throw new ManifestError('Manifest file not found. Is tuck initialized?');\n }\n\n try {\n const content = await readFile(manifestPath, 'utf-8');\n const rawManifest = JSON.parse(content);\n const result = tuckManifestSchema.safeParse(rawManifest);\n\n if (!result.success) {\n throw new ManifestError(`Invalid manifest: ${result.error.message}`);\n }\n\n cachedManifest = result.data;\n cachedManifestDir = tuckDir;\n\n return cachedManifest;\n } catch (error) {\n if (error instanceof ManifestError) {\n throw error;\n }\n if (error instanceof SyntaxError) {\n throw new ManifestError('Manifest file contains invalid JSON');\n }\n throw new ManifestError(`Failed to load manifest: ${error}`);\n }\n};\n\nexport const saveManifest = async (\n manifest: TuckManifestOutput,\n tuckDir: string\n): Promise<void> => {\n const manifestPath = getManifestPath(tuckDir);\n\n // Update the updated timestamp\n manifest.updated = new Date().toISOString();\n\n // Validate before saving\n const result = tuckManifestSchema.safeParse(manifest);\n if (!result.success) {\n throw new ManifestError(`Invalid manifest: ${result.error.message}`);\n }\n\n try {\n await writeFile(manifestPath, JSON.stringify(result.data, null, 2) + '\\n', 'utf-8');\n cachedManifest = result.data;\n cachedManifestDir = tuckDir;\n } catch (error) {\n throw new ManifestError(`Failed to save manifest: ${error}`);\n }\n};\n\nexport const createManifest = async (\n tuckDir: string,\n machine?: string\n): Promise<TuckManifestOutput> => {\n const manifestPath = getManifestPath(tuckDir);\n\n if (await pathExists(manifestPath)) {\n throw new ManifestError('Manifest already exists');\n }\n\n const manifest = createEmptyManifest(machine);\n\n try {\n await writeFile(manifestPath, JSON.stringify(manifest, null, 2) + '\\n', 'utf-8');\n cachedManifest = manifest;\n cachedManifestDir = tuckDir;\n return manifest;\n } catch (error) {\n throw new ManifestError(`Failed to create manifest: ${error}`);\n }\n};\n\nexport const addFileToManifest = async (\n tuckDir: string,\n id: string,\n file: TrackedFileOutput\n): Promise<void> => {\n const manifest = await loadManifest(tuckDir);\n\n if (manifest.files[id]) {\n throw new ManifestError(`File already tracked with ID: ${id}`);\n }\n\n manifest.files[id] = file;\n await saveManifest(manifest, tuckDir);\n};\n\nexport const updateFileInManifest = async (\n tuckDir: string,\n id: string,\n updates: Partial<TrackedFileOutput>\n): Promise<void> => {\n const manifest = await loadManifest(tuckDir);\n\n if (!manifest.files[id]) {\n throw new ManifestError(`File not found in manifest: ${id}`);\n }\n\n manifest.files[id] = {\n ...manifest.files[id],\n ...updates,\n modified: new Date().toISOString(),\n };\n\n await saveManifest(manifest, tuckDir);\n};\n\nexport const removeFileFromManifest = async (tuckDir: string, id: string): Promise<void> => {\n const manifest = await loadManifest(tuckDir);\n\n if (!manifest.files[id]) {\n throw new ManifestError(`File not found in manifest: ${id}`);\n }\n\n delete manifest.files[id];\n await saveManifest(manifest, tuckDir);\n};\n\nexport const getTrackedFile = async (\n tuckDir: string,\n id: string\n): Promise<TrackedFileOutput | null> => {\n const manifest = await loadManifest(tuckDir);\n return manifest.files[id] || null;\n};\n\nexport const getTrackedFileBySource = async (\n tuckDir: string,\n source: string\n): Promise<{ id: string; file: TrackedFileOutput } | null> => {\n const manifest = await loadManifest(tuckDir);\n\n for (const [id, file] of Object.entries(manifest.files)) {\n if (file.source === source) {\n return { id, file };\n }\n }\n\n return null;\n};\n\nexport const getAllTrackedFiles = async (\n tuckDir: string\n): Promise<Record<string, TrackedFileOutput>> => {\n const manifest = await loadManifest(tuckDir);\n return manifest.files;\n};\n\nexport const getTrackedFilesByCategory = async (\n tuckDir: string,\n category: string\n): Promise<Record<string, TrackedFileOutput>> => {\n const manifest = await loadManifest(tuckDir);\n const filtered: Record<string, TrackedFileOutput> = {};\n\n for (const [id, file] of Object.entries(manifest.files)) {\n if (file.category === category) {\n filtered[id] = file;\n }\n }\n\n return filtered;\n};\n\nexport const isFileTracked = async (tuckDir: string, source: string): Promise<boolean> => {\n const result = await getTrackedFileBySource(tuckDir, source);\n return result !== null;\n};\n\nexport const getFileCount = async (tuckDir: string): Promise<number> => {\n const manifest = await loadManifest(tuckDir);\n return Object.keys(manifest.files).length;\n};\n\nexport const getCategories = async (tuckDir: string): Promise<string[]> => {\n const manifest = await loadManifest(tuckDir);\n const categories = new Set<string>();\n\n for (const file of Object.values(manifest.files)) {\n categories.add(file.category);\n }\n\n return Array.from(categories).sort();\n};\n\nexport const clearManifestCache = (): void => {\n cachedManifest = null;\n cachedManifestDir = null;\n};\n","import simpleGit, { SimpleGit, StatusResult } from 'simple-git';\nimport { GitError } from '../errors.js';\nimport { pathExists } from './paths.js';\nimport { join } from 'path';\n\nexport interface GitStatus {\n isRepo: boolean;\n branch: string;\n tracking?: string;\n ahead: number;\n behind: number;\n staged: string[];\n modified: string[];\n untracked: string[];\n deleted: string[];\n hasChanges: boolean;\n}\n\nexport interface GitCommit {\n hash: string;\n date: string;\n message: string;\n author: string;\n}\n\nconst createGit = (dir: string): SimpleGit => {\n return simpleGit(dir, {\n binary: 'git',\n maxConcurrentProcesses: 6,\n trimmed: true,\n });\n};\n\nexport const isGitRepo = async (dir: string): Promise<boolean> => {\n const gitDir = join(dir, '.git');\n return pathExists(gitDir);\n};\n\nexport const initRepo = async (dir: string): Promise<void> => {\n try {\n const git = createGit(dir);\n await git.init();\n } catch (error) {\n throw new GitError('Failed to initialize repository', String(error));\n }\n};\n\nexport const cloneRepo = async (url: string, dir: string): Promise<void> => {\n try {\n const git = simpleGit();\n await git.clone(url, dir);\n } catch (error) {\n throw new GitError(`Failed to clone repository from ${url}`, String(error));\n }\n};\n\nexport const addRemote = async (dir: string, name: string, url: string): Promise<void> => {\n try {\n const git = createGit(dir);\n await git.addRemote(name, url);\n } catch (error) {\n throw new GitError('Failed to add remote', String(error));\n }\n};\n\nexport const removeRemote = async (dir: string, name: string): Promise<void> => {\n try {\n const git = createGit(dir);\n await git.removeRemote(name);\n } catch (error) {\n throw new GitError('Failed to remove remote', String(error));\n }\n};\n\nexport const getRemotes = async (dir: string): Promise<{ name: string; url: string }[]> => {\n try {\n const git = createGit(dir);\n const remotes = await git.getRemotes(true);\n return remotes.map((r) => ({ name: r.name, url: r.refs.fetch || r.refs.push || '' }));\n } catch (error) {\n throw new GitError('Failed to get remotes', String(error));\n }\n};\n\nexport const getStatus = async (dir: string): Promise<GitStatus> => {\n try {\n const git = createGit(dir);\n const status: StatusResult = await git.status();\n\n return {\n isRepo: true,\n branch: status.current || 'main',\n tracking: status.tracking || undefined,\n ahead: status.ahead,\n behind: status.behind,\n staged: status.staged,\n modified: status.modified,\n untracked: status.not_added,\n deleted: status.deleted,\n hasChanges: !status.isClean(),\n };\n } catch (error) {\n throw new GitError('Failed to get status', String(error));\n }\n};\n\nexport const stageFiles = async (dir: string, files: string[]): Promise<void> => {\n try {\n const git = createGit(dir);\n await git.add(files);\n } catch (error) {\n throw new GitError('Failed to stage files', String(error));\n }\n};\n\nexport const stageAll = async (dir: string): Promise<void> => {\n try {\n const git = createGit(dir);\n await git.add('.');\n } catch (error) {\n throw new GitError('Failed to stage all files', String(error));\n }\n};\n\nexport const commit = async (dir: string, message: string): Promise<string> => {\n try {\n const git = createGit(dir);\n const result = await git.commit(message);\n return result.commit;\n } catch (error) {\n throw new GitError('Failed to commit', String(error));\n }\n};\n\nexport const push = async (\n dir: string,\n options?: { remote?: string; branch?: string; force?: boolean; setUpstream?: boolean }\n): Promise<void> => {\n try {\n const git = createGit(dir);\n const args: string[] = [];\n\n if (options?.setUpstream) {\n args.push('-u');\n }\n if (options?.force) {\n args.push('--force');\n }\n\n const remote = options?.remote || 'origin';\n const branch = options?.branch;\n\n if (branch) {\n await git.push([remote, branch, ...args]);\n } else {\n await git.push([remote, ...args]);\n }\n } catch (error) {\n throw new GitError('Failed to push', String(error));\n }\n};\n\nexport const pull = async (\n dir: string,\n options?: { remote?: string; branch?: string; rebase?: boolean }\n): Promise<void> => {\n try {\n const git = createGit(dir);\n const args: string[] = [];\n\n if (options?.rebase) {\n args.push('--rebase');\n }\n\n const remote = options?.remote || 'origin';\n const branch = options?.branch;\n\n if (branch) {\n await git.pull(remote, branch, args);\n } else {\n await git.pull(remote, undefined, args);\n }\n } catch (error) {\n throw new GitError('Failed to pull', String(error));\n }\n};\n\nexport const fetch = async (dir: string, remote = 'origin'): Promise<void> => {\n try {\n const git = createGit(dir);\n await git.fetch(remote);\n } catch (error) {\n throw new GitError('Failed to fetch', String(error));\n }\n};\n\nexport const getLog = async (\n dir: string,\n options?: { maxCount?: number }\n): Promise<GitCommit[]> => {\n try {\n const git = createGit(dir);\n const log = await git.log({\n maxCount: options?.maxCount || 10,\n });\n\n return log.all.map((entry) => ({\n hash: entry.hash,\n date: entry.date,\n message: entry.message,\n author: entry.author_name || 'Unknown',\n }));\n } catch (error) {\n throw new GitError('Failed to get log', String(error));\n }\n};\n\nexport const getDiff = async (\n dir: string,\n options?: { staged?: boolean; stat?: boolean; files?: string[] }\n): Promise<string> => {\n try {\n const git = createGit(dir);\n const args: string[] = [];\n\n if (options?.staged) {\n args.push('--staged');\n }\n if (options?.stat) {\n args.push('--stat');\n }\n if (options?.files) {\n args.push('--');\n args.push(...options.files);\n }\n\n const result = await git.diff(args);\n return result;\n } catch (error) {\n throw new GitError('Failed to get diff', String(error));\n }\n};\n\nexport const getCurrentBranch = async (dir: string): Promise<string> => {\n try {\n const git = createGit(dir);\n const branch = await git.revparse(['--abbrev-ref', 'HEAD']);\n return branch;\n } catch (error) {\n throw new GitError('Failed to get current branch', String(error));\n }\n};\n\nexport const hasRemote = async (dir: string, name = 'origin'): Promise<boolean> => {\n try {\n const remotes = await getRemotes(dir);\n return remotes.some((r) => r.name === name);\n } catch {\n return false;\n }\n};\n\nexport const getRemoteUrl = async (dir: string, name = 'origin'): Promise<string | null> => {\n try {\n const remotes = await getRemotes(dir);\n const remote = remotes.find((r) => r.name === name);\n return remote?.url || null;\n } catch {\n return null;\n }\n};\n\nexport const setDefaultBranch = async (dir: string, branch: string): Promise<void> => {\n try {\n const git = createGit(dir);\n await git.branch(['-M', branch]);\n } catch (error) {\n throw new GitError('Failed to set default branch', String(error));\n }\n};\n","import { execFile } from 'child_process';\nimport { promisify } from 'util';\nimport { GitHubCliError } from '../errors.js';\n\nconst execFileAsync = promisify(execFile);\n\n/**\n * Validate repository name/identifier to prevent command injection.\n * Valid formats: \"owner/repo\", \"repo\", or full URLs\n */\nconst validateRepoName = (repoName: string): void => {\n // Allow full URLs (https:// or git@)\n if (repoName.includes('://') || repoName.startsWith('git@')) {\n // Basic URL validation - must not contain shell metacharacters\n if (/[;&|`$(){}[\\]<>!#*?]/.test(repoName.replace(/[/:@.]/g, ''))) {\n throw new GitHubCliError(`Invalid repository URL: ${repoName}`);\n }\n return;\n }\n\n // For owner/repo or repo format, validate strictly\n // Valid: alphanumeric, hyphens, underscores, dots, and single forward slash\n const validPattern = /^[a-zA-Z0-9._-]+(?:\\/[a-zA-Z0-9._-]+)?$/;\n if (!validPattern.test(repoName)) {\n throw new GitHubCliError(`Invalid repository name: ${repoName}`, [\n 'Repository names can only contain alphanumeric characters, hyphens, underscores, and dots',\n 'Format: \"owner/repo\" or \"repo\"',\n ]);\n }\n};\n\nexport interface GitHubUser {\n login: string;\n name: string | null;\n email: string | null;\n}\n\nexport interface GitHubRepo {\n name: string;\n fullName: string;\n url: string;\n sshUrl: string;\n httpsUrl: string;\n isPrivate: boolean;\n}\n\nexport interface CreateRepoOptions {\n name: string;\n description?: string;\n isPrivate?: boolean;\n homepage?: string;\n}\n\n/**\n * Check if the GitHub CLI (gh) is installed\n */\nexport const isGhInstalled = async (): Promise<boolean> => {\n try {\n await execFileAsync('gh', ['--version']);\n return true;\n } catch {\n return false;\n }\n};\n\n/**\n * Check if the user is authenticated with GitHub CLI\n */\nexport const isGhAuthenticated = async (): Promise<boolean> => {\n try {\n // gh auth status outputs to stderr, not stdout\n // execFileAsync provides both stdout and stderr even on success\n const { stdout, stderr } = await execFileAsync('gh', ['auth', 'status']);\n // Check stderr (where gh auth status outputs) and stdout (as fallback)\n const output = (stderr || stdout || '').trim();\n // Only return true if we can definitively confirm authentication\n // Check for positive indicator, not absence of negative indicator\n return output.includes('Logged in');\n } catch (error) {\n // gh auth status returns exit code 1 when not authenticated\n // and outputs error message to stderr\n if (error instanceof Error && 'stderr' in error) {\n const stderr = (error as { stderr: string }).stderr;\n // Only return true if stderr explicitly confirms authentication\n return stderr.includes('Logged in');\n }\n return false;\n }\n};\n\n/**\n * Get the authenticated GitHub user's information\n */\nexport const getAuthenticatedUser = async (): Promise<GitHubUser> => {\n if (!(await isGhInstalled())) {\n throw new GitHubCliError('GitHub CLI is not installed');\n }\n\n if (!(await isGhAuthenticated())) {\n throw new GitHubCliError('Not authenticated with GitHub CLI', [\n 'Run `gh auth login` to authenticate',\n ]);\n }\n\n try {\n const { stdout } = await execFileAsync('gh', ['api', 'user', '--jq', '.login, .name, .email']);\n const lines = stdout.trim().split('\\n');\n return {\n login: lines[0] || '',\n name: lines[1] !== 'null' ? lines[1] : null,\n email: lines[2] !== 'null' ? lines[2] : null,\n };\n } catch (error) {\n throw new GitHubCliError('Failed to get user information', [\n String(error),\n 'Check your GitHub CLI authentication',\n ]);\n }\n};\n\n/**\n * Check if a repository exists on GitHub\n */\nexport const repoExists = async (repoName: string): Promise<boolean> => {\n try {\n validateRepoName(repoName);\n await execFileAsync('gh', ['repo', 'view', repoName, '--json', 'name']);\n return true;\n } catch {\n return false;\n }\n};\n\n/**\n * Create a new GitHub repository\n */\nexport const createRepo = async (options: CreateRepoOptions): Promise<GitHubRepo> => {\n if (!(await isGhInstalled())) {\n throw new GitHubCliError('GitHub CLI is not installed');\n }\n\n if (!(await isGhAuthenticated())) {\n throw new GitHubCliError('Not authenticated with GitHub CLI', [\n 'Run `gh auth login` to authenticate',\n ]);\n }\n\n // Check if repo already exists\n const user = await getAuthenticatedUser();\n const fullName = `${user.login}/${options.name}`;\n\n if (await repoExists(fullName)) {\n throw new GitHubCliError(`Repository \"${fullName}\" already exists`, [\n `Use a different name or run \\`tuck init --remote ${fullName}\\``,\n ]);\n }\n\n // Validate inputs to prevent command injection\n validateRepoName(options.name);\n \n if (options.description && /[;&|`$(){}[\\]<>!#*?]/.test(options.description)) {\n throw new GitHubCliError('Invalid description: contains unsafe characters');\n }\n \n if (options.homepage && /[;&|`$(){}[\\]<>!#*?]/.test(options.homepage)) {\n throw new GitHubCliError('Invalid homepage: contains unsafe characters');\n }\n\n try {\n // Build command arguments array to prevent command injection\n const args: string[] = ['repo', 'create', options.name];\n \n if (options.isPrivate !== false) {\n args.push('--private');\n } else {\n args.push('--public');\n }\n \n if (options.description) {\n args.push('--description', options.description);\n }\n \n if (options.homepage) {\n args.push('--homepage', options.homepage);\n }\n \n args.push('--confirm', '--json', 'name,url,sshUrl');\n \n const { stdout } = await execFileAsync('gh', args);\n const result = JSON.parse(stdout);\n\n return {\n name: result.name,\n fullName: `${user.login}/${result.name}`,\n url: result.url,\n sshUrl: result.sshUrl,\n httpsUrl: result.url.replace('github.com', 'github.com').replace(/^https?:\\/\\//, 'https://'),\n isPrivate: options.isPrivate !== false,\n };\n } catch (error) {\n throw new GitHubCliError(`Failed to create repository \"${options.name}\"`, [\n String(error),\n 'Check your GitHub permissions',\n ]);\n }\n};\n\n/**\n * Get the preferred remote URL format (SSH or HTTPS)\n */\nexport const getPreferredRemoteProtocol = async (): Promise<'ssh' | 'https'> => {\n try {\n const { stdout } = await execFileAsync('gh', ['config', 'get', 'git_protocol']);\n const protocol = stdout.trim().toLowerCase();\n return protocol === 'ssh' ? 'ssh' : 'https';\n } catch {\n // Default to HTTPS if we can't determine preference\n return 'https';\n }\n};\n\n/**\n * Get repository information from GitHub\n */\nexport const getRepoInfo = async (repoName: string): Promise<GitHubRepo | null> => {\n try {\n validateRepoName(repoName);\n const { stdout } = await execFileAsync('gh', [\n 'repo',\n 'view',\n repoName,\n '--json',\n 'name,url,sshUrl,isPrivate,owner',\n ]);\n const result = JSON.parse(stdout);\n\n return {\n name: result.name,\n fullName: `${result.owner.login}/${result.name}`,\n url: result.url,\n sshUrl: result.sshUrl,\n httpsUrl: result.url,\n isPrivate: result.isPrivate,\n };\n } catch {\n return null;\n }\n};\n\n/**\n * Clone a repository to a specific directory using gh CLI\n */\nexport const ghCloneRepo = async (repoName: string, targetDir: string): Promise<void> => {\n if (!(await isGhInstalled())) {\n throw new GitHubCliError('GitHub CLI is not installed');\n }\n\n validateRepoName(repoName);\n\n try {\n await execFileAsync('gh', ['repo', 'clone', repoName, targetDir]);\n } catch (error) {\n throw new GitHubCliError(`Failed to clone repository \"${repoName}\"`, [\n String(error),\n 'Check that the repository exists and you have access',\n ]);\n }\n};\n\n/**\n * Find a user's dotfiles repository (checks common names)\n */\nexport const findDotfilesRepo = async (username?: string): Promise<string | null> => {\n const user = username || (await getAuthenticatedUser()).login;\n const commonNames = ['dotfiles', 'tuck', '.dotfiles', 'dot-files', 'dots'];\n\n for (const name of commonNames) {\n const repoName = `${user}/${name}`;\n if (await repoExists(repoName)) {\n return repoName;\n }\n }\n\n return null;\n};\n\n/**\n * Get the remote URL in the user's preferred format (SSH or HTTPS)\n */\nexport const getPreferredRepoUrl = async (repo: GitHubRepo): Promise<string> => {\n const protocol = await getPreferredRemoteProtocol();\n return protocol === 'ssh' ? repo.sshUrl : repo.httpsUrl;\n};\n","import { createHash } from 'crypto';\nimport { readFile, stat, readdir, copyFile, symlink, unlink, rm } from 'fs/promises';\nimport { copy, ensureDir } from 'fs-extra';\nimport { join, dirname } from 'path';\nimport { FileNotFoundError, PermissionError } from '../errors.js';\nimport { expandPath, pathExists, isDirectory } from './paths.js';\n\nexport interface FileInfo {\n path: string;\n isDirectory: boolean;\n isSymlink: boolean;\n size: number;\n permissions: string;\n modified: Date;\n}\n\nexport interface CopyResult {\n source: string;\n destination: string;\n fileCount: number;\n totalSize: number;\n}\n\nexport const getFileChecksum = async (filepath: string): Promise<string> => {\n const expandedPath = expandPath(filepath);\n\n if (await isDirectory(expandedPath)) {\n // For directories, create a hash of all file checksums\n const files = await getDirectoryFiles(expandedPath);\n const hashes: string[] = [];\n\n for (const file of files) {\n const content = await readFile(file);\n hashes.push(createHash('sha256').update(content).digest('hex'));\n }\n\n return createHash('sha256').update(hashes.join('')).digest('hex');\n }\n\n const content = await readFile(expandedPath);\n return createHash('sha256').update(content).digest('hex');\n};\n\nexport const getFileInfo = async (filepath: string): Promise<FileInfo> => {\n const expandedPath = expandPath(filepath);\n\n if (!(await pathExists(expandedPath))) {\n throw new FileNotFoundError(filepath);\n }\n\n try {\n const stats = await stat(expandedPath);\n const permissions = (stats.mode & 0o777).toString(8).padStart(3, '0');\n\n return {\n path: expandedPath,\n isDirectory: stats.isDirectory(),\n isSymlink: stats.isSymbolicLink(),\n size: stats.size,\n permissions,\n modified: stats.mtime,\n };\n } catch (error) {\n throw new PermissionError(filepath, 'read');\n }\n};\n\nexport const getDirectoryFiles = async (dirpath: string): Promise<string[]> => {\n const expandedPath = expandPath(dirpath);\n const files: string[] = [];\n\n const entries = await readdir(expandedPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const entryPath = join(expandedPath, entry.name);\n\n if (entry.isDirectory()) {\n const subFiles = await getDirectoryFiles(entryPath);\n files.push(...subFiles);\n } else if (entry.isFile()) {\n files.push(entryPath);\n }\n }\n\n return files.sort();\n};\n\nexport const getDirectoryFileCount = async (dirpath: string): Promise<number> => {\n const files = await getDirectoryFiles(dirpath);\n return files.length;\n};\n\nexport const copyFileOrDir = async (\n source: string,\n destination: string,\n options?: { overwrite?: boolean }\n): Promise<CopyResult> => {\n const expandedSource = expandPath(source);\n const expandedDest = expandPath(destination);\n\n if (!(await pathExists(expandedSource))) {\n throw new FileNotFoundError(source);\n }\n\n // Ensure destination directory exists\n await ensureDir(dirname(expandedDest));\n\n const sourceIsDir = await isDirectory(expandedSource);\n\n try {\n if (sourceIsDir) {\n await copy(expandedSource, expandedDest, { overwrite: options?.overwrite ?? true });\n const fileCount = await getDirectoryFileCount(expandedDest);\n const files = await getDirectoryFiles(expandedDest);\n let totalSize = 0;\n for (const file of files) {\n const stats = await stat(file);\n totalSize += stats.size;\n }\n return { source: expandedSource, destination: expandedDest, fileCount, totalSize };\n } else {\n await copyFile(expandedSource, expandedDest);\n const stats = await stat(expandedDest);\n return { source: expandedSource, destination: expandedDest, fileCount: 1, totalSize: stats.size };\n }\n } catch (error) {\n throw new PermissionError(destination, 'write');\n }\n};\n\nexport const createSymlink = async (\n target: string,\n linkPath: string,\n options?: { overwrite?: boolean }\n): Promise<void> => {\n const expandedTarget = expandPath(target);\n const expandedLink = expandPath(linkPath);\n\n if (!(await pathExists(expandedTarget))) {\n throw new FileNotFoundError(target);\n }\n\n // Ensure link parent directory exists\n await ensureDir(dirname(expandedLink));\n\n // Remove existing file/symlink if overwrite is true\n if (options?.overwrite && (await pathExists(expandedLink))) {\n await unlink(expandedLink);\n }\n\n try {\n await symlink(expandedTarget, expandedLink);\n } catch (error) {\n throw new PermissionError(linkPath, 'create symlink');\n }\n};\n\nexport const deleteFileOrDir = async (filepath: string): Promise<void> => {\n const expandedPath = expandPath(filepath);\n\n if (!(await pathExists(expandedPath))) {\n return; // Already deleted\n }\n\n try {\n if (await isDirectory(expandedPath)) {\n await rm(expandedPath, { recursive: true });\n } else {\n await unlink(expandedPath);\n }\n } catch (error) {\n throw new PermissionError(filepath, 'delete');\n }\n};\n\nexport const ensureDirectory = async (dirpath: string): Promise<void> => {\n const expandedPath = expandPath(dirpath);\n await ensureDir(expandedPath);\n};\n\nexport const moveFile = async (\n source: string,\n destination: string,\n options?: { overwrite?: boolean }\n): Promise<void> => {\n await copyFileOrDir(source, destination, options);\n await deleteFileOrDir(source);\n};\n\nexport const hasFileChanged = async (\n file1: string,\n file2: string\n): Promise<boolean> => {\n const expandedFile1 = expandPath(file1);\n const expandedFile2 = expandPath(file2);\n\n // If either doesn't exist, they're different\n if (!(await pathExists(expandedFile1)) || !(await pathExists(expandedFile2))) {\n return true;\n }\n\n const checksum1 = await getFileChecksum(expandedFile1);\n const checksum2 = await getFileChecksum(expandedFile2);\n\n return checksum1 !== checksum2;\n};\n\nexport const getFilePermissions = async (filepath: string): Promise<string> => {\n const expandedPath = expandPath(filepath);\n const stats = await stat(expandedPath);\n return (stats.mode & 0o777).toString(8).padStart(3, '0');\n};\n\nexport const setFilePermissions = async (filepath: string, mode: string): Promise<void> => {\n const expandedPath = expandPath(filepath);\n const { chmod } = await import('fs/promises');\n await chmod(expandedPath, parseInt(mode, 8));\n};\n\nexport const 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(1))} ${sizes[i]}`;\n};\n","import { Command } from 'commander';\nimport { basename } from 'path';\nimport chalk from 'chalk';\nimport { prompts, logger, withSpinner } from '../ui/index.js';\nimport {\n getTuckDir,\n expandPath,\n collapsePath,\n pathExists,\n isDirectory,\n detectCategory,\n sanitizeFilename,\n getDestinationPath,\n getRelativeDestination,\n generateFileId,\n} from '../lib/paths.js';\nimport { loadConfig } from '../lib/config.js';\nimport {\n addFileToManifest,\n isFileTracked,\n loadManifest,\n} from '../lib/manifest.js';\nimport { copyFileOrDir, getFileChecksum, getDirectoryFileCount, getFileInfo } from '../lib/files.js';\nimport { NotInitializedError, FileNotFoundError, FileAlreadyTrackedError } from '../errors.js';\nimport { CATEGORIES } from '../constants.js';\nimport type { AddOptions } from '../types.js';\n\n// SSH private key patterns - NEVER allow these\nconst PRIVATE_KEY_PATTERNS = [\n /^id_rsa$/,\n /^id_dsa$/,\n /^id_ecdsa$/,\n /^id_ed25519$/,\n /^id_.*$/, // Any id_ file without .pub\n /\\.pem$/,\n /\\.key$/,\n /^.*_key$/, // aws_key, github_key, etc.\n];\n\n// Files that should trigger a warning\nconst SENSITIVE_FILE_PATTERNS = [\n /^\\.netrc$/,\n /^\\.aws\\/credentials$/,\n /^\\.docker\\/config\\.json$/,\n /^\\.npmrc$/, // May contain tokens\n /^\\.pypirc$/,\n /^\\.kube\\/config$/,\n /^\\.ssh\\/config$/,\n /^\\.gnupg\\//,\n /credentials/i,\n /secrets?/i,\n /tokens?\\.json$/i,\n /\\.env$/,\n /\\.env\\./,\n];\n\n/**\n * Check if a path is a private key (should never be tracked)\n */\nconst isPrivateKey = (path: string): boolean => {\n const name = basename(path);\n\n // SSH private keys (without .pub extension)\n if (path.includes('.ssh/') && !name.endsWith('.pub')) {\n for (const pattern of PRIVATE_KEY_PATTERNS) {\n if (pattern.test(name)) {\n return true;\n }\n }\n }\n\n // Other private key patterns\n if (name.endsWith('.pem') || name.endsWith('.key')) {\n return true;\n }\n\n return false;\n};\n\n/**\n * Check if a path contains potentially sensitive data\n */\nconst isSensitiveFile = (path: string): boolean => {\n // Strip ~/ prefix if present, since patterns with ^ anchor expect paths without it\n // e.g., ~/.netrc should match /^\\.netrc$/ pattern\n const pathToTest = path.startsWith('~/') ? path.slice(2) : path;\n\n for (const pattern of SENSITIVE_FILE_PATTERNS) {\n if (pattern.test(pathToTest)) {\n return true;\n }\n }\n return false;\n};\n\ninterface FileToAdd {\n source: string;\n destination: string;\n category: string;\n filename: string;\n isDir: boolean;\n fileCount: number;\n sensitive: boolean;\n}\n\nconst validateAndPrepareFiles = async (\n paths: string[],\n tuckDir: string,\n options: AddOptions\n): Promise<FileToAdd[]> => {\n const filesToAdd: FileToAdd[] = [];\n\n for (const path of paths) {\n const expandedPath = expandPath(path);\n const collapsedPath = collapsePath(expandedPath);\n\n // SECURITY: Block private keys\n if (isPrivateKey(collapsedPath)) {\n throw new Error(\n `Cannot track private key: ${path}\\n` +\n `Private keys should NEVER be committed to a repository.\\n` +\n `If you need to backup SSH keys, use a secure password manager.`\n );\n }\n\n // Check if file exists\n if (!(await pathExists(expandedPath))) {\n throw new FileNotFoundError(path);\n }\n\n // Check if already tracked\n if (await isFileTracked(tuckDir, collapsedPath)) {\n throw new FileAlreadyTrackedError(path);\n }\n\n // Determine if it's a directory\n const isDir = await isDirectory(expandedPath);\n const fileCount = isDir ? await getDirectoryFileCount(expandedPath) : 1;\n\n // Determine category\n const category = options.category || detectCategory(expandedPath);\n\n // Generate filename for storage\n const filename = options.name || sanitizeFilename(expandedPath);\n\n // Determine destination path\n const destination = getDestinationPath(tuckDir, category, filename);\n\n // Check if sensitive\n const sensitive = isSensitiveFile(collapsedPath);\n\n filesToAdd.push({\n source: collapsedPath,\n destination,\n category,\n filename,\n isDir,\n fileCount,\n sensitive,\n });\n }\n\n return filesToAdd;\n};\n\nconst addFiles = async (\n filesToAdd: FileToAdd[],\n tuckDir: string,\n options: AddOptions\n): Promise<void> => {\n const config = await loadConfig(tuckDir);\n const strategy = options.symlink ? 'symlink' : (config.files.strategy || 'copy');\n\n for (const file of filesToAdd) {\n const expandedSource = expandPath(file.source);\n\n // Copy file to repository\n await withSpinner(`Copying ${file.source}...`, async () => {\n await copyFileOrDir(expandedSource, file.destination, { overwrite: true });\n });\n\n // Get file info\n const checksum = await getFileChecksum(file.destination);\n const info = await getFileInfo(expandedSource);\n const now = new Date().toISOString();\n\n // Generate unique ID\n const id = generateFileId(file.source);\n\n // Add to manifest\n await addFileToManifest(tuckDir, id, {\n source: file.source,\n destination: getRelativeDestination(file.category, file.filename),\n category: file.category,\n strategy,\n encrypted: options.encrypt || false,\n template: options.template || false,\n permissions: info.permissions,\n added: now,\n modified: now,\n checksum,\n });\n\n // Log result\n const categoryInfo = CATEGORIES[file.category];\n const icon = categoryInfo?.icon || '-';\n logger.success(`Added ${file.source}`);\n logger.dim(` ${icon} Category: ${file.category}`);\n if (file.isDir) {\n logger.dim(` [dir] Directory with ${file.fileCount} files`);\n }\n\n // Warn about sensitive files\n if (file.sensitive) {\n console.log(chalk.yellow(` [!] Warning: This file may contain sensitive data`));\n console.log(chalk.dim(` Make sure your repository is private!`));\n }\n }\n};\n\nconst runInteractiveAdd = async (tuckDir: string): Promise<void> => {\n prompts.intro('tuck add');\n\n // Ask for paths\n const pathsInput = await prompts.text('Enter file paths to track (space-separated):', {\n placeholder: '~/.zshrc ~/.gitconfig',\n validate: (value) => {\n if (!value.trim()) return 'At least one path is required';\n return undefined;\n },\n });\n\n const paths = pathsInput.split(/\\s+/).filter(Boolean);\n\n // Validate and prepare\n let filesToAdd: FileToAdd[];\n try {\n filesToAdd = await validateAndPrepareFiles(paths, tuckDir, {});\n } catch (error) {\n if (error instanceof Error) {\n prompts.log.error(error.message);\n }\n prompts.cancel();\n return;\n }\n\n // Show what will be added and ask for category confirmation\n for (const file of filesToAdd) {\n prompts.log.step(`${file.source}`);\n\n const categoryOptions = Object.entries(CATEGORIES).map(([name, config]) => ({\n value: name,\n label: `${config.icon} ${name}`,\n hint: file.category === name ? '(auto-detected)' : undefined,\n }));\n\n // Move detected category to top\n categoryOptions.sort((a, b) => {\n if (a.value === file.category) return -1;\n if (b.value === file.category) return 1;\n return 0;\n });\n\n const selectedCategory = await prompts.select('Category:', categoryOptions);\n file.category = selectedCategory as string;\n\n // Update destination with new category\n file.destination = getDestinationPath(tuckDir, file.category, file.filename);\n }\n\n // Confirm\n const confirm = await prompts.confirm(\n `Add ${filesToAdd.length} ${filesToAdd.length === 1 ? 'file' : 'files'}?`,\n true\n );\n\n if (!confirm) {\n prompts.cancel('Operation cancelled');\n return;\n }\n\n // Add files\n await addFiles(filesToAdd, tuckDir, {});\n\n prompts.outro(`Added ${filesToAdd.length} ${filesToAdd.length === 1 ? 'file' : 'files'}`);\n logger.info(\"Run 'tuck sync' to commit changes\");\n};\n\n/**\n * Add files programmatically (used by scan command)\n */\nexport const addFilesFromPaths = async (paths: string[], options: AddOptions = {}): Promise<number> => {\n const tuckDir = getTuckDir();\n\n // Verify tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n // Validate and prepare files\n const filesToAdd = await validateAndPrepareFiles(paths, tuckDir, options);\n\n // Add files\n await addFiles(filesToAdd, tuckDir, options);\n\n return filesToAdd.length;\n};\n\nconst runAdd = async (paths: string[], options: AddOptions): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Verify tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n if (paths.length === 0) {\n await runInteractiveAdd(tuckDir);\n return;\n }\n\n // Validate and prepare files\n const filesToAdd = await validateAndPrepareFiles(paths, tuckDir, options);\n\n // Add files\n await addFiles(filesToAdd, tuckDir, options);\n\n logger.blank();\n logger.success(`Added ${filesToAdd.length} ${filesToAdd.length === 1 ? 'item' : 'items'}`);\n logger.info(\"Run 'tuck sync' to commit changes\");\n};\n\nexport const addCommand = new Command('add')\n .description('Track new dotfiles')\n .argument('[paths...]', 'Paths to dotfiles to track')\n .option('-c, --category <name>', 'Category to organize under')\n .option('-n, --name <name>', 'Custom name for the file in manifest')\n .option('--symlink', 'Create symlink instead of copy')\n .option('--encrypt', 'Encrypt this file (requires GPG setup)')\n .option('--template', 'Treat as template with variable substitution')\n .action(async (paths: string[], options: AddOptions) => {\n await runAdd(paths, options);\n });\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport {\n initCommand,\n addCommand,\n removeCommand,\n syncCommand,\n pushCommand,\n pullCommand,\n restoreCommand,\n statusCommand,\n listCommand,\n diffCommand,\n configCommand,\n applyCommand,\n undoCommand,\n scanCommand,\n} from './commands/index.js';\nimport { handleError } from './errors.js';\nimport { VERSION, DESCRIPTION } from './constants.js';\nimport { customHelp, miniBanner } from './ui/banner.js';\nimport { getTuckDir, pathExists } from './lib/paths.js';\nimport { loadManifest } from './lib/manifest.js';\nimport { getStatus } from './lib/git.js';\n\nconst program = new Command();\n\nprogram\n .name('tuck')\n .description(DESCRIPTION)\n .version(VERSION, '-v, --version', 'Display version number')\n .configureOutput({\n outputError: (str, write) => write(chalk.red(str)),\n })\n .addHelpText('beforeAll', customHelp(VERSION))\n .helpOption('-h, --help', 'Display this help message')\n .showHelpAfterError(false);\n\n// Override default help to use our custom version\nprogram.configureHelp({\n formatHelp: () => '',\n});\n\n// Register commands\nprogram.addCommand(initCommand);\nprogram.addCommand(addCommand);\nprogram.addCommand(removeCommand);\nprogram.addCommand(syncCommand);\nprogram.addCommand(pushCommand);\nprogram.addCommand(pullCommand);\nprogram.addCommand(restoreCommand);\nprogram.addCommand(statusCommand);\nprogram.addCommand(listCommand);\nprogram.addCommand(diffCommand);\nprogram.addCommand(configCommand);\nprogram.addCommand(applyCommand);\nprogram.addCommand(undoCommand);\nprogram.addCommand(scanCommand);\n\n// Default action when no command is provided\nconst runDefaultAction = async (): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Check if tuck is initialized\n if (!(await pathExists(tuckDir))) {\n miniBanner();\n console.log(chalk.bold('Get started with tuck:\\n'));\n console.log(chalk.cyan(' tuck init') + chalk.dim(' - Set up tuck and create a GitHub repo'));\n console.log(chalk.cyan(' tuck scan') + chalk.dim(' - Find dotfiles to track'));\n console.log();\n console.log(chalk.dim('On a new machine:'));\n console.log(chalk.cyan(' tuck apply <username>') + chalk.dim(' - Apply your dotfiles'));\n console.log();\n return;\n }\n\n // Load manifest to check status\n try {\n const manifest = await loadManifest(tuckDir);\n const trackedCount = Object.keys(manifest.files).length;\n const gitStatus = await getStatus(tuckDir);\n\n miniBanner();\n console.log(chalk.bold('Status:\\n'));\n\n // Show tracked files count\n console.log(` Tracked files: ${chalk.cyan(trackedCount.toString())}`);\n\n // Show git status\n const pendingChanges = gitStatus.modified.length + gitStatus.staged.length;\n if (pendingChanges > 0) {\n console.log(` Pending changes: ${chalk.yellow(pendingChanges.toString())}`);\n } else {\n console.log(` Pending changes: ${chalk.dim('none')}`);\n }\n\n // Show remote status\n if (gitStatus.ahead > 0) {\n console.log(` Commits to push: ${chalk.yellow(gitStatus.ahead.toString())}`);\n }\n\n console.log();\n\n // Show what to do next\n console.log(chalk.bold('Next steps:\\n'));\n\n if (trackedCount === 0) {\n console.log(chalk.cyan(' tuck scan') + chalk.dim(' - Find dotfiles to track'));\n console.log(chalk.cyan(' tuck add <file>') + chalk.dim(' - Track a specific file'));\n } else if (pendingChanges > 0) {\n console.log(chalk.cyan(' tuck sync') + chalk.dim(' - Commit and push your changes'));\n console.log(chalk.cyan(' tuck diff') + chalk.dim(' - Preview what changed'));\n } else if (gitStatus.ahead > 0) {\n console.log(chalk.cyan(' tuck push') + chalk.dim(' - Push commits to GitHub'));\n } else {\n console.log(chalk.dim(' All synced! Your dotfiles are up to date.'));\n console.log();\n console.log(chalk.cyan(' tuck scan') + chalk.dim(' - Find more dotfiles to track'));\n console.log(chalk.cyan(' tuck list') + chalk.dim(' - See tracked files'));\n }\n\n console.log();\n } catch {\n // Manifest load failed, treat as not initialized\n miniBanner();\n console.log(chalk.yellow('Tuck directory exists but may be corrupted.'));\n console.log(chalk.dim('Run `tuck init` to reinitialize.'));\n console.log();\n }\n};\n\n// Check if no command provided\nconst hasCommand = process.argv.slice(2).some(\n (arg) => !arg.startsWith('-') && arg !== '--help' && arg !== '-h'\n);\n\n// Global error handling\nprocess.on('uncaughtException', handleError);\nprocess.on('unhandledRejection', (reason) => {\n handleError(reason instanceof Error ? reason : new Error(String(reason)));\n});\n\n// Parse and execute\nif (!hasCommand && !process.argv.includes('--help') && !process.argv.includes('-h') && !process.argv.includes('--version') && !process.argv.includes('-v')) {\n runDefaultAction().catch(handleError);\n} else {\n program.parseAsync(process.argv).catch(handleError);\n}\n","import { Command } from 'commander';\nimport { join, resolve, sep } from 'path';\nimport { writeFile } from 'fs/promises';\nimport { ensureDir } from 'fs-extra';\nimport { banner, nextSteps, prompts, withSpinner, logger } from '../ui/index.js';\nimport {\n getTuckDir,\n getManifestPath,\n getConfigPath,\n getFilesDir,\n getCategoryDir,\n pathExists,\n expandPath,\n collapsePath,\n validateSafeSourcePath,\n} from '../lib/paths.js';\nimport { saveConfig } from '../lib/config.js';\nimport { createManifest } from '../lib/manifest.js';\nimport type { TuckManifest } from '../types.js';\nimport { initRepo, addRemote, cloneRepo, setDefaultBranch, stageAll, commit, push } from '../lib/git.js';\nimport {\n isGhInstalled,\n isGhAuthenticated,\n getAuthenticatedUser,\n createRepo,\n getPreferredRepoUrl,\n findDotfilesRepo,\n ghCloneRepo,\n} from '../lib/github.js';\nimport { detectDotfiles, DetectedFile, DETECTION_CATEGORIES } from '../lib/detect.js';\nimport { createPreApplySnapshot } from '../lib/timemachine.js';\nimport { copy } from 'fs-extra';\nimport { tmpdir } from 'os';\nimport { readFile, rm } from 'fs/promises';\nimport { AlreadyInitializedError } from '../errors.js';\nimport { CATEGORIES, COMMON_DOTFILES } from '../constants.js';\nimport { defaultConfig } from '../schemas/config.schema.js';\nimport type { InitOptions } from '../types.js';\n\nconst GITIGNORE_TEMPLATE = `# OS generated files\n.DS_Store\n.DS_Store?\n._*\n.Spotlight-V100\n.Trashes\nehthumbs.db\nThumbs.db\n\n# Backup files\n*.bak\n*.backup\n*~\n\n# Secret files (add patterns for files you want to exclude)\n# *.secret\n# .env.local\n`;\n\nconst README_TEMPLATE = (machine?: string) => `# Dotfiles\n\nManaged with [tuck](https://github.com/Pranav-Karra-3301/tuck) - Modern Dotfiles Manager\n\n${machine ? `## Machine: ${machine}\\n` : ''}\n\n## Quick Start\n\n\\`\\`\\`bash\n# Restore dotfiles to a new machine\ntuck init --from <this-repo-url>\n\n# Or clone and restore manually\ngit clone <this-repo-url> ~/.tuck\ntuck restore --all\n\\`\\`\\`\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| \\`tuck add <paths>\\` | Track new dotfiles |\n| \\`tuck sync\\` | Sync changes to repository |\n| \\`tuck push\\` | Push to remote |\n| \\`tuck pull\\` | Pull from remote |\n| \\`tuck restore\\` | Restore dotfiles to system |\n| \\`tuck status\\` | Show tracking status |\n| \\`tuck list\\` | List tracked files |\n\n## Structure\n\n\\`\\`\\`\n.tuck/\n├── files/ # Tracked dotfiles organized by category\n│ ├── shell/ # Shell configs (.zshrc, .bashrc, etc.)\n│ ├── git/ # Git configs (.gitconfig, etc.)\n│ ├── editors/ # Editor configs (nvim, vim, etc.)\n│ ├── terminal/ # Terminal configs (tmux, alacritty, etc.)\n│ └── misc/ # Other dotfiles\n├── .tuckmanifest.json # Tracks all managed files\n└── .tuckrc.json # Tuck configuration\n\\`\\`\\`\n`;\n\nconst createDirectoryStructure = async (tuckDir: string): Promise<void> => {\n // Create main directories\n await ensureDir(tuckDir);\n await ensureDir(getFilesDir(tuckDir));\n\n // Create category directories\n for (const category of Object.keys(CATEGORIES)) {\n await ensureDir(getCategoryDir(tuckDir, category));\n }\n};\n\nconst createDefaultFiles = async (tuckDir: string, machine?: string): Promise<void> => {\n // Create .gitignore only if it doesn't exist\n const gitignorePath = join(tuckDir, '.gitignore');\n if (!(await pathExists(gitignorePath))) {\n await writeFile(gitignorePath, GITIGNORE_TEMPLATE, 'utf-8');\n }\n\n // Create README.md only if it doesn't exist\n const readmePath = join(tuckDir, 'README.md');\n if (!(await pathExists(readmePath))) {\n await writeFile(readmePath, README_TEMPLATE(machine), 'utf-8');\n }\n};\n\nconst initFromScratch = async (\n tuckDir: string,\n options: { remote?: string; bare?: boolean }\n): Promise<void> => {\n // Check if already initialized\n if (await pathExists(getManifestPath(tuckDir))) {\n throw new AlreadyInitializedError(tuckDir);\n }\n\n // Create directory structure\n await withSpinner('Creating directory structure...', async () => {\n await createDirectoryStructure(tuckDir);\n });\n\n // Initialize git repository\n await withSpinner('Initializing git repository...', async () => {\n await initRepo(tuckDir);\n await setDefaultBranch(tuckDir, 'main');\n });\n\n // Create manifest\n await withSpinner('Creating manifest...', async () => {\n const hostname = (await import('os')).hostname();\n await createManifest(tuckDir, hostname);\n });\n\n // Create config\n await withSpinner('Creating configuration...', async () => {\n await saveConfig(\n {\n ...defaultConfig,\n repository: { ...defaultConfig.repository, path: tuckDir },\n },\n tuckDir\n );\n });\n\n // Create default files unless --bare\n if (!options.bare) {\n await withSpinner('Creating default files...', async () => {\n const hostname = (await import('os')).hostname();\n await createDefaultFiles(tuckDir, hostname);\n });\n }\n\n // Add remote if provided\n if (options.remote) {\n await withSpinner('Adding remote...', async () => {\n await addRemote(tuckDir, 'origin', options.remote!);\n });\n }\n};\n\ninterface GitHubSetupResult {\n remoteUrl: string | null;\n pushed: boolean;\n}\n\nconst setupGitHubRepo = async (tuckDir: string): Promise<GitHubSetupResult> => {\n // Check if GitHub CLI is available\n const ghInstalled = await isGhInstalled();\n if (!ghInstalled) {\n prompts.log.info('GitHub CLI (gh) is not installed');\n prompts.log.info('Install it from https://cli.github.com/ for auto-setup');\n return { remoteUrl: null, pushed: false };\n }\n\n const ghAuth = await isGhAuthenticated();\n if (!ghAuth) {\n prompts.log.info('GitHub CLI is not authenticated');\n prompts.log.info('Run `gh auth login` to enable auto-setup');\n return { remoteUrl: null, pushed: false };\n }\n\n // Get authenticated user\n const user = await getAuthenticatedUser();\n prompts.log.success(`Detected GitHub account: ${user.login}`);\n\n // Ask if they want to auto-create repo\n const createGhRepo = await prompts.confirm('Create a GitHub repository automatically?', true);\n\n if (!createGhRepo) {\n return { remoteUrl: null, pushed: false };\n }\n\n // Ask for repo name\n const repoName = await prompts.text('Repository name:', {\n defaultValue: 'dotfiles',\n placeholder: 'dotfiles',\n validate: (value) => {\n if (!value) return 'Repository name is required';\n if (!/^[a-zA-Z0-9._-]+$/.test(value)) {\n return 'Invalid repository name';\n }\n return undefined;\n },\n });\n\n // Ask for visibility\n const visibility = await prompts.select('Repository visibility:', [\n { value: 'private', label: 'Private (recommended)', hint: 'Only you can see it' },\n { value: 'public', label: 'Public', hint: 'Anyone can see it' },\n ]);\n\n // Create the repository\n let repo;\n try {\n const spinner = prompts.spinner();\n spinner.start(`Creating repository ${user.login}/${repoName}...`);\n\n repo = await createRepo({\n name: repoName,\n description: 'My dotfiles managed with tuck',\n isPrivate: visibility === 'private',\n });\n\n spinner.stop(`Repository created: ${repo.fullName}`);\n } catch (error) {\n prompts.log.error(`Failed to create repository: ${error instanceof Error ? error.message : String(error)}`);\n return { remoteUrl: null, pushed: false };\n }\n\n // Get the remote URL in preferred format\n const remoteUrl = await getPreferredRepoUrl(repo);\n\n // Add as remote\n await addRemote(tuckDir, 'origin', remoteUrl);\n prompts.log.success('Remote origin configured');\n\n // Ask to push initial commit\n const shouldPush = await prompts.confirm('Push initial commit to GitHub?', true);\n\n if (shouldPush) {\n try {\n const spinner = prompts.spinner();\n spinner.start('Creating initial commit...');\n\n await stageAll(tuckDir);\n await commit(tuckDir, 'Initial commit: tuck dotfiles setup');\n\n spinner.stop('Initial commit created');\n\n spinner.start('Pushing to GitHub...');\n await push(tuckDir, { remote: 'origin', branch: 'main', setUpstream: true });\n spinner.stop('Pushed to GitHub');\n\n prompts.note(\n `Your dotfiles are now at:\\n${repo.url}\\n\\nOn a new machine, run:\\ntuck apply ${user.login}`,\n 'Success'\n );\n\n return { remoteUrl, pushed: true };\n } catch (error) {\n prompts.log.error(`Failed to push: ${error instanceof Error ? error.message : String(error)}`);\n return { remoteUrl, pushed: false };\n }\n }\n\n return { remoteUrl, pushed: false };\n};\n\ntype RepositoryAnalysis =\n | { type: 'valid-tuck'; manifest: TuckManifest }\n | { type: 'plain-dotfiles'; files: DetectedFile[] }\n | { type: 'messed-up'; reason: string };\n\n/**\n * Analyze a cloned repository to determine its state\n */\nconst analyzeRepository = async (repoDir: string): Promise<RepositoryAnalysis> => {\n const manifestPath = join(repoDir, '.tuckmanifest.json');\n\n // Check for valid tuck manifest\n if (await pathExists(manifestPath)) {\n try {\n const content = await readFile(manifestPath, 'utf-8');\n const manifest = JSON.parse(content) as TuckManifest;\n\n // Validate manifest has files\n if (manifest.files && Object.keys(manifest.files).length > 0) {\n return { type: 'valid-tuck', manifest };\n }\n\n // Manifest exists but is empty\n return { type: 'messed-up', reason: 'Manifest exists but contains no tracked files' };\n } catch {\n return { type: 'messed-up', reason: 'Manifest file is corrupted or invalid' };\n }\n }\n\n // No manifest - check for common dotfiles in the files directory or root\n const filesDir = join(repoDir, 'files');\n const hasFilesDir = await pathExists(filesDir);\n\n // Look for common dotfile patterns in the repo\n const commonPatterns = [\n '.zshrc', '.bashrc', '.bash_profile', '.gitconfig', '.vimrc',\n '.tmux.conf', '.profile', 'zshrc', 'bashrc', 'gitconfig', 'vimrc',\n ];\n\n const foundFiles: string[] = [];\n\n // Check in files directory if it exists\n if (hasFilesDir) {\n const { readdir } = await import('fs/promises');\n try {\n const categories = await readdir(filesDir);\n for (const category of categories) {\n const categoryPath = join(filesDir, category);\n const categoryStats = await import('fs/promises').then((fs) => fs.stat(categoryPath).catch(() => null));\n if (categoryStats?.isDirectory()) {\n const files = await readdir(categoryPath);\n foundFiles.push(...files);\n }\n }\n } catch {\n // Ignore errors\n }\n }\n\n // Check root directory\n const { readdir } = await import('fs/promises');\n try {\n const rootFiles = await readdir(repoDir);\n for (const file of rootFiles) {\n if (commonPatterns.some((p) => file.includes(p) || file.startsWith('.'))) {\n foundFiles.push(file);\n }\n }\n } catch {\n // Ignore errors\n }\n\n // Filter to meaningful dotfiles (not just .git, README, etc.)\n const meaningfulFiles = foundFiles.filter(\n (f) => !['README.md', 'README', '.git', '.gitignore', 'LICENSE', '.tuckrc.json'].includes(f)\n );\n\n if (meaningfulFiles.length > 0) {\n // Run detection on user's system and show what would be tracked\n const detectedOnSystem = await detectDotfiles();\n return { type: 'plain-dotfiles', files: detectedOnSystem };\n }\n\n // Check if repo is essentially empty (only has README, .git, etc.)\n const { readdir: rd } = await import('fs/promises');\n try {\n const allFiles = await rd(repoDir);\n const nonEssentialFiles = allFiles.filter(\n (f) => !['.git', 'README.md', 'README', 'LICENSE', '.gitignore'].includes(f)\n );\n if (nonEssentialFiles.length === 0) {\n return { type: 'messed-up', reason: 'Repository is empty (only contains README or license)' };\n }\n } catch {\n // Ignore\n }\n\n return { type: 'messed-up', reason: 'Repository does not contain recognizable dotfiles' };\n};\n\ninterface ImportResult {\n success: boolean;\n filesInRepo: number; // Files imported to ~/.tuck\n filesApplied: number; // Files applied to system (0 if user declined)\n remoteUrl?: string;\n}\n\n/**\n * Validate that a destination path stays within the tuck directory\n * Prevents path traversal attacks via malicious manifest files\n */\nconst validateDestinationPath = (tuckDir: string, destination: string): boolean => {\n const fullPath = resolve(join(tuckDir, destination));\n const normalizedTuckDir = resolve(tuckDir);\n // Ensure the resolved path starts with tuckDir + separator to prevent escaping\n return fullPath.startsWith(normalizedTuckDir + sep) || fullPath === normalizedTuckDir;\n};\n\n/**\n * Import an existing GitHub dotfiles repository\n */\nconst importExistingRepo = async (\n tuckDir: string,\n repoName: string,\n analysis: RepositoryAnalysis,\n repoDir: string\n): Promise<ImportResult> => {\n const { getPreferredRemoteProtocol } = await import('../lib/github.js');\n const protocol = await getPreferredRemoteProtocol();\n const remoteUrl = protocol === 'ssh'\n ? `git@github.com:${repoName}.git`\n : `https://github.com/${repoName}.git`;\n\n if (analysis.type === 'valid-tuck') {\n // Scenario A: Valid tuck repository - full import\n prompts.log.step('Importing tuck repository...');\n\n // Copy the entire repo to tuck directory\n const spinner = prompts.spinner();\n spinner.start('Copying repository...');\n\n // Copy files from cloned repo to tuck directory\n await copy(repoDir, tuckDir, { overwrite: true });\n\n spinner.stop('Repository copied');\n\n // Get file count\n const fileCount = Object.keys(analysis.manifest.files).length;\n\n // Track how many files are actually applied to the system\n let appliedCount = 0;\n\n // Apply dotfiles to system with merge strategy\n const shouldApply = await prompts.confirm(\n `Apply ${fileCount} dotfiles to your system?`,\n true\n );\n\n if (shouldApply) {\n // Validate and filter files once to avoid duplicate warnings\n const validFiles: Array<typeof analysis.manifest.files[string]> = [];\n for (const [_id, file] of Object.entries(analysis.manifest.files)) {\n // Validate that the source path is safe (within home directory)\n // This prevents malicious manifests from writing to arbitrary locations\n try {\n validateSafeSourcePath(file.source);\n } catch (error) {\n prompts.log.warning(`Skipping unsafe source path from manifest: ${file.source}`);\n continue;\n }\n\n // Validate that the destination path stays within tuckDir\n // This prevents path traversal attacks reading files from outside the repo\n if (!validateDestinationPath(tuckDir, file.destination)) {\n prompts.log.warning(`Skipping unsafe destination path from manifest: ${file.destination}`);\n continue;\n }\n\n validFiles.push(file);\n }\n\n // Create backup before applying\n const existingPaths: string[] = [];\n for (const file of validFiles) {\n const destPath = expandPath(file.source);\n if (await pathExists(destPath)) {\n existingPaths.push(destPath);\n }\n }\n\n if (existingPaths.length > 0) {\n const backupSpinner = prompts.spinner();\n backupSpinner.start('Creating backup of existing files...');\n await createPreApplySnapshot(existingPaths, repoName);\n backupSpinner.stop('Backup created');\n }\n\n // Apply files using the pre-validated list\n const applySpinner = prompts.spinner();\n applySpinner.start('Applying dotfiles...');\n\n for (const file of validFiles) {\n const repoFilePath = join(tuckDir, file.destination);\n const destPath = expandPath(file.source);\n\n if (await pathExists(repoFilePath)) {\n // Ensure destination directory exists\n const destDir = join(destPath, '..');\n await ensureDir(destDir);\n\n // Copy file\n await copy(repoFilePath, destPath, { overwrite: true });\n appliedCount++;\n }\n }\n\n applySpinner.stop(`Applied ${appliedCount} dotfiles`);\n }\n\n // Return both the number of files in the repo and the number applied to system\n // filesInRepo: total files imported to ~/.tuck (always happens)\n // filesApplied: files actually applied to system (0 if user declined)\n return { success: true, filesInRepo: fileCount, filesApplied: appliedCount, remoteUrl };\n }\n\n if (analysis.type === 'plain-dotfiles') {\n // Scenario B: Plain dotfiles repository - copy contents and initialize tuck\n prompts.log.step('Repository contains dotfiles but no tuck manifest');\n prompts.log.info('Importing repository and setting up tuck...');\n\n // Copy the repository contents to tuck directory first (preserving existing files)\n const copySpinner = prompts.spinner();\n copySpinner.start('Copying repository contents...');\n await copy(repoDir, tuckDir, { overwrite: true });\n copySpinner.stop('Repository contents copied');\n\n // Now initialize git and create tuck config on top of the copied files\n // Note: The .git directory was copied, so we don't need to reinitialize\n await setDefaultBranch(tuckDir, 'main');\n\n const hostname = (await import('os')).hostname();\n await createManifest(tuckDir, hostname);\n await saveConfig(\n {\n ...defaultConfig,\n repository: { ...defaultConfig.repository, path: tuckDir },\n },\n tuckDir\n );\n\n // Create directory structure for categories (if not already present)\n await createDirectoryStructure(tuckDir);\n await createDefaultFiles(tuckDir, hostname);\n\n // Update remote to use the correct URL (may differ from cloned URL)\n try {\n // Remove existing origin if present and add the correct one\n const { removeRemote } = await import('../lib/git.js');\n await removeRemote(tuckDir, 'origin').catch(() => { /* ignore if not exists */ });\n await addRemote(tuckDir, 'origin', remoteUrl);\n } catch {\n // If removing fails, try adding anyway\n await addRemote(tuckDir, 'origin', remoteUrl).catch(() => { /* ignore if already exists */ });\n }\n\n // Detect dotfiles on system that could be tracked\n const detected = analysis.files.filter((f) => !f.sensitive);\n\n console.log();\n prompts.log.success('Repository imported to ~/.tuck');\n prompts.log.info(\"The repository's files are now in your tuck directory.\");\n\n if (detected.length > 0) {\n console.log();\n prompts.log.info(`Found ${detected.length} dotfiles on your system that could be tracked`);\n\n const trackNow = await prompts.confirm('Would you like to add some of these to tuck?', true);\n\n if (trackNow) {\n // Group by category for display\n const grouped: Record<string, DetectedFile[]> = {};\n for (const file of detected) {\n if (!grouped[file.category]) grouped[file.category] = [];\n grouped[file.category].push(file);\n }\n\n // Show categories\n console.log();\n for (const [category, files] of Object.entries(grouped)) {\n const config = DETECTION_CATEGORIES[category] || { icon: '-', name: category };\n console.log(` ${config.icon} ${config.name}: ${files.length} files`);\n }\n\n console.log();\n prompts.log.info(\"Run 'tuck scan' to interactively select files to track\");\n prompts.log.info(\"Or run 'tuck add <path>' to add specific files\");\n }\n }\n\n // Count the files that were copied (excluding .git and tuck config files)\n let importedCount = 0;\n const { readdir, stat } = await import('fs/promises');\n try {\n const countFiles = async (dir: string): Promise<number> => {\n let count = 0;\n const entries = await readdir(dir);\n for (const entry of entries) {\n if (entry === '.git' || entry === '.tuckmanifest.json' || entry === '.tuckrc.json') continue;\n const fullPath = join(dir, entry);\n const stats = await stat(fullPath).catch(() => null);\n if (stats?.isDirectory()) {\n count += await countFiles(fullPath);\n } else if (stats?.isFile()) {\n count++;\n }\n }\n return count;\n };\n importedCount = await countFiles(tuckDir);\n } catch {\n // Ignore counting errors\n }\n\n // For plain-dotfiles, importedCount represents files copied to ~/.tuck\n // No files are applied to system in this flow (user needs to add them manually)\n return { success: true, filesInRepo: importedCount, filesApplied: 0, remoteUrl };\n }\n\n // Scenario C: Messed up repository\n prompts.log.warning(`Repository issue: ${analysis.reason}`);\n console.log();\n\n const action = await prompts.select('How would you like to proceed?', [\n {\n value: 'fresh',\n label: 'Start fresh',\n hint: 'Initialize tuck and set this repo as remote (will overwrite on push)',\n },\n {\n value: 'remote-only',\n label: 'Set as remote only',\n hint: 'Initialize tuck locally, keep existing repo contents',\n },\n {\n value: 'cancel',\n label: 'Cancel',\n hint: 'Inspect the repository manually first',\n },\n ]);\n\n if (action === 'cancel') {\n return { success: false, filesInRepo: 0, filesApplied: 0 };\n }\n\n // Initialize tuck\n await createDirectoryStructure(tuckDir);\n await initRepo(tuckDir);\n await setDefaultBranch(tuckDir, 'main');\n\n const hostname = (await import('os')).hostname();\n await createManifest(tuckDir, hostname);\n await saveConfig(\n {\n ...defaultConfig,\n repository: { ...defaultConfig.repository, path: tuckDir },\n },\n tuckDir\n );\n await createDefaultFiles(tuckDir, hostname);\n\n // Set up remote\n await addRemote(tuckDir, 'origin', remoteUrl);\n\n if (action === 'fresh') {\n prompts.log.info('Tuck initialized. When you push, it will replace the repository contents.');\n prompts.log.info(\"Run 'tuck add' to track files, then 'tuck sync && tuck push --force' to update remote\");\n } else {\n prompts.log.info('Tuck initialized with remote configured');\n prompts.log.info(\"Run 'tuck add' to start tracking files\");\n }\n\n // For messed-up repos, no files are imported or applied\n return { success: true, filesInRepo: 0, filesApplied: 0, remoteUrl };\n};\n\nconst initFromRemote = async (tuckDir: string, remoteUrl: string): Promise<void> => {\n // Clone the repository\n await withSpinner(`Cloning from ${remoteUrl}...`, async () => {\n await cloneRepo(remoteUrl, tuckDir);\n });\n\n // Verify manifest exists\n if (!(await pathExists(getManifestPath(tuckDir)))) {\n logger.warning('No manifest found in cloned repository. Creating new manifest...');\n const hostname = (await import('os')).hostname();\n await createManifest(tuckDir, hostname);\n }\n\n // Verify config exists\n if (!(await pathExists(getConfigPath(tuckDir)))) {\n logger.warning('No config found in cloned repository. Creating default config...');\n await saveConfig(\n {\n ...defaultConfig,\n repository: { ...defaultConfig.repository, path: tuckDir },\n },\n tuckDir\n );\n }\n};\n\nconst runInteractiveInit = async (): Promise<void> => {\n banner();\n prompts.intro('tuck init');\n\n // Ask for tuck directory\n const dirInput = await prompts.text('Where should tuck store your dotfiles?', {\n defaultValue: '~/.tuck',\n });\n const tuckDir = getTuckDir(dirInput);\n\n // Check if already initialized\n if (await pathExists(getManifestPath(tuckDir))) {\n prompts.log.error(`Tuck is already initialized at ${collapsePath(tuckDir)}`);\n prompts.outro('Use `tuck status` to see current state');\n return;\n }\n\n // Auto-detect existing GitHub dotfiles repository\n const ghInstalled = await isGhInstalled();\n const ghAuth = ghInstalled && (await isGhAuthenticated());\n\n if (ghAuth) {\n const spinner = prompts.spinner();\n spinner.start('Checking for existing dotfiles repository on GitHub...');\n\n try {\n const user = await getAuthenticatedUser();\n const existingRepoName = await findDotfilesRepo(user.login);\n\n if (existingRepoName) {\n spinner.stop(`Found repository: ${existingRepoName}`);\n\n const importRepo = await prompts.confirm(\n `Import dotfiles from ${existingRepoName}?`,\n true\n );\n\n if (importRepo) {\n // Clone to temp directory\n const tempDir = join(tmpdir(), `tuck-import-${Date.now()}`);\n const cloneSpinner = prompts.spinner();\n cloneSpinner.start('Cloning repository...');\n let phase: 'cloning' | 'analyzing' | 'importing' = 'cloning';\n\n try {\n await ghCloneRepo(existingRepoName, tempDir);\n cloneSpinner.stop('Repository cloned');\n phase = 'analyzing';\n\n // Analyze the repository\n const analysisSpinner = prompts.spinner();\n analysisSpinner.start('Analyzing repository...');\n let analysis: RepositoryAnalysis;\n try {\n analysis = await analyzeRepository(tempDir);\n analysisSpinner.stop('Analysis complete');\n } catch (error) {\n analysisSpinner.stop('Analysis failed');\n throw new Error(\n `Failed to analyze repository: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n phase = 'importing';\n // Import based on analysis\n const result = await importExistingRepo(tuckDir, existingRepoName, analysis, tempDir);\n\n if (result.success) {\n console.log();\n // Always show that repository was imported to ~/.tuck\n if (result.filesInRepo > 0) {\n prompts.log.success(`Repository imported to ~/.tuck (${result.filesInRepo} files)`);\n if (result.filesApplied > 0) {\n prompts.log.info(`Applied ${result.filesApplied} files to your system`);\n } else if (result.filesInRepo > 0) {\n prompts.log.info('Files are ready in ~/.tuck. Run \"tuck restore\" to apply them to your system');\n }\n } else {\n prompts.log.success(`Tuck initialized with ${existingRepoName} as remote`);\n }\n\n prompts.outro('Ready to manage your dotfiles!');\n\n nextSteps([\n `View status: tuck status`,\n `Add files: tuck add ~/.zshrc`,\n `Sync: tuck sync`,\n ]);\n return;\n }\n\n // User cancelled - continue with normal flow\n console.log();\n } catch (error) {\n // Only stop clone spinner if we're still in cloning phase\n if (phase === 'cloning') {\n cloneSpinner.stop('Clone failed');\n }\n\n // Provide accurate error messages based on which phase failed\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (phase === 'analyzing') {\n prompts.log.warning(errorMessage);\n } else if (phase === 'importing') {\n prompts.log.warning(errorMessage);\n } else {\n prompts.log.warning(\n `Could not clone repository: ${errorMessage}`\n );\n }\n console.log();\n // Continue with normal flow\n } finally {\n // Always clean up temp directory if it exists\n if (await pathExists(tempDir)) {\n try {\n await rm(tempDir, { recursive: true, force: true });\n } catch (cleanupError) {\n // Log but don't throw - cleanup failure shouldn't break the flow\n prompts.log.warning(\n `Failed to clean up temporary directory: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`\n );\n }\n }\n }\n }\n } else {\n spinner.stop('No existing dotfiles repository found');\n }\n } catch {\n spinner.stop('Could not check for existing repositories');\n }\n }\n\n // Ask about existing repo (manual flow)\n const hasExisting = await prompts.select('Do you have an existing dotfiles repository?', [\n { value: 'no', label: 'No, start fresh' },\n { value: 'yes', label: 'Yes, clone from URL' },\n ]);\n\n if (hasExisting === 'yes') {\n const repoUrl = await prompts.text('Enter repository URL:', {\n placeholder: 'git@github.com:user/dotfiles.git',\n validate: (value) => {\n if (!value) return 'Repository URL is required';\n if (!value.includes('github.com') && !value.includes('gitlab.com') && !value.includes('git@')) {\n return 'Please enter a valid git URL';\n }\n return undefined;\n },\n });\n\n await initFromRemote(tuckDir, repoUrl);\n\n prompts.log.success('Repository cloned successfully!');\n\n const shouldRestore = await prompts.confirm('Would you like to restore dotfiles now?', true);\n\n if (shouldRestore) {\n prompts.log.info('Run `tuck restore --all` to restore all dotfiles');\n }\n } else {\n // Check for common dotfiles that exist\n const existingDotfiles: { path: string; label: string }[] = [];\n\n for (const df of COMMON_DOTFILES) {\n const fullPath = expandPath(df.path);\n if (await pathExists(fullPath)) {\n existingDotfiles.push({\n path: df.path,\n label: `${df.path} (${df.category})`,\n });\n }\n }\n\n await initFromScratch(tuckDir, {});\n\n // Ask to add common dotfiles if any exist\n if (existingDotfiles.length > 0) {\n const selectedFiles = await prompts.multiselect(\n 'Would you like to track some common dotfiles?',\n existingDotfiles.map((f) => ({\n value: f.path,\n label: f.label,\n }))\n );\n\n if (selectedFiles.length > 0) {\n prompts.log.step(\n `Run the following to track these files:\\n tuck add ${selectedFiles.join(' ')}`\n );\n }\n }\n\n // Ask about remote - try GitHub auto-setup first\n const wantsRemote = await prompts.confirm('Would you like to set up a remote repository?');\n\n if (wantsRemote) {\n // Try GitHub auto-setup\n const ghResult = await setupGitHubRepo(tuckDir);\n\n // If GitHub setup didn't add a remote, fall back to manual entry\n if (!ghResult.remoteUrl) {\n const useManual = await prompts.confirm('Enter a remote URL manually?');\n\n if (useManual) {\n const remoteUrl = await prompts.text('Enter remote URL:', {\n placeholder: 'git@github.com:user/dotfiles.git',\n });\n\n if (remoteUrl) {\n await addRemote(tuckDir, 'origin', remoteUrl);\n prompts.log.success('Remote added successfully');\n }\n }\n }\n }\n }\n\n prompts.outro('Tuck initialized successfully!');\n\n nextSteps([\n `Add files: tuck add ~/.zshrc`,\n `Sync changes: tuck sync`,\n `Push remote: tuck push`,\n ]);\n};\n\nconst runInit = async (options: InitOptions): Promise<void> => {\n const tuckDir = getTuckDir(options.dir);\n\n // If --from is provided, clone from remote\n if (options.from) {\n await initFromRemote(tuckDir, options.from);\n logger.success(`Tuck initialized from ${options.from}`);\n logger.info('Run `tuck restore --all` to restore dotfiles');\n return;\n }\n\n // Initialize from scratch\n await initFromScratch(tuckDir, {\n remote: options.remote,\n bare: options.bare,\n });\n\n logger.success(`Tuck initialized at ${collapsePath(tuckDir)}`);\n\n nextSteps([\n `Add files: tuck add ~/.zshrc`,\n `Sync changes: tuck sync`,\n `Push remote: tuck push`,\n ]);\n};\n\nexport const initCommand = new Command('init')\n .description('Initialize tuck repository')\n .option('-d, --dir <path>', 'Directory for tuck repository', '~/.tuck')\n .option('-r, --remote <url>', 'Git remote URL to set up')\n .option('--bare', 'Initialize without any default files')\n .option('--from <url>', 'Clone from existing tuck repository')\n .action(async (options: InitOptions) => {\n // If no options provided, run interactive mode\n if (!options.remote && !options.bare && !options.from && options.dir === '~/.tuck') {\n await runInteractiveInit();\n } else {\n await runInit(options);\n }\n });\n","import { join, basename } from 'path';\nimport { readdir, stat } from 'fs/promises';\nimport { platform } from 'os';\nimport { pathExists, expandPath } from './paths.js';\n\nconst IS_MACOS = platform() === 'darwin';\nconst IS_LINUX = platform() === 'linux';\n\nexport interface DetectedFile {\n path: string;\n name: string;\n category: string;\n description: string;\n isDirectory: boolean;\n size?: number;\n sensitive?: boolean;\n exclude?: string[]; // Patterns to exclude within directories\n}\n\nexport interface DetectionCategory {\n name: string;\n icon: string;\n description: string;\n}\n\nexport const DETECTION_CATEGORIES: Record<string, DetectionCategory> = {\n shell: {\n name: 'Shell',\n icon: '$',\n description: 'Shell configs, aliases, functions, and environment',\n },\n git: {\n name: 'Git',\n icon: '*',\n description: 'Git settings, aliases, and global ignores',\n },\n editors: {\n name: 'Editors',\n icon: '>',\n description: 'Editor configurations and settings',\n },\n terminal: {\n name: 'Terminal',\n icon: '#',\n description: 'Terminal emulators and tmux/screen',\n },\n prompt: {\n name: 'Prompt & Theme',\n icon: '~',\n description: 'Shell prompts, themes, and color schemes',\n },\n cli: {\n name: 'CLI Tools',\n icon: '%',\n description: 'Command-line tool configurations',\n },\n languages: {\n name: 'Languages',\n icon: '@',\n description: 'Programming language and package manager configs',\n },\n ssh: {\n name: 'SSH & Security',\n icon: '!',\n description: 'SSH config and GPG settings (no private keys)',\n },\n xdg: {\n name: 'XDG Apps',\n icon: '.',\n description: 'Applications using ~/.config standard',\n },\n desktop: {\n name: 'Desktop & WM',\n icon: '+',\n description: 'Window managers and desktop environment configs',\n },\n scripts: {\n name: 'Scripts',\n icon: '/',\n description: 'Custom scripts and local binaries',\n },\n macos: {\n name: 'macOS',\n icon: '^',\n description: 'macOS-specific configurations',\n },\n misc: {\n name: 'Other',\n icon: '-',\n description: 'Other configuration files',\n },\n};\n\n/**\n * Comprehensive list of dotfiles to detect\n */\nconst DOTFILE_PATTERNS: Array<{\n path: string;\n category: string;\n description: string;\n sensitive?: boolean;\n exclude?: string[];\n platform?: 'darwin' | 'linux' | 'all';\n}> = [\n // ==================== SHELL CONFIGURATION ====================\n // Bash\n { path: '~/.bashrc', category: 'shell', description: 'Bash interactive shell config' },\n { path: '~/.bash_profile', category: 'shell', description: 'Bash login shell config' },\n { path: '~/.bash_aliases', category: 'shell', description: 'Bash aliases' },\n { path: '~/.bash_functions', category: 'shell', description: 'Bash functions' },\n { path: '~/.bash_logout', category: 'shell', description: 'Bash logout script' },\n\n // Zsh\n { path: '~/.zshrc', category: 'shell', description: 'Zsh interactive shell config' },\n { path: '~/.zprofile', category: 'shell', description: 'Zsh login shell config' },\n { path: '~/.zshenv', category: 'shell', description: 'Zsh environment variables' },\n { path: '~/.zlogin', category: 'shell', description: 'Zsh login script' },\n { path: '~/.zlogout', category: 'shell', description: 'Zsh logout script' },\n { path: '~/.zsh', category: 'shell', description: 'Zsh configuration directory' },\n\n // Fish\n { path: '~/.config/fish/config.fish', category: 'shell', description: 'Fish shell config' },\n { path: '~/.config/fish/functions', category: 'shell', description: 'Fish functions' },\n { path: '~/.config/fish/completions', category: 'shell', description: 'Fish completions' },\n { path: '~/.config/fish/conf.d', category: 'shell', description: 'Fish config snippets' },\n\n // Generic shell\n { path: '~/.profile', category: 'shell', description: 'Generic shell profile' },\n { path: '~/.aliases', category: 'shell', description: 'Shell aliases' },\n { path: '~/.functions', category: 'shell', description: 'Shell functions' },\n { path: '~/.exports', category: 'shell', description: 'Environment exports' },\n { path: '~/.inputrc', category: 'shell', description: 'Readline configuration' },\n { path: '~/.hushlogin', category: 'shell', description: 'Suppress login message' },\n\n // ==================== GIT CONFIGURATION ====================\n { path: '~/.gitconfig', category: 'git', description: 'Git global configuration' },\n { path: '~/.gitignore_global', category: 'git', description: 'Global gitignore patterns' },\n { path: '~/.gitignore', category: 'git', description: 'Global gitignore (alt location)' },\n { path: '~/.gitmessage', category: 'git', description: 'Git commit message template' },\n { path: '~/.gitattributes', category: 'git', description: 'Git attributes' },\n { path: '~/.config/git/config', category: 'git', description: 'Git XDG config' },\n { path: '~/.config/git/ignore', category: 'git', description: 'Git XDG ignore' },\n { path: '~/.config/gh', category: 'git', description: 'GitHub CLI config' },\n { path: '~/.config/hub', category: 'git', description: 'Hub CLI config' },\n\n // ==================== EDITORS & IDES ====================\n // Vim/Neovim\n { path: '~/.vimrc', category: 'editors', description: 'Vim configuration' },\n { path: '~/.vim', category: 'editors', description: 'Vim directory', exclude: ['plugged', 'bundle', '.netrwhist'] },\n { path: '~/.config/nvim', category: 'editors', description: 'Neovim configuration' },\n { path: '~/.ideavimrc', category: 'editors', description: 'IdeaVim (JetBrains) config' },\n\n // Emacs\n { path: '~/.emacs', category: 'editors', description: 'Emacs configuration' },\n { path: '~/.emacs.d/init.el', category: 'editors', description: 'Emacs init file' },\n { path: '~/.doom.d', category: 'editors', description: 'Doom Emacs config' },\n { path: '~/.spacemacs', category: 'editors', description: 'Spacemacs config' },\n\n // VS Code\n { path: '~/.config/Code/User/settings.json', category: 'editors', description: 'VS Code settings', platform: 'linux' },\n { path: '~/.config/Code/User/keybindings.json', category: 'editors', description: 'VS Code keybindings', platform: 'linux' },\n { path: '~/.config/Code/User/snippets', category: 'editors', description: 'VS Code snippets', platform: 'linux' },\n { path: '~/Library/Application Support/Code/User/settings.json', category: 'editors', description: 'VS Code settings', platform: 'darwin' },\n { path: '~/Library/Application Support/Code/User/keybindings.json', category: 'editors', description: 'VS Code keybindings', platform: 'darwin' },\n { path: '~/Library/Application Support/Code/User/snippets', category: 'editors', description: 'VS Code snippets', platform: 'darwin' },\n\n // Cursor (VS Code fork)\n { path: '~/.config/Cursor/User/settings.json', category: 'editors', description: 'Cursor settings', platform: 'linux' },\n { path: '~/Library/Application Support/Cursor/User/settings.json', category: 'editors', description: 'Cursor settings', platform: 'darwin' },\n\n // Other editors\n { path: '~/.nanorc', category: 'editors', description: 'Nano configuration' },\n { path: '~/.config/micro', category: 'editors', description: 'Micro editor config' },\n { path: '~/.config/helix', category: 'editors', description: 'Helix editor config' },\n { path: '~/.sublime-text/Packages/User', category: 'editors', description: 'Sublime Text settings' },\n\n // ==================== TERMINAL & MULTIPLEXERS ====================\n // Tmux\n { path: '~/.tmux.conf', category: 'terminal', description: 'Tmux configuration' },\n { path: '~/.tmux', category: 'terminal', description: 'Tmux directory' },\n { path: '~/.config/tmux/tmux.conf', category: 'terminal', description: 'Tmux XDG config' },\n\n // Screen\n { path: '~/.screenrc', category: 'terminal', description: 'GNU Screen configuration' },\n\n // Terminal emulators\n { path: '~/.config/alacritty', category: 'terminal', description: 'Alacritty terminal config' },\n { path: '~/.config/kitty', category: 'terminal', description: 'Kitty terminal config' },\n { path: '~/.config/wezterm', category: 'terminal', description: 'WezTerm config' },\n { path: '~/.wezterm.lua', category: 'terminal', description: 'WezTerm config (alt)' },\n { path: '~/.config/hyper', category: 'terminal', description: 'Hyper terminal config' },\n { path: '~/.hyper.js', category: 'terminal', description: 'Hyper terminal config (alt)' },\n { path: '~/.config/foot', category: 'terminal', description: 'Foot terminal config' },\n { path: '~/.config/terminator', category: 'terminal', description: 'Terminator config' },\n { path: '~/.config/tilix', category: 'terminal', description: 'Tilix terminal config' },\n { path: '~/Library/Preferences/com.googlecode.iterm2.plist', category: 'terminal', description: 'iTerm2 preferences', platform: 'darwin' },\n\n // ==================== PROMPT & THEMES ====================\n { path: '~/.config/starship.toml', category: 'prompt', description: 'Starship prompt config' },\n { path: '~/.p10k.zsh', category: 'prompt', description: 'Powerlevel10k config' },\n { path: '~/.oh-my-zsh/custom', category: 'prompt', description: 'Oh My Zsh customizations' },\n { path: '~/.config/powerline', category: 'prompt', description: 'Powerline config' },\n { path: '~/.dir_colors', category: 'prompt', description: 'Directory colors' },\n { path: '~/.dircolors', category: 'prompt', description: 'Directory colors (alt)' },\n\n // ==================== CLI TOOLS ====================\n // Search & navigation\n { path: '~/.config/ripgrep', category: 'cli', description: 'Ripgrep config' },\n { path: '~/.ripgreprc', category: 'cli', description: 'Ripgrep config (alt)' },\n { path: '~/.rgrc', category: 'cli', description: 'Ripgrep config (short)' },\n { path: '~/.config/fd', category: 'cli', description: 'fd find config' },\n { path: '~/.fdignore', category: 'cli', description: 'fd ignore patterns' },\n { path: '~/.config/bat', category: 'cli', description: 'bat (better cat) config' },\n { path: '~/.config/lsd', category: 'cli', description: 'lsd (better ls) config' },\n { path: '~/.config/exa', category: 'cli', description: 'exa config' },\n { path: '~/.config/eza', category: 'cli', description: 'eza config' },\n\n // Fuzzy finders\n { path: '~/.fzf.zsh', category: 'cli', description: 'fzf Zsh integration' },\n { path: '~/.fzf.bash', category: 'cli', description: 'fzf Bash integration' },\n { path: '~/.config/fzf', category: 'cli', description: 'fzf config directory' },\n\n // Network tools\n { path: '~/.curlrc', category: 'cli', description: 'curl configuration' },\n { path: '~/.wgetrc', category: 'cli', description: 'wget configuration' },\n { path: '~/.netrc', category: 'cli', description: 'Network credentials', sensitive: true },\n { path: '~/.config/aria2', category: 'cli', description: 'aria2 download manager' },\n\n // System monitoring\n { path: '~/.config/htop', category: 'cli', description: 'htop config' },\n { path: '~/.config/btop', category: 'cli', description: 'btop config' },\n { path: '~/.config/bottom', category: 'cli', description: 'bottom config' },\n { path: '~/.config/glances', category: 'cli', description: 'Glances config' },\n\n // Other CLI tools\n { path: '~/.config/lazygit', category: 'cli', description: 'Lazygit config' },\n { path: '~/.config/lazydocker', category: 'cli', description: 'Lazydocker config' },\n { path: '~/.config/ranger', category: 'cli', description: 'Ranger file manager' },\n { path: '~/.config/lf', category: 'cli', description: 'lf file manager' },\n { path: '~/.config/yazi', category: 'cli', description: 'Yazi file manager' },\n { path: '~/.config/nnn', category: 'cli', description: 'nnn file manager' },\n { path: '~/.config/zoxide', category: 'cli', description: 'zoxide (smart cd)' },\n { path: '~/.config/atuin', category: 'cli', description: 'Atuin shell history' },\n { path: '~/.config/thefuck', category: 'cli', description: 'thefuck config' },\n { path: '~/.config/direnv', category: 'cli', description: 'direnv config' },\n { path: '~/.direnvrc', category: 'cli', description: 'direnv config (alt)' },\n { path: '~/.ackrc', category: 'cli', description: 'ack search config' },\n { path: '~/.agignore', category: 'cli', description: 'silver searcher ignore' },\n { path: '~/.editorconfig', category: 'cli', description: 'EditorConfig' },\n\n // ==================== LANGUAGES & PACKAGE MANAGERS ====================\n // Node.js\n { path: '~/.npmrc', category: 'languages', description: 'npm configuration' },\n { path: '~/.yarnrc', category: 'languages', description: 'Yarn configuration' },\n { path: '~/.config/yarn', category: 'languages', description: 'Yarn config directory' },\n { path: '~/.bunfig.toml', category: 'languages', description: 'Bun configuration' },\n { path: '~/.nvmrc', category: 'languages', description: 'nvm default version' },\n { path: '~/.node-version', category: 'languages', description: 'Node version file' },\n\n // Python\n { path: '~/.config/pip', category: 'languages', description: 'pip configuration' },\n { path: '~/.pip', category: 'languages', description: 'pip config (legacy)' },\n { path: '~/.pypirc', category: 'languages', description: 'PyPI configuration', sensitive: true },\n { path: '~/.python-version', category: 'languages', description: 'pyenv version' },\n { path: '~/.config/flake8', category: 'languages', description: 'Flake8 config' },\n { path: '~/.config/black', category: 'languages', description: 'Black formatter' },\n { path: '~/.config/ruff', category: 'languages', description: 'Ruff linter' },\n { path: '~/.pylintrc', category: 'languages', description: 'Pylint config' },\n { path: '~/.config/pypoetry', category: 'languages', description: 'Poetry config' },\n { path: '~/.config/pdm', category: 'languages', description: 'PDM config' },\n\n // Ruby\n { path: '~/.gemrc', category: 'languages', description: 'RubyGems configuration' },\n { path: '~/.irbrc', category: 'languages', description: 'IRB configuration' },\n { path: '~/.pryrc', category: 'languages', description: 'Pry configuration' },\n { path: '~/.ruby-version', category: 'languages', description: 'Ruby version file' },\n { path: '~/.bundle/config', category: 'languages', description: 'Bundler config' },\n\n // Rust\n { path: '~/.cargo/config.toml', category: 'languages', description: 'Cargo configuration' },\n { path: '~/.cargo/config', category: 'languages', description: 'Cargo config (legacy)' },\n { path: '~/.rustfmt.toml', category: 'languages', description: 'rustfmt config' },\n\n // Go\n { path: '~/.config/go', category: 'languages', description: 'Go configuration' },\n\n // Java/JVM\n { path: '~/.gradle/gradle.properties', category: 'languages', description: 'Gradle properties' },\n { path: '~/.m2/settings.xml', category: 'languages', description: 'Maven settings' },\n { path: '~/.sbt', category: 'languages', description: 'SBT config' },\n\n // Docker\n { path: '~/.docker/config.json', category: 'languages', description: 'Docker config' },\n\n // Kubernetes\n { path: '~/.kube/config', category: 'languages', description: 'kubectl config', sensitive: true },\n\n // Cloud\n { path: '~/.aws/config', category: 'languages', description: 'AWS CLI config' },\n { path: '~/.config/gcloud', category: 'languages', description: 'Google Cloud config' },\n\n // ==================== SSH & SECURITY ====================\n {\n path: '~/.ssh/config',\n category: 'ssh',\n description: 'SSH client configuration',\n sensitive: true,\n },\n {\n path: '~/.ssh/known_hosts',\n category: 'ssh',\n description: 'SSH known hosts',\n },\n {\n path: '~/.ssh/authorized_keys',\n category: 'ssh',\n description: 'Authorized SSH keys',\n },\n {\n path: '~/.ssh/rc',\n category: 'ssh',\n description: 'SSH connection script',\n },\n {\n path: '~/.gnupg/gpg.conf',\n category: 'ssh',\n description: 'GPG configuration',\n sensitive: true,\n },\n {\n path: '~/.gnupg/gpg-agent.conf',\n category: 'ssh',\n description: 'GPG agent configuration',\n },\n\n // ==================== XDG CONFIG APPS ====================\n { path: '~/.config/fontconfig', category: 'xdg', description: 'Font configuration' },\n { path: '~/.config/gtk-3.0', category: 'xdg', description: 'GTK3 settings' },\n { path: '~/.config/gtk-4.0', category: 'xdg', description: 'GTK4 settings' },\n { path: '~/.config/qt5ct', category: 'xdg', description: 'Qt5 settings' },\n { path: '~/.config/mimeapps.list', category: 'xdg', description: 'Default applications' },\n { path: '~/.config/user-dirs.dirs', category: 'xdg', description: 'XDG user directories' },\n { path: '~/.config/autostart', category: 'xdg', description: 'Autostart applications' },\n { path: '~/.config/environment.d', category: 'xdg', description: 'Environment variables' },\n { path: '~/.config/systemd/user', category: 'xdg', description: 'User systemd services', platform: 'linux' },\n { path: '~/.config/dunst', category: 'xdg', description: 'Dunst notifications', platform: 'linux' },\n { path: '~/.config/rofi', category: 'xdg', description: 'Rofi launcher', platform: 'linux' },\n { path: '~/.config/wofi', category: 'xdg', description: 'Wofi launcher', platform: 'linux' },\n\n // ==================== DESKTOP & WINDOW MANAGERS ====================\n // i3/sway\n { path: '~/.config/i3', category: 'desktop', description: 'i3 window manager', platform: 'linux' },\n { path: '~/.config/sway', category: 'desktop', description: 'Sway (Wayland i3)', platform: 'linux' },\n { path: '~/.config/i3status', category: 'desktop', description: 'i3status bar', platform: 'linux' },\n { path: '~/.config/i3status-rust', category: 'desktop', description: 'i3status-rust bar', platform: 'linux' },\n { path: '~/.config/waybar', category: 'desktop', description: 'Waybar', platform: 'linux' },\n { path: '~/.config/polybar', category: 'desktop', description: 'Polybar', platform: 'linux' },\n\n // Hyprland\n { path: '~/.config/hypr', category: 'desktop', description: 'Hyprland config', platform: 'linux' },\n\n // Other WMs\n { path: '~/.config/bspwm', category: 'desktop', description: 'bspwm config', platform: 'linux' },\n { path: '~/.config/sxhkd', category: 'desktop', description: 'sxhkd hotkeys', platform: 'linux' },\n { path: '~/.config/awesome', category: 'desktop', description: 'AwesomeWM config', platform: 'linux' },\n { path: '~/.config/openbox', category: 'desktop', description: 'Openbox config', platform: 'linux' },\n { path: '~/.config/qtile', category: 'desktop', description: 'Qtile config', platform: 'linux' },\n { path: '~/.config/herbstluftwm', category: 'desktop', description: 'herbstluftwm config', platform: 'linux' },\n\n // macOS window managers\n { path: '~/.yabairc', category: 'desktop', description: 'yabai config', platform: 'darwin' },\n { path: '~/.config/yabai', category: 'desktop', description: 'yabai config (XDG)', platform: 'darwin' },\n { path: '~/.skhdrc', category: 'desktop', description: 'skhd hotkeys', platform: 'darwin' },\n { path: '~/.config/skhd', category: 'desktop', description: 'skhd config (XDG)', platform: 'darwin' },\n { path: '~/.config/spacebar', category: 'desktop', description: 'spacebar config', platform: 'darwin' },\n { path: '~/.config/borders', category: 'desktop', description: 'borders config', platform: 'darwin' },\n { path: '~/.aerospace.toml', category: 'desktop', description: 'AeroSpace config', platform: 'darwin' },\n\n // Picom/Compton\n { path: '~/.config/picom', category: 'desktop', description: 'Picom compositor', platform: 'linux' },\n { path: '~/.config/picom.conf', category: 'desktop', description: 'Picom config (alt)', platform: 'linux' },\n\n // ==================== SCRIPTS & BINS ====================\n { path: '~/.local/bin', category: 'scripts', description: 'Local scripts and binaries' },\n { path: '~/bin', category: 'scripts', description: 'User bin directory' },\n { path: '~/.scripts', category: 'scripts', description: 'Custom scripts' },\n\n // ==================== MACOS SPECIFIC ====================\n { path: '~/.finicky.js', category: 'macos', description: 'Finicky browser picker', platform: 'darwin' },\n { path: '~/.config/karabiner', category: 'macos', description: 'Karabiner key remapping', platform: 'darwin' },\n { path: '~/.hammerspoon', category: 'macos', description: 'Hammerspoon automation', platform: 'darwin' },\n { path: '~/.config/raycast', category: 'macos', description: 'Raycast config', platform: 'darwin' },\n\n // ==================== MISCELLANEOUS ====================\n { path: '~/.config/neofetch', category: 'misc', description: 'Neofetch config' },\n { path: '~/.config/fastfetch', category: 'misc', description: 'Fastfetch config' },\n { path: '~/.config/onefetch', category: 'misc', description: 'Onefetch config' },\n { path: '~/.config/topgrade.toml', category: 'misc', description: 'Topgrade updater' },\n { path: '~/.config/youtube-dl', category: 'misc', description: 'youtube-dl config' },\n { path: '~/.config/yt-dlp', category: 'misc', description: 'yt-dlp config' },\n { path: '~/.config/mpv', category: 'misc', description: 'MPV media player' },\n { path: '~/.config/newsboat', category: 'misc', description: 'Newsboat RSS reader' },\n { path: '~/.config/cmus', category: 'misc', description: 'cmus music player' },\n { path: '~/.config/spotify-tui', category: 'misc', description: 'Spotify TUI' },\n { path: '~/.mailcap', category: 'misc', description: 'MIME type handlers' },\n { path: '~/.muttrc', category: 'misc', description: 'Mutt email client' },\n { path: '~/.config/mutt', category: 'misc', description: 'Mutt config directory' },\n { path: '~/.config/neomutt', category: 'misc', description: 'Neomutt config' },\n { path: '~/.Xresources', category: 'misc', description: 'X11 resources', platform: 'linux' },\n { path: '~/.Xmodmap', category: 'misc', description: 'X11 keymap', platform: 'linux' },\n { path: '~/.xinitrc', category: 'misc', description: 'X11 init script', platform: 'linux' },\n { path: '~/.xprofile', category: 'misc', description: 'X11 profile', platform: 'linux' },\n];\n\n/**\n * Check if a path should be included for current platform\n */\nconst shouldIncludeForPlatform = (item: { platform?: string }): boolean => {\n if (!item.platform || item.platform === 'all') return true;\n if (item.platform === 'darwin' && IS_MACOS) return true;\n if (item.platform === 'linux' && IS_LINUX) return true;\n return false;\n};\n\n/**\n * Get file/directory size\n */\nconst getSize = async (path: string): Promise<number | undefined> => {\n try {\n const stats = await stat(path);\n return stats.size;\n } catch {\n return undefined;\n }\n};\n\n/**\n * Check if path is a directory\n */\nconst isDirectory = async (path: string): Promise<boolean> => {\n try {\n const stats = await stat(path);\n return stats.isDirectory();\n } catch {\n return false;\n }\n};\n\n/**\n * Scan system for existing dotfiles\n */\nexport const detectDotfiles = async (): Promise<DetectedFile[]> => {\n const detected: DetectedFile[] = [];\n\n for (const pattern of DOTFILE_PATTERNS) {\n // Skip if not for current platform\n if (!shouldIncludeForPlatform(pattern)) continue;\n\n const fullPath = expandPath(pattern.path);\n\n if (await pathExists(fullPath)) {\n const isDir = await isDirectory(fullPath);\n const size = await getSize(fullPath);\n\n detected.push({\n path: pattern.path,\n name: basename(pattern.path),\n category: pattern.category,\n description: pattern.description,\n isDirectory: isDir,\n size,\n sensitive: pattern.sensitive,\n exclude: pattern.exclude,\n });\n }\n }\n\n return detected;\n};\n\n/**\n * Group detected files by category\n */\nexport const groupByCategory = (\n files: DetectedFile[]\n): Record<string, DetectedFile[]> => {\n const grouped: Record<string, DetectedFile[]> = {};\n\n for (const file of files) {\n if (!grouped[file.category]) {\n grouped[file.category] = [];\n }\n grouped[file.category].push(file);\n }\n\n return grouped;\n};\n\n/**\n * Get SSH files that are safe to backup (no private keys)\n */\nexport const getSafeSSHFiles = async (): Promise<string[]> => {\n const sshDir = expandPath('~/.ssh');\n const safeFiles: string[] = [];\n\n if (!(await pathExists(sshDir))) {\n return safeFiles;\n }\n\n try {\n const entries = await readdir(sshDir);\n\n for (const entry of entries) {\n // Skip private keys and other sensitive files\n if (\n entry.endsWith('.pub') ||\n entry === 'config' ||\n entry === 'known_hosts' ||\n entry === 'authorized_keys' ||\n entry === 'rc' ||\n entry === 'environment'\n ) {\n safeFiles.push(join('~/.ssh', entry));\n }\n }\n } catch {\n // Ignore errors\n }\n\n return safeFiles;\n};\n\n/**\n * Format file size for display\n */\nexport const formatSize = (bytes: number | undefined): string => {\n if (bytes === undefined) return '';\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(1))} ${sizes[i]}`;\n};\n\n/**\n * Get count of files in each category\n */\nexport const getCategoryCounts = (\n files: DetectedFile[]\n): Record<string, number> => {\n const counts: Record<string, number> = {};\n\n for (const file of files) {\n counts[file.category] = (counts[file.category] || 0) + 1;\n }\n\n return counts;\n};\n","import { join, dirname } from 'path';\nimport { readdir, readFile, writeFile, rm, stat } from 'fs/promises';\nimport { copy, ensureDir, pathExists } from 'fs-extra';\nimport { homedir } from 'os';\nimport { expandPath, collapsePath, pathExists as checkPathExists } from './paths.js';\nimport { BackupError } from '../errors.js';\n\nconst TIMEMACHINE_DIR = join(homedir(), '.tuck', 'backups');\n\nexport interface SnapshotMetadata {\n id: string;\n timestamp: string;\n reason: string;\n files: SnapshotFile[];\n machine: string;\n profile?: string;\n}\n\nexport interface SnapshotFile {\n originalPath: string;\n backupPath: string;\n existed: boolean;\n}\n\nexport interface Snapshot {\n id: string;\n path: string;\n timestamp: Date;\n reason: string;\n files: SnapshotFile[];\n machine: string;\n profile?: string;\n}\n\n/**\n * Generate a unique snapshot ID (YYYY-MM-DD-HHMMSS)\n */\nconst generateSnapshotId = (): string => {\n const now = new Date();\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, '0');\n const day = String(now.getDate()).padStart(2, '0');\n const hours = String(now.getHours()).padStart(2, '0');\n const minutes = String(now.getMinutes()).padStart(2, '0');\n const seconds = String(now.getSeconds()).padStart(2, '0');\n return `${year}-${month}-${day}-${hours}${minutes}${seconds}`;\n};\n\n/**\n * Get the path to a snapshot directory\n */\nconst getSnapshotPath = (snapshotId: string): string => {\n return join(TIMEMACHINE_DIR, snapshotId);\n};\n\n/**\n * Convert original path to a safe backup path, preserving directory structure\n * to prevent filename collisions. The path is relative to the backup files directory.\n * e.g., ~/.zshrc -> .zshrc\n * e.g., ~/.config/nvim -> .config/nvim\n * e.g., ~/.foo.bar -> .foo.bar (distinct from ~/.foo-bar -> .foo-bar)\n */\nconst toBackupPath = (originalPath: string): string => {\n const collapsed = collapsePath(originalPath);\n // Remove ~/ prefix to get a path relative to home directory\n // This preserves the full directory structure, preventing collisions\n return collapsed.replace(/^~\\//, '');\n};\n\n/**\n * Create a Time Machine snapshot of multiple files\n * This is the main entry point for creating backups before apply operations\n */\nexport const createSnapshot = async (\n filePaths: string[],\n reason: string,\n profile?: string\n): Promise<Snapshot> => {\n const snapshotId = generateSnapshotId();\n const snapshotPath = getSnapshotPath(snapshotId);\n\n await ensureDir(snapshotPath);\n\n const files: SnapshotFile[] = [];\n const machine = (await import('os')).hostname();\n\n for (const filePath of filePaths) {\n const expandedPath = expandPath(filePath);\n const backupRelativePath = toBackupPath(expandedPath);\n const backupPath = join(snapshotPath, 'files', backupRelativePath);\n\n const existed = await checkPathExists(expandedPath);\n\n if (existed) {\n await ensureDir(dirname(backupPath));\n await copy(expandedPath, backupPath, { overwrite: true, preserveTimestamps: true });\n }\n\n files.push({\n originalPath: expandedPath,\n backupPath,\n existed,\n });\n }\n\n // Save metadata\n const metadata: SnapshotMetadata = {\n id: snapshotId,\n timestamp: new Date().toISOString(),\n reason,\n files,\n machine,\n profile,\n };\n\n await writeFile(\n join(snapshotPath, 'metadata.json'),\n JSON.stringify(metadata, null, 2),\n 'utf-8'\n );\n\n return {\n id: snapshotId,\n path: snapshotPath,\n timestamp: new Date(metadata.timestamp),\n reason,\n files,\n machine,\n profile,\n };\n};\n\n/**\n * Create a snapshot of the user's current dotfiles before applying new ones\n */\nexport const createPreApplySnapshot = async (\n targetPaths: string[],\n sourceRepo?: string\n): Promise<Snapshot> => {\n const reason = sourceRepo\n ? `Pre-apply backup before applying from ${sourceRepo}`\n : 'Pre-apply backup';\n\n return createSnapshot(targetPaths, reason);\n};\n\n/**\n * List all available snapshots\n */\nexport const listSnapshots = async (): Promise<Snapshot[]> => {\n if (!(await pathExists(TIMEMACHINE_DIR))) {\n return [];\n }\n\n const entries = await readdir(TIMEMACHINE_DIR, { withFileTypes: true });\n const snapshots: Snapshot[] = [];\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n const snapshotPath = join(TIMEMACHINE_DIR, entry.name);\n const metadataPath = join(snapshotPath, 'metadata.json');\n\n if (!(await pathExists(metadataPath))) continue;\n\n try {\n const content = await readFile(metadataPath, 'utf-8');\n const metadata: SnapshotMetadata = JSON.parse(content);\n\n snapshots.push({\n id: metadata.id,\n path: snapshotPath,\n timestamp: new Date(metadata.timestamp),\n reason: metadata.reason,\n files: metadata.files,\n machine: metadata.machine,\n profile: metadata.profile,\n });\n } catch {\n // Skip invalid snapshots\n }\n }\n\n // Sort by timestamp, newest first\n return snapshots.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());\n};\n\n/**\n * Get a specific snapshot by ID\n */\nexport const getSnapshot = async (snapshotId: string): Promise<Snapshot | null> => {\n const snapshotPath = getSnapshotPath(snapshotId);\n\n if (!(await pathExists(snapshotPath))) {\n return null;\n }\n\n const metadataPath = join(snapshotPath, 'metadata.json');\n\n if (!(await pathExists(metadataPath))) {\n return null;\n }\n\n try {\n const content = await readFile(metadataPath, 'utf-8');\n const metadata: SnapshotMetadata = JSON.parse(content);\n\n return {\n id: metadata.id,\n path: snapshotPath,\n timestamp: new Date(metadata.timestamp),\n reason: metadata.reason,\n files: metadata.files,\n machine: metadata.machine,\n profile: metadata.profile,\n };\n } catch {\n return null;\n }\n};\n\n/**\n * Get the latest snapshot\n */\nexport const getLatestSnapshot = async (): Promise<Snapshot | null> => {\n const snapshots = await listSnapshots();\n return snapshots.length > 0 ? snapshots[0] : null;\n};\n\n/**\n * Restore all files from a snapshot\n */\nexport const restoreSnapshot = async (snapshotId: string): Promise<string[]> => {\n const snapshot = await getSnapshot(snapshotId);\n\n if (!snapshot) {\n throw new BackupError(`Snapshot not found: ${snapshotId}`, [\n 'Run `tuck restore --list` to see available snapshots',\n ]);\n }\n\n const restoredFiles: string[] = [];\n\n for (const file of snapshot.files) {\n if (!file.existed) {\n // File didn't exist before, delete it if it exists now\n if (await checkPathExists(file.originalPath)) {\n await rm(file.originalPath, { recursive: true });\n }\n continue;\n }\n\n // Restore the backup\n if (await pathExists(file.backupPath)) {\n await ensureDir(dirname(file.originalPath));\n await copy(file.backupPath, file.originalPath, { overwrite: true, preserveTimestamps: true });\n restoredFiles.push(file.originalPath);\n }\n }\n\n return restoredFiles;\n};\n\n/**\n * Restore a single file from a snapshot\n */\nexport const restoreFileFromSnapshot = async (\n snapshotId: string,\n filePath: string\n): Promise<boolean> => {\n const snapshot = await getSnapshot(snapshotId);\n\n if (!snapshot) {\n throw new BackupError(`Snapshot not found: ${snapshotId}`);\n }\n\n const expandedPath = expandPath(filePath);\n const file = snapshot.files.find((f) => f.originalPath === expandedPath);\n\n if (!file) {\n throw new BackupError(`File not found in snapshot: ${filePath}`, [\n 'This file was not included in the snapshot',\n ]);\n }\n\n if (!file.existed) {\n // File didn't exist before, delete it if it exists now\n if (await checkPathExists(file.originalPath)) {\n await rm(file.originalPath, { recursive: true });\n }\n return true;\n }\n\n if (!(await pathExists(file.backupPath))) {\n throw new BackupError(`Backup file is missing: ${file.backupPath}`);\n }\n\n await ensureDir(dirname(file.originalPath));\n await copy(file.backupPath, file.originalPath, { overwrite: true, preserveTimestamps: true });\n return true;\n};\n\n/**\n * Delete a snapshot\n */\nexport const deleteSnapshot = async (snapshotId: string): Promise<void> => {\n const snapshotPath = getSnapshotPath(snapshotId);\n\n if (await pathExists(snapshotPath)) {\n await rm(snapshotPath, { recursive: true });\n }\n};\n\n/**\n * Clean up old snapshots, keeping only the specified number\n */\nexport const cleanOldSnapshots = async (keepCount: number): Promise<number> => {\n const snapshots = await listSnapshots();\n\n if (snapshots.length <= keepCount) {\n return 0;\n }\n\n const toDelete = snapshots.slice(keepCount);\n let deletedCount = 0;\n\n for (const snapshot of toDelete) {\n await deleteSnapshot(snapshot.id);\n deletedCount++;\n }\n\n return deletedCount;\n};\n\n/**\n * Get the total size of all snapshots in bytes\n */\nexport const getSnapshotsSize = async (): Promise<number> => {\n if (!(await pathExists(TIMEMACHINE_DIR))) {\n return 0;\n }\n\n let totalSize = 0;\n\n const calculateDirSize = async (dirPath: string): Promise<number> => {\n let size = 0;\n const entries = await readdir(dirPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const entryPath = join(dirPath, entry.name);\n if (entry.isDirectory()) {\n size += await calculateDirSize(entryPath);\n } else {\n const stats = await stat(entryPath);\n size += stats.size;\n }\n }\n\n return size;\n };\n\n totalSize = await calculateDirSize(TIMEMACHINE_DIR);\n return totalSize;\n};\n\n/**\n * Format bytes to human readable string\n */\nexport const formatSnapshotSize = (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\n/**\n * Format a snapshot ID to a human-readable date string\n */\nexport const formatSnapshotDate = (snapshotId: string): string => {\n // Parse YYYY-MM-DD-HHMMSS format\n const match = snapshotId.match(/^(\\d{4})-(\\d{2})-(\\d{2})-(\\d{2})(\\d{2})(\\d{2})$/);\n if (!match) return snapshotId;\n\n const [, year, month, day, hours, minutes, seconds] = match;\n const date = new Date(\n parseInt(year),\n parseInt(month) - 1,\n parseInt(day),\n parseInt(hours),\n parseInt(minutes),\n parseInt(seconds)\n );\n\n return date.toLocaleString();\n};\n","export { initCommand } from './init.js';\nexport { addCommand } from './add.js';\nexport { removeCommand } from './remove.js';\nexport { syncCommand } from './sync.js';\nexport { pushCommand } from './push.js';\nexport { pullCommand } from './pull.js';\nexport { restoreCommand } from './restore.js';\nexport { statusCommand } from './status.js';\nexport { listCommand } from './list.js';\nexport { diffCommand } from './diff.js';\nexport { configCommand } from './config.js';\nexport { applyCommand } from './apply.js';\nexport { undoCommand } from './undo.js';\nexport { scanCommand } from './scan.js';\n","import { Command } from 'commander';\nimport { prompts, logger, withSpinner } from '../ui/index.js';\nimport {\n getTuckDir,\n expandPath,\n collapsePath,\n pathExists,\n} from '../lib/paths.js';\nimport { loadManifest, removeFileFromManifest, getTrackedFileBySource, getAllTrackedFiles } from '../lib/manifest.js';\nimport { deleteFileOrDir } from '../lib/files.js';\nimport { NotInitializedError, FileNotTrackedError } from '../errors.js';\nimport type { RemoveOptions } from '../types.js';\nimport { join } from 'path';\n\ninterface FileToRemove {\n id: string;\n source: string;\n destination: string;\n}\n\nconst validateAndPrepareFiles = async (\n paths: string[],\n tuckDir: string\n): Promise<FileToRemove[]> => {\n const filesToRemove: FileToRemove[] = [];\n\n for (const path of paths) {\n const expandedPath = expandPath(path);\n const collapsedPath = collapsePath(expandedPath);\n\n // Check if tracked\n const tracked = await getTrackedFileBySource(tuckDir, collapsedPath);\n if (!tracked) {\n throw new FileNotTrackedError(path);\n }\n\n filesToRemove.push({\n id: tracked.id,\n source: tracked.file.source,\n destination: join(tuckDir, tracked.file.destination),\n });\n }\n\n return filesToRemove;\n};\n\nconst removeFiles = async (\n filesToRemove: FileToRemove[],\n tuckDir: string,\n options: RemoveOptions\n): Promise<void> => {\n for (const file of filesToRemove) {\n // Remove from manifest\n await removeFileFromManifest(tuckDir, file.id);\n\n // Delete from repository if requested\n if (options.delete) {\n if (await pathExists(file.destination)) {\n await withSpinner(`Deleting ${file.source} from repository...`, async () => {\n await deleteFileOrDir(file.destination);\n });\n }\n }\n\n logger.success(`Removed ${file.source} from tracking`);\n if (options.delete) {\n logger.dim(' Also deleted from repository');\n }\n }\n};\n\nconst runInteractiveRemove = async (tuckDir: string): Promise<void> => {\n prompts.intro('tuck remove');\n\n // Get all tracked files\n const trackedFiles = await getAllTrackedFiles(tuckDir);\n const fileEntries = Object.entries(trackedFiles);\n\n if (fileEntries.length === 0) {\n prompts.log.warning('No files are currently tracked');\n prompts.outro('');\n return;\n }\n\n // Let user select files to remove\n const selectedFiles = await prompts.multiselect(\n 'Select files to stop tracking:',\n fileEntries.map(([id, file]) => ({\n value: id,\n label: file.source,\n hint: file.category,\n })),\n true\n );\n\n if (selectedFiles.length === 0) {\n prompts.cancel('No files selected');\n return;\n }\n\n // Ask if they want to delete from repo\n const shouldDelete = await prompts.confirm('Also delete files from repository?');\n\n // Confirm\n const confirm = await prompts.confirm(\n `Remove ${selectedFiles.length} ${selectedFiles.length === 1 ? 'file' : 'files'} from tracking?`,\n true\n );\n\n if (!confirm) {\n prompts.cancel('Operation cancelled');\n return;\n }\n\n // Prepare files to remove\n const filesToRemove: FileToRemove[] = selectedFiles.map((id) => {\n const file = trackedFiles[id as string];\n return {\n id: id as string,\n source: file.source,\n destination: join(tuckDir, file.destination),\n };\n });\n\n // Remove files\n await removeFiles(filesToRemove, tuckDir, { delete: shouldDelete });\n\n prompts.outro(`Removed ${selectedFiles.length} ${selectedFiles.length === 1 ? 'file' : 'files'}`);\n logger.info(\"Run 'tuck sync' to commit changes\");\n};\n\nconst runRemove = async (paths: string[], options: RemoveOptions): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Verify tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n if (paths.length === 0) {\n await runInteractiveRemove(tuckDir);\n return;\n }\n\n // Validate and prepare files\n const filesToRemove = await validateAndPrepareFiles(paths, tuckDir);\n\n // Remove files\n await removeFiles(filesToRemove, tuckDir, options);\n\n logger.blank();\n logger.success(`Removed ${filesToRemove.length} ${filesToRemove.length === 1 ? 'item' : 'items'} from tracking`);\n logger.info(\"Run 'tuck sync' to commit changes\");\n};\n\nexport const removeCommand = new Command('remove')\n .description('Stop tracking dotfiles')\n .argument('[paths...]', 'Paths to dotfiles to untrack')\n .option('--delete', 'Also delete from tuck repository')\n .option('--keep-original', \"Don't restore symlinks to regular files\")\n .action(async (paths: string[], options: RemoveOptions) => {\n await runRemove(paths, options);\n });\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { join } from 'path';\nimport { prompts, logger, withSpinner } from '../ui/index.js';\nimport { getTuckDir, expandPath, pathExists } from '../lib/paths.js';\nimport { loadManifest, getAllTrackedFiles, updateFileInManifest } from '../lib/manifest.js';\nimport { stageAll, commit, getStatus, push, hasRemote } from '../lib/git.js';\nimport { copyFileOrDir, getFileChecksum } from '../lib/files.js';\nimport { runPreSyncHook, runPostSyncHook, type HookOptions } from '../lib/hooks.js';\nimport { NotInitializedError } from '../errors.js';\nimport type { SyncOptions, FileChange } from '../types.js';\n\ninterface SyncResult {\n modified: string[];\n added: string[];\n deleted: string[];\n commitHash?: string;\n}\n\nconst detectChanges = async (tuckDir: string): Promise<FileChange[]> => {\n const files = await getAllTrackedFiles(tuckDir);\n const changes: FileChange[] = [];\n\n for (const [, file] of Object.entries(files)) {\n const sourcePath = expandPath(file.source);\n\n // Check if source still exists\n if (!(await pathExists(sourcePath))) {\n changes.push({\n path: file.source,\n status: 'deleted',\n source: file.source,\n destination: file.destination,\n });\n continue;\n }\n\n // Check if file has changed compared to stored checksum\n try {\n const sourceChecksum = await getFileChecksum(sourcePath);\n if (sourceChecksum !== file.checksum) {\n changes.push({\n path: file.source,\n status: 'modified',\n source: file.source,\n destination: file.destination,\n });\n }\n } catch {\n changes.push({\n path: file.source,\n status: 'modified',\n source: file.source,\n destination: file.destination,\n });\n }\n }\n\n return changes;\n};\n\nconst generateCommitMessage = (result: SyncResult): string => {\n const parts: string[] = [];\n\n if (result.added.length > 0) {\n parts.push(`Add: ${result.added.join(', ')}`);\n }\n if (result.modified.length > 0) {\n parts.push(`Update: ${result.modified.join(', ')}`);\n }\n if (result.deleted.length > 0) {\n parts.push(`Remove: ${result.deleted.join(', ')}`);\n }\n\n if (parts.length === 0) {\n return 'Sync dotfiles';\n }\n\n const totalCount =\n result.added.length + result.modified.length + result.deleted.length;\n\n if (parts.length === 1 && totalCount <= 3) {\n return parts[0];\n }\n\n return `Sync: ${totalCount} file${totalCount > 1 ? 's' : ''} changed`;\n};\n\nconst syncFiles = async (\n tuckDir: string,\n changes: FileChange[],\n options: SyncOptions\n): Promise<SyncResult> => {\n const result: SyncResult = {\n modified: [],\n added: [],\n deleted: [],\n };\n\n // Prepare hook options\n const hookOptions: HookOptions = {\n skipHooks: options.noHooks,\n trustHooks: options.trustHooks,\n };\n\n // Run pre-sync hook\n await runPreSyncHook(tuckDir, hookOptions);\n\n // Process each change\n for (const change of changes) {\n const sourcePath = expandPath(change.source);\n const destPath = join(tuckDir, change.destination!);\n\n if (change.status === 'modified') {\n await withSpinner(`Syncing ${change.path}...`, async () => {\n await copyFileOrDir(sourcePath, destPath, { overwrite: true });\n\n // Update checksum in manifest\n const newChecksum = await getFileChecksum(destPath);\n const files = await getAllTrackedFiles(tuckDir);\n const fileId = Object.entries(files).find(([, f]) => f.source === change.source)?.[0];\n\n if (fileId) {\n await updateFileInManifest(tuckDir, fileId, {\n checksum: newChecksum,\n modified: new Date().toISOString(),\n });\n }\n });\n result.modified.push(change.path.split('/').pop() || change.path);\n } else if (change.status === 'deleted') {\n logger.warning(`Source file deleted: ${change.path}`);\n result.deleted.push(change.path.split('/').pop() || change.path);\n }\n }\n\n // Stage and commit if not --no-commit\n if (!options.noCommit && (result.modified.length > 0 || result.deleted.length > 0)) {\n await withSpinner('Staging changes...', async () => {\n await stageAll(tuckDir);\n });\n\n const message = options.message || generateCommitMessage(result);\n\n await withSpinner('Committing...', async () => {\n result.commitHash = await commit(tuckDir, message);\n });\n }\n\n // Run post-sync hook\n await runPostSyncHook(tuckDir, hookOptions);\n\n return result;\n};\n\nconst runInteractiveSync = async (tuckDir: string, options: SyncOptions = {}): Promise<void> => {\n prompts.intro('tuck sync');\n\n // Detect changes\n const spinner = prompts.spinner();\n spinner.start('Detecting changes...');\n const changes = await detectChanges(tuckDir);\n spinner.stop('Changes detected');\n\n if (changes.length === 0) {\n // Check for git changes\n const gitStatus = await getStatus(tuckDir);\n if (gitStatus.hasChanges) {\n prompts.log.info('No dotfile changes, but repository has uncommitted changes');\n\n const commitAnyway = await prompts.confirm('Commit repository changes?');\n if (commitAnyway) {\n const message = await prompts.text('Commit message:', {\n defaultValue: 'Update dotfiles',\n });\n\n await stageAll(tuckDir);\n const hash = await commit(tuckDir, message);\n prompts.log.success(`Committed: ${hash.slice(0, 7)}`);\n }\n } else {\n prompts.log.success('Everything is up to date');\n }\n return;\n }\n\n // Show changes\n console.log();\n console.log(chalk.bold('Changes detected:'));\n for (const change of changes) {\n if (change.status === 'modified') {\n console.log(chalk.yellow(` ~ ${change.path}`));\n } else if (change.status === 'deleted') {\n console.log(chalk.red(` - ${change.path}`));\n }\n }\n console.log();\n\n // Confirm\n const confirm = await prompts.confirm('Sync these changes?', true);\n if (!confirm) {\n prompts.cancel('Operation cancelled');\n return;\n }\n\n // Get commit message\n const autoMessage = generateCommitMessage({\n modified: changes.filter((c) => c.status === 'modified').map((c) => c.path),\n added: [],\n deleted: changes.filter((c) => c.status === 'deleted').map((c) => c.path),\n });\n\n const message = await prompts.text('Commit message:', {\n defaultValue: autoMessage,\n });\n\n // Sync\n const result = await syncFiles(tuckDir, changes, { message });\n\n console.log();\n if (result.commitHash) {\n prompts.log.success(`Committed: ${result.commitHash.slice(0, 7)}`);\n\n // Push by default if remote exists (unless --no-push specified)\n // Commander converts --no-push to push: false, default is push: true\n if (options.push !== false && (await hasRemote(tuckDir))) {\n const spinner2 = prompts.spinner();\n spinner2.start('Pushing to remote...');\n try {\n await push(tuckDir);\n spinner2.stop('Pushed to remote');\n } catch {\n spinner2.stop('Push failed (will retry on next sync)');\n }\n } else if (options.push === false) {\n prompts.log.info(\"Run 'tuck push' when ready to upload\");\n }\n }\n\n prompts.outro('Synced successfully!');\n};\n\nconst runSync = async (messageArg: string | undefined, options: SyncOptions): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Verify tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n // If no options (except --no-push), run interactive\n if (!messageArg && !options.message && !options.all && !options.noCommit && !options.amend) {\n await runInteractiveSync(tuckDir, options);\n return;\n }\n\n // Detect changes\n const changes = await detectChanges(tuckDir);\n\n if (changes.length === 0) {\n logger.info('No changes detected');\n return;\n }\n\n // Show changes\n logger.heading('Changes detected:');\n for (const change of changes) {\n logger.file(change.status === 'modified' ? 'modify' : 'delete', change.path);\n }\n logger.blank();\n\n // Sync\n const message = messageArg || options.message;\n const result = await syncFiles(tuckDir, changes, { ...options, message });\n\n logger.blank();\n logger.success(`Synced ${changes.length} file${changes.length > 1 ? 's' : ''}`);\n\n if (result.commitHash) {\n logger.info(`Commit: ${result.commitHash.slice(0, 7)}`);\n\n // Push by default unless --no-push\n // Commander converts --no-push to push: false, default is push: true\n if (options.push !== false && (await hasRemote(tuckDir))) {\n await withSpinner('Pushing to remote...', async () => {\n await push(tuckDir);\n });\n logger.success('Pushed to remote');\n } else if (options.push === false) {\n logger.info(\"Run 'tuck push' when ready to upload\");\n }\n }\n};\n\nexport const syncCommand = new Command('sync')\n .description('Sync changes to repository (commits and pushes)')\n .argument('[message]', 'Commit message')\n .option('-m, --message <msg>', 'Commit message')\n .option('-a, --all', 'Sync all tracked files, not just changed')\n .option('--no-commit', \"Stage changes but don't commit\")\n .option('--no-push', \"Commit but don't push to remote\")\n .option('--amend', 'Amend previous commit')\n .option('--no-hooks', 'Skip execution of pre/post sync hooks')\n .option('--trust-hooks', 'Trust and run hooks without confirmation (use with caution)')\n .action(async (messageArg: string | undefined, options: SyncOptions) => {\n await runSync(messageArg, options);\n });\n","import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport chalk from 'chalk';\nimport { loadConfig } from './config.js';\nimport { logger } from '../ui/logger.js';\nimport { prompts } from '../ui/prompts.js';\n\nconst execAsync = promisify(exec);\n\nexport type HookType = 'preSync' | 'postSync' | 'preRestore' | 'postRestore';\n\nexport interface HookResult {\n success: boolean;\n output?: string;\n error?: string;\n skipped?: boolean;\n}\n\nexport interface HookOptions {\n silent?: boolean;\n skipHooks?: boolean;\n trustHooks?: boolean;\n}\n\n/**\n * SECURITY: This function executes shell commands from the configuration file.\n * When cloning from untrusted repositories, hooks could contain malicious commands.\n * We require explicit user confirmation before executing any hooks.\n */\nexport const runHook = async (\n hookType: HookType,\n tuckDir: string,\n options?: HookOptions\n): Promise<HookResult> => {\n // If hooks are explicitly disabled, skip execution\n if (options?.skipHooks) {\n return { success: true, skipped: true };\n }\n\n const config = await loadConfig(tuckDir);\n const command = config.hooks[hookType];\n\n if (!command) {\n return { success: true };\n }\n\n // SECURITY: Always show the hook command and require confirmation\n // unless trustHooks is explicitly set (for non-interactive/scripted use)\n if (!options?.trustHooks) {\n console.log();\n console.log(chalk.yellow.bold('WARNING: Hook Execution'));\n console.log(chalk.dim('─'.repeat(50)));\n console.log(chalk.white(`Hook type: ${chalk.cyan(hookType)}`));\n console.log(chalk.white('Command:'));\n console.log(chalk.red(` ${command}`));\n console.log(chalk.dim('─'.repeat(50)));\n console.log(\n chalk.yellow(\n 'SECURITY: Hooks can execute arbitrary commands on your system.'\n )\n );\n console.log(\n chalk.yellow(\n 'Only proceed if you trust the source of this configuration.'\n )\n );\n console.log();\n\n const confirmed = await prompts.confirm(\n 'Execute this hook?',\n false // Default to NO for safety\n );\n\n if (!confirmed) {\n logger.warning(`Hook ${hookType} skipped by user`);\n return { success: true, skipped: true };\n }\n }\n\n if (!options?.silent) {\n logger.dim(`Running ${hookType} hook...`);\n }\n\n try {\n const { stdout, stderr } = await execAsync(command, {\n cwd: tuckDir,\n timeout: 30000, // 30 second timeout\n env: {\n ...process.env,\n TUCK_DIR: tuckDir,\n TUCK_HOOK: hookType,\n },\n });\n\n if (stdout && !options?.silent) {\n logger.dim(stdout.trim());\n }\n\n if (stderr && !options?.silent) {\n logger.warning(stderr.trim());\n }\n\n return { success: true, output: stdout };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n if (!options?.silent) {\n logger.error(`Hook ${hookType} failed: ${errorMessage}`);\n }\n\n return { success: false, error: errorMessage };\n }\n};\n\nexport const runPreSyncHook = async (\n tuckDir: string,\n options?: HookOptions\n): Promise<HookResult> => {\n return runHook('preSync', tuckDir, options);\n};\n\nexport const runPostSyncHook = async (\n tuckDir: string,\n options?: HookOptions\n): Promise<HookResult> => {\n return runHook('postSync', tuckDir, options);\n};\n\nexport const runPreRestoreHook = async (\n tuckDir: string,\n options?: HookOptions\n): Promise<HookResult> => {\n return runHook('preRestore', tuckDir, options);\n};\n\nexport const runPostRestoreHook = async (\n tuckDir: string,\n options?: HookOptions\n): Promise<HookResult> => {\n return runHook('postRestore', tuckDir, options);\n};\n\nexport const hasHook = async (hookType: HookType, tuckDir: string): Promise<boolean> => {\n const config = await loadConfig(tuckDir);\n return Boolean(config.hooks[hookType]);\n};\n\nexport const getHookCommand = async (\n hookType: HookType,\n tuckDir: string\n): Promise<string | undefined> => {\n const config = await loadConfig(tuckDir);\n return config.hooks[hookType];\n};\n\n/**\n * Check if any hooks are configured\n */\nexport const hasAnyHooks = async (tuckDir: string): Promise<boolean> => {\n const config = await loadConfig(tuckDir);\n return Boolean(\n config.hooks.preSync ||\n config.hooks.postSync ||\n config.hooks.preRestore ||\n config.hooks.postRestore\n );\n};\n\n/**\n * Get all configured hooks for display\n */\nexport const getAllHooks = async (\n tuckDir: string\n): Promise<Record<HookType, string | undefined>> => {\n const config = await loadConfig(tuckDir);\n return {\n preSync: config.hooks.preSync,\n postSync: config.hooks.postSync,\n preRestore: config.hooks.preRestore,\n postRestore: config.hooks.postRestore,\n };\n};\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { prompts, logger, withSpinner } from '../ui/index.js';\nimport { getTuckDir } from '../lib/paths.js';\nimport { loadManifest } from '../lib/manifest.js';\nimport {\n push,\n hasRemote,\n getRemoteUrl,\n getStatus,\n getCurrentBranch,\n addRemote,\n} from '../lib/git.js';\nimport { NotInitializedError, GitError } from '../errors.js';\nimport type { PushOptions } from '../types.js';\n\nconst runInteractivePush = async (tuckDir: string): Promise<void> => {\n prompts.intro('tuck push');\n\n // Check if remote exists\n const hasRemoteRepo = await hasRemote(tuckDir);\n\n if (!hasRemoteRepo) {\n prompts.log.warning('No remote configured');\n\n const addRemoteNow = await prompts.confirm('Would you like to add a remote?');\n if (!addRemoteNow) {\n prompts.cancel('No remote to push to');\n return;\n }\n\n const remoteUrl = await prompts.text('Enter remote URL:', {\n placeholder: 'git@github.com:user/dotfiles.git',\n validate: (value) => {\n if (!value) return 'Remote URL is required';\n return undefined;\n },\n });\n\n await addRemote(tuckDir, 'origin', remoteUrl);\n prompts.log.success('Remote added');\n }\n\n // Get current status\n const status = await getStatus(tuckDir);\n const branch = await getCurrentBranch(tuckDir);\n const remoteUrl = await getRemoteUrl(tuckDir);\n\n if (status.ahead === 0 && status.tracking) {\n prompts.log.success('Already up to date with remote');\n return;\n }\n\n // Show what will be pushed\n console.log();\n console.log(chalk.dim('Remote:'), remoteUrl);\n console.log(chalk.dim('Branch:'), branch);\n\n if (status.ahead > 0) {\n console.log(chalk.dim('Commits:'), chalk.green(`↑ ${status.ahead} to push`));\n }\n\n if (status.behind > 0) {\n console.log(chalk.dim('Warning:'), chalk.yellow(`↓ ${status.behind} commits behind remote`));\n\n const pullFirst = await prompts.confirm('Pull changes first?', true);\n if (pullFirst) {\n prompts.log.info(\"Run 'tuck pull' first, then push\");\n return;\n }\n }\n\n console.log();\n\n // Confirm\n const confirm = await prompts.confirm('Push to remote?', true);\n if (!confirm) {\n prompts.cancel('Operation cancelled');\n return;\n }\n\n // Push\n const needsUpstream = !status.tracking;\n\n await withSpinner('Pushing...', async () => {\n await push(tuckDir, {\n setUpstream: needsUpstream,\n branch: needsUpstream ? branch : undefined,\n });\n });\n\n prompts.log.success('Pushed successfully!');\n\n if (remoteUrl) {\n // Extract repo URL for display\n let viewUrl = remoteUrl;\n if (remoteUrl.startsWith('git@github.com:')) {\n viewUrl = remoteUrl\n .replace('git@github.com:', 'https://github.com/')\n .replace('.git', '');\n }\n console.log();\n console.log(chalk.dim('View at:'), chalk.cyan(viewUrl));\n }\n\n prompts.outro('');\n};\n\nconst runPush = async (options: PushOptions): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Verify tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n // If no options, run interactive\n if (!options.force && !options.setUpstream) {\n await runInteractivePush(tuckDir);\n return;\n }\n\n // Check if remote exists\n const hasRemoteRepo = await hasRemote(tuckDir);\n if (!hasRemoteRepo) {\n throw new GitError('No remote configured', \"Run 'tuck init -r <url>' or add a remote manually\");\n }\n\n const branch = await getCurrentBranch(tuckDir);\n\n await withSpinner('Pushing...', async () => {\n await push(tuckDir, {\n force: options.force,\n setUpstream: Boolean(options.setUpstream),\n branch: options.setUpstream || branch,\n });\n });\n\n logger.success('Pushed successfully!');\n};\n\nexport const pushCommand = new Command('push')\n .description('Push changes to remote repository')\n .option('-f, --force', 'Force push')\n .option('--set-upstream <name>', 'Set upstream branch')\n .action(async (options: PushOptions) => {\n await runPush(options);\n });\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { prompts, logger, withSpinner } from '../ui/index.js';\nimport { getTuckDir } from '../lib/paths.js';\nimport { loadManifest } from '../lib/manifest.js';\nimport {\n pull,\n fetch,\n hasRemote,\n getRemoteUrl,\n getStatus,\n getCurrentBranch,\n} from '../lib/git.js';\nimport { NotInitializedError, GitError } from '../errors.js';\nimport type { PullOptions } from '../types.js';\n\nconst runInteractivePull = async (tuckDir: string): Promise<void> => {\n prompts.intro('tuck pull');\n\n // Check if remote exists\n const hasRemoteRepo = await hasRemote(tuckDir);\n if (!hasRemoteRepo) {\n prompts.log.error('No remote configured');\n prompts.note(\"Run 'tuck init -r <url>' or add a remote manually\", 'Tip');\n return;\n }\n\n // Fetch first to get latest remote status\n await withSpinner('Fetching...', async () => {\n await fetch(tuckDir);\n });\n\n // Get current status\n const status = await getStatus(tuckDir);\n const branch = await getCurrentBranch(tuckDir);\n const remoteUrl = await getRemoteUrl(tuckDir);\n\n // Show status\n console.log();\n console.log(chalk.dim('Remote:'), remoteUrl);\n console.log(chalk.dim('Branch:'), branch);\n\n if (status.behind === 0) {\n prompts.log.success('Already up to date');\n return;\n }\n\n console.log(chalk.dim('Commits:'), chalk.yellow(`↓ ${status.behind} to pull`));\n\n if (status.ahead > 0) {\n console.log(\n chalk.dim('Note:'),\n chalk.yellow(`You also have ${status.ahead} local commit${status.ahead > 1 ? 's' : ''} to push`)\n );\n }\n\n // Check for local changes\n if (status.modified.length > 0 || status.staged.length > 0) {\n console.log();\n prompts.log.warning('You have uncommitted changes');\n console.log(chalk.dim('Modified:'), status.modified.join(', '));\n\n const continueAnyway = await prompts.confirm('Pull anyway? (may cause merge conflicts)');\n if (!continueAnyway) {\n prompts.cancel(\"Commit or stash your changes first with 'tuck sync'\");\n return;\n }\n }\n\n console.log();\n\n // Ask about rebase\n const useRebase = await prompts.confirm('Use rebase instead of merge?');\n\n // Pull\n await withSpinner('Pulling...', async () => {\n await pull(tuckDir, { rebase: useRebase });\n });\n\n prompts.log.success('Pulled successfully!');\n\n // Ask about restore\n const shouldRestore = await prompts.confirm('Restore updated dotfiles to system?', true);\n if (shouldRestore) {\n prompts.note(\"Run 'tuck restore --all' to restore all dotfiles\", 'Next step');\n }\n\n prompts.outro('');\n};\n\nconst runPull = async (options: PullOptions): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Verify tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n // If no options, run interactive\n if (!options.rebase && !options.restore) {\n await runInteractivePull(tuckDir);\n return;\n }\n\n // Check if remote exists\n const hasRemoteRepo = await hasRemote(tuckDir);\n if (!hasRemoteRepo) {\n throw new GitError('No remote configured', \"Run 'tuck init -r <url>' or add a remote manually\");\n }\n\n // Fetch first\n await withSpinner('Fetching...', async () => {\n await fetch(tuckDir);\n });\n\n // Pull\n await withSpinner('Pulling...', async () => {\n await pull(tuckDir, { rebase: options.rebase });\n });\n\n logger.success('Pulled successfully!');\n\n if (options.restore) {\n logger.info(\"Run 'tuck restore --all' to restore dotfiles\");\n }\n};\n\nexport const pullCommand = new Command('pull')\n .description('Pull changes from remote')\n .option('--rebase', 'Pull with rebase')\n .option('--restore', 'Also restore files to system after pull')\n .action(async (options: PullOptions) => {\n await runPull(options);\n });\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { join } from 'path';\nimport { chmod, stat } from 'fs/promises';\nimport { prompts, logger, withSpinner } from '../ui/index.js';\nimport { getTuckDir, expandPath, pathExists, collapsePath } from '../lib/paths.js';\nimport { loadManifest, getAllTrackedFiles, getTrackedFileBySource } from '../lib/manifest.js';\nimport { loadConfig } from '../lib/config.js';\nimport { copyFileOrDir, createSymlink } from '../lib/files.js';\nimport { createBackup } from '../lib/backup.js';\nimport { runPreRestoreHook, runPostRestoreHook, type HookOptions } from '../lib/hooks.js';\nimport { NotInitializedError, FileNotFoundError } from '../errors.js';\nimport { CATEGORIES } from '../constants.js';\nimport type { RestoreOptions } from '../types.js';\n\n/**\n * Fix permissions for SSH files after restore\n * SSH requires strict permissions: 700 for directories, 600 for private files\n */\nconst fixSSHPermissions = async (path: string): Promise<void> => {\n const expandedPath = expandPath(path);\n\n // Only fix permissions for SSH files\n // Check for files inside .ssh/ directory or the .ssh directory itself\n if (!path.includes('.ssh/') && !path.endsWith('.ssh')) {\n return;\n }\n\n try {\n const stats = await stat(expandedPath);\n\n if (stats.isDirectory()) {\n // Directories should be 700\n await chmod(expandedPath, 0o700);\n } else {\n // Files should be 600\n await chmod(expandedPath, 0o600);\n }\n } catch {\n // Ignore permission errors (might be on Windows)\n }\n};\n\n/**\n * Fix GPG permissions after restore\n */\nconst fixGPGPermissions = async (path: string): Promise<void> => {\n const expandedPath = expandPath(path);\n\n // Only fix permissions for GPG files\n // Check for files inside .gnupg/ directory or the .gnupg directory itself\n if (!path.includes('.gnupg/') && !path.endsWith('.gnupg')) {\n return;\n }\n\n try {\n const stats = await stat(expandedPath);\n\n if (stats.isDirectory()) {\n await chmod(expandedPath, 0o700);\n } else {\n await chmod(expandedPath, 0o600);\n }\n } catch {\n // Ignore permission errors\n }\n};\n\ninterface FileToRestore {\n id: string;\n source: string;\n destination: string;\n category: string;\n existsAtTarget: boolean;\n}\n\nconst prepareFilesToRestore = async (\n tuckDir: string,\n paths?: string[]\n): Promise<FileToRestore[]> => {\n const allFiles = await getAllTrackedFiles(tuckDir);\n const filesToRestore: FileToRestore[] = [];\n\n if (paths && paths.length > 0) {\n // Restore specific files\n for (const path of paths) {\n const expandedPath = expandPath(path);\n const collapsedPath = collapsePath(expandedPath);\n\n const tracked = await getTrackedFileBySource(tuckDir, collapsedPath);\n if (!tracked) {\n throw new FileNotFoundError(`Not tracked: ${path}`);\n }\n\n filesToRestore.push({\n id: tracked.id,\n source: tracked.file.source,\n destination: join(tuckDir, tracked.file.destination),\n category: tracked.file.category,\n existsAtTarget: await pathExists(expandedPath),\n });\n }\n } else {\n // Restore all files\n for (const [id, file] of Object.entries(allFiles)) {\n const targetPath = expandPath(file.source);\n filesToRestore.push({\n id,\n source: file.source,\n destination: join(tuckDir, file.destination),\n category: file.category,\n existsAtTarget: await pathExists(targetPath),\n });\n }\n }\n\n return filesToRestore;\n};\n\nconst restoreFiles = async (\n tuckDir: string,\n files: FileToRestore[],\n options: RestoreOptions\n): Promise<number> => {\n const config = await loadConfig(tuckDir);\n const useSymlink = options.symlink || config.files.strategy === 'symlink';\n const shouldBackup = options.backup ?? config.files.backupOnRestore;\n\n // Prepare hook options\n const hookOptions: HookOptions = {\n skipHooks: options.noHooks,\n trustHooks: options.trustHooks,\n };\n\n // Run pre-restore hook\n await runPreRestoreHook(tuckDir, hookOptions);\n\n let restoredCount = 0;\n\n for (const file of files) {\n const targetPath = expandPath(file.source);\n\n // Check if source exists in repository\n if (!(await pathExists(file.destination))) {\n logger.warning(`Source not found in repository: ${file.source}`);\n continue;\n }\n\n // Dry run - just show what would happen\n if (options.dryRun) {\n if (file.existsAtTarget) {\n logger.file('modify', `${file.source} (would overwrite)`);\n } else {\n logger.file('add', `${file.source} (would create)`);\n }\n continue;\n }\n\n // Create backup if needed\n if (shouldBackup && file.existsAtTarget) {\n await withSpinner(`Backing up ${file.source}...`, async () => {\n await createBackup(targetPath);\n });\n }\n\n // Restore file\n await withSpinner(`Restoring ${file.source}...`, async () => {\n if (useSymlink) {\n await createSymlink(file.destination, targetPath, { overwrite: true });\n } else {\n await copyFileOrDir(file.destination, targetPath, { overwrite: true });\n }\n\n // Fix permissions for sensitive files\n await fixSSHPermissions(file.source);\n await fixGPGPermissions(file.source);\n });\n\n restoredCount++;\n }\n\n // Run post-restore hook\n await runPostRestoreHook(tuckDir, hookOptions);\n\n return restoredCount;\n};\n\nconst runInteractiveRestore = async (tuckDir: string): Promise<void> => {\n prompts.intro('tuck restore');\n\n // Get all tracked files\n const files = await prepareFilesToRestore(tuckDir);\n\n if (files.length === 0) {\n prompts.log.warning('No files to restore');\n prompts.note(\"Run 'tuck add <path>' to track files first\", 'Tip');\n return;\n }\n\n // Let user select files to restore\n const fileOptions = files.map((file) => {\n const categoryConfig = CATEGORIES[file.category] || { icon: '📄' };\n const status = file.existsAtTarget ? chalk.yellow('(exists, will backup)') : '';\n\n return {\n value: file.id,\n label: `${categoryConfig.icon} ${file.source} ${status}`,\n hint: file.category,\n };\n });\n\n const selectedIds = await prompts.multiselect('Select files to restore:', fileOptions, true);\n\n if (selectedIds.length === 0) {\n prompts.cancel('No files selected');\n return;\n }\n\n const selectedFiles = files.filter((f) => selectedIds.includes(f.id));\n\n // Check for files that exist\n const existingFiles = selectedFiles.filter((f) => f.existsAtTarget);\n if (existingFiles.length > 0) {\n console.log();\n prompts.log.warning(\n `${existingFiles.length} file${existingFiles.length > 1 ? 's' : ''} will be backed up:`\n );\n existingFiles.forEach((f) => console.log(chalk.dim(` ${f.source}`)));\n console.log();\n }\n\n // Ask about strategy\n const useSymlink = await prompts.select('Restore method:', [\n { value: false, label: 'Copy files', hint: 'Recommended' },\n { value: true, label: 'Create symlinks', hint: 'Files stay in tuck repo' },\n ]);\n\n // Confirm\n const confirm = await prompts.confirm(\n `Restore ${selectedFiles.length} file${selectedFiles.length > 1 ? 's' : ''}?`,\n true\n );\n\n if (!confirm) {\n prompts.cancel('Operation cancelled');\n return;\n }\n\n // Restore\n const restoredCount = await restoreFiles(tuckDir, selectedFiles, {\n symlink: useSymlink as boolean,\n backup: true,\n });\n\n console.log();\n prompts.outro(`Restored ${restoredCount} file${restoredCount > 1 ? 's' : ''}`);\n};\n\nconst runRestore = async (paths: string[], options: RestoreOptions): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Verify tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n // If no paths and no --all, run interactive\n if (paths.length === 0 && !options.all) {\n await runInteractiveRestore(tuckDir);\n return;\n }\n\n // Prepare files to restore\n const files = await prepareFilesToRestore(tuckDir, options.all ? undefined : paths);\n\n if (files.length === 0) {\n logger.warning('No files to restore');\n return;\n }\n\n // Show what will be restored\n if (options.dryRun) {\n logger.heading('Dry run - would restore:');\n } else {\n logger.heading('Restoring:');\n }\n\n // Restore files\n const restoredCount = await restoreFiles(tuckDir, files, options);\n\n logger.blank();\n\n if (options.dryRun) {\n logger.info(`Would restore ${files.length} file${files.length > 1 ? 's' : ''}`);\n } else {\n logger.success(`Restored ${restoredCount} file${restoredCount > 1 ? 's' : ''}`);\n }\n};\n\nexport const restoreCommand = new Command('restore')\n .description('Restore dotfiles to the system')\n .argument('[paths...]', 'Paths to restore (or use --all)')\n .option('-a, --all', 'Restore all tracked files')\n .option('--symlink', 'Create symlinks instead of copies')\n .option('--backup', 'Backup existing files before restore')\n .option('--no-backup', 'Skip backup of existing files')\n .option('--dry-run', 'Show what would be done')\n .option('--no-hooks', 'Skip execution of pre/post restore hooks')\n .option('--trust-hooks', 'Trust and run hooks without confirmation (use with caution)')\n .action(async (paths: string[], options: RestoreOptions) => {\n await runRestore(paths, options);\n });\n","import { join } from 'path';\nimport { readdir, rm } from 'fs/promises';\nimport { copy, ensureDir, pathExists } from 'fs-extra';\nimport { BACKUP_DIR } from '../constants.js';\nimport { expandPath, collapsePath, pathExists as checkPathExists } from './paths.js';\n\nexport interface BackupInfo {\n path: string;\n date: Date;\n files: string[];\n}\n\nexport interface BackupResult {\n originalPath: string;\n backupPath: string;\n date: Date;\n}\n\nconst getBackupDir = (): string => {\n return expandPath(BACKUP_DIR);\n};\n\nconst formatDateForBackup = (date: Date): string => {\n return date.toISOString().slice(0, 10); // YYYY-MM-DD\n};\n\nconst getTimestampedBackupDir = (date: Date): string => {\n const backupRoot = getBackupDir();\n const timestamp = formatDateForBackup(date);\n return join(backupRoot, timestamp);\n};\n\nexport const createBackup = async (\n sourcePath: string,\n customBackupDir?: string\n): Promise<BackupResult> => {\n const expandedSource = expandPath(sourcePath);\n const date = new Date();\n\n if (!(await checkPathExists(expandedSource))) {\n throw new Error(`Source path does not exist: ${sourcePath}`);\n }\n\n // Create backup directory with date\n const backupRoot = customBackupDir\n ? expandPath(customBackupDir)\n : getTimestampedBackupDir(date);\n await ensureDir(backupRoot);\n\n // Generate backup filename that preserves structure\n const collapsed = collapsePath(expandedSource);\n const backupName = collapsed\n .replace(/^~\\//, '')\n .replace(/\\//g, '_')\n .replace(/^\\./, 'dot-');\n\n // Add timestamp to handle multiple backups of same file in a day\n const timestamp = date.toISOString().replace(/[:.]/g, '-').slice(11, 19);\n const backupPath = join(backupRoot, `${backupName}_${timestamp}`);\n\n await copy(expandedSource, backupPath, { overwrite: true });\n\n return {\n originalPath: expandedSource,\n backupPath,\n date,\n };\n};\n\nexport const createMultipleBackups = async (\n sourcePaths: string[],\n customBackupDir?: string\n): Promise<BackupResult[]> => {\n const results: BackupResult[] = [];\n\n for (const path of sourcePaths) {\n const result = await createBackup(path, customBackupDir);\n results.push(result);\n }\n\n return results;\n};\n\nexport const listBackups = async (): Promise<BackupInfo[]> => {\n const backupRoot = getBackupDir();\n\n if (!(await pathExists(backupRoot))) {\n return [];\n }\n\n const backups: BackupInfo[] = [];\n const dateDirs = await readdir(backupRoot, { withFileTypes: true });\n\n for (const dateDir of dateDirs) {\n if (!dateDir.isDirectory()) continue;\n\n const datePath = join(backupRoot, dateDir.name);\n const files = await readdir(datePath);\n\n // Parse date from directory name\n const dateMatch = dateDir.name.match(/^(\\d{4})-(\\d{2})-(\\d{2})$/);\n if (!dateMatch) continue;\n\n const date = new Date(`${dateMatch[1]}-${dateMatch[2]}-${dateMatch[3]}`);\n\n backups.push({\n path: datePath,\n date,\n files: files.map((f) => join(datePath, f)),\n });\n }\n\n // Sort by date, newest first\n return backups.sort((a, b) => b.date.getTime() - a.date.getTime());\n};\n\nexport const getBackupsByDate = async (date: Date): Promise<string[]> => {\n const backupDir = getTimestampedBackupDir(date);\n\n if (!(await pathExists(backupDir))) {\n return [];\n }\n\n const files = await readdir(backupDir);\n return files.map((f) => join(backupDir, f));\n};\n\nexport const restoreBackup = async (backupPath: string, targetPath: string): Promise<void> => {\n const expandedBackup = expandPath(backupPath);\n const expandedTarget = expandPath(targetPath);\n\n if (!(await checkPathExists(expandedBackup))) {\n throw new Error(`Backup not found: ${backupPath}`);\n }\n\n // Create backup of current state before restoring\n if (await checkPathExists(expandedTarget)) {\n await createBackup(expandedTarget);\n }\n\n await copy(expandedBackup, expandedTarget, { overwrite: true });\n};\n\nexport const deleteBackup = async (backupPath: string): Promise<void> => {\n const expandedPath = expandPath(backupPath);\n\n if (await checkPathExists(expandedPath)) {\n await rm(expandedPath, { recursive: true });\n }\n};\n\nexport const cleanOldBackups = async (daysToKeep: number): Promise<number> => {\n const backups = await listBackups();\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - daysToKeep);\n\n let deletedCount = 0;\n\n for (const backup of backups) {\n if (backup.date < cutoffDate) {\n await rm(backup.path, { recursive: true });\n deletedCount++;\n }\n }\n\n return deletedCount;\n};\n\nexport const getBackupSize = async (): Promise<number> => {\n const backups = await listBackups();\n let totalSize = 0;\n\n for (const backup of backups) {\n for (const file of backup.files) {\n const { stat } = await import('fs/promises');\n try {\n const stats = await stat(file);\n totalSize += stats.size;\n } catch {\n // Ignore errors\n }\n }\n }\n\n return totalSize;\n};\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { prompts, formatStatus } from '../ui/index.js';\nimport { getTuckDir, collapsePath, expandPath, pathExists } from '../lib/paths.js';\nimport { loadManifest, getAllTrackedFiles } from '../lib/manifest.js';\nimport { getStatus, hasRemote, getRemoteUrl, getCurrentBranch } from '../lib/git.js';\nimport { getFileChecksum } from '../lib/files.js';\nimport { NotInitializedError } from '../errors.js';\nimport type { StatusOptions, FileChange } from '../types.js';\n\ninterface TuckStatus {\n tuckDir: string;\n branch: string;\n remote?: string;\n remoteStatus: 'up-to-date' | 'ahead' | 'behind' | 'diverged' | 'no-remote';\n ahead: number;\n behind: number;\n trackedCount: number;\n changes: FileChange[];\n gitChanges: {\n staged: string[];\n modified: string[];\n untracked: string[];\n };\n}\n\nconst detectFileChanges = async (tuckDir: string): Promise<FileChange[]> => {\n const files = await getAllTrackedFiles(tuckDir);\n const changes: FileChange[] = [];\n\n for (const [, file] of Object.entries(files)) {\n const sourcePath = expandPath(file.source);\n\n // Check if source still exists\n if (!(await pathExists(sourcePath))) {\n changes.push({\n path: file.source,\n status: 'deleted',\n source: file.source,\n destination: file.destination,\n });\n continue;\n }\n\n // Check if file has changed\n try {\n const sourceChecksum = await getFileChecksum(sourcePath);\n if (sourceChecksum !== file.checksum) {\n changes.push({\n path: file.source,\n status: 'modified',\n source: file.source,\n destination: file.destination,\n });\n }\n } catch {\n // Error reading file, mark as modified\n changes.push({\n path: file.source,\n status: 'modified',\n source: file.source,\n destination: file.destination,\n });\n }\n }\n\n return changes;\n};\n\nconst getFullStatus = async (tuckDir: string): Promise<TuckStatus> => {\n const manifest = await loadManifest(tuckDir);\n const gitStatus = await getStatus(tuckDir);\n const branch = await getCurrentBranch(tuckDir);\n const hasRemoteRepo = await hasRemote(tuckDir);\n const remoteUrl = hasRemoteRepo ? await getRemoteUrl(tuckDir) : undefined;\n\n let remoteStatus: TuckStatus['remoteStatus'] = 'no-remote';\n if (hasRemoteRepo) {\n if (gitStatus.ahead > 0 && gitStatus.behind > 0) {\n remoteStatus = 'diverged';\n } else if (gitStatus.ahead > 0) {\n remoteStatus = 'ahead';\n } else if (gitStatus.behind > 0) {\n remoteStatus = 'behind';\n } else {\n remoteStatus = 'up-to-date';\n }\n }\n\n const fileChanges = await detectFileChanges(tuckDir);\n\n return {\n tuckDir,\n branch,\n remote: remoteUrl || undefined,\n remoteStatus,\n ahead: gitStatus.ahead,\n behind: gitStatus.behind,\n trackedCount: Object.keys(manifest.files).length,\n changes: fileChanges,\n gitChanges: {\n staged: gitStatus.staged,\n modified: gitStatus.modified,\n untracked: gitStatus.untracked,\n },\n };\n};\n\nconst printStatus = (status: TuckStatus): void => {\n prompts.intro('tuck status');\n\n // Repository info\n console.log();\n console.log(chalk.dim('Repository:'), collapsePath(status.tuckDir));\n console.log(chalk.dim('Branch:'), chalk.cyan(status.branch));\n\n if (status.remote) {\n console.log(chalk.dim('Remote:'), status.remote);\n\n let remoteInfo = '';\n switch (status.remoteStatus) {\n case 'up-to-date':\n remoteInfo = chalk.green('up to date');\n break;\n case 'ahead':\n remoteInfo = chalk.yellow(`${status.ahead} commit${status.ahead > 1 ? 's' : ''} ahead`);\n break;\n case 'behind':\n remoteInfo = chalk.yellow(`${status.behind} commit${status.behind > 1 ? 's' : ''} behind`);\n break;\n case 'diverged':\n remoteInfo = chalk.red(`diverged (${status.ahead} ahead, ${status.behind} behind)`);\n break;\n }\n console.log(chalk.dim('Status:'), remoteInfo);\n } else {\n console.log(chalk.dim('Remote:'), chalk.yellow('not configured'));\n }\n\n console.log();\n console.log(chalk.dim('Tracked files:'), status.trackedCount);\n\n // File changes\n if (status.changes.length > 0) {\n console.log();\n console.log(chalk.bold('Changes detected:'));\n for (const change of status.changes) {\n const statusText = formatStatus(change.status);\n console.log(` ${statusText}: ${chalk.cyan(change.path)}`);\n }\n }\n\n // Git changes in repository\n const hasGitChanges =\n status.gitChanges.staged.length > 0 ||\n status.gitChanges.modified.length > 0 ||\n status.gitChanges.untracked.length > 0;\n\n if (hasGitChanges) {\n console.log();\n console.log(chalk.bold('Repository changes:'));\n\n if (status.gitChanges.staged.length > 0) {\n console.log(chalk.green(' Staged:'));\n status.gitChanges.staged.forEach((f) => console.log(chalk.green(` + ${f}`)));\n }\n\n if (status.gitChanges.modified.length > 0) {\n console.log(chalk.yellow(' Modified:'));\n status.gitChanges.modified.forEach((f) => console.log(chalk.yellow(` ~ ${f}`)));\n }\n\n if (status.gitChanges.untracked.length > 0) {\n console.log(chalk.dim(' Untracked:'));\n status.gitChanges.untracked.forEach((f) => console.log(chalk.dim(` ? ${f}`)));\n }\n }\n\n console.log();\n\n // Suggestions\n if (status.changes.length > 0) {\n prompts.note(\"Run 'tuck sync' to commit changes\", 'Next step');\n } else if (status.remoteStatus === 'ahead') {\n prompts.note(\"Run 'tuck push' to push changes to remote\", 'Next step');\n } else if (status.remoteStatus === 'behind') {\n prompts.note(\"Run 'tuck pull' to pull changes from remote\", 'Next step');\n } else if (status.trackedCount === 0) {\n prompts.note(\"Run 'tuck add <path>' to start tracking files\", 'Next step');\n } else {\n prompts.outro('Everything is up to date');\n }\n};\n\nconst printShortStatus = (status: TuckStatus): void => {\n const parts: string[] = [];\n\n parts.push(`[${status.branch}]`);\n\n if (status.remoteStatus === 'ahead') {\n parts.push(`↑${status.ahead}`);\n } else if (status.remoteStatus === 'behind') {\n parts.push(`↓${status.behind}`);\n } else if (status.remoteStatus === 'diverged') {\n parts.push(`↑${status.ahead}↓${status.behind}`);\n }\n\n if (status.changes.length > 0) {\n const modified = status.changes.filter((c) => c.status === 'modified').length;\n const deleted = status.changes.filter((c) => c.status === 'deleted').length;\n if (modified > 0) parts.push(`~${modified}`);\n if (deleted > 0) parts.push(`-${deleted}`);\n }\n\n parts.push(`(${status.trackedCount} tracked)`);\n\n console.log(parts.join(' '));\n};\n\nconst printJsonStatus = (status: TuckStatus): void => {\n console.log(JSON.stringify(status, null, 2));\n};\n\nconst runStatus = async (options: StatusOptions): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Verify tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n const status = await getFullStatus(tuckDir);\n\n if (options.json) {\n printJsonStatus(status);\n } else if (options.short) {\n printShortStatus(status);\n } else {\n printStatus(status);\n }\n};\n\nexport const statusCommand = new Command('status')\n .description('Show current tracking status')\n .option('--short', 'Short format')\n .option('--json', 'Output as JSON')\n .action(async (options: StatusOptions) => {\n await runStatus(options);\n });\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { prompts, logger, formatCount } from '../ui/index.js';\nimport { getTuckDir } from '../lib/paths.js';\nimport { loadManifest, getAllTrackedFiles } from '../lib/manifest.js';\nimport { NotInitializedError } from '../errors.js';\nimport { CATEGORIES } from '../constants.js';\nimport type { ListOptions } from '../types.js';\n\ninterface CategoryGroup {\n name: string;\n icon: string;\n files: { id: string; source: string; destination: string; isDir: boolean }[];\n}\n\nconst groupByCategory = async (tuckDir: string): Promise<CategoryGroup[]> => {\n const files = await getAllTrackedFiles(tuckDir);\n const groups: Map<string, CategoryGroup> = new Map();\n\n for (const [id, file] of Object.entries(files)) {\n const category = file.category;\n const categoryConfig = CATEGORIES[category] || { icon: '📄' };\n\n if (!groups.has(category)) {\n groups.set(category, {\n name: category,\n icon: categoryConfig.icon,\n files: [],\n });\n }\n\n groups.get(category)!.files.push({\n id,\n source: file.source,\n destination: file.destination,\n isDir: file.destination.endsWith('/') || file.destination.includes('nvim'),\n });\n }\n\n // Sort groups by name and files within each group\n return Array.from(groups.values())\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((group) => ({\n ...group,\n files: group.files.sort((a, b) => a.source.localeCompare(b.source)),\n }));\n};\n\nconst printList = (groups: CategoryGroup[]): void => {\n prompts.intro('tuck list');\n\n if (groups.length === 0) {\n prompts.log.warning('No files are currently tracked');\n prompts.note(\"Run 'tuck add <path>' to start tracking files\", 'Tip');\n return;\n }\n\n let totalFiles = 0;\n\n for (const group of groups) {\n const fileCount = group.files.length;\n totalFiles += fileCount;\n\n console.log();\n console.log(\n chalk.bold(`${group.icon} ${group.name}`) +\n chalk.dim(` (${formatCount(fileCount, 'file')})`)\n );\n\n group.files.forEach((file, index) => {\n const isLast = index === group.files.length - 1;\n const prefix = isLast ? '└── ' : '├── ';\n const name = file.source.split('/').pop() || file.source;\n const arrow = chalk.dim(' → ');\n const dest = chalk.dim(file.source);\n\n console.log(chalk.dim(prefix) + chalk.cyan(name) + arrow + dest);\n });\n }\n\n console.log();\n prompts.outro(`Total: ${formatCount(totalFiles, 'tracked item')}`);\n};\n\nconst printPathsOnly = (groups: CategoryGroup[]): void => {\n for (const group of groups) {\n for (const file of group.files) {\n console.log(file.source);\n }\n }\n};\n\nconst printJson = (groups: CategoryGroup[]): void => {\n const output = groups.reduce(\n (acc, group) => {\n acc[group.name] = group.files.map((f) => ({\n source: f.source,\n destination: f.destination,\n }));\n return acc;\n },\n {} as Record<string, { source: string; destination: string }[]>\n );\n\n console.log(JSON.stringify(output, null, 2));\n};\n\nconst runList = async (options: ListOptions): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Verify tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n let groups = await groupByCategory(tuckDir);\n\n // Filter by category if specified\n if (options.category) {\n groups = groups.filter((g) => g.name === options.category);\n if (groups.length === 0) {\n logger.warning(`No files found in category: ${options.category}`);\n return;\n }\n }\n\n // Output based on format\n if (options.json) {\n printJson(groups);\n } else if (options.paths) {\n printPathsOnly(groups);\n } else {\n printList(groups);\n }\n};\n\nexport const listCommand = new Command('list')\n .description('List all tracked files')\n .option('-c, --category <name>', 'Filter by category')\n .option('--paths', 'Show only paths')\n .option('--json', 'Output as JSON')\n .action(async (options: ListOptions) => {\n await runList(options);\n });\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { join } from 'path';\nimport { prompts, logger } from '../ui/index.js';\nimport { getTuckDir, expandPath, pathExists, collapsePath } from '../lib/paths.js';\nimport { loadManifest, getAllTrackedFiles, getTrackedFileBySource } from '../lib/manifest.js';\nimport { getDiff } from '../lib/git.js';\nimport { getFileChecksum } from '../lib/files.js';\nimport { NotInitializedError, FileNotFoundError } from '../errors.js';\nimport type { DiffOptions } from '../types.js';\nimport { readFile } from 'fs/promises';\n\ninterface FileDiff {\n source: string;\n destination: string;\n hasChanges: boolean;\n systemContent?: string;\n repoContent?: string;\n}\n\nconst getFileDiff = async (tuckDir: string, source: string): Promise<FileDiff> => {\n const tracked = await getTrackedFileBySource(tuckDir, source);\n if (!tracked) {\n throw new FileNotFoundError(`Not tracked: ${source}`);\n }\n\n const systemPath = expandPath(source);\n const repoPath = join(tuckDir, tracked.file.destination);\n\n const diff: FileDiff = {\n source,\n destination: tracked.file.destination,\n hasChanges: false,\n };\n\n // Check if system file exists\n if (!(await pathExists(systemPath))) {\n diff.hasChanges = true;\n if (await pathExists(repoPath)) {\n diff.repoContent = await readFile(repoPath, 'utf-8');\n }\n return diff;\n }\n\n // Check if repo file exists\n if (!(await pathExists(repoPath))) {\n diff.hasChanges = true;\n diff.systemContent = await readFile(systemPath, 'utf-8');\n return diff;\n }\n\n // Compare checksums\n const systemChecksum = await getFileChecksum(systemPath);\n const repoChecksum = await getFileChecksum(repoPath);\n\n if (systemChecksum !== repoChecksum) {\n diff.hasChanges = true;\n diff.systemContent = await readFile(systemPath, 'utf-8');\n diff.repoContent = await readFile(repoPath, 'utf-8');\n }\n\n return diff;\n};\n\nconst formatUnifiedDiff = (\n source: string,\n systemContent?: string,\n repoContent?: string\n): string => {\n const lines: string[] = [];\n\n lines.push(chalk.bold(`--- a/${source} (system)`));\n lines.push(chalk.bold(`+++ b/${source} (repository)`));\n\n if (!systemContent && repoContent) {\n // File only in repo\n lines.push(chalk.red('File missing on system'));\n lines.push(chalk.dim('Repository content:'));\n repoContent.split('\\n').forEach((line) => {\n lines.push(chalk.green(`+ ${line}`));\n });\n } else if (systemContent && !repoContent) {\n // File only on system\n lines.push(chalk.yellow('File not yet synced to repository'));\n lines.push(chalk.dim('System content:'));\n systemContent.split('\\n').forEach((line) => {\n lines.push(chalk.red(`- ${line}`));\n });\n } else if (systemContent && repoContent) {\n // Simple line-by-line diff\n const systemLines = systemContent.split('\\n');\n const repoLines = repoContent.split('\\n');\n\n const maxLines = Math.max(systemLines.length, repoLines.length);\n\n let inDiff = false;\n let diffStart = 0;\n\n for (let i = 0; i < maxLines; i++) {\n const sysLine = systemLines[i];\n const repoLine = repoLines[i];\n\n if (sysLine !== repoLine) {\n if (!inDiff) {\n inDiff = true;\n diffStart = i;\n lines.push(chalk.cyan(`@@ -${i + 1} +${i + 1} @@`));\n }\n\n if (sysLine !== undefined) {\n lines.push(chalk.red(`- ${sysLine}`));\n }\n if (repoLine !== undefined) {\n lines.push(chalk.green(`+ ${repoLine}`));\n }\n } else if (inDiff) {\n // Show a bit of context then stop\n lines.push(chalk.dim(` ${sysLine || ''}`));\n if (i - diffStart > 3) {\n inDiff = false;\n }\n }\n }\n }\n\n return lines.join('\\n');\n};\n\nconst runDiff = async (paths: string[], options: DiffOptions): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Verify tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n // If --staged, show git diff\n if (options.staged) {\n const diff = await getDiff(tuckDir, { staged: true, stat: options.stat });\n if (diff) {\n console.log(diff);\n } else {\n logger.info('No staged changes');\n }\n return;\n }\n\n // If no paths, show all changed files\n if (paths.length === 0) {\n const allFiles = await getAllTrackedFiles(tuckDir);\n const changedFiles: FileDiff[] = [];\n\n for (const [, file] of Object.entries(allFiles)) {\n const diff = await getFileDiff(tuckDir, file.source);\n if (diff.hasChanges) {\n changedFiles.push(diff);\n }\n }\n\n if (changedFiles.length === 0) {\n logger.success('No differences found');\n return;\n }\n\n if (options.stat) {\n // Show summary only\n prompts.intro('tuck diff');\n console.log();\n console.log(chalk.bold(`${changedFiles.length} file${changedFiles.length > 1 ? 's' : ''} changed:`));\n console.log();\n\n for (const diff of changedFiles) {\n console.log(chalk.yellow(` ~ ${diff.source}`));\n }\n\n console.log();\n return;\n }\n\n // Show full diff for each file\n for (const diff of changedFiles) {\n console.log();\n console.log(formatUnifiedDiff(diff.source, diff.systemContent, diff.repoContent));\n console.log();\n }\n\n return;\n }\n\n // Show diff for specific files\n for (const path of paths) {\n const expandedPath = expandPath(path);\n const collapsedPath = collapsePath(expandedPath);\n\n const diff = await getFileDiff(tuckDir, collapsedPath);\n\n if (!diff.hasChanges) {\n logger.info(`No changes: ${path}`);\n continue;\n }\n\n if (options.stat) {\n console.log(chalk.yellow(`~ ${path}`));\n } else {\n console.log(formatUnifiedDiff(path, diff.systemContent, diff.repoContent));\n console.log();\n }\n }\n};\n\nexport const diffCommand = new Command('diff')\n .description('Show differences between system and repository')\n .argument('[paths...]', 'Specific files to diff')\n .option('--staged', 'Show staged git changes')\n .option('--stat', 'Show diffstat only')\n .action(async (paths: string[], options: DiffOptions) => {\n await runDiff(paths, options);\n });\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { spawn } from 'child_process';\nimport { prompts, logger } from '../ui/index.js';\nimport { getTuckDir, getConfigPath, collapsePath } from '../lib/paths.js';\nimport { loadConfig, saveConfig, resetConfig } from '../lib/config.js';\nimport { loadManifest } from '../lib/manifest.js';\nimport { NotInitializedError, ConfigError } from '../errors.js';\nimport type { TuckConfigOutput } from '../schemas/config.schema.js';\n\nconst printConfig = (config: TuckConfigOutput): void => {\n console.log(JSON.stringify(config, null, 2));\n};\n\nconst getNestedValue = (obj: Record<string, unknown>, path: string): unknown => {\n const keys = path.split('.');\n let current: unknown = obj;\n\n for (const key of keys) {\n if (current === null || current === undefined) {\n return undefined;\n }\n if (typeof current !== 'object') {\n return undefined;\n }\n current = (current as Record<string, unknown>)[key];\n }\n\n return current;\n};\n\nconst setNestedValue = (\n obj: Record<string, unknown>,\n path: string,\n value: unknown\n): void => {\n const keys = path.split('.');\n let current = obj;\n\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n if (!(key in current) || typeof current[key] !== 'object') {\n current[key] = {};\n }\n current = current[key] as Record<string, unknown>;\n }\n\n current[keys[keys.length - 1]] = value;\n};\n\nconst parseValue = (value: string): unknown => {\n // Try to parse as JSON\n try {\n return JSON.parse(value);\n } catch {\n // Return as string if not valid JSON\n return value;\n }\n};\n\nconst runConfigGet = async (key: string): Promise<void> => {\n const tuckDir = getTuckDir();\n const config = await loadConfig(tuckDir);\n\n const value = getNestedValue(config as unknown as Record<string, unknown>, key);\n\n if (value === undefined) {\n logger.error(`Key not found: ${key}`);\n return;\n }\n\n if (typeof value === 'object') {\n console.log(JSON.stringify(value, null, 2));\n } else {\n console.log(value);\n }\n};\n\nconst runConfigSet = async (key: string, value: string): Promise<void> => {\n const tuckDir = getTuckDir();\n const config = await loadConfig(tuckDir);\n\n const parsedValue = parseValue(value);\n const configObj = config as unknown as Record<string, unknown>;\n\n setNestedValue(configObj, key, parsedValue);\n\n await saveConfig(config, tuckDir);\n logger.success(`Set ${key} = ${JSON.stringify(parsedValue)}`);\n};\n\nconst runConfigList = async (): Promise<void> => {\n const tuckDir = getTuckDir();\n const config = await loadConfig(tuckDir);\n\n prompts.intro('tuck config');\n console.log();\n console.log(chalk.dim('Configuration file:'), collapsePath(getConfigPath(tuckDir)));\n console.log();\n\n printConfig(config);\n};\n\nconst runConfigEdit = async (): Promise<void> => {\n const tuckDir = getTuckDir();\n const configPath = getConfigPath(tuckDir);\n\n const editor = process.env.EDITOR || process.env.VISUAL || 'vim';\n\n logger.info(`Opening ${collapsePath(configPath)} in ${editor}...`);\n\n return new Promise((resolve, reject) => {\n const child = spawn(editor, [configPath], {\n stdio: 'inherit',\n });\n\n child.on('exit', (code) => {\n if (code === 0) {\n logger.success('Configuration updated');\n resolve();\n } else {\n reject(new ConfigError(`Editor exited with code ${code}`));\n }\n });\n\n child.on('error', (err) => {\n reject(new ConfigError(`Failed to open editor: ${err.message}`));\n });\n });\n};\n\nconst runConfigReset = async (): Promise<void> => {\n const tuckDir = getTuckDir();\n\n const confirm = await prompts.confirm('Reset configuration to defaults? This cannot be undone.', false);\n\n if (!confirm) {\n prompts.cancel('Operation cancelled');\n return;\n }\n\n await resetConfig(tuckDir);\n logger.success('Configuration reset to defaults');\n};\n\nexport const configCommand = new Command('config')\n .description('Manage tuck configuration')\n .addCommand(\n new Command('get')\n .description('Get a config value')\n .argument('<key>', 'Config key (e.g., \"repository.autoCommit\")')\n .action(async (key: string) => {\n const tuckDir = getTuckDir();\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n await runConfigGet(key);\n })\n )\n .addCommand(\n new Command('set')\n .description('Set a config value')\n .argument('<key>', 'Config key')\n .argument('<value>', 'Value to set (JSON or string)')\n .action(async (key: string, value: string) => {\n const tuckDir = getTuckDir();\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n await runConfigSet(key, value);\n })\n )\n .addCommand(\n new Command('list')\n .description('List all config')\n .action(async () => {\n const tuckDir = getTuckDir();\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n await runConfigList();\n })\n )\n .addCommand(\n new Command('edit')\n .description('Open config in editor')\n .action(async () => {\n const tuckDir = getTuckDir();\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n await runConfigEdit();\n })\n )\n .addCommand(\n new Command('reset')\n .description('Reset to defaults')\n .action(async () => {\n const tuckDir = getTuckDir();\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n await runConfigReset();\n })\n );\n","import { Command } from 'commander';\nimport { join } from 'path';\nimport { readFile, rm, chmod, stat } from 'fs/promises';\nimport { ensureDir, pathExists as fsPathExists } from 'fs-extra';\nimport { tmpdir } from 'os';\nimport chalk from 'chalk';\nimport { banner, prompts, logger } from '../ui/index.js';\nimport { expandPath, pathExists, collapsePath, validateSafeSourcePath } from '../lib/paths.js';\nimport { cloneRepo } from '../lib/git.js';\nimport {\n isGhInstalled,\n findDotfilesRepo,\n ghCloneRepo,\n repoExists,\n} from '../lib/github.js';\nimport { createPreApplySnapshot } from '../lib/timemachine.js';\nimport { smartMerge, isShellFile, generateMergePreview } from '../lib/merge.js';\nimport { copyFileOrDir } from '../lib/files.js';\nimport { CATEGORIES } from '../constants.js';\nimport type { TuckManifest } from '../types.js';\n\n/**\n * Fix permissions for SSH/GPG files after apply\n */\nconst fixSecurePermissions = async (path: string): Promise<void> => {\n const collapsedPath = collapsePath(path);\n\n // Only fix permissions for SSH and GPG files\n if (!collapsedPath.includes('.ssh/') && !collapsedPath.includes('.gnupg/')) {\n return;\n }\n\n try {\n const stats = await stat(path);\n\n if (stats.isDirectory()) {\n await chmod(path, 0o700);\n } else {\n await chmod(path, 0o600);\n }\n } catch {\n // Ignore permission errors (might be on Windows)\n }\n};\n\nexport interface ApplyOptions {\n merge?: boolean;\n replace?: boolean;\n dryRun?: boolean;\n force?: boolean;\n yes?: boolean;\n}\n\ninterface ApplyFile {\n source: string;\n destination: string;\n category: string;\n repoPath: string;\n}\n\n/**\n * Resolve a source (username or repo URL) to a full repository identifier\n */\nconst resolveSource = async (source: string): Promise<{ repoId: string; isUrl: boolean }> => {\n // Check if it's a full URL\n if (source.includes('://') || source.startsWith('git@')) {\n return { repoId: source, isUrl: true };\n }\n\n // Check if it's a GitHub repo identifier (user/repo)\n if (source.includes('/')) {\n return { repoId: source, isUrl: false };\n }\n\n // Assume it's a username, try to find their dotfiles repo\n logger.info(`Looking for dotfiles repository for ${source}...`);\n\n if (await isGhInstalled()) {\n const dotfilesRepo = await findDotfilesRepo(source);\n if (dotfilesRepo) {\n logger.success(`Found repository: ${dotfilesRepo}`);\n return { repoId: dotfilesRepo, isUrl: false };\n }\n }\n\n // Try common repo names\n const commonNames = ['dotfiles', 'tuck', '.dotfiles'];\n for (const name of commonNames) {\n const repoId = `${source}/${name}`;\n if (await repoExists(repoId)) {\n logger.success(`Found repository: ${repoId}`);\n return { repoId, isUrl: false };\n }\n }\n\n throw new Error(\n `Could not find a dotfiles repository for \"${source}\". ` +\n 'Try specifying the full repository name (e.g., username/dotfiles)'\n );\n};\n\n/**\n * Clone the source repository to a temporary directory\n */\nconst cloneSource = async (repoId: string, isUrl: boolean): Promise<string> => {\n const tempDir = join(tmpdir(), `tuck-apply-${Date.now()}`);\n await ensureDir(tempDir);\n\n if (isUrl) {\n await cloneRepo(repoId, tempDir);\n } else {\n // Use gh CLI to clone if available, otherwise construct URL\n if (await isGhInstalled()) {\n await ghCloneRepo(repoId, tempDir);\n } else {\n const url = `https://github.com/${repoId}.git`;\n await cloneRepo(url, tempDir);\n }\n }\n\n return tempDir;\n};\n\n/**\n * Read the manifest from a cloned repository\n */\nconst readClonedManifest = async (repoDir: string): Promise<TuckManifest | null> => {\n const manifestPath = join(repoDir, '.tuckmanifest.json');\n\n if (!(await fsPathExists(manifestPath))) {\n return null;\n }\n\n try {\n const content = await readFile(manifestPath, 'utf-8');\n return JSON.parse(content) as TuckManifest;\n } catch {\n return null;\n }\n};\n\n/**\n * Prepare the list of files to apply\n */\nconst prepareFilesToApply = async (\n repoDir: string,\n manifest: TuckManifest\n): Promise<ApplyFile[]> => {\n const files: ApplyFile[] = [];\n\n for (const [_id, file] of Object.entries(manifest.files)) {\n const repoFilePath = join(repoDir, file.destination);\n\n if (await fsPathExists(repoFilePath)) {\n // Validate that the source path is safe (within home directory)\n // This prevents malicious manifests from writing to arbitrary locations\n try {\n validateSafeSourcePath(file.source);\n } catch (error) {\n logger.warning(`Skipping unsafe path from manifest: ${file.source}`);\n continue;\n }\n\n files.push({\n source: file.source,\n destination: expandPath(file.source),\n category: file.category,\n repoPath: repoFilePath,\n });\n }\n }\n\n return files;\n};\n\n/**\n * Apply files with merge strategy\n */\nconst applyWithMerge = async (files: ApplyFile[], dryRun: boolean): Promise<number> => {\n let appliedCount = 0;\n\n for (const file of files) {\n const fileContent = await readFile(file.repoPath, 'utf-8');\n\n if (isShellFile(file.source) && (await pathExists(file.destination))) {\n // Use smart merge for shell files\n const mergeResult = await smartMerge(file.destination, fileContent);\n\n if (dryRun) {\n logger.file('merge', `${collapsePath(file.destination)} (${mergeResult.preservedBlocks} blocks preserved)`);\n } else {\n const { writeFile } = await import('fs/promises');\n const { ensureDir } = await import('fs-extra');\n const { dirname } = await import('path');\n\n await ensureDir(dirname(file.destination));\n await writeFile(file.destination, mergeResult.content, 'utf-8');\n logger.file('merge', collapsePath(file.destination));\n }\n } else {\n // Copy non-shell files directly\n if (dryRun) {\n if (await pathExists(file.destination)) {\n logger.file('modify', collapsePath(file.destination));\n } else {\n logger.file('add', collapsePath(file.destination));\n }\n } else {\n const fileExists = await pathExists(file.destination);\n await copyFileOrDir(file.repoPath, file.destination, { overwrite: true });\n await fixSecurePermissions(file.destination);\n logger.file(\n fileExists ? 'modify' : 'add',\n collapsePath(file.destination)\n );\n }\n }\n\n appliedCount++;\n }\n\n return appliedCount;\n};\n\n/**\n * Apply files with replace strategy\n */\nconst applyWithReplace = async (files: ApplyFile[], dryRun: boolean): Promise<number> => {\n let appliedCount = 0;\n\n for (const file of files) {\n if (dryRun) {\n if (await pathExists(file.destination)) {\n logger.file('modify', `${collapsePath(file.destination)} (replace)`);\n } else {\n logger.file('add', collapsePath(file.destination));\n }\n } else {\n const fileExists = await pathExists(file.destination);\n await copyFileOrDir(file.repoPath, file.destination, { overwrite: true });\n await fixSecurePermissions(file.destination);\n logger.file(\n fileExists ? 'modify' : 'add',\n collapsePath(file.destination)\n );\n }\n\n appliedCount++;\n }\n\n return appliedCount;\n};\n\n/**\n * Run interactive apply flow\n */\nconst runInteractiveApply = async (source: string, options: ApplyOptions): Promise<void> => {\n banner();\n prompts.intro('tuck apply');\n\n // Resolve the source\n let repoId: string;\n let isUrl: boolean;\n\n try {\n const resolved = await resolveSource(source);\n repoId = resolved.repoId;\n isUrl = resolved.isUrl;\n } catch (error) {\n prompts.log.error(error instanceof Error ? error.message : String(error));\n return;\n }\n\n // Clone the repository\n let repoDir: string;\n try {\n const spinner = prompts.spinner();\n spinner.start('Cloning repository...');\n repoDir = await cloneSource(repoId, isUrl);\n spinner.stop('Repository cloned');\n } catch (error) {\n prompts.log.error(`Failed to clone: ${error instanceof Error ? error.message : String(error)}`);\n return;\n }\n\n try {\n // Read the manifest\n const manifest = await readClonedManifest(repoDir);\n\n if (!manifest) {\n prompts.log.error('No tuck manifest found in repository');\n prompts.note(\n 'This repository may not be managed by tuck.\\nLook for a .tuckmanifest.json file.',\n 'Tip'\n );\n return;\n }\n\n // Prepare files to apply\n const files = await prepareFilesToApply(repoDir, manifest);\n\n if (files.length === 0) {\n prompts.log.warning('No files to apply');\n return;\n }\n\n // Show what will be applied\n prompts.log.info(`Found ${files.length} file(s) to apply:`);\n console.log();\n\n // Group by category\n const byCategory: Record<string, ApplyFile[]> = {};\n for (const file of files) {\n if (!byCategory[file.category]) {\n byCategory[file.category] = [];\n }\n byCategory[file.category].push(file);\n }\n\n for (const [category, categoryFiles] of Object.entries(byCategory)) {\n const categoryConfig = CATEGORIES[category] || { icon: '📄' };\n console.log(chalk.bold(` ${categoryConfig.icon} ${category}`));\n for (const file of categoryFiles) {\n const exists = await pathExists(file.destination);\n const status = exists ? chalk.yellow('(will update)') : chalk.green('(new)');\n console.log(chalk.dim(` ${collapsePath(file.destination)} ${status}`));\n }\n }\n console.log();\n\n // Ask for merge strategy\n let strategy: 'merge' | 'replace';\n\n if (options.merge) {\n strategy = 'merge';\n } else if (options.replace) {\n strategy = 'replace';\n } else {\n strategy = await prompts.select('How should conflicts be handled?', [\n {\n value: 'merge',\n label: 'Merge (recommended)',\n hint: 'Preserve local customizations marked with # local or # tuck:preserve',\n },\n {\n value: 'replace',\n label: 'Replace',\n hint: 'Overwrite all files completely',\n },\n ]);\n }\n\n // Show merge preview for shell files if using merge strategy\n if (strategy === 'merge') {\n const shellFiles = files.filter((f) => isShellFile(f.source));\n if (shellFiles.length > 0) {\n console.log();\n for (const file of shellFiles.slice(0, 3)) {\n if (await pathExists(file.destination)) {\n const fileContent = await readFile(file.repoPath, 'utf-8');\n const preview = await generateMergePreview(file.destination, fileContent);\n prompts.note(preview, collapsePath(file.destination));\n }\n }\n if (shellFiles.length > 3) {\n prompts.log.info(`... and ${shellFiles.length - 3} more shell files`);\n }\n }\n }\n\n // Confirm\n if (!options.yes && !options.force) {\n console.log();\n const confirmed = await prompts.confirm(\n `Apply ${files.length} files using ${strategy} strategy?`,\n true\n );\n\n if (!confirmed) {\n prompts.cancel('Apply cancelled');\n return;\n }\n }\n\n // Create Time Machine backup before applying\n // Note: We need to properly await async checks - Array.filter doesn't await promises\n const existingPaths = [];\n for (const file of files) {\n if (await pathExists(file.destination)) {\n existingPaths.push(file.destination);\n }\n }\n\n if (existingPaths.length > 0 && !options.dryRun) {\n const spinner = prompts.spinner();\n spinner.start('Creating backup snapshot...');\n const snapshot = await createPreApplySnapshot(existingPaths, repoId);\n spinner.stop(`Backup created: ${snapshot.id}`);\n console.log();\n }\n\n // Apply files\n if (options.dryRun) {\n prompts.log.info('Dry run - no changes will be made:');\n } else {\n prompts.log.info('Applying files...');\n }\n console.log();\n\n let appliedCount: number;\n if (strategy === 'merge') {\n appliedCount = await applyWithMerge(files, options.dryRun || false);\n } else {\n appliedCount = await applyWithReplace(files, options.dryRun || false);\n }\n\n console.log();\n\n if (options.dryRun) {\n prompts.log.info(`Would apply ${appliedCount} files`);\n } else {\n prompts.log.success(`Applied ${appliedCount} files`);\n console.log();\n prompts.note(\n 'To undo this apply, run:\\n tuck restore --latest\\n\\nTo see all backups:\\n tuck restore --list',\n 'Undo'\n );\n }\n\n prompts.outro('Done!');\n } finally {\n // Clean up temp directory\n try {\n await rm(repoDir, { recursive: true, force: true });\n } catch {\n // Ignore cleanup errors\n }\n }\n};\n\n/**\n * Run non-interactive apply\n */\nconst runApply = async (source: string, options: ApplyOptions): Promise<void> => {\n // Resolve the source\n const { repoId, isUrl } = await resolveSource(source);\n\n // Clone the repository\n logger.info('Cloning repository...');\n const repoDir = await cloneSource(repoId, isUrl);\n\n try {\n // Read the manifest\n const manifest = await readClonedManifest(repoDir);\n\n if (!manifest) {\n throw new Error('No tuck manifest found in repository');\n }\n\n // Prepare files to apply\n const files = await prepareFilesToApply(repoDir, manifest);\n\n if (files.length === 0) {\n logger.warning('No files to apply');\n return;\n }\n\n // Determine strategy\n const strategy = options.replace ? 'replace' : 'merge';\n\n // Create backup if not dry run\n if (!options.dryRun) {\n const existingPaths = [];\n for (const file of files) {\n if (await pathExists(file.destination)) {\n existingPaths.push(file.destination);\n }\n }\n\n if (existingPaths.length > 0) {\n logger.info('Creating backup snapshot...');\n const snapshot = await createPreApplySnapshot(existingPaths, repoId);\n logger.success(`Backup created: ${snapshot.id}`);\n }\n }\n\n // Apply files\n if (options.dryRun) {\n logger.heading('Dry run - would apply:');\n } else {\n logger.heading('Applying:');\n }\n\n let appliedCount: number;\n if (strategy === 'merge') {\n appliedCount = await applyWithMerge(files, options.dryRun || false);\n } else {\n appliedCount = await applyWithReplace(files, options.dryRun || false);\n }\n\n logger.blank();\n\n if (options.dryRun) {\n logger.info(`Would apply ${appliedCount} files`);\n } else {\n logger.success(`Applied ${appliedCount} files`);\n logger.info('To undo: tuck restore --latest');\n }\n } finally {\n // Clean up temp directory\n try {\n await rm(repoDir, { recursive: true, force: true });\n } catch {\n // Ignore cleanup errors\n }\n }\n};\n\nexport const applyCommand = new Command('apply')\n .description('Apply dotfiles from a repository to this machine')\n .argument('<source>', 'GitHub username, user/repo, or full repository URL')\n .option('-m, --merge', 'Merge with existing files (preserve local customizations)')\n .option('-r, --replace', 'Replace existing files completely')\n .option('--dry-run', 'Show what would be applied without making changes')\n .option('-f, --force', 'Apply without confirmation prompts')\n .option('-y, --yes', 'Assume yes to all prompts')\n .action(async (source: string, options: ApplyOptions) => {\n // Determine if we should run interactive mode\n const isInteractive = !options.force && !options.yes && process.stdout.isTTY;\n\n if (isInteractive) {\n await runInteractiveApply(source, options);\n } else {\n await runApply(source, options);\n }\n });\n","import { readFile } from 'fs/promises';\nimport { expandPath, pathExists } from './paths.js';\n\n/**\n * Markers that indicate content should be preserved during merge\n */\nconst PRESERVE_MARKERS = [\n '# local',\n '# LOCAL',\n '# machine-specific',\n '# MACHINE-SPECIFIC',\n '# machine specific',\n '# do not sync',\n '# DO NOT SYNC',\n '# keep',\n '# KEEP',\n '# private',\n '# PRIVATE',\n '# tuck:preserve',\n '# tuck:keep',\n '# tuck:local',\n];\n\n/**\n * Shell file patterns that are known to be shell configuration\n */\nconst SHELL_FILE_PATTERNS = [\n '.zshrc',\n '.bashrc',\n '.bash_profile',\n '.profile',\n '.zprofile',\n '.zshenv',\n '.bash_aliases',\n '.aliases',\n '.functions',\n];\n\nexport interface MergeBlock {\n type: 'preserved' | 'incoming' | 'local';\n content: string;\n marker?: string;\n lineStart: number;\n lineEnd: number;\n}\n\nexport interface MergeResult {\n content: string;\n preservedBlocks: number;\n incomingBlocks: number;\n conflicts: MergeConflict[];\n}\n\nexport interface MergeConflict {\n type: 'duplicate_export' | 'duplicate_alias' | 'duplicate_function';\n name: string;\n localLine: number;\n incomingLine: number;\n}\n\nexport interface ParsedExport {\n name: string;\n value: string;\n line: number;\n fullLine: string;\n}\n\nexport interface ParsedAlias {\n name: string;\n value: string;\n line: number;\n fullLine: string;\n}\n\nexport interface ParsedFunction {\n name: string;\n content: string;\n lineStart: number;\n lineEnd: number;\n}\n\n/**\n * Check if a file is a shell configuration file\n */\nexport const isShellFile = (filePath: string): boolean => {\n const fileName = filePath.split('/').pop() || '';\n return SHELL_FILE_PATTERNS.some(\n (pattern) => fileName === pattern || fileName.endsWith(pattern)\n );\n};\n\n/**\n * Parse export statements from shell content\n * Handles: export FOO=bar, export FOO=\"bar\", FOO=bar\n */\nexport const parseExports = (content: string): ParsedExport[] => {\n const exports: ParsedExport[] = [];\n const lines = content.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n\n // Skip comments and empty lines\n if (line.startsWith('#') || !line) continue;\n\n // Match export statements\n const exportMatch = line.match(/^(?:export\\s+)?([A-Za-z_][A-Za-z0-9_]*)=(.*)$/);\n if (exportMatch) {\n exports.push({\n name: exportMatch[1],\n value: exportMatch[2],\n line: i + 1,\n fullLine: lines[i],\n });\n }\n }\n\n return exports;\n};\n\n/**\n * Parse alias definitions from shell content\n * Handles: alias foo='bar', alias foo=\"bar\"\n */\nexport const parseAliases = (content: string): ParsedAlias[] => {\n const aliases: ParsedAlias[] = [];\n const lines = content.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n\n // Skip comments and empty lines\n if (line.startsWith('#') || !line) continue;\n\n // Match alias statements\n const aliasMatch = line.match(/^alias\\s+([a-zA-Z_][a-zA-Z0-9_-]*)=(['\"]?)(.+?)\\2\\s*$/);\n if (aliasMatch) {\n aliases.push({\n name: aliasMatch[1],\n value: aliasMatch[3],\n line: i + 1,\n fullLine: lines[i],\n });\n }\n }\n\n return aliases;\n};\n\n/**\n * Find blocks that should be preserved during merge\n * A preserved block starts with a preserve marker and ends at:\n * - The next non-indented non-comment line\n * - The end of file\n * - Another preserve marker\n */\nexport const findPreservedBlocks = (content: string): MergeBlock[] => {\n const blocks: MergeBlock[] = [];\n const lines = content.split('\\n');\n let currentBlock: MergeBlock | null = null;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmedLine = line.trim();\n\n // Check if this line has a preserve marker\n const marker = PRESERVE_MARKERS.find((m) => trimmedLine.includes(m));\n\n if (marker) {\n // Save previous block if exists\n if (currentBlock) {\n currentBlock.lineEnd = i;\n currentBlock.content = lines.slice(currentBlock.lineStart - 1, i).join('\\n');\n blocks.push(currentBlock);\n }\n\n // Start new preserved block\n currentBlock = {\n type: 'preserved',\n content: '',\n marker,\n lineStart: i + 1,\n lineEnd: i + 1,\n };\n } else if (currentBlock) {\n // Check if we should end the current block\n // End if: empty line followed by non-indented content, or end of file\n const isEndOfBlock =\n (trimmedLine === '' && i + 1 < lines.length && !lines[i + 1].startsWith(' ') && !lines[i + 1].startsWith('\\t') && lines[i + 1].trim() !== '' && !lines[i + 1].trim().startsWith('#')) ||\n i === lines.length - 1;\n\n if (isEndOfBlock) {\n currentBlock.lineEnd = i + 1;\n currentBlock.content = lines.slice(currentBlock.lineStart - 1, i + 1).join('\\n');\n blocks.push(currentBlock);\n currentBlock = null;\n }\n }\n }\n\n // Handle block that extends to end of file\n if (currentBlock) {\n currentBlock.lineEnd = lines.length;\n currentBlock.content = lines.slice(currentBlock.lineStart - 1).join('\\n');\n blocks.push(currentBlock);\n }\n\n return blocks;\n};\n\n/**\n * Extract PATH modifications from content\n */\nexport const extractPathModifications = (content: string): string[] => {\n const paths: string[] = [];\n const lines = content.split('\\n');\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed.startsWith('#')) continue;\n\n // Match PATH exports\n if (trimmed.includes('PATH') && (trimmed.includes('export') || trimmed.includes('='))) {\n paths.push(line);\n }\n }\n\n return paths;\n};\n\n/**\n * Smart merge of shell configuration files\n * Preserves local customizations while applying incoming changes\n */\nexport const smartMerge = async (\n localPath: string,\n incomingContent: string\n): Promise<MergeResult> => {\n const expandedPath = expandPath(localPath);\n\n // If local file doesn't exist, just return incoming content\n if (!(await pathExists(expandedPath))) {\n return {\n content: incomingContent,\n preservedBlocks: 0,\n incomingBlocks: 1,\n conflicts: [],\n };\n }\n\n const localContent = await readFile(expandedPath, 'utf-8');\n\n // Find blocks to preserve from local content\n const preservedBlocks = findPreservedBlocks(localContent);\n\n // Parse exports and aliases from both files\n const localExports = parseExports(localContent);\n const incomingExports = parseExports(incomingContent);\n const localAliases = parseAliases(localContent);\n const incomingAliases = parseAliases(incomingContent);\n\n // Find conflicts\n const conflicts: MergeConflict[] = [];\n\n // Check for duplicate exports\n for (const local of localExports) {\n const duplicate = incomingExports.find((e) => e.name === local.name);\n if (duplicate && local.value !== duplicate.value) {\n conflicts.push({\n type: 'duplicate_export',\n name: local.name,\n localLine: local.line,\n incomingLine: duplicate.line,\n });\n }\n }\n\n // Check for duplicate aliases\n for (const local of localAliases) {\n const duplicate = incomingAliases.find((a) => a.name === local.name);\n if (duplicate && local.value !== duplicate.value) {\n conflicts.push({\n type: 'duplicate_alias',\n name: local.name,\n localLine: local.line,\n incomingLine: duplicate.line,\n });\n }\n }\n\n // Build merged content\n let mergedContent = incomingContent;\n\n // Append preserved blocks at the end\n if (preservedBlocks.length > 0) {\n mergedContent += '\\n\\n';\n mergedContent += '# ============================================\\n';\n mergedContent += '# LOCAL CUSTOMIZATIONS (preserved by tuck)\\n';\n mergedContent += '# ============================================\\n\\n';\n\n for (const block of preservedBlocks) {\n mergedContent += block.content + '\\n\\n';\n }\n }\n\n return {\n content: mergedContent.trim() + '\\n',\n preservedBlocks: preservedBlocks.length,\n incomingBlocks: 1,\n conflicts,\n };\n};\n\n/**\n * Generate a diff-like preview of what will change\n */\nexport const generateMergePreview = async (\n localPath: string,\n incomingContent: string\n): Promise<string> => {\n const expandedPath = expandPath(localPath);\n\n if (!(await pathExists(expandedPath))) {\n return `New file will be created:\\n${incomingContent.slice(0, 500)}${incomingContent.length > 500 ? '...' : ''}`;\n }\n\n const localContent = await readFile(expandedPath, 'utf-8');\n const preservedBlocks = findPreservedBlocks(localContent);\n const localExports = parseExports(localContent);\n const incomingExports = parseExports(incomingContent);\n\n const lines: string[] = [];\n\n lines.push('=== Merge Preview ===');\n lines.push('');\n\n // Show preserved blocks\n if (preservedBlocks.length > 0) {\n lines.push(`📌 ${preservedBlocks.length} block(s) will be preserved:`);\n for (const block of preservedBlocks) {\n lines.push(` - Lines ${block.lineStart}-${block.lineEnd} (${block.marker})`);\n }\n lines.push('');\n }\n\n // Show export changes\n const newExports = incomingExports.filter(\n (e) => !localExports.find((l) => l.name === e.name)\n );\n const changedExports = incomingExports.filter((e) => {\n const local = localExports.find((l) => l.name === e.name);\n return local && local.value !== e.value;\n });\n\n if (newExports.length > 0) {\n lines.push(`➕ ${newExports.length} new export(s):`);\n for (const exp of newExports.slice(0, 5)) {\n lines.push(` + ${exp.name}=${exp.value.slice(0, 50)}`);\n }\n if (newExports.length > 5) {\n lines.push(` ... and ${newExports.length - 5} more`);\n }\n lines.push('');\n }\n\n if (changedExports.length > 0) {\n lines.push(`🔄 ${changedExports.length} export(s) will be updated:`);\n for (const exp of changedExports.slice(0, 5)) {\n const local = localExports.find((l) => l.name === exp.name);\n lines.push(` ~ ${exp.name}: \"${local?.value.slice(0, 20)}...\" → \"${exp.value.slice(0, 20)}...\"`);\n }\n if (changedExports.length > 5) {\n lines.push(` ... and ${changedExports.length - 5} more`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n};\n\n/**\n * Check if content has any preserve markers\n */\nexport const hasPreserveMarkers = (content: string): boolean => {\n return PRESERVE_MARKERS.some((marker) => content.includes(marker));\n};\n\n/**\n * Add a preserve marker to content\n */\nexport const addPreserveMarker = (content: string, marker = '# tuck:preserve'): string => {\n return `${marker}\\n${content}`;\n};\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { prompts, logger } from '../ui/index.js';\nimport { collapsePath } from '../lib/paths.js';\nimport {\n listSnapshots,\n getSnapshot,\n getLatestSnapshot,\n restoreSnapshot,\n restoreFileFromSnapshot,\n deleteSnapshot,\n getSnapshotsSize,\n formatSnapshotSize,\n formatSnapshotDate,\n Snapshot,\n} from '../lib/timemachine.js';\n\nexport interface UndoOptions {\n list?: boolean;\n latest?: boolean;\n file?: string;\n delete?: string;\n force?: boolean;\n dryRun?: boolean;\n}\n\n/**\n * Display a list of available snapshots\n */\nconst showSnapshotList = async (): Promise<void> => {\n const snapshots = await listSnapshots();\n\n if (snapshots.length === 0) {\n logger.warning('No backup snapshots found');\n logger.dim('Snapshots are created automatically when using `tuck apply`');\n return;\n }\n\n logger.heading('Backup Snapshots:');\n logger.blank();\n\n for (const snapshot of snapshots) {\n const date = formatSnapshotDate(snapshot.id);\n const fileCount = snapshot.files.filter((f) => f.existed).length;\n\n console.log(chalk.cyan(` ${snapshot.id}`));\n console.log(chalk.dim(` Date: ${date}`));\n console.log(chalk.dim(` Reason: ${snapshot.reason}`));\n console.log(chalk.dim(` Files: ${fileCount} file(s) backed up`));\n console.log(chalk.dim(` Machine: ${snapshot.machine}`));\n console.log();\n }\n\n const totalSize = await getSnapshotsSize();\n logger.dim(`Total backup size: ${formatSnapshotSize(totalSize)}`);\n logger.blank();\n logger.info('To restore a snapshot: tuck undo <snapshot-id>');\n logger.info('To restore the latest: tuck undo --latest');\n};\n\n/**\n * Display details of a specific snapshot\n */\nconst showSnapshotDetails = (snapshot: Snapshot): void => {\n console.log();\n console.log(chalk.bold('Snapshot Details:'));\n console.log(chalk.dim(` ID: ${snapshot.id}`));\n console.log(chalk.dim(` Date: ${formatSnapshotDate(snapshot.id)}`));\n console.log(chalk.dim(` Reason: ${snapshot.reason}`));\n console.log(chalk.dim(` Machine: ${snapshot.machine}`));\n console.log();\n console.log(chalk.bold('Files in snapshot:'));\n\n for (const file of snapshot.files) {\n if (file.existed) {\n console.log(chalk.dim(` ok ${collapsePath(file.originalPath)}`));\n } else {\n console.log(chalk.dim(` - ${collapsePath(file.originalPath)} (did not exist)`));\n }\n }\n console.log();\n};\n\n/**\n * Restore from a specific snapshot\n */\nconst restoreFromSnapshot = async (\n snapshotId: string,\n options: UndoOptions\n): Promise<void> => {\n const snapshot = await getSnapshot(snapshotId);\n\n if (!snapshot) {\n logger.error(`Snapshot not found: ${snapshotId}`);\n const snapshots = await listSnapshots();\n if (snapshots.length > 0) {\n logger.info('Available snapshots:');\n for (const s of snapshots.slice(0, 5)) {\n logger.dim(` ${s.id} - ${formatSnapshotDate(s.id)}`);\n }\n if (snapshots.length > 5) {\n logger.dim(` ... and ${snapshots.length - 5} more`);\n }\n }\n return;\n }\n\n // Show snapshot details\n showSnapshotDetails(snapshot);\n\n // Confirm unless --force or dry-run\n if (!options.force && !options.dryRun) {\n const backedUpCount = snapshot.files.filter((f) => f.existed).length;\n const confirmed = await prompts.confirm(\n `Restore ${backedUpCount} file(s) from this snapshot?`,\n true\n );\n\n if (!confirmed) {\n logger.info('Restore cancelled');\n return;\n }\n }\n\n // Dry run\n if (options.dryRun) {\n logger.heading('Dry run - would restore:');\n for (const file of snapshot.files) {\n if (file.existed) {\n logger.file('modify', collapsePath(file.originalPath));\n } else {\n logger.file('delete', `${collapsePath(file.originalPath)} (would remove)`);\n }\n }\n return;\n }\n\n // Restore\n logger.info('Restoring files...');\n const restoredFiles = await restoreSnapshot(snapshotId);\n\n logger.blank();\n logger.success(`Restored ${restoredFiles.length} file(s)`);\n\n for (const file of restoredFiles) {\n logger.dim(` ok ${collapsePath(file)}`);\n }\n};\n\n/**\n * Restore a single file from a snapshot\n */\nconst restoreSingleFile = async (\n snapshotId: string,\n filePath: string,\n options: UndoOptions\n): Promise<void> => {\n const snapshot = await getSnapshot(snapshotId);\n\n if (!snapshot) {\n logger.error(`Snapshot not found: ${snapshotId}`);\n return;\n }\n\n // Dry run\n if (options.dryRun) {\n logger.info(`Would restore ${filePath} from snapshot ${snapshotId}`);\n return;\n }\n\n // Restore the file\n await restoreFileFromSnapshot(snapshotId, filePath);\n logger.success(`Restored ${filePath}`);\n};\n\n/**\n * Delete a snapshot\n */\nconst removeSnapshot = async (snapshotId: string, options: UndoOptions): Promise<void> => {\n const snapshot = await getSnapshot(snapshotId);\n\n if (!snapshot) {\n logger.error(`Snapshot not found: ${snapshotId}`);\n return;\n }\n\n // Confirm unless --force\n if (!options.force) {\n showSnapshotDetails(snapshot);\n const confirmed = await prompts.confirm('Delete this snapshot permanently?', false);\n\n if (!confirmed) {\n logger.info('Deletion cancelled');\n return;\n }\n }\n\n await deleteSnapshot(snapshotId);\n logger.success(`Deleted snapshot: ${snapshotId}`);\n};\n\n/**\n * Interactive undo selection\n */\nconst runInteractiveUndo = async (): Promise<void> => {\n prompts.intro('tuck undo');\n\n const snapshots = await listSnapshots();\n\n if (snapshots.length === 0) {\n prompts.log.warning('No backup snapshots available');\n prompts.note('Snapshots are created when using `tuck apply`', 'Info');\n return;\n }\n\n // Let user select a snapshot\n const snapshotOptions = snapshots.map((s) => ({\n value: s.id,\n label: `${s.id} - ${s.reason.slice(0, 40)}${s.reason.length > 40 ? '...' : ''}`,\n hint: `${s.files.filter((f) => f.existed).length} files`,\n }));\n\n const selectedId = await prompts.select(\n 'Select a snapshot to restore:',\n snapshotOptions\n );\n\n const snapshot = await getSnapshot(selectedId);\n if (!snapshot) {\n prompts.log.error('Snapshot not found');\n return;\n }\n\n // Show what will be restored\n console.log();\n prompts.log.info('Files in this snapshot:');\n for (const file of snapshot.files.slice(0, 10)) {\n if (file.existed) {\n console.log(chalk.dim(` ${collapsePath(file.originalPath)}`));\n }\n }\n if (snapshot.files.length > 10) {\n console.log(chalk.dim(` ... and ${snapshot.files.length - 10} more`));\n }\n console.log();\n\n // Confirm\n const confirmed = await prompts.confirm('Restore these files?', true);\n\n if (!confirmed) {\n prompts.cancel('Restore cancelled');\n return;\n }\n\n // Restore\n const spinner = prompts.spinner();\n spinner.start('Restoring files...');\n\n const restoredFiles = await restoreSnapshot(selectedId);\n\n spinner.stop(`Restored ${restoredFiles.length} files`);\n\n prompts.outro('Done!');\n};\n\n/**\n * Main undo command handler\n */\nconst runUndo = async (snapshotId: string | undefined, options: UndoOptions): Promise<void> => {\n // Handle --list\n if (options.list) {\n await showSnapshotList();\n return;\n }\n\n // Handle --delete\n if (options.delete) {\n await removeSnapshot(options.delete, options);\n return;\n }\n\n // Handle --latest\n if (options.latest) {\n const latest = await getLatestSnapshot();\n if (!latest) {\n logger.warning('No backup snapshots available');\n return;\n }\n await restoreFromSnapshot(latest.id, options);\n return;\n }\n\n // Handle specific snapshot ID\n if (snapshotId) {\n // Check if we're restoring a single file\n if (options.file) {\n await restoreSingleFile(snapshotId, options.file, options);\n } else {\n await restoreFromSnapshot(snapshotId, options);\n }\n return;\n }\n\n // No arguments - run interactive mode\n await runInteractiveUndo();\n};\n\nexport const undoCommand = new Command('undo')\n .description('Restore files from a Time Machine backup snapshot')\n .argument('[snapshot-id]', 'Snapshot ID to restore (format: YYYY-MM-DD-HHMMSS)')\n .option('-l, --list', 'List all available backup snapshots')\n .option('--latest', 'Restore the most recent snapshot')\n .option('--file <path>', 'Restore a single file from the snapshot')\n .option('--delete <id>', 'Delete a specific snapshot')\n .option('-f, --force', 'Skip confirmation prompts')\n .option('--dry-run', 'Show what would be restored without making changes')\n .action(async (snapshotId: string | undefined, options: UndoOptions) => {\n await runUndo(snapshotId, options);\n });\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { prompts, logger, banner } from '../ui/index.js';\nimport { getTuckDir } from '../lib/paths.js';\nimport { loadManifest, getTrackedFileBySource } from '../lib/manifest.js';\nimport {\n detectDotfiles,\n DETECTION_CATEGORIES,\n DetectedFile,\n} from '../lib/detect.js';\nimport { NotInitializedError } from '../errors.js';\n\nexport interface ScanOptions {\n all?: boolean;\n category?: string;\n json?: boolean;\n quick?: boolean;\n}\n\ninterface SelectableFile extends DetectedFile {\n selected: boolean;\n alreadyTracked: boolean;\n}\n\n/**\n * Group selectable files by category\n */\nconst groupSelectableByCategory = (\n files: SelectableFile[]\n): Record<string, SelectableFile[]> => {\n const grouped: Record<string, SelectableFile[]> = {};\n\n for (const file of files) {\n if (!grouped[file.category]) {\n grouped[file.category] = [];\n }\n grouped[file.category].push(file);\n }\n\n return grouped;\n};\n\n/**\n * Display detected files grouped by category\n */\nconst displayGroupedFiles = (\n files: SelectableFile[],\n showAll: boolean\n): void => {\n const grouped = groupSelectableByCategory(files);\n const categories = Object.keys(grouped).sort((a, b) => {\n // Sort by category order in DETECTION_CATEGORIES\n const order = Object.keys(DETECTION_CATEGORIES);\n return order.indexOf(a) - order.indexOf(b);\n });\n\n for (const category of categories) {\n const categoryFiles = grouped[category];\n const config = DETECTION_CATEGORIES[category] || { icon: '-', name: category };\n const newFiles = categoryFiles.filter((f) => !f.alreadyTracked);\n const trackedFiles = categoryFiles.filter((f) => f.alreadyTracked);\n\n console.log();\n console.log(\n chalk.bold(`${config.icon} ${config.name}`) +\n chalk.dim(` (${newFiles.length} new, ${trackedFiles.length} tracked)`)\n );\n console.log(chalk.dim('─'.repeat(50)));\n\n for (const file of categoryFiles) {\n if (!showAll && file.alreadyTracked) continue;\n\n const status = file.selected ? chalk.green('[x]') : chalk.dim('[ ]');\n const name = file.path;\n const tracked = file.alreadyTracked ? chalk.dim(' (tracked)') : '';\n const sensitive = file.sensitive ? chalk.yellow(' [!]') : '';\n const dir = file.isDirectory ? chalk.cyan(' [dir]') : '';\n\n console.log(` ${status} ${name}${dir}${sensitive}${tracked}`);\n console.log(chalk.dim(` ${file.description}`));\n }\n }\n};\n\n/**\n * Interactive file selection\n */\nconst runInteractiveSelection = async (\n files: SelectableFile[]\n): Promise<SelectableFile[]> => {\n const newFiles = files.filter((f) => !f.alreadyTracked);\n\n if (newFiles.length === 0) {\n prompts.log.success('All detected dotfiles are already being tracked!');\n return [];\n }\n\n // Group files for selection\n const grouped = groupSelectableByCategory(newFiles);\n const selectedFiles: SelectableFile[] = [];\n\n // Ask for each category\n for (const [category, categoryFiles] of Object.entries(grouped)) {\n const config = DETECTION_CATEGORIES[category] || { icon: '-', name: category };\n\n console.log();\n console.log(chalk.bold(`${config.icon} ${config.name}`));\n console.log(chalk.dim(config.description || ''));\n console.log();\n\n // Create options for multiselect\n const options = categoryFiles.map((file: SelectableFile) => {\n let label = file.path;\n if (file.sensitive) {\n label += chalk.yellow(' [!]');\n }\n if (file.isDirectory) {\n label += chalk.cyan(' [dir]');\n }\n\n return {\n value: file.path,\n label,\n hint: file.description,\n };\n });\n\n // All selected by default\n const selected = await prompts.multiselect(\n `Select files to track from ${config.name}:`,\n options.map((opt: { value: string; label: string; hint: string }) => ({ ...opt, selected: true }))\n );\n\n // Mark selected files\n for (const file of categoryFiles) {\n if (selected.includes(file.path)) {\n file.selected = true;\n selectedFiles.push(file);\n }\n }\n }\n\n return selectedFiles;\n};\n\n/**\n * Quick display mode - just show what's detected\n */\nconst runQuickScan = async (files: SelectableFile[]): Promise<void> => {\n const newFiles = files.filter((f) => !f.alreadyTracked);\n const trackedFiles = files.filter((f) => f.alreadyTracked);\n\n console.log();\n console.log(\n chalk.bold.cyan('Detected Dotfiles: ') +\n chalk.white(`${newFiles.length} new, ${trackedFiles.length} already tracked`)\n );\n\n displayGroupedFiles(files, false);\n\n console.log();\n console.log(chalk.dim('─'.repeat(60)));\n console.log();\n\n if (newFiles.length > 0) {\n logger.info(`Found ${newFiles.length} new dotfiles to track`);\n logger.dim('Run `tuck scan` (without --quick) to interactively select files');\n logger.dim('Or run `tuck add <path>` to add specific files');\n } else {\n logger.success('All detected dotfiles are already being tracked!');\n }\n};\n\n/**\n * Summary display after selection\n */\nconst showSummary = (selected: SelectableFile[]): void => {\n if (selected.length === 0) {\n logger.info('No files selected');\n return;\n }\n\n console.log();\n console.log(chalk.bold.green(`Selected ${selected.length} files to track:`));\n console.log();\n\n const grouped = groupSelectableByCategory(selected);\n\n for (const [category, files] of Object.entries(grouped)) {\n const config = DETECTION_CATEGORIES[category] || { icon: '-', name: category };\n console.log(chalk.bold(`${config.icon} ${config.name}`));\n\n for (const file of files) {\n const sensitive = file.sensitive ? chalk.yellow(' [!]') : '';\n console.log(chalk.dim(` • ${file.path}${sensitive}`));\n }\n }\n\n console.log();\n\n // Show warnings for sensitive files\n const sensitiveFiles = selected.filter((f) => f.sensitive);\n if (sensitiveFiles.length > 0) {\n console.log(chalk.yellow('Warning: Some selected files may contain sensitive data:'));\n for (const file of sensitiveFiles) {\n console.log(chalk.yellow(` • ${file.path}`));\n }\n console.log(chalk.dim(' Make sure your repository is private!'));\n console.log();\n }\n\n // Show command to add files\n const paths = selected.map((f) => f.path).join(' ');\n console.log(chalk.bold('Run this command to add the selected files:'));\n console.log();\n console.log(chalk.cyan(` tuck add ${paths}`));\n console.log();\n};\n\n/**\n * Main scan function\n */\nconst runScan = async (options: ScanOptions): Promise<void> => {\n const tuckDir = getTuckDir();\n\n // Check if tuck is initialized\n try {\n await loadManifest(tuckDir);\n } catch {\n throw new NotInitializedError();\n }\n\n // Detect dotfiles\n const spinner = prompts.spinner();\n spinner.start('Scanning for dotfiles...');\n\n const detected = await detectDotfiles();\n\n spinner.stop(`Found ${detected.length} dotfiles on this system`);\n\n if (detected.length === 0) {\n logger.warning('No common dotfiles detected on this system');\n return;\n }\n\n // Check which files are already tracked\n const selectableFiles: SelectableFile[] = [];\n\n for (const file of detected) {\n const tracked = await getTrackedFileBySource(tuckDir, file.path);\n\n selectableFiles.push({\n ...file,\n selected: true, // All selected by default\n alreadyTracked: tracked !== null,\n });\n }\n\n // Filter by category if specified\n let filesToShow = selectableFiles;\n if (options.category) {\n filesToShow = selectableFiles.filter((f) => f.category === options.category);\n if (filesToShow.length === 0) {\n logger.warning(`No dotfiles found in category: ${options.category}`);\n logger.info('Available categories:');\n for (const [key, config] of Object.entries(DETECTION_CATEGORIES)) {\n console.log(chalk.dim(` ${config.icon} ${key} - ${config.name}`));\n }\n return;\n }\n }\n\n // JSON output\n if (options.json) {\n console.log(JSON.stringify(filesToShow, null, 2));\n return;\n }\n\n // Quick mode - just display\n if (options.quick) {\n await runQuickScan(filesToShow);\n return;\n }\n\n // Interactive mode\n banner();\n prompts.intro('tuck scan');\n\n const newFiles = filesToShow.filter((f) => !f.alreadyTracked);\n const trackedCount = filesToShow.filter((f) => f.alreadyTracked).length;\n\n prompts.log.info(\n `Found ${filesToShow.length} dotfiles (${newFiles.length} new, ${trackedCount} tracked)`\n );\n\n if (newFiles.length === 0) {\n prompts.log.success('All detected dotfiles are already being tracked!');\n prompts.outro('Nothing to do');\n return;\n }\n\n // Ask how to proceed\n const action = await prompts.select('How would you like to proceed?', [\n {\n value: 'all',\n label: 'Track all new files',\n hint: `Add all ${newFiles.length} files`,\n },\n {\n value: 'select',\n label: 'Select files to track',\n hint: 'Choose which files to add',\n },\n {\n value: 'preview',\n label: 'Just show me what was found',\n hint: 'Display files without tracking',\n },\n ]);\n\n if (action === 'preview') {\n displayGroupedFiles(filesToShow, options.all || false);\n prompts.outro('Run `tuck scan` again to select files');\n return;\n }\n\n let selected: SelectableFile[];\n\n if (action === 'all') {\n selected = newFiles.map((f) => ({ ...f, selected: true }));\n } else {\n selected = await runInteractiveSelection(filesToShow);\n }\n\n if (selected.length === 0) {\n prompts.cancel('No files selected');\n return;\n }\n\n // Confirm selection\n showSummary(selected);\n\n const confirmed = await prompts.confirm(\n `Add ${selected.length} files to tuck?`,\n true\n );\n\n if (!confirmed) {\n prompts.cancel('Operation cancelled');\n return;\n }\n\n // Add the files\n const { addFilesFromPaths } = await import('./add.js');\n const paths = selected.map((f) => f.path);\n\n await addFilesFromPaths(paths, {});\n\n prompts.outro(`Added ${selected.length} files to tuck!`);\n};\n\nexport const scanCommand = new Command('scan')\n .description('Scan system for dotfiles and select which to track')\n .option('-a, --all', 'Show all files including already tracked ones')\n .option('-c, --category <name>', 'Filter by category (shell, git, editors, etc.)')\n .option('-q, --quick', 'Quick scan - just show detected files without interactive selection')\n .option('--json', 'Output results as JSON')\n .action(async (options: ScanOptions) => {\n await runScan(options);\n });\n"],"mappings":"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","names":["chalk","chalk","chalk","spinner","text","chalk","homedir","join","chalk","z","fileStrategySchema","readFile","writeFile","join","log","readFile","stat","readdir","rm","copy","ensureDir","join","dirname","content","Command","basename","chalk","confirm","Command","chalk","join","resolve","writeFile","ensureDir","join","basename","stat","isDirectory","join","dirname","readdir","readFile","writeFile","stat","pathExists","homedir","pathExists","readdir","join","stat","copy","readFile","rm","ensureDir","join","writeFile","spinner","readdir","p","resolve","getPreferredRemoteProtocol","hostname","removeRemote","stat","Command","join","validateAndPrepareFiles","confirm","Command","chalk","join","promisify","chalk","join","spinner","message","chalk","confirm","spinner2","Command","Command","chalk","remoteUrl","confirm","Command","chalk","Command","chalk","join","stat","join","copy","ensureDir","pathExists","join","stat","join","chalk","confirm","Command","Command","chalk","Command","chalk","group","Command","chalk","join","readFile","Command","chalk","resolve","confirm","Command","join","readFile","rm","chmod","stat","ensureDir","tmpdir","chalk","readFile","readFile","stat","chmod","join","tmpdir","ensureDir","readFile","writeFile","dirname","spinner","chalk","rm","Command","Command","chalk","chalk","spinner","Command","Command","chalk","chalk","spinner","addFilesFromPaths","Command","Command","chalk"]}
|