Skip to content
github-actions[bot] edited this page Sep 15, 2026 · 2 revisions

Models Reference

All TypeScript model interfaces. See Architecture for how models relate to stores and services.

Note

File: src/models/Note.ts

interface Note {
  id: string;                    // Client-generated: Crypto.randomUUID() or timestamp+random fallback
  title: string;
  content: string;                // Raw content (Markdown, Neorg, Org, JSON)
  tags: string[];
  color?: NoteColor;              // 'red' | 'orange' | 'yellow' | 'green' | 'blue' | 'purple' | 'pink' | 'gray'
  repo?: string;                 // 'owner/repo' format
  branch?: string;                // git branch name
  commit?: string;               // git commit SHA of last save
  folderPath?: string;            // e.g. 'Work/Projects' (no leading slash)
  filePath?: string;             // Full path relative to repo root: 'Work/Projects/my-note.md'
  isPinned?: boolean;
  format?: NoteFormat;           // 'markdown' | 'neorg' | 'org' | 'pdf' | 'json'
  // NOTE: 'pdf' is retained in the type for legacy records that may exist in storage.
  // New PDF files are NOT imported as text notes (PDF was removed from NOTE_EXTS in RepoPullService).
  // Legacy PDF notes are searchable by title and tags only — body content is not scanned.
  attachments?: Attachment[];
  accountId?: string;             // Which account's repo this note belongs to
  createdAt: number;             // Unix timestamp ms
  updatedAt: number;              // Unix timestamp ms
}

NoteColor: 'red' | 'orange' | 'yellow' | 'green' | 'blue' | 'purple' | 'pink' | 'gray'

NoteFormat: 'markdown' | 'neorg' | 'org' | 'pdf' | 'json'

Legacy PDF note behaviour: 'pdf' is kept in the type to support records created by earlier versions of the app. New PDF files are not imported as text notes (the pdf extension was removed from NOTE_EXTS in RepoPullService). Legacy 'pdf' notes are searchable by title and tags but their binary body content is skipped by filterNotesBySearch (the note.format !== 'pdf' guard).

Key functions: createNote(), updateNote(), sortNotesByUpdated(), sortNotesWithPinnedFirst(), filterNotesBySearch(), filterNotesByFolder(), getNoteFileExtension()


Todo

File: src/models/Todo.ts

interface Todo {
  id: string;
  title: string;
  content?: string;              // Optional extended description
  completed: boolean;
  dueDate?: number;             // Unix timestamp ms
  repo?: string;
  branch?: string;
  filePath?: string;
  tags: string[];
  createdAt: number;
  updatedAt: number;
}

Canvas

File: src/models/Canvas.ts

interface Canvas {
  id: string;
  title: string;
  tiles: CanvasTile[];          // Sparse tile data
  hotspots: Hotspot[];           // Interactive regions
  repo?: string;
  branch?: string;
  commit?: string;
  createdAt: number;
  updatedAt: number;
}

interface CanvasTile {
  id: string;
  x: number;
  y: number;
  width: number;
  height: number;
  type: 'image' | 'text' | 'drawing' | 'ai';
  content: string;              // JSON or base64 for images
  zIndex: number;
}

interface Hotspot {
  id: string;
  x: number;
  y: number;
  width: number;
  height: number;
  action: 'link' | 'note' | 'canvas' | 'url';
  target: string;               // Note ID, canvas ID, or URL
}

Chat

File: src/models/Chat.ts

interface Chat {
  id: string;
  threadId: string;
  messages: ChatMessage[];
  repo?: string;                 // Repo context for this chat
  branch?: string;
  createdAt: number;
  updatedAt: number;
}

interface ChatMessage {
  id: string;
  role: 'user' | 'assistant';
  content: string;
  model?: string;               // Which AI model was used
  createdAt: number;
}

AIProvider

File: src/models/AIProvider.ts

interface AIProvider {
  id: string;
  name: string;                  // 'Anthropic' | 'OpenAI' | 'Ollama' | 'AppleIntelligence'
  apiKey?: string;
  baseURL?: string;             // Custom endpoint for OpenAI-compatible providers
  model: string;                // e.g. 'claude-sonnet-4-20250514'
  isActive: boolean;
}

Attachment

File: src/models/Attachment.ts

interface Attachment {
  id: string;
  noteId: string;
  filename: string;              // Original filename
  mimeType: string;             // e.g. 'image/png'
  size: number;                 // bytes
  localPath?: string;           // Local cache path
  remotePath?: string;          // Git LFS pointer or CDN URL
  createdAt: number;
}

Folder

File: src/models/Folder.ts

interface Folder {
  id: string;
  name: string;                 // Display name, not the full path
  path: string;                 // Full path: 'Work/Projects/ClientA'
  repo: string;
  branch: string;
  parentPath?: string;           // Parent folder path
  noteCount: number;            // Cached count of notes in this folder
}

Reminder

File: src/models/Reminder.ts

interface Reminder {
  id: string;
  noteId?: string;              // Associated note (optional)
  title: string;
  dueDate: number;             // Unix timestamp ms
  repeatInterval?: 'daily' | 'weekly' | 'monthly';
  isCompleted: boolean;
  createdAt: number;
}

ThoughtDump

File: src/models/ThoughtDump.ts

interface ThoughtDump {
  id: string;
  content: string;              // Raw captured content
  targetRepo?: string;
  targetBranch?: string;
  targetFolder?: string;         // Where to save as a note
  createdAt: number;
}

NeorgDocument

File: src/models/NeorgDocument.ts

interface NeorgDocument {
  version: string;              // Neorg format version
  paragraphs: NeorgContent[];
  headings: NeorgHeading[];
  lists: NeorgList[];
  links: NeorgLink[];
  todoItems: NeorgTodoItem[];
  tags: string[];
}

interface NeorgHeading {
  level: 1 | 2 | 3 | 4 | 5 | 6;
  text: string;
  anchor?: string;
}

interface NeorgList {
  ordered: boolean;
  items: string[];
}

interface NeorgTodoItem {
  status: 'pending' | 'done' | 'pending_on' | 'running';
  content: string;
}

NeorgContent

File: src/models/NeorgContent.ts

interface NeorgContent {
  type: 'paragraph' | 'quote' | 'code' | 'divider';
  content: string;
  marks?: NeorgMark[];        // Bold, italic, code, etc.
}

interface NeorgMark {
  type: 'bold' | 'italic' | 'code' | 'underline' | 'strike';
  from: number;               // Start offset
  to: number;                 // End offset
}

NeorgLink

File: src/models/NeorgLink.ts

interface NeorgLink {
  type: 'wiki' | 'external' | 'anchor';
  target: string;              // 'Note Title' or 'https://...'
  displayText?: string;        // Custom display text
}

NeorgInline

File: src/models/NeorgInline.ts

interface NeorgInline {
  type: 'text' | 'mark' | 'link' | 'inlineMath' | 'inlineCode';
  content: string;
  from: number;
  to: number;
}

See Also

Clone this wiki locally