@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.
Files changed (148) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +80 -0
  3. package/dist/cli/colors.d.ts +48 -0
  4. package/dist/cli/colors.js +48 -0
  5. package/dist/cli/commands/ask.d.ts +7 -0
  6. package/dist/cli/commands/ask.js +97 -0
  7. package/dist/cli/commands/auth.d.ts +10 -0
  8. package/dist/cli/commands/auth.js +484 -0
  9. package/dist/cli/commands/daemon.d.ts +22 -0
  10. package/dist/cli/commands/daemon.js +244 -0
  11. package/dist/cli/commands/docs.d.ts +7 -0
  12. package/dist/cli/commands/docs.js +188 -0
  13. package/dist/cli/commands/extensions.d.ts +7 -0
  14. package/dist/cli/commands/extensions.js +204 -0
  15. package/dist/cli/commands/misc.d.ts +7 -0
  16. package/dist/cli/commands/misc.js +172 -0
  17. package/dist/cli/commands/pending.d.ts +7 -0
  18. package/dist/cli/commands/pending.js +63 -0
  19. package/dist/cli/commands/projects.d.ts +7 -0
  20. package/dist/cli/commands/projects.js +136 -0
  21. package/dist/cli/commands/search.d.ts +7 -0
  22. package/dist/cli/commands/search.js +102 -0
  23. package/dist/cli/commands/skills.d.ts +24 -0
  24. package/dist/cli/commands/skills.js +447 -0
  25. package/dist/cli/commands/sources.d.ts +7 -0
  26. package/dist/cli/commands/sources.js +121 -0
  27. package/dist/cli/commands/sync.d.ts +31 -0
  28. package/dist/cli/commands/sync.js +768 -0
  29. package/dist/cli/helpers.d.ts +30 -0
  30. package/dist/cli/helpers.js +119 -0
  31. package/dist/core/auth.d.ts +62 -0
  32. package/dist/core/auth.js +330 -0
  33. package/dist/core/config.d.ts +41 -0
  34. package/dist/core/config.js +96 -0
  35. package/dist/core/data-repo.d.ts +31 -0
  36. package/dist/core/data-repo.js +146 -0
  37. package/dist/core/embedder.d.ts +22 -0
  38. package/dist/core/embedder.js +104 -0
  39. package/dist/core/git.d.ts +37 -0
  40. package/dist/core/git.js +140 -0
  41. package/dist/core/index.d.ts +4 -0
  42. package/dist/core/index.js +5 -0
  43. package/dist/core/insight-extractor.d.ts +26 -0
  44. package/dist/core/insight-extractor.js +114 -0
  45. package/dist/core/local-search.d.ts +43 -0
  46. package/dist/core/local-search.js +221 -0
  47. package/dist/core/themes.d.ts +15 -0
  48. package/dist/core/themes.js +77 -0
  49. package/dist/core/types.d.ts +177 -0
  50. package/dist/core/types.js +9 -0
  51. package/dist/core/user-settings.d.ts +15 -0
  52. package/dist/core/user-settings.js +42 -0
  53. package/dist/core/vector-store-lance.d.ts +98 -0
  54. package/dist/core/vector-store-lance.js +384 -0
  55. package/dist/core/vector-store-supabase.d.ts +89 -0
  56. package/dist/core/vector-store-supabase.js +295 -0
  57. package/dist/core/vector-store.d.ts +131 -0
  58. package/dist/core/vector-store.js +503 -0
  59. package/dist/daemon-runner.d.ts +8 -0
  60. package/dist/daemon-runner.js +246 -0
  61. package/dist/extensions/config.d.ts +22 -0
  62. package/dist/extensions/config.js +102 -0
  63. package/dist/extensions/proposals.d.ts +30 -0
  64. package/dist/extensions/proposals.js +178 -0
  65. package/dist/extensions/registry.d.ts +35 -0
  66. package/dist/extensions/registry.js +309 -0
  67. package/dist/extensions/sandbox.d.ts +16 -0
  68. package/dist/extensions/sandbox.js +17 -0
  69. package/dist/extensions/types.d.ts +114 -0
  70. package/dist/extensions/types.js +4 -0
  71. package/dist/extensions/worker.d.ts +1 -0
  72. package/dist/extensions/worker.js +49 -0
  73. package/dist/index.d.ts +17 -0
  74. package/dist/index.js +105 -0
  75. package/dist/mcp/handlers/archive-project.d.ts +51 -0
  76. package/dist/mcp/handlers/archive-project.js +112 -0
  77. package/dist/mcp/handlers/get-quotes.d.ts +27 -0
  78. package/dist/mcp/handlers/get-quotes.js +61 -0
  79. package/dist/mcp/handlers/get-source.d.ts +9 -0
  80. package/dist/mcp/handlers/get-source.js +40 -0
  81. package/dist/mcp/handlers/ingest.d.ts +25 -0
  82. package/dist/mcp/handlers/ingest.js +305 -0
  83. package/dist/mcp/handlers/list-projects.d.ts +4 -0
  84. package/dist/mcp/handlers/list-projects.js +16 -0
  85. package/dist/mcp/handlers/list-sources.d.ts +11 -0
  86. package/dist/mcp/handlers/list-sources.js +20 -0
  87. package/dist/mcp/handlers/research-agent.d.ts +21 -0
  88. package/dist/mcp/handlers/research-agent.js +369 -0
  89. package/dist/mcp/handlers/research.d.ts +22 -0
  90. package/dist/mcp/handlers/research.js +225 -0
  91. package/dist/mcp/handlers/retain.d.ts +18 -0
  92. package/dist/mcp/handlers/retain.js +92 -0
  93. package/dist/mcp/handlers/search.d.ts +52 -0
  94. package/dist/mcp/handlers/search.js +145 -0
  95. package/dist/mcp/handlers/sync.d.ts +47 -0
  96. package/dist/mcp/handlers/sync.js +211 -0
  97. package/dist/mcp/server.d.ts +10 -0
  98. package/dist/mcp/server.js +268 -0
  99. package/dist/mcp/tools.d.ts +16 -0
  100. package/dist/mcp/tools.js +297 -0
  101. package/dist/sync/config.d.ts +26 -0
  102. package/dist/sync/config.js +140 -0
  103. package/dist/sync/discover.d.ts +51 -0
  104. package/dist/sync/discover.js +190 -0
  105. package/dist/sync/index.d.ts +11 -0
  106. package/dist/sync/index.js +11 -0
  107. package/dist/sync/process.d.ts +50 -0
  108. package/dist/sync/process.js +285 -0
  109. package/dist/sync/processors.d.ts +24 -0
  110. package/dist/sync/processors.js +351 -0
  111. package/dist/tui/browse-handlers-ask.d.ts +30 -0
  112. package/dist/tui/browse-handlers-ask.js +372 -0
  113. package/dist/tui/browse-handlers-autocomplete.d.ts +49 -0
  114. package/dist/tui/browse-handlers-autocomplete.js +270 -0
  115. package/dist/tui/browse-handlers-extensions.d.ts +18 -0
  116. package/dist/tui/browse-handlers-extensions.js +107 -0
  117. package/dist/tui/browse-handlers-pending.d.ts +22 -0
  118. package/dist/tui/browse-handlers-pending.js +100 -0
  119. package/dist/tui/browse-handlers-research.d.ts +32 -0
  120. package/dist/tui/browse-handlers-research.js +363 -0
  121. package/dist/tui/browse-handlers-tools.d.ts +42 -0
  122. package/dist/tui/browse-handlers-tools.js +289 -0
  123. package/dist/tui/browse-handlers.d.ts +239 -0
  124. package/dist/tui/browse-handlers.js +1944 -0
  125. package/dist/tui/browse-render-extensions.d.ts +14 -0
  126. package/dist/tui/browse-render-extensions.js +114 -0
  127. package/dist/tui/browse-render-tools.d.ts +18 -0
  128. package/dist/tui/browse-render-tools.js +259 -0
  129. package/dist/tui/browse-render.d.ts +51 -0
  130. package/dist/tui/browse-render.js +599 -0
  131. package/dist/tui/browse-types.d.ts +142 -0
  132. package/dist/tui/browse-types.js +70 -0
  133. package/dist/tui/browse-ui.d.ts +10 -0
  134. package/dist/tui/browse-ui.js +432 -0
  135. package/dist/tui/browse.d.ts +17 -0
  136. package/dist/tui/browse.js +625 -0
  137. package/dist/tui/markdown.d.ts +22 -0
  138. package/dist/tui/markdown.js +223 -0
  139. package/package.json +71 -0
  140. package/plugins/claude-code/.claude-plugin/plugin.json +10 -0
  141. package/plugins/claude-code/.mcp.json +6 -0
  142. package/plugins/claude-code/skills/lore/SKILL.md +63 -0
  143. package/plugins/codex/SKILL.md +36 -0
  144. package/plugins/codex/agents/openai.yaml +10 -0
  145. package/plugins/gemini/GEMINI.md +31 -0
  146. package/plugins/gemini/gemini-extension.json +11 -0
  147. package/skills/generic-agent.md +99 -0
  148. 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,6 @@
1
+ {
2
+ "lore": {
3
+ "command": "npx",
4
+ "args": ["-y", "@getlore/cli", "mcp"]
5
+ }
6
+ }
@@ -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,10 @@
1
+ display_name: Lore
2
+ description: Research knowledge repository with semantic search, citations, and agent-driven ingestion
3
+ icon_url: https://github.com/getlore-ai/lore
4
+ mcp_servers:
5
+ - name: lore
6
+ command: npx
7
+ args:
8
+ - "-y"
9
+ - "@getlore/cli"
10
+ - mcp
@@ -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