@telvok/librarian-mcp 1.5.4 → 2.3.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 (123) hide show
  1. package/dist/library/errors.d.ts +48 -0
  2. package/dist/library/errors.js +80 -0
  3. package/dist/library/schemas.d.ts +6 -6
  4. package/dist/library/sensitive-scanner.d.ts +20 -0
  5. package/dist/library/sensitive-scanner.js +56 -0
  6. package/dist/library/storage.d.ts +2 -2
  7. package/dist/library/storage.js +2 -2
  8. package/dist/library 2/embeddings.d.ts +21 -0
  9. package/dist/library 2/embeddings.js +86 -0
  10. package/dist/library 2/manager.d.ts +42 -0
  11. package/dist/library 2/manager.js +218 -0
  12. package/dist/library 2/parsers/cursor.d.ts +15 -0
  13. package/dist/library 2/parsers/cursor.js +168 -0
  14. package/dist/library 2/parsers/index.d.ts +6 -0
  15. package/dist/library 2/parsers/index.js +5 -0
  16. package/dist/library 2/parsers/json.d.ts +11 -0
  17. package/dist/library 2/parsers/json.js +95 -0
  18. package/dist/library 2/parsers/jsonl.d.ts +14 -0
  19. package/dist/library 2/parsers/jsonl.js +85 -0
  20. package/dist/library 2/parsers/markdown.d.ts +15 -0
  21. package/dist/library 2/parsers/markdown.js +77 -0
  22. package/dist/library 2/parsers/sqlite.d.ts +8 -0
  23. package/dist/library 2/parsers/sqlite.js +123 -0
  24. package/dist/library 2/parsers/types.d.ts +21 -0
  25. package/dist/library 2/parsers/types.js +4 -0
  26. package/dist/library 2/query.d.ts +26 -0
  27. package/dist/library 2/query.js +104 -0
  28. package/dist/library 2/schemas.d.ts +324 -0
  29. package/dist/library 2/schemas.js +79 -0
  30. package/dist/library 2/storage.d.ts +22 -0
  31. package/dist/library 2/storage.js +36 -0
  32. package/dist/library 2/vector-index.d.ts +55 -0
  33. package/dist/library 2/vector-index.js +160 -0
  34. package/dist/server 2.js +199 -0
  35. package/dist/server.d 2.ts +2 -0
  36. package/dist/server.js +104 -54
  37. package/dist/tools/adopt.d.ts +1 -0
  38. package/dist/tools/adopt.js +37 -10
  39. package/dist/tools/audit.d.ts +27 -0
  40. package/dist/tools/audit.js +126 -0
  41. package/dist/tools/auth.d.ts +69 -0
  42. package/dist/tools/auth.js +379 -0
  43. package/dist/tools/bounty-claim.d.ts +28 -0
  44. package/dist/tools/bounty-claim.js +92 -0
  45. package/dist/tools/bounty-create.d.ts +47 -0
  46. package/dist/tools/bounty-create.js +118 -0
  47. package/dist/tools/bounty-list.d.ts +50 -0
  48. package/dist/tools/bounty-list.js +116 -0
  49. package/dist/tools/bounty-submit.d.ts +34 -0
  50. package/dist/tools/bounty-submit.js +94 -0
  51. package/dist/tools/brief.d.ts +94 -0
  52. package/dist/tools/brief.js +234 -15
  53. package/dist/tools/delete.d.ts +87 -0
  54. package/dist/tools/delete.js +266 -0
  55. package/dist/tools/feedback.d.ts +27 -0
  56. package/dist/tools/feedback.js +98 -0
  57. package/dist/tools/help.d.ts +22 -0
  58. package/dist/tools/help.js +482 -0
  59. package/dist/tools/import-memories.d.ts +1 -0
  60. package/dist/tools/import-memories.js +18 -13
  61. package/dist/tools/index.d.ts +11 -0
  62. package/dist/tools/index.js +12 -0
  63. package/dist/tools/library-buy.d.ts +31 -0
  64. package/dist/tools/library-buy.js +104 -0
  65. package/dist/tools/library-download.d.ts +27 -0
  66. package/dist/tools/library-download.js +177 -0
  67. package/dist/tools/library-publish.d.ts +117 -0
  68. package/dist/tools/library-publish.js +447 -0
  69. package/dist/tools/library-search.d.ts +110 -0
  70. package/dist/tools/library-search.js +132 -0
  71. package/dist/tools/mark-hit.d.ts +1 -0
  72. package/dist/tools/mark-hit.js +83 -5
  73. package/dist/tools/my-books.d.ts +51 -0
  74. package/dist/tools/my-books.js +115 -0
  75. package/dist/tools/my-bounties.d.ts +43 -0
  76. package/dist/tools/my-bounties.js +126 -0
  77. package/dist/tools/rate-book.d.ts +40 -0
  78. package/dist/tools/rate-book.js +147 -0
  79. package/dist/tools/rebuild-index.d.ts +1 -0
  80. package/dist/tools/rebuild-index.js +40 -8
  81. package/dist/tools/record.d.ts +18 -0
  82. package/dist/tools/record.js +30 -26
  83. package/dist/tools/seller-analytics.d.ts +53 -0
  84. package/dist/tools/seller-analytics.js +180 -0
  85. package/dist/tools/sync.d.ts +55 -0
  86. package/dist/tools/sync.js +304 -0
  87. package/dist/tools/unsubscribe.d.ts +48 -0
  88. package/dist/tools/unsubscribe.js +120 -0
  89. package/dist/tools 2/adopt.d.ts +24 -0
  90. package/dist/tools 2/adopt.js +154 -0
  91. package/dist/tools 2/auth.d.ts +35 -0
  92. package/dist/tools 2/auth.js +229 -0
  93. package/dist/tools 2/brief.d.ts +56 -0
  94. package/dist/tools 2/brief.js +414 -0
  95. package/dist/tools 2/help.d.ts +21 -0
  96. package/dist/tools 2/help.js +267 -0
  97. package/dist/tools 2/import-memories.d.ts +32 -0
  98. package/dist/tools 2/import-memories.js +231 -0
  99. package/dist/tools 2/index.d.ts +12 -0
  100. package/dist/tools 2/index.js +12 -0
  101. package/dist/tools 2/mark-hit.d.ts +20 -0
  102. package/dist/tools 2/mark-hit.js +71 -0
  103. package/dist/tools 2/marketplace-buy.d.ts +30 -0
  104. package/dist/tools 2/marketplace-buy.js +97 -0
  105. package/dist/tools 2/marketplace-download.d.ts +26 -0
  106. package/dist/tools 2/marketplace-download.js +160 -0
  107. package/dist/tools 2/marketplace-publish.d.ts +111 -0
  108. package/dist/tools 2/marketplace-publish.js +377 -0
  109. package/dist/tools 2/marketplace-search.d.ts +57 -0
  110. package/dist/tools 2/marketplace-search.js +96 -0
  111. package/dist/tools 2/my-books.d.ts +50 -0
  112. package/dist/tools 2/my-books.js +107 -0
  113. package/dist/tools 2/rate-book.d.ts +39 -0
  114. package/dist/tools 2/rate-book.js +139 -0
  115. package/dist/tools 2/rebuild-index.d.ts +23 -0
  116. package/dist/tools 2/rebuild-index.js +107 -0
  117. package/dist/tools 2/record.d.ts +40 -0
  118. package/dist/tools 2/record.js +205 -0
  119. package/dist/tools 2/seller-analytics.d.ts +35 -0
  120. package/dist/tools 2/seller-analytics.js +102 -0
  121. package/dist/tools 2/sync.d.ts +54 -0
  122. package/dist/tools 2/sync.js +298 -0
  123. package/package.json +1 -1
