@get-technology-inc/jamf-docs-mcp-server 0.0.1 → 1.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.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +189 -29
  3. package/dist/constants.d.ts +260 -0
  4. package/dist/constants.d.ts.map +1 -0
  5. package/dist/constants.js +303 -0
  6. package/dist/constants.js.map +1 -0
  7. package/dist/index.d.ts +9 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +36 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/schemas/index.d.ts +98 -0
  12. package/dist/schemas/index.d.ts.map +1 -0
  13. package/dist/schemas/index.js +110 -0
  14. package/dist/schemas/index.js.map +1 -0
  15. package/dist/services/cache.d.ts +56 -0
  16. package/dist/services/cache.d.ts.map +1 -0
  17. package/dist/services/cache.js +189 -0
  18. package/dist/services/cache.js.map +1 -0
  19. package/dist/services/scraper.d.ts +62 -0
  20. package/dist/services/scraper.d.ts.map +1 -0
  21. package/dist/services/scraper.js +568 -0
  22. package/dist/services/scraper.js.map +1 -0
  23. package/dist/services/tokenizer.d.ts +77 -0
  24. package/dist/services/tokenizer.d.ts.map +1 -0
  25. package/dist/services/tokenizer.js +274 -0
  26. package/dist/services/tokenizer.js.map +1 -0
  27. package/dist/tools/get-article.d.ts +7 -0
  28. package/dist/tools/get-article.d.ts.map +1 -0
  29. package/dist/tools/get-article.js +195 -0
  30. package/dist/tools/get-article.js.map +1 -0
  31. package/dist/tools/get-toc.d.ts +7 -0
  32. package/dist/tools/get-toc.d.ts.map +1 -0
  33. package/dist/tools/get-toc.js +172 -0
  34. package/dist/tools/get-toc.js.map +1 -0
  35. package/dist/tools/list-products.d.ts +7 -0
  36. package/dist/tools/list-products.d.ts.map +1 -0
  37. package/dist/tools/list-products.js +132 -0
  38. package/dist/tools/list-products.js.map +1 -0
  39. package/dist/tools/search.d.ts +7 -0
  40. package/dist/tools/search.d.ts.map +1 -0
  41. package/dist/tools/search.js +212 -0
  42. package/dist/tools/search.js.map +1 -0
  43. package/dist/types.d.ts +197 -0
  44. package/dist/types.d.ts.map +1 -0
  45. package/dist/types.js +28 -0
  46. package/dist/types.js.map +1 -0
  47. package/package.json +68 -6
