@hiveforge/hivemind-mcp 0.1.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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +148 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +175 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/graph/builder.d.ts +47 -0
  8. package/dist/graph/builder.d.ts.map +1 -0
  9. package/dist/graph/builder.js +182 -0
  10. package/dist/graph/builder.js.map +1 -0
  11. package/dist/graph/database.d.ts +71 -0
  12. package/dist/graph/database.d.ts.map +1 -0
  13. package/dist/graph/database.js +255 -0
  14. package/dist/graph/database.js.map +1 -0
  15. package/dist/index.d.ts +3 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +53 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/parser/markdown.d.ts +29 -0
  20. package/dist/parser/markdown.d.ts.map +1 -0
  21. package/dist/parser/markdown.js +122 -0
  22. package/dist/parser/markdown.js.map +1 -0
  23. package/dist/search/engine.d.ts +48 -0
  24. package/dist/search/engine.d.ts.map +1 -0
  25. package/dist/search/engine.js +88 -0
  26. package/dist/search/engine.js.map +1 -0
  27. package/dist/server.d.ts +23 -0
  28. package/dist/server.d.ts.map +1 -0
  29. package/dist/server.js +504 -0
  30. package/dist/server.js.map +1 -0
  31. package/dist/types/index.d.ts +646 -0
  32. package/dist/types/index.d.ts.map +1 -0
  33. package/dist/types/index.js +133 -0
  34. package/dist/types/index.js.map +1 -0
  35. package/dist/vault/reader.d.ts +56 -0
  36. package/dist/vault/reader.d.ts.map +1 -0
  37. package/dist/vault/reader.js +185 -0
  38. package/dist/vault/reader.js.map +1 -0
  39. package/dist/vault/watcher.d.ts +33 -0
  40. package/dist/vault/watcher.d.ts.map +1 -0
  41. package/dist/vault/watcher.js +92 -0
  42. package/dist/vault/watcher.js.map +1 -0
  43. package/package.json +77 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Preston
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,148 @@
1
+ # Hivemind MCP Server
2
+
3
+ An MCP (Model Context Protocol) server for Obsidian worldbuilding vaults that provides AI tools with consistent, canonical context from your fictional worlds.
4
+
5
+ ## What is Hivemind?
6
+
7
+ Hivemind bridges your Obsidian vault (where you maintain your worldbuilding canon) and AI tools (Claude, ComfyUI, etc.) via the Model Context Protocol. It ensures AI-generated content stays consistent with your established characters, locations, lore, and approved assets.
8
+
9
+ ## Features
10
+
11
+ - 🔍 **HybridRAG Search**: Combines vector, graph, and keyword search for accurate context retrieval
12
+ - 📚 **Obsidian Native**: Works with standard markdown, YAML frontmatter, and wikilinks
13
+ - 🎨 **Asset Provenance**: Track AI-generated images and their generation settings
14
+ - 🔐 **Local-First**: Your data stays on your machine, with optional cloud deployment
15
+ - ✅ **Canon Management**: Draft → Pending → Canon approval workflow
16
+ - 🚀 **High Performance**: <300ms query latency, supports 1000+ note vaults
17
+
18
+ ## Quick Start
19
+
20
+ ### Installation
21
+
22
+ ```bash
23
+ # Install globally
24
+ npm install -g hivemind-mcp
25
+
26
+ # Or use with npx (no installation needed)
27
+ npx hivemind-mcp init
28
+ ```
29
+
30
+ ### Setup
31
+
32
+ ```bash
33
+ # Interactive setup - creates config.json
34
+ npx hivemind-mcp init
35
+
36
+ # Validate your configuration
37
+ npx hivemind-mcp validate
38
+
39
+ # Start the server
40
+ npx hivemind-mcp start
41
+ ```
42
+
43
+ ### Configuration for MCP Clients
44
+
45
+ **Claude Desktop** (`%APPDATA%\Claude\claude_desktop_config.json`):
46
+ ```json
47
+ {
48
+ "mcpServers": {
49
+ "hivemind": {
50
+ "command": "npx",
51
+ "args": ["-y", "hivemind-mcp", "start"]
52
+ }
53
+ }
54
+ }
55
+ ```
56
+
57
+ **GitHub Copilot** (`~/.copilot/mcp-config.json`):
58
+ ```json
59
+ {
60
+ "mcpServers": {
61
+ "hivemind": {
62
+ "type": "local",
63
+ "command": "npx",
64
+ "args": ["-y", "hivemind-mcp", "start"],
65
+ "tools": ["*"]
66
+ }
67
+ }
68
+ }
69
+ ```
70
+
71
+ ### Manual Configuration
72
+
73
+ If you prefer to configure manually, create a `config.json`:
74
+
75
+ ```json
76
+ {
77
+ "vault": {
78
+ "path": "/path/to/your/obsidian/vault",
79
+ "watchForChanges": true,
80
+ "debounceMs": 100
81
+ },
82
+ "server": {
83
+ "transport": "stdio"
84
+ },
85
+ "indexing": {
86
+ "strategy": "incremental",
87
+ "batchSize": 100,
88
+ "enableVectorSearch": false,
89
+ "enableFullTextSearch": true
90
+ }
91
+ }
92
+ ```
93
+
94
+ ## Architecture
95
+
96
+ ```
97
+ Obsidian Vault → File Watcher → Markdown Parser → Knowledge Graph
98
+
99
+ ┌───────────────────┴─────────────────┐
100
+ │ │
101
+ Full-Text Index Vector Index
102
+ (SQLite) (FAISS)
103
+ │ │
104
+ └───────────────────┬─────────────────┘
105
+
106
+ HybridRAG Router
107
+
108
+ MCP Server
109
+
110
+ AI Clients (Claude, etc.)
111
+ ```
112
+
113
+ ## Development Status
114
+
115
+ **Current Phase**: Phase 1 - MVP Implementation
116
+ **Version**: 0.1.0 (Pre-release)
117
+
118
+ ### Roadmap
119
+
120
+ See [.planning/PROJECT.md](.planning/PROJECT.md) for the active requirements and progress tracking.
121
+
122
+ **Recently Completed:**
123
+ - [x] Project setup and dependencies
124
+ - [x] Vault reading and file watching (VaultReader, VaultWatcher)
125
+ - [x] Markdown parsing with wikilinks (MarkdownParser)
126
+ - [x] Knowledge graph construction (GraphBuilder, HivemindDatabase)
127
+ - [x] HybridRAG search implementation (SearchEngine)
128
+ - [x] MCP tools (query_character, query_location, search_vault)
129
+
130
+ **Up Next:**
131
+ - [ ] Testing and validation
132
+ - [ ] ComfyUI integration
133
+ - [ ] Obsidian plugin
134
+
135
+ ## Documentation
136
+
137
+ - [Project Requirements & Roadmap](.planning/PROJECT.md)
138
+ - [Architecture Research](.planning/research/ARCHITECTURE.md)
139
+ - [Technology Stack](.planning/research/STACK.md)
140
+ - [Features Specification](.planning/research/FEATURES.md)
141
+
142
+ ## License
143
+
144
+ MIT
145
+
146
+ ## Contributing
147
+
148
+ This project is currently in early development. Contributions welcome once MVP is stable.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,175 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync, writeFileSync, existsSync } from 'fs';
3
+ import { resolve, join } from 'path';
4
+ import * as readline from 'readline/promises';
5
+ import { stdin as input, stdout as output } from 'process';
6
+ const DEFAULT_CONFIG = {
7
+ vault: {
8
+ path: '',
9
+ watchForChanges: true,
10
+ debounceMs: 100
11
+ },
12
+ server: {
13
+ transport: 'stdio'
14
+ },
15
+ indexing: {
16
+ strategy: 'incremental',
17
+ batchSize: 100,
18
+ enableVectorSearch: false,
19
+ enableFullTextSearch: true
20
+ }
21
+ };
22
+ async function init() {
23
+ console.log('🧠 Hivemind MCP Server - Configuration Setup\n');
24
+ const rl = readline.createInterface({ input, output });
25
+ try {
26
+ // Check if config already exists
27
+ const configPath = resolve(process.cwd(), 'config.json');
28
+ if (existsSync(configPath)) {
29
+ const overwrite = await rl.question('config.json already exists. Overwrite? (y/N): ');
30
+ if (overwrite.toLowerCase() !== 'y') {
31
+ console.log('Setup cancelled.');
32
+ rl.close();
33
+ return;
34
+ }
35
+ }
36
+ // Ask for vault path
37
+ const vaultPath = await rl.question('Enter your Obsidian vault path: ');
38
+ if (!vaultPath.trim()) {
39
+ console.error('❌ Vault path is required');
40
+ rl.close();
41
+ process.exit(1);
42
+ }
43
+ const resolvedPath = resolve(vaultPath.trim());
44
+ if (!existsSync(resolvedPath)) {
45
+ console.warn(`⚠️ Warning: Path does not exist: ${resolvedPath}`);
46
+ const proceed = await rl.question('Continue anyway? (y/N): ');
47
+ if (proceed.toLowerCase() !== 'y') {
48
+ console.log('Setup cancelled.');
49
+ rl.close();
50
+ return;
51
+ }
52
+ }
53
+ // Optional: Enable vector search
54
+ const enableVector = await rl.question('Enable vector search (experimental)? (y/N): ');
55
+ // Create config
56
+ const config = {
57
+ ...DEFAULT_CONFIG,
58
+ vault: {
59
+ ...DEFAULT_CONFIG.vault,
60
+ path: resolvedPath
61
+ },
62
+ indexing: {
63
+ ...DEFAULT_CONFIG.indexing,
64
+ enableVectorSearch: enableVector.toLowerCase() === 'y'
65
+ }
66
+ };
67
+ // Write config
68
+ writeFileSync(configPath, JSON.stringify(config, null, 2));
69
+ console.log(`\n✅ Configuration saved to ${configPath}`);
70
+ console.log('\n📝 Next steps:');
71
+ console.log(' 1. Build the project: npm run build');
72
+ console.log(' 2. Start the server: npm start');
73
+ console.log(' 3. Configure your MCP client to connect to this server');
74
+ rl.close();
75
+ }
76
+ catch (error) {
77
+ console.error('Error during setup:', error);
78
+ rl.close();
79
+ process.exit(1);
80
+ }
81
+ }
82
+ async function start() {
83
+ const configPath = resolve(process.cwd(), 'config.json');
84
+ if (!existsSync(configPath)) {
85
+ console.error('❌ config.json not found. Run "npx hivemind init" first.');
86
+ process.exit(1);
87
+ }
88
+ console.log('🚀 Starting Hivemind MCP Server...\n');
89
+ // Import and start the server
90
+ const { startServer } = await import('./index.js');
91
+ await startServer();
92
+ }
93
+ async function validate() {
94
+ const configPath = resolve(process.cwd(), 'config.json');
95
+ console.log('🔍 Validating Hivemind configuration...\n');
96
+ // Check config exists
97
+ if (!existsSync(configPath)) {
98
+ console.error('❌ config.json not found');
99
+ console.log(' Run "npx hivemind init" to create one');
100
+ process.exit(1);
101
+ }
102
+ // Load and validate config
103
+ try {
104
+ const config = JSON.parse(readFileSync(configPath, 'utf-8'));
105
+ console.log('✅ config.json found and valid JSON');
106
+ // Check vault path
107
+ if (!config.vault?.path) {
108
+ console.error('❌ vault.path is missing in config');
109
+ process.exit(1);
110
+ }
111
+ const vaultPath = resolve(config.vault.path);
112
+ if (!existsSync(vaultPath)) {
113
+ console.error(`❌ Vault path does not exist: ${vaultPath}`);
114
+ process.exit(1);
115
+ }
116
+ console.log(`✅ Vault path exists: ${vaultPath}`);
117
+ // Check for .md files
118
+ const { readdirSync } = await import('fs');
119
+ let mdCount = 0;
120
+ function countMarkdown(dir) {
121
+ try {
122
+ const entries = readdirSync(dir, { withFileTypes: true });
123
+ for (const entry of entries) {
124
+ const fullPath = join(dir, entry.name);
125
+ if (entry.isDirectory() && !entry.name.startsWith('.')) {
126
+ countMarkdown(fullPath);
127
+ }
128
+ else if (entry.isFile() && entry.name.endsWith('.md')) {
129
+ mdCount++;
130
+ }
131
+ }
132
+ }
133
+ catch (err) {
134
+ // Skip directories we can't read
135
+ }
136
+ }
137
+ countMarkdown(vaultPath);
138
+ console.log(`✅ Found ${mdCount} markdown file(s)`);
139
+ // Check if built
140
+ const distPath = resolve(process.cwd(), 'dist', 'index.js');
141
+ if (!existsSync(distPath)) {
142
+ console.warn('⚠️ dist/index.js not found - run "npm run build"');
143
+ }
144
+ else {
145
+ console.log('✅ Server built (dist/index.js exists)');
146
+ }
147
+ console.log('\n✅ Configuration is valid!');
148
+ console.log('\nTo start the server: npm start');
149
+ }
150
+ catch (error) {
151
+ console.error('❌ Error reading config.json:', error);
152
+ process.exit(1);
153
+ }
154
+ }
155
+ // Parse command
156
+ const command = process.argv[2];
157
+ switch (command) {
158
+ case 'init':
159
+ init();
160
+ break;
161
+ case 'start':
162
+ start();
163
+ break;
164
+ case 'validate':
165
+ validate();
166
+ break;
167
+ default:
168
+ console.log('Hivemind MCP Server\n');
169
+ console.log('Usage:');
170
+ console.log(' npx hivemind init - Interactive configuration setup');
171
+ console.log(' npx hivemind validate - Validate configuration');
172
+ console.log(' npx hivemind start - Start the MCP server');
173
+ process.exit(command ? 1 : 0);
174
+ }
175
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import type { VaultNote, KnowledgeGraph } from '../types/index.js';
2
+ import { HivemindDatabase } from './database.js';
3
+ export declare class GraphBuilder {
4
+ private db;
5
+ constructor(db: HivemindDatabase);
6
+ /**
7
+ * Build knowledge graph from vault notes
8
+ */
9
+ buildGraph(notes: VaultNote[]): void;
10
+ /**
11
+ * Build relationships from wikilinks in a note
12
+ */
13
+ private buildRelationships;
14
+ /**
15
+ * Infer relationship type from note types
16
+ */
17
+ private inferRelationType;
18
+ /**
19
+ * Check if a relationship type should be bidirectional
20
+ */
21
+ private isBidirectional;
22
+ /**
23
+ * Get reverse relationship type
24
+ */
25
+ private getReverseRelationType;
26
+ /**
27
+ * Find note by name or ID
28
+ */
29
+ private findNoteByNameOrId;
30
+ /**
31
+ * Extract ID from wikilink format [[id]] or [[id|alias]]
32
+ */
33
+ private extractIdFromWikilink;
34
+ /**
35
+ * Get in-memory graph representation
36
+ */
37
+ getGraph(): KnowledgeGraph;
38
+ /**
39
+ * Incremental update: add or update a single note
40
+ */
41
+ updateNote(note: VaultNote, allNotes: VaultNote[]): void;
42
+ /**
43
+ * Incremental update: remove a note
44
+ */
45
+ removeNote(noteId: string): void;
46
+ }
47
+ //# sourceMappingURL=builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/graph/builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAa,MAAM,mBAAmB,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,qBAAa,YAAY;IACvB,OAAO,CAAC,EAAE,CAAmB;gBAEjB,EAAE,EAAE,gBAAgB;IAIhC;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI;IAwBpC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAsC1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA4BzB;;OAEG;IACH,OAAO,CAAC,eAAe;IAKvB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAY9B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAwB1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAW7B;;OAEG;IACH,QAAQ,IAAI,cAAc;IA8B1B;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI;IASxD;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAGjC"}
@@ -0,0 +1,182 @@
1
+ export class GraphBuilder {
2
+ db;
3
+ constructor(db) {
4
+ this.db = db;
5
+ }
6
+ /**
7
+ * Build knowledge graph from vault notes
8
+ */
9
+ buildGraph(notes) {
10
+ console.error(`Building knowledge graph from ${notes.length} notes...`);
11
+ const startTime = Date.now();
12
+ // First pass: Insert all nodes
13
+ for (const note of notes) {
14
+ this.db.upsertNode(note);
15
+ }
16
+ // Second pass: Build relationships from wikilinks
17
+ for (const note of notes) {
18
+ this.buildRelationships(note, notes);
19
+ }
20
+ const elapsed = Date.now() - startTime;
21
+ const stats = this.db.getStats();
22
+ console.error(`Knowledge graph built in ${elapsed}ms:`);
23
+ console.error(` Nodes: ${stats.nodes}`);
24
+ console.error(` Relationships: ${stats.relationships}`);
25
+ console.error(` By type:`, stats.byType);
26
+ }
27
+ /**
28
+ * Build relationships from wikilinks in a note
29
+ */
30
+ buildRelationships(note, allNotes) {
31
+ // Extract relationships from wikilinks
32
+ for (const link of note.links) {
33
+ // Find the target note
34
+ const targetNote = this.findNoteByNameOrId(link, allNotes);
35
+ if (targetNote) {
36
+ // Infer relationship type based on note types
37
+ const relType = this.inferRelationType(note, targetNote);
38
+ // Insert relationship
39
+ this.db.insertRelationship(note.id, targetNote.id, relType);
40
+ // For certain relationships, create bidirectional link
41
+ if (this.isBidirectional(relType)) {
42
+ const reverseType = this.getReverseRelationType(relType);
43
+ this.db.insertRelationship(targetNote.id, note.id, reverseType);
44
+ }
45
+ }
46
+ }
47
+ // Extract explicit relationships from frontmatter
48
+ const frontmatter = note.frontmatter;
49
+ if (frontmatter.relationships) {
50
+ for (const rel of frontmatter.relationships) {
51
+ if (rel.target) {
52
+ const targetId = this.extractIdFromWikilink(rel.target);
53
+ this.db.insertRelationship(note.id, targetId, rel.type || 'related', { status: rel.status });
54
+ }
55
+ }
56
+ }
57
+ }
58
+ /**
59
+ * Infer relationship type from note types
60
+ */
61
+ inferRelationType(source, target) {
62
+ const sourceType = source.frontmatter.type;
63
+ const targetType = target.frontmatter.type;
64
+ // Character → Character
65
+ if (sourceType === 'character' && targetType === 'character') {
66
+ return 'knows';
67
+ }
68
+ // Character → Location
69
+ if (sourceType === 'character' && targetType === 'location') {
70
+ return 'located_in';
71
+ }
72
+ // Location → Character
73
+ if (sourceType === 'location' && targetType === 'character') {
74
+ return 'has_inhabitant';
75
+ }
76
+ // Location → Location
77
+ if (sourceType === 'location' && targetType === 'location') {
78
+ return 'connected_to';
79
+ }
80
+ // Default
81
+ return 'related';
82
+ }
83
+ /**
84
+ * Check if a relationship type should be bidirectional
85
+ */
86
+ isBidirectional(relType) {
87
+ const bidirectionalTypes = ['knows', 'connected_to', 'related'];
88
+ return bidirectionalTypes.includes(relType);
89
+ }
90
+ /**
91
+ * Get reverse relationship type
92
+ */
93
+ getReverseRelationType(relType) {
94
+ const reverseMap = {
95
+ 'knows': 'knows',
96
+ 'connected_to': 'connected_to',
97
+ 'related': 'related',
98
+ 'located_in': 'has_inhabitant',
99
+ 'has_inhabitant': 'located_in',
100
+ };
101
+ return reverseMap[relType] || 'related';
102
+ }
103
+ /**
104
+ * Find note by name or ID
105
+ */
106
+ findNoteByNameOrId(nameOrId, notes) {
107
+ const normalized = nameOrId.toLowerCase().trim();
108
+ // Try exact ID match
109
+ let note = notes.find(n => n.id === normalized);
110
+ if (note)
111
+ return note;
112
+ // Try by title/name
113
+ note = notes.find(n => {
114
+ const fm = n.frontmatter;
115
+ const title = (fm.title || fm.name || '').toLowerCase();
116
+ return title === normalized;
117
+ });
118
+ if (note)
119
+ return note;
120
+ // Try by filename
121
+ note = notes.find(n => {
122
+ const fileName = n.fileName.replace(/\.md$/, '').toLowerCase();
123
+ return fileName === normalized;
124
+ });
125
+ return note;
126
+ }
127
+ /**
128
+ * Extract ID from wikilink format [[id]] or [[id|alias]]
129
+ */
130
+ extractIdFromWikilink(link) {
131
+ // Remove [[ and ]]
132
+ const cleaned = link.replace(/^\[\[/, '').replace(/\]\]$/, '');
133
+ // Split on | to handle aliases
134
+ const parts = cleaned.split('|');
135
+ // Return first part (the actual link target)
136
+ return parts[0].trim().toLowerCase().replace(/\s+/g, '-');
137
+ }
138
+ /**
139
+ * Get in-memory graph representation
140
+ */
141
+ getGraph() {
142
+ const nodes = this.db.getAllNodes();
143
+ const edges = [];
144
+ const adjacencyList = new Map();
145
+ // Build adjacency list
146
+ for (const node of nodes) {
147
+ const rels = this.db.getRelationships(node.id);
148
+ const neighbors = new Set();
149
+ for (const rel of rels) {
150
+ edges.push(rel);
151
+ // Add both directions to adjacency list
152
+ neighbors.add(rel.targetId);
153
+ if (rel.sourceId !== node.id) {
154
+ neighbors.add(rel.sourceId);
155
+ }
156
+ }
157
+ adjacencyList.set(node.id, neighbors);
158
+ }
159
+ return {
160
+ nodes: new Map(nodes.map(n => [n.id, n])),
161
+ edges: new Map(edges.map(e => [e.id, e])),
162
+ adjacencyList,
163
+ };
164
+ }
165
+ /**
166
+ * Incremental update: add or update a single note
167
+ */
168
+ updateNote(note, allNotes) {
169
+ // Update node
170
+ this.db.upsertNode(note);
171
+ // Rebuild relationships for this note
172
+ // TODO: Delete old relationships first (needs relationship cleanup)
173
+ this.buildRelationships(note, allNotes);
174
+ }
175
+ /**
176
+ * Incremental update: remove a note
177
+ */
178
+ removeNote(noteId) {
179
+ this.db.deleteNode(noteId);
180
+ }
181
+ }
182
+ //# sourceMappingURL=builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/graph/builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ import type { VaultNote, GraphNode, GraphEdge } from '../types/index.js';
2
+ export interface DatabaseConfig {
3
+ path: string;
4
+ readonly?: boolean;
5
+ }
6
+ export declare class HivemindDatabase {
7
+ private db;
8
+ constructor(config: DatabaseConfig);
9
+ /**
10
+ * Ensure database directory exists
11
+ */
12
+ private ensureDirectory;
13
+ /**
14
+ * Initialize database schema
15
+ */
16
+ private initializeSchema;
17
+ /**
18
+ * Insert or update a node
19
+ */
20
+ upsertNode(note: VaultNote): void;
21
+ /**
22
+ * Insert a relationship
23
+ */
24
+ insertRelationship(sourceId: string, targetId: string, relType?: string, properties?: Record<string, any>): void;
25
+ /**
26
+ * Get a node by ID
27
+ */
28
+ getNode(id: string): GraphNode | undefined;
29
+ /**
30
+ * Get all nodes
31
+ */
32
+ getAllNodes(): GraphNode[];
33
+ /**
34
+ * Get nodes by type
35
+ */
36
+ getNodesByType(type: string): GraphNode[];
37
+ /**
38
+ * Get relationships for a node
39
+ */
40
+ getRelationships(nodeId: string): GraphEdge[];
41
+ /**
42
+ * Full-text search using FTS5
43
+ */
44
+ search(query: string, limit?: number): Array<{
45
+ id: string;
46
+ rank: number;
47
+ }>;
48
+ /**
49
+ * Delete a node and its relationships
50
+ */
51
+ deleteNode(id: string): void;
52
+ /**
53
+ * Clear all data
54
+ */
55
+ clear(): void;
56
+ /**
57
+ * Get database statistics
58
+ */
59
+ getStats(): {
60
+ nodes: number;
61
+ relationships: number;
62
+ byType: {
63
+ [k: string]: number;
64
+ };
65
+ };
66
+ /**
67
+ * Close database connection
68
+ */
69
+ close(): void;
70
+ }
71
+ //# sourceMappingURL=database.d.ts.map