@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.
- package/LICENSE +21 -0
- package/README.md +148 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +175 -0
- package/dist/cli.js.map +1 -0
- package/dist/graph/builder.d.ts +47 -0
- package/dist/graph/builder.d.ts.map +1 -0
- package/dist/graph/builder.js +182 -0
- package/dist/graph/builder.js.map +1 -0
- package/dist/graph/database.d.ts +71 -0
- package/dist/graph/database.d.ts.map +1 -0
- package/dist/graph/database.js +255 -0
- package/dist/graph/database.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/markdown.d.ts +29 -0
- package/dist/parser/markdown.d.ts.map +1 -0
- package/dist/parser/markdown.js +122 -0
- package/dist/parser/markdown.js.map +1 -0
- package/dist/search/engine.d.ts +48 -0
- package/dist/search/engine.d.ts.map +1 -0
- package/dist/search/engine.js +88 -0
- package/dist/search/engine.js.map +1 -0
- package/dist/server.d.ts +23 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +504 -0
- package/dist/server.js.map +1 -0
- package/dist/types/index.d.ts +646 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +133 -0
- package/dist/types/index.js.map +1 -0
- package/dist/vault/reader.d.ts +56 -0
- package/dist/vault/reader.d.ts.map +1 -0
- package/dist/vault/reader.js +185 -0
- package/dist/vault/reader.js.map +1 -0
- package/dist/vault/watcher.d.ts +33 -0
- package/dist/vault/watcher.d.ts.map +1 -0
- package/dist/vault/watcher.js +92 -0
- package/dist/vault/watcher.js.map +1 -0
- 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 @@
|
|
|
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
|
package/dist/cli.js.map
ADDED
|
@@ -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
|