steps 4-6 + doc overhaul: files, notes, GUI, plugins docs

DOCUMENTATION (shift from personal to universal product):
- README.md: rewritten with 'one product, different doors' framing,
  universal entities table, audience segments
- 01_Product_Spec.md: removed personal references (sshkeeper, Godot,
  DokuWiki, servers), added audience segments (freelancer, repairmaster,
  developer, maker, consultant), universal scenarios
- 02_Architecture.md: added 'Plugins (Extensibility)' section with
  calendar/kanban/importer/template examples
- 03_Data_Model_Storage.md: added section 6 on plugin extensibility
  (node_meta, type registry, SQL migrations per plugin)
- 09_Extensibility.md (NEW): full plugin architecture — Lua runtime,
  plugin.json, hooks, sandbox, templates, registry
- PLAN.md: added step 16 (plugins), updated status table
- 00_README.md: rewritten product index with plugin principle

CODE — STEP 4 (Files):
- migration 002: files table (id, node_id, filename, path,
  storage_mode, size, sha256, mime, ...)
- FileService: AddExternal, CopyIntoVault, Get, ListByNode,
  MarkMissing, DeleteToTrash, Open (xdg-open)
- file_test.go: 5 tests (external, copy-vault, list-node,
  delete-trash, MIME guess)

CODE — STEP 5 (Notes):
- migration 003: notes table (node_id PK, file_id, format,
  original_format, encrypted)
- NoteService: Create (node+file+link), Read, Save (with backup to
  .verstak/history/), Delete, Load
- note_test.go: 3 tests (create-read, save-backup, delete)

CODE — STEP 6 (GUI):
- cmd/verstak-gui/main.go: launches GUI server, opens browser
- internal/gui/server.go: HTTP API for nodes/notes/files/search
- internal/gui/index.html.go: full inline SPA frontend (dark theme,
  sidebar tree, cards grid, note editor, search, create modals)
- Navigation: sidebar tree → click node → detail view with
  children + files cards → tab switch (overview/notes/files)
  → create node/note via modal → edit note in fullscreen
  textarea → save (with history backup)

Acceptance: go build ./... pass, go build -tags gui ./cmd/verstak-gui pass,
  go test ./... pass (20+ tests). GUI serves on random port, opens browser.
  API returns JSON for all resource types.
