Skip to content

Commit 8fd7d12

Browse files
author
StackMemory Bot (CLI)
committed
feat(obsidian): auto-initialize vault adapter from config
Wire ObsidianVaultAdapter into both CLI and MCP server startup: - Reads obsidian.vaultPath from .stackmemory/config.yaml - Auto-initializes on session start (CLI) and MCP server init - Singleton pattern — safe to call multiple times - Config passthrough in config-manager.ts Usage: add to .stackmemory/config.yaml: obsidian: vaultPath: /path/to/vault
1 parent 8f6a960 commit 8fd7d12

4 files changed

Lines changed: 78 additions & 0 deletions

File tree

src/cli/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,11 @@ program
262262
await sessionManager.initialize();
263263
await sharedContextLayer.initialize();
264264

265+
// Auto-init Obsidian vault adapter if configured
266+
const { initObsidianVault } =
267+
await import('../core/storage/obsidian-vault-adapter.js');
268+
await initObsidianVault();
269+
265270
const session = await sessionManager.getOrCreateSession({
266271
projectPath: projectRoot,
267272
sessionId: options.session,

src/core/config/config-manager.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ export class ConfigManager {
9898
performance: { ...DEFAULT_CONFIG.performance, ...loaded.performance },
9999
enrichment: { ...DEFAULT_ENRICHMENT, ...loaded.enrichment },
100100
profiles: { ...PRESET_PROFILES, ...loaded.profiles },
101+
obsidian: loaded.obsidian,
101102
};
102103

103104
// Apply active profile if specified

src/core/storage/obsidian-vault-adapter.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,3 +485,68 @@ export class ObsidianVaultAdapter {
485485
logger.info('Obsidian vault adapter cleaned up');
486486
}
487487
}
488+
489+
// ── Auto-init singleton ──
490+
491+
let _instance: ObsidianVaultAdapter | null = null;
492+
493+
/**
494+
* Initialize the Obsidian vault adapter from StackMemory config.
495+
* Safe to call multiple times — only initializes once.
496+
* Returns null if obsidian is not configured.
497+
*/
498+
export async function initObsidianVault(): Promise<ObsidianVaultAdapter | null> {
499+
if (_instance) return _instance;
500+
501+
try {
502+
const configPath = join(process.cwd(), '.stackmemory', 'config.yaml');
503+
if (!existsSync(configPath)) return null;
504+
505+
const content = readFileSync(configPath, 'utf-8');
506+
// Simple YAML parse for obsidian.vaultPath
507+
const vaultMatch = content.match(
508+
/obsidian:\s*\n\s+vaultPath:\s*["']?([^\n"']+)/
509+
);
510+
if (!vaultMatch) return null;
511+
512+
const vaultPath = vaultMatch[1].trim();
513+
if (!vaultPath || !existsSync(vaultPath)) {
514+
logger.warn('Obsidian vaultPath configured but directory not found', {
515+
vaultPath,
516+
});
517+
return null;
518+
}
519+
520+
// Parse optional settings
521+
const subdirMatch = content.match(
522+
/obsidian:\s*\n(?:\s+\w+:.*\n)*\s+subdir:\s*["']?([^\n"']+)/
523+
);
524+
const watchRawMatch = content.match(
525+
/obsidian:\s*\n(?:\s+\w+:.*\n)*\s+watchRaw:\s*(true|false)/
526+
);
527+
const autoIndexMatch = content.match(
528+
/obsidian:\s*\n(?:\s+\w+:.*\n)*\s+autoIndex:\s*(true|false)/
529+
);
530+
531+
_instance = new ObsidianVaultAdapter({
532+
vaultPath,
533+
subdir: subdirMatch?.[1]?.trim(),
534+
watchRaw: watchRawMatch ? watchRawMatch[1] === 'true' : undefined,
535+
autoIndex: autoIndexMatch ? autoIndexMatch[1] === 'true' : undefined,
536+
});
537+
538+
await _instance.initialize();
539+
logger.info('Obsidian vault adapter auto-initialized', { vaultPath });
540+
return _instance;
541+
} catch (err) {
542+
logger.debug('Obsidian vault adapter not initialized', {
543+
error: (err as Error).message,
544+
});
545+
return null;
546+
}
547+
}
548+
549+
/** Get the current adapter instance (null if not initialized) */
550+
export function getObsidianVault(): ObsidianVaultAdapter | null {
551+
return _instance;
552+
}

src/integrations/mcp/server.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,13 @@ class LocalStackMemoryMCP {
220220
logger.error('Failed to initialize Browser MCP', error);
221221
});
222222

223+
// Auto-init Obsidian vault adapter if configured
224+
import('../../core/storage/obsidian-vault-adapter.js')
225+
.then(({ initObsidianVault }) => initObsidianVault())
226+
.catch(() => {
227+
/* optional */
228+
});
229+
223230
logger.info('StackMemory MCP Server initialized', {
224231
projectRoot: this.projectRoot,
225232
projectId: this.projectId,

0 commit comments

Comments
 (0)