Виджеты

Проектные панели поверх локального ResearcherOS: пакет лежит в koi-structure/widgets/, ядро только обнаруживает манифест и монтирует mount() в #koi-widgets-root. Ядро приложения ради виджета не меняют.

Слот для картинки или видео

Как работает

Виджет — папка в исследовании:

tree/<repo>/koi-structure/widgets/<widget-id>/
  manifest.yaml
  README.md
  web/
    widget.js    # export async function mount(host, ctx)
    widget.css
  backend/       # опционально: fetch.py → dict

Манифест задаёт id (как имя папки), title, summary, visibility, surfaces (web / desktop), default_enabled, точку входа.

При загрузке главной страницы клиент запрашивает каталог GET /api/widgets, для каждого включённого с web_url динамически импортирует JS и вызывает mount(host, ctx). Контекст: api, id/key виджета, assetBase, манифест.

Включение/выключение хранится в .run/widgets.json (ключ project_id/widget_id), не в Git проекта — локальный выбор на машине.

Общие хелперы UI (например плавающее окно): /widgets/_base/floating.js из widgets/base/web/ в репозитории ResearcherOS. Ассеты пакета: /widgets/<project_id>/<id>/….

Опционально бэкенд: если есть backend/fetch.py с fetch() -> dict, UI зовёт GET /api/widgets/<project>/<id>/data (квоты, метрики кластера и т.п.).

Пример из манифеста: «Cursor usage» — кольцо остатка квоты Cursor; другие проекты кладут свои панели (ресурсы, кастомный мониторинг).

Как человек работает в интерфейсе

  1. Виджеты появляются сами на главном workspace, если пакет есть и включён (часто плавающий элемент поверх карты).
  2. Включение через CLI (или API), не через отдельную большую «витрину» в UI:
python -m widgets.base.cli list
python -m widgets.base.cli enable  <project_id>/<widget-id>
python -m widgets.base.cli disable <project_id>/<widget-id>
  1. Чтобы добавить виджет в проект: положить папку по контракту выше в koi-structure/widgets/, закоммитить в ветку исследования, перезагрузить страницу.
  2. Hub задуман как место публикации переиспользуемых виджетов (как скиллы); живая правка пакета — локально в своём проекте.

Отдельного скилла «виджет» нет: это расширение UI, не сценарий агента. Агент может помочь написать widget.js, но монтирование — ответственность runtime.

Какие сценарии для агента подключаются

Что Роль
Нет обязательного skill Виджет не в очереди Inbox
Ручная разработка Агент в IDE правит файлы в widgets/<id>/ по контракту README
Hub (каталог) Позже — browse/download чужих пакетов; сейчас акцент на project-local

Как устроено технически

Engine vs project

Где Что
ReseachOS/widgets/base/ манифест, registry, CLI, floating.js
tree/…/koi-structure/widgets/ пакеты исследователя
web/widgets-loader.js загрузка и mount
#koi-widgets-root в index.html контейнер
api/routers/widgets.py + api/web_proxy.py каталог, data, раздача статики

Legacy: cursor-usage-widget.js — shim на тот же initWidgets.

Контракт mount

export async function mount(host, ctx) {
  // ctx.api, ctx.widgetId, ctx.widgetKey, ctx.assetBase, ctx.manifest
  return () => { /* unmount */ };
}

Ограничения

  • Без валидного манифеста и entry.web пакет не попадёт в каталог с URL.
  • Состояние enable локальное (.run/widgets.json) — у коллеги виджет нужно включить отдельно (или сменить default_enabled в манифесте).
  • Desktop surface в манифесте зарезервирован; текущий loader — web.

Связанные страницы

Текст: content/widgets.md. Медиа: media/widgets-hero.*. Контракт пакета: widgets/README.md.