visus-mcp 0.3.0 → 0.6.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/.claude/settings.local.json +22 -0
- package/LINKEDIN-STRATEGY.md +367 -0
- package/README.md +491 -16
- package/ROADMAP.md +167 -30
- package/SECURITY-AUDIT-v1.md +277 -0
- package/STATUS.md +801 -42
- package/TROUBLESHOOT-AUTH-20260322-2019.md +291 -0
- package/TROUBLESHOOT-JEST-20260323-1357.md +139 -0
- package/TROUBLESHOOT-LAMBDA-20260322-1945.md +183 -0
- package/VISUS-CLAUDE-CODE-PROMPT.md +1 -1
- package/VISUS-PROJECT-PLAN.md +7 -0
- package/dist/browser/playwright-renderer.d.ts.map +1 -1
- package/dist/browser/playwright-renderer.js +7 -0
- package/dist/browser/playwright-renderer.js.map +1 -1
- package/dist/browser/reader.d.ts +31 -0
- package/dist/browser/reader.d.ts.map +1 -0
- package/dist/browser/reader.js +98 -0
- package/dist/browser/reader.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -5
- package/dist/index.js.map +1 -1
- package/dist/lambda-handler.d.ts +0 -6
- package/dist/lambda-handler.d.ts.map +1 -1
- package/dist/lambda-handler.js +97 -25
- package/dist/lambda-handler.js.map +1 -1
- package/dist/sanitizer/framework-mapper.d.ts +22 -0
- package/dist/sanitizer/framework-mapper.d.ts.map +1 -0
- package/dist/sanitizer/framework-mapper.js +296 -0
- package/dist/sanitizer/framework-mapper.js.map +1 -0
- package/dist/sanitizer/index.d.ts +2 -0
- package/dist/sanitizer/index.d.ts.map +1 -1
- package/dist/sanitizer/index.js +14 -1
- package/dist/sanitizer/index.js.map +1 -1
- package/dist/sanitizer/patterns.js +1 -1
- package/dist/sanitizer/patterns.js.map +1 -1
- package/dist/sanitizer/severity-classifier.d.ts +33 -0
- package/dist/sanitizer/severity-classifier.d.ts.map +1 -0
- package/dist/sanitizer/severity-classifier.js +113 -0
- package/dist/sanitizer/severity-classifier.js.map +1 -0
- package/dist/sanitizer/threat-reporter.d.ts +65 -0
- package/dist/sanitizer/threat-reporter.d.ts.map +1 -0
- package/dist/sanitizer/threat-reporter.js +160 -0
- package/dist/sanitizer/threat-reporter.js.map +1 -0
- package/dist/tools/fetch-structured.d.ts +5 -0
- package/dist/tools/fetch-structured.d.ts.map +1 -1
- package/dist/tools/fetch-structured.js +54 -6
- package/dist/tools/fetch-structured.js.map +1 -1
- package/dist/tools/fetch.d.ts +5 -0
- package/dist/tools/fetch.d.ts.map +1 -1
- package/dist/tools/fetch.js +42 -9
- package/dist/tools/fetch.js.map +1 -1
- package/dist/tools/read.d.ts +51 -0
- package/dist/tools/read.d.ts.map +1 -0
- package/dist/tools/read.js +127 -0
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/search.d.ts +45 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +220 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/types.d.ts +64 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/format-converter.d.ts +39 -0
- package/dist/utils/format-converter.d.ts.map +1 -0
- package/dist/utils/format-converter.js +191 -0
- package/dist/utils/format-converter.js.map +1 -0
- package/dist/utils/truncate.d.ts +26 -0
- package/dist/utils/truncate.d.ts.map +1 -0
- package/dist/utils/truncate.js +54 -0
- package/dist/utils/truncate.js.map +1 -0
- package/infrastructure/stack.ts +55 -6
- package/jest.config.js +3 -0
- package/package.json +9 -2
- package/src/browser/playwright-renderer.ts +8 -0
- package/src/browser/reader.ts +129 -0
- package/src/index.ts +49 -5
- package/src/lambda-handler.ts +131 -26
- package/src/sanitizer/framework-mapper.ts +347 -0
- package/src/sanitizer/index.ts +18 -1
- package/src/sanitizer/patterns.ts +1 -1
- package/src/sanitizer/severity-classifier.ts +132 -0
- package/src/sanitizer/threat-reporter.ts +261 -0
- package/src/tools/fetch-structured.ts +58 -6
- package/src/tools/fetch.ts +44 -9
- package/src/tools/read.ts +143 -0
- package/src/tools/search.ts +263 -0
- package/src/types.ts +69 -0
- package/src/utils/format-converter.ts +236 -0
- package/src/utils/truncate.ts +64 -0
- package/tests/auth-smoke.test.ts +480 -0
- package/tests/fetch-tool.test.ts +595 -2
- package/tests/reader.test.ts +353 -0
- package/tests/sanitizer.test.ts +52 -0
- package/tests/search.test.ts +456 -0
- package/tests/threat-reporter.test.ts +266 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Visus Search Tool - Safe Web Search
|
|
3
|
+
*
|
|
4
|
+
* Queries DuckDuckGo's Instant Answer API and sanitizes all results
|
|
5
|
+
* before returning them to the LLM.
|
|
6
|
+
*
|
|
7
|
+
* SECURITY: Every search result snippet and title passes through the
|
|
8
|
+
* sanitization pipeline. This prevents prompt injection via search results.
|
|
9
|
+
*/
|
|
10
|
+
import type { VisusSearchInput, VisusSearchOutput, Result } from '../types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Search the web via DuckDuckGo and return sanitized results
|
|
13
|
+
*
|
|
14
|
+
* @param input Search query and options
|
|
15
|
+
* @returns Sanitized search results with injection detection metadata
|
|
16
|
+
*/
|
|
17
|
+
export declare function visusSearch(input: VisusSearchInput): Promise<Result<VisusSearchOutput, Error>>;
|
|
18
|
+
/**
|
|
19
|
+
* Tool definition for MCP registration
|
|
20
|
+
*/
|
|
21
|
+
export declare const visusSearchToolDefinition: {
|
|
22
|
+
name: string;
|
|
23
|
+
title: string;
|
|
24
|
+
description: string;
|
|
25
|
+
inputSchema: {
|
|
26
|
+
type: string;
|
|
27
|
+
properties: {
|
|
28
|
+
query: {
|
|
29
|
+
type: string;
|
|
30
|
+
description: string;
|
|
31
|
+
};
|
|
32
|
+
max_results: {
|
|
33
|
+
type: string;
|
|
34
|
+
description: string;
|
|
35
|
+
default: number;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
required: string[];
|
|
39
|
+
};
|
|
40
|
+
readOnlyHint: boolean;
|
|
41
|
+
destructiveHint: boolean;
|
|
42
|
+
idempotentHint: boolean;
|
|
43
|
+
openWorldHint: boolean;
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAiB/E;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC,CAkLpG;AAuBD;;GAEG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;CAuBrC,CAAC"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Visus Search Tool - Safe Web Search
|
|
3
|
+
*
|
|
4
|
+
* Queries DuckDuckGo's Instant Answer API and sanitizes all results
|
|
5
|
+
* before returning them to the LLM.
|
|
6
|
+
*
|
|
7
|
+
* SECURITY: Every search result snippet and title passes through the
|
|
8
|
+
* sanitization pipeline. This prevents prompt injection via search results.
|
|
9
|
+
*/
|
|
10
|
+
import { sanitize } from '../sanitizer/index.js';
|
|
11
|
+
import { generateThreatReport } from '../sanitizer/threat-reporter.js';
|
|
12
|
+
import { Ok, Err } from '../types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Search the web via DuckDuckGo and return sanitized results
|
|
15
|
+
*
|
|
16
|
+
* @param input Search query and options
|
|
17
|
+
* @returns Sanitized search results with injection detection metadata
|
|
18
|
+
*/
|
|
19
|
+
export async function visusSearch(input) {
|
|
20
|
+
// Validate input
|
|
21
|
+
if (!input.query || typeof input.query !== 'string' || input.query.trim().length === 0) {
|
|
22
|
+
return Err(new Error('query must be a non-empty string'));
|
|
23
|
+
}
|
|
24
|
+
// Enforce max_results cap
|
|
25
|
+
const maxResults = Math.min(input.max_results ?? 5, 10);
|
|
26
|
+
try {
|
|
27
|
+
// Call DuckDuckGo Instant Answer API
|
|
28
|
+
const query = encodeURIComponent(input.query.trim());
|
|
29
|
+
const apiUrl = `https://api.duckduckgo.com/?q=${query}&format=json&no_redirect=1&no_html=1`;
|
|
30
|
+
const controller = new AbortController();
|
|
31
|
+
const timeout = setTimeout(() => controller.abort(), 8000);
|
|
32
|
+
let response;
|
|
33
|
+
try {
|
|
34
|
+
response = await fetch(apiUrl, {
|
|
35
|
+
signal: controller.signal,
|
|
36
|
+
headers: {
|
|
37
|
+
'User-Agent': 'visus-mcp/0.3.0 (https://github.com/lateos/visus-mcp)'
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
clearTimeout(timeout);
|
|
43
|
+
}
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
return Ok({
|
|
46
|
+
query: input.query,
|
|
47
|
+
result_count: 0,
|
|
48
|
+
sanitized: true,
|
|
49
|
+
results: [],
|
|
50
|
+
total_injections_removed: 0,
|
|
51
|
+
message: `Search unavailable (HTTP ${response.status})`
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const data = await response.json();
|
|
55
|
+
// Extract results from DuckDuckGo response
|
|
56
|
+
const rawResults = [];
|
|
57
|
+
// Add AbstractText as first result if present
|
|
58
|
+
if (data.AbstractText && data.AbstractURL) {
|
|
59
|
+
rawResults.push({
|
|
60
|
+
title: extractTitle(data.AbstractText),
|
|
61
|
+
url: data.AbstractURL,
|
|
62
|
+
snippet: data.AbstractText
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
// Extract from RelatedTopics
|
|
66
|
+
if (data.RelatedTopics) {
|
|
67
|
+
for (const topic of data.RelatedTopics) {
|
|
68
|
+
// Handle both direct topics and nested topic groups
|
|
69
|
+
if ('Topics' in topic && Array.isArray(topic.Topics)) {
|
|
70
|
+
// Nested topics group
|
|
71
|
+
for (const nestedTopic of topic.Topics) {
|
|
72
|
+
if (nestedTopic.Text && nestedTopic.FirstURL) {
|
|
73
|
+
rawResults.push({
|
|
74
|
+
title: extractTitle(nestedTopic.Text),
|
|
75
|
+
url: nestedTopic.FirstURL,
|
|
76
|
+
snippet: nestedTopic.Text
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else if ('Text' in topic && topic.Text && topic.FirstURL) {
|
|
82
|
+
// Direct topic
|
|
83
|
+
rawResults.push({
|
|
84
|
+
title: extractTitle(topic.Text),
|
|
85
|
+
url: topic.FirstURL,
|
|
86
|
+
snippet: topic.Text
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
// Stop if we've collected enough results
|
|
90
|
+
if (rawResults.length >= maxResults) {
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Filter out results with empty URLs and limit to max_results
|
|
96
|
+
const validResults = rawResults
|
|
97
|
+
.filter(r => r.url && r.url.trim().length > 0)
|
|
98
|
+
.slice(0, maxResults);
|
|
99
|
+
// If no results found, return empty array with message
|
|
100
|
+
if (validResults.length === 0) {
|
|
101
|
+
return Ok({
|
|
102
|
+
query: input.query,
|
|
103
|
+
result_count: 0,
|
|
104
|
+
sanitized: true,
|
|
105
|
+
results: [],
|
|
106
|
+
total_injections_removed: 0,
|
|
107
|
+
message: 'No results found'
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
// Sanitize each result independently
|
|
111
|
+
const sanitizedResults = [];
|
|
112
|
+
const allPatternsDetected = new Set();
|
|
113
|
+
let totalInjectionsRemoved = 0;
|
|
114
|
+
let totalPIIRedacted = 0;
|
|
115
|
+
for (const result of validResults) {
|
|
116
|
+
// Sanitize title
|
|
117
|
+
const titleSanitization = sanitize(result.title);
|
|
118
|
+
// Sanitize snippet
|
|
119
|
+
const snippetSanitization = sanitize(result.snippet);
|
|
120
|
+
const injectionsRemoved = titleSanitization.sanitization.patterns_detected.length +
|
|
121
|
+
snippetSanitization.sanitization.patterns_detected.length;
|
|
122
|
+
const piiRedacted = titleSanitization.sanitization.pii_types_redacted.length +
|
|
123
|
+
snippetSanitization.sanitization.pii_types_redacted.length;
|
|
124
|
+
totalInjectionsRemoved += injectionsRemoved;
|
|
125
|
+
totalPIIRedacted += piiRedacted;
|
|
126
|
+
// Collect all patterns detected across all results
|
|
127
|
+
titleSanitization.sanitization.patterns_detected.forEach(p => allPatternsDetected.add(p));
|
|
128
|
+
snippetSanitization.sanitization.patterns_detected.forEach(p => allPatternsDetected.add(p));
|
|
129
|
+
sanitizedResults.push({
|
|
130
|
+
title: titleSanitization.content,
|
|
131
|
+
url: result.url,
|
|
132
|
+
snippet: snippetSanitization.content,
|
|
133
|
+
injections_removed: injectionsRemoved,
|
|
134
|
+
pii_redacted: piiRedacted
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
// Generate aggregated threat report for all search results
|
|
138
|
+
const threatReport = generateThreatReport({
|
|
139
|
+
patterns_detected: Array.from(allPatternsDetected),
|
|
140
|
+
pii_redacted: totalPIIRedacted,
|
|
141
|
+
source_url: `DuckDuckGo Search: ${input.query}`
|
|
142
|
+
});
|
|
143
|
+
return Ok({
|
|
144
|
+
query: input.query,
|
|
145
|
+
result_count: sanitizedResults.length,
|
|
146
|
+
sanitized: true,
|
|
147
|
+
results: sanitizedResults,
|
|
148
|
+
total_injections_removed: totalInjectionsRemoved,
|
|
149
|
+
// Include threat_report only if findings exist
|
|
150
|
+
...(threatReport && { threat_report: threatReport })
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
// Handle timeout or network errors
|
|
155
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
156
|
+
return Ok({
|
|
157
|
+
query: input.query,
|
|
158
|
+
result_count: 0,
|
|
159
|
+
sanitized: true,
|
|
160
|
+
results: [],
|
|
161
|
+
total_injections_removed: 0,
|
|
162
|
+
message: 'Search unavailable (timeout)'
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
return Ok({
|
|
166
|
+
query: input.query,
|
|
167
|
+
result_count: 0,
|
|
168
|
+
sanitized: true,
|
|
169
|
+
results: [],
|
|
170
|
+
total_injections_removed: 0,
|
|
171
|
+
message: `Search unavailable: ${error instanceof Error ? error.message : String(error)}`
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Extract title from text (first sentence or up to 80 chars)
|
|
177
|
+
*/
|
|
178
|
+
function extractTitle(text) {
|
|
179
|
+
// Try to find first sentence
|
|
180
|
+
const firstSentenceMatch = text.match(/^[^.!?]+[.!?]/);
|
|
181
|
+
if (firstSentenceMatch) {
|
|
182
|
+
const sentence = firstSentenceMatch[0].trim();
|
|
183
|
+
if (sentence.length <= 80) {
|
|
184
|
+
return sentence;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
// Fallback to first 80 chars
|
|
188
|
+
if (text.length <= 80) {
|
|
189
|
+
return text.trim();
|
|
190
|
+
}
|
|
191
|
+
return text.substring(0, 77).trim() + '...';
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Tool definition for MCP registration
|
|
195
|
+
*/
|
|
196
|
+
export const visusSearchToolDefinition = {
|
|
197
|
+
name: 'visus_search',
|
|
198
|
+
title: 'Search the Web (Sanitized)',
|
|
199
|
+
description: 'Searches the web via DuckDuckGo and returns sanitized results with prompt injection and PII removed before reaching the LLM. Use before visus_fetch or visus_read to safely discover and then read pages.',
|
|
200
|
+
inputSchema: {
|
|
201
|
+
type: 'object',
|
|
202
|
+
properties: {
|
|
203
|
+
query: {
|
|
204
|
+
type: 'string',
|
|
205
|
+
description: 'Search query'
|
|
206
|
+
},
|
|
207
|
+
max_results: {
|
|
208
|
+
type: 'number',
|
|
209
|
+
description: 'Maximum number of results to return (default: 5, max: 10)',
|
|
210
|
+
default: 5
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
required: ['query']
|
|
214
|
+
},
|
|
215
|
+
readOnlyHint: true,
|
|
216
|
+
destructiveHint: false,
|
|
217
|
+
idempotentHint: true,
|
|
218
|
+
openWorldHint: true
|
|
219
|
+
};
|
|
220
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared TypeScript interfaces for Visus MCP tool
|
|
3
3
|
*/
|
|
4
|
+
import type { ThreatReport } from './sanitizer/threat-reporter.js';
|
|
4
5
|
/**
|
|
5
6
|
* Input options for visus_fetch tool
|
|
6
7
|
*/
|
|
@@ -30,7 +31,12 @@ export interface VisusFetchOutput {
|
|
|
30
31
|
fetched_at: string;
|
|
31
32
|
content_length_original: number;
|
|
32
33
|
content_length_sanitized: number;
|
|
34
|
+
format_detected?: 'html' | 'json' | 'xml' | 'rss';
|
|
35
|
+
content_type?: string;
|
|
36
|
+
truncated?: boolean;
|
|
37
|
+
truncated_at_chars?: number;
|
|
33
38
|
};
|
|
39
|
+
threat_report?: ThreatReport;
|
|
34
40
|
}
|
|
35
41
|
/**
|
|
36
42
|
* Input for visus_fetch_structured tool
|
|
@@ -40,6 +46,13 @@ export interface VisusFetchStructuredInput {
|
|
|
40
46
|
schema: Record<string, string>;
|
|
41
47
|
timeout_ms?: number;
|
|
42
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Input for visus_read tool
|
|
51
|
+
*/
|
|
52
|
+
export interface VisusReadInput {
|
|
53
|
+
url: string;
|
|
54
|
+
timeout_ms?: number;
|
|
55
|
+
}
|
|
43
56
|
/**
|
|
44
57
|
* Output from visus_fetch_structured tool
|
|
45
58
|
*/
|
|
@@ -61,7 +74,57 @@ export interface VisusFetchStructuredOutput {
|
|
|
61
74
|
fetched_at: string;
|
|
62
75
|
content_length_original: number;
|
|
63
76
|
content_length_sanitized: number;
|
|
77
|
+
format_detected?: 'html' | 'json' | 'xml' | 'rss';
|
|
78
|
+
content_type?: string;
|
|
79
|
+
truncated?: boolean;
|
|
80
|
+
truncated_at_chars?: number;
|
|
81
|
+
};
|
|
82
|
+
threat_report?: ThreatReport;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Output from visus_read tool
|
|
86
|
+
*/
|
|
87
|
+
export interface VisusReadOutput {
|
|
88
|
+
url: string;
|
|
89
|
+
content: string;
|
|
90
|
+
metadata: {
|
|
91
|
+
title: string;
|
|
92
|
+
author: string | null;
|
|
93
|
+
published: string | null;
|
|
94
|
+
word_count: number;
|
|
95
|
+
reader_mode_available: boolean;
|
|
96
|
+
sanitized: true;
|
|
97
|
+
injections_removed: number;
|
|
98
|
+
pii_redacted: number;
|
|
99
|
+
truncated: boolean;
|
|
100
|
+
fetched_at?: string;
|
|
64
101
|
};
|
|
102
|
+
threat_report?: ThreatReport;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Input for visus_search tool
|
|
106
|
+
*/
|
|
107
|
+
export interface VisusSearchInput {
|
|
108
|
+
query: string;
|
|
109
|
+
max_results?: number;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Output from visus_search tool
|
|
113
|
+
*/
|
|
114
|
+
export interface VisusSearchOutput {
|
|
115
|
+
query: string;
|
|
116
|
+
result_count: number;
|
|
117
|
+
sanitized: true;
|
|
118
|
+
results: Array<{
|
|
119
|
+
title: string;
|
|
120
|
+
url: string;
|
|
121
|
+
snippet: string;
|
|
122
|
+
injections_removed: number;
|
|
123
|
+
pii_redacted: number;
|
|
124
|
+
}>;
|
|
125
|
+
total_injections_removed: number;
|
|
126
|
+
message?: string;
|
|
127
|
+
threat_report?: ThreatReport;
|
|
65
128
|
}
|
|
66
129
|
/**
|
|
67
130
|
* Result from browser rendering
|
|
@@ -70,6 +133,7 @@ export interface BrowserRenderResult {
|
|
|
70
133
|
html: string;
|
|
71
134
|
title: string;
|
|
72
135
|
url: string;
|
|
136
|
+
contentType?: string;
|
|
73
137
|
text?: string;
|
|
74
138
|
error?: string;
|
|
75
139
|
}
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE;QACZ,iBAAiB,EAAE,MAAM,EAAE,CAAC;QAC5B,kBAAkB,EAAE,MAAM,EAAE,CAAC;QAC7B,eAAe,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACxE,gBAAgB,EAAE,OAAO,CAAC;KAC3B,CAAC;IACF,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,uBAAuB,EAAE,MAAM,CAAC;QAChC,wBAAwB,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE;QACZ,iBAAiB,EAAE,MAAM,EAAE,CAAC;QAC5B,kBAAkB,EAAE,MAAM,EAAE,CAAC;QAC7B,eAAe,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACxE,gBAAgB,EAAE,OAAO,CAAC;KAC3B,CAAC;IACF,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,uBAAuB,EAAE,MAAM,CAAC;QAChC,wBAAwB,EAAE,MAAM,CAAC;QACjC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;QAClD,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,aAAa,CAAC,EAAE,YAAY,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IACpC,YAAY,EAAE;QACZ,iBAAiB,EAAE,MAAM,EAAE,CAAC;QAC5B,kBAAkB,EAAE,MAAM,EAAE,CAAC;QAC7B,eAAe,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACxE,gBAAgB,EAAE,OAAO,CAAC;KAC3B,CAAC;IACF,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,uBAAuB,EAAE,MAAM,CAAC;QAChC,wBAAwB,EAAE,MAAM,CAAC;QACjC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;QAClD,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,aAAa,CAAC,EAAE,YAAY,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,UAAU,EAAE,MAAM,CAAC;QACnB,qBAAqB,EAAE,OAAO,CAAC;QAC/B,SAAS,EAAE,IAAI,CAAC;QAChB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,OAAO,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,aAAa,CAAC,EAAE,YAAY,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,EAAE,KAAK,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC,CAAC;IACH,wBAAwB,EAAE,MAAM,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,YAAY,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,IAC3B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GACtB;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC;AAE5B;;GAEG;AACH,wBAAgB,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAEhD;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAEjD"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AA6JH;;GAEG;AACH,MAAM,UAAU,EAAE,CAAI,KAAQ;IAC5B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,GAAG,CAAI,KAAQ;IAC7B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format Converter - Content-Type based format detection and conversion
|
|
3
|
+
*
|
|
4
|
+
* Handles format-appropriate conversion based on detected Content-Type.
|
|
5
|
+
* Supports HTML, JSON, XML, and RSS/Atom feeds.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Detected format type
|
|
9
|
+
*/
|
|
10
|
+
export type FormatType = 'html' | 'json' | 'xml' | 'rss';
|
|
11
|
+
/**
|
|
12
|
+
* Detect format from Content-Type header
|
|
13
|
+
*
|
|
14
|
+
* @param contentType - Content-Type header value (e.g., "application/json", "text/html; charset=utf-8")
|
|
15
|
+
* @returns Detected format type
|
|
16
|
+
*/
|
|
17
|
+
export declare function detectFormat(contentType: string): FormatType;
|
|
18
|
+
/**
|
|
19
|
+
* Convert JSON content to formatted string
|
|
20
|
+
*
|
|
21
|
+
* @param raw - Raw JSON string
|
|
22
|
+
* @returns Formatted JSON string with prefix, or raw string if parse fails
|
|
23
|
+
*/
|
|
24
|
+
export declare function convertJson(raw: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Convert XML content to clean text representation
|
|
27
|
+
*
|
|
28
|
+
* @param raw - Raw XML string
|
|
29
|
+
* @returns Formatted XML representation with prefix, or tag-stripped fallback if parse fails
|
|
30
|
+
*/
|
|
31
|
+
export declare function convertXml(raw: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* Convert RSS/Atom feed content to clean Markdown
|
|
34
|
+
*
|
|
35
|
+
* @param raw - Raw RSS/Atom XML string
|
|
36
|
+
* @returns Formatted Markdown representation, or falls back to convertXml if parse fails
|
|
37
|
+
*/
|
|
38
|
+
export declare function convertRss(raw: string): string;
|
|
39
|
+
//# sourceMappingURL=format-converter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-converter.d.ts","sourceRoot":"","sources":["../../src/utils/format-converter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;AAEzD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,CA4B5D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAU/C;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAoB9C;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAiC9C"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format Converter - Content-Type based format detection and conversion
|
|
3
|
+
*
|
|
4
|
+
* Handles format-appropriate conversion based on detected Content-Type.
|
|
5
|
+
* Supports HTML, JSON, XML, and RSS/Atom feeds.
|
|
6
|
+
*/
|
|
7
|
+
import { XMLParser } from 'fast-xml-parser';
|
|
8
|
+
/**
|
|
9
|
+
* Detect format from Content-Type header
|
|
10
|
+
*
|
|
11
|
+
* @param contentType - Content-Type header value (e.g., "application/json", "text/html; charset=utf-8")
|
|
12
|
+
* @returns Detected format type
|
|
13
|
+
*/
|
|
14
|
+
export function detectFormat(contentType) {
|
|
15
|
+
// Normalize: lowercase and extract MIME type (before semicolon)
|
|
16
|
+
const mimeType = contentType.toLowerCase().split(';')[0].trim();
|
|
17
|
+
// HTML formats
|
|
18
|
+
if (mimeType === 'text/html' || mimeType === 'application/xhtml+xml') {
|
|
19
|
+
return 'html';
|
|
20
|
+
}
|
|
21
|
+
// JSON formats
|
|
22
|
+
if (mimeType === 'application/json' || mimeType === 'text/json') {
|
|
23
|
+
return 'json';
|
|
24
|
+
}
|
|
25
|
+
// RSS/Atom feed formats
|
|
26
|
+
if (mimeType === 'application/rss+xml' ||
|
|
27
|
+
mimeType === 'application/atom+xml' ||
|
|
28
|
+
mimeType === 'application/feed+json') {
|
|
29
|
+
return 'rss';
|
|
30
|
+
}
|
|
31
|
+
// XML formats (must come after RSS check)
|
|
32
|
+
if (mimeType === 'application/xml' || mimeType === 'text/xml') {
|
|
33
|
+
return 'xml';
|
|
34
|
+
}
|
|
35
|
+
// Default to HTML for unknown types
|
|
36
|
+
return 'html';
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Convert JSON content to formatted string
|
|
40
|
+
*
|
|
41
|
+
* @param raw - Raw JSON string
|
|
42
|
+
* @returns Formatted JSON string with prefix, or raw string if parse fails
|
|
43
|
+
*/
|
|
44
|
+
export function convertJson(raw) {
|
|
45
|
+
try {
|
|
46
|
+
// Parse and re-stringify with 2-space indent for readability
|
|
47
|
+
const parsed = JSON.parse(raw);
|
|
48
|
+
const formatted = JSON.stringify(parsed, null, 2);
|
|
49
|
+
return `JSON Response:\n\n${formatted}`;
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
// Parse failed, return raw string unchanged
|
|
53
|
+
return raw;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Convert XML content to clean text representation
|
|
58
|
+
*
|
|
59
|
+
* @param raw - Raw XML string
|
|
60
|
+
* @returns Formatted XML representation with prefix, or tag-stripped fallback if parse fails
|
|
61
|
+
*/
|
|
62
|
+
export function convertXml(raw) {
|
|
63
|
+
try {
|
|
64
|
+
const parser = new XMLParser({
|
|
65
|
+
ignoreAttributes: false,
|
|
66
|
+
attributeNamePrefix: '@_',
|
|
67
|
+
textNodeName: '#text',
|
|
68
|
+
ignoreDeclaration: true,
|
|
69
|
+
ignorePiTags: true,
|
|
70
|
+
removeNSPrefix: true,
|
|
71
|
+
});
|
|
72
|
+
const parsed = parser.parse(raw);
|
|
73
|
+
const formatted = JSON.stringify(parsed, null, 2);
|
|
74
|
+
return `XML Response:\n\n${formatted}`;
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
// Parse failed, strip XML tags using regex and return
|
|
78
|
+
const stripped = raw.replace(/<[^>]+>/g, '').trim();
|
|
79
|
+
return `XML Response:\n\n${stripped}`;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Convert RSS/Atom feed content to clean Markdown
|
|
84
|
+
*
|
|
85
|
+
* @param raw - Raw RSS/Atom XML string
|
|
86
|
+
* @returns Formatted Markdown representation, or falls back to convertXml if parse fails
|
|
87
|
+
*/
|
|
88
|
+
export function convertRss(raw) {
|
|
89
|
+
try {
|
|
90
|
+
const parser = new XMLParser({
|
|
91
|
+
ignoreAttributes: false,
|
|
92
|
+
attributeNamePrefix: '@_',
|
|
93
|
+
textNodeName: '#text',
|
|
94
|
+
removeNSPrefix: true,
|
|
95
|
+
});
|
|
96
|
+
const parsed = parser.parse(raw);
|
|
97
|
+
// Handle RSS 2.0 format
|
|
98
|
+
if (parsed.rss && parsed.rss.channel) {
|
|
99
|
+
return formatRss2(parsed.rss.channel);
|
|
100
|
+
}
|
|
101
|
+
// Handle Atom format
|
|
102
|
+
if (parsed.feed) {
|
|
103
|
+
return formatAtom(parsed.feed);
|
|
104
|
+
}
|
|
105
|
+
// Handle RSS 1.0 (RDF) format
|
|
106
|
+
if (parsed.rdf && parsed.rdf.channel) {
|
|
107
|
+
return formatRss2(parsed.rdf.channel);
|
|
108
|
+
}
|
|
109
|
+
// Unknown feed format, fall back to XML
|
|
110
|
+
return convertXml(raw);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
// Parse failed, fall back to XML converter
|
|
114
|
+
return convertXml(raw);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Format RSS 2.0 feed data as Markdown
|
|
119
|
+
*/
|
|
120
|
+
function formatRss2(channel) {
|
|
121
|
+
const title = channel.title || 'Untitled Feed';
|
|
122
|
+
const description = channel.description || '';
|
|
123
|
+
const items = Array.isArray(channel.item) ? channel.item : (channel.item ? [channel.item] : []);
|
|
124
|
+
let markdown = `RSS Feed:\n\n# ${title}\n`;
|
|
125
|
+
if (description) {
|
|
126
|
+
markdown += `${description}\n`;
|
|
127
|
+
}
|
|
128
|
+
markdown += '\n## Items\n\n';
|
|
129
|
+
// Extract up to 10 items
|
|
130
|
+
const itemsToShow = items.slice(0, 10);
|
|
131
|
+
for (const item of itemsToShow) {
|
|
132
|
+
const itemTitle = item.title || 'Untitled';
|
|
133
|
+
const itemLink = item.link || '';
|
|
134
|
+
const itemDescription = item.description || '';
|
|
135
|
+
const itemPubDate = item.pubDate || '';
|
|
136
|
+
// Truncate description to 200 chars
|
|
137
|
+
const truncatedDesc = itemDescription.length > 200
|
|
138
|
+
? itemDescription.substring(0, 200) + '...'
|
|
139
|
+
: itemDescription;
|
|
140
|
+
markdown += `### ${itemTitle}\n\n`;
|
|
141
|
+
if (truncatedDesc) {
|
|
142
|
+
markdown += `${truncatedDesc}\n\n`;
|
|
143
|
+
}
|
|
144
|
+
if (itemLink) {
|
|
145
|
+
markdown += `Link: ${itemLink}\n`;
|
|
146
|
+
}
|
|
147
|
+
if (itemPubDate) {
|
|
148
|
+
markdown += `Published: ${itemPubDate}\n`;
|
|
149
|
+
}
|
|
150
|
+
markdown += '\n---\n\n';
|
|
151
|
+
}
|
|
152
|
+
return markdown;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Format Atom feed data as Markdown
|
|
156
|
+
*/
|
|
157
|
+
function formatAtom(feed) {
|
|
158
|
+
const title = feed.title || 'Untitled Feed';
|
|
159
|
+
const subtitle = feed.subtitle || '';
|
|
160
|
+
const entries = Array.isArray(feed.entry) ? feed.entry : (feed.entry ? [feed.entry] : []);
|
|
161
|
+
let markdown = `RSS Feed:\n\n# ${title}\n`;
|
|
162
|
+
if (subtitle) {
|
|
163
|
+
markdown += `${subtitle}\n`;
|
|
164
|
+
}
|
|
165
|
+
markdown += '\n## Items\n\n';
|
|
166
|
+
// Extract up to 10 entries
|
|
167
|
+
const entriesToShow = entries.slice(0, 10);
|
|
168
|
+
for (const entry of entriesToShow) {
|
|
169
|
+
const entryTitle = entry.title || 'Untitled';
|
|
170
|
+
const entryLink = entry.link ? (entry.link['@_href'] || entry.link) : '';
|
|
171
|
+
const entrySummary = entry.summary || entry.content || '';
|
|
172
|
+
const entryPublished = entry.published || entry.updated || '';
|
|
173
|
+
// Truncate summary to 200 chars
|
|
174
|
+
const truncatedSummary = entrySummary.length > 200
|
|
175
|
+
? entrySummary.substring(0, 200) + '...'
|
|
176
|
+
: entrySummary;
|
|
177
|
+
markdown += `### ${entryTitle}\n\n`;
|
|
178
|
+
if (truncatedSummary) {
|
|
179
|
+
markdown += `${truncatedSummary}\n\n`;
|
|
180
|
+
}
|
|
181
|
+
if (entryLink) {
|
|
182
|
+
markdown += `Link: ${entryLink}\n`;
|
|
183
|
+
}
|
|
184
|
+
if (entryPublished) {
|
|
185
|
+
markdown += `Published: ${entryPublished}\n`;
|
|
186
|
+
}
|
|
187
|
+
markdown += '\n---\n\n';
|
|
188
|
+
}
|
|
189
|
+
return markdown;
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=format-converter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-converter.js","sourceRoot":"","sources":["../../src/utils/format-converter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token-aware content truncation utility
|
|
3
|
+
*
|
|
4
|
+
* Anthropic MCP Directory enforces a 25,000 token response limit.
|
|
5
|
+
* This utility provides safe truncation with token estimation.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Truncate content if it exceeds the token ceiling
|
|
9
|
+
*
|
|
10
|
+
* @param content Content to potentially truncate
|
|
11
|
+
* @returns Truncated content and metadata
|
|
12
|
+
*/
|
|
13
|
+
export declare function truncateContent(content: string): {
|
|
14
|
+
content: string;
|
|
15
|
+
truncated: boolean;
|
|
16
|
+
truncated_at_chars?: number;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Estimate token count for a given string
|
|
20
|
+
* Uses conservative 4 chars per token approximation
|
|
21
|
+
*
|
|
22
|
+
* @param text Text to estimate
|
|
23
|
+
* @returns Estimated token count
|
|
24
|
+
*/
|
|
25
|
+
export declare function estimateTokens(text: string): number;
|
|
26
|
+
//# sourceMappingURL=truncate.d.ts.map
|