Flow Search logo

Flow Search

Community
jpoindexter
flow-search

Use when designing or reviewing search or filtering — placing a search box, building typeahead/autocomplete, faceted filters with chips, a results page, or scoped/command-palette search. Also applies when users report zero-result dead ends, can't find items they know exist, filters that reset unexpectedly, or a catalog/list too large to browse.

Overview

Publisherjpoindexter
Repositoryux-flow-skills
Skill nameflow-search
Stars
5
Forks
0
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by jpoindexter on GitHub. Read the source before you install it.

Installation

Install the Flow Search AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/jpoindexter/ux-flow-skills/tree/main/skills/flow-search
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/jpoindexter/ux-flow-skills.git /tmp/ux-flow-skills
mkdir -p .claude/skills
cp -r /tmp/ux-flow-skills/skills/flow-search .claude/skills/flow-search
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Flow Search in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Flow Search on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Flow Search is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Search & Filtering Flows

Overview

Search is a conversation: the user offers an imperfect query and the system must always move them forward — suggest while typing, tolerate typos, never answer with a dead end. Filters narrow; search finds; the proven products (Amazon, Airbnb, Google) combine both and keep every applied constraint visible and removable.

When to Use

  • Adding search to an app or catalog with more items than users will browse (>~50)
  • Building typeahead/autocomplete, faceted filtering, or a results page
  • Fixing "no results" dead ends, typo intolerance, or filter state loss
  • Deciding instant vs submit search behavior, or adding scoped/⌘K search
  • Users say "I searched for X and it's not there" about content that exists
  • Reviewing a filter UI where users don't understand why results are limited
  • NOT for picking one value from a short known set — that's a select/combobox
  • NOT for navigation structure between destinations (see flow-navigation)

The Proven Flow

  1. Search box.
    • Magnifying-glass icon inside the field; placeholder states the scope ("Search orders…", never bare "Search").
    • Placement: header, center or right-of-center for search-centric products (Amazon, Airbnb, GitHub); local search sits directly above the list it filters.
    • Mobile: search as a tab-bar destination or a header icon expanding to a full-width field with autofocus + keyboard raised.
    • Web apps: / or ⌘K focuses search from anywhere.
    • Commerce mobile adds barcode/camera and voice entry inside the field (Amazon) — only when the catalog justifies it.
  2. Instant vs submit.
    • Instant (filter-as-you-type): bounded local datasets — lists, tables, settings, sidebars. Debounce 150–300ms; results update in place; no Enter needed. Linear, Notion, iOS Settings.
    • Submit (Enter → results page): open-ended corpus search where a query has real cost and results deserve a dedicated page. Google, Amazon. Typeahead still fires while typing; Enter commits.
    • Hybrid is the norm for big products: instant suggestions, submitted results page.
  3. Typeahead anatomy (dropdown under the field, in this order):
    • ① Recent searches — shown on focus before typing, each with its own × and a "clear all". Respect privacy: local-first, clearable.
    • ② Query suggestions/completions — matched substring bolded.
    • ③ Direct entity hits — icon/thumbnail + name + type label ("Nike Air Max — Product"); Enter on one goes straight to the entity, skipping the results page.
    • ④ "Search for '⟨query⟩'" as the last row and the Enter default.
    • Max ~8 rows; keyboard ↑↓ + Enter; Esc dismisses; keyboard selection wins until the mouse moves.
    • Suggestions must respond <100ms perceived — precompute or cache; a slow typeahead is worse than none.
    • Amazon and Airbnb prove this exact stack.
  4. Results page anatomy (top → bottom):
    • Search box stays populated with the query, editable — search is iterative, users refine.
    • Result count + sort control right-aligned: "1–24 of 312 · Sort: Relevance". Alternatives: newest, price, rating — relevance is the default for queries, recency for browsing.
    • Filter rail (desktop, left 240–280px) or filter button with count badge (mobile).
    • Applied-filter chips row directly above results.
    • Results as list rows (documents/records: title + snippet with matched terms highlighted + metadata) or card grid (visual goods).
    • Load-more or pagination at the bottom — infinite scroll only for discovery feeds.
  5. Faceted filtering.
    • Facets derive from result attributes, each value showing its count: "Brand · Nike (43)". Hide or disable zero-count values — they are guaranteed dead ends.
    • Applied filters render as chips — each removable with ×, plus "Clear all" once ≥2 active. Chips are the single source of truth for "why am I seeing this."
    • Desktop: results update immediately on facet change. Mobile: the filter sheet batches changes behind an explicit "Show 128 results" button so results don't shift under the sheet mid-selection — Airbnb's pattern.
    • The filter trigger carries a count badge ("Filters · 3") so hidden state is never invisible.
    • Multi-select within a facet = OR; across facets = AND. Ranges (price, date) get a dual-handle slider or min/max inputs.
    • Order facets by usage, not alphabet; the top 2–3 facets do most of the narrowing (category, price, availability).
    • Persist query + filters in the URL (?q=boots&brand=nike&size=10) — shareable, refresh-safe, back-button-correct.
    • Facet/chip toggles use replaceState; only new query submissions push a history entry — back returns to the previous query, not through every chip toggle.
  6. Zero-results recovery — never dead-end. In order of preference:
    • Fix it silently: spell-correct and show corrected results — "Showing results for sneakers. Search instead for snekers" (Google). Fuzzy matching, stemming, and synonym expansion run before zero is ever shown.
    • Broaden automatically: relax the least-important constraint and say so — "No exact matches. Removing color: green shows 14 results" — or show partial matches labeled as such (Amazon).
    • Offer exits: name which applied filters are killing results with one-tap removal; suggest related/popular queries; link to browse categories.
    • The zero-results page always contains at least one tappable path forward.
    • Log zero-result queries — they are the top backlog for synonyms and content.
  7. Scoped search.
    • Scope selector attached to the field (dropdown left of the input) or scope tabs on the results page: All / Docs / People / Issues — GitHub, Slack.
    • Default to the user's current context ("this channel", "this project"); widening to "everywhere" is one visible tap.
    • Always show which scope produced the results. If the current scope has 0 but a wider scope has hits, say so: "No matches in #design — 12 in all channels".
  8. Command palette as search (⌘K).
    • Unifies navigation + actions + entity search in one input; same typeahead anatomy with groups Recent → Actions → Results-by-type.
    • Prefix operators scope it: > commands, # channels, @ people (Slack / VS Code convention).
    • It complements the visible search box for power users; it never replaces it.

