mirivlad
d83c8c80e1
fix: второй стабилизационный проход Lua plugin lifecycle
...
1. Enabled/Active state separation:
- Enable() sets Enabled=true (persisted in config), does NOT create runtime
- ActivatePlugin() checks Enabled && !Active, creates VM + scheduler
- DeactivatePlugin() stops runtime, keeps Enabled=true
- InitRuntimes() iterates Enabled plugins, sets Active=true after creation
- SyncConfig() restores Enabled from config, does NOT touch Active
2. ActivatePlugin: добавлен vm.SetServices(m.Services)
3. Discover: атомарная замена списка (newPlugins slice), нет дублирования
4. CallPluginFunction: thread-safe через LuaVM.CallFunction (vm.mu + callWithTimeout)
5. Uninstall активного плагина: полная деактивация (StopScheduler → on_shutdown → CloseVM → Active=false)
6. GetPluginPanelHTML: валидация panel path (no absolute, no .., must be .html, must be within plugin dir)
7. PluginPage: убран hardcoded 'calendar-plugin', используется funcPrefix из pluginName
Тесты:
- security_test.go: +8 тестов (FullLifecycle, ActivatePlugin_Services, Discover_Idempotent,
ReloadPlugins_NoDuplicates, CallPluginFunction_Timeout, Uninstall_ActivePlugin,
GetPluginPanelHTML_PathTraversal, FullLifecycle_EndToEnd)
- manager_test.go: обновлены тесты под новую семантику Enabled/Active
2026-06-07 20:49:43 +08:00
mirivlad
4df83cd361
security: стабилизационный аудит Lua plugin system
...
Исправления:
- Install: идемпотентность (no duplicates in InstalledPlugins)
- ReloadPlugins: StopSchedulers + CallShutdownHooks перед CloseRuntimes
- StopSchedulers: обнуление scheduler=nil после остановки
- Scheduler.Stop: обнуление tasks после wg.Wait
- Lua sandbox: блокировка package.loadlib/seeall/preload/loaders/loaded/path/cpath/config/searchpath
- Lua sandbox: блокировка load (глобальная функция)
- CallPluginFunction: валидация funcName (regex [a-zA-Z_][a-zA-Z0-9_]*, max 3 segments)
- CallPluginFunction: убрана строковая сборка Lua-кодa, вызов через PCall напрямую
- PluginPage.svelte: проверка e.source === iframeEl.contentWindow
- PluginPage.svelte: type checking для msg.source, msg.action
Тесты:
- security_test.go: 18 новых тестов (sandbox, lifecycle, validation)
- Все существующие тесты проходят
Документация:
- docs/plugins-security.md: модель безопасности, sandbox, протокол, lifecycle
2026-06-07 19:19:44 +08:00
mirivlad
3f787ec66d
fix: only plugins with on_install are managed - skip others entirely
...
- Discover(): skip plugins without on_install hook (not shown in UI)
- Enable(): simplified - just check Installed flag
- SyncConfig(): simplified - no HasInstall special case
- Frontend: simplified toggle logic (only installed/uninstalled states)
- Tests: updated all test fixtures to include on_install hook
2026-06-07 15:55:04 +08:00
mirivlad
5c769c92a0
fix: simplify plugin lifecycle - no install/uninstall = just toggle
...
- Plugins without on_install hook: always 'installed', toggle works directly
- Plugins with on_install: must Install first, then toggle, then Uninstall available
- No data cleanup on Disable (only on Uninstall via on_uninstall hook)
- Old plugins without lifecycle hooks simply don't get install/uninstall UI
2026-06-07 15:38:04 +08:00
mirivlad
e99ff984b1
feat: plugin install/uninstall lifecycle + UI buttons
...
- AppConfig: add InstalledPlugins []string
- Manager.Discover(): no config dependency, all plugins start inactive
- Manager.SyncConfig(): apply installed/enabled state from AppConfig
- Manager.Enable(): works for plugins without on_install hook
- Manager.Install/Uninstall(): run on_install/on_uninstall hooks
- ActivatePlugin: skip if HasInstall && !Installed
- ReloadPlugins: Discover → SyncConfig → InitRuntimes
- Bindings: InstallPlugin, UninstallPlugin
- SettingsPlugins: install/uninstall buttons, toggle only after install
- Calendar: migration moved from on_init to on_install, on_uninstall drops tables
- Tests: all 12 pass (manager + runtime + calendar)
2026-06-07 15:28:37 +08:00
mirivlad
b80941f908
feat: плагин-система Lua + Calendar reference plugin
...
- Lua VM runtime: gopher-lua с песочницей, хуки on_init/on_tick/on_shutdown
- API: verstak.node.* / verstak.db.* / verstak.config.* / verstak.state.*
- API: verstak.worklog.* / verstak.activity.* / verstak.file.*
- API: verstak.schedule.* / verstak.http.* / verstak.ui.*
- Менеджер плагинов: жизненный цикл, инициализация, шаблоны
- Scheduler: фоновые задачи с интервалами
- PluginPage.svelte: контейнер для iframe-панелей плагинов
- Calendar plugin: миграция, категории CRUD, события CRUD
- Calendar: расширенный рекарренс (daily/weekly/monthly/yearly)
- Calendar: связь с узлами Верстака, напоминания, HTTP-праздники
- Calendar: Lua-тест-сьют (15 тестов), Go-интеграционный тест
- fix: query_row использует реальные Column() вместо guessColumns
2026-06-07 14:59:46 +08:00
mirivlad
0c0b0d98c7
fix: keep plugin templates separate from system templates
2026-06-04 03:34:18 +08:00
mirivlad
2fa583d157
stabilization: server.go split + i18n templates + frontend localization
...
cmd/verstak-server/server.go (2838→127 строк): разделён на 12 файлов
- config.go, tokens.go, schema.go
- server.go (только struct + NewServer + ListenAndServe)
- routes.go, middleware.go, smtp.go
- handlers_api.go, handlers_user.go, handlers_web_user.go, handlers_admin.go
- templates.go (конвертирован в функции с i18n.T())
frontend: все русские строки заменены на t() вызовы
- App.svelte, FileTreeRow.svelte, ConfirmModal.svelte
- FilePreviewModal.svelte, fileUtils.js
core: gofmt по всему проекту
Все сборки (CLI, server, gui, frontend), go vet, go test проходят.
check-i18n.sh: frontend чист, Go-файлы с кириллицей — только тесты/легаси.
2026-06-02 11:08:29 +08:00
mirivlad
b800bce7e4
step 10: plugins system (Lua + templates) + DokuWiki as optional plugin
...
Plugin Manager:
- Discover plugins from .verstak/plugins/<name>/plugin.json
- Enable/disable per plugin
- Template definitions (JSON) → pre-filled node trees
- SQL migrations from plugins
- Built-in templates loaded from internal/core/plugins/builtin/templates/
Lua Runtime:
- Stub (gopher-lua placeholder) — ready for real implementation
- When dep added: hooks (on_init, on_vault_open, on_node_create),
sandbox (no io/os.execute), Plugin API
GUI:
- Template selector in create node modal
- POST /api/nodes/from-template creates tree from template
- Built-in "Клиент" template: Overview note + Документы/Переписка/Скриншоты
CLI:
- verstak plugin list/enable/disable/templates
DokuWiki Importer:
- Moved to contrib/plugins/importer-dokuwiki/ (optional plugin)
- plugin.json + migration + README
DokuWiki removed from MVP core — now an opt-in plugin.
Acceptance: go build ./... pass, go test ./... pass (all packages).
2026-05-31 11:20:45 +08:00