@@ -0,0 +1,568 @@
1
+ /**
2
+ * Web scraping service for Jamf documentation
3
+ *
4
+ * This module handles fetching and parsing HTML from learn.jamf.com
5
+ * (Jamf documentation has moved from docs.jamf.com to learn.jamf.com)
6
+ */
7
+ import axios from 'axios';
8
+ import * as cheerio from 'cheerio';
9
+ import TurndownService from 'turndown';
10
+ import { DOCS_BASE_URL, DOCS_API_URL, JAMF_PRODUCTS, JAMF_TOPICS, REQUEST_CONFIG, SELECTORS, CONTENT_LIMITS, TOKEN_CONFIG, PAGINATION_CONFIG } from '../constants.js';
11
+ import { JamfDocsError, JamfDocsErrorCode } from '../types.js';
12
+ import { cache } from './cache.js';
13
+ import { estimateTokens, createTokenInfo, extractSections, extractSection, truncateToTokenLimit, calculatePagination } from './tokenizer.js';
14
+ // Initialize Turndown for HTML to Markdown conversion
15
+ const turndown = new TurndownService({
16
+ headingStyle: 'atx',
17
+ codeBlockStyle: 'fenced',
18
+ bulletListMarker: '-',
19
+ emDelimiter: '*',
20
+ strongDelimiter: '**'
21
+ });
22
+ // Custom Turndown rules
23
+ turndown.addRule('codeBlocks', {
24
+ filter: 'pre',
25
+ replacement: (content, node) => {
26
+ // Handle code element extraction safely
27
+ const nodeElement = node;
28
+ const codeElement = nodeElement.querySelector?.('code');
29
+ const language = codeElement?.className?.replace('language-', '') || '';
30
+ return `\n\`\`\`${language}\n${content.trim()}\n\`\`\`\n`;
31
+ }
32
+ });
33
+ // Rate limiter
34
+ let lastRequestTime = 0;
35
+ async function throttle() {
36
+ const now = Date.now();
37
+ const elapsed = now - lastRequestTime;
38
+ if (elapsed < REQUEST_CONFIG.RATE_LIMIT_DELAY) {
39
+ await new Promise(resolve => setTimeout(resolve, REQUEST_CONFIG.RATE_LIMIT_DELAY - elapsed));
40
+ }
41
+ lastRequestTime = Date.now();
42
+ }
43
+ /**
44
+ * Transform frontend URL to backend URL for content fetching
45
+ * learn.jamf.com -> learn-be.jamf.com
46
+ */
47
+ function transformToBackendUrl(url) {
48
+ return url.replace('learn.jamf.com', 'learn-be.jamf.com');
49
+ }
50
+ /**
51
+ * Transform backend URL to frontend URL for display
52
+ * learn-be.jamf.com -> learn.jamf.com
53
+ */
54
+ function transformToFrontendUrl(url) {
55
+ return url.replace('learn-be.jamf.com', 'learn.jamf.com');
56
+ }
57
+ /**
58
+ * Strip HTML tags from a string
59
+ */
60
+ function stripHtml(html) {
61
+ return html
62
+ .replace(/<[^>]*>/g, '')
63
+ .replace(/&nbsp;/g, ' ')
64
+ .replace(/&amp;/g, '&')
65
+ .replace(/&lt;/g, '<')
66
+ .replace(/&gt;/g, '>')
67
+ .replace(/&quot;/g, '"')
68
+ .replace(/&#39;/g, "'")
69
+ .replace(/\s+/g, ' ')
70
+ .trim();
71
+ }
72
+ /**
73
+ * Fetch JSON data from a URL with error handling
74
+ */
75
+ async function fetchJson(url) {
76
+ await throttle();
77
+ try {
78
+ const response = await axios.get(url, {
79
+ timeout: REQUEST_CONFIG.TIMEOUT,
80
+ headers: {
81
+ 'User-Agent': REQUEST_CONFIG.USER_AGENT,
82
+ 'Accept': 'application/json',
83
+ 'Accept-Language': 'en-US,en;q=0.9'
84
+ }
85
+ });
86
+ return response.data;
87
+ }
88
+ catch (error) {
89
+ if (axios.isAxiosError(error)) {
90
+ const axiosError = error;
91
+ if (axiosError.response?.status === 404) {
92
+ throw new JamfDocsError(`Resource not found: ${url}`, JamfDocsErrorCode.NOT_FOUND, url, 404);
93
+ }
94
+ if (axiosError.response?.status === 429) {
95
+ throw new JamfDocsError('Rate limited. Please wait and try again.', JamfDocsErrorCode.RATE_LIMITED, url, 429);
96
+ }
97
+ if (axiosError.code === 'ECONNABORTED') {
98
+ throw new JamfDocsError('Request timed out', JamfDocsErrorCode.TIMEOUT, url);
99
+ }
100
+ throw new JamfDocsError(`Network error: ${axiosError.message}`, JamfDocsErrorCode.NETWORK_ERROR, url);
101
+ }
102
+ throw error;
103
+ }
104
+ }
105
+ /**
106
+ * Fetch HTML content from a URL with error handling
107
+ */
108
+ async function fetchHtml(url) {
109
+ await throttle();
110
+ try {
111
+ const response = await axios.get(url, {
112
+ timeout: REQUEST_CONFIG.TIMEOUT,
113
+ headers: {
114
+ 'User-Agent': REQUEST_CONFIG.USER_AGENT,
115
+ 'Accept': 'text/html,application/xhtml+xml',
116
+ 'Accept-Language': 'en-US,en;q=0.9'
117
+ }
118
+ });
119
+ return response.data;
120
+ }
121
+ catch (error) {
122
+ if (axios.isAxiosError(error)) {
123
+ const axiosError = error;
124
+ if (axiosError.response?.status === 404) {
125
+ throw new JamfDocsError(`Article not found: ${url}`, JamfDocsErrorCode.NOT_FOUND, url, 404);
126
+ }
127
+ if (axiosError.response?.status === 429) {
128
+ throw new JamfDocsError('Rate limited. Please wait and try again.', JamfDocsErrorCode.RATE_LIMITED, url, 429);
129
+ }
130
+ if (axiosError.code === 'ECONNABORTED') {
131
+ throw new JamfDocsError('Request timed out', JamfDocsErrorCode.TIMEOUT, url);
132
+ }
133
+ throw new JamfDocsError(`Network error: ${axiosError.message}`, JamfDocsErrorCode.NETWORK_ERROR, url);
134
+ }
135
+ throw error;
136
+ }
137
+ }
138
+ /**
139
+ * Clean HTML content by removing unwanted elements
140
+ */
141
+ function cleanHtml($) {
142
+ // Remove unwanted elements
143
+ $(SELECTORS.REMOVE).remove();
144
+ // Fix relative URLs
145
+ $('a[href^="/"]').each((_, el) => {
146
+ const href = $(el).attr('href');
147
+ if (href) {
148
+ $(el).attr('href', `${DOCS_BASE_URL}${href}`);
149
+ }
150
+ });
151
+ $('img[src^="/"]').each((_, el) => {
152
+ const src = $(el).attr('src');
153
+ if (src) {
154
+ $(el).attr('src', `${DOCS_BASE_URL}${src}`);
155
+ }
156
+ });
157
+ }
158
+ /**
159
+ * Extract product and version from URL
160
+ * Supports both old docs.jamf.com and new learn.jamf.com URL structures
161
+ */
162
+ function extractProductInfo(url) {
163
+ // learn.jamf.com structure: /en-US/bundle/{product}-documentation/page/{page}.html
164
+ const bundleMatch = url.match(/\/bundle\/([^/]+)-documentation\//);
165
+ if (bundleMatch) {
166
+ const bundleSlug = bundleMatch[1];
167
+ const product = Object.values(JAMF_PRODUCTS).find(p => p.bundleId.includes(bundleSlug ?? ''));
168
+ return { product: product?.name, version: 'current' };
169
+ }
170
+ // Legacy docs.jamf.com structure: /{version}/{product}/...
171
+ const urlObj = new URL(url);
172
+ const pathParts = urlObj.pathname.split('/').filter(Boolean);
173
+ // Check for versioned paths like /11.5.0/jamf-pro/...
174
+ const versionMatch = pathParts[0]?.match(/^\d+\.\d+(\.\d+)?$/);
175
+ if (versionMatch) {
176
+ const version = pathParts[0];
177
+ const productSlug = pathParts[1];
178
+ const product = Object.values(JAMF_PRODUCTS).find(p => p.urlPattern.includes(productSlug ?? ''));
179
+ return { product: product?.name, version };
180
+ }
181
+ // Check for unversioned paths like /jamf-connect/...
182
+ for (const [, product] of Object.entries(JAMF_PRODUCTS)) {
183
+ if (url.includes(product.bundleId) || url.includes(product.id)) {
184
+ return { product: product.name, version: 'current' };
185
+ }
186
+ }
187
+ return { product: undefined, version: undefined };
188
+ }
189
+ /**
190
+ * Check if a search result matches a topic based on keywords
191
+ */
192
+ function matchesTopic(result, topicId) {
193
+ const topic = JAMF_TOPICS[topicId];
194
+ const searchText = `${result.title} ${result.snippet}`.toLowerCase();
195
+ return topic.keywords.some(keyword => searchText.includes(keyword.toLowerCase()));
196
+ }
197
+ /**
198
+ * Search Jamf documentation using Zoomin Search API
199
+ */
200
+ export async function searchDocumentation(params) {
201
+ const page = params.page ?? PAGINATION_CONFIG.DEFAULT_PAGE;
202
+ const pageSize = params.limit ?? CONTENT_LIMITS.DEFAULT_SEARCH_RESULTS;
203
+ const maxTokens = params.maxTokens ?? TOKEN_CONFIG.DEFAULT_MAX_TOKENS;
204
+ const cacheKey = `search:${JSON.stringify({ ...params, page: 1 })}`; // Cache without page for full results
205
+ // Check cache for full results
206
+ let allResults = await cache.get(cacheKey);
207
+ if (!allResults) {
208
+ // Fetch more results to allow for filtering
209
+ const fetchLimit = CONTENT_LIMITS.MAX_SEARCH_RESULTS;
210
+ // Build API URL with query params
211
+ const apiUrl = new URL(`${DOCS_API_URL}/api/search`);
212
+ apiUrl.searchParams.set('q', params.query);
213
+ apiUrl.searchParams.set('rpp', fetchLimit.toString());
214
+ console.error(`[SEARCH] Query: "${params.query}", Product: ${params.product ?? 'all'}, Topic: ${params.topic ?? 'all'}, URL: ${apiUrl.toString()}`);
215
+ try {
216
+ const response = await fetchJson(apiUrl.toString());
217
+ // Transform Zoomin results to SearchResult format with metadata
218
+ allResults = response.Results
219
+ .filter(wrapper => wrapper.leading_result !== null)
220
+ .map(wrapper => {
221
+ const result = wrapper.leading_result;
222
+ // Extract product from bundle_id
223
+ const bundleId = result.bundle_id || '';
224
+ const bundleMatch = bundleId.match(/^(jamf-[a-z]+)-documentation/);
225
+ const bundleSlug = bundleMatch?.[1] ?? null;
226
+ const productEntry = bundleSlug
227
+ ? Object.entries(JAMF_PRODUCTS).find(([id]) => id === bundleSlug)
228
+ : null;
229
+ const searchResult = {
230
+ title: result.title || 'Untitled',
231
+ url: transformToFrontendUrl(result.url || ''),
232
+ snippet: stripHtml(result.snippet || '').slice(0, CONTENT_LIMITS.MAX_SNIPPET_LENGTH),
233
+ product: productEntry ? productEntry[1].name : (result.publication_title || 'Jamf'),
234
+ version: 'current'
235
+ };
236
+ if (result.score !== undefined && result.score !== null) {
237
+ searchResult.relevance = result.score;
238
+ }
239
+ // Find matched topics
240
+ const matchedTopics = Object.keys(JAMF_TOPICS)
241
+ .filter(topicId => matchesTopic(searchResult, topicId));
242
+ return { result: searchResult, bundleSlug, matchedTopics };
243
+ });
244
+ // Cache full results
245
+ await cache.set(cacheKey, allResults);
246
+ }
247
+ catch (error) {
248
+ console.error('[SEARCH] Error:', error);
249
+ if (error instanceof JamfDocsError) {
250
+ throw error;
251
+ }
252
+ // Return empty results on error
253
+ return {
254
+ results: [],
255
+ pagination: {
256
+ page: 1,
257
+ pageSize,
258
+ totalPages: 0,
259
+ totalItems: 0,
260
+ hasNext: false,
261
+ hasPrev: false
262
+ },
263
+ tokenInfo: createTokenInfo('', maxTokens)
264
+ };
265
+ }
266
+ }
267
+ // Apply filters
268
+ let filteredResults = allResults;
269
+ // Product filter
270
+ if (params.product) {
271
+ filteredResults = filteredResults.filter(r => r.bundleSlug === params.product);
272
+ }
273
+ // Topic filter
274
+ if (params.topic) {
275
+ const topicFilter = params.topic;
276
+ filteredResults = filteredResults.filter(r => r.matchedTopics.includes(topicFilter));
277
+ }
278
+ // Calculate pagination
279
+ const paginationInfo = calculatePagination(filteredResults.length, page, pageSize);
280
+ // Get paginated results
281
+ const paginatedResults = filteredResults
282
+ .slice(paginationInfo.startIndex, paginationInfo.endIndex)
283
+ .map(r => r.result);
284
+ // Calculate token info
285
+ const resultText = paginatedResults.map(r => `${r.title}\n${r.snippet}\n${r.url}`).join('\n\n');
286
+ const tokenCount = estimateTokens(resultText);
287
+ // Check if we need to truncate
288
+ let finalResults = paginatedResults;
289
+ let truncated = false;
290
+ if (tokenCount > maxTokens) {
291
+ // Truncate results to fit token limit
292
+ let runningTokens = 0;
293
+ finalResults = [];
294
+ for (const result of paginatedResults) {
295
+ const resultTokens = estimateTokens(`${result.title}\n${result.snippet}\n${result.url}`);
296
+ if (runningTokens + resultTokens > maxTokens) {
297
+ truncated = true;
298
+ break;
299
+ }
300
+ finalResults.push(result);
301
+ runningTokens += resultTokens;
302
+ }
303
+ }
304
+ return {
305
+ results: finalResults,
306
+ pagination: {
307
+ page: paginationInfo.page,
308
+ pageSize: paginationInfo.pageSize,
309
+ totalPages: paginationInfo.totalPages,
310
+ totalItems: filteredResults.length,
311
+ hasNext: paginationInfo.hasNext || truncated,
312
+ hasPrev: paginationInfo.hasPrev
313
+ },
314
+ tokenInfo: {
315
+ tokenCount: estimateTokens(finalResults.map(r => `${r.title}\n${r.snippet}\n${r.url}`).join('\n\n')),
316
+ truncated,
317
+ maxTokens
318
+ }
319
+ };
320
+ }
321
+ /**
322
+ * Fetch and parse a documentation article
323
+ * Uses backend URL (learn-be.jamf.com) for pre-rendered content
324
+ */
325
+ export async function fetchArticle(url, options = {}) {
326
+ const maxTokens = options.maxTokens ?? TOKEN_CONFIG.DEFAULT_MAX_TOKENS;
327
+ // Store original URL for display, use backend URL for fetching
328
+ const displayUrl = transformToFrontendUrl(url);
329
+ const fetchUrl = transformToBackendUrl(url);
330
+ const cacheKey = `article:${displayUrl}`;
331
+ // Check cache for raw article (without section/token processing)
332
+ let rawArticle = await cache.get(cacheKey);
333
+ if (!rawArticle) {
334
+ // Fetch HTML from backend URL (pre-rendered content, not SPA shell)
335
+ const html = await fetchHtml(fetchUrl);
336
+ const $ = cheerio.load(html);
337
+ // Clean content
338
+ cleanHtml($);
339
+ // Extract content
340
+ const contentHtml = $(SELECTORS.CONTENT).html() ?? '';
341
+ const title = $(SELECTORS.TITLE).first().text().trim() || 'Untitled';
342
+ // Convert to Markdown
343
+ const content = turndown.turndown(contentHtml);
344
+ // Extract breadcrumb
345
+ const breadcrumb = $(SELECTORS.BREADCRUMB)
346
+ .map((_, el) => $(el).text().trim())
347
+ .get()
348
+ .filter(Boolean);
349
+ // Extract related articles
350
+ const relatedArticles = options.includeRelated
351
+ ? $(SELECTORS.RELATED).map((_, el) => ({
352
+ title: $(el).text().trim(),
353
+ url: $(el).attr('href') ?? ''
354
+ })).get().filter(r => r.title && r.url)
355
+ : undefined;
356
+ // Extract product info from URL
357
+ const { product, version } = extractProductInfo(displayUrl);
358
+ rawArticle = {
359
+ title,
360
+ content,
361
+ url: displayUrl,
362
+ product,
363
+ version,
364
+ breadcrumb: breadcrumb.length > 0 ? breadcrumb : undefined,
365
+ relatedArticles: relatedArticles && relatedArticles.length > 0 ? relatedArticles : undefined
366
+ };
367
+ // Cache raw article
368
+ await cache.set(cacheKey, rawArticle);
369
+ }
370
+ // Extract all sections
371
+ const allSections = extractSections(rawArticle.content);
372
+ // Handle section extraction if requested
373
+ let processedContent = rawArticle.content;
374
+ let tokenInfo;
375
+ if (options.section) {
376
+ // Extract specific section
377
+ const sectionResult = extractSection(rawArticle.content, options.section, maxTokens);
378
+ processedContent = sectionResult.content;
379
+ tokenInfo = sectionResult.tokenInfo;
380
+ if (!sectionResult.section) {
381
+ // Section not found, return error info
382
+ processedContent = `*Section "${options.section}" not found.*\n\n**Available sections:**\n${allSections.map(s => `- ${s.title}`).join('\n')}`;
383
+ tokenInfo = createTokenInfo(processedContent, maxTokens);
384
+ }
385
+ }
386
+ else {
387
+ // Apply token limit with smart truncation
388
+ const truncateResult = truncateToTokenLimit(rawArticle.content, maxTokens);
389
+ processedContent = truncateResult.content;
390
+ tokenInfo = truncateResult.tokenInfo;
391
+ }
392
+ return {
393
+ ...rawArticle,
394
+ content: processedContent,
395
+ tokenInfo,
396
+ sections: allSections
397
+ };
398
+ }
399
+ /**
400
+ * Discover the latest bundle version for a product via search API
401
+ */
402
+ async function discoverLatestBundleId(product) {
403
+ const productInfo = JAMF_PRODUCTS[product];
404
+ const baseBundleId = productInfo.bundleId;
405
+ try {
406
+ // Search for any document from this product to discover the latest version
407
+ const apiUrl = `${DOCS_API_URL}/api/search?q=${encodeURIComponent(productInfo.name)}&rpp=10`;
408
+ const response = await fetchJson(apiUrl);
409
+ // Find a result with a matching bundle prefix
410
+ for (const wrapper of response.Results) {
411
+ const bundleId = wrapper.leading_result?.bundle_id;
412
+ if (bundleId && bundleId.startsWith(baseBundleId)) {
413
+ return bundleId;
414
+ }
415
+ }
416
+ }
417
+ catch (error) {
418
+ console.error(`[TOC] Error discovering bundle version for ${product}:`, error);
419
+ }
420
+ return null;
421
+ }
422
+ /**
423
+ * Parse TOC HTML from Zoomin backend
424
+ */
425
+ function parseTocHtml(html) {
426
+ const $ = cheerio.load(html);
427
+ const toc = [];
428
+ // Parse the nested list structure
429
+ $('ul.list-links > li.toc').each((_, el) => {
430
+ const entry = parseTocEntry($, el);
431
+ if (entry) {
432
+ toc.push(entry);
433
+ }
434
+ });
435
+ return toc;
436
+ }
437
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
438
+ function parseTocEntry($, el) {
439
+ const $el = $(el);
440
+ const $link = $el.children('.inner').children('a').first();
441
+ const title = $link.text().trim();
442
+ let url = $link.attr('href') ?? '';
443
+ if (!title || !url) {
444
+ return null;
445
+ }
446
+ // Transform to frontend URL for display
447
+ url = transformToFrontendUrl(url);
448
+ const entry = { title, url };
449
+ // Check for children
450
+ const $children = $el.children('ul.list-links');
451
+ if ($children.length > 0) {
452
+ const children = [];
453
+ $children.children('li.toc').each((_, childEl) => {
454
+ const childEntry = parseTocEntry($, childEl);
455
+ if (childEntry) {
456
+ children.push(childEntry);
457
+ }
458
+ });
459
+ if (children.length > 0) {
460
+ entry.children = children;
461
+ }
462
+ }
463
+ return entry;
464
+ }
465
+ /**
466
+ * Convert TOC entry to string for token counting
467
+ */
468
+ function tocEntryToString(entry, depth = 0) {
469
+ const indent = ' '.repeat(depth);
470
+ let result = `${indent}- ${entry.title}\n`;
471
+ if (entry.children) {
472
+ for (const child of entry.children) {
473
+ result += tocEntryToString(child, depth + 1);
474
+ }
475
+ }
476
+ return result;
477
+ }
478
+ /**
479
+ * Count total TOC entries including children
480
+ */
481
+ function countTocEntries(entries) {
482
+ let count = entries.length;
483
+ for (const entry of entries) {
484
+ if (entry.children) {
485
+ count += countTocEntries(entry.children);
486
+ }
487
+ }
488
+ return count;
489
+ }
490
+ /**
491
+ * Fetch table of contents for a product
492
+ * Uses backend TOC endpoint (learn-be.jamf.com/bundle/{bundleId}/toc)
493
+ */
494
+ export async function fetchTableOfContents(product, _version, // Version is not used for learn.jamf.com (always current)
495
+ options = {}) {
496
+ const page = options.page ?? PAGINATION_CONFIG.DEFAULT_PAGE;
497
+ const maxTokens = options.maxTokens ?? TOKEN_CONFIG.DEFAULT_MAX_TOKENS;
498
+ const cacheKey = `toc:${product}`;
499
+ // Check cache
500
+ let allToc = await cache.get(cacheKey);
501
+ if (!allToc) {
502
+ // Discover the latest bundle version
503
+ const bundleId = await discoverLatestBundleId(product);
504
+ if (!bundleId) {
505
+ throw new JamfDocsError(`Could not discover bundle version for ${product}`, JamfDocsErrorCode.NOT_FOUND);
506
+ }
507
+ // Fetch TOC from backend
508
+ const tocUrl = `${DOCS_API_URL}/bundle/${bundleId}/toc`;
509
+ console.error(`[TOC] Fetching TOC from: ${tocUrl}`);
510
+ const tocJson = await fetchJson(tocUrl);
511
+ // Parse TOC
512
+ allToc = [];
513
+ for (const [, html] of Object.entries(tocJson)) {
514
+ if (typeof html === 'string' && html.includes('<ul')) {
515
+ const entries = parseTocHtml(html);
516
+ allToc.push(...entries);
517
+ }
518
+ }
519
+ // Cache result
520
+ await cache.set(cacheKey, allToc);
521
+ }
522
+ // Count total entries
523
+ const totalItems = countTocEntries(allToc);
524
+ // For TOC, we paginate at the top-level entries
525
+ const topLevelCount = allToc.length;
526
+ const pageSize = PAGINATION_CONFIG.DEFAULT_PAGE_SIZE;
527
+ const paginationInfo = calculatePagination(topLevelCount, page, pageSize);
528
+ // Get paginated top-level entries (with their children)
529
+ const paginatedToc = allToc.slice(paginationInfo.startIndex, paginationInfo.endIndex);
530
+ // Calculate tokens for paginated TOC
531
+ const tocText = paginatedToc.map(e => tocEntryToString(e)).join('');
532
+ let tokenCount = estimateTokens(tocText);
533
+ let truncated = false;
534
+ let finalToc = paginatedToc;
535
+ // Truncate if over token limit
536
+ if (tokenCount > maxTokens) {
537
+ truncated = true;
538
+ finalToc = [];
539
+ let runningTokens = 0;
540
+ for (const entry of paginatedToc) {
541
+ const entryText = tocEntryToString(entry);
542
+ const entryTokens = estimateTokens(entryText);
543
+ if (runningTokens + entryTokens > maxTokens) {
544
+ break;
545
+ }
546
+ finalToc.push(entry);
547
+ runningTokens += entryTokens;
548
+ }
549
+ tokenCount = runningTokens;
550
+ }
551
+ return {
552
+ toc: finalToc,
553
+ pagination: {
554
+ page: paginationInfo.page,
555
+ pageSize: paginationInfo.pageSize,
556
+ totalPages: paginationInfo.totalPages,
557
+ totalItems,
558
+ hasNext: paginationInfo.hasNext || truncated,
559
+ hasPrev: paginationInfo.hasPrev
560
+ },
561
+ tokenInfo: {
562
+ tokenCount,
563
+ truncated,
564
+ maxTokens
565
+ }
566
+ };
567
+ }
568
+ //# sourceMappingURL=scraper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scraper.js","sourceRoot":"","sources":["../../src/services/scraper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Tokenizer service for Context7-style token management
3
+ *
4
+ * Provides token estimation, smart truncation, and section extraction
5
+ * for controlling response size in LLM contexts.
6
+ */
7
+ import type { TokenInfo, ArticleSection } from '../types.js';
8
+ /**
9
+ * Result of truncation operation
10
+ */
11
+ export interface TruncateResult {
12
+ content: string;
13
+ tokenInfo: TokenInfo;
14
+ remainingSections?: ArticleSection[];
15
+ }
16
+ /**
17
+ * Result of section extraction
18
+ */
19
+ export interface ExtractSectionResult {
20
+ content: string;
21
+ section: ArticleSection | null;
22
+ tokenInfo: TokenInfo;
23
+ }
24
+ /**
25
+ * Estimate token count for a text string
26
+ * Uses different ratios for code blocks vs normal text
27
+ */
28
+ export declare function estimateTokens(text: string): number;
29
+ /**
30
+ * Create a TokenInfo object
31
+ */
32
+ export declare function createTokenInfo(content: string, maxTokens: number, truncated?: boolean): TokenInfo;
33
+ /**
34
+ * Extract sections (headings) from Markdown content
35
+ */
36
+ export declare function extractSections(content: string): ArticleSection[];
37
+ /**
38
+ * Extract a specific section from Markdown content
39
+ */
40
+ export declare function extractSection(content: string, sectionIdentifier: string, maxTokens?: number): ExtractSectionResult;
41
+ /**
42
+ * Smart truncation that preserves document structure
43
+ * - Preserves paragraph boundaries
44
+ * - Correctly closes code blocks
45
+ * - Lists remaining sections when truncated
46
+ */
47
+ export declare function truncateToTokenLimit(content: string, maxTokens?: number): TruncateResult;
48
+ /**
49
+ * Calculate pagination info
50
+ */
51
+ export declare function calculatePagination(totalItems: number, page: number, pageSize: number): {
52
+ page: number;
53
+ pageSize: number;
54
+ totalPages: number;
55
+ totalItems: number;
56
+ hasNext: boolean;
57
+ hasPrev: boolean;
58
+ startIndex: number;
59
+ endIndex: number;
60
+ };
61
+ /**
62
+ * Truncate an array of items to fit within token limit
63
+ * Returns items that fit and pagination info
64
+ */
65
+ export declare function truncateItemsToTokenLimit<T>(items: T[], maxTokens: number, itemToString: (item: T) => string, page?: number, pageSize?: number): {
66
+ items: T[];
67
+ tokenInfo: TokenInfo;
68
+ pagination: {
69
+ page: number;
70
+ pageSize: number;
71
+ totalPages: number;
72
+ totalItems: number;
73
+ hasNext: boolean;
74
+ hasPrev: boolean;
75
+ };
76
+ };
77
+ //# sourceMappingURL=tokenizer.d.ts.map