> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xneon.org/llms.txt
> Use this file to discover all available pages before exploring further.

# @xnlc/types: единый источник типов для Xneon Launcher Core

> Полный обзор пакета @xnlc/types: все типы данных, IPC-контракты, launch-типы, серверные типы и инструкция по добавлению новых IPC-каналов в монорепозиторий Xneon Launcher.

`@xnlc/types`: единый источник типов для всего монорепозитория Xneon Launcher. Все остальные пакеты (`@xnlc/core`, `@xnlc/mods`, `@xnlc/servers`, `@xnlc/skins`, `@xnlc/nbt`) и Electron main/renderer импортируют типы отсюда. Это исключает дублирование определений и обеспечивает согласованность между процессами.

Пакет чисто типовой: не содержит runtime-кода, только TypeScript-интерфейсы и type-алиасы. Используется как `devDependency` или `dependency` во всех ESM-пакетах проекта.

## Установка

Добавьте в проект `.npmrc` (если еще не добавлен):

```ini theme={null}
@xnlc:registry=https://git.xneon.org/api/packages/MAINER4IK/npm/
```

```bash theme={null}
pnpm add -D @xnlc/types
```

## Структура типов

Типы организованы по доменам. Основной файл `src/index.ts` реэкспортирует все группы:

```typescript theme={null}
import type {
  // Domain
  DbAccount, DbBuild, DbBuildLight,
  // Laby
  LabySkin, LabyCatalogPage,
  // Mod
  ModSearchResult, ModDetails,
  // IPC
  IpcInvokeMap, IpcEventMap, ElectronAPI,
  // Launch
  MinecraftLaunchParams, LaunchRequestOptions,
  // Worker
  WorkerLaunchPayload, WorkerMessage,
  // Server
  McServerInfo, McServerState, XnConnectState,
} from "@xnlc/types";
```

### Доменные типы (domain-types.ts)

