verstak/docs/09_Extensibility.md

5.1 KiB
Raw Blame History

Верстак — архитектура плагинов

Принцип

Верстак — это минималистичный движок с деревом дел. Всё, что не входит в минимальную модель, — плагин.

Плагин — это директория в .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

{
  "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:

-- Получить 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 — при закрытии.

Реестр типов дел

Плагины могут регистрировать новые типы:

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-описание предзаполненного дерева:

{
  "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 (отдельный проект).

Установка:

verstak plugin install calendar
verstak plugin enable calendar
verstak plugin list