@telvok/librarian-mcp 1.5.3 → 2.0.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/dist/library/errors.d.ts +48 -0
- package/dist/library/errors.js +80 -0
- package/dist/library/parsers/jsonl.d.ts +9 -4
- package/dist/library/parsers/jsonl.js +52 -20
- package/dist/library/schemas.d.ts +6 -6
- package/dist/library/storage.d.ts +2 -2
- package/dist/library/storage.js +2 -2
- package/dist/library 2/embeddings.d.ts +21 -0
- package/dist/library 2/embeddings.js +86 -0
- package/dist/library 2/manager.d.ts +42 -0
- package/dist/library 2/manager.js +218 -0
- package/dist/library 2/parsers/cursor.d.ts +15 -0
- package/dist/library 2/parsers/cursor.js +168 -0
- package/dist/library 2/parsers/index.d.ts +6 -0
- package/dist/library 2/parsers/index.js +5 -0
- package/dist/library 2/parsers/json.d.ts +11 -0
- package/dist/library 2/parsers/json.js +95 -0
- package/dist/library 2/parsers/jsonl.d.ts +14 -0
- package/dist/library 2/parsers/jsonl.js +85 -0
- package/dist/library 2/parsers/markdown.d.ts +15 -0
- package/dist/library 2/parsers/markdown.js +77 -0
- package/dist/library 2/parsers/sqlite.d.ts +8 -0
- package/dist/library 2/parsers/sqlite.js +123 -0
- package/dist/library 2/parsers/types.d.ts +21 -0
- package/dist/library 2/parsers/types.js +4 -0
- package/dist/library 2/query.d.ts +26 -0
- package/dist/library 2/query.js +104 -0
- package/dist/library 2/schemas.d.ts +324 -0
- package/dist/library 2/schemas.js +79 -0
- package/dist/library 2/storage.d.ts +22 -0
- package/dist/library 2/storage.js +36 -0
- package/dist/library 2/vector-index.d.ts +55 -0
- package/dist/library 2/vector-index.js +160 -0
- package/dist/server 2.js +199 -0
- package/dist/server.d 2.ts +2 -0
- package/dist/server.js +102 -54
- package/dist/tools/adopt.d.ts +1 -0
- package/dist/tools/adopt.js +37 -10
- package/dist/tools/auth.d.ts +69 -0
- package/dist/tools/auth.js +379 -0
- package/dist/tools/bounty-claim.d.ts +28 -0
- package/dist/tools/bounty-claim.js +92 -0
- package/dist/tools/bounty-create.d.ts +47 -0
- package/dist/tools/bounty-create.js +118 -0
- package/dist/tools/bounty-list.d.ts +50 -0
- package/dist/tools/bounty-list.js +116 -0
- package/dist/tools/bounty-submit.d.ts +34 -0
- package/dist/tools/bounty-submit.js +94 -0
- package/dist/tools/brief.d.ts +94 -0
- package/dist/tools/brief.js +234 -15
- package/dist/tools/delete.d.ts +87 -0
- package/dist/tools/delete.js +266 -0
- package/dist/tools/feedback.d.ts +27 -0
- package/dist/tools/feedback.js +98 -0
- package/dist/tools/help.d.ts +22 -0
- package/dist/tools/help.js +482 -0
- package/dist/tools/import-memories.d.ts +1 -0
- package/dist/tools/import-memories.js +18 -13
- package/dist/tools/index.d.ts +11 -0
- package/dist/tools/index.js +12 -0
- package/dist/tools/library-buy.d.ts +31 -0
- package/dist/tools/library-buy.js +104 -0
- package/dist/tools/library-download.d.ts +27 -0
- package/dist/tools/library-download.js +177 -0
- package/dist/tools/library-publish.d.ts +112 -0
- package/dist/tools/library-publish.js +387 -0
- package/dist/tools/library-search.d.ts +110 -0
- package/dist/tools/library-search.js +132 -0
- package/dist/tools/mark-hit.d.ts +1 -0
- package/dist/tools/mark-hit.js +83 -5
- package/dist/tools/my-books.d.ts +51 -0
- package/dist/tools/my-books.js +115 -0
- package/dist/tools/my-bounties.d.ts +43 -0
- package/dist/tools/my-bounties.js +126 -0
- package/dist/tools/rate-book.d.ts +40 -0
- package/dist/tools/rate-book.js +147 -0
- package/dist/tools/rebuild-index.d.ts +1 -0
- package/dist/tools/rebuild-index.js +40 -8
- package/dist/tools/record.d.ts +18 -0
- package/dist/tools/record.js +30 -26
- package/dist/tools/seller-analytics.d.ts +53 -0
- package/dist/tools/seller-analytics.js +180 -0
- package/dist/tools/sync.d.ts +55 -0
- package/dist/tools/sync.js +304 -0
- package/dist/tools/unsubscribe.d.ts +48 -0
- package/dist/tools/unsubscribe.js +120 -0
- package/dist/tools 2/adopt.d.ts +24 -0
- package/dist/tools 2/adopt.js +154 -0
- package/dist/tools 2/auth.d.ts +35 -0
- package/dist/tools 2/auth.js +229 -0
- package/dist/tools 2/brief.d.ts +56 -0
- package/dist/tools 2/brief.js +414 -0
- package/dist/tools 2/help.d.ts +21 -0
- package/dist/tools 2/help.js +267 -0
- package/dist/tools 2/import-memories.d.ts +32 -0
- package/dist/tools 2/import-memories.js +231 -0
- package/dist/tools 2/index.d.ts +12 -0
- package/dist/tools 2/index.js +12 -0
- package/dist/tools 2/mark-hit.d.ts +20 -0
- package/dist/tools 2/mark-hit.js +71 -0
- package/dist/tools 2/marketplace-buy.d.ts +30 -0
- package/dist/tools 2/marketplace-buy.js +97 -0
- package/dist/tools 2/marketplace-download.d.ts +26 -0
- package/dist/tools 2/marketplace-download.js +160 -0
- package/dist/tools 2/marketplace-publish.d.ts +111 -0
- package/dist/tools 2/marketplace-publish.js +377 -0
- package/dist/tools 2/marketplace-search.d.ts +57 -0
- package/dist/tools 2/marketplace-search.js +96 -0
- package/dist/tools 2/my-books.d.ts +50 -0
- package/dist/tools 2/my-books.js +107 -0
- package/dist/tools 2/rate-book.d.ts +39 -0
- package/dist/tools 2/rate-book.js +139 -0
- package/dist/tools 2/rebuild-index.d.ts +23 -0
- package/dist/tools 2/rebuild-index.js +107 -0
- package/dist/tools 2/record.d.ts +40 -0
- package/dist/tools 2/record.js +205 -0
- package/dist/tools 2/seller-analytics.d.ts +35 -0
- package/dist/tools 2/seller-analytics.js +102 -0
- package/dist/tools 2/sync.d.ts +54 -0
- package/dist/tools 2/sync.js +298 -0
- package/package.json +1 -1
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import * as fs from 'fs/promises';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { glob } from 'glob';
|
|
4
|
+
import matter from 'gray-matter';
|
|
5
|
+
/**
|
|
6
|
+
* Parse a folder of markdown files (Basic Memory MCP / Obsidian / any .md).
|
|
7
|
+
*
|
|
8
|
+
* Input format:
|
|
9
|
+
* ---
|
|
10
|
+
* title: API Rate Limits
|
|
11
|
+
* tags: [api, performance]
|
|
12
|
+
* ---
|
|
13
|
+
*
|
|
14
|
+
* # API Rate Limits
|
|
15
|
+
*
|
|
16
|
+
* Always implement exponential backoff...
|
|
17
|
+
*/
|
|
18
|
+
export async function parseMarkdown(dirPath) {
|
|
19
|
+
const entries = [];
|
|
20
|
+
const errors = [];
|
|
21
|
+
let skipped = 0;
|
|
22
|
+
try {
|
|
23
|
+
// Handle both single file and directory
|
|
24
|
+
const stats = await fs.stat(dirPath);
|
|
25
|
+
const files = stats.isDirectory()
|
|
26
|
+
? await glob(path.join(dirPath, '**/*.md'), { nodir: true })
|
|
27
|
+
: [dirPath];
|
|
28
|
+
for (const filePath of files) {
|
|
29
|
+
try {
|
|
30
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
31
|
+
const { data, content: body } = matter(content);
|
|
32
|
+
const frontmatter = data;
|
|
33
|
+
// Skip empty files
|
|
34
|
+
const trimmedBody = body.trim();
|
|
35
|
+
if (!trimmedBody) {
|
|
36
|
+
skipped++;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
// Extract title from frontmatter, H1, or filename
|
|
40
|
+
let title = frontmatter.title;
|
|
41
|
+
if (!title) {
|
|
42
|
+
const headingMatch = trimmedBody.match(/^#\s+(.+)$/m);
|
|
43
|
+
if (headingMatch) {
|
|
44
|
+
title = headingMatch[1].trim();
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
title = path.basename(filePath, '.md').replace(/-/g, ' ');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Extract context from tags or context field
|
|
51
|
+
let context;
|
|
52
|
+
if (frontmatter.context) {
|
|
53
|
+
context = frontmatter.context;
|
|
54
|
+
}
|
|
55
|
+
else if (frontmatter.tags && Array.isArray(frontmatter.tags)) {
|
|
56
|
+
context = frontmatter.tags.join(', ');
|
|
57
|
+
}
|
|
58
|
+
entries.push({
|
|
59
|
+
title,
|
|
60
|
+
content: trimmedBody,
|
|
61
|
+
context,
|
|
62
|
+
intent: frontmatter.intent,
|
|
63
|
+
source: 'markdown',
|
|
64
|
+
originalPath: filePath,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch (fileError) {
|
|
68
|
+
errors.push(`${filePath}: ${fileError instanceof Error ? fileError.message : String(fileError)}`);
|
|
69
|
+
skipped++;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch (dirError) {
|
|
74
|
+
errors.push(`Failed to access path: ${dirError instanceof Error ? dirError.message : String(dirError)}`);
|
|
75
|
+
}
|
|
76
|
+
return { entries, skipped, errors };
|
|
77
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ParseResult } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parse a SQLite database file for memory entries.
|
|
4
|
+
*
|
|
5
|
+
* Auto-detects table and column names from common patterns.
|
|
6
|
+
* Supports mcp-memory-service, SQLite-vec, and custom schemas.
|
|
7
|
+
*/
|
|
8
|
+
export declare function parseSQLite(filePath: string): Promise<ParseResult>;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
// ============================================================================
|
|
3
|
+
// SQLite Parser - mcp-memory-service, SQLite-vec, custom databases
|
|
4
|
+
// ============================================================================
|
|
5
|
+
// Common table names for memory storage
|
|
6
|
+
const TABLE_CANDIDATES = ['memories', 'entries', 'knowledge', 'notes', 'items', 'documents'];
|
|
7
|
+
// Common column names for different fields
|
|
8
|
+
const TITLE_CANDIDATES = ['title', 'name', 'key', 'id', 'subject', 'heading'];
|
|
9
|
+
const CONTENT_CANDIDATES = ['content', 'text', 'value', 'memory', 'observation', 'body', 'description', 'note'];
|
|
10
|
+
const CONTEXT_CANDIDATES = ['context', 'category', 'type', 'tags', 'topic', 'area'];
|
|
11
|
+
/**
|
|
12
|
+
* Parse a SQLite database file for memory entries.
|
|
13
|
+
*
|
|
14
|
+
* Auto-detects table and column names from common patterns.
|
|
15
|
+
* Supports mcp-memory-service, SQLite-vec, and custom schemas.
|
|
16
|
+
*/
|
|
17
|
+
export async function parseSQLite(filePath) {
|
|
18
|
+
const entries = [];
|
|
19
|
+
const errors = [];
|
|
20
|
+
let skipped = 0;
|
|
21
|
+
let db = null;
|
|
22
|
+
try {
|
|
23
|
+
db = new Database(filePath, { readonly: true });
|
|
24
|
+
// Find a suitable table
|
|
25
|
+
const tables = db
|
|
26
|
+
.prepare("SELECT name FROM sqlite_master WHERE type='table'")
|
|
27
|
+
.all();
|
|
28
|
+
const tableNames = tables.map((t) => t.name.toLowerCase());
|
|
29
|
+
const targetTable = TABLE_CANDIDATES.find((candidate) => tableNames.includes(candidate));
|
|
30
|
+
if (!targetTable) {
|
|
31
|
+
errors.push(`No memory table found. Available tables: ${tableNames.join(', ')}. ` +
|
|
32
|
+
`Expected one of: ${TABLE_CANDIDATES.join(', ')}`);
|
|
33
|
+
return { entries, skipped, errors };
|
|
34
|
+
}
|
|
35
|
+
// Get column info for the target table
|
|
36
|
+
const columns = db.prepare(`PRAGMA table_info(${targetTable})`).all();
|
|
37
|
+
const columnNames = columns.map((c) => c.name.toLowerCase());
|
|
38
|
+
// Find content column (required)
|
|
39
|
+
const contentColumn = CONTENT_CANDIDATES.find((candidate) => columnNames.includes(candidate));
|
|
40
|
+
if (!contentColumn) {
|
|
41
|
+
errors.push(`No content column found in table "${targetTable}". ` +
|
|
42
|
+
`Available columns: ${columnNames.join(', ')}. ` +
|
|
43
|
+
`Expected one of: ${CONTENT_CANDIDATES.join(', ')}`);
|
|
44
|
+
return { entries, skipped, errors };
|
|
45
|
+
}
|
|
46
|
+
// Find optional columns
|
|
47
|
+
const titleColumn = TITLE_CANDIDATES.find((candidate) => columnNames.includes(candidate));
|
|
48
|
+
const contextColumn = CONTEXT_CANDIDATES.find((candidate) => columnNames.includes(candidate));
|
|
49
|
+
// Build and execute query
|
|
50
|
+
const selectColumns = [
|
|
51
|
+
contentColumn,
|
|
52
|
+
titleColumn,
|
|
53
|
+
contextColumn,
|
|
54
|
+
].filter(Boolean);
|
|
55
|
+
const query = `SELECT ${selectColumns.join(', ')} FROM ${targetTable}`;
|
|
56
|
+
const rows = db.prepare(query).all();
|
|
57
|
+
for (let i = 0; i < rows.length; i++) {
|
|
58
|
+
const row = rows[i];
|
|
59
|
+
// Extract content
|
|
60
|
+
const content = row[contentColumn];
|
|
61
|
+
if (!content || typeof content !== 'string' || !content.trim()) {
|
|
62
|
+
skipped++;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
// Extract title
|
|
66
|
+
let title;
|
|
67
|
+
if (titleColumn && row[titleColumn]) {
|
|
68
|
+
title = String(row[titleColumn]);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// Generate title from content
|
|
72
|
+
title = content.slice(0, 60).replace(/\s+/g, ' ').trim();
|
|
73
|
+
if (content.length > 60)
|
|
74
|
+
title += '...';
|
|
75
|
+
}
|
|
76
|
+
// Extract context
|
|
77
|
+
let context;
|
|
78
|
+
if (contextColumn && row[contextColumn]) {
|
|
79
|
+
const contextValue = row[contextColumn];
|
|
80
|
+
if (typeof contextValue === 'string') {
|
|
81
|
+
context = contextValue;
|
|
82
|
+
}
|
|
83
|
+
else if (Array.isArray(contextValue)) {
|
|
84
|
+
context = contextValue.join(', ');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
entries.push({
|
|
88
|
+
title,
|
|
89
|
+
content: content.trim(),
|
|
90
|
+
context,
|
|
91
|
+
source: 'sqlite',
|
|
92
|
+
originalPath: `${filePath}:${targetTable}`,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
if (error instanceof Error) {
|
|
98
|
+
if (error.message.includes('SQLITE_CANTOPEN')) {
|
|
99
|
+
errors.push(`Cannot open database file: ${filePath}`);
|
|
100
|
+
}
|
|
101
|
+
else if (error.message.includes('file is not a database')) {
|
|
102
|
+
errors.push(`File is not a valid SQLite database: ${filePath}`);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
errors.push(`SQLite error: ${error.message}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
errors.push(`Unknown error: ${String(error)}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
if (db) {
|
|
114
|
+
try {
|
|
115
|
+
db.close();
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// Ignore close errors
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return { entries, skipped, errors };
|
|
123
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A parsed memory entry ready to be converted to Librarian format.
|
|
3
|
+
*/
|
|
4
|
+
export interface ParsedEntry {
|
|
5
|
+
title: string;
|
|
6
|
+
content: string;
|
|
7
|
+
context?: string;
|
|
8
|
+
intent?: string;
|
|
9
|
+
reasoning?: string;
|
|
10
|
+
example?: string;
|
|
11
|
+
source: 'jsonl' | 'markdown' | 'cursor' | 'json' | 'sqlite';
|
|
12
|
+
originalPath?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Result of a parse operation.
|
|
16
|
+
*/
|
|
17
|
+
export interface ParseResult {
|
|
18
|
+
entries: ParsedEntry[];
|
|
19
|
+
skipped: number;
|
|
20
|
+
errors: string[];
|
|
21
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { LibraryEntry } from './schemas.js';
|
|
2
|
+
/**
|
|
3
|
+
* Score how well an entry matches a search term.
|
|
4
|
+
*/
|
|
5
|
+
export declare function scoreMatch(entry: LibraryEntry, searchTerm: string): number;
|
|
6
|
+
/**
|
|
7
|
+
* Detect potential conflicts between entries.
|
|
8
|
+
* Returns true if entries on the same topic give contradictory advice.
|
|
9
|
+
*/
|
|
10
|
+
export declare function detectConflict(entries: LibraryEntry[]): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Generate a conflict summary.
|
|
13
|
+
*/
|
|
14
|
+
export declare function generateConflictSummary(entries: LibraryEntry[]): string;
|
|
15
|
+
/**
|
|
16
|
+
* Filter entries by topic.
|
|
17
|
+
*/
|
|
18
|
+
export declare function filterByTopic(entries: LibraryEntry[], topic: string): LibraryEntry[];
|
|
19
|
+
/**
|
|
20
|
+
* Sort entries by relevance to search term.
|
|
21
|
+
*/
|
|
22
|
+
export declare function sortByRelevance(entries: LibraryEntry[], searchTerm: string): LibraryEntry[];
|
|
23
|
+
/**
|
|
24
|
+
* Group entries by source.
|
|
25
|
+
*/
|
|
26
|
+
export declare function groupBySource(entries: LibraryEntry[]): Record<string, LibraryEntry[]>;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Query Utilities
|
|
3
|
+
// ============================================================================
|
|
4
|
+
/**
|
|
5
|
+
* Score how well an entry matches a search term.
|
|
6
|
+
*/
|
|
7
|
+
export function scoreMatch(entry, searchTerm) {
|
|
8
|
+
const term = searchTerm.toLowerCase();
|
|
9
|
+
let score = 0;
|
|
10
|
+
// Topic matches (highest weight)
|
|
11
|
+
for (const topic of entry.topics) {
|
|
12
|
+
if (topic.toLowerCase() === term) {
|
|
13
|
+
score += 10; // Exact match
|
|
14
|
+
}
|
|
15
|
+
else if (topic.toLowerCase().includes(term)) {
|
|
16
|
+
score += 5; // Partial match
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
// Content matches
|
|
20
|
+
const contentLower = entry.content.toLowerCase();
|
|
21
|
+
if (contentLower.includes(term)) {
|
|
22
|
+
// Count occurrences
|
|
23
|
+
const matches = contentLower.split(term).length - 1;
|
|
24
|
+
score += Math.min(matches * 2, 8); // Cap at 8
|
|
25
|
+
}
|
|
26
|
+
return score;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Detect potential conflicts between entries.
|
|
30
|
+
* Returns true if entries on the same topic give contradictory advice.
|
|
31
|
+
*/
|
|
32
|
+
export function detectConflict(entries) {
|
|
33
|
+
if (entries.length < 2)
|
|
34
|
+
return false;
|
|
35
|
+
// Simple heuristic: look for negation patterns
|
|
36
|
+
const negationPatterns = [
|
|
37
|
+
/don't|dont|never|avoid|stop/i,
|
|
38
|
+
/always|must|should/i,
|
|
39
|
+
];
|
|
40
|
+
let hasNegation = false;
|
|
41
|
+
let hasAffirmation = false;
|
|
42
|
+
for (const entry of entries) {
|
|
43
|
+
if (negationPatterns[0].test(entry.content)) {
|
|
44
|
+
hasNegation = true;
|
|
45
|
+
}
|
|
46
|
+
if (negationPatterns[1].test(entry.content)) {
|
|
47
|
+
hasAffirmation = true;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// This is a very simple heuristic - could be improved with semantic analysis
|
|
51
|
+
return hasNegation && hasAffirmation;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Generate a conflict summary.
|
|
55
|
+
*/
|
|
56
|
+
export function generateConflictSummary(entries) {
|
|
57
|
+
if (entries.length < 2)
|
|
58
|
+
return '';
|
|
59
|
+
const sources = entries.map(e => {
|
|
60
|
+
if (e.imported_from) {
|
|
61
|
+
return `imported/${e.imported_from}`;
|
|
62
|
+
}
|
|
63
|
+
return e.source;
|
|
64
|
+
});
|
|
65
|
+
const uniqueSources = [...new Set(sources)];
|
|
66
|
+
return `Found ${entries.length} entries that may conflict. Sources: ${uniqueSources.join(', ')}. Review and decide which to keep.`;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Filter entries by topic.
|
|
70
|
+
*/
|
|
71
|
+
export function filterByTopic(entries, topic) {
|
|
72
|
+
const term = topic.toLowerCase();
|
|
73
|
+
return entries.filter(entry => entry.topics.some(t => t.toLowerCase().includes(term)));
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Sort entries by relevance to search term.
|
|
77
|
+
*/
|
|
78
|
+
export function sortByRelevance(entries, searchTerm) {
|
|
79
|
+
return [...entries].sort((a, b) => {
|
|
80
|
+
const scoreA = scoreMatch(a, searchTerm);
|
|
81
|
+
const scoreB = scoreMatch(b, searchTerm);
|
|
82
|
+
return scoreB - scoreA;
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Group entries by source.
|
|
87
|
+
*/
|
|
88
|
+
export function groupBySource(entries) {
|
|
89
|
+
const groups = {
|
|
90
|
+
local: [],
|
|
91
|
+
imported: [],
|
|
92
|
+
archived: [],
|
|
93
|
+
};
|
|
94
|
+
for (const entry of entries) {
|
|
95
|
+
const key = entry.source;
|
|
96
|
+
if (groups[key]) {
|
|
97
|
+
groups[key].push(entry);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
groups.local.push(entry); // Default to local
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return groups;
|
|
104
|
+
}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const SourceTypeSchema: z.ZodEnum<["local", "imported", "archived"]>;
|
|
3
|
+
export type SourceType = z.infer<typeof SourceTypeSchema>;
|
|
4
|
+
export declare const EntrySourceSchema: z.ZodEnum<["manual", "precompact", "imported"]>;
|
|
5
|
+
export type EntrySource = z.infer<typeof EntrySourceSchema>;
|
|
6
|
+
export declare const LibraryEntrySchema: z.ZodObject<{
|
|
7
|
+
id: z.ZodString;
|
|
8
|
+
topics: z.ZodArray<z.ZodString, "many">;
|
|
9
|
+
content: z.ZodString;
|
|
10
|
+
created: z.ZodString;
|
|
11
|
+
source: z.ZodEnum<["local", "imported", "archived"]>;
|
|
12
|
+
origin: z.ZodOptional<z.ZodEnum<["manual", "precompact", "imported"]>>;
|
|
13
|
+
imported_from: z.ZodOptional<z.ZodString>;
|
|
14
|
+
}, "strip", z.ZodTypeAny, {
|
|
15
|
+
content: string;
|
|
16
|
+
created: string;
|
|
17
|
+
source: "local" | "imported" | "archived";
|
|
18
|
+
id: string;
|
|
19
|
+
topics: string[];
|
|
20
|
+
origin?: "imported" | "manual" | "precompact" | undefined;
|
|
21
|
+
imported_from?: string | undefined;
|
|
22
|
+
}, {
|
|
23
|
+
content: string;
|
|
24
|
+
created: string;
|
|
25
|
+
source: "local" | "imported" | "archived";
|
|
26
|
+
id: string;
|
|
27
|
+
topics: string[];
|
|
28
|
+
origin?: "imported" | "manual" | "precompact" | undefined;
|
|
29
|
+
imported_from?: string | undefined;
|
|
30
|
+
}>;
|
|
31
|
+
export type LibraryEntry = z.infer<typeof LibraryEntrySchema>;
|
|
32
|
+
export declare const FrontmatterSchema: z.ZodObject<{
|
|
33
|
+
id: z.ZodString;
|
|
34
|
+
topics: z.ZodArray<z.ZodString, "many">;
|
|
35
|
+
created: z.ZodString;
|
|
36
|
+
source: z.ZodOptional<z.ZodEnum<["manual", "precompact", "imported"]>>;
|
|
37
|
+
imported_from: z.ZodOptional<z.ZodString>;
|
|
38
|
+
}, "strip", z.ZodTypeAny, {
|
|
39
|
+
created: string;
|
|
40
|
+
id: string;
|
|
41
|
+
topics: string[];
|
|
42
|
+
source?: "imported" | "manual" | "precompact" | undefined;
|
|
43
|
+
imported_from?: string | undefined;
|
|
44
|
+
}, {
|
|
45
|
+
created: string;
|
|
46
|
+
id: string;
|
|
47
|
+
topics: string[];
|
|
48
|
+
source?: "imported" | "manual" | "precompact" | undefined;
|
|
49
|
+
imported_from?: string | undefined;
|
|
50
|
+
}>;
|
|
51
|
+
export type Frontmatter = z.infer<typeof FrontmatterSchema>;
|
|
52
|
+
export declare const BriefParamsSchema: z.ZodObject<{
|
|
53
|
+
topic: z.ZodString;
|
|
54
|
+
context: z.ZodOptional<z.ZodString>;
|
|
55
|
+
}, "strip", z.ZodTypeAny, {
|
|
56
|
+
topic: string;
|
|
57
|
+
context?: string | undefined;
|
|
58
|
+
}, {
|
|
59
|
+
topic: string;
|
|
60
|
+
context?: string | undefined;
|
|
61
|
+
}>;
|
|
62
|
+
export type BriefParams = z.infer<typeof BriefParamsSchema>;
|
|
63
|
+
export declare const RecordParamsSchema: z.ZodObject<{
|
|
64
|
+
topics: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>;
|
|
65
|
+
content: z.ZodString;
|
|
66
|
+
}, "strip", z.ZodTypeAny, {
|
|
67
|
+
content: string;
|
|
68
|
+
topics: string | string[];
|
|
69
|
+
}, {
|
|
70
|
+
content: string;
|
|
71
|
+
topics: string | string[];
|
|
72
|
+
}>;
|
|
73
|
+
export type RecordParams = z.infer<typeof RecordParamsSchema>;
|
|
74
|
+
export declare const AdoptParamsSchema: z.ZodObject<{
|
|
75
|
+
entry_id: z.ZodString;
|
|
76
|
+
library_name: z.ZodOptional<z.ZodString>;
|
|
77
|
+
}, "strip", z.ZodTypeAny, {
|
|
78
|
+
entry_id: string;
|
|
79
|
+
library_name?: string | undefined;
|
|
80
|
+
}, {
|
|
81
|
+
entry_id: string;
|
|
82
|
+
library_name?: string | undefined;
|
|
83
|
+
}>;
|
|
84
|
+
export type AdoptParams = z.infer<typeof AdoptParamsSchema>;
|
|
85
|
+
export declare const BriefResultSchema: z.ZodObject<{
|
|
86
|
+
entries: z.ZodArray<z.ZodObject<{
|
|
87
|
+
id: z.ZodString;
|
|
88
|
+
topics: z.ZodArray<z.ZodString, "many">;
|
|
89
|
+
content: z.ZodString;
|
|
90
|
+
created: z.ZodString;
|
|
91
|
+
source: z.ZodEnum<["local", "imported", "archived"]>;
|
|
92
|
+
origin: z.ZodOptional<z.ZodEnum<["manual", "precompact", "imported"]>>;
|
|
93
|
+
imported_from: z.ZodOptional<z.ZodString>;
|
|
94
|
+
}, "strip", z.ZodTypeAny, {
|
|
95
|
+
content: string;
|
|
96
|
+
created: string;
|
|
97
|
+
source: "local" | "imported" | "archived";
|
|
98
|
+
id: string;
|
|
99
|
+
topics: string[];
|
|
100
|
+
origin?: "imported" | "manual" | "precompact" | undefined;
|
|
101
|
+
imported_from?: string | undefined;
|
|
102
|
+
}, {
|
|
103
|
+
content: string;
|
|
104
|
+
created: string;
|
|
105
|
+
source: "local" | "imported" | "archived";
|
|
106
|
+
id: string;
|
|
107
|
+
topics: string[];
|
|
108
|
+
origin?: "imported" | "manual" | "precompact" | undefined;
|
|
109
|
+
imported_from?: string | undefined;
|
|
110
|
+
}>, "many">;
|
|
111
|
+
conflict: z.ZodOptional<z.ZodBoolean>;
|
|
112
|
+
conflict_summary: z.ZodOptional<z.ZodString>;
|
|
113
|
+
}, "strip", z.ZodTypeAny, {
|
|
114
|
+
entries: {
|
|
115
|
+
content: string;
|
|
116
|
+
created: string;
|
|
117
|
+
source: "local" | "imported" | "archived";
|
|
118
|
+
id: string;
|
|
119
|
+
topics: string[];
|
|
120
|
+
origin?: "imported" | "manual" | "precompact" | undefined;
|
|
121
|
+
imported_from?: string | undefined;
|
|
122
|
+
}[];
|
|
123
|
+
conflict?: boolean | undefined;
|
|
124
|
+
conflict_summary?: string | undefined;
|
|
125
|
+
}, {
|
|
126
|
+
entries: {
|
|
127
|
+
content: string;
|
|
128
|
+
created: string;
|
|
129
|
+
source: "local" | "imported" | "archived";
|
|
130
|
+
id: string;
|
|
131
|
+
topics: string[];
|
|
132
|
+
origin?: "imported" | "manual" | "precompact" | undefined;
|
|
133
|
+
imported_from?: string | undefined;
|
|
134
|
+
}[];
|
|
135
|
+
conflict?: boolean | undefined;
|
|
136
|
+
conflict_summary?: string | undefined;
|
|
137
|
+
}>;
|
|
138
|
+
export type BriefResult = z.infer<typeof BriefResultSchema>;
|
|
139
|
+
export declare const ImportedLibrarySchema: z.ZodObject<{
|
|
140
|
+
name: z.ZodString;
|
|
141
|
+
entry_count: z.ZodNumber;
|
|
142
|
+
purchased_at: z.ZodString;
|
|
143
|
+
sync_preference: z.ZodOptional<z.ZodEnum<["auto", "manual", "pinned"]>>;
|
|
144
|
+
last_synced: z.ZodOptional<z.ZodString>;
|
|
145
|
+
}, "strip", z.ZodTypeAny, {
|
|
146
|
+
name: string;
|
|
147
|
+
entry_count: number;
|
|
148
|
+
purchased_at: string;
|
|
149
|
+
last_synced?: string | undefined;
|
|
150
|
+
sync_preference?: "pinned" | "manual" | "auto" | undefined;
|
|
151
|
+
}, {
|
|
152
|
+
name: string;
|
|
153
|
+
entry_count: number;
|
|
154
|
+
purchased_at: string;
|
|
155
|
+
last_synced?: string | undefined;
|
|
156
|
+
sync_preference?: "pinned" | "manual" | "auto" | undefined;
|
|
157
|
+
}>;
|
|
158
|
+
export type ImportedLibrary = z.infer<typeof ImportedLibrarySchema>;
|
|
159
|
+
export declare const StateResultSchema: z.ZodObject<{
|
|
160
|
+
entries: z.ZodArray<z.ZodObject<{
|
|
161
|
+
id: z.ZodString;
|
|
162
|
+
topics: z.ZodArray<z.ZodString, "many">;
|
|
163
|
+
content: z.ZodString;
|
|
164
|
+
created: z.ZodString;
|
|
165
|
+
source: z.ZodEnum<["local", "imported", "archived"]>;
|
|
166
|
+
origin: z.ZodOptional<z.ZodEnum<["manual", "precompact", "imported"]>>;
|
|
167
|
+
imported_from: z.ZodOptional<z.ZodString>;
|
|
168
|
+
}, "strip", z.ZodTypeAny, {
|
|
169
|
+
content: string;
|
|
170
|
+
created: string;
|
|
171
|
+
source: "local" | "imported" | "archived";
|
|
172
|
+
id: string;
|
|
173
|
+
topics: string[];
|
|
174
|
+
origin?: "imported" | "manual" | "precompact" | undefined;
|
|
175
|
+
imported_from?: string | undefined;
|
|
176
|
+
}, {
|
|
177
|
+
content: string;
|
|
178
|
+
created: string;
|
|
179
|
+
source: "local" | "imported" | "archived";
|
|
180
|
+
id: string;
|
|
181
|
+
topics: string[];
|
|
182
|
+
origin?: "imported" | "manual" | "precompact" | undefined;
|
|
183
|
+
imported_from?: string | undefined;
|
|
184
|
+
}>, "many">;
|
|
185
|
+
imported_libraries: z.ZodArray<z.ZodObject<{
|
|
186
|
+
name: z.ZodString;
|
|
187
|
+
entry_count: z.ZodNumber;
|
|
188
|
+
purchased_at: z.ZodString;
|
|
189
|
+
sync_preference: z.ZodOptional<z.ZodEnum<["auto", "manual", "pinned"]>>;
|
|
190
|
+
last_synced: z.ZodOptional<z.ZodString>;
|
|
191
|
+
}, "strip", z.ZodTypeAny, {
|
|
192
|
+
name: string;
|
|
193
|
+
entry_count: number;
|
|
194
|
+
purchased_at: string;
|
|
195
|
+
last_synced?: string | undefined;
|
|
196
|
+
sync_preference?: "pinned" | "manual" | "auto" | undefined;
|
|
197
|
+
}, {
|
|
198
|
+
name: string;
|
|
199
|
+
entry_count: number;
|
|
200
|
+
purchased_at: string;
|
|
201
|
+
last_synced?: string | undefined;
|
|
202
|
+
sync_preference?: "pinned" | "manual" | "auto" | undefined;
|
|
203
|
+
}>, "many">;
|
|
204
|
+
}, "strip", z.ZodTypeAny, {
|
|
205
|
+
entries: {
|
|
206
|
+
content: string;
|
|
207
|
+
created: string;
|
|
208
|
+
source: "local" | "imported" | "archived";
|
|
209
|
+
id: string;
|
|
210
|
+
topics: string[];
|
|
211
|
+
origin?: "imported" | "manual" | "precompact" | undefined;
|
|
212
|
+
imported_from?: string | undefined;
|
|
213
|
+
}[];
|
|
214
|
+
imported_libraries: {
|
|
215
|
+
name: string;
|
|
216
|
+
entry_count: number;
|
|
217
|
+
purchased_at: string;
|
|
218
|
+
last_synced?: string | undefined;
|
|
219
|
+
sync_preference?: "pinned" | "manual" | "auto" | undefined;
|
|
220
|
+
}[];
|
|
221
|
+
}, {
|
|
222
|
+
entries: {
|
|
223
|
+
content: string;
|
|
224
|
+
created: string;
|
|
225
|
+
source: "local" | "imported" | "archived";
|
|
226
|
+
id: string;
|
|
227
|
+
topics: string[];
|
|
228
|
+
origin?: "imported" | "manual" | "precompact" | undefined;
|
|
229
|
+
imported_from?: string | undefined;
|
|
230
|
+
}[];
|
|
231
|
+
imported_libraries: {
|
|
232
|
+
name: string;
|
|
233
|
+
entry_count: number;
|
|
234
|
+
purchased_at: string;
|
|
235
|
+
last_synced?: string | undefined;
|
|
236
|
+
sync_preference?: "pinned" | "manual" | "auto" | undefined;
|
|
237
|
+
}[];
|
|
238
|
+
}>;
|
|
239
|
+
export type StateResult = z.infer<typeof StateResultSchema>;
|
|
240
|
+
export declare const RecordResultSchema: z.ZodObject<{
|
|
241
|
+
entry: z.ZodObject<{
|
|
242
|
+
id: z.ZodString;
|
|
243
|
+
topics: z.ZodArray<z.ZodString, "many">;
|
|
244
|
+
content: z.ZodString;
|
|
245
|
+
created: z.ZodString;
|
|
246
|
+
source: z.ZodEnum<["local", "imported", "archived"]>;
|
|
247
|
+
origin: z.ZodOptional<z.ZodEnum<["manual", "precompact", "imported"]>>;
|
|
248
|
+
imported_from: z.ZodOptional<z.ZodString>;
|
|
249
|
+
}, "strip", z.ZodTypeAny, {
|
|
250
|
+
content: string;
|
|
251
|
+
created: string;
|
|
252
|
+
source: "local" | "imported" | "archived";
|
|
253
|
+
id: string;
|
|
254
|
+
topics: string[];
|
|
255
|
+
origin?: "imported" | "manual" | "precompact" | undefined;
|
|
256
|
+
imported_from?: string | undefined;
|
|
257
|
+
}, {
|
|
258
|
+
content: string;
|
|
259
|
+
created: string;
|
|
260
|
+
source: "local" | "imported" | "archived";
|
|
261
|
+
id: string;
|
|
262
|
+
topics: string[];
|
|
263
|
+
origin?: "imported" | "manual" | "precompact" | undefined;
|
|
264
|
+
imported_from?: string | undefined;
|
|
265
|
+
}>;
|
|
266
|
+
path: z.ZodString;
|
|
267
|
+
}, "strip", z.ZodTypeAny, {
|
|
268
|
+
path: string;
|
|
269
|
+
entry: {
|
|
270
|
+
content: string;
|
|
271
|
+
created: string;
|
|
272
|
+
source: "local" | "imported" | "archived";
|
|
273
|
+
id: string;
|
|
274
|
+
topics: string[];
|
|
275
|
+
origin?: "imported" | "manual" | "precompact" | undefined;
|
|
276
|
+
imported_from?: string | undefined;
|
|
277
|
+
};
|
|
278
|
+
}, {
|
|
279
|
+
path: string;
|
|
280
|
+
entry: {
|
|
281
|
+
content: string;
|
|
282
|
+
created: string;
|
|
283
|
+
source: "local" | "imported" | "archived";
|
|
284
|
+
id: string;
|
|
285
|
+
topics: string[];
|
|
286
|
+
origin?: "imported" | "manual" | "precompact" | undefined;
|
|
287
|
+
imported_from?: string | undefined;
|
|
288
|
+
};
|
|
289
|
+
}>;
|
|
290
|
+
export type RecordResult = z.infer<typeof RecordResultSchema>;
|
|
291
|
+
export declare const ExtractedEntrySchema: z.ZodObject<{
|
|
292
|
+
topics: z.ZodArray<z.ZodString, "many">;
|
|
293
|
+
content: z.ZodString;
|
|
294
|
+
}, "strip", z.ZodTypeAny, {
|
|
295
|
+
content: string;
|
|
296
|
+
topics: string[];
|
|
297
|
+
}, {
|
|
298
|
+
content: string;
|
|
299
|
+
topics: string[];
|
|
300
|
+
}>;
|
|
301
|
+
export type ExtractedEntry = z.infer<typeof ExtractedEntrySchema>;
|
|
302
|
+
export declare const ExtractionResultSchema: z.ZodObject<{
|
|
303
|
+
entries: z.ZodArray<z.ZodObject<{
|
|
304
|
+
topics: z.ZodArray<z.ZodString, "many">;
|
|
305
|
+
content: z.ZodString;
|
|
306
|
+
}, "strip", z.ZodTypeAny, {
|
|
307
|
+
content: string;
|
|
308
|
+
topics: string[];
|
|
309
|
+
}, {
|
|
310
|
+
content: string;
|
|
311
|
+
topics: string[];
|
|
312
|
+
}>, "many">;
|
|
313
|
+
}, "strip", z.ZodTypeAny, {
|
|
314
|
+
entries: {
|
|
315
|
+
content: string;
|
|
316
|
+
topics: string[];
|
|
317
|
+
}[];
|
|
318
|
+
}, {
|
|
319
|
+
entries: {
|
|
320
|
+
content: string;
|
|
321
|
+
topics: string[];
|
|
322
|
+
}[];
|
|
323
|
+
}>;
|
|
324
|
+
export type ExtractionResult = z.infer<typeof ExtractionResultSchema>;
|