This commit is contained in:
2026-05-30 20:35:04 +08:00
parent 69eb909d48
commit 39271fc28f
19 changed files with 1948 additions and 236 deletions
+30 -33
View File
@@ -1,69 +1,66 @@
# Верстак — индекс документации
**Верстак** — local-first рабочий vault для дел, клиентов, проектов, документов, заметок, файлов, скриптов, действий запуска, журнала работ и синхронизации между машинами.
**Верстак** — local-first рабочий vault, где всё организовано вокруг "дел".
Это не просто заметочник и не CRM. Главная сущность — **дело**.
Верстак нужен людям, у которых работа организована через дела,
а не через задачи.
Дело может быть:
- клиентом;
- сайтом клиента;
- личным проектом;
- Godot-проектом;
- набором документов;
- рецептом/инструкцией;
- архивом;
- разовой помощью человеку;
- рабочей областью вроде `Рецепты / MySQL / Backup сайта`.
- разовой работой.
Внутри дела живут:
- вложенные папки;
- Markdown-заметки;
- документы `docx/pdf/xlsx/odt`;
- скриншоты;
- архивы;
- исходники;
- скрипты;
- SQL-фрагменты;
- ссылки;
- запускаемые действия;
- документы (docx/pdf/xlsx/odt/png/zip);
- файлы любых типов;
- запускаемые действия (URL, файл, папка, команда);
- журнал работ;
- примерное время;
- история активности;
- связанные дела.
- история активности.
## Файлы пакета
1. [[01_Product_Spec]] — полное описание продукта и сценариев.
2. [[02_Architecture]] — архитектура core/GUI/TUI/CLI/server.
3. [[03_Data_Model_Storage]] — модель данных, SQLite, vault, files, notes, actions.
4. [[04_Sync_Backup_Activity]] — синхронизация, восстановление, backup, activity/time tracking.
5. [[05_UI_UX]] — экраны GUI/TUI, дерево, дело, поиск, документы, действия.
1. [[01_Product_Spec]] — описание продукта, аудитория, сценарии.
2. [[02_Architecture]] — архитектура core/GUI/TUI/CLI/server, плагины.
3. [[03_Data_Model_Storage]] — модель данных, SQLite, vault, files, notes.
4. [[04_Sync_Backup_Activity]] — синхронизация, backup, activity.
5. [[05_UI_UX]] — экраны GUI/TUI.
6. [[06_Roadmap]] — план разработки по этапам.
7. [[07_AI_Coder_Prompts]] — промпты для ИИ-кодера.
8. [[08_MVP_Checklist]] — чеклист первого MVP.
9. [[09_Extensibility]] — архитектура плагинов (Lua + шаблоны дел).
## Главные принципы
1. **Local-first.**
Рабочая копия всегда локальная. Сервер нужен для sync/backup/restore, но программа не должна зависеть от сервера каждый день.
1. **Local-first.**
Рабочая копия всегда локальная. Сервер для sync/backup.
2. **Данные принадлежат пользователю.**
Заметки и файлы физически лежат обычными файлами в vault. SQLite хранит индекс, связи, метаданные, FTS и sync state.
2. **Универсальная база + плагины.**
Базовая модель (дело + заметка + файл + действие + журнал)
работает для любого сегмента. Плагины добавляют календарь,
канбан, импортёры — без перекомпиляции.
3. **Дерево дел важнее тегов.**
Теги полезны, но основная навигация — вложенное дерево: `Клиенты / Ромашка / Сайт / Документы`.
3. **Данные принадлежат пользователю.**
Заметки и файлы лежат обычными файлами. SQLite — индекс.
4. **Не таймтрекер, а восстановитель следов.**
Верстак не требует постоянно нажимать Start/Stop. Он собирает следы работы и предлагает записать их в журнал.
4. **Дерево дел важнее тегов.**
5. **GUI основной, TUI быстрый, CLI служебный.**
GUI — основная рабочая среда. TUI — быстрый доступ из терминала. CLI — sync, import, scripts, rescue mode.
5. **Не таймтрекер, а восстановитель следов.**
6. **Sync не должен уничтожать данные.**
Нужны trash, conflict copies, versions, snapshots и retention.
6. **GUI основной, TUI быстрый, CLI служебный.**
7. **Sync не уничтожает данные.**
## Короткая формула
> Верстак — это локальный рабочий кабинет для людей, у которых жизнь состоит из проектов, клиентов, документов, заметок, скриптов, файлов, репозиториев и вечного “где я это сохранил?”.
> Верстак — локальная программа, где по каждому клиенту или проекту
> лежат все его файлы, заметки, документы, ссылки, действия и
> история работ.
+110 -180
View File
@@ -2,242 +2,172 @@
## 1. Проблема
У пользователя есть много разнородной рабочей информации:
У фрилансеров, мастеров, разработчиков и мейкеров есть много
разнородной рабочей информации:
- папка `work` и подпапки;
- архивы нужных файлов;
- служебки;
- договоры;
- письма;
- скриншоты;
- файлы с серийными номерами;
- инструкции;
- статьи по установке;
- скрипты;
- SQL-фрагменты;
- заметки в DokuWiki;
- доступы к серверам и сервисам клиентов;
- записи о нестандартных действиях;
- репозитории личных проектов;
- Godot-проекты;
- локальные утилиты вроде sshkeeper.
- клиентские проекты и переписка;
- договоры, счета, акты;
- заметки и инструкции;
- скриншоты и фото;
- скрипты и конфиги;
- доступы и серийники;
- файлы с правками и версиями.
Проблема не только в хранении. Проблема в **контексте**:
Проблема не в хранении. Проблема в **контексте**:
- что к чему относится;
- где лежит актуальная версия;
- где заметка по клиенту;
- где договор;
- где скрипт;
- где актуальная версия;
- что было сделано в прошлый раз;
- сколько примерно времени ушло;
- что можно сказать человеку, когда он спрашивает “сколько должен?”.
- сколько времени ушло;
- где договор, где заметка, где скрипт.
Обычные инструменты закрывают только кусок:
- Obsidian — заметки, но не рабочий кабинет с документами, действиями и журналом работ;
- DokuWiki — заметки, но не локальная рабочая оболочка над файлами и программами;
- CRM — клиенты и продажи, но не личная техническая память;
- файловый менеджер — файлы, но без смысла;
- таймтрекер — время, но требует дисциплины;
- лаунчер — запуск, но не память;
- Nextcloud — файлы, но не дела.
Обычные инструменты закрывают только кусок: Obsidian — заметки,
CRM — продажи, таймтрекер — время, файловый менеджер — файлы без смысла.
## 2. Что такое Верстак
**Верстак** — local-first рабочий vault, где всё организовано вокруг дел.
**Верстак** — local-first рабочий vault, где всё организовано вокруг "дел".
Дело — это контекст, в который складываются заметки, документы, файлы, действия и история работы.
Дело — это контекст, в который складываются заметки, документы,
файлы, действия и история работы.
Примеры дерева:
**Главная формула:**
> Верстак — локальная программа, где по каждому клиенту или проекту
> лежат все его файлы, заметки, документы, ссылки, действия и история работ.
## 3. Аудитория
Верстак нужен людям, у которых работа идёт через **дела**, а не через задачи.
Есть люди, которым нужен таск-трекер (task → done). А есть люди,
которым нужно место, где накапливается контекст по каждому клиенту
или проекту — и всё это доступно через месяц, через год.
### Сегменты
| Сегмент | Зачем Верстак |
|---------|---------------|
| Фрилансер / дизайнер | Клиенты, файлы, правки, история работ, отчёты |
| Мастер по ремонту/ПК | Клиенты, устройства, серийники, фото, журнал |
| Разработчик | Workspace: заметки, репозитории, команды, логи |
| Мейкер / писатель | Проекты: материалы, заметки, версии, история |
| Консультант | Клиенты, документы, журнал времени, отчёты |
## 4. Основные сущности (универсальные)
### Дело
Главный рабочий контекст. Поля: название, тип, родитель,
описание, статус (active / sleeping / archived), теги.
### Заметка
Markdown-файл внутри vault. Резервная копия при перезаписи.
### Файл / Документ
Любой файл, привязанный к делу. Открывается системным приложением.
### Действие
Кнопка запуска: URL, файл, папка, команда. Опасные — с подтверждением.
### Журнал работ
Записи о затраченном времени: дата, длительность, описание.
### Активность
Следы работы: открыт файл, изменена заметка, запущено действие.
Используется для восстановления времени.
## 5. Примеры дерева (универсальные)
```text
Клиенты
ООО Ромашка
Сайт
Обзор.md
Документы
Скрипты
Скриншоты
Журнал работ
Почта
Договоры
Личные проекты
sshkeeper
Roadmap.md
Releases
dist
Действия
Tyaplyapiya
Godot project
Design notes
Проекты
Мой проект
Notes
Assets
dist
Рецепты
MySQL
Очистка таблиц
Backup dump
Сайты
Backup сайта одной строкой
Очистка кеша WordPress
Backup одной строкой
Очистка кеша
Документы
Служебки
Счета
Договоры
Серийники
```
## 3. Основные сущности
## 6. Сценарии (сегмент-agnostic)
### Дело
Главный рабочий контекст.
Поля:
- название;
- тип: клиент / проект / рецепт / документальная область / архив / личное;
- родитель;
- описание;
- статус: active / sleeping / archived;
- теги;
- связанные ссылки;
- связанные actions;
- журнал работ.
### Заметка
Обычный Markdown-файл внутри vault.
Примеры:
- `overview.md`;
- `nginx.md`;
- `mysql-cleanup.md`;
- `roadmap.md`;
- `access.secret.md`.
### Документ
Файл внутри дела:
- `docx`;
- `xlsx`;
- `pdf`;
- `odt`;
- `png/jpg`;
- `zip`;
- любые другие файлы.
В MVP документы открываются системным приложением. Встроенный preview можно добавить позже.
### Действие
Кнопка, которую можно запустить из дела:
- открыть URL;
- открыть папку;
- открыть файл;
- запустить Godot;
- открыть IDE;
- запустить sshkeeper;
- выполнить скрипт;
- открыть терминал;
- собрать проект.
### Журнал работ
Записи вида:
```text
2026-05-30
Дело: ООО Ромашка / Сайт
Время: примерно 3ч
Описание: обновил витрину сайта, товары, баннеры, проверил отображение.
```
### Активность
Сырые следы:
- открыто дело;
- открыта заметка;
- изменён файл;
- запущено действие;
- открыта папка;
- later: активное окно;
- later: browser URL;
- later: sshkeeper session.
## 4. Основные сценарии
### Клиентская работа
### Работа с клиентом
1. Открыть дело клиента.
2. Посмотреть заметки и документы.
3. Открыть админку сайта.
4. Запустить sshkeeper или скрипт.
5. Добавить скриншоты.
6. Записать работу.
7. Сформировать текст отчёта.
3. Открыть связанный URL или папку.
4. Добавить файлы.
5. Записать время.
6. Сформировать отчёт для клиента.
### Личный проект
1. Открыть проект `sshkeeper`.
2. Нажать Открыть IDE.
3. Нажать “Собрать”.
4. Посмотреть roadmap.
5. Добавить заметку “на чём остановился”.
### Импорт DokuWiki
1. Выбрать `data/pages`.
2. Выбрать `data/media`.
3. Импортировать namespaces как дерево.
4. Сохранить оригиналы.
5. Постепенно разобрать по делам.
1. Открыть дело проекта.
2. Нажать "Открыть в IDE".
3. Обновить roadmap-заметку.
4. Записать "на чём остановился".
### Восстановление времени
Пользователь не нажимал таймер, но вечером видит:
```text
Похоже, ты работал по делу “ООО Ромашка / Сайт:
Похоже, работа по "Клиенты / Ромашка / Сайт":
14:0517:12, примерно 3ч.
Основания:
- открывалась админка сайта;
- открывался URL админки сайта;
- менялся catalog.xlsx;
- запускался sshkeeper profile;
- создавались скриншоты.
[Записать 3ч] [Исправить] [Игнорировать]
[Записать 3ч] [Изменить] [Игнорировать]
```
## 5. Что точно не делать в начале
## 7. Расширяемость
Базовые сущности универсальны. Плагины добавляют функционал
без перекомпиляции программы:
- шаблоны дел (клиент, ремонт, проект, рецепт...);
- календарь;
- канбан;
- импортёры (DokuWiki, Obsidian, plain folder);
- интеграции с внешними сервисами.
Подробнее: [docs/09_Extensibility.md](docs/09_Extensibility.md).
## 8. Что не делать в начале
- не делать SaaS;
- не делать multi-user CRM;
- не делать встроенный офисный пакет;
- не делать полноценный password manager;
- не делать офисный пакет;
- не делать password manager;
- не делать ИИ;
- не делать мобильное приложение;
- не делать сложные права пользователей;
- не делать бухгалтерию;
- не пытаться автоматически понимать всё.
- не делать бухгалтерию.
## 6. Уникальность
## 9. Уникальность
Верстак отличается тем, что объединяет:
- заметочник;
- файловый кабинет;
- project launcher;
- журнал работ;
- рабочий контекст;
- sync/backup;
- TUI/GUI;
- миграцию из DokuWiki.
Но всё это не как отдельные модули, а вокруг одного понятия: **дело**.
Верстак объединяет заметочник, файловый кабинет, лаунчер,
журнал работ и контекст вокруг одного понятия: **дело**.
Плагины делают его адаптируемым под любой сегмент.
+19 -1
View File
@@ -311,7 +311,25 @@ Scanner сравнивает реальность с SQLite:
- moved file later;
- hash mismatch.
## 6. Внешние приложения
## 6. Плагины (Extensibility)
Верстак изначально проектируется как база с плагинами.
Базовая модель (дело + заметка + файл + действие + журнал)
универсальна. Плагины добавляют функционал без перекомпиляции.
Примеры плагинов:
- `calendar` — календарь событий с привязкой к делам
- `kanban` — доска задач внутри дела
- `importer-dokuwiki` — импорт из DokuWiki
- `importer-obsidian` — импорт из Obsidian
- `browser-activity` — отслеживание браузерной активности
- `secret-notes` — зашифрованные заметки
- `client-template` — шаблон "Клиент" с полями (сайт, домен, ...)
Архитектура плагинов: [docs/09_Extensibility.md](docs/09_Extensibility.md)
### Внешние приложения
Верстак не пишет свой офисный пакет.
+14
View File
@@ -274,3 +274,17 @@ CREATE TABLE sync_ops (
- private keys;
- token-like values;
- binary content in MVP.
## 6. Расширяемость через плагины
Базовая схема фиксирована и поддерживает плагины:
- Новые типы нод регистрируются плагинами через Lua API
(`verstak.node.register_type()`) — схема таблицы `nodes` не меняется,
`type` принимает любое строковое значение.
- Мета-поля (`node_meta`) хранят произвольные key-value пары,
зарегистрированные плагинами.
- Плагины могут создавать собственные таблицы через SQL-миграции
в своей директории `.verstak/plugins/<name>/migrations/`.
- `device_id` на уровне nodes позволяет плагинам синхронизировать
свои данные через sync_ops.
+159
View File
@@ -0,0 +1,159 @@
# Верстак — архитектура плагинов
## Принцип
Верстак — это минималистичный движок с деревом дел.
Всё, что не входит в минимальную модель, — плагин.
Плагин — это директория в `.verstak/plugins/<name>/`, которую
программа подхватывает без перекомпиляции.
## Структура плагина
```
.verstak/plugins/<name>/
plugin.json # мета: name, version, author, hooks
main.lua # точка входа
templates/ # шаблоны дел (опционально)
client.json
repair.json
panels/ # UI-панели для GUI (опционально)
kanban.html
calendar.html
migrations/ # SQL-миграции (опционально)
001_create_tables.sql
```
## plugin.json
```json
{
"name": "calendar",
"version": "1.0.0",
"author": "...",
"description": "Календарь событий, привязанных к делам",
"hooks": {
"on_init": "on_init",
"on_node_open": "on_node_open"
},
"node_types": ["event"],
"panel": "panels/calendar.html",
"migrations": ["migrations/001_create_tables.sql"]
}
```
## Lua API
Плагины пишутся на Lua (gopher-lua). API:
```lua
-- Получить node по ID
local node = verstak.node.get(id)
-- Создать node
local n = verstak.node.create(parent_id, "type", "title")
-- Получить config value
local v = verstak.config.get("key")
-- Записать в activity log
verstak.activity.log({
node_id = n.id,
event_type = "calendar_event",
title = "Встреча с клиентом"
})
-- Зарегистрировать HTTP-эндпоинт (для GUI)
verstak.http.route("GET", "/api/calendar/events", get_events)
-- Показать уведомление
verstak.ui.toast("Событие добавлено")
```
## Жизненный цикл плагина
1. **on_init** — при старте программы, до открытия vault.
Инициализация, создание таблиц.
2. **on_vault_open** — при открытии vault.
3. **on_node_create / on_node_open / on_node_delete** — хуки на действия.
4. **on_shutdown** — при закрытии.
## Реестр типов дел
Плагины могут регистрировать новые типы:
```lua
verstak.node.register_type({
name = "event",
label = "Событие",
icon = "calendar",
fields = {
{ name = "date", label = "Дата", type = "date" },
{ name = "time", label = "Время", type = "time" },
{ name = "location", label = "Место", type = "text" },
}
})
```
GUI рисует карточку дела на основе зарегистрированных полей типа.
## Шаблоны дела
Шаблон — JSON-описание предзаполненного дерева:
```json
{
"name": "Клиент",
"icon": "user",
"tree": [
{ "type": "folder", "title": "Документы" },
{ "type": "folder", "title": "Переписка" },
{ "type": "folder", "title": "Скриншоты" },
{ "type": "note", "title": "Overview" },
{ "type": "action", "title": "Открыть сайт", "kind": "open_url", "url": "" }
],
"meta": [
{ "key": "domain", "label": "Домен сайта", "type": "text" },
{ "key": "admin_url", "label": "Админка", "type": "url" }
]
}
```
GUI: при создании дела пользователь выбирает шаблон — и дерево
создаётся автоматически.
## Песочница
Lua-плагины работают в песочнице:
- нет доступа к файловой системе напрямую (только через API vault);
- нет `io.*`, `os.execute` и т.д.;
- память ограничена;
- нет сетевых вызовов кроме зарегистрированных HTTP-эндпоинтов.
Go-плагины (buildmode=plugin) доступны для продвинутых
разработчиков, но требуют совместимости версий.
## Инициализация
При старте `verstak init` создаёт `.verstak/plugins/`.
При старте GUI/CLI/TUI:
1. Сканировать `.verstak/plugins/*/plugin.json`
2. Валидировать (имя, версия, структура)
3. Загрузить миграции и выполнить
4. Загрузить Lua-скрипты через gopher-lua
5. Вызвать `on_init` у каждого плагина
6. Зарегистрировать node types, HTTP routes, UI panels
## Распространение
Плагин — это zip-архив с правильной структурой.
Репозиторий плагинов: `verstak-registry` (отдельный проект).
Установка:
```bash
verstak plugin install calendar
verstak plugin enable calendar
verstak plugin list
```
+29 -1
View File
@@ -13,7 +13,7 @@
|---|-----|--------|
| 1 | Git init + Skeleton | ✅ выполнен |
| 2 | Init + SQLite + First Migration | ✅ выполнен |
| 3 | Nodes Repository + CRUD + CLI Node | ⬜ не начат |
| 3 | Nodes Repository + CRUD + CLI Node | ✅ выполнен |
| 4 | Vault Files: Trash + File Service + CLI File | ⬜ не начат |
| 5 | Markdown Notes: Create/Read/Save + CLI Note | ⬜ не начат |
| 6 | Wails GUI MVP: Sidebar + Main Panel | ⬜ не начат |
@@ -26,6 +26,7 @@
| 13 | Activity + File Scanner/Watcher | ⬜ не начат |
| 14 | TUI MVP (Bubble Tea) | ⬜ не начат |
| 15 | Integrity Check + Repair + Vault Restore | ⬜ не начат |
| 16 | Plugins System (Lua + Templates) | ⬜ не начат |
---
@@ -334,6 +335,32 @@
---
## ШАГ 16 — Система плагинов (Lua + шаблоны дел)
**Цель:** можно положить Lua-скрипт в `.verstak/plugins/` — и он работает.
**Acceptance:**
- `.verstak/plugins/<name>/plugin.json` — мета
- `main.lua` — загрузка через gopher-lua
- `on_init`, `on_vault_open`, `on_node_create` хуки
- `verstak.node.register_type()` — новые типы дел
- `verstak.http.route()` — API для GUI
- шаблоны дела (JSON) → предзаполненное дерево
- CLI: `verstak plugin list / install / enable`
**Действия:**
- `internal/core/plugins/manager.go` — сканирование, загрузка, валидация
- Lua runtime (gopher-lua) с песочницей
- Plugin API: node, config, activity, http, ui, vault
- Миграции плагинов (SQL)
- Реестр типов дел → GUI рендерит разные карточки
- CLI: plugin list/install/enable
- Базовый шаблон дела (client.json)
**Commit:** `step 16: plugins system`
---
## Сводка структуры репозитория
```
@@ -363,6 +390,7 @@ verstak/
sync/
security/
config/
plugins/
frontend/ # Wails frontend (Svelte/Vue)