Ranking & relevance defaults

  • Rank: exact match > prefix match > fuzzy match; title/name hits above body hits; recent and popular items boosted.
  • Personal scope first in app search: the user's own items outrank global items with an equal text score (Slack, Notion).
  • Detect obvious intents: an order ID, email, or URL pasted into search jumps straight to the entity, skipping results.
  • Recency vs relevance: time-sensitive corpora (news, messages) default to recency; catalogs and docs default to relevance.
  • App-wide search groups results by type with counts and a "See all N" per group — Spotlight, Slack.

Layout & Structure

  • Search field: 40–48px tall in a desktop header, ≥44pt on mobile; expanded width 480–680px for search-first products; icon left inside the field.
  • Clear-× appears as soon as text is entered — mandatory on touch, where clearing by backspace is punishing.
  • Typeahead dropdown: matches field width (min 320px); max ~8 visible rows; distinct hover and keyboard-selection states; group headers labeled.
  • Filter rail (desktop): 240–280px left column; facets as collapsible groups, most-used first; 5–7 values visible per facet + "Show more"; checkboxes with counts.
  • Long facet lists (brands, tags) get their own mini search-within-facet input once values exceed ~15.
  • Mobile filter sheet: full-height or 90% bottom sheet; facet list with inline expanders or per-facet screens; sticky footer with "Clear all" (left, secondary) + "Show N results" (right, primary).
  • Sort lives in the same sheet or its own visible control — never buried two levels deep.
  • Chips row: directly above results; wraps to max 2 lines then "+3 more"; chip = field + value + × ("Brand: Nike ×").
  • Results list row: title (link-styled) + 1–2 line snippet with matched terms bolded + metadata line (date, type, path).
  • Card grid for visual goods: image top, 2–4 columns, price/title below; consistent image aspect ratio per grid.
  • Result count always visible — it's how users judge whether to narrow or broaden.
  • Latency budgets: typeahead <100ms perceived; results <1s; show skeletons past ~300ms; never blank existing results while new ones load — replace on arrival.
  • Highlighting: bold the matched substring in both suggestions and snippets; it is the user's primary relevance check.
  • Empty-query search page (search tab opened, nothing typed): recent searches + trending/popular + browse categories — never a blank screen.
  • Keyboard: full flow operable without a mouse — focus search (/), arrow through suggestions, Enter to commit, Tab into filters.
  • Announce result-count changes to screen readers (aria-live polite) when filters update results in place.
  • Min query length: instant search fires from 1 character for local lists, 2–3 characters for remote-backed search.
  • Did-you-mean row: directly above results, link-styled correction, one tap to re-run — never below the fold.
  • Results scroll: preserve position when results update in place; focus stays in the field while typing.
  • Applied chips on mobile: horizontally scrollable row under the search bar, filter button pinned at its left.
  • Voice/barcode affordances (commerce mobile): inside the field's right edge, placed before the clear-×, each ≥44pt.
  • Back to results: returning from a result restores query, filters, sort, and scroll position — the single most common search rage point.

