⌘F finds the cell, not just the row
A real find-in-sheet: every match highlighted, Enter walks through them, and the grid jumps straight to the cell.
- NewFind in sheet (⌘F): type to see every matching cell highlighted with a live count, press Enter / ⇧Enter to walk through matches (wrapping around), and the grid scrolls the current match into view and puts the cursor on it — unlike row search, it never changes what rows you see.
Undo is here: ⌘Z takes cell edits back
Fat-fingered a cell or cleared one by accident? ⌘Z puts it back — and email addresses in computed cells are now clickable.
- NewUndo/redo for cell edits: ⌘Z reverses your last edit (including clearing a cell with Delete), ⌘⇧Z brings it back — up to 200 steps per sheet, with ↶ ↷ buttons in the statusbar and a notice naming the column that changed.
- NewEmail addresses in computed cells are clickable mailto links, matching how URLs already behave.
Guides, real 404s & privacy-friendly analytics
Four in-depth guides join the public site, unknown URLs return honest 404s, and self-hosted analytics measure the funnel without tracking app users.
- NewA guides section at /guides/: what data enrichment is, how waterfall enrichment works, every email verification status explained, and a step-by-step lead-list playbook — cross-linked from every public page.
- NewSelf-hosted, first-party analytics (Umami) for the public site: page views and signup conversions, no third-party trackers, no cookies — and logged-in app usage is never tracked.
- ImprovedUnknown URLs now return a real 404 with a branded page instead of silently serving the app shell — search engines stop indexing junk paths.
The model picker knows what your server has
The model list now syncs live with your provider — pull a model on Ollama and it appears in the picker, no update required.
- NewLive model catalog: opening the model picker asks the provider what models actually exist (your Ollama server's installed models, or the account catalog for hosted providers with a key) and lists them under the curated ones — "on the server".
- FixedThe security hardening in 0.35.1 accidentally blocked the ✨ AI-assist from using a local Ollama server (private LAN addresses were rejected). Self-hosted LLM endpoints are now explicitly allowlisted by the operator while everything else stays blocked.
Hardening pass: filters, dialogs & server-side safety
Number filters survive messy data, dialogs behave (Escape, focus return), and every server-side fetch now blocks internal addresses.
- FixedNumber filters (>, <, between) no longer fail the whole view when a column contains non-numeric text like "N/A" or "$1k" — rows that aren't numeric simply don't match. Text filters now treat % and _ literally, and "equals" matches case-insensitively like the rest of the text operators.
- ImprovedDialogs and side panels close with Escape and return focus to where you were; view tabs, rename/delete controls and close buttons are now real, keyboard-operable buttons with screen-reader labels.
- FixedColumn widths no longer leak between sheets — each sheet reloads its own saved layout when you switch.
- ImprovedSecurity hardening under the hood: all server-side URL fetches (HTTP columns, agent page reads) block private and cluster-internal addresses via one shared guard, secrets can no longer be smuggled in through cell values or echoed back in error messages, and imports with many new columns build the column graph once instead of per column.
- FixedThe filter panel stays in sync when a saved view or error-badge click changes the filter externally, sign-up emails match case-insensitively, and a broken workspace load now shows an error with retry instead of a blank sidebar.
Model guidance for every provider & smarter key handling
Hover guidance now covers hosted models too, deleted keys warn instead of failing silently, and HTTP headers get one-click key insertion.
- NewThe model picker's hover guidance now covers every provider — OpenAI, Anthropic, Grok, Groq and OpenRouter models show what each is good for, context window, speed, tool support, and a relative cost tier ($ to $$$), not just the local Ollama models.
- NewHTTP columns (and waterfall HTTP steps) show your saved keys under the headers editor — one click inserts the {{secret:REF}} auth header instead of hand-typing template syntax.
- FixedA column whose API key was deleted from the workspace now shows an amber "key missing" warning with a one-click reconnect, instead of claiming it's connected and failing at run time.
A bigger front door: solution pages, public changelog & a real sign-in
The public site grows from one page to five, the changelog goes public, and signing in finally looks like the product it opens.
- NewSolution pages for lead enrichment, AI research agents, and email verification — deep, crawlable pages at /lead-enrichment/, /ai-research-agents/, and /email-verification/, cross-linked from the landing page.
- NewPublic changelog at /whats-new/ — generated straight from this changelog on every build, so search engines (and curious prospects) see what's shipping without signing in.
- ImprovedThe sign-in page got a full redesign: split brand panel, proper input styling, autocomplete hints, and a direct path between "Create account" and "Sign in" modes.
- ImprovedExpanded sitemap and a security.txt contact file for responsible disclosure.
API keys without the dropdown archaeology
Pick a provider and the right key just connects — paste it once, inline, and every column knows about it.
- NewPaste-to-connect API keys: when a provider has no key yet, the column editor shows a paste field right there — one paste stores it encrypted in the workspace under the provider's conventional name and connects it. No more separate secrets trip + dropdown hunt.
- NewPicking a provider now implies its key: chips show a green dot when a provider is ready to run (key connected, or none needed for local Ollama), and selecting one auto-connects its workspace key.
- ImprovedConnected keys show as a clear status pill with replace / switch / remove — and local providers say plainly that no key is needed.
- ImprovedAgent extras are now honest about being optional: web search and proxies explain what the free default does and what a key upgrades, instead of presenting a bare secret dropdown.
- ImprovedThe Secrets modal is now "API keys & secrets": each key is labeled with what it's for, and adding one is guided by purpose (provider, web search, proxies, custom).
A real front door: public site & SEO
liquidrows.com now greets logged-out visitors with a proper marketing page, and search engines finally see what the product is.
- NewPublic landing page at the root domain for logged-out visitors: product story, feature tour, how-it-works, and FAQ — served as static HTML so search engines index it without running the app.
- NewSearch & social metadata: page title and description, Open Graph / Twitter share cards with a branded image, structured data (Organization, SoftwareApplication, FAQ), robots.txt and a sitemap.
- NewBranded favicon — the app finally has a face in browser tabs and search results.
- ImprovedLanding "Get started" buttons open the signup form directly (/login?mode=register), and the login page is excluded from search indexing.
Per-cell runs, right-click run options & agent reliability
Run a single cell or a range of rows, right-click a column for run options, plus grid and agent fixes.
- NewHover any enrichment cell for a ▶ button that runs just that cell — no need to run the whole column to fill or retry one row.
- NewRight-click a column header for run options: run empty cells only, run a specific range of rows (a count starting from row N), or force-run all rows (overwrites existing data, with a confirmation).
- ImprovedThe cell details panel now re-runs just that one cell and shows it live, instead of silently re-running the whole row.
- FixedAgent columns no longer occasionally leak an intermediate "I'll search again" message as the answer — the agent gets dedicated final attempts to commit, and pure narration is recorded as not-found.
- FixedColumn headers stay aligned with their cells when the grid is scrolled all the way to the right.
Local Ollama models + guided model picker
Run AI/agent columns on your own Ollama server, and pick the right model with hover-over guidance.
- NewThe model dropdown now shows guidance on hover — what each model is good for, plus stats (parameters, context window, VRAM fit, and whether it supports the tool-calling that agent columns require) — so it is easy to pick the right one.
- NewOllama provider preset points at the local server and lists every installed model, tagged by tool-calling support.
- ImprovedNew AI and agent columns default to the local Ollama host.
- FixedGrid header and body no longer drift out of alignment when a vertical scrollbar appears.
MillionVerifier email verification
One-click email verification: load the MillionVerifier starter on an HTTP column.
- NewNew built-in enrichment "Verify email (MillionVerifier)": pick it from the HTTP column templates, add your key as a workspace secret named MILLIONVERIFIER_API_KEY, and point it at your email column. The cell fills with the result (ok / catch_all / disposable / invalid / unknown), and you can map quality, free, role and did-you-mean into their own columns.
Bulletproof agent runs
Search engines fall back instead of failing, blank cells explain themselves, and spend limits now stop a run mid-flight.
- FixedWeb search now falls through the engine chain (Serper → SearXNG → DuckDuckGo) when an engine rejects a query or runs out of credits, instead of erroring the agent’s search. A drained Serper account no longer silently degrades a whole batch.
- ImprovedA cell the agent deliberately left blank now shows a subtle "not found" pill instead of looking like it never ran — and the cell drill-in explains the run in plain terms: outcome, answer, sources, and the step-by-step trace with real error reasons.
- ImprovedAnswers that come back slightly malformed (markdown fences, prose around the JSON, near-miss field names like CEO_Name vs ceo) are now tolerantly parsed and mapped instead of dropped.
- ImprovedThe per-sheet spend limit is now enforced mid-run by the worker: once hit, remaining queued cells stop (as retryable errors) instead of spending to the end of the queue.
- NewRun-quality telemetry: each agent run records its outcome (found / not found, search errors, format salvages) into the cost ledger, powering run-health reports.
OpenRouter support
- NewOpenRouter as an AI provider: one key for Claude, GPT, Gemini, Llama, DeepSeek, Grok and 300+ more — available in AI columns, agents, waterfall steps, and the ✨ assist. Pick it from the provider presets or use any openrouter model id via "Other…".
Spend limits per sheet
Set a spend ceiling on a sheet so a big run can't blow past your budget.
- NewSet a spend limit in Usage & costs: once a sheet hits it, bulk runs (Run column / Run sheet) are blocked with a clear message until you raise or clear it. Per-row auto-runs are unaffected. A guardrail against runaway agent/AI cost.
No duplicate rows from list agents
List-output agents can dedupe, so re-running never piles up duplicate rows.
- NewList-output agents (write-to-table) get a "Dedupe by field" option: items whose value already exists in the target column are skipped (case-insensitive), within a run and across re-runs — so you can safely re-run without creating duplicates.
Pilot runs: test on a few rows first
Run an agent or AI column on the first N rows before committing to the whole sheet.
- NewNew "Pilot…" button on a column: run it on just the first N rows (oldest first) to check quality and cost, then run the full sheet once you are happy. The smart way to start a big enrichment.
Agent citations + smoother long runs
Capture the URLs an agent used, and stop seeing false errors on slow test runs.
- NewAgent columns can write their source URLs into a column you pick — so every answer carries its citations for auditing or outreach.
- FixedTesting or single-running a slow agent no longer shows a timeout error: the run keeps going in the background and the cell fills in live when it finishes.
Agents can write rows to another sheet
One agent run can find a list of things and drop each as a new row in a target sheet.
- NewNew agent output mode "list -> rows in another sheet": ask an agent to find many items (competitors, locations, executives, products) and each result becomes a row in a sheet you choose, with fields mapped to its columns. The agent cell itself shows the count. New rows are added as data (not auto-run), and there is a per-run safety cap.
Vision: AI columns can see images
Point an AI column at a logo or screenshot URL and let a vision model analyze it.
- NewAI columns now take an optional Image URL (templated, e.g. {{logo_url}}). The image is fetched server-side and passed to the model, so vision-capable models (Grok 4.3, GPT-4o, Claude) can describe a logo, read a screenshot, or classify a product photo per row.
Workspace agent defaults
Set your model, key, proxies and search once — every new agent column starts ready.
- NewIn an agent column, "Save as default" stores the model, API key, proxy list and search settings for the workspace. New agent columns start pre-filled with them, so you only configure the boilerplate once.
Reliable JSON from AI columns
AI columns in JSON mode now return clean, parseable JSON far more consistently.
- ImprovedAI columns set to JSON output now ask the provider for guaranteed-valid JSON (on providers that support it) and tolerate models that wrap their answer in prose or ``` fences — so your column-mapped fields stop coming back empty when the model gets chatty.
See what your agents actually did
The usage panel now shows web activity per column, so agent spend is transparent.
- NewUsage & costs now breaks down agent web activity per column: how many web searches and page fetches ran, and how many fetches were served from cache — so you can see exactly what drove search/proxy spend on a run.
Run modes: retry only the rows you need
After a big run, re-run just the empty or errored rows instead of paying for all of them again.
- NewThe column editor now has "Run empty" and "↻ Retry errors" alongside "Run column" — so after a large agent or AI run you can re-process only the rows that failed or have no value, without re-spending on the ones that already succeeded.
Agent columns: caching, cost guard & starter templates
Faster, cheaper, easier agent enrichments — built for running thousands of rows.
- NewStarter templates for agent columns: pick "Company summary", "Company facts", "Funding & investors", "Find LinkedIn URL", or "Pricing model check" and the prompt, tools, and output fields are filled in for you.
- NewPer-row token budget: cap the tokens an agent may spend on a row — once it crosses the ceiling it commits its best answer instead of researching further. A safety net against runaway cost on big runs.
- ImprovedCross-row caching: pages and searches are cached, so a batch that keeps hitting the same sites or queries pays for each one once instead of once per row — big speedups and lower search/proxy spend.
- NewDomain controls: restrict an agent to specific source domains (e.g. only sec.gov + the company site) or block ones you never want it to read — applied to both search results and page fetches.
Rotating proxies for agent columns
Point agent columns at a proxy list to run big enrichments without IP blocks.
- NewAgent columns can rotate through a pool of proxies: add a workspace secret with a newline-delimited list (host:port or host:port:user:pass) and pick it in the agent editor — a secret named PROXY_LIST is used automatically.
- ImprovedSearch, page fetches, and headless renders each get a rotating IP, so the keyless web-search throttle lifts and large runs stop getting rate-limited or blocked.
- ImprovedDead or slow proxies cool down automatically and requests retry on a fresh one, so a few bad entries in the list never stall a run.
Agent columns — AI web research per row
Point an AI agent at every row: it searches, reads pages, and writes back verified answers.
- NewAgent columns: give a research task in plain English and the agent searches the web, reads pages, and fills the cell — with sources. Works with any AI provider you already use (BYOK).
- NewMulti-field answers: one agent run can fill several columns at once — define extra fields and each writes into the child column with that key.
- NewHonest "not found": when nothing can be verified the cell stays empty instead of guessing, so waterfalls and run-if conditions keep working.
- NewWeb search built in — keyless out of the box, or add a Serper.dev key as a workspace secret ("Search key" in the column editor) for Google-quality results.
- ImprovedCell drill-in on an agent column shows the full research trail: every search, every page read, and the committed answer.
- ImprovedJS-heavy pages render through a pooled headless-Chrome service; plain pages are fetched the fast, cheap way.
Cross-sheet lookups, public API & conditional formatting
Sheets can talk to each other — and so can your scripts.
- NewLookup columns: match a value from this row against another sheet and pull back any column — like VLOOKUP across sheets, recomputed on demand.
- NewPublic REST API: create personal access tokens (sheet ⋯ menu → API tokens) and call every endpoint with Authorization: Bearer lrt_… from scripts.
- NewConditional formatting: per-column color rules (contains / equals / </> / regex / empty) painted straight onto cells.
- NewRun history: the sheet ⋯ menu lists the last 50 runs — when, which column, what mode, how many rows.
- NewLive run progress per column: headers show a spinner with the number of cells still computing.
Excel, dark mode, multi-sort & the command palette
Working through the roadmap.
- NewImport Excel (.xlsx) workbooks — first worksheet, formulas resolved, same mapping dialog as CSV.
- NewMulti-column sort: add secondary sorts from the column menu; order shows on headers and chips, and saves into views.
- NewDark mode — toggle in the sidebar footer (◐) or from the palette.
- New⌘K command palette: jump to any sheet, create sheets, toggle theme, and more.
- NewPrompt library: save an AI column setup once, load it in any sheet of the workspace.
- NewNumber & date pipes: num, round, add, mul, age.
- NewColumn descriptions shown on header tooltips (editing one no longer marks cells stale).
- ImprovedView tabs show live row counts; import header preview now happens server-side for perfect parity with the import itself.
Run control, scheduling & data tooling
The operations release — see ROADMAP.md for where this is heading.
- NewRun modes: run a column on every row, on empty cells only, or retry just the errors — plus a Cancel button to stop an in-flight run.
- NewError badges on column headers show failing-cell counts; click one to filter to those rows.
- NewAuto-refresh schedules (hourly / daily / weekly) recompute empty, stale, and errored cells — set it from the new sheet ⋯ menu.
- NewDuplicate a sheet (columns, views, and optionally all rows) from the ⋯ menu.
- NewFind & replace across a text column (plain or regex) from the column menu.
- NewNew pipes: domain, urlencode, split, slice, len — extract domains from emails/URLs, build query strings, pick name parts.
- NewSelection bar: copy selected rows as CSV, duplicate selected rows.
- ImprovedLinks in computed cells are clickable; row-height toggle (compact/comfortable); the last active view is remembered per sheet; built-in HTTP starter templates; webhook-intake sheet template.
Faster runs
- ImprovedBig column runs feel dramatically smoother: live cell updates are batched in the grid instead of re-rendering per cell, worker throughput is 3× higher, and per-row metadata fetches are cached during a burst.
- FixedFormula runs no longer write zero-cost entries to the usage ledger.
Column-level text & popover fix
- NewText columns now have "Column text" when editing too: a plain string fills every row, /variables make a per-row sentence — no more typing the same value 2,800 times. Cells stay hand-editable when it's left empty.
- FixedThe ✨ AI panel opens toward whichever side has room, so the run-if assist no longer renders off-screen.
Text with variables & AI button polish
- NewText columns can start with content: type a sentence with / variables and every row renders it (left empty, cells stay blank and editable).
- FixedThe ✨ AI assist now looks like a button and its panel opens inside the drawer instead of off-screen.
Slash variables, regex, AI assist & more
The enrichment-builder release.
- NewType / in any template field (formulas, AI prompts, HTTP URLs and bodies, run-if) to insert a column with autocomplete.
- NewRegex in templates and conditions: {{col | test "pattern"}}, {{col | match "pattern"}}, {{col | replace "pattern" "repl"}} — test pairs with run-if for conditional runs.
- New✨ AI assist on formula and run-if fields: describe the condition in plain English and your own provider writes the expression.
- NewModel dropdowns per provider with an "Other…" override, plus Grok (xAI) support.
- NewHTTP call templates: save a configured call once, load it in any sheet of the workspace.
- NewDelete a workspace (type "delete workspace" to confirm — unrecoverable).
- FixedFormula columns now compute for existing rows immediately on save instead of sitting empty.
- ImprovedColumns are now called enrichments where you create them.
Smarter CSV import into existing sheets
Append or replace, map to existing columns, skip what you don’t want.
- NewImporting into a sheet that already has rows now offers Append or Replace-all, like Google Sheets.
- NewCSV columns auto-match existing columns by name; each can be mapped, created fresh, or skipped — with "create all new" / "skip all" shortcuts.
- ImprovedThe import dialog stays open with a clear progress indicator while large files upload and process, instead of silently closing.
Large CSV imports
- FixedCSV uploads over 1MB were rejected by the web proxy with an unhelpful "Request failed" — imports up to 100MB now go through.
- ImprovedFailed requests now report their HTTP status instead of a generic message.
Header row fix
- FixedOn sheets with more rows than fit on screen, the frozen column-header row was squashed to half height and its labels clipped. It now keeps its full height regardless of row count.
Multi-line header fix
- FixedCSV headers containing line breaks inside quotes (common in scraper exports) were cut in half at import, garbling column names and misaligning the first rows — the header record now parses fully, with names whitespace-normalized end to end.
Import hygiene
- FixedCSV lines with no values (comma-only padding from scrapers and Excel) no longer import as broken empty rows at the top of the grid; values are also whitespace-trimmed.
- ImprovedThe import notice now reports how many rows came in and how many junk lines were skipped.
Waterfall columns & outbound push
Stack providers without paying for all of them.
- NewWaterfall columns: chain AI and HTTP steps — each step only runs if the previous one came back empty or failed, so you stop paying the moment one hits.
- NewPush results: a guided wizard builds an outbound HTTP column that POSTs your chosen fields as JSON to any webhook or CRM when rows run.
- ImprovedSorting is numeric-aware: number-like values order as numbers, text falls back to alphabetical.
CSV import fix
- FixedCSV files saved by Excel or Google Sheets (which add a hidden byte-order mark) imported the first column empty — the header now parses correctly so every column comes in.
Sorting, sharing, costs & smarter columns
The collaboration and control release.
- NewSort by any column from its header menu (server-side, empty cells last); the sort is part of saved views.
- NewShare: invite teammates to a workspace by email, manage roles, remove members — from the new Share button.
- NewUsage & costs: a Σ pill in the status bar opens a per-column spend breakdown from the cost ledger.
- NewColumn execution controls: toggle auto-run per column and add a "run if" condition (e.g. only when {{email}} is present).
- NewLead enrichment template: one click scaffolds a fresh sheet with data, formula, and AI columns.
- ImprovedDelete key clears the selected cell; a live "N running" counter shows cascade progress.
Frozen columns
- ImprovedRow numbers and the first column stay pinned while scrolling horizontally, with a shadow edge — the header row was already frozen vertically.
MVP: saved views, test runs & a real spreadsheet feel
The biggest release yet — the grid now feels like a real spreadsheet.
- NewSaved views: tabs above the grid that pin a filter + hidden-column set, shared with everyone on the sheet.
- NewTest a column on the first row from the editor — see the result (and the request) before running thousands of rows.
- NewKeyboard navigation: arrows move the cell cursor, Enter edits or opens details, Space selects the row, ⌘C copies the cell.
- NewColumn menus on every header: run, duplicate, hide, move, or delete without opening the editor.
- NewRow details drawer (⤢) showing every field of a record, editable in place.
- NewQuick search across all columns, evaluated server-side.
- NewCSV import mapping: match headers to columns and pick a dedup key before importing.
- NewAI provider presets (OpenAI, Anthropic, Groq, Ollama) for one-click column setup.
- NewCreate workspaces from the sidebar.
- ImprovedColumn headers show a fill-rate bar; empty sheets get a guided setup screen.
Versioning & changelog
The app now tells you what version you are on and what changed.
- NewVersion badge in the sidebar — click it to open this changelog.
- NewChangelog page with the full release history.
Filters, multi-select & sheet management
Work with slices of your data instead of the whole sheet.
- NewFilter bar: build conditions on any column (contains, is, between, empty…), cell status (including stale), and row source, combined with AND/OR — evaluated server-side.
- NewCSV export honors the active filter — export exactly what you see.
- NewRow multi-select with select-all and bulk Run / Delete on the selection.
- NewDrag column headers to reorder; the layout persists.
- NewRun a single column across all rows from the column editor.
- NewRename a sheet inline from the title; delete a sheet from the toolbar.
- Improved"Run all" reports how many rows were enqueued and asks for confirmation above the run ceiling.
Spreadsheet-native redesign
A complete visual and structural overhaul of the app.
- NewPersistent sidebar with workspace → sheet navigation and search.
- NewRight-side drawer panels for column config and cell details.
- NewVisual column type picker and colored type chips on every header.
- NewColumn delete from the editor drawer.
- ImprovedLight theme, Inter typography, breadcrumb topbar, status footer.
- ImprovedCell states: spinner while running, red pill on error.
Scale & observability
The grid handles 100k+ rows, and you can see exactly what each cell did.
- NewVirtualized grid — only visible rows render; pages load as you scroll.
- NewPer-cell drill-in: value, state, source, version, cost, and the captured AI/HTTP request + response.
- NewDrag-resizable columns with persisted widths.
- FixedSecret values are redacted from captured response previews.
Inbound webhooks
- NewPer-sheet webhook URL: POST JSON to create rows; keys map to columns and email dedups/merges.
- NewAuto-run cascades new webhook rows through the columns immediately.
AI & HTTP columns
Every column can now call a model or any API.
- NewAI columns: OpenAI-compatible prompts with templated inputs, text or JSON output mapped to columns.
- NewHTTP columns: templated requests with JMESPath response mapping, retries and rate limits.
- NewBYOK secrets, encrypted at rest, referenced as {{secret:REF}}.
- NewLive cell updates over WebSocket while runs are in flight.
Execution engine
- NewQueue-based execution: row runs fan out to workers via Redis.
- NewColumn DAG with topological execution order and staleness tracking.
Foundation
- NewWorkspaces, sheets, typed columns, and the JSONB record store.
- NewCSV import/export, formula columns, inline cell editing.
- NewAuth, k3s deployment, hash-partitioned records for 100k+ row sheets.