wayBetter Store

(FOSS) Пул-реквест — это и есть заявка

Опубликуйте своё.

Тема — это один JSON-файл. Плагин — один JavaScript-файл. Сделайте, попробуйте в приложении, а затем добавьте в Каталог: одна папка в одном пул-реквесте или файл в issue, если вы не пользуетесь git. Для обоих способов нужен бесплатный аккаунт git.crt.fyi — и больше ничего.

1

Сделайте

Начните с рабочего файла. Генератор шаблонов создаст его за вас; в разделе «Создать» самого приложения (wayBetter → «Создать») есть примеры и актуальные значения темы.

Тема

Цвета, шрифты, углы, плотность, вёрстка, фон, эффекты. Трёх цветов достаточно; остальное выводится автоматически, а текст остаётся читаемым.

Или соберите её в приложении: «Оформление» → «Конструктор тем» → «Экспорт». В THEMES.md перечислено всё, что может задавать тема.

Плагин

Класс с start() и stop() и заголовок, в котором сказано, кто его сделал и что он использует.

Добавьте --ts, чтобы получить проект на TypeScript. В PLUGINS.md описаны API, разрешения и живая перезагрузка.

hide-trends.plugin.js
/**
 * @name Hide Trends
 * @description Hides the trends box in the right column, so the timeline is the only thing moving.
 * @version 1.0.0
 * @author you
 * @permissions network:none
 */
module.exports = class HideTrends {
  start() { wayBetter.api.injectCSS('hide-trends', '[data-testid="sidebarColumn"] section { display: none }'); }
  stop()  { wayBetter.api.clearCSS('hide-trends'); }
};

Каталог читает название, автора, версию, описание и разрешения плагина из этого заголовка, а название, автора и описание темы — из её JSON. Экран установки показывает те же значения, поэтому они никогда не расходятся.

2

Попробуйте

Каталог необязателен. Рабочим файлом уже можно делиться.

  • Бросьте файл в окно wayBetter. Вы увидите тот же экран установки, что и для элемента Каталога: название, автор, версия, SHA-256, разрешения, код.
  • Включите режим разработчика («Настройки» → «Разработчикам») на время работы: сохранённый плагин, файл темы или custom.css сразу перезагружается во всех вкладках.
  • Делитесь без Каталога. Отправьте файл или ссылку waybetter://install на https-адрес на waybetter.fyi, cdn1.crt.fyi или на исходный файл на git.crt.fyi. Без экрана установки он никогда не устанавливается.
3

Добавьте одну папку

Каждый элемент Каталога — это папка внутри store/<app>/ в репозитории. Имя папки — это id элемента и его адрес здесь: /store/plugins/<id>/.

store/x/ — элементы wayBetter for X
store/x/plugins/hide-trends/
  hide-trends.plugin.js   the plugin, exactly as it installs
  item.json               { "category": "focus", "tags": ["trends", "sidebar"] }
  preview.svg             optional, 640×400 (.svg or .png); drawn for you without one

store/x/themes/midnight-mint/
  theme.json              the theme, as Appearance → Export writes it
  item.json               { "version": "1.0.0" }
  preview.svg             optional; drawn from the theme without one
category
Плагины: reading, writing, filters, focus или tools. Темы: dark или light — берётся из mode темы, если вы его не указали.
tags
До 12 слов, по которым люди будут искать.
version
Только для тем (у плагина она указана в заголовке). Увеличивайте её, когда меняете файл.
Описание
Одно-два предложения о том, что он делает, не короче 50 символов. Первые 160 становятся описанием его страницы для поисковых систем.

Это и есть вся заявка. Страница, карточка, запись в поиске, превью ссылки, структурированные данные и запись в карте сайта создаются из подписанного каталога при сборке сайта. Полные правила — в store/README.md.

4

Запустите проверки

Внешнего CI нет. Проверки — это команды, которые вы запускаете перед отправкой, а мейнтейнер запускает ещё раз перед слиянием.