@@ -9,16 +9,24 @@ import { saveIndex, addToIndex, getIndexStats } from '../library/vector-index.js
9
9
  // ============================================================================
10
10
  export const rebuildIndexTool = {
11
11
  name: 'rebuild_index',
12
- description: `Rebuild the semantic search index for all library entries.
12
+ title: 'Rebuild Search Index',
13
+ description: `Rebuild the semantic search index.
13
14
 
14
- Use this when semantic search returns poor results, when user reports search seems broken, or after manually adding entries outside the normal workflow.
15
+ USE THIS TOOL WHEN:
16
+ - brief() returns poor or no results when entries exist
17
+ - After import_memories() to index new content
18
+ - User reports search seems broken
19
+ - Manually edited .librarian/ files outside normal workflow
15
20
 
16
- Use this after:
17
- - Upgrading to v1.2.0 (existing entries need embeddings)
18
- - Importing memories from other tools
19
- - If semantic search seems broken
21
+ Reads all .md entries and regenerates embeddings. May take a minute.
20
22
 
21
- Reads all .md entries and generates embeddings. May take a minute on first run.`,
23
+ TRIGGER PATTERNS:
24
+ - brief() returning nothing when it shouldn't → rebuild_index()
25
+ - After bulk import → rebuild_index()
26
+ - "Search seems broken" → rebuild_index()
27
+
28
+ Example:
29
+ - rebuild_index()`,
22
30
  inputSchema: {
23
31
  type: 'object',
24
32
  properties: {},
@@ -39,6 +47,8 @@ Reads all .md entries and generates embeddings. May take a minute on first run.`
39
47
  let indexed = 0;
40
48
  let skipped = 0;
41
49
  const errors = [];
50
+ // Progress file for status checks during rebuild
51
+ const progressFile = path.join(libraryPath, '.rebuild-progress.json');
42
52
  // Collect all .md files from all directories
43
53
  const allDirs = [localPath, importedPath, packagesPath];
44
54
  const allFiles = [];
@@ -51,8 +61,28 @@ Reads all .md entries and generates embeddings. May take a minute on first run.`
51
61
  // Directory doesn't exist, skip
52
62
  }
53
63
  }
