Skip to content

feat(#5630): add scoped search filters to docs site - #5704

Merged
rh-hemartin merged 1 commit into
mainfrom
fix/5630-docs-search-scopes
Jul 29, 2026
Merged

feat(#5630): add scoped search filters to docs site#5704
rh-hemartin merged 1 commit into
mainfrom
fix/5630-docs-search-scopes

Conversation

@rh-hemartin

@rh-hemartin rh-hemartin commented Jul 29, 2026

Copy link
Copy Markdown
Member

Summary

  • Override VitePress's VPLocalSearchBox with a custom component that reads search scope definitions from themeConfig.search.options.scopes
  • Each scope has a label and prefixes array; users toggle pill-style buttons in the search modal to restrict results to matching path prefixes
  • When no scope is active, all pages are searched; when a scope is active and no results match, a hint nudges the user to remove the filter
  • Pin vitepress to exact 1.6.4; the vendored component relies on internal paths (dist/client/...) that are not public API
  • Add stylelint-config-html/vue so stylelint can parse .vue SFCs; :deep/:global pseudo-classes are handled by inline stylelint-disable comments in the component

Closes #5630

🤖 Generated with Claude Code

@rh-hemartin
rh-hemartin requested a review from a team as a code owner July 29, 2026 09:15
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add scoped filters to VitePress local search modal

✨ Enhancement ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Add search “scope” pills to restrict local search results by docs path prefixes.
• Override VitePress’s LocalSearchBox via Vite alias to inject scoped filtering UX.
• Update stylelint config to support Vue scoped styles and VitePress selectors.
Diagram

graph TD
  Config["website/.vitepress/config.ts"] --> Alias["Vite alias override"] --> SearchBox["Custom VPLocalSearchBox.vue"] --> Index[("MiniSearch index") ] --> Results[["Filtered results list"]]
  Config --> Scopes["search.options.scopes"] --> SearchBox
  SearchBox --> UX[["Scope pills + hint"]]
  Stylelint[".stylelintrc.json"] --> SearchBox

  subgraph Legend
    direction LR
    _cfg["Config/File"] ~~~ _idx[("Search index")] ~~~ _ui[["UI surface"]]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Index-time tagging (section field) instead of path-prefix matching
  • ➕ More robust than URL prefix heuristics (survives moves/redirects better)
  • ➕ Allows richer filters (e.g., multiple facets) without relying on path structure
  • ➖ Requires changes to index generation pipeline (more invasive)
  • ➖ Harder to keep aligned with VitePress local-search internals
2. Algolia/DocSearch with facets
  • ➕ Built-in facet filtering and scalable search UX
  • ➕ Avoids maintaining a large fork of VitePress’s local search modal
  • ➖ External dependency and operational overhead (index hosting/config)
  • ➖ May be overkill if local search is a requirement
3. Upstream VitePress enhancement (contribute scopes feature)
  • ➕ Reduces long-term maintenance burden of component overrides
  • ➕ Keeps behavior aligned with upstream accessibility and UX updates
  • ➖ Longer lead time; may not match the exact UX desired
  • ➖ Requires maintaining the feature through upstream review cycles

Recommendation: The chosen approach (aliasing and overriding VPLocalSearchBox with a scope-aware fork) is the fastest path with minimal impact on the existing indexing model and keeps the feature fully client-side. The main tradeoff is maintenance risk if VitePress changes the upstream component; if this becomes a recurring pattern, consider upstreaming the scopes concept or moving to an index-time tagging approach.

Files changed (3) +983 / -23

Enhancement (2) +979 / -21
config.tsDefine search scopes and alias VPLocalSearchBox override +51/-21

Define search scopes and alias VPLocalSearchBox override

• Adds local-search scope definitions (labels + path prefixes) under search.options.scopes. Converts Vite resolve.alias to array form and adds a regex alias to replace VitePress’s VPLocalSearchBox with a local theme component.

website/.vitepress/config.ts

VPLocalSearchBox.vueCustom local search modal with scope pill filtering +928/-0

Custom local search modal with scope pill filtering

• Introduces a full override of VitePress’s local search modal, adding scope toggles that filter MiniSearch results by configured path prefixes. Preserves keyboard navigation, detailed view excerpts, and term highlighting, and adds a no-results hint when scopes are active.

website/.vitepress/theme/components/VPLocalSearchBox.vue

Other (1) +4 / -2
.stylelintrc.jsonEnable Vue-aware linting for VitePress theme styles +4/-2

Enable Vue-aware linting for VitePress theme styles

• Extends stylelint with Vue support and allows Vue-specific pseudo-classes (:deep, :global). Disables no-descending-specificity to avoid conflicts with upstream VitePress CSS ordering.

.stylelintrc.json

@fullsend-ai-review

fullsend-ai-review Bot commented Jul 29, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 9:16 AM UTC · Completed 9:37 AM UTC
Commit: 7598df0 · View workflow run →

@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown

Site preview

Preview: https://01d070e6-site.fullsend-ai.workers.dev

Commit: f958fcb9dd4bc68bc8880f4c2a5bd8b090f23803

@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@qodo-code-review

qodo-code-review Bot commented Jul 29, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 54 rules

Grey Divider


Action required

1. Hashless id truncation 🐞 Bug ≡ Correctness
Description
fetchExcerpt() (and the excerpt cache) derive the page id with id.slice(0, id.indexOf('#'));
when a result id has no #, indexOf returns -1 and slice(0, -1) drops the last character. This
can make excerpt imports fail and cache lookups inconsistent for page-level results without anchors
when detailed view is enabled.
Code

website/.vitepress/theme/components/VPLocalSearchBox.vue[R265-270]

+async function fetchExcerpt(id: string) {
+  const file = pathToFile(id.slice(0, id.indexOf("#")));
+  try {
+    if (!file) throw new Error(`Cannot find file for id: ${id}`);
+    return { id, mod: await import(/*@vite-ignore*/ file) };
+  } catch (e) {
Relevance

●●● Strong

Team has accepted VitePress edge-case correctness fixes; hashless-id slice(0,-1) bug likely to be
fixed.

PR-#2765
PR-#4020

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The implementation slices using id.indexOf('#') in both the excerpt cache and excerpt import path;
in JS, indexOf returning -1 makes slice(0, -1) truncate the string, which then propagates into
pathToFile(...) and cache keys.

website/.vitepress/theme/components/VPLocalSearchBox.vue[191-197]
website/.vitepress/theme/components/VPLocalSearchBox.vue[234-241]
website/.vitepress/theme/components/VPLocalSearchBox.vue[265-270]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The code assumes every `SearchResult.id` contains a `#` anchor and uses `id.slice(0, id.indexOf('#'))`. If an id has no hash, `indexOf('#')` is `-1` and `slice(0, -1)` truncates the page id (drops the last character), which breaks excerpt importing (`pathToFile(...)`) and excerpt cache keys.

### Issue Context
This affects the detailed excerpt path (`fetchExcerpt`) and the per-page excerpt cache key (`mapId`). It can surface as failed dynamic imports and missing excerpts when a result points to the page itself (no anchor).

### Fix
Compute a safe `pageId` once per id:
- `const hash = id.indexOf('#')`
- `const pageId = hash === -1 ? id : id.slice(0, hash)`
Use `pageId` consistently for:
- cache keying (`cache.get(pageId)` / `cache.set(pageId, ...)`)
- `pathToFile(pageId)`

### Fix Focus Areas
- website/.vitepress/theme/components/VPLocalSearchBox.vue[191-197]
- website/.vitepress/theme/components/VPLocalSearchBox.vue[234-241]
- website/.vitepress/theme/components/VPLocalSearchBox.vue[265-270]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Empty regex highlighting ✓ Resolved 🐞 Bug ☼ Reliability
Description
The code calls markRegExp(formMarkRegex(terms)) unconditionally, but formMarkRegex builds `new
RegExp('', 'gi') when terms` is empty. Passing an empty regex to the highlighter is
undefined/undesired behavior and can cause unnecessary work or incorrect marking.
Code

website/.vitepress/theme/components/VPLocalSearchBox.vue[R247-251]

+    await new Promise((r) => {
+      mark.value?.unmark({
+        done: () => {
+          mark.value?.markRegExp(formMarkRegex(terms), { done: r });
+        },
Relevance

●● Moderate

No repo history on mark.js empty-regex guards; team fixes edge cases elsewhere but no direct
precedent here.

PR-#2765

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
terms is initialized empty and only populated from r.match; formMarkRegex joins the (possibly
empty) term list into a regex source string, and the result is passed to markRegExp regardless of
whether it is empty.

website/.vitepress/theme/components/VPLocalSearchBox.vue[232-253]
website/.vitepress/theme/components/VPLocalSearchBox.vue[409-417]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`terms` can be empty, yet the code always calls `mark.value?.markRegExp(formMarkRegex(terms), ...)`. When `terms.size === 0`, `formMarkRegex` creates `new RegExp('', 'gi')`.

### Issue Context
This runs after every search update (debounced watcher) and should only run when there are actual matched terms to highlight.

### Fix
Add a guard:
- If `terms.size === 0`, skip `markRegExp(...)` (you can still `unmark` and then resolve the promise).
Or make `formMarkRegex` return `null` for empty input and conditionally call `markRegExp`.

### Fix Focus Areas
- website/.vitepress/theme/components/VPLocalSearchBox.vue[232-253]
- website/.vitepress/theme/components/VPLocalSearchBox.vue[409-417]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Blank query still searches 🐞 Bug ➹ Performance
Description
The debounced watcher runs immediately and calls index.search(filterTextValue, ...) even when
filterTextValue is blank. This adds avoidable work on modal open/clear and can cascade into
highlight/excerpt logic depending on the search library’s behavior.
Code

website/.vitepress/theme/components/VPLocalSearchBox.vue[R171-184]

+    // Search
+    const active = activeScopes.value;
+    const searchOpts =
+      active.size > 0
+        ? {
+            filter: (r: SearchResult) => {
+              const prefixes = [...active].flatMap((i) => scopes.value[i]?.prefixes || []);
+              return prefixes.some((p) => r.id.startsWith(p));
+            },
+          }
+        : {};
+    results.value = index.search(filterTextValue, searchOpts).slice(0, 16) as (SearchResult &
+      Result)[];
+    enableNoResults.value = true;
Relevance

●● Moderate

No similar historical findings found; blank-query search might be intentional UX (show initial
results) so acceptance uncertain.

PR-#2701

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The watcher is immediate: true and invokes index.search(filterTextValue, ...) without any early
return/guard for blank input.

website/.vitepress/theme/components/VPLocalSearchBox.vue[156-184]
website/.vitepress/theme/components/VPLocalSearchBox.vue[262-263]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The search watcher calls `index.search(filterTextValue, ...)` without checking for blank/whitespace input, and the watcher is configured with `immediate: true`. This means opening the modal (or clearing the query) always triggers the search pipeline.

### Issue Context
The component already has UI logic for “no results” when `filterText` is non-empty; a blank query can safely short-circuit.

### Fix
Before calling `index.search(...)`:
- If `!filterTextValue.trim()`:
 - set `results.value = []`
 - set `enableNoResults.value = false` (optional, to avoid transient UI)
 - `mark.value?.unmark(...)` (optional cleanup)
 - return early

### Fix Focus Areas
- website/.vitepress/theme/components/VPLocalSearchBox.vue[156-190]
- website/.vitepress/theme/components/VPLocalSearchBox.vue[262-263]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment thread website/.vitepress/theme/components/VPLocalSearchBox.vue
Comment thread website/.vitepress/theme/components/VPLocalSearchBox.vue
Comment thread website/.vitepress/theme/components/VPLocalSearchBox.vue
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review

Findings

Medium

  • [logic-error] website/.vitepress/config.ts:611 — Top-level docs pages (vision.md, architecture.md, runtimes.md, glossary.md, roadmap.md, landscape.md, doc-site.md, admin-oauth-worker.md, web-admin-deployment.md, index.md) live at paths like /docs/vision, /docs/architecture, etc. None of the defined scope prefixes cover these paths. When any scope pill is active, these pages become unreachable in search. The PR's own docs/doc-site.md update states "Every docs/ subfolder that produces rendered pages must appear in at least one scope" — root-level files violate this stated invariant. See also: [intent-alignment] finding at this location.
    Remediation: Add a catch-all scope (e.g., "Concepts" covering root-level paths) or include these paths in an existing scope.

  • [protected-path] AGENTS.md — This PR modifies AGENTS.md, which is a protected governance file. The change adds guidance about search scope configuration, which is authorized by the linked issue Add folder-based filter to docs search #5630. Human approval is always required for protected-path changes, regardless of context.

Low

  • [intent-alignment] website/.vitepress/config.ts:611 — Issue Add folder-based filter to docs search #5630 requests per-folder filtering with 10 specific top-level doc folders listed individually. The implementation groups them into 4 aggregate scopes (Guides, Design Docs, Experiments, Contributing), so users cannot filter to just ADRs or just problems independently. The scope configuration is data-driven, making per-folder scopes trivial to add later. See also: [logic-error] finding at this location.
    Remediation: Confirm with the issue author that 4-scope grouping is the intended UX, or provide per-folder scopes as originally requested.

  • [dead-config] website/.vitepress/config.ts:625 — The Contributing scope includes the prefix /docs/testing/, but srcExclude contains **/testing/**, which prevents any file under docs/testing/ from being built. The prefix will never match a rendered page.

  • [script-attribute-ordering] website/.vitepress/theme/components/VPLocalSearchBox.vue:1 — The script tag uses <script lang="ts" setup> but existing Vue components in this repo use <script setup lang="ts">. However, this is a vendored upstream file and matching upstream's attribute order minimizes diff noise during future VitePress upgrades.

  • [type-duplication] website/.vitepress/search.d.ts:6 — The scope shape { label: string; prefixes: string[] } is defined inline here and also as the named SearchScope interface in searchScopes.ts. Since this is a module-augmentation .d.ts file, adding a runtime import would change the file's semantics — the duplication is pragmatic.

Previous run

Review

Findings

Medium

  • [intent-alignment] website/.vitepress/config.ts:346 — The implementation groups 10 individual doc folders into 3 scopes (Guides, Design Docs, Experiments), but issue Add folder-based filter to docs search #5630 requests per-folder filtering. Users cannot filter to only ADRs or only problems independently. The scope configuration is data-driven so adding granular scopes later is trivial.
    Remediation: Confirm with the issue author whether 3-scope grouping is the intended UX, or provide per-folder scopes as requested.

Low

  • [architectural-coherence] website/.vitepress/theme/components/VPLocalSearchBox.vue — The PR copies VitePress's VPLocalSearchBox.vue (929 lines) with imports from internal paths (vitepress/dist/client/theme-default/support/lru, vitepress/dist/client/shared) that are not part of VitePress's public API and may break across releases. Consider adding a provenance comment noting the upstream source and VitePress version, and documenting the update strategy.

  • [script-attribute-ordering] website/.vitepress/theme/components/VPLocalSearchBox.vue:1 — The script tag uses <script lang="ts" setup> but existing Vue components in this repo (ReadingProgress.vue, Mermaid.vue) use <script setup lang="ts"> (setup before lang).

  • [type-safety] website/.vitepress/theme/components/VPLocalSearchBox.vue:101 — Uses as any type assertion to access theme.value.search.options?.scopes. A narrower type assertion or module augmentation of VitePress's DefaultTheme.LocalSearchOptions would preserve type safety.

Previous run (2)

Review

Findings

Medium

  • [intent-alignment] website/.vitepress/config.ts:346 — The implementation groups 10 individual doc folders into 3 scopes (Guides, Design Docs, Experiments), but issue Add folder-based filter to docs search #5630 requests per-folder filtering. Users cannot filter to only ADRs or only problems independently. The scope configuration is data-driven so adding granular scopes later is trivial.
    Remediation: Confirm with the issue author whether 3-scope grouping is the intended UX, or provide per-folder scopes as requested.

  • [edge-case] website/.vitepress/config.ts:356 — The prefix "/docs/spikes" is missing a trailing slash, unlike all other prefixes (e.g., "/docs/guides/", "/docs/ADRs/"). The filter uses r.id.startsWith(p), so "/docs/spikes" would also match any future path starting with that string (e.g., /docs/spikestorm/).
    Remediation: Change "/docs/spikes" to "/docs/spikes/".

  • [maintenance-burden] website/.vitepress/theme/components/VPLocalSearchBox.vue — This PR copies VitePress's VPLocalSearchBox.vue (928 lines) with imports from internal paths (vitepress/dist/client/theme-default/support/lru, vitepress/dist/client/shared) that are not part of VitePress's public API and may break across releases.
    Remediation: Add a provenance comment at the top noting the upstream source, version forked from, and a link to the original.

Low

  • [edge-case] website/.vitepress/theme/components/VPLocalSearchBox.vue:250formMarkRegex produces new RegExp("", "gi") when the terms Set is empty, matching every empty-string boundary. Impact is minimal (matches upstream behavior), but a terms.size > 0 guard is a one-line fix.

  • [XSS] website/.vitepress/theme/components/VPLocalSearchBox.vue:545 — Three v-html directives (lines 545, 549, 555) render search result data without sanitization. Data originates from the build-time MiniSearch index (not runtime user input), matching upstream VitePress behavior exactly.


Labels: PR adds search scoping feature to the VitePress documentation site

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment component/docs User-facing documentation type/feature New capability request labels Jul 29, 2026
@rh-hemartin
rh-hemartin force-pushed the fix/5630-docs-search-scopes branch from 7598df0 to 062e993 Compare July 29, 2026 09:41
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 29, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 9:42 AM UTC · Completed 10:00 AM UTC
Commit: 062e993 · View workflow run →

fullsend-ai-review[bot]

This comment was marked as outdated.

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the scoped search filter changes. Left inline comments covering keyboard/screen-reader accessibility of the new scope toggles, undeclared dependencies pulled in only via hoisting, a TypeScript excess-property gap on the new config field, missing test coverage for the filter predicate, an overly broad stylelint rule disable, and a docs folder left out of every search scope.

Comment thread website/.vitepress/theme/components/VPLocalSearchBox.vue Outdated
Comment thread .stylelintrc.json Outdated
Comment thread website/.vitepress/config.ts
Comment thread website/.vitepress/theme/components/VPLocalSearchBox.vue Outdated
Comment thread website/.vitepress/theme/components/VPLocalSearchBox.vue
Comment thread website/.vitepress/config.ts
@rh-hemartin
rh-hemartin force-pushed the fix/5630-docs-search-scopes branch 2 times, most recently from 33bb3e6 to 2a980ee Compare July 29, 2026 14:43
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 29, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 2:43 PM UTC · Ended 2:44 PM UTC
Commit: 33bb3e6 · View workflow run →

@fullsend-ai-review

fullsend-ai-review Bot commented Jul 29, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 2:45 PM UTC · Completed 2:59 PM UTC
Commit: 2a980ee · View workflow run →

@fullsend-ai-review fullsend-ai-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the review comment for full details.


Note: The following inline comments could not be posted on the diff (GitHub returned 422) and are included here instead:

  • website/.vitepress/config.ts (file-level): Line 611 · [medium] logic-error

Top-level docs pages (vision.md, architecture.md, runtimes.md, glossary.md, roadmap.md, landscape.md, doc-site.md, admin-oauth-worker.md, web-admin-deployment.md, index.md) live at paths like /docs/vision, /docs/architecture, etc. None of the defined scope prefixes cover these paths. When any scope pill is active, these pages become unreachable in search. The PR's own docs/doc-site.md update states 'Every docs/ subfolder that produces rendered pages must appear in at least one scope' — root-level files violate this stated invariant.

Suggested fix: Add a catch-all scope (e.g., 'Concepts' covering root-level paths) or include these paths in an existing scope.

  • website/.vitepress/config.ts (file-level): Line 611 · [low] intent-alignment

Issue #5630 requests per-folder filtering with 10 specific top-level doc folders listed individually. The implementation groups them into 4 aggregate scopes (Guides, Design Docs, Experiments, Contributing), so users cannot filter to just ADRs or just problems independently. The scope configuration is data-driven, making per-folder scopes trivial to add later.

Suggested fix: Confirm with the issue author that 4-scope grouping is the intended UX, or provide per-folder scopes as originally requested.

  • website/.vitepress/config.ts (file-level): Line 625 · [low] dead-config

The Contributing scope includes the prefix /docs/testing/, but srcExclude contains /testing/, which prevents any file under docs/testing/ from being built. The prefix will never match a rendered page.

  • website/.vitepress/theme/components/VPLocalSearchBox.vue:1: [low] script-attribute-ordering

The script tag uses <script lang="ts" setup> but existing Vue components in this repo use <script setup lang="ts">. However, this is a vendored upstream file and matching upstream's attribute order minimizes diff noise during future VitePress upgrades.

  • website/.vitepress/search.d.ts:6: [low] type-duplication

The scope shape { label: string; prefixes: string[] } is defined inline here and also as the named SearchScope interface in searchScopes.ts. Since this is a module-augmentation .d.ts file, adding a runtime import would change the file's semantics — the duplication is pragmatic.

@rh-hemartin
rh-hemartin force-pushed the fix/5630-docs-search-scopes branch from 2a980ee to 68572ad Compare July 29, 2026 15:23
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 29, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 3:25 PM UTC · Ended 3:37 PM UTC
Commit: 68572ad · View workflow run →

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated multi-agent review pass (3 independent reviewers: 2x Claude, Grok). Left 3 new inline findings below (1 high, 2 medium) plus a reply flagging that an earlier "resolved" thread's underlying bug is still present in the current code.

Two other findings from this pass — root-level docs pages becoming unreachable under a scope filter, and a dead /docs/testing/ prefix — were already fixed by the latest push before I could post them. No action needed there.

Comment thread website/.vitepress/theme/components/VPLocalSearchBox.vue
Comment thread .stylelintrc.json
Comment thread website/.vitepress/theme/components/VPLocalSearchBox.vue
Override VitePress's VPLocalSearchBox with scope pills that filter
search results by path prefix. Extract the filtering predicate into a
tested utility. Add a vitepress type augmentation for the scopes config
field. Make scope checkboxes keyboard-accessible and visible to
assistive tech. Scope stylelint exemptions to inline comments instead
of global rule disables. Declare hoisted vitepress transitive deps
explicitly in website/package.json.

Closes #5630

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Hector Martinez <hemartin@redhat.com>
@rh-hemartin
rh-hemartin force-pushed the fix/5630-docs-search-scopes branch from 68572ad to f958fcb Compare July 29, 2026 15:36
@fullsend-ai-review

fullsend-ai-review Bot commented Jul 29, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 3:39 PM UTC · Completed 3:55 PM UTC
Commit: f958fcb · View workflow run →

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both HIGH findings from the review pass are resolved and verified in code at f958fcb9:

  • Enter-key-on-checkbox navigation bug — fixed (checkbox inputs now excluded from the Enter handler's fallthrough)
  • Root-level pages unreachable under a scope filter — fixed earlier via the "Others" catch-all scope, with test coverage

The two MEDIUM findings from this pass are also addressed (vitepress pinned to exact 1.6.4, PR description corrected). One MEDIUM item remains open (hashless search-result id truncation) but it's inherited from upstream VitePress unchanged, has narrow reachability, and degrades gracefully — not blocking.

All CI checks pass. Approving.

@rh-hemartin
rh-hemartin added this pull request to the merge queue Jul 29, 2026
Merged via the queue into main with commit a486edd Jul 29, 2026
16 checks passed
@rh-hemartin
rh-hemartin deleted the fix/5630-docs-search-scopes branch July 29, 2026 15:47
@fullsend-ai-retro

fullsend-ai-retro Bot commented Jul 29, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ❌ Failure · Started 3:50 PM UTC · Completed 3:51 PM UTC
Commit: f958fcb · View workflow run →

@fullsend-ai-review

Copy link
Copy Markdown

Review skipped — this PR is already merged.

The /fs-review command only reviews open pull requests.

Posted by fullsend post-review check

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/docs User-facing documentation requires-manual-review Review requires human judgment type/feature New capability request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add folder-based filter to docs search

2 participants