context-vault 2.15.0 → 2.16.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/bin/cli.js
CHANGED
|
@@ -64,6 +64,7 @@ function writeMarkerFile(vaultDir) {
|
|
|
64
64
|
|
|
65
65
|
function scanForVaults() {
|
|
66
66
|
const candidates = [
|
|
67
|
+
join(HOME, ".vault"),
|
|
67
68
|
join(HOME, "vault"),
|
|
68
69
|
join(HOME, "omni", "vault"),
|
|
69
70
|
process.cwd(),
|
|
@@ -324,6 +325,7 @@ ${bold("Options:")}
|
|
|
324
325
|
--version Show version
|
|
325
326
|
--vault-dir <path> Set vault directory (setup/serve)
|
|
326
327
|
--yes Non-interactive mode (accept all defaults)
|
|
328
|
+
--force Overwrite existing config without confirmation
|
|
327
329
|
--skip-embeddings Skip embedding model download (FTS-only mode)
|
|
328
330
|
`);
|
|
329
331
|
}
|
|
@@ -538,7 +540,21 @@ async function runSetup() {
|
|
|
538
540
|
console.log(dim(` [2/6]`) + bold(" Configuring vault...\n"));
|
|
539
541
|
|
|
540
542
|
// Scan for existing vaults via marker file
|
|
541
|
-
let defaultVaultDir = getFlag("--vault-dir") || join(HOME, "vault");
|
|
543
|
+
let defaultVaultDir = getFlag("--vault-dir") || join(HOME, ".vault");
|
|
544
|
+
|
|
545
|
+
// Prefer existing config vaultDir over default (prevents accidental overwrite)
|
|
546
|
+
if (!getFlag("--vault-dir")) {
|
|
547
|
+
const existingCfgPath = join(HOME, ".context-mcp", "config.json");
|
|
548
|
+
if (existsSync(existingCfgPath)) {
|
|
549
|
+
try {
|
|
550
|
+
const cfg = JSON.parse(readFileSync(existingCfgPath, "utf-8"));
|
|
551
|
+
if (cfg.vaultDir && existsSync(resolve(cfg.vaultDir))) {
|
|
552
|
+
defaultVaultDir = cfg.vaultDir;
|
|
553
|
+
}
|
|
554
|
+
} catch {}
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
542
558
|
if (!getFlag("--vault-dir") && !isNonInteractive) {
|
|
543
559
|
const existingVaults = scanForVaults();
|
|
544
560
|
if (existingVaults.length === 1) {
|
|
@@ -576,7 +592,7 @@ async function runSetup() {
|
|
|
576
592
|
const vaultDir = isNonInteractive
|
|
577
593
|
? defaultVaultDir
|
|
578
594
|
: await prompt(` Vault directory:`, defaultVaultDir);
|
|
579
|
-
|
|
595
|
+
let resolvedVaultDir = resolve(vaultDir);
|
|
580
596
|
|
|
581
597
|
// Guard: vault dir path must not be an existing file
|
|
582
598
|
if (existsSync(resolvedVaultDir)) {
|
|
@@ -626,6 +642,57 @@ async function runSetup() {
|
|
|
626
642
|
Object.assign(vaultConfig, JSON.parse(readFileSync(configPath, "utf-8")));
|
|
627
643
|
} catch {}
|
|
628
644
|
}
|
|
645
|
+
|
|
646
|
+
const existingVaultDir = vaultConfig.vaultDir;
|
|
647
|
+
if (
|
|
648
|
+
existingVaultDir &&
|
|
649
|
+
resolve(existingVaultDir) !== resolvedVaultDir &&
|
|
650
|
+
!flags.has("--force")
|
|
651
|
+
) {
|
|
652
|
+
let entryCount = 0;
|
|
653
|
+
try {
|
|
654
|
+
const knowledgeDir = join(resolve(existingVaultDir), "knowledge");
|
|
655
|
+
if (existsSync(knowledgeDir)) {
|
|
656
|
+
const countMd = (d) => {
|
|
657
|
+
let n = 0;
|
|
658
|
+
for (const e of readdirSync(d, { withFileTypes: true })) {
|
|
659
|
+
if (e.isDirectory()) n += countMd(join(d, e.name));
|
|
660
|
+
else if (e.name.endsWith(".md")) n++;
|
|
661
|
+
}
|
|
662
|
+
return n;
|
|
663
|
+
};
|
|
664
|
+
entryCount = countMd(knowledgeDir);
|
|
665
|
+
}
|
|
666
|
+
} catch {}
|
|
667
|
+
|
|
668
|
+
console.log();
|
|
669
|
+
console.log(
|
|
670
|
+
yellow(` ⚠ Existing config points to: ${resolve(existingVaultDir)}`) +
|
|
671
|
+
(entryCount > 0 ? dim(` (${entryCount} entries)`) : ""),
|
|
672
|
+
);
|
|
673
|
+
console.log(` Setup would change vaultDir to: ${resolvedVaultDir}`);
|
|
674
|
+
|
|
675
|
+
if (isNonInteractive) {
|
|
676
|
+
console.log();
|
|
677
|
+
console.log(
|
|
678
|
+
red(" Refusing to overwrite vaultDir in non-interactive mode."),
|
|
679
|
+
);
|
|
680
|
+
console.log(
|
|
681
|
+
dim(" Use --force to override, or --vault-dir to set explicitly."),
|
|
682
|
+
);
|
|
683
|
+
process.exit(1);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
console.log();
|
|
687
|
+
const overwrite = await prompt(" Overwrite? (y/N):", "N");
|
|
688
|
+
if (overwrite.toLowerCase() !== "y" && overwrite.toLowerCase() !== "yes") {
|
|
689
|
+
console.log(
|
|
690
|
+
dim(` Keeping existing vaultDir: ${resolve(existingVaultDir)}`),
|
|
691
|
+
);
|
|
692
|
+
resolvedVaultDir = resolve(existingVaultDir);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
|
|
629
696
|
vaultConfig.vaultDir = resolvedVaultDir;
|
|
630
697
|
vaultConfig.dataDir = dataDir;
|
|
631
698
|
vaultConfig.dbPath = join(dataDir, "vault.db");
|
package/package.json
CHANGED
package/src/server/index.js
CHANGED
|
@@ -138,6 +138,24 @@ async function main() {
|
|
|
138
138
|
{ capabilities: { tools: {} } },
|
|
139
139
|
);
|
|
140
140
|
|
|
141
|
+
// Hot-reload config.json on every tool call (Option C from #144).
|
|
142
|
+
// resolveConfig() re-reads the small file each time — negligible I/O
|
|
143
|
+
// compared to DB queries and embedding operations that follow.
|
|
144
|
+
let lastVaultDir = config.vaultDir;
|
|
145
|
+
Object.defineProperty(ctx, "config", {
|
|
146
|
+
get() {
|
|
147
|
+
const fresh = resolveConfig();
|
|
148
|
+
if (fresh.vaultDir !== lastVaultDir) {
|
|
149
|
+
console.error(
|
|
150
|
+
`[context-vault] Config reloaded: vaultDir changed to ${fresh.vaultDir}`,
|
|
151
|
+
);
|
|
152
|
+
lastVaultDir = fresh.vaultDir;
|
|
153
|
+
}
|
|
154
|
+
return fresh;
|
|
155
|
+
},
|
|
156
|
+
configurable: true,
|
|
157
|
+
});
|
|
158
|
+
|
|
141
159
|
registerTools(server, ctx);
|
|
142
160
|
|
|
143
161
|
// ── Graceful Shutdown ────────────────────────────────────────────────────
|