Quick Capture
AI-powered natural language input that parses free text into structured entities with automatic type detection, field extraction, and suggested relations.
Quick Capture
Quick Capture lets users type natural language into a single input bar and have it parsed by AI into a fully structured entity record. The system detects the appropriate entity type, generates a title, populates content fields, and optionally suggests relations to existing entities based on the current page context.
Overview
Quick Capture solves the friction of structured data entry. Instead of navigating to a creation form, selecting a type, and filling in fields one by one, users type something like "New opportunity: automate invoice processing, estimated savings $200K/year, medium effort" and the system handles the rest.
The feature lives in features/capture/ and is available in the sidebar via the CaptureBar component. It is page-context-aware: if a user is viewing the opportunity entity type list, the parser biases toward creating an opportunity. If viewing a specific entity detail page, the parser may suggest a relation to that entity.
Key Concepts
ParseResult -- The Zod-validated output schema from the AI parser. Contains:
entityTypeSlug-- which entity type to createtitle-- a generated title for the new recordcontent-- field values matching the entity type's JSON schemasuggestedRelations-- optional links to existing entities (target ID + relationship type)
Page Context -- The usePageContext() hook reads the current URL pathname to determine whether the user is on an entity type list page or an entity detail page. Reserved routes (dashboard, chat, feed, etc.) return empty context.
Two-Step Flow -- Capture uses a confirm-before-create pattern. The AI parses the input and shows a preview card. The user can edit the title, review extracted fields, then confirm or discard.
How It Works
1. User Input
The CaptureBar component renders a compact input field in the sidebar with a keyboard shortcut (Cmd+Shift+K on Mac, Ctrl+Shift+K elsewhere). The user types a free-text description and presses Enter.
2. AI Parsing
The parseCapture() server action:
- Validates input with Zod — text must be 1 to
CAPTURE_MAX_LENGTHcharacters (10,000; generous enough to cover in-flow dictation or a pasted email/meeting-note dump). On failure, throws a typedCaptureInputErrorwith a user-facing message and logs theZodErrorto Sentry at warning level viacaptureNonFatal(taggedcapture-parse:input-validation). The clients mirror the cap viamaxLength={CAPTURE_MAX_LENGTH}so typing stops at the limit before the server is hit; raw text is never used as the entity title — the AI generates the title separately viaParseResultSchema.title. - Fetches all available entity types with their JSON schemas
- Builds a prompt that includes type descriptions and page context
- Calls
safeGenerateObject()(wrappinggenerateObject()) with theParseResultSchemato produce structured output — failures on the AI output side surface as a grouped Sentry warning plus a cleanStructuredGenerationError, not an unhandledZodError. - Returns the
ParseResultto the client
The AI receives the full set of entity types and their schemas, so it can pick the most appropriate type and populate fields accurately.
3. Preview and Confirm
The CapturePreview component renders a card showing:
- Entity type as a badge
- Editable title
- Extracted content fields as key-value pairs
- Suggested relations as link badges
The user can edit the title inline, then click Confirm or Discard.
4. Entity Creation
The createFromCapture() server action:
- Validates the
ParseResultwith Zod - Creates the entity via the standard
createEntity()action - Tags the entity with
metadata.created_via: "quick_capture"for traceability — provenance markers live onmetadata, NOTcontent, because content keys are validated against the entity type'sjson_schema.propertiesand any unknown key throwsEntityValidationError. Mirrors the convention infeatures/entities/server/resolve-relation-targets.ts(metadata: { created_via: "relation_inline" }). - Creates any suggested relations in
entity_relations(usingPromise.allSettledso relation failures do not block entity creation)
API Reference
Server Actions
| Function | Location | Purpose |
|---|---|---|
parseCapture(text, context) | features/capture/server/parse.ts | AI-parse free text into ParseResult |
createFromCapture(input) | features/capture/server/create-from-capture.ts | Create entity + relations from parsed result |
Schemas
| Schema | Location | Purpose |
|---|---|---|
ParseResultSchema | features/capture/server/parse-schema.ts | Zod schema for AI-generated structured output |
CAPTURE_MAX_LENGTH | features/capture/server/parse-schema.ts | Shared char cap (10,000) — enforced client, server, and agent-handoff |
ParseCaptureInput | features/capture/server/parse.ts | Input validation (text + optional context) |
CaptureInputError | features/capture/server/parse-schema.ts | Typed error thrown on invalid input, carries user-facing message |
Hooks
| Hook | Location | Purpose |
|---|---|---|
usePageContext() | features/capture/hooks/use-page-context.ts | Extract entity type slug and entity ID from current URL |
Components
| Component | Location | Purpose |
|---|---|---|
CaptureBar | features/capture/components/capture-bar.tsx | Input field with keyboard shortcut, loading state, preview trigger |
CapturePreview | features/capture/components/capture-preview.tsx | Confirm/edit/discard card for parsed results |
Pure Functions
| Function | Location | Purpose |
|---|---|---|
getPageContextFromPathname(pathname) | features/capture/hooks/use-page-context.ts | Extract context from a URL path (exported for testing) |
For Agents
Agents do not interact with Quick Capture directly. Instead, they use the standard entity tools:
createEntity-- create a record with structured contentcreateRelation-- link two entitieslistEntityTypes-- discover available types and their schemas
Quick Capture is a human-facing convenience layer that ultimately calls the same createEntity() action that agents use.
Related Modules
- Entity System (
features/entities/) -- providescreateEntity()and entity type schemas - Chat (
features/chat/) -- an alternative path for AI-assisted record creation via conversation - Navigation (
features/navigation/) -- CaptureBar is rendered in the sidebar layout
Feed System
Personalized entity feed with configurable sorting, filtering, card and compact views, for-you personalization, activity enrichment, digest summarization, and block integration.
Navigation
Config-driven sidebar powered by a recursive NavNode tree — supports arbitrary nesting, style presets, and a menu block type for embedding nav trees in views.