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 1/2] 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); From be979a3bf144fca8bc09a48bdbee13ad6465f8cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=91=E6=B3=BD=E5=AE=87?= Date: Fri, 5 Jun 2026 11:50:23 +0800 Subject: [PATCH 2/2] fix(cli): respect mirror positional arg before --vault flag Per vrtmrz's review feedback, restore the mirror [vault-path] positional argument support with correct priority order: mirror positional arg > --vault flag > databasePath Also update --vault help text and CLI README with the new option. --- src/apps/cli/README.md | 7 ++++++- src/apps/cli/main.ts | 10 ++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/apps/cli/README.md b/src/apps/cli/README.md index 18f70b7..7adc18c 100644 --- a/src/apps/cli/README.md +++ b/src/apps/cli/README.md @@ -61,6 +61,9 @@ livesync-cli [database-path] [command] [args...] - `database-path`: Path to the directory where `.livesync` folder and `settings.json` are (or will be) located. - Note: In previous versions, this was referred to as the "vault" path. Now it is clearly distinguished from the actual vault (the directory containing your `.md` files). +- `--vault ` / `-V `: (daemon/mirror only) Path to the vault directory containing `.md` files. + - Allows the PouchDB database directory and the actual vault directory to be different locations. + - For `mirror` command, the positional `[vault-path]` argument takes precedence over `--vault`. ### Commands @@ -312,6 +315,7 @@ Options: --verbose, -v Enable verbose logging --debug, -d Enable debug logging (includes verbose) --interval , -i (daemon only) Poll CouchDB every N seconds instead of using the _changes feed + --vault , -V (daemon/mirror) Path to vault directory, decoupled from database-path --help, -h Show this help message Commands: @@ -332,7 +336,8 @@ Commands: info Show file metadata including current and past revisions, conflicts, and chunk list rm Mark file as deleted in local database resolve Resolve conflict by keeping the specified revision - mirror [vaultPath] Mirror database contents to the local file system (vaultPath defaults to database-path) + mirror [vaultPath] Mirror database contents to the local file system + (vaultPath positional arg > --vault flag > database-path) ``` Run via npm script: diff --git a/src/apps/cli/main.ts b/src/apps/cli/main.ts index 44ba4e8..093b8f5 100644 --- a/src/apps/cli/main.ts +++ b/src/apps/cli/main.ts @@ -304,11 +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 + // Resolve vault path: mirror positional argument takes priority, + // then --vault flag, 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!; + const vaultPath = + options.command === "mirror" && options.commandArgs[0] + ? path.resolve(options.commandArgs[0]) + : options.vaultPath + ? path.resolve(options.vaultPath) + : databasePath!; infoLog(`Self-hosted LiveSync CLI`); infoLog(`Database Path: ${databasePath}`);