Resolves what action to take when a user selects a search result, returning one of five typed discriminated union variants for the caller to handle via a single `switch`. ## Key Components ### `SearchResultAction` (type) Discriminated union with five variants: | Kind | Payload | Triggered when | |---|---|---| | `navigate-same-tab` | `href: string` | External URL, same-platform navigation | | `navigate-new-tab` | `href: string` | External URL, cross-platform navigation | | `ask-ai` | `{ source, ref: ChatRef }` | Row has `id`, `sourceRepo`, and `documentType` | | `route` | `path: string` | Row has only a `path` (legacy fallback) | | `noop` | — | Nothing actionable found | ### `resolveSearchResultAction(result, source, runtimeMode?)` (function) Pure function — no React, no side effects, no telemetry. Evaluates `result.metadata` in priority order: 1. **`externalUrl`** → delegates to `decideNewTab` using `targetPlatform`, `runtimeMode`, and `source` as `currentSource` 2. **`id` + `sourceRepo` + `documentType`** → returns `ask-ai` with a `ChatRef` entity reference 3. **`result.path`** → returns `route` for legacy path-based navigation 4. **Fallthrough** → returns `noop` ## Usage Example ```typescript import { resolveSearchResultAction } from './resolve-search-result-action' const action = resolveSearchResultAction(searchResult, 'my-source', 'host') switch (action.kind) { case 'navigate-same-tab': router.push(action.href) break case 'navigate-new-tab': window.open(action.href, '_blank') break case 'ask-ai': chat.openWithRef(action.detail.ref) break case 'route': router.push(action.path) break case 'noop': break } ``` > **Source:** [`resolve-search-result-action.ts`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/resolve-search-result-action.ts) — lifted from the hub's `hooks/use-docs.ts` and extracted as a standalone pure utility.