<Accordion title="Аккаунты и авторизация">
  | Тип | Описание | | | |
  | - | - | - | - | - |
  | `DbAccount` | Учетная запись в базе данных: `id`, \`type: "elyby" | "xnskins" | "microsoft" | "offline"`, `username`, `uuid`, `accessToken`, `refreshToken`, `skinUrl`, `sortOrder\` |
  | `AuthPayload` | Результат авторизации: `id`, `username`, `uuid`, `accessToken`, `refreshToken` | | | |
  | `AuthSession` | Сессия для запуска: `uuid`, `username`, `accessToken`, `profileId`, `profileName` | | | |
  | `DeviceCodeStart` | Начало device-code flow: `deviceCode`, `userCode`, `verificationUri`, `expiresIn` | | | |
  | `DeviceCodePoll` | Результат опроса: `pending`, `expired`, `complete` (с `AuthPayload`), `error` | | | |
</Accordion>

<Accordion title="Сборки (builds)">
  | Тип | Описание |
  | - | - |
  | `DbBuild` | Полная модель сборки: имя, версия MC, загрузчик, моды, ресурспаки, шейдеры, Java-переопределения, команды до/после запуска, wrapper, переменные окружения |
  | `DbBuildLight` | Облегченная модель (без списков модов) для быстрой загрузки списка сборок |
  | `DbBuildMod` | Мод в сборке: `id`, `slug`, `name`, `version`, `source`, `enabled` |
  | `BuildIntentScanResult` | Результат сканирования папки сборки: найденные моды, ресурспаки, шейдеры |
  | `BuildExportCategory` | Категории экспорта: `"mods"`, `"resourcepacks"`, `"shaderpacks"`, `"saves"`, `"data"`, `"logs"` |
  | `BuildContentUpdates` | Доступные обновления контента сборки с учетом канала (`release`/`beta`/`alpha`) |
  | `UpdateChannel` | `"release"`, `"beta"`, `"alpha"` |
</Accordion>

<Accordion title="Миры, скриншоты, серверы">
  | Тип | Описание |
  | - | - |
  | `WorldInfo` | Информация о мире: `folder`, `name`, `seed`, `gameMode`, `hardcore`, `lastPlayed`, `mcVersion`, `iconDataUrl` |
  | `DatapackInfo` | Датапак: `name`, `sizeBytes`, `lastModified` |
  | `ScreenshotInfo` | Скриншот: `name`, `thumbDataUrl`, `sizeBytes`, `lastModified` |
  | `QuickPlayEntry` | Быстрый доступ: одиночный мир или сервер с `label`, `address`, `lastPlayed` |
</Accordion>

<Accordion title="Java и хранилище">
  | Тип | Описание |
  | - | - |
  | `JavaDetectResult` | Найденная Java: `path`, `version`, `label`, `vendor`, `arch` |
  | `JavaRuntimeEntry` | Скачанный рантайм: `path`, `component`, `size`, `label`, `versionLabel` |
  | `StorageScanResult` | Результат скана хранилища: размеры сборок, серверов, корзины, Java |
  | `StorageCleanTarget` | Цель очистки: логи, краш-репорты, кэш, корзина, рантайм |
  | `StorageCleanResult` | Результат очистки: `success`, `freedBytes` |
</Accordion>

<Accordion title="Облако">
  | Тип | Описание |
  | - | - |
  | `CloudUploadCategory` | Категории синхронизации: моды, ресурспаки, миры, конфиги, плагины и др. |
  | `CloudFile` | Файл в облаке: `id`, `name`, `size`, `category`, `downloadUrl` |
  | `CloudUser` | Пользователь облака: `id`, `username`, `email` |
  | `CloudStorageInfo` | Квота: `used_bytes`, `limit_bytes` |
</Accordion>

<Accordion title="Статистика">
  | Тип | Описание |
  | - | - |
  | `GameSessionInfo` | Игровая сессия: `buildId`, `buildName`, `startedAt`, `endedAt`, `duration` |
  | `ServerSessionInfo` | Сессия сервера: `serverId`, `serverName`, `startedAt`, `endedAt`, `duration` |
  | `StatsOverview` | Обзор статистики: время игры, сессии, топ сборок, топ серверов, дневные графики |
  | `StatsRange` | Диапазон дат для агрегации: `from`, `to` (epoch ms) |
</Accordion>

<Accordion title="Импорт">
  | Тип | Описание |
  | - | - |
  | `ImportableLauncherInstance` | Обнаруженная сборка из другого лаунчера (Prism, MultiMC, GDLauncher и др.) |
  | `ImportProgress` | Прогресс импорта: `current`, `total`, `message`, `itemName` |
  | `ModpackImportResult` | Результат импорта модпака: версия, загрузчик, моды, конфликты |
  | `ModpackImportConflict` | Конфликт импорта: `duplicate` (такой модпак уже есть) или `name` (имя занято) |
</Accordion>

### Типы скинов (laby.ts)

| Тип | Описание | |
| - | - | - |
| `LabySkin` | Скин из каталога Laby: текстуры, теги, счетчик использования | |
| `LabyCatalogPage` | Страница каталога: скины, общее количество, флаг `endOfFeed` | |
| `LabyTag` | Тег каталога: `id`, `name`, `description` | |
| `LabyPlayer` | Профиль игрока: `uniqueId`, ник, скины | |
| `LabyPlayerSkin` | Скин игрока: вариант (`classic`/`slim`), URL текстуры | |
| `LabyOrder` | Порядок сортировки каталога | |
| `LabyImportResult` | Результат импорта скина в библиотеку | |
| `LibrarySkin` | Скин в локальной библиотеке: `id`, `name`, `variant`, `capeId`, `sourceId` | |
| `McProfile` | Minecraft-профиль: `id`, `name`, массив `skins` и `capes` | |
| `MinecraftSkin` | Активный скин: `id`, `url`, \`variant: "CLASSIC" | "SLIM"\` |
| `MinecraftCape` | Плащ: `id`, `url`, `alias` | |

### Типы модов (mod-types.ts)

| Тип | Описание |
| - | - |
| `ModContentType` | `"mod"`, `"resourcepack"`, `"shader"`, `"modpack"` |
| `ModSort` | Варианты сортировки поиска |
| `ModLoaderFilter` | Фильтр по загрузчику |
| `ModSource` | `"modrinth"`, `"curseforge"`, `"local"` |
| `ModEnvironment` | `"client"`, `"server"`, `"both"`, `"optional"` |
| `ModSearchResult` / `ModSearchResponse` | Результат поиска модов |
| `ModDetails` | Детали проекта: описание, автор, ссылки, зависимости |
| `ModVersion` | Конкретная версия мода: номер, загрузчик, Minecraft, файлы |
| `ModDependency` | Зависимость: `projectId`, `versionId`, `optional` |
| `JarDeclaredDependency` / `JarDependencyInspection` | Зависимости, прочитанные из JAR-файла |
| `CurseForgeCategory` / `ModCategory` | Категории платформ |
| `FTBVersionManifest` | Манифест версии FTB-модпака |

### Типы запуска (launch-types.ts)

| Тип | Описание |
| - | - |
| `MinecraftLaunchParams` | Полные параметры запуска для IPC-канала `minecraft:launch` |
| `MinecraftProgress` | Прогресс загрузки: тип, фаза, процент, байты |
| `MinecraftCloseInfo` | Информация о завершении процесса: код, сигнал, причина |
| `JavaProgress` | Прогресс скачивания/установки Java |
| `LaunchRequestOptions` | Опции запуска для воркера: версия, загрузчик, память, Java |
| `ResolvedLaunchRequest` | Разрешенный запрос с дефолтами |

### Типы воркера (worker-types.ts)

| Тип | Описание |
| - | - |
| `WorkerAccountPayload` | Данные аккаунта для воркера |
| `WorkerLaunchPayload` | Данные запуска для воркера |
| `WorkerMessage` | Сообщения между main и воркером процесса |

<Note>
  Воркер запуска находится в `electron/main/minecraft-launch-worker.ts`. Он изолирует длительные операции (скачивание, установка) от main-процесса Electron.
</Note>

### Типы серверов (server-types.ts)

| Тип | Описание |
| - | - |
| `McServerInfo` | Полная информация о сервере: имя, версия, ядро, порт, Java, XN Connect relay |
| `McServerState` | Состояние: `stopped`, `starting`, `running`, `stopping` + `pid`, `startTime` |
| `McServerMetrics` | Метрики: `cpuPercent`, `memoryMb`, `uptimeSeconds` |
| `McPlayerEntry` | Игрок: `uuid`, `name` |
| `McFsEntry` | Файл/папка файлового менеджера: `name`, `isDirectory`, `size`, `modifiedAt` |
| `ResolvedPlugin` | Установленный плагин/мод сервера |
| `XnConnectState` | Состояние туннеля XN Connect |
| `XnConnectUsage` | Использование туннеля: лимиты и текущая нагрузка |
| `McServerDownloadProgress` | Прогресс скачивания серверного ядра |
| `ServerStatusResult` | Результат SLP-пинга: онлайн, MOTD, версия, пинг |

## IPC-контракты (ipc-contracts.ts)

Самая важная часть `@xnlc/types` для разработки лаунчера. `IpcInvokeMap` и `IpcEventMap` являются единственным источником правды для всех каналов IPC между Electron main и renderer.

### IpcInvokeMap

Каждый invoke-канал описывает кортеж аргументов и возвращаемый тип:

```typescript theme={null}
export interface IpcInvokeMap {
  "system:get-total-memory": { args: []; return: number }
  "auth:microsoft-login": { args: []; return: AuthPayload }
  "minecraft:launch": { args: [params: MinecraftLaunchParams]; return: { success: boolean; error?: string } }
  "mods:modrinth-search": { args: [query, contentType?, gameVersion?, modLoader?, sortBy?, page?, categories?]; return: ModSearchResponse }
  // ... и ~120+ каналов
}
```

Ключевые группы каналов:

<Accordion title="Системные">
  | Канал | Аргументы | Возвращает |
  | - | - | - |
  | `system:get-total-memory` | | Общий объем RAM системы |
</Accordion>

<Accordion title="Авторизация">
  | Канал | Аргументы | Возвращает |
  | - | - | - |
  | `auth:elyby-login` | | `AuthPayload` |
  | `auth:elyby-device-start` | | `DeviceCodeStart` |
  | `auth:elyby-device-poll` | `deviceCode: string` | `DeviceCodePoll` |
  | `auth:microsoft-login` | | `AuthPayload` |
  | `auth:microsoft-device-start` | | `DeviceCodeStart` |
  | `auth:xnskins-login` | | `AuthPayload` |
</Accordion>

<Accordion title="Сборки">
  | Канал | Аргументы | Возвращает |
  | - | - | - |
  | `build:scan-intent-content` | `buildName: string` | `BuildIntentScanResult` |
  | `build:save-mod-to-intent` | `buildId, url, fileName` | Путь к файлу или `null` |
  | `build:export-zip` | `buildName, label, categories?` | `{ success, path?, error? }` |
  | `build:import-modrinth` | `buildName, projectSlug, versionId?, targetBuildId?` | `ModpackImportResult` |
  | `build:check-content-updates` | `buildId, channel?` | `BuildContentUpdates` |
</Accordion>

<Accordion title="Моды (каталоги)">
  | Канал | Аргументы | Возвращает | |
  | - | - | - | - |
  | `mods:modrinth-search` | `query, contentType?, gameVersion?, modLoader?, sortBy?, page?, categories?` | `ModSearchResponse` | |
  | `mods:modrinth-details` | `slug: string` | \`ModDetails | null\` |
  | `mods:curseforge-search` | Аналогично | `ModSearchResponse` | |
  | `mods:curseforge-details` | `modId: number` | \`ModDetails | null\` |
  | `mods:ftb-search` | `query, page?, options?` | `ModSearchResponse` | |
  | `mods:resolve-dependencies` | `version, source` | `ModDependency[]` | |
  | `mods:inspect-jar-dependencies` | `url, source` | `JarDependencyInspection` | |
  | `mods:check-loader-requirements` | `buildName, modLoader?, loaderVersion?` | `BuildLoaderRequirementReport` | |
</Accordion>

<Accordion title="Minecraft и запуск">
  | Канал | Аргументы | Возвращает | |
  | - | - | - | - |
  | `minecraft:get-versions` | | `MinecraftVersionInfo[]` | |
  | `minecraft:get-latest-release` | | \`string | null\` |
  | `minecraft:get-fabric-versions` | `mcVersion: string` | `{ version, stable }[]` | |
  | `minecraft:set-offline-auth` | `username: string` | \`AuthSession | null\` |
  | `minecraft:launch` | `params: MinecraftLaunchParams` | `{ success, error? }` | |
  | `minecraft:stop` | | `void` | |
  | `minecraft:is-running` | | `boolean` | |
</Accordion>

<Accordion title="Серверы">
  | Канал | Аргументы | Возвращает | |
  | - | - | - | - |
  | `mc-server:create` | `{ name, gameVersion, modloader?, port?, javaPath?, xmx?, xms? }` | `McServerInfo` | |
  | `mc-server:start` | `id: string` | `void` | |
  | `mc-server:stop` | `id: string` | `void` | |
  | `mc-server:send-command` | `id, command: string` | `void` | |
  | `mc-server:status` | `id: string` | `McServerState` | |
  | `mc-server:metrics-subscribe` | `id: string` | `void` | |
  | `mc-server:logs` | `id: string` | `string[]` | |
  | `mc-server:read-properties` | `id: string` | `Record<string, string>` | |
  | `mc-server:write-properties` | `id, properties` | `void` | |
  | `mc-server:get-whitelist` | `id: string` | `McPlayerEntry[]` | |
  | `mc-server:add-whitelist` | `id, username` | `void` | |
  | `mc-server:get-ops` / `add-op` | Аналогично | | |
  | `mc-server:get-banned` / `ban-player` / `unban-player` | Аналогично | | |
  | `mc-server:fs-list` | `id, relativePath` | `McFsEntry[]` | |
  | `mc-server:fs-read` | `id, relativePath` | \`string | null\` |
  | `mc-server:fs-write` | `id, relativePath, content` | `void` | |
</Accordion>

<Accordion title="XN Connect">
  | Канал | Аргументы | Возвращает | |
  | - | - | - | - |
  | `xn-connect:authorize` | | `boolean` | |
  | `xn-connect:start` | `serverId: string` | `XnConnectState` | |
  | `xn-connect:stop` | `serverId: string` | `void` | |
  | `xn-connect:status` | `serverId: string` | `XnConnectState` | |
  | `xn-connect:usage` | | \`XnConnectUsage | null\` |
</Accordion>

<Accordion title="Облако">
  | Канал | Аргументы | Возвращает |
  | - | - | - |
  | `cloud:list-providers` | | `[{ id, name }]` |
  | `cloud:connect` | `providerId, authData?` | `{ success, provider?, error? }` |
  | `cloud:upload-build` | `providerId, buildName, uploadId?, categories?` | `{ success, id?, name?, error? }` |
  | `cloud:download-and-import` | `providerId, remotePath, fileType, categories?` | `{ success, error?, account? }` |
</Accordion>

<Accordion title="AI">
  | Канал | Аргументы | Возвращает |
  | - | - | - |
  | `ai:get-config` | | `{ apiKey, endpoint, model }` |
  | `ai:save-config` | `config` | `void` |
  | `ai:list-models` | `override?` | `{ success, models?, error? }` |
  | `ai:analyze-crash` | `logContent: string` | `{ success, analysis?, error? }` |
  | `ai:analyze-crash-stream` | `requestId, logContent` | `{ success, analysis?, error? }` |
</Accordion>

### IpcEventMap

Event-каналы для подписки (`ipcRenderer.on`):

```typescript theme={null}
export interface IpcEventMap {
  "minecraft:java-progress": JavaProgress
  "minecraft:download-progress": MinecraftProgress
  "minecraft:close": MinecraftCloseInfo
  "mc-server:log": { id: string; line: string }
  "mc-server:state-change": { id: string; state: McServerState }
  "mc-server:metrics": { id: string; metrics: McServerMetrics }
  "xn-connect:usage-updated": XnConnectUsage
  "xn-connect:state": { serverId: string; state: XnConnectState }
  "ai:stream-chunk": { requestId: string; content: string }
  "ai:stream-done": { requestId: string; fullText: string }
  "ai:stream-error": { requestId: string; error: string }
  "update:status": { status, version?, releaseDate?, releaseNotes?, error? }
  "update:progress": { percent, transferred, total }
  "content:download-progress": ContentDownloadProgress
  "cloud:upload-progress": { id, percent, stage: "zip" | "upload" }
  "import:progress": ImportProgress
  "stats:updated": {}
}
```

### ElectronAPIExplicit и ElectronAPIExtra

`ElectronAPIExplicit` содержит типизированные обертки всех invoke-каналов в формате camelCase (`launchMinecraft`, `getMinecraftVersions`, `modsModrinthSearch` и т.д.). `ElectronAPIExtra` добавляет специфичные для лаунчера методы, которые исторически жили в `src/electron.d.ts`.

Полный `ElectronAPI` объединяет explicit + extra + window control (`minimize`, `maximize`, `close`, `restore`).

## Как добавить новый IPC-канал

Чтобы добавить новый канал связи между main и renderer:

<Steps>
  <Step title="Добавить тип в IpcInvokeMap или IpcEventMap">
    Откройте `packages/xnlc-types/src/ipc-contracts.ts` и добавьте запись в соответствующий интерфейс:

    ```typescript theme={null}
    "my-domain:my-action": {
      args: [param: string];
      return: { success: boolean; data?: string };
    }
    ```
  </Step>

  <Step title="Обновить ElectronAPIExplicit">
    Добавьте camelCase метод в `ElectronAPIExplicit`:

    ```typescript theme={null}
    myDomainMyAction: (param: string) => Promise<{ success: boolean; data?: string }>;
    ```
  </Step>

  <Step title="Реализовать обработчик в main">
    Создайте (или дополните) файл в `electron/main/my-domain/`:

    ```typescript theme={null}
    ipcMain.handle("my-domain:my-action", async (_event, param: string) => {
      // Логика обработки
      return { success: true, data: param.toUpperCase() };
    });
    ```
  </Step>

  <Step title="Добавить мост в preload">
    В `electron/preload.ts` зарегистрируйте метод:

    ```typescript theme={null}
    myDomainMyAction: (param) => ipcRenderer.invoke("my-domain:my-action", param),
    ```
  </Step>

  <Step title="Добавить тип в electron.d.ts">
    В `src/electron.d.ts` (или где объявлен `window.electronAPI`) добавьте:

    ```typescript theme={null}
    myDomainMyAction: (param: string) => Promise<{ success: boolean; data?: string }>;
    ```
  </Step>

  <Step title="Использовать в renderer">
    Теперь канал доступен через `window.electronAPI`:

    ```typescript theme={null}
    const result = await window.electronAPI.myDomainMyAction("hello");
    console.log(result.data); // "HELLO"
    ```
  </Step>
</Steps>

<Warning>
  Все 5 мест (`ipc-contracts.ts`, `ElectronAPIExplicit`, `preload.ts`, обработчик в `electron/main/`, `electron.d.ts`) должны быть синхронизированы. `@xnlc/types` гарантирует консистентность типов, но runtime-регистрацию нужно обновлять вручную.
</Warning>

<Note>
  Каналы с префиксом `minecraft:` (запуск, остановка, прогресс) обрабатываются воркером `electron/main/minecraft-launch-worker.ts`. Они изолированы от основного main-процесса для предотвращения блокировки UI при длительных операциях.
</Note>

## BuildLoaderRequirementIssue

Специальные типы для проверки совместимости модов с версией загрузчика:

```typescript theme={null}
interface BuildLoaderRequirementIssue {
  fileName: string
  modName?: string
  modId?: string
  loaderId: string        // "minecraft", "fabric", "forge", ...
  requirement: string      // ">=1.20"
  buildLoaderVersion?: string
  satisfied: boolean
  reason?: string
}

interface BuildLoaderRequirementReport {
  loaderId: string
  loaderVersion?: string
  checked: number
  issues: BuildLoaderRequirementIssue[]
}
```

Эти типы используются каналом `mods:check-loader-requirements`, который читает declared dependencies прямо из JAR-файлов модов и сравнивает их с установленной версией загрузчика.

## Пример: типобезопасный IPC

```typescript theme={null}
// renderer-процесс
async function searchMods(query: string) {
  // Полная типизация: аргументы и возвращаемое значение проверяются компилятором
  const response = await window.electronAPI.modsModrinthSearch(
    query,
    "mod",           // contentType
    "1.21.4",        // gameVersion
    "fabric",        // modLoader
    "relevance",     // sortBy
    1                // page
  );

  // response: ModSearchResponse
  response.hits.forEach((mod: ModSearchResult) => {
    console.log(mod.title, mod.downloads);
  });
}

// main-процесс
ipcMain.handle("mods:modrinth-search", async (_event, query, contentType, gameVersion, modLoader, sortBy, page) => {
  // query: string, contentType: ModContentType | undefined, ...
  // Все аргументы типизированы благодаря IpcInvokeMap
  return await modrinthClient.search(query, { contentType, gameVersion, modLoader, sortBy, page });
});
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.