@getlore/cli 0.2.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 +13 -0
- package/README.md +80 -0
- package/dist/cli/colors.d.ts +48 -0
- package/dist/cli/colors.js +48 -0
- package/dist/cli/commands/ask.d.ts +7 -0
- package/dist/cli/commands/ask.js +97 -0
- package/dist/cli/commands/auth.d.ts +10 -0
- package/dist/cli/commands/auth.js +484 -0
- package/dist/cli/commands/daemon.d.ts +22 -0
- package/dist/cli/commands/daemon.js +244 -0
- package/dist/cli/commands/docs.d.ts +7 -0
- package/dist/cli/commands/docs.js +188 -0
- package/dist/cli/commands/extensions.d.ts +7 -0
- package/dist/cli/commands/extensions.js +204 -0
- package/dist/cli/commands/misc.d.ts +7 -0
- package/dist/cli/commands/misc.js +172 -0
- package/dist/cli/commands/pending.d.ts +7 -0
- package/dist/cli/commands/pending.js +63 -0
- package/dist/cli/commands/projects.d.ts +7 -0
- package/dist/cli/commands/projects.js +136 -0
- package/dist/cli/commands/search.d.ts +7 -0
- package/dist/cli/commands/search.js +102 -0
- package/dist/cli/commands/skills.d.ts +24 -0
- package/dist/cli/commands/skills.js +447 -0
- package/dist/cli/commands/sources.d.ts +7 -0
- package/dist/cli/commands/sources.js +121 -0
- package/dist/cli/commands/sync.d.ts +31 -0
- package/dist/cli/commands/sync.js +768 -0
- package/dist/cli/helpers.d.ts +30 -0
- package/dist/cli/helpers.js +119 -0
- package/dist/core/auth.d.ts +62 -0
- package/dist/core/auth.js +330 -0
- package/dist/core/config.d.ts +41 -0
- package/dist/core/config.js +96 -0
- package/dist/core/data-repo.d.ts +31 -0
- package/dist/core/data-repo.js +146 -0
- package/dist/core/embedder.d.ts +22 -0
- package/dist/core/embedder.js +104 -0
- package/dist/core/git.d.ts +37 -0
- package/dist/core/git.js +140 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.js +5 -0
- package/dist/core/insight-extractor.d.ts +26 -0
- package/dist/core/insight-extractor.js +114 -0
- package/dist/core/local-search.d.ts +43 -0
- package/dist/core/local-search.js +221 -0
- package/dist/core/themes.d.ts +15 -0
- package/dist/core/themes.js +77 -0
- package/dist/core/types.d.ts +177 -0
- package/dist/core/types.js +9 -0
- package/dist/core/user-settings.d.ts +15 -0
- package/dist/core/user-settings.js +42 -0
- package/dist/core/vector-store-lance.d.ts +98 -0
- package/dist/core/vector-store-lance.js +384 -0
- package/dist/core/vector-store-supabase.d.ts +89 -0
- package/dist/core/vector-store-supabase.js +295 -0
- package/dist/core/vector-store.d.ts +131 -0
- package/dist/core/vector-store.js +503 -0
- package/dist/daemon-runner.d.ts +8 -0
- package/dist/daemon-runner.js +246 -0
- package/dist/extensions/config.d.ts +22 -0
- package/dist/extensions/config.js +102 -0
- package/dist/extensions/proposals.d.ts +30 -0
- package/dist/extensions/proposals.js +178 -0
- package/dist/extensions/registry.d.ts +35 -0
- package/dist/extensions/registry.js +309 -0
- package/dist/extensions/sandbox.d.ts +16 -0
- package/dist/extensions/sandbox.js +17 -0
- package/dist/extensions/types.d.ts +114 -0
- package/dist/extensions/types.js +4 -0
- package/dist/extensions/worker.d.ts +1 -0
- package/dist/extensions/worker.js +49 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +105 -0
- package/dist/mcp/handlers/archive-project.d.ts +51 -0
- package/dist/mcp/handlers/archive-project.js +112 -0
- package/dist/mcp/handlers/get-quotes.d.ts +27 -0
- package/dist/mcp/handlers/get-quotes.js +61 -0
- package/dist/mcp/handlers/get-source.d.ts +9 -0
- package/dist/mcp/handlers/get-source.js +40 -0
- package/dist/mcp/handlers/ingest.d.ts +25 -0
- package/dist/mcp/handlers/ingest.js +305 -0
- package/dist/mcp/handlers/list-projects.d.ts +4 -0
- package/dist/mcp/handlers/list-projects.js +16 -0
- package/dist/mcp/handlers/list-sources.d.ts +11 -0
- package/dist/mcp/handlers/list-sources.js +20 -0
- package/dist/mcp/handlers/research-agent.d.ts +21 -0
- package/dist/mcp/handlers/research-agent.js +369 -0
- package/dist/mcp/handlers/research.d.ts +22 -0
- package/dist/mcp/handlers/research.js +225 -0
- package/dist/mcp/handlers/retain.d.ts +18 -0
- package/dist/mcp/handlers/retain.js +92 -0
- package/dist/mcp/handlers/search.d.ts +52 -0
- package/dist/mcp/handlers/search.js +145 -0
- package/dist/mcp/handlers/sync.d.ts +47 -0
- package/dist/mcp/handlers/sync.js +211 -0
- package/dist/mcp/server.d.ts +10 -0
- package/dist/mcp/server.js +268 -0
- package/dist/mcp/tools.d.ts +16 -0
- package/dist/mcp/tools.js +297 -0
- package/dist/sync/config.d.ts +26 -0
- package/dist/sync/config.js +140 -0
- package/dist/sync/discover.d.ts +51 -0
- package/dist/sync/discover.js +190 -0
- package/dist/sync/index.d.ts +11 -0
- package/dist/sync/index.js +11 -0
- package/dist/sync/process.d.ts +50 -0
- package/dist/sync/process.js +285 -0
- package/dist/sync/processors.d.ts +24 -0
- package/dist/sync/processors.js +351 -0
- package/dist/tui/browse-handlers-ask.d.ts +30 -0
- package/dist/tui/browse-handlers-ask.js +372 -0
- package/dist/tui/browse-handlers-autocomplete.d.ts +49 -0
- package/dist/tui/browse-handlers-autocomplete.js +270 -0
- package/dist/tui/browse-handlers-extensions.d.ts +18 -0
- package/dist/tui/browse-handlers-extensions.js +107 -0
- package/dist/tui/browse-handlers-pending.d.ts +22 -0
- package/dist/tui/browse-handlers-pending.js +100 -0
- package/dist/tui/browse-handlers-research.d.ts +32 -0
- package/dist/tui/browse-handlers-research.js +363 -0
- package/dist/tui/browse-handlers-tools.d.ts +42 -0
- package/dist/tui/browse-handlers-tools.js +289 -0
- package/dist/tui/browse-handlers.d.ts +239 -0
- package/dist/tui/browse-handlers.js +1944 -0
- package/dist/tui/browse-render-extensions.d.ts +14 -0
- package/dist/tui/browse-render-extensions.js +114 -0
- package/dist/tui/browse-render-tools.d.ts +18 -0
- package/dist/tui/browse-render-tools.js +259 -0
- package/dist/tui/browse-render.d.ts +51 -0
- package/dist/tui/browse-render.js +599 -0
- package/dist/tui/browse-types.d.ts +142 -0
- package/dist/tui/browse-types.js +70 -0
- package/dist/tui/browse-ui.d.ts +10 -0
- package/dist/tui/browse-ui.js +432 -0
- package/dist/tui/browse.d.ts +17 -0
- package/dist/tui/browse.js +625 -0
- package/dist/tui/markdown.d.ts +22 -0
- package/dist/tui/markdown.js +223 -0
- package/package.json +71 -0
- package/plugins/claude-code/.claude-plugin/plugin.json +10 -0
- package/plugins/claude-code/.mcp.json +6 -0
- package/plugins/claude-code/skills/lore/SKILL.md +63 -0
- package/plugins/codex/SKILL.md +36 -0
- package/plugins/codex/agents/openai.yaml +10 -0
- package/plugins/gemini/GEMINI.md +31 -0
- package/plugins/gemini/gemini-extension.json +11 -0
- package/skills/generic-agent.md +99 -0
- package/skills/openclaw.md +67 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal markdown renderer
|
|
3
|
+
*
|
|
4
|
+
* Converts markdown to styled terminal output using ANSI codes.
|
|
5
|
+
* Designed for blessed terminals.
|
|
6
|
+
*/
|
|
7
|
+
import { colors } from '../cli/colors.js';
|
|
8
|
+
/**
|
|
9
|
+
* Render markdown to terminal-friendly styled text
|
|
10
|
+
*/
|
|
11
|
+
export function renderMarkdown(text, width = 80) {
|
|
12
|
+
const lines = text.split('\n');
|
|
13
|
+
const result = [];
|
|
14
|
+
let inCodeBlock = false;
|
|
15
|
+
let codeBlockLang = '';
|
|
16
|
+
for (let i = 0; i < lines.length; i++) {
|
|
17
|
+
let line = lines[i];
|
|
18
|
+
// Code blocks
|
|
19
|
+
if (line.startsWith('```')) {
|
|
20
|
+
if (!inCodeBlock) {
|
|
21
|
+
inCodeBlock = true;
|
|
22
|
+
codeBlockLang = line.slice(3).trim();
|
|
23
|
+
result.push(`${colors.dim}┌${'─'.repeat(Math.min(width - 2, 40))}${colors.reset}`);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
inCodeBlock = false;
|
|
28
|
+
codeBlockLang = '';
|
|
29
|
+
result.push(`${colors.dim}└${'─'.repeat(Math.min(width - 2, 40))}${colors.reset}`);
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (inCodeBlock) {
|
|
34
|
+
result.push(`${colors.dim}│${colors.reset} ${colors.yellow}${line}${colors.reset}`);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
// Headers
|
|
38
|
+
if (line.startsWith('######')) {
|
|
39
|
+
result.push(`${colors.bold}${colors.cyan}${line.slice(7).trim()}${colors.reset}`);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (line.startsWith('#####')) {
|
|
43
|
+
result.push(`${colors.bold}${colors.cyan}${line.slice(6).trim()}${colors.reset}`);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (line.startsWith('####')) {
|
|
47
|
+
result.push(`${colors.bold}${colors.cyan}${line.slice(5).trim()}${colors.reset}`);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (line.startsWith('###')) {
|
|
51
|
+
result.push(`${colors.bold}${colors.cyan}${line.slice(4).trim()}${colors.reset}`);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (line.startsWith('##')) {
|
|
55
|
+
result.push('');
|
|
56
|
+
result.push(`${colors.bold}${colors.blue}${line.slice(3).trim()}${colors.reset}`);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (line.startsWith('#')) {
|
|
60
|
+
result.push('');
|
|
61
|
+
result.push(`${colors.bold}${colors.cyan}${'═'.repeat(Math.min(line.slice(2).trim().length, width))}${colors.reset}`);
|
|
62
|
+
result.push(`${colors.bold}${colors.cyan}${line.slice(2).trim()}${colors.reset}`);
|
|
63
|
+
result.push(`${colors.bold}${colors.cyan}${'═'.repeat(Math.min(line.slice(2).trim().length, width))}${colors.reset}`);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
// Horizontal rules
|
|
67
|
+
if (/^[-*_]{3,}$/.test(line.trim())) {
|
|
68
|
+
result.push(`${colors.dim}${'─'.repeat(Math.min(width, 60))}${colors.reset}`);
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
// Blockquotes
|
|
72
|
+
if (line.startsWith('>')) {
|
|
73
|
+
const quoteText = line.slice(1).trim();
|
|
74
|
+
result.push(`${colors.dim}│${colors.reset} ${colors.italic}${quoteText}${colors.reset}`);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
// Unordered lists
|
|
78
|
+
if (/^\s*[-*+]\s/.test(line)) {
|
|
79
|
+
const indent = line.match(/^(\s*)/)?.[1] || '';
|
|
80
|
+
const content = line.replace(/^\s*[-*+]\s/, '');
|
|
81
|
+
result.push(`${indent}${colors.yellow}•${colors.reset} ${renderInline(content)}`);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
// Ordered lists
|
|
85
|
+
if (/^\s*\d+\.\s/.test(line)) {
|
|
86
|
+
const match = line.match(/^(\s*)(\d+)\.\s(.*)/);
|
|
87
|
+
if (match) {
|
|
88
|
+
const [, indent, num, content] = match;
|
|
89
|
+
result.push(`${indent}${colors.yellow}${num}.${colors.reset} ${renderInline(content)}`);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Regular paragraph with inline formatting
|
|
94
|
+
result.push(renderInline(line));
|
|
95
|
+
}
|
|
96
|
+
return result.join('\n');
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Render inline markdown elements
|
|
100
|
+
*/
|
|
101
|
+
function renderInline(text) {
|
|
102
|
+
// Bold **text** or __text__
|
|
103
|
+
text = text.replace(/\*\*(.+?)\*\*/g, `${colors.bold}$1${colors.reset}`);
|
|
104
|
+
text = text.replace(/__(.+?)__/g, `${colors.bold}$1${colors.reset}`);
|
|
105
|
+
// Italic *text* or _text_
|
|
106
|
+
text = text.replace(/\*([^*]+)\*/g, `${colors.italic}$1${colors.reset}`);
|
|
107
|
+
text = text.replace(/_([^_]+)_/g, `${colors.italic}$1${colors.reset}`);
|
|
108
|
+
// Inline code `text`
|
|
109
|
+
text = text.replace(/`([^`]+)`/g, `${colors.bgMagenta}${colors.white}$1${colors.reset}`);
|
|
110
|
+
// Links [text](url) - show text with underline
|
|
111
|
+
text = text.replace(/\[([^\]]+)\]\([^)]+\)/g, `${colors.underline}${colors.blue}$1${colors.reset}`);
|
|
112
|
+
// Strikethrough ~~text~~
|
|
113
|
+
text = text.replace(/~~(.+?)~~/g, `${colors.dim}$1${colors.reset}`);
|
|
114
|
+
return text;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Strip markdown formatting to get plain text
|
|
118
|
+
*/
|
|
119
|
+
export function stripMarkdown(text) {
|
|
120
|
+
// Remove code blocks
|
|
121
|
+
text = text.replace(/```[\s\S]*?```/g, '');
|
|
122
|
+
// Remove inline code
|
|
123
|
+
text = text.replace(/`([^`]+)`/g, '$1');
|
|
124
|
+
// Remove headers markers
|
|
125
|
+
text = text.replace(/^#{1,6}\s+/gm, '');
|
|
126
|
+
// Remove bold/italic
|
|
127
|
+
text = text.replace(/\*\*(.+?)\*\*/g, '$1');
|
|
128
|
+
text = text.replace(/__(.+?)__/g, '$1');
|
|
129
|
+
text = text.replace(/\*([^*]+)\*/g, '$1');
|
|
130
|
+
text = text.replace(/_([^_]+)_/g, '$1');
|
|
131
|
+
// Remove links but keep text
|
|
132
|
+
text = text.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1');
|
|
133
|
+
// Remove strikethrough
|
|
134
|
+
text = text.replace(/~~(.+?)~~/g, '$1');
|
|
135
|
+
// Remove blockquote markers
|
|
136
|
+
text = text.replace(/^>\s?/gm, '');
|
|
137
|
+
// Remove list markers
|
|
138
|
+
text = text.replace(/^\s*[-*+]\s/gm, '');
|
|
139
|
+
text = text.replace(/^\s*\d+\.\s/gm, '');
|
|
140
|
+
// Remove horizontal rules
|
|
141
|
+
text = text.replace(/^[-*_]{3,}$/gm, '');
|
|
142
|
+
return text.trim();
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Truncate text to fit width, preserving ANSI codes
|
|
146
|
+
*/
|
|
147
|
+
export function truncateWithAnsi(text, maxWidth) {
|
|
148
|
+
// ANSI escape code regex
|
|
149
|
+
const ansiRegex = /\x1b\[[0-9;]*m/g;
|
|
150
|
+
let visibleLength = 0;
|
|
151
|
+
let result = '';
|
|
152
|
+
let lastIndex = 0;
|
|
153
|
+
let match;
|
|
154
|
+
// Track open ANSI codes to properly close them
|
|
155
|
+
const openCodes = [];
|
|
156
|
+
while ((match = ansiRegex.exec(text)) !== null) {
|
|
157
|
+
// Add text before this ANSI code
|
|
158
|
+
const textBefore = text.slice(lastIndex, match.index);
|
|
159
|
+
const remainingSpace = maxWidth - visibleLength;
|
|
160
|
+
if (textBefore.length <= remainingSpace) {
|
|
161
|
+
result += textBefore;
|
|
162
|
+
visibleLength += textBefore.length;
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
result += textBefore.slice(0, remainingSpace - 1) + '…';
|
|
166
|
+
// Close any open ANSI codes
|
|
167
|
+
if (openCodes.length > 0) {
|
|
168
|
+
result += colors.reset;
|
|
169
|
+
}
|
|
170
|
+
return result;
|
|
171
|
+
}
|
|
172
|
+
// Add the ANSI code
|
|
173
|
+
result += match[0];
|
|
174
|
+
// Track open/close codes
|
|
175
|
+
if (match[0] === colors.reset) {
|
|
176
|
+
openCodes.length = 0;
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
openCodes.push(match[0]);
|
|
180
|
+
}
|
|
181
|
+
lastIndex = match.index + match[0].length;
|
|
182
|
+
}
|
|
183
|
+
// Add remaining text
|
|
184
|
+
const remainingText = text.slice(lastIndex);
|
|
185
|
+
const remainingSpace = maxWidth - visibleLength;
|
|
186
|
+
if (remainingText.length <= remainingSpace) {
|
|
187
|
+
result += remainingText;
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
result += remainingText.slice(0, remainingSpace - 1) + '…';
|
|
191
|
+
}
|
|
192
|
+
// Close any open ANSI codes
|
|
193
|
+
if (openCodes.length > 0) {
|
|
194
|
+
result += colors.reset;
|
|
195
|
+
}
|
|
196
|
+
return result;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Word wrap text while preserving ANSI codes
|
|
200
|
+
*/
|
|
201
|
+
export function wrapText(text, width) {
|
|
202
|
+
const words = text.split(/(\s+)/);
|
|
203
|
+
const lines = [];
|
|
204
|
+
let currentLine = '';
|
|
205
|
+
let currentLength = 0;
|
|
206
|
+
// ANSI escape code regex
|
|
207
|
+
const ansiRegex = /\x1b\[[0-9;]*m/g;
|
|
208
|
+
for (const word of words) {
|
|
209
|
+
// Calculate visible length (excluding ANSI codes)
|
|
210
|
+
const visibleLength = word.replace(ansiRegex, '').length;
|
|
211
|
+
if (currentLength + visibleLength > width && currentLine.length > 0) {
|
|
212
|
+
lines.push(currentLine.trimEnd());
|
|
213
|
+
currentLine = '';
|
|
214
|
+
currentLength = 0;
|
|
215
|
+
}
|
|
216
|
+
currentLine += word;
|
|
217
|
+
currentLength += visibleLength;
|
|
218
|
+
}
|
|
219
|
+
if (currentLine.length > 0) {
|
|
220
|
+
lines.push(currentLine.trimEnd());
|
|
221
|
+
}
|
|
222
|
+
return lines;
|
|
223
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@getlore/cli",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Research knowledge repository with semantic search, citations, and project lineage tracking",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"lore": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"plugins",
|
|
13
|
+
"skills",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE"
|
|
16
|
+
],
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc",
|
|
22
|
+
"start": "node dist/index.js",
|
|
23
|
+
"dev": "tsx src/index.ts",
|
|
24
|
+
"mcp": "node dist/mcp/server.js",
|
|
25
|
+
"prepublishOnly": "npm run build"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"knowledge-base",
|
|
29
|
+
"research",
|
|
30
|
+
"mcp",
|
|
31
|
+
"model-context-protocol",
|
|
32
|
+
"semantic-search",
|
|
33
|
+
"citations",
|
|
34
|
+
"project-management",
|
|
35
|
+
"ai-agents",
|
|
36
|
+
"claude"
|
|
37
|
+
],
|
|
38
|
+
"author": "Mishkin Faustini",
|
|
39
|
+
"homepage": "https://getlore.ai",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "https://github.com/getlore-ai/lore.git"
|
|
43
|
+
},
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/getlore-ai/lore/issues"
|
|
46
|
+
},
|
|
47
|
+
"license": "UNLICENSED",
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=18"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@anthropic-ai/claude-agent-sdk": "^0.2.22",
|
|
53
|
+
"@anthropic-ai/sdk": "^0.52.0",
|
|
54
|
+
"@modelcontextprotocol/sdk": "^1.25.3",
|
|
55
|
+
"@supabase/supabase-js": "^2.93.2",
|
|
56
|
+
"apache-arrow": "^18.1.0",
|
|
57
|
+
"blessed": "^0.1.81",
|
|
58
|
+
"chokidar": "^5.0.0",
|
|
59
|
+
"commander": "^12.1.0",
|
|
60
|
+
"dotenv": "^17.2.3",
|
|
61
|
+
"openai": "^4.77.0",
|
|
62
|
+
"pdf-parse": "^2.4.5",
|
|
63
|
+
"zod": "^3.24.0"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@types/blessed": "^0.1.27",
|
|
67
|
+
"@types/node": "^22.10.0",
|
|
68
|
+
"tsx": "^4.19.0",
|
|
69
|
+
"typescript": "^5.7.0"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "lore",
|
|
3
|
+
"description": "Research knowledge repository — semantic search, citations, and agent-driven ingestion from any source",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Mishkin Faustini"
|
|
7
|
+
},
|
|
8
|
+
"repository": "https://github.com/getlore-ai/lore",
|
|
9
|
+
"keywords": ["knowledge-base", "research", "citations", "semantic-search", "mcp"]
|
|
10
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lore
|
|
3
|
+
description: Search and ingest knowledge from Lore — a research repository with citations and semantic search
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Lore Knowledge Base
|
|
8
|
+
|
|
9
|
+
Lore is a research knowledge repository available via MCP. It stores documents, meeting notes, interviews, and decisions with full citations back to original sources. Use it to ground your work in evidence and preserve important context.
|
|
10
|
+
|
|
11
|
+
## MCP Tools
|
|
12
|
+
|
|
13
|
+
| Tool | Cost | Use For |
|
|
14
|
+
|------|------|---------|
|
|
15
|
+
| `search` | Low | Quick lookups, finding relevant sources |
|
|
16
|
+
| `get_source` | Low | Full document retrieval by ID |
|
|
17
|
+
| `list_sources` | Low | Browse what exists in a project |
|
|
18
|
+
| `list_projects` | Low | Discover available knowledge domains |
|
|
19
|
+
| `retain` | Low | Save discrete insights/decisions |
|
|
20
|
+
| `ingest` | Medium | Push full documents into the knowledge base |
|
|
21
|
+
| `research` | High | Cross-reference multiple sources, synthesize findings |
|
|
22
|
+
| `sync` | Variable | Refresh from configured source directories |
|
|
23
|
+
|
|
24
|
+
## When to Ingest
|
|
25
|
+
|
|
26
|
+
Use `ingest` to push content into Lore when:
|
|
27
|
+
- Working context should be preserved for future sessions
|
|
28
|
+
- Documents, specs, or research are shared that the team needs to reference later
|
|
29
|
+
- You encounter important external content (from integrations, web, etc.)
|
|
30
|
+
|
|
31
|
+
Always pass `source_url` (original URL for linking) and `source_name` (human-readable label like "GitHub PR #123") when available. Ingestion is idempotent — safe to call repeatedly with the same content.
|
|
32
|
+
|
|
33
|
+
## When to Search
|
|
34
|
+
|
|
35
|
+
Before making recommendations or answering questions about past work:
|
|
36
|
+
1. `search` first — it's fast and cheap
|
|
37
|
+
2. Only use `research` if the question genuinely needs cross-referencing multiple sources
|
|
38
|
+
3. Use `get_source(id, include_content: true)` when you need the full text
|
|
39
|
+
|
|
40
|
+
## When to Retain
|
|
41
|
+
|
|
42
|
+
Use `retain` for short synthesized knowledge (not full documents):
|
|
43
|
+
- Decisions made during a session
|
|
44
|
+
- Key insights distilled from analysis
|
|
45
|
+
- Requirements extracted from conversations
|
|
46
|
+
|
|
47
|
+
## Example: Grounding a Decision
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
# 1. Check what exists
|
|
51
|
+
search("database migration approach", project: "backend-rewrite")
|
|
52
|
+
|
|
53
|
+
# 2. If results are relevant, get full context
|
|
54
|
+
get_source("abc-123", include_content: true)
|
|
55
|
+
|
|
56
|
+
# 3. After making a decision, retain it
|
|
57
|
+
retain(
|
|
58
|
+
content: "Chose pgvector over Pinecone for embeddings — lower latency, simpler ops, sufficient scale",
|
|
59
|
+
project: "backend-rewrite",
|
|
60
|
+
type: "decision",
|
|
61
|
+
source_context: "Architecture review session"
|
|
62
|
+
)
|
|
63
|
+
```
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lore
|
|
3
|
+
description: Search and ingest knowledge from Lore — a research repository with citations and semantic search
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Lore Knowledge Base
|
|
7
|
+
|
|
8
|
+
Lore is a research knowledge repository available via MCP. It stores documents, meeting notes, interviews, and decisions with full citations back to original sources. Use it to ground your work in evidence and preserve important context.
|
|
9
|
+
|
|
10
|
+
## MCP Tools
|
|
11
|
+
|
|
12
|
+
| Tool | Cost | Use For |
|
|
13
|
+
|------|------|---------|
|
|
14
|
+
| `search` | Low | Quick lookups, finding relevant sources |
|
|
15
|
+
| `get_source` | Low | Full document retrieval by ID |
|
|
16
|
+
| `list_sources` | Low | Browse what exists in a project |
|
|
17
|
+
| `list_projects` | Low | Discover available knowledge domains |
|
|
18
|
+
| `retain` | Low | Save discrete insights/decisions |
|
|
19
|
+
| `ingest` | Medium | Push full documents into the knowledge base |
|
|
20
|
+
| `research` | High | Cross-reference multiple sources, synthesize findings |
|
|
21
|
+
| `sync` | Variable | Refresh from configured source directories |
|
|
22
|
+
|
|
23
|
+
## When to Ingest
|
|
24
|
+
|
|
25
|
+
Use `ingest` to push content into Lore when working context should be preserved, documents are shared, or you encounter important external content. Always pass `source_url` and `source_name` when available. Ingestion is idempotent.
|
|
26
|
+
|
|
27
|
+
## When to Search
|
|
28
|
+
|
|
29
|
+
Before making recommendations or answering questions about past work:
|
|
30
|
+
1. `search` first — it's fast and cheap
|
|
31
|
+
2. Only use `research` for multi-source synthesis (10x more expensive)
|
|
32
|
+
3. Use `get_source(id, include_content: true)` for full text
|
|
33
|
+
|
|
34
|
+
## When to Retain
|
|
35
|
+
|
|
36
|
+
Use `retain` for short synthesized knowledge (decisions, insights, requirements) — not full documents.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Lore Knowledge Base
|
|
2
|
+
|
|
3
|
+
Lore is a research knowledge repository available via MCP. It stores documents, meeting notes, interviews, and decisions with full citations back to original sources. Use it to ground your work in evidence and preserve important context.
|
|
4
|
+
|
|
5
|
+
## MCP Tools
|
|
6
|
+
|
|
7
|
+
| Tool | Cost | Use For |
|
|
8
|
+
|------|------|---------|
|
|
9
|
+
| `search` | Low | Quick lookups, finding relevant sources |
|
|
10
|
+
| `get_source` | Low | Full document retrieval by ID |
|
|
11
|
+
| `list_sources` | Low | Browse what exists in a project |
|
|
12
|
+
| `list_projects` | Low | Discover available knowledge domains |
|
|
13
|
+
| `retain` | Low | Save discrete insights/decisions |
|
|
14
|
+
| `ingest` | Medium | Push full documents into the knowledge base |
|
|
15
|
+
| `research` | High | Cross-reference multiple sources, synthesize findings |
|
|
16
|
+
| `sync` | Variable | Refresh from configured source directories |
|
|
17
|
+
|
|
18
|
+
## When to Ingest
|
|
19
|
+
|
|
20
|
+
Use `ingest` to push content into Lore when working context should be preserved, documents are shared, or you encounter important external content. Always pass `source_url` and `source_name` when available. Ingestion is idempotent.
|
|
21
|
+
|
|
22
|
+
## When to Search
|
|
23
|
+
|
|
24
|
+
Before making recommendations or answering questions about past work:
|
|
25
|
+
1. `search` first — it's fast and cheap
|
|
26
|
+
2. Only use `research` for multi-source synthesis (10x more expensive)
|
|
27
|
+
3. Use `get_source(id, include_content: true)` for full text
|
|
28
|
+
|
|
29
|
+
## When to Retain
|
|
30
|
+
|
|
31
|
+
Use `retain` for short synthesized knowledge (decisions, insights, requirements) — not full documents.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "lore",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Research knowledge repository — semantic search, citations, and agent-driven ingestion from any source",
|
|
5
|
+
"mcpServers": {
|
|
6
|
+
"lore": {
|
|
7
|
+
"command": "npx",
|
|
8
|
+
"args": ["-y", "@getlore/cli", "mcp"]
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Lore Knowledge Base — Agent Instructions
|
|
2
|
+
|
|
3
|
+
Lore is a research knowledge repository accessible via MCP (Model Context Protocol). It stores documents with full-text search, semantic search, and citation tracking. Content is deduplicated, embedded for retrieval, and organized by project.
|
|
4
|
+
|
|
5
|
+
## Core Concepts
|
|
6
|
+
|
|
7
|
+
- **Sources**: Full documents (meeting notes, interviews, Slack threads, specs, etc.)
|
|
8
|
+
- **Projects**: Organizational grouping for sources
|
|
9
|
+
- **Insights**: Short retained knowledge (decisions, requirements, observations)
|
|
10
|
+
- **Citations**: Every piece of knowledge links back to its original source
|
|
11
|
+
|
|
12
|
+
## Tools Reference
|
|
13
|
+
|
|
14
|
+
### `ingest` — Push content into Lore
|
|
15
|
+
The primary way to add content. Accepts any document with metadata.
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"content": "Full document text...",
|
|
20
|
+
"title": "Sprint Planning — Jan 15",
|
|
21
|
+
"project": "my-project",
|
|
22
|
+
"source_type": "meeting",
|
|
23
|
+
"source_url": "https://meet.google.com/abc-123",
|
|
24
|
+
"source_name": "Google Meet",
|
|
25
|
+
"participants": ["Alice", "Bob"],
|
|
26
|
+
"tags": ["sprint", "planning"]
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
- **Idempotent**: Duplicate content returns `{deduplicated: true}` with no processing cost.
|
|
31
|
+
- **source_type**: Free-form string. Common values: `meeting`, `interview`, `document`, `notes`, `analysis`, `conversation`, `slack`, `email`, `github-issue`, `notion`.
|
|
32
|
+
- **source_url**: Always pass when available — enables citation linking.
|
|
33
|
+
- **source_name**: Human-readable origin label.
|
|
34
|
+
|
|
35
|
+
### `search` — Find relevant sources
|
|
36
|
+
Fast lookup. Returns summaries with relevance scores.
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"query": "user feedback on export speed",
|
|
41
|
+
"project": "my-project",
|
|
42
|
+
"mode": "hybrid",
|
|
43
|
+
"limit": 5
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Modes:
|
|
48
|
+
- `hybrid` (default): Combined vector + full-text search. Best for most queries.
|
|
49
|
+
- `semantic`: Vector similarity only. For conceptual queries.
|
|
50
|
+
- `keyword`: Full-text only. For exact terms, names, identifiers.
|
|
51
|
+
- `regex`: Pattern matching. For code patterns or complex text matching.
|
|
52
|
+
|
|
53
|
+
### `get_source` — Retrieve full document
|
|
54
|
+
Get complete details of a source by ID. Set `include_content: true` for the full text.
|
|
55
|
+
|
|
56
|
+
### `list_sources` — Browse sources
|
|
57
|
+
List sources filtered by project or type. Sorted by date (newest first).
|
|
58
|
+
|
|
59
|
+
### `list_projects` — Discover projects
|
|
60
|
+
Lists all projects with source counts and activity dates.
|
|
61
|
+
|
|
62
|
+
### `retain` — Save discrete knowledge
|
|
63
|
+
For short insights, decisions, or requirements — not full documents.
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"content": "Users consistently report export takes >30s for large datasets",
|
|
68
|
+
"project": "my-project",
|
|
69
|
+
"type": "insight",
|
|
70
|
+
"source_context": "User interview synthesis — Jan batch"
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### `research` — Deep research with citations
|
|
75
|
+
Runs an internal agent that iteratively searches, reads, and synthesizes findings.
|
|
76
|
+
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"task": "What authentication approach should we use based on user feedback?",
|
|
80
|
+
"project": "my-project"
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Cost warning**: Makes 3-8 internal LLM calls. Use `search` for simple lookups.
|
|
85
|
+
|
|
86
|
+
### `sync` — Refresh from source directories
|
|
87
|
+
Scans configured directories for new files. Use `ingest` for agent-pushed content instead.
|
|
88
|
+
|
|
89
|
+
### `archive_project` — Archive a project
|
|
90
|
+
Excludes from default search. Only use when explicitly requested.
|
|
91
|
+
|
|
92
|
+
## Best Practices
|
|
93
|
+
|
|
94
|
+
1. **Search before you answer**: If a question might have documented context, search Lore first.
|
|
95
|
+
2. **Ingest what matters**: After meaningful conversations or when processing external content, ingest it.
|
|
96
|
+
3. **Always pass source_url**: Enables citation linking back to the original.
|
|
97
|
+
4. **Use retain for synthesis**: After analyzing multiple sources, retain the key insight.
|
|
98
|
+
5. **Prefer search over research**: `search` is 10x cheaper. Only use `research` for multi-source synthesis.
|
|
99
|
+
6. **Cite your sources**: When presenting Lore results, reference the source title and date.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lore
|
|
3
|
+
description: Search and ingest knowledge from Lore, a research repository with citations
|
|
4
|
+
version: "1.0"
|
|
5
|
+
user-invocable: false
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Lore Knowledge Base
|
|
9
|
+
|
|
10
|
+
Lore is a research knowledge repository you have access to via MCP tools. It stores documents, meeting notes, interviews, and decisions with full citations — not just summaries, but the original content linked back to its source. Use it to ground your answers in evidence and to preserve important context from your conversations.
|
|
11
|
+
|
|
12
|
+
## When to Ingest Content into Lore
|
|
13
|
+
|
|
14
|
+
Push content into Lore using the `ingest` tool whenever you encounter information worth preserving:
|
|
15
|
+
|
|
16
|
+
- **After conversations**: When a user shares meeting notes, interview transcripts, or important documents, ingest them so they're searchable later.
|
|
17
|
+
- **External content**: When you fetch content from Slack, Notion, GitHub, email, or other systems, ingest the relevant parts into Lore.
|
|
18
|
+
- **Decisions and context**: When important decisions are made or context is shared that future conversations will need.
|
|
19
|
+
|
|
20
|
+
Always include:
|
|
21
|
+
- `source_url`: The original URL (Slack permalink, Notion page URL, GitHub issue URL) for citation linking.
|
|
22
|
+
- `source_name`: A human-readable label like "Slack #product-team" or "GitHub issue #42".
|
|
23
|
+
- `project`: The project this content belongs to.
|
|
24
|
+
|
|
25
|
+
Ingestion is idempotent — calling `ingest` with the same content twice is safe and cheap (returns immediately with `deduplicated: true`).
|
|
26
|
+
|
|
27
|
+
## When to Search Lore
|
|
28
|
+
|
|
29
|
+
Before answering questions about past decisions, user feedback, project history, or anything that might already be documented:
|
|
30
|
+
|
|
31
|
+
1. **Use `search`** for quick lookups. Pick the right mode:
|
|
32
|
+
- `hybrid` (default): Best for most queries
|
|
33
|
+
- `keyword`: For exact terms, names, identifiers
|
|
34
|
+
- `semantic`: For conceptual queries ("user frustrations", "pain points")
|
|
35
|
+
|
|
36
|
+
2. **Use `research`** only when the question requires cross-referencing multiple sources or synthesizing findings. It costs 10x more than `search` — don't use it for simple lookups.
|
|
37
|
+
|
|
38
|
+
3. **Use `get_source`** with `include_content=true` when you need the full original text of a specific document.
|
|
39
|
+
|
|
40
|
+
## When to Retain Insights
|
|
41
|
+
|
|
42
|
+
Use `retain` (not `ingest`) for short, discrete pieces of knowledge:
|
|
43
|
+
- Key decisions: "We chose X because Y"
|
|
44
|
+
- Synthesized insights: "3/5 users mentioned Z as their top issue"
|
|
45
|
+
- Requirements: "Must support SSO for enterprise"
|
|
46
|
+
|
|
47
|
+
## Citation Best Practices
|
|
48
|
+
|
|
49
|
+
When presenting information from Lore, always cite your sources:
|
|
50
|
+
- Reference the source title and date
|
|
51
|
+
- Quote directly when possible
|
|
52
|
+
- If a `source_url` is available, link to the original
|
|
53
|
+
|
|
54
|
+
## Example Workflows
|
|
55
|
+
|
|
56
|
+
**User asks about past decisions:**
|
|
57
|
+
1. `search("authentication approach decisions", project: "my-app")`
|
|
58
|
+
2. Review results, get full source if needed: `get_source(source_id, include_content: true)`
|
|
59
|
+
3. Present findings with citations
|
|
60
|
+
|
|
61
|
+
**User shares meeting notes:**
|
|
62
|
+
1. `ingest(content: "...", title: "Sprint Planning Jan 15", project: "my-app", source_type: "meeting", source_name: "Google Meet", participants: ["Alice", "Bob"])`
|
|
63
|
+
2. Confirm ingestion to user
|
|
64
|
+
|
|
65
|
+
**User asks a broad research question:**
|
|
66
|
+
1. `research(task: "What do users think about our onboarding flow?", project: "my-app")`
|
|
67
|
+
2. Present the synthesized findings with citations
|