`getWikiPage`'s attachments fetch had a bare `catch` that swallowed
401/403/429 one function away from discovery code that correctly
rethrows them. During a 50-page discovery scan a rate limit was eaten
once per page and every page cached with `attachments: []`, then
reported to the model as fact.
The discovery probe loop incremented `consecutiveMisses` only on 404, so
a run where every probe failed with a 500 or a network error never
tripped the cutoff, never rethrew, and cached nothing — yet still ran
`discoveredCacheKeys.add(cacheKey)` unconditionally, marking discovery
complete. Every later wiki search then short-circuited on an empty
corpus and returned `[]` for the life of the process.
Discovery is now marked complete only when at least one page was cached
or the loop ended via the 404 cutoff. An all-errors scan satisfies
neither, so it retries; a genuinely empty wiki trips the cutoff and is
still marked complete rather than re-probed on every search.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Retain the page body from the formattable text field (already fetched
per-page, zero extra API calls) and rank title/text matches with
rankRecords instead of exact substring on title alone. searchWikiPages
now returns WikiPageSearchResult[] with score, snippet, and
matchedFields; empty-query behavior (project scoping + limit, no
ranking) is preserved. Adds a matchMode tool parameter defaulting to
fuzzy.
Updates the pre-existing tool-metadata assertion in tests/tools.test.ts
to match the new search_wiki_pages description introduced here.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>