diff --git a/00_README.md b/00_README.md new file mode 100644 index 0000000..518160b --- /dev/null +++ b/00_README.md @@ -0,0 +1,36 @@ +# Verstak Platform Docs + +Этот комплект фиксирует новый архитектурный курс Верстака: не монолитное приложение с набором встроенных экранов, а local-first платформа рабочего vault, где пользовательские функции подключаются динамическими плагинами. + +Исходная идея Верстака сохраняется: + +> Верстак - локальная рабочая среда, где по каждому клиенту, проекту или делу собраны файлы, заметки, документы, ссылки, действия, журнал и история работы. + +Меняется внутреннее устройство. Заметки, файловый менеджер, редакторы, предпросмотр, журнал, активность, браузерный inbox и подобные части больше не считаются внутренними разделами одного приложения. Они становятся плагинами, которые подключаются к платформе через capability registry, contribution points и permissions. + +## Документы + +- [01_Product_Vision.md](01_Product_Vision.md) - продуктовая идея, что остается неизменным и зачем Верстак нужен. +- [02_Platform_Architecture.md](02_Platform_Architecture.md) - архитектура ядра, runtime, vault, UI shell и plugin host. +- [03_Repositories.md](03_Repositories.md) - разбиение на репозитории и назначение каждого. +- [04_Plugin_System.md](04_Plugin_System.md) - динамические плагины, manifest, lifecycle, capabilities, settings, permissions. +- [05_Official_Plugins.md](05_Official_Plugins.md) - состав официальных плагинов и их зависимости через capabilities. +- [06_Migration_Strategy.md](06_Migration_Strategy.md) - как переходить от текущего приложения к платформе без потери смысла. +- [AGENTS.md](AGENTS.md) - инструкция для coding agents, чтобы они не возвращали проект к монолиту. + +## Главный архитектурный инвариант + +Core не знает о конкретных функциях вроде "заметки", "файловый менеджер" или "markdown editor". Core знает о: + +- vault; +- plugin runtime; +- capability registry; +- contribution points; +- permissions; +- settings registry; +- event bus; +- storage API; +- UI shell. + +Все рабочие инструменты поставляются плагинами. Даже официальные плагины должны жить по тем же правилам, что и будущие сторонние. + diff --git a/01_Product_Vision.md b/01_Product_Vision.md new file mode 100644 index 0000000..0c968af --- /dev/null +++ b/01_Product_Vision.md @@ -0,0 +1,82 @@ +# Verstak - Product Vision + +## 1. Зачем существует Верстак + +Верстак нужен не как еще один заметочник, файловый менеджер, CRM или таск-трекер. Его задача - удерживать рабочий контекст вокруг дела. + +Дело может быть клиентом, проектом, ремонтом, сервером, статьей, устройством, заказом, учебным курсом или личной разработкой. В обычной жизни информация по делу расползается по папкам, wiki, заметкам, истории терминала, чатам, браузеру, password manager, таблицам и памяти. Через месяц трудно восстановить, что было сделано, где актуальный файл, какой сервер относится к какому клиенту, почему была принята та или иная настройка. + +Верстак собирает это в один локальный vault. + +## 2. Главная формула + +> Верстак - local-first рабочий vault вокруг дел. + +Внутри дела живут: + +- заметки; +- файлы и документы; +- ссылки; +- действия; +- журнал работ; +- история активности; +- отправленные из браузера материалы; +- клиентские доступы и секреты; +- контекст, который нужен, чтобы вернуться к работе через месяц или год. + +## 3. Что меняется в платформенной версии + +Раньше Верстак можно было описать как приложение: + +```text +Верстак = дерево дел + заметки + файлы + редактор + журнал + синхронизация +``` + +Новая модель: + +```text +Верстак = core platform + vault + plugin runtime + official plugins +``` + +Это важно не ради архитектурной красоты. Это защищает проект от превращения в жесткий комбайн, где каждая новая функция врастает в `App.svelte`, backend methods и общий state. + +## 4. Что должно остаться неизменным + +- Local-first: пользовательские данные живут локально и остаются доступными без облака. +- Vault остается читаемым человеком: файлы и заметки не должны превращаться в непрозрачную базу. +- Главное понятие - дело, а не задача. +- Верстак не становится SaaS, CRM или корпоративной системой. +- Синхронизация - дополнение, а не источник правды. +- Плагины расширяют рабочую среду, но не ломают базовую доступность данных. +- Пользователь должен понимать, где лежат его данные и что с ними происходит. + +## 5. Что не входит в ядро + +В ядро не входят: + +- markdown editor; +- file manager; +- image/pdf preview; +- notes workflow; +- activity reconstruction; +- journal UI; +- browser inbox; +- secrets manager; +- importer/exporter; +- AI assistant; +- kanban/calendar/client-specific screens. + +Все это должно быть плагинами. + +## 6. Продуктовая цель платформы + +Платформенная архитектура нужна, чтобы Верстак мог расти не как один большой экран, а как рабочий стол мастера: + +- один пользователь может использовать только файлы, заметки и журнал; +- другой добавит браузерный inbox и activity recovery; +- третий подключит секреты, SSH, серверные профили и клиентские шаблоны; +- четвертый заменит markdown editor на другой; +- пятый поставит два редактора и будет выбирать нужный. + +Верстак остается одним рабочим местом, но инструменты на этом месте можно менять. + diff --git a/02_Platform_Architecture.md b/02_Platform_Architecture.md new file mode 100644 index 0000000..df5f3d6 --- /dev/null +++ b/02_Platform_Architecture.md @@ -0,0 +1,277 @@ +# Verstak Platform Architecture + +## 1. Общая схема + +```text + +----------------------+ + | UI Shell | + | windows, layout, | + | command palette, | + | settings, toasts | + +----------+-----------+ + | + +----------v-----------+ + | Core Platform | + | plugin manager, | + | capabilities, | + | permissions, events | + +----------+-----------+ + | + +-------------------+-------------------+ + | | | ++-------v--------+ +-------v--------+ +-------v--------+ +| Local Vault | | Storage API | | Sync Boundary | +| files, notes, | | SQLite, index, | | client adapter | +| assets, trash | | migrations | | not core truth | ++-------+--------+ +-------+--------+ +-------+--------+ + | | | + +-------------------+-------------------+ + | + +----------v-----------+ + | Dynamic Plugins | + | official and third | + | party packages | + +----------------------+ +``` + +## 2. Core Platform + +Core Platform - минимальное ядро приложения. Оно не содержит бизнес-функции пользователя. Его задача - дать среду, в которую плагины безопасно подключают рабочие инструменты. + +Core отвечает за: + +- запуск приложения; +- открытие и проверку vault; +- загрузку и выгрузку плагинов; +- enable/disable состояние плагинов; +- capability registry; +- contribution points; +- settings registry; +- permissions; +- event bus; +- storage API; +- vault file API; +- command registry; +- diagnostics; +- sync boundary. + +Core не должен импортировать конкретные плагины как обязательные модули. + +## 3. UI Shell + +UI Shell - общий интерфейс платформы: + +- главное окно; +- навигация; +- вкладки и панели; +- command palette; +- global search entry point; +- settings window; +- plugin manager window; +- dialogs/toasts; +- error boundary для plugin UI. + +UI Shell не знает, что такое notes editor или file preview как конкретная реализация. Он знает contribution points: + +- sidebar items; +- main views; +- case tabs; +- file actions; +- note actions; +- context menu entries; +- settings panels; +- command palette commands; +- status bar items; +- activity cards; +- search providers. + +## 4. Vault + +Vault остается пользовательским рабочим пространством. Он должен быть максимально понятным снаружи. + +Пример: + +```text +VerstakVault/ + .verstak/ + db.sqlite + config.json + plugins/ + plugin-state/ + cache/ + trash/ + Clients/ + Romashka/ + Notes/ + Overview.md + Files/ + Screenshots/ + Projects/ +``` + +Правила: + +- пользовательские документы не прячутся в непрозрачные blob-таблицы без необходимости; +- SQLite хранит индексы, связи, историю, состояние UI, plugin metadata; +- файловая структура должна оставаться пригодной для ручного восстановления; +- имена заметок и файлов остаются человекочитаемыми; +- sync не является единственным способом доступа к данным. + +## 5. Plugin Runtime + +Плагины загружаются динамически из каталогов. Официальные плагины используют тот же механизм, что и сторонние. + +Папки плагинов: + +```text +VerstakVault/.verstak/plugins/ + official.files/ + official.notes/ + official.markdown-editor/ + +~/.config/verstak/plugins/ + user.local-plugin/ +``` + +Порядок загрузки: + +1. Найти plugin manifests. +2. Проверить schemaVersion и apiVersion. +3. Проверить enabled/disabled state. +4. Проверить обязательные capabilities. +5. Запросить permissions. +6. Запустить backend sidecar, если нужен. +7. Загрузить frontend bundle, если нужен. +8. Принять регистрации capabilities и contributions. +9. Перевести плагин в состояние loaded/degraded/failed/incompatible. + +## 6. Backend Model + +Не использовать Go `plugin` как основной механизм. Он плохо подходит для кроссплатформенного desktop-приложения из-за ABI, версий компилятора и сборки под разные ОС. + +Предпочтительная модель: + +- плагин может быть pure frontend; +- плагин может быть pure manifest/data; +- плагин может иметь backend sidecar; +- sidecar общается с core через локальный RPC; +- core выдает sidecar только разрешенные API; +- прямой произвольный доступ к vault и OS запрещен по умолчанию. + +Sidecar может быть написан на Go, Rust, Python или другом языке, если он соблюдает протокол. + +## 7. Frontend Model + +Плагин поставляет frontend bundle: + +```text +frontend/ + index.js + style.css +``` + +Frontend bundle не должен напрямую обращаться к Wails backend methods как к глобальному хаосу. Он работает через `VerstakPluginAPI`, который предоставляет: + +- registerView; +- registerSettingsPanel; +- registerCommand; +- registerFileAction; +- callBackend; +- readSettings/writeSettings; +- subscribe/publish events; +- requestCapability. + +## 8. Capability Registry + +Плагины связываются не по имени друг друга, а через capabilities. + +Пример: + +```text +editor.text +editor.text.markdown +viewer.file +viewer.image +preview.markdown +workspace.files +workspace.notes +capture.browser +activity.provider +secret-store +search.provider +``` + +Файловый плагин не зависит от `official.markdown-editor`. Он проверяет, есть ли capability `editor.text.markdown`. Если есть - показывает действие "Редактировать". Если нет - действие не появляется. + +## 9. Plugin Manager UI + +Core обязан иметь окно управления плагинами с первого платформенного этапа. + +Функции: + +- список установленных плагинов; +- enable/disable; +- status: loaded, disabled, failed, incompatible, degraded; +- version и apiVersion; +- source: official, local, third-party; +- capabilities provided; +- required/optional capabilities; +- permissions; +- кнопка "Settings", если плагин предоставляет settings panels; +- diagnostics/error log. + +Выключение плагина не удаляет пользовательские данные. + +## 10. Settings Registry + +Настройки плагинов не должны быть произвольными экранами, спрятанными в разных местах. + +Плагин регистрирует settings panels: + +```json +{ + "contributes": { + "settingsPanels": [ + { + "id": "official.notes.general", + "title": "Notes", + "component": "settings.general" + } + ] + } +} +``` + +Core показывает кнопку настроек у выбранного плагина и открывает соответствующую панель/окно. + +## 11. Event Bus + +Event bus связывает плагины без прямых импортов. + +Примеры событий: + +- `vault.opened`; +- `case.selected`; +- `file.added`; +- `file.changed`; +- `note.saved`; +- `activity.recorded`; +- `browser.capture.received`; +- `plugin.enabled`; +- `plugin.disabled`. + +События должны иметь стабильные схемы. Плагин не должен полагаться на приватные поля другого плагина. + +## 12. Sync Boundary + +Sync server и browser extension выносятся в отдельные репозитории, но должны использовать общие protocol contracts. + +Sync не должен знать о внутренних UI-плагинах. Он синхронизирует: + +- vault metadata; +- files/blobs; +- plugin state where allowed; +- plugin data через зарегистрированные storage namespaces. + +Плагины должны явно указывать, какие данные можно синхронизировать, а какие локальны только на устройстве. + diff --git a/03_Repositories.md b/03_Repositories.md new file mode 100644 index 0000000..1d0c413 --- /dev/null +++ b/03_Repositories.md @@ -0,0 +1,173 @@ +# Verstak Repositories + +## 1. Организация + +Для GitHub/Gitea лучше использовать organization `verstak` или аналогичную общую группу. Внутри нее живут отдельные репозитории одной продуктовой идеи. + +Project board можно вести на уровне organization: roadmap, issues, milestones, cross-repo tasks. + +## 2. Минимальный набор репозиториев + +### `verstak-desktop` + +Основное desktop-приложение. + +Содержит: + +- Core Platform; +- UI Shell; +- plugin loader; +- capability registry; +- settings window; +- plugin manager UI; +- vault API; +- storage API; +- event bus; +- sync client boundary; +- dev harness для локальных плагинов. + +Не содержит: + +- notes как обязательный модуль; +- file manager как обязательный модуль; +- markdown editor как обязательный модуль; +- browser extension код; +- sync server код. + +### `verstak-official-plugins` + +Монорепозиторий официальных плагинов. + +Содержит: + +```text +plugins/ + files/ + notes/ + markdown-editor/ + markdown-preview/ + file-preview/ + activity/ + journal/ + browser-inbox/ + search/ + secrets/ + templates/ +packages/ + plugin-sdk/ + shared-ui/ + test-harness/ +``` + +Официальные плагины должны устанавливаться и загружаться так же, как сторонние. Нельзя делать для них скрытый privileged path, кроме явно описанных platform permissions. + +### `verstak-sdk` + +Общие контракты для разработки плагинов. + +Содержит: + +- manifest schema; +- TypeScript SDK; +- RPC protocol definitions; +- capability contracts; +- event schemas; +- test helpers; +- plugin packaging tools; +- examples. + +На раннем этапе SDK может жить в `verstak-official-plugins/packages/plugin-sdk`, но должен быть выделен в отдельный репозиторий, когда API начнет стабилизироваться. + +### `verstak-sync-server` + +Отдельный сервер синхронизации. + +Содержит: + +- HTTP API; +- auth/pairing; +- device registry; +- vault operation log; +- blob upload/download; +- conflict handling; +- retention/deleted file policy; +- server migrations; +- deployment docs. + +Sync server не должен импортировать desktop UI или official plugins. + +### `verstak-browser-extension` + +Расширение браузера. + +Содержит: + +- Firefox/Chromium extension; +- local pairing with Verstak; +- page capture; +- selected text capture; +- link sending; +- pending queue if desktop is offline; +- domain bindings support; +- protocol docs for browser inbox plugin. + +Расширение не должно напрямую знать внутреннюю структуру notes/files/activity. Оно отправляет события в local receiver, а обработка идет через плагин `official.browser-inbox`. + +## 3. Репозитории позже + +### `verstak-plugin-registry` + +Каталог доступных плагинов: + +- official plugin index; +- third-party plugin metadata; +- signatures/checksums; +- compatibility matrix; +- install URLs. + +Не нужен в первый этап, если плагины ставятся вручную из локальной папки или из `verstak-official-plugins`. + +### `verstak-docs` + +Публичная документация: + +- user guide; +- developer guide; +- plugin authoring guide; +- sync setup; +- security model; +- migration guides. + +Может быть отдельным репозиторием позже. Сейчас допустимо держать архитектурные документы рядом с `verstak-desktop`. + +## 4. Что не дробить слишком рано + +Не стоит сразу создавать отдельный репозиторий на каждый официальный плагин. Это увеличит накладные расходы и усложнит синхронные изменения SDK/API. + +Лучше: + +```text +verstak-official-plugins - один repo для официальных плагинов +``` + +А отдельные repo оставить для сторонних плагинов или крупных независимых модулей. + +## 5. Версионирование + +Версии должны существовать на трех уровнях: + +- app version: версия `verstak-desktop`; +- platform apiVersion: версия API плагинов; +- plugin version: версия конкретного плагина. + +Плагин объявляет: + +```json +{ + "version": "0.1.0", + "apiVersion": "1" +} +``` + +Core может загрузить плагин только при совместимости `apiVersion`. + diff --git a/04_Plugin_System.md b/04_Plugin_System.md new file mode 100644 index 0000000..83950ca --- /dev/null +++ b/04_Plugin_System.md @@ -0,0 +1,309 @@ +# Verstak Plugin System + +## 1. Цель + +Плагины превращают Верстак из монолитного приложения в платформу. Любая пользовательская функция должна быть реализуема как плагин: + +- заметки; +- файловый менеджер; +- редактор; +- просмотрщик; +- журнал; +- активность; +- браузерный inbox; +- поиск; +- секреты; +- импорт; +- шаблоны дел. + +## 2. Структура плагина + +```text +official.notes/ + plugin.json + frontend/ + index.js + style.css + backend/ + plugin-linux-amd64 + plugin-windows-amd64.exe + migrations/ + 001_init.sql + assets/ + README.md +``` + +Не каждый плагин обязан иметь frontend/backend/migrations. Manifest обязателен. + +## 3. Manifest + +```json +{ + "schemaVersion": 1, + "id": "official.notes", + "name": "Notes", + "version": "0.1.0", + "apiVersion": "1", + "description": "Markdown notes inside Verstak cases.", + "source": "official", + "provides": [ + "workspace.notes", + "entity.note" + ], + "requires": [ + "vault.files" + ], + "optionalRequires": [ + "editor.text.markdown", + "preview.markdown", + "search.provider" + ], + "permissions": [ + "vault.read", + "vault.write", + "storage.namespace", + "ui.register", + "events.publish", + "events.subscribe" + ], + "frontend": { + "entry": "frontend/index.js", + "style": "frontend/style.css" + }, + "backend": { + "type": "sidecar", + "entry": { + "linux-amd64": "backend/plugin-linux-amd64", + "windows-amd64": "backend/plugin-windows-amd64.exe" + } + }, + "contributes": { + "views": [], + "commands": [], + "settingsPanels": [] + } +} +``` + +## 4. Capabilities Instead Of Plugin Names + +Плагины не должны требовать конкретный плагин, если им нужна способность. + +Плохо: + +```json +{ + "requires": ["official.markdown-editor"] +} +``` + +Хорошо: + +```json +{ + "optionalRequires": ["editor.text.markdown"] +} +``` + +Так можно заменить редактор, поставить два редактора или временно выключить предпросмотр без поломки файлового плагина. + +## 5. Required And Optional Capabilities + +`requires` - без этих capabilities плагин не может работать. + +`optionalRequires` - без них плагин работает в degraded mode. + +Пример: + +```text +official.notes + requires: + vault.files + optionalRequires: + editor.text.markdown + preview.markdown + search.provider +``` + +Если нет `preview.markdown`, заметки работают, но кнопка предпросмотра не появляется. + +## 6. Plugin States + +Core должен различать состояния: + +- `discovered` - manifest найден; +- `disabled` - пользователь выключил; +- `loading` - идет загрузка; +- `loaded` - успешно загружен; +- `degraded` - работает без optional capabilities; +- `failed` - ошибка загрузки/запуска; +- `incompatible` - неподдерживаемый apiVersion/schemaVersion; +- `missing-required-capability` - не хватает обязательной capability. + +Состояние видно в Plugin Manager UI. + +## 7. Lifecycle + +```text +discover +validate manifest +check compatibility +check enabled state +resolve required capabilities +request permissions +run migrations +start backend sidecar +load frontend bundle +register capabilities +register contributions +activate +deactivate +shutdown +``` + +Lifecycle hooks: + +- `onInstall`; +- `onEnable`; +- `onVaultOpen`; +- `onActivate`; +- `onDeactivate`; +- `onDisable`; +- `onUninstall`; +- `onShutdown`. + +## 8. Contribution Points + +Плагин может регистрировать: + +- sidebar item; +- main view; +- case tab; +- file action; +- note action; +- context menu item; +- command palette command; +- settings panel; +- search provider; +- activity provider; +- importer; +- exporter; +- vault scanner; +- protocol receiver. + +Contribution должен быть декларативным, где возможно. Runtime callbacks нужны только для поведения. + +## 9. Plugin Settings + +Окно настроек плагинов - обязательная часть core. + +Плагин объявляет settings panels: + +```json +{ + "contributes": { + "settingsPanels": [ + { + "id": "official.markdown-editor.general", + "title": "Markdown Editor", + "component": "settings.general" + } + ] + } +} +``` + +Plugin Manager показывает кнопку настроек только если у плагина есть settings panels. + +Настройки хранятся в namespace плагина: + +```text +plugin_settings.official.markdown-editor +``` + +Плагин не должен читать/писать настройки другого плагина без разрешения. + +## 10. Enable/Disable Rules + +Выключение плагина: + +- убирает его UI contributions; +- убирает commands/actions; +- отзывает provided capabilities; +- останавливает sidecar; +- сохраняет данные плагина; +- не удаляет пользовательские файлы; +- публикует событие `plugin.disabled`. + +Включение плагина: + +- повторно проверяет совместимость; +- выполняет pending migrations; +- регистрирует contributions; +- публикует событие `plugin.enabled`. + +Если другой плагин использовал optional capability выключенного плагина, он переходит в degraded mode. Если required capability исчезла, зависимый плагин должен быть деактивирован или переведен в failed/missing-required state. + +## 11. Permissions + +Минимальный набор permissions: + +```text +vault.read +vault.write +vault.watch +storage.namespace +storage.migrations +events.publish +events.subscribe +ui.register +commands.register +network.local +network.remote +process.spawn +secrets.read +secrets.write +sync.participate +``` + +Опасные разрешения должны быть видны пользователю до включения плагина: + +- `network.remote`; +- `process.spawn`; +- `secrets.read`; +- `vault.write`; +- `sync.participate`. + +## 12. Data Ownership + +Каждый плагин имеет namespace: + +```text +plugin_data// +plugin_settings// +plugin_cache// +``` + +Пользовательские данные должны отделяться от cache. + +Uninstall не должен автоматически удалять пользовательские данные без явного подтверждения. + +## 13. Packaging + +Плагин распространяется как zip/tar package: + +```text +official.notes-0.1.0.vpkg +``` + +Пакет содержит: + +- `plugin.json`; +- frontend bundle; +- backend binaries if any; +- migrations; +- README; +- checksums/signature later. + +На первом этапе допустима ручная установка папкой в plugin directory. + diff --git a/05_Official_Plugins.md b/05_Official_Plugins.md new file mode 100644 index 0000000..7d321ab --- /dev/null +++ b/05_Official_Plugins.md @@ -0,0 +1,303 @@ +# Official Plugins + +Официальные плагины - это базовый набор инструментов Верстака. Они не должны быть скрытыми частями core. Их задача - показать, что платформа действительно работает через capabilities и contribution points. + +## 1. `official.files` + +Назначение: + +- дерево/список файлов внутри дела; +- добавление файлов; +- перемещение/копирование в vault; +- открытие системным приложением; +- file metadata; +- file actions registry consumer. + +Provides: + +```text +workspace.files +vault.files +entity.file +file.browser +``` + +Optional requires: + +```text +editor.text +viewer.file +preview.file +search.provider +``` + +Поведение: + +- если есть подходящий editor capability, показывает "Edit"; +- если есть viewer/preview capability, показывает "Preview"; +- если нет, оставляет "Open externally". + +## 2. `official.notes` + +Назначение: + +- markdown notes as first-class Verstak entities; +- canonical `Notes/` folder inside case/project; +- Overview note; +- note metadata; +- note links. + +Provides: + +```text +workspace.notes +entity.note +note.registry +``` + +Requires: + +```text +vault.files +``` + +Optional requires: + +```text +editor.text.markdown +preview.markdown +search.provider +``` + +Важное правило: + +- title и filename должны оставаться синхронизированными; +- filename - человекочитаемая проекция title; +- при конфликте имени не добавлять `_2` молча, а показывать понятный conflict dialog. + +## 3. `official.markdown-editor` + +Назначение: + +- редактирование markdown/text; +- toolbar; +- save flow; +- dirty state; +- keyboard shortcuts. + +Provides: + +```text +editor.text +editor.text.markdown +editor.note.markdown +``` + +Optional requires: + +```text +preview.markdown +``` + +Не должен: + +- сам решать, где хранятся notes; +- напрямую зависеть от `official.notes`; +- тащить file manager внутрь себя. + +## 4. `official.markdown-preview` + +Назначение: + +- безопасный markdown render; +- internal `verstak://` links; +- optional syntax highlight. + +Provides: + +```text +preview.markdown +viewer.markdown +``` + +Optional requires: + +```text +link.resolver +``` + +## 5. `official.file-preview` + +Назначение: + +- просмотр изображений; +- просмотр text-like файлов; +- базовый PDF/image metadata preview, если возможно; +- fallback to system open. + +Provides: + +```text +viewer.file +viewer.image +viewer.text +preview.file +``` + +## 6. `official.activity` + +Назначение: + +- сбор activity events; +- отображение истории; +- реконструкция работы; +- подсказки для worklog. + +Provides: + +```text +activity.log +activity.provider +activity.reconstruction +``` + +Subscribes: + +```text +file.opened +file.changed +note.saved +action.started +browser.capture.received +case.selected +``` + +## 7. `official.journal` + +Назначение: + +- ручной журнал работ; +- billable/non-billable; +- отчеты по делу/клиенту; +- принятие suggested time из activity. + +Provides: + +```text +worklog +journal +report.worklog +``` + +Optional requires: + +```text +activity.reconstruction +``` + +## 8. `official.browser-inbox` + +Назначение: + +- прием ссылок, выделенного текста, страниц и snippets из browser extension; +- pending queue; +- привязка доменов к делам; +- создание inbox entries; +- превращение inbox entry в note/link/file/activity. + +Provides: + +```text +capture.browser +browser.inbox +domain.binding +``` + +Requires: + +```text +network.local +``` + +Optional requires: + +```text +workspace.notes +activity.log +search.provider +``` + +## 9. `official.search` + +Назначение: + +- общий поиск по vault; +- индекс notes/files/activity/worklog; +- providers from plugins; +- typo/layout tolerant search later. + +Provides: + +```text +search +search.provider +search.indexer +``` + +## 10. `official.secrets` + +Назначение: + +- защищенное хранилище клиентских доступов; +- SSH/CMS/VPS/database/API secrets; +- bridge secret, sync token, device private key, pairing token; +- permissions for secret access. + +Provides: + +```text +secret-store +secrets.read-ui +secrets.write-ui +``` + +Важное правило: + +- секреты не должны храниться как обычный markdown/plain text; +- доступ к secret-store должен идти через permissions; +- плагины не получают `secrets.read` автоматически. + +## 11. `official.templates` + +Назначение: + +- шаблоны дел; +- client/project/server/device structures; +- initial folder/note/action layout. + +Provides: + +```text +case.templates +``` + +Optional requires: + +```text +workspace.notes +workspace.files +``` + +## 12. Первый минимальный набор + +Для первого платформенного этапа достаточно: + +- `official.files`; +- `official.notes`; +- `official.markdown-editor`; +- `official.markdown-preview`; +- `official.activity`; +- `official.browser-inbox`; + +Но все они должны быть настоящими динамическими плагинами, даже если поставляются вместе с приложением. + diff --git a/06_Migration_Strategy.md b/06_Migration_Strategy.md new file mode 100644 index 0000000..3398697 --- /dev/null +++ b/06_Migration_Strategy.md @@ -0,0 +1,128 @@ +# Migration Strategy + +## 1. Цель миграции + +Нужно перейти от текущего приложения к платформе, не потеряв исходный смысл Верстака: + +- local-first vault; +- дела как центр контекста; +- человекочитаемые файлы; +- заметки, файлы, журнал, активность, браузерные материалы вокруг дела; +- синхронизация и расширение как отдельные части, а не ядро смысла. + +Миграция не должна быть "просто разнести App.svelte". Это смена архитектурной модели. + +## 2. Нельзя делать + +- Нельзя добавлять новые функции в монолитный `App.svelte`. +- Нельзя делать official plugins скрытыми compile-time modules. +- Нельзя связывать плагины по именам, если нужна capability. +- Нельзя делать notes/files/editor обязательными частями core. +- Нельзя ломать существующий vault layout без миграционного плана. +- Нельзя хранить секреты как обычные заметки или plain text. +- Нельзя молча менять title/filename note при конфликте. + +## 3. Этап 1 - Platform Skeleton + +Сделать в `verstak-desktop`: + +- plugin manifest schema; +- plugin discovery from plugin directories; +- enable/disable state; +- plugin manager UI; +- plugin status model; +- capability registry; +- contribution registry; +- settings registry; +- basic event bus; +- diagnostics panel. + +Проверки: + +- приложение запускается без плагинов; +- приложение показывает пустой Plugin Manager; +- тестовый плагин появляется в списке; +- enable/disable работает; +- failed plugin не роняет приложение. + +## 4. Этап 2 - Frontend Plugin Host + +Сделать: + +- загрузку frontend bundle; +- `VerstakPluginAPI`; +- registration of views/settings/commands; +- plugin UI error boundary; +- settings panel invocation from Plugin Manager. + +Проверки: + +- тестовый плагин регистрирует view; +- тестовый плагин регистрирует settings panel; +- выключение плагина убирает view/settings; +- ошибка в plugin UI не роняет shell. + +## 5. Этап 3 - Backend Sidecar Host + +Сделать: + +- sidecar launch protocol; +- local RPC; +- permission-scoped API; +- sidecar shutdown/restart; +- logs/diagnostics. + +Проверки: + +- sidecar отвечает health check; +- sidecar не получает API без permissions; +- падение sidecar переводит плагин в failed; +- disable останавливает sidecar. + +## 6. Этап 4 - Official Plugin Extraction + +Выносить функции по одной: + +1. `official.markdown-preview`; +2. `official.markdown-editor`; +3. `official.files`; +4. `official.notes`; +5. `official.activity`; +6. `official.browser-inbox`. + +После каждого выноса: + +- проверить build; +- проверить запуск; +- проверить Plugin Manager; +- проверить enable/disable; +- проверить degraded mode при отключении optional plugin; +- проверить, что старые данные vault открываются; +- проверить, что UI contributions исчезают при disable. + +## 7. Этап 5 - Repository Split + +Когда plugin runtime работает: + +- оставить core и shell в `verstak-desktop`; +- вынести official plugins в `verstak-official-plugins`; +- вынести sync server в `verstak-sync-server`; +- вынести browser extension в `verstak-browser-extension`; +- выделить `verstak-sdk` после стабилизации API. + +Не начинать с физического split repo, пока runtime не умеет грузить плагины локально. + +## 8. Definition Of Done + +Платформенный переход можно считать состоявшимся, когда: + +- core запускается без official plugins; +- official plugins лежат вне core modules; +- notes/files/editor/preview/activity работают как плагины; +- Plugin Manager умеет включать/выключать плагины; +- плагин может иметь свое settings окно; +- capability registry управляет видимостью actions; +- отсутствие optional capability не считается ошибкой; +- existing vault открывается без миграционной потери данных; +- документация соответствует реализации. + diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..782219d --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,121 @@ +# AGENTS.md - Verstak Platform + +Руководство для coding agents, работающих над Верстаком. + +Язык общения с пользователем: русский. Названия API, файлов, команд, commit messages и технических сущностей можно оставлять на английском. + +## 1. Назначение проекта + +Верстак - local-first рабочая платформа вокруг дел. Дело собирает заметки, файлы, документы, ссылки, действия, журнал, активность, браузерные материалы и секреты в одном локальном vault. + +Новая архитектурная цель: Верстак не монолитное приложение, а платформа с динамическими плагинами. + +## 2. Главные инварианты + +- Core не содержит notes/files/editor/activity/journal/browser inbox как обязательные внутренние фичи. +- Пользовательские функции реализуются как динамические плагины. +- Официальные плагины работают через тот же plugin runtime, что и сторонние. +- Плагины зависят от capabilities, а не от конкретных plugin IDs, если им нужна способность. +- Отсутствие optional capability не ошибка; UI action просто не появляется или плагин работает в degraded mode. +- Выключение плагина не удаляет пользовательские данные. +- Vault остается local-first и человекочитаемым. +- Sync server, browser extension и official plugins должны быть выделяемыми репозиториями. +- Секреты не хранятся как plain text notes. + +## 3. Архитектурные документы + +Перед работой прочитать: + +- `verstak-platform-docs/01_Product_Vision.md` +- `verstak-platform-docs/02_Platform_Architecture.md` +- `verstak-platform-docs/04_Plugin_System.md` +- `verstak-platform-docs/05_Official_Plugins.md` +- `verstak-platform-docs/06_Migration_Strategy.md` + +Если код противоречит документам, не молча подгонять документы под код. Сначала понять, это старый монолитный долг или осознанное новое решение. + +## 4. Plugin Rules + +Manifest обязателен. Плагин должен объявлять: + +- `id`; +- `name`; +- `version`; +- `apiVersion`; +- `provides`; +- `requires`; +- `optionalRequires`; +- `permissions`; +- `frontend/backend` entry, если есть; +- `contributes`, если есть UI/actions/settings. + +Нельзя: + +- импортировать другой плагин напрямую; +- вызывать приватные backend methods другого плагина; +- читать чужой storage namespace без разрешения; +- создавать actions, если нет нужной capability; +- ронять приложение при ошибке плагина. + +## 5. Plugin Manager + +Plugin Manager UI - обязательный core-модуль. + +Он должен показывать: + +- installed plugins; +- enable/disable; +- status: loaded, disabled, failed, incompatible, degraded; +- version/apiVersion; +- source: official/local/third-party; +- provided capabilities; +- required/optional capabilities; +- permissions; +- settings button, если плагин предоставляет settings panel; +- diagnostics/error text. + +## 6. Note/File Rules + +Для notes: + +- canonical folder: `Notes/`; +- Overview note: `Notes/Overview.md`; +- title и filename должны быть синхронизированы; +- filename строится из title как человекочитаемая безопасная проекция; +- при конфликте имени операция не должна молча добавлять `_2`; нужен conflict dialog/suggestion. + +Для files: + +- file plugin не должен жестко зависеть от markdown editor; +- edit/preview actions появляются только при наличии соответствующих capabilities; +- opening external app остается fallback. + +## 7. Work Style + +После каждого этапа: + +- build/check; +- targeted tests; +- ручная проверка ключевого сценария, если есть UI; +- self-review на забытые imports, dead code, orphaned functions, old monolith paths; +- обновить документацию, если изменился контракт. + +Не принимать отчет "сделано", пока не проверено: + +- приложение собирается; +- старые сценарии не сломаны; +- plugin enable/disable не оставляет мусорный UI; +- optional capabilities реально optional; +- failed plugin не роняет shell. + +## 8. Запрет на монолитный откат + +Если задача просит добавить новую пользовательскую функцию, сначала определить: + +- это core platform feature? +- это official plugin? +- это capability? +- это contribution point? + +Если функция относится к заметкам, файлам, редакторам, просмотру, activity, journal, browser inbox, search, secrets, import/export - по умолчанию это плагин, а не core. +