Andrey Epifancev b15ae972ca build: test vault path from VOICE_NOTE_VAULT, warn when missing (M-3, #3)
Default stays the author's test vault. Without the vault the dev build used to skip copying silently; now it says so and names the variable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 19:23:01 +04:00

4.6 KiB
Raw Blame History

Obsidian Voice Note — плагин голосовых заметок

Что это

Плагин Obsidian: запись голоса с телефона или десктопа → отправка файлом во внешний сервис распознавания → текст в заметку. Mobile-first: основной сценарий — iPhone, десктоп получает то же.

Стек и ограничения

  • TypeScript, esbuild (стандартный шаблон obsidian-sample-plugin), vitest для тестов.
  • isDesktopOnly: false в manifest.json. Никакого Node API (fs, child_process, path), только Web API и API Obsidian (requestUrl, app.vault).
  • Запись: MediaRecorder. Форматы на входе различаются: iOS даёт audio/mp4, Android — audio/webm, десктоп — webm/ogg. Провайдер должен принимать все три или конвертировать.
  • Отправка файлом, без стриминга.

Архитектура

  • src/core/ — чистый TypeScript без импортов из obsidian: машина состояний записи (created → saved → sent → transcribed → inserted, ветки на потерю сети и обрыв записи), очередь отправки, провайдеры распознавания, формирование markdown-заметки. Покрывается vitest полностью.
  • src/obsidian/ — тонкая обёртка: команды, настройки, UI, работа с vault. Юнит-тестов нет, проверяется руками в тестовом vault.
  • Провайдер — интерфейс с реализациями: openai-compatible (AITUNNEL по умолчанию; Groq, OpenAI, whisper на VPS — тот же код, другой URL) и при необходимости yandex. Переключение на следующего провайдера по 403/таймауту.
  • Ключи API — в настройках плагина (data.json), в git не попадают.

Команды

  • npm run dev — сборка в watch-режиме в тестовый vault. Другой vault — через VOICE_NOTE_VAULT=<путь> npm run dev; если vault не найден, копирование пропускается с предупреждением.
  • npm test — vitest, вся папка tests/. Зелёным считается весь набор.
  • npm run build — продакшн-сборка main.js.
  • npm run typecheck — два прохода: весь проект с Node-типами и src/core через tsconfig.core.json без Node-типов (process, Buffer в core — ошибка компиляции).
  • Версии зависимостей точные (.npmrc: save-exact=true). Lock-файл не перегенерировать через npm install на одной ОС: npm вычищает опциональные бинарники других платформ.

Тесты

  • Golden-тесты: tests/fixtures/<name>.m4a + tests/fixtures/<name>.txt (эталонный транскрипт). Провайдер в тестах мокается; golden-файлы проверяют формирование заметки и обработку ответа, а не сам сервис.
  • Тестовый vault: /Users/andrey.epifancev/Library/Mobile Documents/iCloud~md~obsidian/Documents/voice-note-test — синхронизируется между Mac и телефоном.

Первая подсистема

Жизненный цикл записи и очередь (core), затем провайдер, затем обёртка. Тестовая инфраструктура — Task 1 первого плана.

OpenSpec и superpowers

  • Вход в любую задачу — superpowers:brainstorming. Skills openspec-propose и openspec-explore сами по себе не запускать.
  • Когда brainstorming классифицировал задачу как architectural, структуру change создать через /opsx:propose <id> (или скопировать его шаблон), а содержимое proposal.md, specs/ и design.md написать по итогам brainstorming. tasks.md из OpenSpec не заполнять — задачи живут в плане superpowers.
  • /opsx:apply не использовать: исполнение идёт через writing-plans и SDD/executing-plans.
  • /opsx:archive <id> — после merge PR, как часть закрытия.