diff --git a/website/public/data/manifest.json b/website/public/data/manifest.json index 1da92aff..d0b5f935 100644 --- a/website/public/data/manifest.json +++ b/website/public/data/manifest.json @@ -1,5 +1,5 @@ { - "generated": "2026-01-28T22:44:20.356Z", + "generated": "2026-01-28T22:56:09.687Z", "counts": { "agents": 140, "prompts": 134, diff --git a/website/src/scripts/pages/agents.ts b/website/src/scripts/pages/agents.ts index 9f661a39..fcc297c5 100644 --- a/website/src/scripts/pages/agents.ts +++ b/website/src/scripts/pages/agents.ts @@ -25,7 +25,7 @@ interface AgentsData { const resourceType = 'agent'; let allItems: Agent[] = []; -let search = new FuzzySearch(); +let search = new FuzzySearch(); let modelSelect: Choices; let toolSelect: Choices; diff --git a/website/src/scripts/pages/collections.ts b/website/src/scripts/pages/collections.ts index 776e7986..4c676859 100644 --- a/website/src/scripts/pages/collections.ts +++ b/website/src/scripts/pages/collections.ts @@ -2,13 +2,14 @@ * Collections page functionality */ import { createChoices, getChoicesValues, type Choices } from '../choices'; -import { FuzzySearch, type SearchItem } from '../search'; +import { FuzzySearch } from '../search'; import { fetchData, debounce, escapeHtml, getGitHubUrl } from '../utils'; import { setupModal, openFileModal } from '../modal'; interface Collection { id: string; name: string; + title: string; description?: string; path: string; tags?: string[]; @@ -25,7 +26,7 @@ interface CollectionsData { const resourceType = 'collection'; let allItems: Collection[] = []; -let search = new FuzzySearch(); +let search = new FuzzySearch(); let tagSelect: Choices; let currentFilters = { tags: [] as string[], diff --git a/website/src/scripts/pages/index.ts b/website/src/scripts/pages/index.ts index 128cbbe9..dfa3773a 100644 --- a/website/src/scripts/pages/index.ts +++ b/website/src/scripts/pages/index.ts @@ -48,7 +48,7 @@ export async function initHomepage(): Promise { // Load search index const searchIndex = await fetchData('search-index.json'); if (searchIndex) { - const search = new FuzzySearch(); + const search = new FuzzySearch(); search.setItems(searchIndex); const searchInput = document.getElementById('global-search') as HTMLInputElement; diff --git a/website/src/scripts/pages/instructions.ts b/website/src/scripts/pages/instructions.ts index 8492e292..74513231 100644 --- a/website/src/scripts/pages/instructions.ts +++ b/website/src/scripts/pages/instructions.ts @@ -23,7 +23,7 @@ interface InstructionsData { const resourceType = 'instruction'; let allItems: Instruction[] = []; -let search = new FuzzySearch(); +let search = new FuzzySearch(); let extensionSelect: Choices; let currentFilters = { extensions: [] as string[] }; diff --git a/website/src/scripts/pages/prompts.ts b/website/src/scripts/pages/prompts.ts index 57bd3a98..bb711e7c 100644 --- a/website/src/scripts/pages/prompts.ts +++ b/website/src/scripts/pages/prompts.ts @@ -22,7 +22,7 @@ interface PromptsData { const resourceType = 'prompt'; let allItems: Prompt[] = []; -let search = new FuzzySearch(); +let search = new FuzzySearch(); let toolSelect: Choices; let currentFilters = { tools: [] as string[] }; diff --git a/website/src/scripts/pages/skills.ts b/website/src/scripts/pages/skills.ts index 4dfe2210..5ae556b5 100644 --- a/website/src/scripts/pages/skills.ts +++ b/website/src/scripts/pages/skills.ts @@ -33,7 +33,7 @@ interface SkillsData { const resourceType = 'skill'; let allItems: Skill[] = []; -let search = new FuzzySearch(); +let search = new FuzzySearch(); let categorySelect: Choices; let currentFilters = { categories: [] as string[], diff --git a/website/src/scripts/search.ts b/website/src/scripts/search.ts index 1bb67699..8856b216 100644 --- a/website/src/scripts/search.ts +++ b/website/src/scripts/search.ts @@ -14,30 +14,36 @@ export interface SearchItem { [key: string]: unknown; } +export interface SearchableItem { + title: string; + description?: string; + [key: string]: unknown; +} + export interface SearchOptions { fields?: string[]; limit?: number; minScore?: number; } -export class FuzzySearch { - private items: SearchItem[] = []; +export class FuzzySearch { + private items: T[] = []; - constructor(items: SearchItem[] = []) { + constructor(items: T[] = []) { this.items = items; } /** * Update the items to search */ - setItems(items: SearchItem[]): void { + setItems(items: T[]): void { this.items = items; } /** * Search items with fuzzy matching */ - search(query: string, options: SearchOptions = {}): SearchItem[] { + search(query: string, options: SearchOptions = {}): T[] { const { fields = ['title', 'description', 'searchText'], limit = 50, @@ -50,7 +56,7 @@ export class FuzzySearch { const normalizedQuery = query.toLowerCase().trim(); const queryWords = normalizedQuery.split(/\s+/); - const results: Array<{ item: SearchItem; score: number }> = []; + const results: Array<{ item: T; score: number }> = []; for (const item of this.items) { const score = this.calculateScore(item, queryWords, fields); @@ -68,14 +74,14 @@ export class FuzzySearch { /** * Calculate match score for an item */ - private calculateScore(item: SearchItem, queryWords: string[], fields: string[]): number { + private calculateScore(item: T, queryWords: string[], fields: string[]): number { let totalScore = 0; for (const word of queryWords) { let wordScore = 0; for (const field of fields) { - const value = item[field]; + const value = (item as Record)[field]; if (!value) continue; const normalizedValue = String(value).toLowerCase(); @@ -108,7 +114,7 @@ export class FuzzySearch { // Bonus for matching all words const matchesAllWords = queryWords.every(word => fields.some(field => { - const value = item[field]; + const value = (item as Record)[field]; return value && String(value).toLowerCase().includes(word); }) ); @@ -140,13 +146,13 @@ export class FuzzySearch { } } -// Global search instance -export const globalSearch = new FuzzySearch(); +// Global search instance (uses SearchItem for the global search index) +export const globalSearch = new FuzzySearch(); /** * Initialize global search with search index */ -export async function initGlobalSearch(): Promise { +export async function initGlobalSearch(): Promise> { const searchIndex = await fetchData('search-index.json'); if (searchIndex) { globalSearch.setItems(searchIndex);