64
+ // Write initial progress
65
+ await fs.writeFile(progressFile, JSON.stringify({
66
+ status: 'processing',
67
+ current: 0,
68
+ total: allFiles.length,
69
+ currentFile: '',
70
+ percent: 0,
71
+ startedAt: new Date().toISOString(),
72
+ }), 'utf-8').catch(() => { });
54
73
  // Process each file
55
- for (const filePath of allFiles) {
74
+ for (let i = 0; i < allFiles.length; i++) {
75
+ const filePath = allFiles[i];
76
+ // Update progress file
77
+ await fs.writeFile(progressFile, JSON.stringify({
78
+ status: 'processing',
79
+ current: i + 1,
80
+ total: allFiles.length,
81
+ currentFile: path.basename(filePath),
82
+ percent: Math.round(((i + 1) / allFiles.length) * 100),
83
+ indexed,
84
+ skipped,
85
+ }), 'utf-8').catch(() => { });
56
86
  try {
57
87
  const content = await fs.readFile(filePath, 'utf-8');
58
88
  const { data, content: body } = matter(content);
@@ -91,6 +121,8 @@ Reads all .md entries and generates embeddings. May take a minute on first run.`
91
121
  }
92
122
  // Save the index
93
123
  await saveIndex(index);
124
+ // Cleanup progress file
125
+ await fs.unlink(progressFile).catch(() => { });
94
126
  const stats = getIndexStats(index);
95
127
  const message = indexed > 0
96
128
  ? `Rebuilt index with ${indexed} entries (${stats.chunkCount} chunks). ${skipped} skipped.`
@@ -5,6 +5,7 @@ export interface RecordResult {
5
5
  }
6
6
  export declare const recordTool: {
7
7
  name: string;
8
+ title: string;
8
9
  description: string;
9
10
  inputSchema: {
10
11
  type: "object";
@@ -36,5 +37,22 @@ export declare const recordTool: {
36
37
  };
37
38
  required: string[];
38
39
  };
40
+ outputSchema: {
41
+ type: "object";
42
+ properties: {
43
+ success: {
44
+ type: string;
45
+ };
46
+ path: {
47
+ type: string;
48
+ description: string;
49
+ };
50
+ title: {
51
+ type: string;
52
+ description: string;
53
+ };
54
+ };
55
+ required: string[];
56
+ };
39
57
  handler(args: unknown): Promise<RecordResult>;
40
58
  };
@@ -7,42 +7,37 @@ import { loadIndex, saveIndex, addToIndex } from '../library/vector-index.js';
7
7
  // ============================================================================
8
8
  export const recordTool = {
9
9
  name: 'record',
10
- description: `Use this tool proactively throughout every conversation.
10
+ title: 'Save New Insight',
11
+ description: `CALL THIS IMMEDIATELY when you learn something worth keeping. Do NOT wait to be asked.
11
12
 
12
- CALL THIS IMMEDIATELY when you:
13
- - Solve a problem (before moving to the next thing)
14
- - Make a decision (capture the reasoning NOW)
15
- - Hit a gotcha (it WILL come up again)
16
- - Learn something non-obvious (context dies fast)
13
+ USE THIS TOOL WHEN:
14
+ - You solve a problem (BEFORE moving to the next thing)
15
+ - You make a decision (capture the WHY now, not later)
16
+ - You hit a gotcha or unexpected behavior
17
+ - You learn something non-obvious about this codebase
18
+ - You discover credentials, API keys, or configuration
19
+ - You find out how something actually works vs how you assumed
17
20
 
18
- Do NOT wait for the user to ask. Do NOT batch multiple insights.
19
- One insight = one record() call. Call it the moment you notice it.
21
+ DO NOT BATCH insights. One insight = one record() call.
22
+ DO NOT SKIP because it seems minor. If it cost us 5+ minutes, record it.
20
23
 
21
24
  Quality bar: "I wish we knew this yesterday"
22
25
 
26
+ TRIGGER PATTERNS:
27
+ - Fixed a bug → record({ insight: "The issue was X because Y" })
28
+ - Found credentials → record({ insight: "Auth uses X", context: "credentials" })
29
+ - Made architectural choice → record({ insight: "Chose X over Y", reasoning: "..." })
30
+ - Something didn't work as expected → record({ insight: "X actually does Y, not Z" })
31
+
23
32
  Good entries:
24
33
  - "Stripe retries webhooks but doesn't dedupe - always check idempotency key"
25
- - "Clock skew between services - add 30s buffer to token validation"
26
- - "GitHub org names are squattable even if you own the domain"
34
+ - "Next.js 16 renamed middleware.ts to proxy.ts"
35
+ - "API key format is tvk_ prefix + 32 chars"
27
36
 
28
37
  Not worth recording:
29
38
  - Generic docs (search exists)
30
39
  - Temporary hacks
31
- - Stuff that'll change next week
32
-
33
- Examples:
34
-
35
- Quick:
36
- - record({ insight: "Stripe webhooks need idempotency checks" })
37
-
38
- Rich:
39
- - record({
40
- intent: "Setting up GitHub org for Telvok",
41
- insight: "GitHub org names are first-come-first-served regardless of domain ownership",
42
- context: "GitHub, npm, branding",
43
- reasoning: "We owned telvok.com but someone squatted telvok org years ago",
44
- example: "Had to use telvokdev instead of telvok"
45
- })`,
40
+ - Things that'll change next week`,
46
41
  inputSchema: {
47
42
  type: 'object',
48
43
  properties: {
@@ -73,9 +68,18 @@ Rich:
73
68
  },
74
69
  required: ['insight'],
75
70
  },
71
+ outputSchema: {
72
+ type: 'object',
73
+ properties: {
74
+ success: { type: 'boolean' },
75
+ path: { type: 'string', description: 'Path to the created entry file' },
76
+ title: { type: 'string', description: 'Title of the created entry' },
77
+ },
78
+ required: ['success', 'path', 'title'],
79
+ },
76
80
  async handler(args) {
77
81
  const { insight, intent, reasoning, context, example, title: providedTitle } = args;
78
- if (!insight) {
82
+ if (!insight || !insight.trim()) {
79
83
  throw new Error('insight is required');
80
84
  }
81
85
  const libraryPath = getLibraryPath();
@@ -0,0 +1,53 @@
1
+ interface SellerAnalyticsResult {
2
+ success: boolean;
3
+ message: string;
4
+ overview?: {
5
+ revenue: string;
6
+ downloads: number;
7
+ hits: number;
8
+ avgRating: string;
9
+ libraryCount: number;
10
+ };
11
+ books?: Array<{
12
+ name: string;
13
+ revenue: string;
14
+ downloads: number;
15
+ hits: number;
16
+ rating: string;
17
+ topEntries?: Array<{
18
+ title: string;
19
+ hits: number;
20
+ trend: string;
21
+ }>;
22
+ searchTerms?: Array<{
23
+ term: string;
24
+ count: number;
25
+ }>;
26
+ }>;
27
+ recent_reviews?: Array<{
28
+ book: string;
29
+ rating: string;
30
+ title: string;
31
+ reviewer: string;
32
+ }>;
33
+ insights?: {
34
+ totalSearches: number;
35
+ uniqueSearchTerms: number;
36
+ gapAnalysis?: Array<{
37
+ term: string;
38
+ count: number;
39
+ }>;
40
+ };
41
+ }
42
+ export declare const sellerAnalyticsTool: {
43
+ name: string;
44
+ title: string;
45
+ description: string;
46
+ inputSchema: {
47
+ type: "object";
48
+ properties: {};
49
+ required: never[];
50
+ };
51
+ handler(): Promise<SellerAnalyticsResult>;
52
+ };
53
+ export default sellerAnalyticsTool;
@@ -0,0 +1,180 @@
1
+ // ============================================================================
2
+ // Seller Analytics Tool
3
+ // View your seller analytics - revenue, downloads, hits, ratings
4
+ // ============================================================================
5
+ import { loadApiKey } from './auth.js';
6
+ const TELVOK_API_URL = process.env.TELVOK_API_URL || 'https://telvok.com';
7
+ // ============================================================================
8
+ // Helper Functions
9
+ // ============================================================================
10
+ function formatGhostModeMessage(data) {
11
+ const lines = [];
12
+ lines.push(`Analytics for ${data.overview.libraryCount} book${data.overview.libraryCount === 1 ? '' : 's'}`);
13
+ lines.push('');
14
+ lines.push(`Overview:`);
15
+ lines.push(` Revenue: $${data.overview.revenue.toFixed(2)}`);
16
+ lines.push(` Downloads: ${data.overview.downloads}`);
17
+ lines.push(` Hits: ${data.overview.hits}`);
18
+ if (data.overview.avgRating) {
19
+ lines.push(` Avg Rating: ${data.overview.avgRating}/5`);
20
+ }
21
+ // Per-book breakdown with Ghost Mode data
22
+ if (data.byLibrary.length > 0) {
23
+ lines.push('');
24
+ lines.push('━'.repeat(40));
25
+ for (const book of data.byLibrary) {
26
+ lines.push('');
27
+ lines.push(`📚 ${book.name} - $${book.revenue.toFixed(2)} - ${book.hits} hits`);
28
+ // Top entries
29
+ if (book.topEntries && book.topEntries.length > 0) {
30
+ lines.push('');
31
+ lines.push(' Top Entries:');
32
+ book.topEntries.slice(0, 5).forEach((entry, i) => {
33
+ lines.push(` ${i + 1}. ${entry.title} - ${entry.hits} hits (${entry.trend})`);
34
+ });
35
+ }
36
+ // Search terms
37
+ if (book.searchTerms && book.searchTerms.length > 0) {
38
+ lines.push('');
39
+ lines.push(' Users searched for:');
40
+ book.searchTerms.slice(0, 5).forEach(term => {
41
+ lines.push(` • "${term.term}" (${term.count} queries)`);
42
+ });
43
+ }
44
+ }
45
+ }
46
+ // Gap analysis
47
+ if (data.insights?.zeroResultSearches && data.insights.zeroResultSearches.length > 0) {
48
+ lines.push('');
49
+ lines.push('━'.repeat(40));
50
+ lines.push('');
51
+ lines.push('💡 Gap Analysis (searches with no results):');
52
+ data.insights.zeroResultSearches.slice(0, 5).forEach(z => {
53
+ lines.push(` • "${z.term}" (${z.count} searches)`);
54
+ });
55
+ }
56
+ return lines.join('\n');
57
+ }
58
+ // ============================================================================
59
+ // Tool Definition
60
+ // ============================================================================
61
+ export const sellerAnalyticsTool = {
62
+ name: 'seller_analytics',
63
+ title: 'View Seller Analytics',
64
+ description: `View seller analytics for your published books.
65
+
66
+ USE THIS TOOL WHEN:
67
+ - User asks "how are my books doing" or "show my sales"
68
+ - Checking revenue, downloads, or ratings
69
+ - User wants to see which entries are most useful (Ghost Mode data)
70
+
71
+ Shows revenue, downloads, hits, ratings, top entries, and search terms.
72
+
73
+ TRIGGER PATTERNS:
74
+ - "How are my books selling?" → seller_analytics()
75
+ - "Show my revenue" → seller_analytics()
76
+ - "What are people searching for?" → seller_analytics() (shows search terms)
77
+
78
+ Example:
79
+ - seller_analytics() - View all your analytics`,
80
+ inputSchema: {
81
+ type: 'object',
82
+ properties: {},
83
+ required: [],
84
+ },
85
+ async handler() {
86
+ // Check authentication
87
+ const apiKey = await loadApiKey();
88
+ if (!apiKey) {
89
+ return {
90
+ success: false,
91
+ message: 'Not authenticated. Run auth({ action: "login" }) to connect your Telvok account first.',
92
+ };
93
+ }
94
+ try {
95
+ const response = await fetch(`${TELVOK_API_URL}/api/seller/analytics`, {
96
+ method: 'GET',
97
+ headers: {
98
+ 'Authorization': `Bearer ${apiKey}`,
99
+ },
100
+ });
101
+ const data = await response.json();
102
+ if (!response.ok) {
103
+ return {
104
+ success: false,
105
+ message: data.error || `Failed to fetch analytics: HTTP ${response.status}`,
106
+ };
107
+ }
108
+ // Check if user has any libraries
109
+ if (data.overview.libraryCount === 0) {
110
+ return {
111
+ success: true,
112
+ message: 'You haven\'t published any books yet. Use library_publish() to publish your first book.',
113
+ overview: {
114
+ revenue: '$0.00',
115
+ downloads: 0,
116
+ hits: 0,
117
+ avgRating: 'N/A',
118
+ libraryCount: 0,
119
+ },
120
+ books: [],
121
+ recent_reviews: [],
122
+ };
123
+ }
124
+ // Format for terminal display with Ghost Mode data
125
+ const result = {
126
+ success: true,
127
+ message: formatGhostModeMessage(data),
128
+ overview: {
129
+ revenue: `$${data.overview.revenue.toFixed(2)}`,
130
+ downloads: data.overview.downloads,
131
+ hits: data.overview.hits,
132
+ avgRating: data.overview.avgRating ? `${data.overview.avgRating}/5` : 'No ratings yet',
133
+ libraryCount: data.overview.libraryCount,
134
+ },
135
+ books: data.byLibrary.map(b => ({
136
+ name: b.name,
137
+ revenue: `$${b.revenue.toFixed(2)}`,
138
+ downloads: b.downloads,
139
+ hits: b.hits,
140
+ rating: b.rating ? `${b.rating}/5` : 'No ratings',
141
+ topEntries: b.topEntries?.slice(0, 5).map(e => ({
142
+ title: e.title,
143
+ hits: e.hits,
144
+ trend: e.trend,
145
+ })),
146
+ searchTerms: b.searchTerms?.slice(0, 5).map(t => ({
147
+ term: t.term,
148
+ count: t.count,
149
+ })),
150
+ })),
151
+ recent_reviews: data.recentReviews.slice(0, 5).map(r => ({
152
+ book: r.library.name,
153
+ rating: `${r.rating}/5`,
154
+ title: r.title || '(no title)',
155
+ reviewer: r.reviewer?.name || 'Anonymous',
156
+ })),
157
+ };
158
+ // Add Ghost Mode insights if available
159
+ if (data.insights) {
160
+ result.insights = {
161
+ totalSearches: data.insights.totalSearches,
162
+ uniqueSearchTerms: data.insights.uniqueSearchTerms,
163
+ gapAnalysis: data.insights.zeroResultSearches?.slice(0, 10).map(z => ({
164
+ term: z.term,
165
+ count: z.count,
166
+ })),
167
+ };
168
+ }
169
+ return result;
170
+ }
171
+ catch (error) {
172
+ const message = error instanceof Error ? error.message : String(error);
173
+ throw new Error(`Failed to fetch analytics: ${message}`);
174
+ }
175
+ },
176
+ };
177
+ // ============================================================================
178
+ // Export
179
+ // ============================================================================
180
+ export default sellerAnalyticsTool;
@@ -0,0 +1,55 @@
1
+ interface SyncedBook {
2
+ slug: string;
3
+ name: string;
4
+ new_entries: number;
5
+ modified_entries: number;
6
+ access: 'cloud' | 'downloaded';
7
+ version?: string;
8
+ synced_from?: string;
9
+ }
10
+ interface SyncResult {
11
+ success: boolean;
12
+ message: string;
13
+ synced?: SyncedBook[];
14
+ available?: {
15
+ slug: string;
16
+ name: string;
17
+ new_entries: number;
18
+ }[];
19
+ pinned?: {
20
+ slug: string;
21
+ name: string;
22
+ }[];
23
+ up_to_date?: number;
24
+ }
25
+ export declare const syncTool: {
26
+ name: string;
27
+ title: string;
28
+ description: string;
29
+ inputSchema: {
30
+ type: "object";
31
+ properties: {
32
+ slug: {
33
+ type: string;
34
+ description: string;
35
+ };
36
+ options: {
37
+ type: string;
38
+ properties: {
39
+ force: {
40
+ type: string;
41
+ description: string;
42
+ };
43
+ download: {
44
+ type: string;
45
+ description: string;
46
+ };
47
+ };
48
+ description: string;
49
+ };
50
+ };
51
+ required: never[];
52
+ };
53
+ handler(args: unknown): Promise<SyncResult>;
54
+ };
55
+ export default syncTool;