From 6202157cbf09943d69b348d65311352f4eba00b4 Mon Sep 17 00:00:00 2001 From: mirivlad Date: Wed, 17 Jun 2026 04:22:16 +0800 Subject: [PATCH] docs: update PLUGIN_RUNTIME.md with app settings, vault plugin state, first run flow --- docs/PLUGIN_RUNTIME.md | 91 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/docs/PLUGIN_RUNTIME.md b/docs/PLUGIN_RUNTIME.md index 210a0d1..8f3a0ea 100644 --- a/docs/PLUGIN_RUNTIME.md +++ b/docs/PLUGIN_RUNTIME.md @@ -341,3 +341,94 @@ Vault plugin state хранится **внутри vault** в `.verstak/plugins. - Plugin Manager показывает "Missing installed plugin" - Auto-install пока НЕ делается - Показывается подсказка: "Install official plugin package" + +## App Settings + +App settings хранятся локально (НЕ внутри vault): `~/.config/verstak/config.json` + +Поля: +- `currentVaultPath` — путь к текущему vault +- `recentVaults` — список недавних vault (max 10, без дублей) +- `theme` — тема (dark/light) +- `devMode` — режим разработки +- `userPluginsDir` — директория пользовательских плагинов +- `windowState` — состояние окна +- `lastOpenedAt` — время последнего открытия + +API: +- `LoadAppSettings()` / `SaveAppSettings()` / `GetAppSettings()` +- `UpdateAppSettings(patch)` — частичное обновление +- `SetCurrentVault(path)` — установить текущий vault + открыть + сохранить + +Правила: +- Если config отсутствует — создать defaults +- Если config битый — backup + создать defaults + вернуть ошибку +- `currentVaultPath` не обязан существовать, но при запуске проверяется +- Secrets НЕ хранятся в app settings + +## Vault Plugin State + +Vault plugin state хранится внутри vault: `/.verstak/plugins.json` + +Структура: +```json +{ + "schemaVersion": 1, + "enabledPlugins": ["verstak.platform-test"], + "disabledPlugins": [], + "desiredPlugins": [ + { + "id": "verstak.platform-test", + "version": "0.1.0", + "source": "official" + } + ], + "updatedAt": "2026-06-17T04:00:00Z" +} +``` + +API: +- `LoadVaultPluginState()` / `SaveVaultPluginState()` +- `IsPluginEnabled(id)` / `IsPluginDisabled(id)` +- `EnablePlugin(id)` / `DisablePlugin(id)` +- `RecordDesiredPlugin(id, version, source)` +- `ListMissingInstalled(installedIDs)` + +Правила: +- Enabled/disabled состояние относится к конкретному vault +- Если vault закрыт — plugin state недоступен +- Plugin settings остаются в `.verstak/plugin-settings//settings.json` +- Отсутствие `plugins.json` — создать defaults +- Битый `plugins.json` — backup + создать defaults + ошибка + +## First Run / Vault Selection Flow + +При запуске: +1. Загрузить app settings +2. Если `currentVaultPath` пустой или vault не открывается → показать Vault Selection UI +3. Если `currentVaultPath` валиден → открыть vault автоматически + +Vault Selection UI: +- Create new vault → `CreateVault(path)` → `SetCurrentVault(path)` +- Open existing vault → `SetCurrentVault(path)` +- Recent vaults → `SetCurrentVault(path)` +- Ошибка открытия → показать понятный текст + +После успешного открытия: +- `currentVaultPath` сохранён в app settings +- Путь добавлен в `recentVaults` +- Переход в основной UI + +## Enable/Disable Lifecycle + +1. Пользователь нажимает Enable/Disable в Plugin Manager +2. Фронт вызывает `EnablePlugin(id)` / `DisablePlugin(id)` на бэкенде +3. Бэкенд пишет в `/.verstak/plugins.json` +4. Фронт вызывает `ReloadPlugins()` для пересчёта lifecycle +5. Disabled plugin не регистрирует capabilities/contributions +6. После enable — capabilities/contributions возвращаются + +Важно: +- Installed plugin package ≠ enabled plugin +- Disabled plugin виден как installed/disabled +- Missing desired plugin показывается как "missing"