# Common Patterns Prefix the URLs with `https://raw.githubusercontent.com/commontoolsinc/labs/refs/heads/main/packages/patterns/` ## `counter.tsx` A simple counter demo. ### Input Schema ```ts interface CounterInput { value: number; } ``` ### Result Schema ```ts interface CounterOutput { value?: number; increment: Stream; decrement: Stream; } ``` ## `todo-list.tsx` A todo list with AI suggestions. ### Input Schema ```ts interface Input {} ``` ### Result Schema ```ts interface TodoItem { title: string; done: Default; } interface Output { items: Cell; } ``` ## `notes/note.tsx` A note demo. ### Input Schema ```ts type NoteInput = { /** The title of the note */ title: string; /** The content of the note */ content: string; }; ``` ### Result Schema ```ts type NoteOutput = { /** The content of the note */ content: string; grep: Stream<{ query: string }>; translate: Stream<{ language: string }>; editContent: Stream<{ detail: { value: string } }>; }; ``` ## `gpa-stats-source.tsx` Source charm for charm linking example. Computes statistics from GPA data and exposes them for other charms to consume. **Keywords:** charm-linking, source, lift, computed-stats ### Input Schema ```ts interface Input { name: Default; rawData: Default; } ``` ### Output Schema ```ts interface Stats { average: number; count: number; min: number; max: number; } interface Output { name: string; rawData: string; gpaStats: Stats | null; // Exposed for linking } ``` ## `gpa-stats-reader.tsx` Consumer charm for charm linking example. Receives linked statistics from gpa-stats-source and displays them. **Keywords:** charm-linking, consumer, Default-null ### Input Schema ```ts interface Stats { average: number; count: number; min: number; max: number; } interface Input { name: Default; gpaStats: Default; // null until linked } ``` ## `chatbot.tsx` Full-featured AI chat assistant with tool support, model selection, and mentionables. Deploy this to have a conversational AI interface. **Keywords:** llm, chat, tools, llmDialog, generateObject ### Input Schema ```ts type ChatInput = { messages?: Cell, []>>; tools?: any; theme?: any; system?: string; }; ``` ### Output Schema ```ts type ChatOutput = { messages: Array; pending: boolean | undefined; addMessage: Stream; clearChat: Stream; cancelGeneration: Stream; title?: string; pinnedCells: Array; tools: any; }; ``` ## `notes/voice-note.tsx` Record voice notes with automatic transcription and note history. Hold the microphone button to record, release to transcribe. **Keywords:** voice, transcription, audio, ct-voice-input ### Input Schema ```ts type Input = { title?: Cell>; }; ``` ### Output Schema ```ts interface TranscriptionData { id: string; text: string; chunks?: TranscriptionChunk[]; audioData?: string; duration: number; timestamp: number; } type Output = { transcription: Default; notes: Default; }; ``` ## `image-analysis.tsx` Upload images and get AI-powered analysis and descriptions. Supports multiple images with customizable prompts. **Keywords:** vision, image, generateText, ct-image-input ### Input Schema ```ts type ImageChatInput = { systemPrompt?: string; model?: string; }; ``` ### Output Schema ```ts type ImageChatOutput = { images: Cell; prompt: Cell; response: string | undefined; pending: boolean | undefined; }; ``` ## `chatbot-outliner.tsx` Structured outliner with integrated AI chat that can manipulate the outline via tools. The AI assistant can add nodes to your outline. **Keywords:** outliner, chat, tools, ct-outliner ### Input Schema ```ts type OutlinerNode = { body: Default; children: Default; attachments: Default[], []>; }; type LLMTestInput = { title?: Cell>; messages?: Cell, []>>; expandChat?: Cell>; outline?: Default< { root: OutlinerNode }, { root: { body: "Untitled Page"; children: []; attachments: [] } } >; }; ``` ### Output Schema ```ts type LLMTestResult = { messages: Default, []>; }; ``` ## `scrabble/scrabble.tsx` Free-for-all multiplayer Scrabble game with lobby, tile bag, game board, and scoring. Two players can join and play simultaneously. **Keywords:** game, multiplayer, scrabble, navigateTo ### Input Schema ```ts interface LobbyInput { gameName: Default; boardJson: Cell>; bagJson: Cell>; bagIndex: Cell>; playersJson: Cell>; gameEventsJson: Cell>; allRacksJson: Cell>; allPlacedJson: Cell>; } ``` ### Output Schema ```ts interface LobbyOutput { gameName: string; boardJson: string; bagJson: string; bagIndex: number; playersJson: string; gameEventsJson: string; allRacksJson: string; allPlacedJson: string; } ``` ## `system/favorites-manager.tsx` View and manage favorited charms with tags. Uses the wish system to query `#favorites` and allows removing items. **Keywords:** favorites, wish, ct-cell-link ### Input Schema ```ts type Input = Record; ``` ### Output Schema ```ts // Uses wish>({ query: "#favorites" }) internally // Displays favorited charms with remove functionality ``` ## `contacts/contact-book.tsx` Manage contacts with search, notes, and relationships between contacts. Contacts can be linked together with labels (friend, spouse, colleague, etc.). **Keywords:** contacts, relationships, search, lift ### Input Schema ```ts interface Contact { name: string; email: Default; phone: Default; company: Default; tags: Default; notes: Default; createdAt: number; } interface Relationship { fromName: string; toName: string; label: Default; } interface Input { contacts: Cell>; relationships: Cell>; } ``` ### Output Schema ```ts interface Output { contacts: Contact[]; relationships: Relationship[]; } ``` ## `habit-tracker.tsx` Track daily habits with streak counting and 7-day history visualization. Mark habits complete for today and see your progress over time. **Keywords:** habits, streaks, daily-tracking, lift ### Input Schema ```ts interface Habit { name: string; icon: Default; color: Default; } interface HabitLog { habitName: string; date: string; // YYYY-MM-DD completed: boolean; } interface Input { habits: Cell>; logs: Cell>; } ``` ### Output Schema ```ts interface Output { habits: Habit[]; logs: HabitLog[]; todayDate: string; } ``` ## `calendar.tsx` Minimal calendar for managing events with date and time. Events are grouped by date with today highlighted. **Keywords:** calendar, events, dates, lift ### Input Schema ```ts interface Event { title: string; date: string; // YYYY-MM-DD time: Default; // HH:MM or empty for all-day notes: Default; } interface Input { events: Cell>; } ``` ### Output Schema ```ts interface Output { events: Event[]; todayDate: string; } ``` ## `reading-list.tsx` Track books, articles, papers, and videos you want to read or have read. Filter by status (want/reading/finished/abandoned) and rate items. **Keywords:** reading, books, articles, status-tracking, lift ### Input Schema ```ts type ItemType = "book" | "article" | "paper" | "video"; type ItemStatus = "want" | "reading" | "finished" | "abandoned"; interface ReadingItem { title: string; author: Default; url: Default; type: Default; status: Default; rating: Default; // 1-5 stars notes: Default; addedAt: number; finishedAt: Default; } interface Input { items: Cell>; } ``` ### Output Schema ```ts interface Output { items: ReadingItem[]; } ``` ## `contacts/contact-detail.tsx` Detail/edit view for a single contact. Use with `navigateTo()` from contact-book or as a standalone contact editor. **Keywords:** contact, detail, edit, form, navigateTo ### Input Schema ```ts interface Contact { name: string; email: Default; phone: Default; company: Default; tags: Default; notes: Default; createdAt: number; } interface Input { contact: Contact; } ``` ### Output Schema ```ts interface Output { contact: Contact; } ``` ## `event-detail.tsx` Detail/edit view for a single calendar event. Use with `navigateTo()` from calendar or as a standalone event editor. **Keywords:** event, detail, edit, form, navigateTo ### Input Schema ```ts interface Event { title: string; date: string; time: Default; notes: Default; } interface Input { event: Event; } ``` ### Output Schema ```ts interface Output { event: Event; } ``` ## `reading-item-detail.tsx` Detail/edit view for a single reading list item. Use with `navigateTo()` from reading-list or as a standalone item editor. **Keywords:** reading, book, article, detail, edit, form, navigateTo ### Input Schema ```ts type ItemType = "book" | "article" | "paper" | "video"; type ItemStatus = "want" | "reading" | "finished" | "abandoned"; interface ReadingItem { title: string; author: Default; url: Default; type: Default; status: Default; rating: Default; notes: Default; addedAt: number; finishedAt: Default; } interface Input { item: ReadingItem; } ``` ### Output Schema ```ts interface Output { item: ReadingItem; } ``` ## `deep-research.tsx` Deep research agent that searches the web and synthesizes findings into a structured response. Give it a question and optional context, and it will search, read sources, and provide a comprehensive answer. **Keywords:** llm, research, web-search, tools, generateObject, agent ### Input Schema ```ts type Input = { /** The research question to investigate */ question: string; /** Optional context to provide to the agent */ context?: { [id: string]: any }; }; ``` ### Output Schema ```ts type ResearchResult = { summary: string; findings: { title: string; source: string; content: string }[]; sources: string[]; confidence: "high" | "medium" | "low"; }; type Output = { question: string; result: Cell; pending: boolean; error: string | undefined; }; ``` ## `record.tsx` Flexible container pattern for structured records with composable field modules. Supports dynamic type selection, soft-delete with restore, and LLM-powered data extraction. Used for contacts, businesses, places, and other structured data. **Keywords:** record, container, sub-charms, type-picker, modules, composable ### Input Schema ```ts interface Input { title?: Default; } ``` ### Output Schema ```ts interface SubCharmEntry { type: string; charm: unknown; } interface Output { title: string; subCharms: SubCharmEntry[]; } ``` --- # Record Field Modules These patterns are composable field modules designed to work with `record.tsx` but can also be used standalone. Each exports `MODULE_METADATA` for self-description. ## `birthday.tsx` Birthday/date of birth tracking with optional birth year. **Keywords:** birthday, date, record-module ### Schema ```ts interface BirthdayModuleInput { birthDate: Default; birthYear: Default; } ``` ## `rating.tsx` Star rating (1-5) with visual star display. **Keywords:** rating, stars, record-module ### Schema ```ts interface RatingModuleInput { rating: Default; } ``` ## `tags.tsx` Comma-separated tags/labels. **Keywords:** tags, labels, record-module ### Schema ```ts interface TagsModuleInput { tags: Default; } ``` ## `status.tsx` Status tracking with customizable options (active, inactive, pending, etc.). **Keywords:** status, state, record-module ### Schema ```ts interface StatusModuleInput { status: Default; } ``` ## `address.tsx` Physical address with street, city, state, postal code, and country. **Keywords:** address, location, record-module ### Schema ```ts interface AddressModuleInput { street: Default; city: Default; state: Default; postalCode: Default; country: Default; } ``` ## `timeline.tsx` Key dates tracking (met, started, ended, etc.). **Keywords:** dates, timeline, history, record-module ### Schema ```ts interface TimelineModuleInput { metDate: Default; startDate: Default; endDate: Default; } ``` ## `social.tsx` Social media profile (platform, handle, URL). **Keywords:** social, twitter, linkedin, github, record-module ### Schema ```ts interface SocialModuleInput { platform: Default; handle: Default; url: Default; } ``` ## `link.tsx` URL/link with optional title. **Keywords:** link, url, web, record-module ### Schema ```ts interface LinkModuleInput { url: Default; title: Default; } ``` ## `location.tsx` Geographic coordinates (latitude, longitude) with optional label. **Keywords:** location, coordinates, geo, record-module ### Schema ```ts interface LocationModuleInput { latitude: Default; longitude: Default; label: Default; } ``` ## `relationship.tsx` Relationship to another entity with type and notes. **Keywords:** relationship, connection, record-module ### Schema ```ts interface RelationshipModuleInput { relationshipType: Default; relatedTo: Default; notes: Default; } ``` ## `giftprefs.tsx` Gift preferences and ideas. **Keywords:** gifts, preferences, record-module ### Schema ```ts interface GiftPrefsModuleInput { likes: Default; dislikes: Default; giftIdeas: Default; } ``` ## `timing.tsx` Best times to contact (morning, afternoon, evening, etc.). **Keywords:** timing, availability, schedule, record-module ### Schema ```ts interface TimingModuleInput { bestTime: Default; timezone: Default; } ``` ## `type-picker.tsx` Controller module for selecting record type. Internal use only - applies templates to parent container and then removes itself. **Keywords:** type-picker, controller, internal, record-module ### Schema ```ts interface TypePickerInput { context: ContainerCoordinationContext; dismissed?: Default; } ``` ## `age-category.tsx` Age categorization with two-tier selection: Adult/Child groups with specific subcategories (Senior, Young Adult, Teenager, etc.). **Keywords:** age, category, adult, child, record-module ### Schema ```ts type AgeCategory = | "adult" | "child" | "senior" | "adult-specific" | "young-adult" | "teenager" | "school-age" | "toddler" | "baby"; interface AgeCategoryModuleInput { ageCategory: Default; } ``` ## `dietary-restrictions.tsx` Comprehensive dietary restriction tracking with severity levels. Handles allergies, intolerances, and lifestyle diets (vegetarian, vegan, halal, kosher, keto, etc.) with automatic expansion of diet groups to specific food items. **Keywords:** dietary, allergies, diet, vegan, vegetarian, record-module ### Schema ```ts type RestrictionLevel = "flexible" | "prefer" | "strict" | "absolute"; interface RestrictionEntry { name: string; level: RestrictionLevel; } interface DietaryRestrictionsInput { restrictions: Default; } ``` ## `email.tsx` Email address with customizable label. Supports multiple instances per Record with smart default labels (Personal, Work, School, Other). **Keywords:** email, contact, record-module, multi-instance ### Schema ```ts interface EmailModuleInput { label: Default; address: Default; } ``` ## `phone.tsx` Phone number with customizable label. Supports multiple instances per Record with smart default labels (Mobile, Home, Work, Other). **Keywords:** phone, contact, record-module, multi-instance ### Schema ```ts interface PhoneModuleInput { label: Default; number: Default; } ``` --- # Utility Patterns ## `record-backup.tsx` Import/export utility for Records. Exports all Records in a space to JSON and imports them back. Designed for data survival after server wipes. **Keywords:** backup, export, import, records, data-migration ### Input Schema ```ts interface Input { importJson: Default; } ``` ### Output Schema ```ts interface Output { exportedJson: string; importJson: string; recordCount: number; importResult: ImportResult | null; } ``` --- # Protocol Types ## `container-protocol.ts` Protocol definitions for controller patterns that coordinate with parent containers. **Keywords:** protocol, container, coordination, types ### Types ```ts interface ContainerCoordinationContext { entries: Cell; trashedEntries: Cell<(TEntry & { trashedAt: string })[]>; createModule: (type: string) => unknown; } interface ModuleMetadata { type: string; label: string; icon: string; internal?: boolean; schema?: Record; fieldMapping?: string[]; } ```