Adds optional query/matchMode to listWorkPackageActivities, ranking the
already-fetched activity list client-side via rankRecords (no extra API
calls). Exposes the same fields on the
openproject_list_work_package_activities tool. When no query is supplied,
every activity is returned exactly as before, and onlyComments continues
to filter independently.
Also fixes a defect in the brief's exact-mode test fixture: the specified
typo query "certificat" is a literal prefix substring of "certificate", so
byte-for-byte exact containment matching (scoreExact in src/search/rank.ts)
finds it regardless of typo tolerance, making the test unable to pass
against a correct implementation. Swapped in "certificatee" (not a
substring of "certificate") to preserve the test's intent without touching
the assertion. Updated one pre-existing test-tools.test.ts call site to
supply matchMode, now required by the extended args type.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Registers openproject_search_work_packages (readOnly: true), taking the tool
registry from 18 to 19. searchWorkPackages now unions a precise server-side
subject filter with a broad recency-ordered candidate window, ranks via the
shared search pipeline, and deep-enriches top candidates with description and
comment text. Exact-mode requests skip the broad query entirely.
searchWorkPackages's return type changes from a flat PaginatedResult<WorkPackageSummary>
to WorkPackageSearchPage, nesting the summary under `workPackage` alongside
score, matchedFields, and an optional snippet.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
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) <[email protected]>
Routes searchMeetings through the shared searchPipeline instead of a
hand-rolled Promise.all fan-out, fixing two live bugs: an expired token
on agenda-item fetch previously produced "no results" (swallowed via
.catch(() => undefined)) instead of propagating the auth error, and up
to 250 candidate meetings could fire simultaneous agenda-item requests.
The pipeline caps enrichment at 25 candidates with 8 in flight, and
isFatalSearchError now lets 401/403/429 propagate while other failures
degrade a single record and set `degraded`.
Also removes the old substring-based extractSnippet from
src/services/meetings.ts in favor of src/search/snippet.ts, and adds
matchMode ("fuzzy" | "exact") to SearchMeetingsParams and the
openproject_search_meetings tool schema.
Updated two pre-existing tests in tests/meetings.test.ts whose fixtures
assumed the old implementation's API surface: one didn't stub the
meeting-detail endpoint the pipeline's deep enrichment now also fetches
(for participants), and one assumed a 50-item candidate page size where
the new pipeline hardcodes 100. Updated one assertion in
tests/tools.test.ts that checked the old literal tool description.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>