Перейти к содержимому

Участие в разработке

Окно терминала
git clone https://github.com/lidge-jun/opencodex.git
cd opencodex
bun install
bun run dev:proxy # прокси-API в режиме разработки
bun run dev:gui # dev-сервер дашборда (другой терминал)
bun run typecheck # bun x tsc --noEmit
bun run test # bun test ./tests/

bun run dev остаётся псевдонимом для bun run dev:proxy. Dev-сервер дашборда — bun run dev:gui; упакованный дашборд, доступный по GET /, собирается командой bun run build:gui (gui/dist).

Корневой пакет — Bun-нативный TypeScript; отдельного шага компиляции сервера нет. Используйте скрипты из репозитория, чтобы локальные команды совпадали с CI:

Окно терминала
bun run typecheck # строгая проверка TypeScript
bun run test # полный набор tests/
bun test tests/router.test.ts # отдельный тестовый файл
bun run build:gui # сборка GUI на Vite + подготовка пакета
bun run privacy:scan # проверка учётных данных/приватности, используемая в CI
bun run prepare:package # обновление лаунчеров/ресурсов пакета

Большинство тестов — плоские Bun-тесты tests/*.test.ts. В tests/helpers/ лежат общие fixtures, а в tests/e2e-style/ — более широкие сценарии нативного паритета. Добавляйте сфокусированный регрессионный тест рядом с существующими тестами изменяемой подсистемы; если затронуты общая маршрутизация, адаптеры, конфигурация или поведение сервера, запускайте полный набор.

Сайт документации, который вы сейчас читаете, находится в docs-site/ (Astro + Starlight):

Окно терминала
cd docs-site && bun install && bun dev

Публичная документация публикуется на GitHub Pages по адресу https://opencodex.me/ru/. Воркфлоу .github/workflows/deploy-docs.yml запускается на push в main, затрагивающих docs-site/** или сам воркфлоу, собирает docs-site и разворачивает сгенерированный сайт. Перед push изменений документации выполните:

Окно терминала
cd docs-site
bun install --frozen-lockfile
bun run build

GitHub Actions намеренно остаются компактными:

  • Windows CI (.github/workflows/ci.yml) запускается на pull request и push в main, затрагивающих файлы рантайма, тестов, пакета, скриптов, TypeScript или воркфлоу. Windows jobs выполняют install, typecheck, тесты, privacy scan, smoke-сборку release-helper, сборку GUI, ocx help и проверяют npm global install без отдельно установленного Bun — за счёт runtime, входящего в состав пакета.
  • Release (.github/workflows/release.yml) запускается вручную. Он не служит вторым полным CI-пайплайном; перед dry-run или publish он требует, чтобы для точного релизного коммита (GITHUB_SHA) уже был успешный запуск Windows CI.
  • Super express release (.github/workflows/super-express-release.yml) — ручной путь упаковки для Windows. Он разрешает выбранный ref в один неизменяемый SHA коммита и, как Release, отказывается от публикации, если для этого точного SHA нет успешного Windows CI. Десктопный релиз содержит намеренно неподписанные Squirrel.Windows Setup.exe, RELEASES и полный .nupkg.

Неподписанный установщик Windows может вызвать предупреждение Unknown Publisher или Microsoft Defender SmartScreen. Соответствующие задания CI, упаковки и релиза запускают защитные сборщики артефактов даже после сбоя предыдущего шага. Они сохраняют в артефактах GitHub Actions только явно безопасные выходные файлы установщика/feed и метаданные запуска; сбой самого сборщика игнорируется, чтобы он не скрыл и не заменил исходный результат задания. Сохранение диагностических материалов не делает неудачную сборку пригодной для публикации.

Для релизов используйте helper:

Окно терминала
bun run release <version> # коммитит/пушит bump версии; publish workflow по умолчанию dry-run
bun run release <version> --publish # publish после осознанного CI-gated dry-run
bun run release:watch # наблюдение за последним запуском Release workflow
  • dev — цель интеграции по умолчанию. Открывайте PR сюда, если он не относится к специализированной ветке ниже.
  • dev2-go — параллельная линия интеграции для нативного порта на Go (go/, точка входа нативного рантайма и инструменты сборки Go-релизов). Принимает pull request’ы наравне с dev. Отправляйте сюда только работу, относящуюся к порту на Go; всё остальное — в dev. Автоматическая проверка целевой ветки допускает обе ветки и не различает их, поэтому границу определяет ревью: мейнтейнер может попросить сменить целевую ветку на dev.
  • main — только релизы. Двигается лишь при продвижении из dev мейнтейнером; не открывайте сюда PR с функциональностью.
  • preview — ветка предрелизов.

Пока проект переводит основной рантайм на нативный порт Go, всё, что попадает в dev, должно попадать и в dev2-go. Для контрибьюторов ничего не меняется: продолжайте открывать pull request’ы в dev. После merge мейнтейнер выполняет rebase этой работы на dev2-go и переносит то, чему нужен аналог в go/. Задача считается завершённой, только когда изменение есть в обеих линиях.

Pull request’ы с портированием и ребейзом приветствуются. Перенос исправления между линиями интеграции или ребейз устаревшей ветки на текущий head — это обычный вклад, а не шум. Укажите исходные коммиты в описании.

  • Только ES Modules (import/export), TypeScript, режим strict. Держите bun x tsc --noEmit без ошибок.
  • Не более ~500 строк на файл — разделяйте по ответственности (сайдкары web-search/ и vision/ — хорошие примеры небольших сфокусированных модулей за единым index.ts).
  • Обрабатывайте асинхронные ошибки на границах — сайдкары никогда не бросают исключения в путь запроса; они деградируют до корректного маркера.
  • Structure SOT — актуальные инварианты для мейнтейнеров живут в structure/. Публичные пользовательские сценарии держите в docs-site/, а исторические заметки расследований — в docs/.
  • Сохраняйте экспорты — от них могут зависеть другие модули.

Все селекторы провайдеров и seed-данные выводятся из канонического реестра (src/providers/registry.ts):

{
id: "my-provider",
label: "My Provider",
baseUrl: "https://api.example.com/v1",
adapter: "openai-chat",
authKind: "key",
dashboardUrl: "https://example.com/keys",
models: ["model-a", "model-b"],
defaultModel: "model-a",
noVisionModels: ["model-a"], // text-only models → vision sidecar describes images
},

src/providers/derive.ts передаёт эту запись в ocx init, ocx provider, пресеты дашборда, вход по API-ключу и seed-конфигурации OAuth. enrichProviderFromCatalog() копирует метаданные моделей и классификацию возможностей в сохранённую конфигурацию провайдера. Реализации OAuth-протоколов по-прежнему живут в src/oauth/; одни лишь метаданные реестра ещё не образуют OAuth-flow.

Реализуйте ProviderAdapter (см. Адаптеры) в src/adapters/, зарегистрируйте его имя в src/server/adapter-resolve.ts и приведите его вывод к внутренним событиям AdapterEvent. Переиспользуйте image.ts для работы с изображениями и ориентируйтесь на openai-chat.ts для обычной потоковой передачи и вызовов инструментов; используйте fetchResponse только когда адаптер сам управляет повторными попытками транспорта, а runTurn — для действительно двунаправленного транспорта вроде Cursor. Добавьте сфокусированные тесты в tests/ и экспортируйте фабрику из src/index.ts, если она входит в публичный API пакета.

Проверяйте, прежде чем объявлять работу завершённой

Заголовок раздела «Проверяйте, прежде чем объявлять работу завершённой»

Запускайте самую узкую команду, которая доказывает ваше изменение: bun run typecheck для типов, сфокусированный bun test tests/<name>.test.ts или runtime-проверку для поведения, а затем более широкие проверки, соответствующие затронутой области. opencodex предпочитает небольшие проверяемые коммиты крупным пачкам изменений.