From fff6df535fa58d7f0da0bdda51c979cb22f054f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=91=E6=B3=BD=E5=AE=87?= Date: Thu, 28 May 2026 16:44:34 +0800 Subject: [PATCH] feat(cli): add --vault option for daemon and mirror commands Allow specifying a separate vault directory for .md files, decoupled from the database directory (where PouchDB data lives). - Add --vault/-V flag to CLI options parser - Use vaultPath (or fallback to databasePath) for file system operations - Works with both daemon and mirror commands - Log vault path alongside database path at startup --- src/apps/cli/commands/types.ts | 1 + src/apps/cli/main.ts | 29 ++++++++++++++++++++++------- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/apps/cli/commands/types.ts b/src/apps/cli/commands/types.ts index 2f5337f..7963996 100644 --- a/src/apps/cli/commands/types.ts +++ b/src/apps/cli/commands/types.ts @@ -30,6 +30,7 @@ export type CLICommand = export interface CLIOptions { databasePath?: string; + vaultPath?: string; settingsPath?: string; verbose?: boolean; debug?: boolean; diff --git a/src/apps/cli/main.ts b/src/apps/cli/main.ts index 1bd1ea5..44ba4e8 100644 --- a/src/apps/cli/main.ts +++ b/src/apps/cli/main.ts @@ -61,7 +61,7 @@ Commands: info Show detailed metadata for a file (ID, revision, conflicts, chunks) rm Mark a file as deleted in local database resolve Resolve conflicts by keeping and deleting others - mirror [vault-path] Mirror database contents to the local file system (vault-path defaults to database-path) + mirror [vault-path] Mirror database contents to the local file system (vault-path takes precedence over --vault; defaults to vault from --vault / database-path) remote-add Add a remote configuration from a connection string remote-rm Remove a remote configuration by ID @@ -74,6 +74,8 @@ Commands: Activate a stored remote configuration by ID Options: + --vault , -V (daemon/mirror) Path to the vault directory containing .md files + (defaults to database-path; allows separate PouchDB and vault dirs) --interval , -i (daemon only) Poll CouchDB every N seconds instead of using the _changes feed Examples: @@ -114,6 +116,7 @@ export function parseArgs(): CLIOptions { } let databasePath: string | undefined; + let vaultPath: string | undefined; let settingsPath: string | undefined; let verbose = false; let debug = false; @@ -125,6 +128,16 @@ export function parseArgs(): CLIOptions { for (let i = 0; i < args.length; i++) { const token = args[i]; switch (token) { + case "--vault": + case "-V": { + i++; + if (!args[i]) { + console.error(`Error: Missing value for ${token}`); + process.exit(1); + } + vaultPath = args[i]; + break; + } case "--settings": case "-s": { i++; @@ -198,6 +211,7 @@ export function parseArgs(): CLIOptions { return { databasePath, + vaultPath, settingsPath, verbose, debug, @@ -290,16 +304,17 @@ export async function main() { : path.join(databasePath, SETTINGS_FILE); configureNodeLocalStorage(path.join(databasePath, ".livesync", "runtime", "local-storage.json")); + // Resolve vault path: --vault flag takes priority, otherwise fall back to databasePath + // For daemon mode, enable chokidar file watching so the _changes feed picks up events. + // mirror runs a single full scan and doesn't need continuous watching. + const watchEnabled = options.command === "daemon"; + const vaultPath = options.vaultPath ? path.resolve(options.vaultPath) : databasePath!; + infoLog(`Self-hosted LiveSync CLI`); infoLog(`Database Path: ${databasePath}`); + infoLog(`Vault Path: ${vaultPath}`); infoLog(`Settings: ${settingsPath}`); infoLog(""); - - // For daemon and mirror mode, load ignore rules before the core is constructed so that - // chokidar's ignored option is populated when beginWatch() fires during onLoad(). - const watchEnabled = options.command === "daemon"; - const vaultPath = - options.command === "mirror" && options.commandArgs[0] ? path.resolve(options.commandArgs[0]) : databasePath; let ignoreRules: IgnoreRules | undefined; if (options.command === "daemon" || options.command === "mirror") { ignoreRules = new IgnoreRules(vaultPath);