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
c443ca23c5
fix: PluginPage.svelte — замена CallPluginAction на CallPluginFunction с dotted path
...
PluginPage.svelte использовал несуществующий Wails binding CallPluginAction.
Заменён на CallPluginFunction с правильным dotted path (calendar.get_events и т.д.),
что соответствует сигнатуре bindings_plugins.go.
Frontend пересобран, go build + go test ./... — всё зелёное.
2026-06-07 16:56:28 +08:00
mirivlad
7b9c9647ac
test: add TestCallPluginFunction + final run - all 13 tests pass
...
- TestCallPluginFunction: verifies DoString calls Lua functions correctly
- add(3,4) → 7, greet('World') → 'Hello, World', get_table() → table
- Full suite: 13 tests, 0 failures
- go build ./... clean
2026-06-07 16:41:47 +08:00
mirivlad
a1d7c7b88b
feat: PluginPage iframe bridge + CallPluginFunction binding
...
- PluginPage.svelte: bidirectional postMessage bridge with iframe
- Handles: ready, get-events, create-event, update-event, delete-event
- Queues messages until iframe is ready
- Exports handleDrop() for drag-and-drop from parent
- CallPluginFunction binding: calls arbitrary Lua functions on active plugins
- Supports dotted paths: 'calendar.create_event' → _G.calendar.create_event
- JSON params → Lua table conversion
- LuaVM: added DoString(), LState(), VM() public methods
- Plugin: added VM() getter for external access
2026-06-07 16:37:32 +08:00
mirivlad
308772dee8
fix: simplify ReloadPlugins - remove redundant deactivate loop
...
- SyncConfig already sets Active correctly from config
- InitRuntimes only processes Active plugins
- No need for separate deactivate pass
2026-06-07 16:01:28 +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
8cbc87cdad
feat: настройки Browser Bridge в Verstak и extension
...
Verstak (GUI):
- SettingsBrowserBridge.svelte — новая секция в Settings:
toggle вкл/выкл сервера, поле порта (default 9786),
статус (Запущен/Остановлен), кнопки Сохранить/Перезапустить
- SettingsWindow + SettingsSidebar — подключена секция browserBridge
- BridgeConfig: добавлено поле Enabled (default true)
- RestartBridge() — новый биндинг для перезапуска сервера
- initVault: проверяет bc.Enabled перед запуском bridge
Extension (Chrome + Firefox):
- popup: панель настроек с полем порта (default 9786)
- кнопка «Проверить» — fetch /api/ping с таймаутом 3с
- кнопка «Сохранить» — сохраняет port в chrome.storage.local
- статус соединения: ✓ Сервер отвечает / ✗ Недоступен / ✗ Таймаут
- оба расширения работают только с 127.0.0.1
2026-06-07 01:03:35 +08:00
mirivlad
1cc0c407b1
fix: исправление 6 пунктов из ревью
...
Critical:
- bridge: AutoGenPort=false по умолчанию, не генерируем secret если пустой
→ extension и bridge совпадают на port 9786 и empty secret
- bridgeConfig: убрана авто-генерация secret, убран secret из BridgeInfo
High:
- extension/background.js + extension-firefox/background.js:
все chrome.* listeners вынесены в global scope (не внутри onInstalled/onStartup)
→ MV3 service worker корректно перезапускается
- UI: acceptBrowserEvent вызывает AcceptBrowserEvent, attachBrowserEvent вызывает
AttachBrowserEventToNode (к текущему selectedNode), а не DismissBrowserEvent
- watcher: при Create проверяется isUnderVault(absPath, vaultRoot) —
если файл уже в vault, используется AddExternal вместо CopyIntoVault
→ нет дублирования файлов с timestamp-суффиксом
Medium:
- bridge.Event: добавлено поле DeviceID, handleEvents обогащает events из batch.DeviceID
→ device_id сохраняется в DB как chrome-*/firefox-*, а не evt_*
- config: FileWatcher изменён на *bool — nil означает default true,
false = явно выключено → старые config.json без поля file_watcher получают true
2026-06-07 00:15:34 +08:00
mirivlad
b676ac675a
feat: иконки для Chrome и Firefox расширений
...
- extension/icons/ + extension-firefox/icons/
- icon16.png (16x16), icon48.png (48x48), icon128.png (128x128)
- взяты из frontend/public/assets/app-icons/
- 48x48 сгенерирован из 64x64 через ImageMagick
- Манифесты: default_icon + icons секции для обоих браузеров
- build.sh: иконки включаются в zip/xpi архивы
2026-06-06 19:21:28 +08:00
mirivlad
f6c61c32e3
build: упаковка расширений в scripts/build.sh
...
- build.sh: новые команды extensions, chrome, firefox
- Chrome: build/verstak-bridge-chrome.zip
- Firefox: build/verstak-bridge-firefox.xpi
- Архивы содержат только нужные файлы (manifest, background, popup)
- Исключены .DS_Store, Thumbs.db, __MACOSX, .git
2026-06-06 19:15:24 +08:00
mirivlad
c5505ee43c
feat: Firefox-расширение Verstak Bridge
...
- extension-firefox/manifest.json — Manifest V3 для Firefox
(browser_specific_settings.gecko, background.scripts)
- extension-firefox/background.js — browser.* API с chrome.* полифиллом
- Стабильный device_id через crypto.getRandomValues (6 байт hex)
- Фильтрация about:, moz-extension:, resource: и пр. внутренних URL
- device_id с префиксом 'firefox-' для различения в activity
- extension-firefox/popup/ — общие popup HTML/CSS/JS (копия Chrome)
2026-06-06 19:08:31 +08:00
mirivlad
fc429ac26e
feat: ШАГ 4 — UI для browser events в TodayScreen
...
Go bindings:
- bindings_browser.go: ListBrowserEvents, CountPendingBrowserEvents,
AcceptBrowserEvent, DismissBrowserEvent, AttachBrowserEventToNode
Frontend:
- BrowserEvents.svelte — компонент списка событий с действиями
(принять/прикрепить/удалить), статусы, домены, длительность
- TodayScreen.svelte — новая вкладка «Браузер» с badge
- App.svelte — loadBrowserEvents, acceptBrowserEvent,
dismissBrowserEvent, attachBrowserEvent handlers
2026-06-06 18:58:39 +08:00
mirivlad
6bd6c9c5ff
feat: ШАГ 3 — Chrome-расширение Verstak Bridge
2026-06-06 18:28:52 +08:00
mirivlad
84d9725b17
feat: ШАГ 2 — Staging-таблица browser_events + Store
2026-06-06 18:27:00 +08:00
mirivlad
358c649b42
feat: ШАГ 1 — Bridge HTTP-сервер для браузерного расширения
...
- internal/core/bridge/ — лёгкий HTTP-сервер на 127.0.0.1
- POST /api/events — приём батча событий от расширения
- GET /api/ping — healthcheck для расширения
- X-Verstak-Secret — аутентификация по shared-secret
- AutoGenPort — случайный порт если 9786 занят
- config.BridgeConfig — порт, секрет, auto_gen_port
- App: интеграция startBridge/stopBridge при open/close vault
- bindings_bridge.go — BridgeInfo(), startBridge(), saveBridgeConfig()
- Тесты: ping, auth, success, empty batch, secret gen, auto-port
2026-06-06 18:23:47 +08:00
mirivlad
f88376264d
fix: reorder journal worklog sections
2026-06-06 02:53:36 +08:00
mirivlad
40c0953904
fix: skip deleted entries in navigation history
2026-06-06 02:42:20 +08:00
mirivlad
0cd8a79049
feat: restore global search in app header
2026-06-06 02:39:29 +08:00
mirivlad
cf770262e5
fix: reset capture drag state reliably
2026-06-06 02:30:54 +08:00
mirivlad
6033ccffa9
Add Verstak agent project rules
2026-06-06 01:33:39 +08:00
mirivlad
a37afd3b67
fix: trash integrity for TypeFile nodes — file record soft-delete, correct preview/restore
2026-06-05 17:31:18 +08:00
mirivlad
64e6c6f735
fix: trash file preview, visual CSS, virtual folder model
...
- Added resolveTrashPath() backend function: walks ancestor chain to find
files inside deleted/moved folders (flat trash directory)
- Added TrashFsPath to TrashNodeDTO, computed during ListTrash via
parent-to-child propagation of physical trash path
- Fixed visual CSS for trash rows: button reset (no white bg, transparent,
inherit font/color), hover styles match app dark theme
- Root view filters out descendant nodes (only shows top-level items)
2026-06-05 17:05:35 +08:00
mirivlad
5257789a4d
fix: trash duplicate path, journal tabs, today undefined, mouse back, inbox search
...
- Trash: removed duplicate fsPath display, folders/files open by clicking icon/name
- Trash: removed separate 'Open' button, only restore/delete right-aligned
- Trash: added ReadTrashFileContent binding + preview for files
- Trash: breadcrumb path under title, compact date display
- Journal: split into 'Предложения' + 'Журнал работы' tabs
- Journal: suggestions tab opens by default
- Today: fixed undefined in feed (null-guard on eventType/title)
- Today: improved event type label readability (blue badge style)
- Today: folder_deleted clicks navigate to trash
- Mouse Back: added mouseup fallback for Wails compat, handle button 3/4
- SearchNodes: case-insensitive with LOWER()
- Inbox assign: added search hint placeholder
2026-06-05 16:49:00 +08:00
mirivlad
c512ada386
cleanup: remove stale frontend-dist assets, fix warnings
2026-06-05 16:21:21 +08:00
mirivlad
ceee03959b
cleanup: remove stale frontend-dist assets
2026-06-05 16:17:31 +08:00
mirivlad
2ed2ecf77a
Today screen: tabs (feed, suggestions, in-progress, captured) + inbox sort/group
...
- Новый экран 'Сегодня' разбит на 4 вкладки: Лента, Предложения,
В работе, Захвачено
- Лента отображает события за сегодня с кликабельными сущностями
- Предложения вынесены в отдельную вкладку (только предложения)
- В работе: изменённые файлы/заметки/действия за сегодня с сортировками
- Захвачено: захваченные элементы за сегодня с сортировками
- Неразобранное: сортировка по дате/имени/типу с направлением
- Неразобранное: переключатель 'Группировать по месту захвата'
- TodayScreen.svelte: новый компонент с 4 вкладками
- Новые i18n ключи для вкладок и сортировок
- Backend: ListTodayInProgress, ListTodayCaptures bindings
- Все переходы из вкладок ведут в соответствующее место программы
2026-06-05 16:17:22 +08:00
mirivlad
c8aaf36533
fix: stabilize trash navigation and action icons
2026-06-05 14:41:40 +08:00
mirivlad
1fa009b1e2
feat: complete trash restore and batch actions
2026-06-05 12:43:30 +08:00
mirivlad
10b287de7b
feat: aggregate journals across node subtrees
2026-06-05 12:37:25 +08:00
mirivlad
23f517dee3
feat: simplify inbox actions and group task tabs
2026-06-05 12:32:36 +08:00
mirivlad
6d15639b41
fix: normalize bare URLs in capture flow
2026-06-05 12:29:19 +08:00
mirivlad
56ef211418
chore: move app icons into frontend assets
2026-06-05 12:25:47 +08:00
mirivlad
22b05f57b4
fix: show inbox capture target context
2026-06-05 08:10:33 +08:00
mirivlad
a8df9d118c
fix: hide explorer action for inbox links
2026-06-05 08:07:39 +08:00
mirivlad
91b5629e01
fix: open inbox artifacts by type
2026-06-05 08:06:06 +08:00
mirivlad
db47d31183
docs: describe unified capture inbox flow
2026-06-05 07:51:08 +08:00
mirivlad
4755d3199d
chore: update embedded gui assets
2026-06-05 07:51:00 +08:00
mirivlad
0e5d13ff01
fix: ignore global hotkeys in editable fields
2026-06-05 07:47:07 +08:00
mirivlad
f112e9a2d0
feat: add local inbox and links tabs
2026-06-05 07:44:38 +08:00
mirivlad
c1dfc456ec
feat: unify frontend capture pipeline
2026-06-05 07:41:15 +08:00
mirivlad
9e70e36f7f
feat: add native clipboard capture bridge
2026-06-05 07:34:45 +08:00
mirivlad
bcb093d453
feat: resolve inbox links separately
2026-06-05 07:33:10 +08:00
mirivlad
336037d887
feat: track capture context in inbox
2026-06-05 07:30:00 +08:00
mirivlad
6eaa4cda49
feat: assign and delete inbox artifacts
2026-06-05 02:15:27 +08:00
mirivlad
a96a316883
feat: capture files and images in inbox
2026-06-05 02:06:21 +08:00
mirivlad
326f6f283d
feat: capture clipboard links in inbox gui
2026-06-05 01:55:38 +08:00
mirivlad
44d0be2649
feat: add text and url inbox capture
2026-06-05 01:46:22 +08:00