в вашем клоне
git submodule update --init
bun install --frozen-lockfile
bun run check:store      # your folder, against the Store's rules
bun run test             # everything else, including the site's SEO test
  • Id и названияid папки (a-z 0-9 -, до 40 символов), name.plugin.js, без дубликатов внутри приложения
  • Размерфайлы элементов до 2 МиБ, превью до 300 КБ в формате 16:10
  • Заголовок@name, @version, описание и строка @permissions, в которой указано network или network:none
  • Честные разрешенияnetwork:none отклоняется, если код вызывает fetch, XMLHttpRequest, WebSocket, EventSource или sendBeacon; вызовы защищённого API должны быть заявлены
  • Никакого удалённого коданикаких eval, new Function или import(); никаких скриптов и внешних файлов в превью; никаких @import и внешних URL в CSS темы
  • Каталогиз элементов собирается каталог, который принимают приложения (по правилам самого фреймворка), а опубликованный каталог по-прежнему соответствует своей подписи и хешам
  • Поиск и публикация ссылокзаголовок страницы до 60 символов, описание от 50 до 160, оба уникальны
5

Отправьте

Два пути. Для обоих нужен бесплатный аккаунт на git.crt.fyi: зарегистрироваться может любой, а каждый новый аккаунт вручную одобряет сопровождающий.

Пул-реквест

  1. Сделайте форк репозитория на git.crt.fyi.
  2. Добавьте свою папку в отдельной ветке и запустите проверки.
  3. Откройте пул-реквест. Шаблон спросит, что он делает и что использует.

Нет git? Откройте issue

  1. Выберите шаблон «Тема» или «Плагин».
  2. Прикрепите файл (и превью, если оно есть).
  3. Мейнтейнер добавит папку за вас.

Затем мейнтейнер подписывает

Ключ подписи Каталога намеренно хранится офлайн, поэтому слияние — ещё не публикация. После слияния мейнтейнер читает код, запускает waybetter store build и waybetter store sign на компьютере, где хранится ключ, и отправляет изменения. Сайт пересобирается, у вашего элемента появляется страница, и каждое приложение видит его при следующем чтении подписанного каталога.

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

{ }

Формат каталога

Один файл для всех приложений wayBetter. Вручную его никогда не редактируют: он собирается из папок.

catalog.json (формат 2)Открыто
{ "format": 2, "name": "wayBetter Store", "generatedAt": "2026-09-30T…Z", "items": [
  { "apps": ["x"], "kind": "plugin", "id": "thread-reader", "name": "Thread Reader",
    "author": "wayBetter", "version": "1.2.0", "description": "…",
    "category": "reading", "tags": ["threads"],
    "url": "https://waybetter.fyi/store/plugins/bt-thread-reader.plugin.js",
    "file": "bt-thread-reader.plugin.js", "sha256": "<64 hex>", "size": 10961,
    "preview": "https://waybetter.fyi/store/previews/plugin-thread-reader.svg",
    "permissions": ["ui", "clipboard", "commands", "network:none"] }
] }
  • Подписан. catalog.json.sig — это подпись Ed25519 для точных байтов catalog.json. Приложения проверяют её вшитым в них открытым ключом, а затем сверяют размер и SHA-256 каждой загрузки.
  • Строгий. Неизвестные поля, более 500 элементов или файл больше 1 МиБ — и каталог отклоняется целиком. store-catalog.schema.json — это JSON Schema; все правила — в STORE.md во фреймворке.
  • Общий. Каждый элемент указывает свой apps. Приложение проверяет весь файл и оставляет только свои элементы.
Aa

Языки

Это не элементы Каталога: все 51 язык встроены в приложение и загружаются по требованию.

  • Исправьте или завершите перевод в apps/desktop/locales/<tag>.json — пул-реквестом или через issue с приложенным изменённым файлом.
  • Проверьте его командой bun run i18n:check: ключи, заполнители, формы множественного числа, никакой разметки. Она должна вывести 0 error(s).
  • Он выходит со следующим обновлением приложения, а не через Каталог. В TRANSLATING.md описаны синтаксис сообщений и способ увидеть свои слова в приложении.

Посмотрите, что уже есть.

Каждый элемент Каталога показывает свой код. Плагины из комплекта — лучшие примеры того, как правильно пользоваться API.