@misterhuydo/cairn-mcp 1.6.5 → 1.6.7

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/graph/db.js +36 -18
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@misterhuydo/cairn-mcp",
3
- "version": "1.6.5",
3
+ "version": "1.6.7",
4
4
  "description": "MCP server that gives Claude Code persistent memory across sessions. Index your codebase once, search symbols, bundle source, scan for vulnerabilities, and checkpoint/resume work — across Java, TypeScript, Vue, Python, SQL and more.",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/src/graph/db.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { DatabaseSync } from 'node:sqlite';
2
2
  import fs from 'fs';
3
3
  import path from 'path';
4
- import { getCairnDir } from './cwd.js';
4
+ import { getCairnDir, getProjectRoot } from './cwd.js';
5
5
 
6
6
  const SCHEMA = `
7
7
  CREATE TABLE IF NOT EXISTS files (
@@ -90,32 +90,50 @@ function findParentCairnDb(currentRoot) {
90
90
 
91
91
  // If a parent .cairn exists, register its index.db (root-level files) and all
92
92
  // of its sub_indexes (siblings) into the current project's sub_indexes table.
93
- // This gives a child session full cross-service visibility automatically.
93
+ // If no parent .cairn exists, fall back to natural sibling discovery: scan the
94
+ // parent directory for any sibling folders that already have a .cairn/index.db.
95
+ // This gives a child session full cross-service visibility automatically,
96
+ // even if the parent project has never run cairn_maintain.
94
97
  function mountParentSubIndexes(db) {
95
98
  const currentRoot = path.resolve(getProjectRoot());
96
- const parentDbPath = findParentCairnDb(currentRoot);
97
- if (!parentDbPath) return;
98
-
99
99
  const selfDbPath = path.resolve(path.join(getCairnDir(), 'index.db'));
100
100
  const stmt = db.prepare('INSERT OR IGNORE INTO main.sub_indexes (path) VALUES (?)');
101
101
 
102
- try {
103
- // Register the parent's own index (root-level files, shared configs, etc.)
104
- if (path.resolve(parentDbPath) !== selfDbPath) {
105
- stmt.run(path.resolve(parentDbPath));
106
- }
102
+ const parentDbPath = findParentCairnDb(currentRoot);
107
103
 
108
- // Register all siblings from the parent's sub_indexes (excluding self)
109
- const parentDb = new DatabaseSync(parentDbPath, { readonly: true });
110
- const siblings = parentDb.prepare('SELECT path FROM sub_indexes').all();
111
- parentDb.close();
104
+ if (parentDbPath) {
105
+ // Parent has been initialized use its registry as source of truth
106
+ try {
107
+ if (path.resolve(parentDbPath) !== selfDbPath) {
108
+ stmt.run(path.resolve(parentDbPath));
109
+ }
110
+ const parentDb = new DatabaseSync(parentDbPath, { readonly: true });
111
+ const siblings = parentDb.prepare('SELECT path FROM sub_indexes').all();
112
+ parentDb.close();
113
+ for (const { path: sibPath } of siblings) {
114
+ const resolved = path.resolve(sibPath);
115
+ if (resolved !== selfDbPath) stmt.run(resolved);
116
+ }
117
+ } catch {
118
+ // Parent DB unreadable or schema mismatch — skip silently
119
+ }
120
+ return;
121
+ }
112
122
 
113
- for (const { path: sibPath } of siblings) {
114
- const resolved = path.resolve(sibPath);
115
- if (resolved !== selfDbPath) stmt.run(resolved);
123
+ // Fallback: parent .cairn not found scan sibling directories naturally.
124
+ // Any sibling folder that already has its own .cairn/index.db is auto-mounted.
125
+ try {
126
+ const parentDir = path.dirname(currentRoot);
127
+ const entries = fs.readdirSync(parentDir, { withFileTypes: true });
128
+ for (const entry of entries) {
129
+ if (!entry.isDirectory()) continue;
130
+ const sibDbPath = path.resolve(path.join(parentDir, entry.name, '.cairn', 'index.db'));
131
+ if (sibDbPath !== selfDbPath && fs.existsSync(sibDbPath)) {
132
+ stmt.run(sibDbPath);
133
+ }
116
134
  }
117
135
  } catch {
118
- // Parent DB unreadable or schema mismatch — skip silently
136
+ // Parent directory unreadable — skip silently
119
137
  }
120
138
  }
121
139