docs: initial platform architecture docs

This commit is contained in:
mirivlad 2026-06-16 11:42:20 +08:00
parent a1e8248673
commit dbd7264cd9
8 changed files with 1429 additions and 0 deletions

36
00_README.md Normal file
View File

@ -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.
Все рабочие инструменты поставляются плагинами. Даже официальные плагины должны жить по тем же правилам, что и будущие сторонние.

82
01_Product_Vision.md Normal file
View File

@ -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 на другой;
- пятый поставит два редактора и будет выбирать нужный.
Верстак остается одним рабочим местом, но инструменты на этом месте можно менять.

277
02_Platform_Architecture.md Normal file
View File

@ -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.
Плагины должны явно указывать, какие данные можно синхронизировать, а какие локальны только на устройстве.

173
03_Repositories.md Normal file
View File

@ -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`.

309
04_Plugin_System.md Normal file
View File

@ -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_id>/
plugin_settings/<plugin_id>/
plugin_cache/<plugin_id>/
```
Пользовательские данные должны отделяться от 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.

303
05_Official_Plugins.md Normal file
View File

@ -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`;
Но все они должны быть настоящими динамическими плагинами, даже если поставляются вместе с приложением.

128
06_Migration_Strategy.md Normal file
View File

@ -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 открывается без миграционной потери данных;
- документация соответствует реализации.

121
AGENTS.md Normal file
View File

@ -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.