Quick Reference

SituationPattern
Bounded local list/tableInstant filter-as-you-type, debounced 150–300ms
Open-ended corpusTypeahead + submit → results page
Field focused, nothing typedRecent searches + popular queries
Search tab opened, no queryRecents + trending + browse categories
Likely typoAuto-correct, "showing results for…" with undo link
Zero resultsCorrect → broaden → suggest; never a dead end
Result set too bigFaceted filters with counts + chips
Facet with >15 valuesSearch-within-facet input
Mobile filteringBottom sheet, batch-apply "Show N results", badged trigger
Search within a contextScoped search; default current scope, one tap to widen
Current scope empty, wider scope has hitsSay so, with a one-tap scope switch
User types an exact entity nameEntity hit in typeahead, Enter goes direct
Power users, mixed nav/actions/search⌘K palette with prefix operators
Sharing/bookmarking a filtered viewQuery + filters in the URL
Deciding what to fix nextZero-result query logs
User pastes an ID / email / URLDetect intent; jump straight to the entity
News / messages corpusDefault sort: recency
Product / docs catalogDefault sort: relevance
App-wide search across typesGrouped results + "See all N" per type
Remote-backed instant searchFire at 2–3 chars, debounce 150–300ms
Returning from a resultRestore query, filters, and scroll position

Anti-Patterns

Anti-patternWhy it breaksFix
"No results found." full stopDead end; the user leavesCorrect, broaden, suggest — always ≥1 tappable exit
Exact-match-only searchTypos and plurals return zero for content that existsFuzzy match + stemming + synonyms before showing zero
Query cleared on the results pageUser can't iterate on their own queryKeep the query in the box, editable
Filters hidden behind an unbadged iconUsers forget filters are active and distrust resultsChips row + count badge on the trigger
Mobile sheet applying every tap instantlyResults shift under the sheet; disorientingBatch behind "Show N results"
Facet values with zero results selectableA guaranteed dead end one tap awayHide or disable zero-count values
Search state lost on back/refreshUsers rebuild query + filters repeatedlyEverything in the URL
Placeholder "Search" with no scopeUsers can't predict what's searchableName the scope: "Search 12k products…"
No clear-× in the fieldClearing on touch takes a dozen backspacesShow × whenever text is present
Typeahead >10 rows or unrankedChoice overload defeats the accelerator≤8 rows, best matches first, labeled groups
Slow (>300ms) typeaheadSuggestions arrive after the user has typed past themPrecompute/cache; drop typeahead if it can't be fast
⌘K palette replacing the visible search boxUndiscoverable for the majority of usersPalette accelerates; the box stays
Blanking results while the next query loadsUsers lose their comparison contextKeep stale results; swap on arrival
Alphabetical facet orderingThe 2–3 facets that matter sit below the foldOrder by narrowing power/usage
Ignoring zero-result query logsThe same failures repeat foreverReview logs; add synonyms/content for top misses
Back from a result losing the results page stateUsers re-run the whole search per resultRestore query, filters, sort, scroll
Global items outranking the user's own"My doc" buried under strangers' docsBoost personal scope in app search
One flat list mixing people/docs/messagesUsers can't scan across typesGroup by type with counts
Remote search firing from character 1Wasted queries; flickering results2–3 char minimum + debounce

Frequently asked questions

What does the Flow Search AI skill do?

Use when designing or reviewing search or filtering — placing a search box, building typeahead/autocomplete, faceted filters with chips, a results page, or scoped/command-palette search. Also applies when users report zero-result dead ends, can't find items they know exist, filters that reset unexpectedly, or a catalog/list too large to browse.

Why use Flow Search on TypingMind?

Because you install it once and use it with any model. Flow Search is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Flow Search in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/jpoindexter/ux-flow-skills/tree/main/skills/flow-search. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Flow Search?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Flow Search?

As many as you like. As long as a model supports skills, you can use Flow Search with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Flow Search AI skill free?

Yes. It is published on GitHub by jpoindexter under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