// Порты core. Реализации — в src/obsidian (позже) и tests/fakes.ts. export interface RecordingStore { write(path: string, data: ArrayBuffer): Promise; read(path: string): Promise; } export interface ListedNote { path: string; frontmatter: Record; } export interface NoteStore { exists(path: string): Promise; create(path: string, content: string): Promise; // Все заметки vault, у которых во frontmatter есть voice-id, с их frontmatter. // КОНТРАКТ: реализация MUST брать данные из metadataCache и MUST NOT читать // содержимое файлов (vault.read / cachedRead / adapter). Вызывается на каждом // tick, в том числе на телефоне. Данные могут отставать от диска — core // перепроверяет состояние внутри process(). list(): Promise; // Атомарное чтение-изменение-запись. false, если заметки нет. process(path: string, fn: (content: string) => string): Promise; } export type TranscribeResult = | { ok: true; text: string } | { ok: false; kind: 'temporary' | 'permanent'; message: string }; export interface Transcriber { transcribe(audio: ArrayBuffer, mime: string, signal: AbortSignal): Promise; } export interface Env { now(): Date; random(): number; readonly deviceId: string; } export interface HttpRequest { url: string; headers: Record; // Тип тела передаётся отдельно от headers: адаптер requestUrl кладёт его в // параметр contentType, иначе boundary может потеряться. contentType: string; body: ArrayBuffer; } export interface HttpResponse { status: number; text: string; } // Любой HTTP-статус — ответ, не исключение. Исключение — только сетевой сбой. // Сигнала и таймаута нет: requestUrl их не умеет, это делает провайдер в core. export interface HttpClient { post(req: HttpRequest): Promise; }