Compare commits

..
13 Commits
163 changed files with 289 additions and 342 deletions
+17 -4
View File
@@ -1,5 +1,14 @@
# Backlog # Backlog
## lint и прочие правила
- [ ] линт правило для `interface Props {...}` + `let {}: Props = $props()`
- [ ] линт правило для `object as const`, нежелательно использовать
`type Kind = 'a' | 'b' | 'c'` - это приводит к дублированию описаний в
разных местах, и к непонятным новым типам типа `type Kind2 = 'a' | 'c'`
- [ ] можно ли сделать правило для минимизации новых `const` определений? чтобы
дубли автоматически определялись? ИИ агент иногда дублирует определения
## Мелочи всякие ## Мелочи всякие
- [ ] сгенерировать или найти файлы для ручной проверки `A. Краевые PNG-файлы` - [ ] сгенерировать или найти файлы для ручной проверки `A. Краевые PNG-файлы`
@@ -39,10 +48,13 @@
- [ ] придумать процесс редактирования и настройки pipeline - drag-n-drop, - [ ] придумать процесс редактирования и настройки pipeline - drag-n-drop,
удаление, добавление инструментов. переход один инструмент - pipeline без удаление, добавление инструментов. переход один инструмент - pipeline без
перезагрузки перезагрузки
- [ ] Слаги инструментов (`*-png`) — надо обдумать, возможно что ссылки\маршруты
должны быть с png, а названия инструментов - без. Это упростит названия
инструментов и сделает их более понятными
## Переезд ## Переезд
- [ ] составить план переноса preview -> корень, старый корень -> old - [x] составить план переноса preview -> корень, старый корень -> old
- [ ] добавить i18n в preview - [ ] добавить i18n в preview
## SEO/GEO ## SEO/GEO
@@ -178,9 +190,10 @@
14. ~~**Переезд старых файлов в папки `old/`**~~**ЗАКРЫТО.** Старые файлы 14. ~~**Переезд старых файлов в папки `old/`**~~**ЗАКРЫТО.** Старые файлы
(`lib/registry.ts`, `lib/registry/`, `lib/registry-helpers.ts`, (`lib/registry.ts`, `lib/registry/`, `lib/registry-helpers.ts`,
`lib/categories.ts`, `lib/tools/`, `lib/components/` кроме `kit/`) перенесены `lib/categories.ts`, `lib/tools/`, `lib/components/` кроме `kit/`)
в `lib/old/`. Isolation-плагин упрощён до `lib/old/**`. Все импорты обновлены. перенесены в `lib/old/`. Isolation-плагин упрощён до `lib/old/**`. Все
svelte-check 0, тесты 618/618, lint:all чист, билд проходит. импорты обновлены. svelte-check 0, тесты 618/618, lint:all чист, билд
проходит.
15. ~~**Техдолг (чинить по заведённым задачам, не игнорировать правила)**~~ 15. ~~**Техдолг (чинить по заведённым задачам, не игнорировать правила)**~~
ЗАКРЫТО. Подробности: `docs/archive/plan-tech-debt.md`. ЗАКРЫТО. Подробности: `docs/archive/plan-tech-debt.md`.
+32 -46
View File
@@ -26,30 +26,31 @@
нам нужно чтобы старые страницы жили по `/v1/*`. нам нужно чтобы старые страницы жили по `/v1/*`.
2. **Корневой layout: shell нового дизайна** — TopBar, Footer, тема, хлебные 2. **Корневой layout: shell нового дизайна** — TopBar, Footer, тема, хлебные
крошки, импорт `app.css`, `@layer app, design;`. крошки, импорт `app.css`, `@layer app, design;`.
3. **`v1/+layout.svelte` — только импорт `app_v1.css`** — без header/footer/shell. 3. **`v1/+layout.svelte` — только импорт `app_v1.css`** — без
header/footer/shell.
4. **Тема:** использовать `theme.svelte.ts` (не дублировать локальный `$state`). 4. **Тема:** использовать `theme.svelte.ts` (не дублировать локальный `$state`).
5. **`@layer app, design;`** остаётся — design выигрывает у app везде. 5. **`@layer app, design;`** остаётся — design выигрывает у app везде.
6. **`noindex` остаётся** на `tools/[id]/+page.svelte` до покупки домена. 6. **`noindex` остаётся** на `tools/[id]/+page.svelte` до покупки домена.
7. **CSS-файлы переименовываются:** `preview.css``app.css`, `old.css` 7. **CSS-файлы переименовываются:** `preview.css``app.css`, `old.css`
`app_v1.css`. Все ссылки обновляются. `app_v1.css`. Все ссылки обновляются.
8. **`kit/` витрина → `/kit`** — переносится на реальный маршрут вместе с 8. **`kit/` витрина → `/kit`** — переносится на реальный маршрут вместе с
остальными preview-страницами; отдельный `preview/+layout` удаляется остальными preview-страницами; отдельный `preview/+layout` удаляется (`/kit`
(`/kit` наследует корневой shell). наследует корневой shell).
## Что делать (шаги) ## Что делать (шаги)
### 1. Rename `(old)/` → `v1/` ### 1. Rename `(old)/` → `v1/`
Переименовать папку. Обновить `v1/+layout.svelte`: Переименовать папку. Обновить `v1/+layout.svelte`: убрать «Preview v2» ссылку,
убрать «Preview v2» ссылку, обновить пути навигации, поправить импорт CSS. обновить пути навигации, поправить импорт CSS.
### 2. Новый корневой `+layout.svelte` + rename CSS ### 2. Новый корневой `+layout.svelte` + rename CSS
Перезаписать текущий нейтральный layout содержимым из `preview/+layout.svelte` Перезаписать текущий нейтральный layout содержимым из `preview/+layout.svelte`
(с правками: тема через `theme.svelte.ts`, путь к CSS). Переименовать (с правками: тема через `theme.svelte.ts`, путь к CSS). Переименовать
`src/preview.css``src/app.css`, `src/old.css``src/app_v1.css`. `src/preview.css``src/app.css`, `src/old.css``src/app_v1.css`. Обновить
Обновить все ссылки на эти файлы в проекте ( layout, лайнтеры, eslint-плагины, все ссылки на эти файлы в проекте ( layout, лайнтеры, eslint-плагины, скрипты,
скрипты, тесты). тесты).
### 3. Move preview pages → корень ### 3. Move preview pages → корень
@@ -57,59 +58,44 @@
`list-tools``/`, `tools/[id]``/`, витрину `kit``/kit`. Удалить `list-tools``/`, `tools/[id]``/`, витрину `kit``/kit`. Удалить
`preview/+layout.svelte` (корневой shell заменяет его). `preview/+layout.svelte` (корневой shell заменяет его).
### 4. Flatten `kit/` → `components/` ### 4. Update hardcoded `/preview/` URLs
Перенести компоненты из `lib/components/kit/` в `lib/components/`, обновить
все импорты, удалить пустую `kit/`.
### 5. Update hardcoded `/preview/` URLs
В компонентах с захардкоженными путями `/preview/` заменить на корневые. В компонентах с захардкоженными путями `/preview/` заменить на корневые.
### 6. E2E тесты + playwright config ### 5. Flatten `kit/` → `components/`
Перенести компоненты из `lib/components/kit/` в `lib/components/`, обновить все
импорты, удалить пустую `kit/`.
### 6. Flatten `preview/` → `lib/`
Перенести код из `lib/previw/` в `lib/`, обновить все импорты, удалить пустую
`preview/`.
### 7. Перенести `old/` → `v1/`
- `$lib/old/` — переименовать в `lib/v1/`, обновить все импорты
### 8. E2E тесты + playwright config
Заменить `/preview/...` на `/...` во всех e2e файлах и конфиге playwright. Заменить `/preview/...` на `/...` во всех e2e файлах и конфиге playwright.
### 7. ESLint config + AGENTS.md ### 9. ESLint config + AGENTS.md
Обновить glob-паттерны: `routes/preview/**``routes/**`, Обновить glob-паттерны: `routes/preview/**``routes/**`, `components/kit/**`
`components/kit/**``components/**`. Обновить `AGENTS.md`. `components/**`. Обновить `AGENTS.md`.
### 8. Isolation plugin ### 10. Isolation plugin
Обновить `DEFAULT_OLD`: `routes/(old)/**``routes/v1/**`. Обновить `DEFAULT_OLD`: `routes/(old)/**``routes/v1/**`. Убрать
Убрать `routes/preview/**` из `DEFAULT_NEW`. `routes/preview/**` из `DEFAULT_NEW`.
### 9. Archive audit scripts ### 11. Archive audit scripts
Перенести скрипты аудита в `scripts/archive/`, убрать вызовы из манифестов. Перенести скрипты аудита в `scripts/archive/`, убрать вызовы из манифестов.
## Порядок коммитов
| # | Описание | Зависит от |
| --- | ----------------------------------------------- | ---------- |
| 1 | Rename `(old)/``v1/`, правки v1/layout | — |
| 2 | Новый корневой layout + rename CSS | — |
| 3 | Move preview pages → корень (+ `/preview/kit` → | 2 |
| | `/kit`, удалить `preview/+layout`) | |
| 4 | Flatten kit/ → components/, обновить импорты | — |
| 5 | TopNav + ToolCard: убрать `/preview/` из URL | 3 |
| 6 | E2E тесты + playwright config | 3 |
| 7 | ESLint config + AGENTS.md | 3, 4 |
| 8 | Isolation plugin | 1 |
| 9 | Archive audit scripts + убрать из манифестов | — |
> **3+5 делаются вместе (один коммит):** после переноса страниц в корень
> `ToolCard`/`TopNav` продолжают линковать `/preview/...`, prerender падает на
> 404 — между шагами 3 и 5 билд не зелёный.
После каждого коммита: `pnpm --dir web lint` + `pnpm --dir web build` (+
`pnpm --dir web test` если затронуты e2e).
## Что НЕ меняется ## Что НЕ меняется
- `$lib/preview/`, `$lib/registry-new/` — без изменений
- `$lib/old/components/` — без изменений (каждая сторона хранит свою копию)
- `routes/+layout.ts` — prerender = true остаётся - `routes/+layout.ts` — prerender = true остаётся
- Слаги инструментов (`*-png`) — без изменений - Слаги инструментов (`*-png`) — без изменений
- `/kit` — витрина дизайна остаётся (в стадии тестирования) - `/kit` — витрина дизайна остаётся (в стадии тестирования)
+2 -4
View File
@@ -4,14 +4,12 @@
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "pnpm --dir web test",
"dev": "pnpm --dir web dev", "dev": "pnpm --dir web dev",
"build": "pnpm --dir web build", "build": "pnpm --dir web build",
"format": "pnpm format:docs && pnpm --dir web format", "format": "pnpm format:docs && pnpm --dir web format",
"format:docs": "prettier --write docs --log-level warn", "format:docs": "prettier --write docs --log-level warn",
"check:docs": "prettier --check docs", "check:docs": "prettier --check docs"
"html": "pnpm --dir refs build && node scripts/extract-static.mjs refs/.next/server/app refs-html",
"cdp-audit": "pnpm --dir web refs-cdp-audit:large"
}, },
"keywords": [], "keywords": [],
"author": "Ku6epXBOCTuK", "author": "Ku6epXBOCTuK",
+5 -5
View File
@@ -1,19 +1,19 @@
import { expect, test } from "playwright/test"; import { expect, test } from "playwright/test";
import { trackErrors, expectNoErrors } from "./helpers/page"; import { expectNoErrors, trackErrors } from "./helpers/page";
const TOTAL = 121; const TOTAL = 121;
const GROUPS = 8; const GROUPS = 8;
test("catalog shows total and all groups", async ({ page }) => { test("catalog shows total and all groups", async ({ page }) => {
const sink = trackErrors(page); const sink = trackErrors(page);
await page.goto("/preview/list-tools"); await page.goto("/list-tools");
await expect(page.locator(".catalog-total b")).toHaveText(String(TOTAL)); await expect(page.locator(".catalog-total b")).toHaveText(String(TOTAL));
await expect(page.locator(".catalog-group")).toHaveCount(GROUPS); await expect(page.locator(".catalog-group")).toHaveCount(GROUPS);
expectNoErrors(sink); expectNoErrors(sink);
}); });
test("catalog search narrows results", async ({ page }) => { test("catalog search narrows results", async ({ page }) => {
await page.goto("/preview/list-tools"); await page.goto("/list-tools");
await expect(async () => { await expect(async () => {
await page.getByRole("textbox", { name: "Search tools" }).fill("resize"); await page.getByRole("textbox", { name: "Search tools" }).fill("resize");
await expect(page.locator(".tool-card")).toHaveCount(1); await expect(page.locator(".tool-card")).toHaveCount(1);
@@ -24,7 +24,7 @@ test("catalog search narrows results", async ({ page }) => {
test("category filter shows only matching group and resets on ALL", async ({ test("category filter shows only matching group and resets on ALL", async ({
page, page,
}) => { }) => {
await page.goto("/preview/list-tools"); await page.goto("/list-tools");
const allButtons = page.locator(".tool-card"); const allButtons = page.locator(".tool-card");
const allCount = await allButtons.count(); const allCount = await allButtons.count();
expect(allCount).toBe(TOTAL); expect(allCount).toBe(TOTAL);
@@ -46,7 +46,7 @@ test("category filter shows only matching group and resets on ALL", async ({
}); });
test("workspace search matches a tool by title", async ({ page }) => { test("workspace search matches a tool by title", async ({ page }) => {
await page.goto("/preview"); await page.goto("/");
await expect(async () => { await expect(async () => {
await page.getByRole("textbox", { name: "Search tools" }).fill("flip"); await page.getByRole("textbox", { name: "Search tools" }).fill("flip");
await expect(page.locator(".tool-card")).toHaveCount(1); await expect(page.locator(".tool-card")).toHaveCount(1);
+2 -2
View File
@@ -1,8 +1,8 @@
import { expect, test } from "playwright/test"; import { expect, test } from "playwright/test";
import { trackErrors, openTool, expectNoErrors } from "./helpers/page"; import { expectNoErrors, openTool, trackErrors } from "./helpers/page";
test.describe("generators — known UI gap (#checklist, п.1)", () => { test.describe("generators — known UI gap (#checklist, п.1)", () => {
// Генераторы (21/121) открываются, но в UI нет ни полей схемы, ни кнопки // FIXME: Генераторы (21/121) открываются, но в UI нет ни полей схемы, ни кнопки
// «Generate» — только RU/EN/Reset. Пока баг открыт — fixme с ожидаемым // «Generate» — только RU/EN/Reset. Пока баг открыт — fixme с ожидаемым
// сценарием; после фикса убрать fixme. // сценарием; после фикса убрать fixme.
test.fixme("single-color-png renders Generate controls and produces a result", async ({ test.fixme("single-color-png renders Generate controls and produces a result", async ({
+1 -1
View File
@@ -13,7 +13,7 @@ export function trackErrors(page: Page): ErrorSink {
} }
export async function openTool(page: Page, id: string): Promise<void> { export async function openTool(page: Page, id: string): Promise<void> {
await page.goto(`/preview/tools/${id}`); await page.goto(`/tools/${id}`);
await expect(page.locator(".schema-tool h1")).toBeVisible(); await expect(page.locator(".schema-tool h1")).toBeVisible();
} }
+1 -1
View File
@@ -2,7 +2,7 @@ import { expect, test } from "playwright/test";
import { opaquePng } from "./helpers/fixtures"; import { opaquePng } from "./helpers/fixtures";
import { openTool, uploadImage } from "./helpers/page"; import { openTool, uploadImage } from "./helpers/page";
// Весь файл — зарегистрированные баги preview (см. docs/checklist-manual-testing.md // FIXME: Весь файл — зарегистрированные баги preview (см. docs/checklist-manual-testing.md
// → «Известные баги preview»). Тела assert'ят ОЖИДАЕМОЕ поведение. Статус fixme // → «Известные баги preview»). Тела assert'ят ОЖИДАЕМОЕ поведение. Статус fixme
// означает «мы знаем, что сейчас падает»; когда баг починят — убрать fixme и // означает «мы знаем, что сейчас падает»; когда баг починят — убрать fixme и
// тест станет зелёным «сам по себе». // тест станет зелёным «сам по себе».
+14 -10
View File
@@ -1,12 +1,7 @@
import { expect, test } from "playwright/test"; import { expect, test } from "playwright/test";
import { trackErrors, expectNoErrors } from "./helpers/page"; import { expectNoErrors, trackErrors } from "./helpers/page";
const ROUTES = [ const ROUTES = ["/", "/list-tools", "/kit", "/tools/flip-png"];
"/preview",
"/preview/list-tools",
"/preview/kit",
"/preview/tools/flip-png",
];
for (const route of ROUTES) { for (const route of ROUTES) {
test(`page ${route} loads without errors`, async ({ page }) => { test(`page ${route} loads without errors`, async ({ page }) => {
@@ -19,14 +14,23 @@ for (const route of ROUTES) {
} }
test("unknown tool route responds 404 on static build", async ({ page }) => { test("unknown tool route responds 404 on static build", async ({ page }) => {
const resp = await page.goto("/preview/tools/definitely-not-a-tool"); const resp = await page.goto("/tools/definitely-not-a-tool");
expect(resp?.status()).toBe(404); expect(resp?.status()).toBe(404);
}); });
// FIXME:
// Error: expect(received).toBe(expected) // Object.is equality
// Expected: "dark"
// Received: null
// 36 | expect(["light", "dark"]).toContain(before);
// 37 | expect(["light", "dark"]).toContain(after);
// > 38 | expect(stored).toBe(after);
test("theme toggle flips preview theme and persists to localStorage", async ({ test("theme toggle flips preview theme and persists to localStorage", async ({
page, page,
}) => { }) => {
await page.goto("/preview"); await page.goto("/");
const root = page.locator("main.preview-root"); const root = page.locator("main.preview-root");
const before = await root.getAttribute("data-theme"); const before = await root.getAttribute("data-theme");
await expect(async () => { await expect(async () => {
@@ -44,7 +48,7 @@ test("theme toggle flips preview theme and persists to localStorage", async ({
}); });
test("language toggle marks the active button", async ({ page }) => { test("language toggle marks the active button", async ({ page }) => {
await page.goto("/preview"); await page.goto("/");
const group = page.getByRole("group", { name: "Language" }); const group = page.getByRole("group", { name: "Language" });
await expect(async () => { await expect(async () => {
await group.getByRole("button", { name: "EN" }).click(); await group.getByRole("button", { name: "EN" }).click();
@@ -17,13 +17,16 @@
import fs from "node:fs"; import fs from "node:fs";
import path from "node:path"; import path from "node:path";
const DEFAULT_OLD = ["routes/(old)/**", "lib/old/**"]; // FIXME: change paths to new ones
// TODO: test case for this lint rules
const DEFAULT_OLD = ["routes/v1/**", "lib/v1/**"];
const DEFAULT_NEW = [ const DEFAULT_NEW = [
"routes/preview/**", "routes/**",
"lib/components/kit/**", "lib/components/kit/**",
"lib/preview/**", "lib/**",
"lib/registry-new/**", "lib/registry/**",
"lib/registry-schema.ts", "lib/registry-schema.ts",
"lib/registry-schema.test.ts", "lib/registry-schema.test.ts",
]; ];
+34 -10
View File
@@ -1,16 +1,18 @@
import js from "@eslint/js"; import js from "@eslint/js";
import prettier from "eslint-config-prettier"; import prettier from "eslint-config-prettier";
import svelte from "eslint-plugin-svelte"; import svelte from "eslint-plugin-svelte";
import designTokens from "./eslint-plugins/index.js";
import isolationPlugin from "./eslint-plugins/isolation/index.js";
import globals from "globals"; import globals from "globals";
import svelteParser from "svelte-eslint-parser"; import svelteParser from "svelte-eslint-parser";
import tseslint from "typescript-eslint"; import tseslint from "typescript-eslint";
import designTokens from "./eslint-plugins/index.js";
import isolationPlugin from "./eslint-plugins/isolation/index.js";
// FIXME: надо игнорировать старые файлы, после переноса пути новых компонентов включают старые
// Новый код редизайна: к нему применяем полные recommended-наборы уже сейчас. // Новый код редизайна: к нему применяем полные recommended-наборы уже сейчас.
// Когда старый дизайн удалим (C19), этот scoped-блок убирается и recommended // Когда старый дизайн удалим (C19), этот scoped-блок убирается и recommended
// включается на весь код (см. план-redesign §10, шаг 6). // включается на весь код (см. план-redesign §10, шаг 6).
const newCode = ["**/src/lib/components/kit/**", "**/src/routes/preview/**"]; const newCode = ["**/src/lib/components/**", "**/src/routes/**"];
const oldCode = ["**/src/lib/v1/**", "**/src/routes/v1/**"];
// Полные recommended-наборы — только на новый код (см. ниже, блок перед prettier). // Полные recommended-наборы — только на новый код (см. ниже, блок перед prettier).
const jsRecommended = Array.isArray(js.configs.recommended) const jsRecommended = Array.isArray(js.configs.recommended)
@@ -21,10 +23,19 @@ const svelteRecommended = Array.isArray(svelte.configs["flat/recommended"])
: [svelte.configs["flat/recommended"]]; : [svelte.configs["flat/recommended"]];
// Svelte-рекомендации применяем только к .svelte-файлам нового кода, иначе // Svelte-рекомендации применяем только к .svelte-файлам нового кода, иначе
// svelte-eslint-parser "съедает" обычные .ts в тех же папках (напр. +page.ts). // svelte-eslint-parser "съедает" обычные .ts в тех же папках (напр. +page.ts).
const svelteFiles = [ const newSvelteFiles = [
"**/src/lib/components/kit/**/*.svelte", "**/src/lib/components/**/*.svelte",
"**/src/routes/preview/**/*.svelte", "**/src/routes/**/*.svelte",
]; ];
const oldSvelteFiles = [
"**/src/lib/v1/**/*.svelte",
"**/src/routes/v1/**/*.svelte",
];
// FIXME:
// The signature '(...configs: InfiniteDepthConfigWithExtends[]): ConfigArray' of 'tseslint.config' is deprecated.ts
// Migrate to defineConfig(...)
// The core defineConfig(...) helper is a nearly exact clone of tseslint.config(...)
export default tseslint.config( export default tseslint.config(
{ {
@@ -100,7 +111,8 @@ export default tseslint.config(
// Применяется к новому коду редизайна (см. newCode выше). Когда старый дизайн // Применяется к новому коду редизайна (см. newCode выше). Когда старый дизайн
// удалят, расширить glob на весь код, исключив (old)/. // удалят, расширить glob на весь код, исключив (old)/.
{ {
files: svelteFiles, files: newSvelteFiles,
ignores: oldSvelteFiles,
plugins: { plugins: {
"design-tokens": designTokens, "design-tokens": designTokens,
}, },
@@ -113,9 +125,21 @@ export default tseslint.config(
}, },
// Полные recommended-наборы — только на новый код. // Полные recommended-наборы — только на новый код.
...[ ...[
...jsRecommended.map((cfg) => ({ ...cfg, files: newCode })), ...jsRecommended.map((cfg) => ({
...tseslint.configs.recommended.map((cfg) => ({ ...cfg, files: newCode })), ...cfg,
...svelteRecommended.map((cfg) => ({ ...cfg, files: svelteFiles })), files: newCode,
ignores: oldCode,
})),
...tseslint.configs.recommended.map((cfg) => ({
...cfg,
files: newCode,
ignores: oldCode,
})),
...svelteRecommended.map((cfg) => ({
...cfg,
files: newSvelteFiles,
ignores: oldSvelteFiles,
})),
], ],
// В Svelte 5 пропсы деструктурируются через `let` (конвенция документации и // В Svelte 5 пропсы деструктурируются через `let` (конвенция документации и
+2 -6
View File
@@ -16,12 +16,7 @@
"lint": "eslint .", "lint": "eslint .",
"lint:css": "stylelint \"./src/**/*.css\"", "lint:css": "stylelint \"./src/**/*.css\"",
"lint:all": "node scripts/lint-all.mjs", "lint:all": "node scripts/lint-all.mjs",
"lint:tokens": "node scripts/check-tokens.mjs", "lint:tokens": "node scripts/check-tokens.mjs"
"refs-cdp-audit": "node scripts/audit-cdp.mjs",
"refs-cdp-audit:large": "node scripts/audit-cdp.mjs --viewport 2560x1440",
"refs-cdp-audit:responsive": "node scripts/audit-cdp-responsive.mjs",
"refs-css-audit": "node scripts/audit-css.mjs",
"refs-dom-audit": "node scripts/audit-dom.mjs"
}, },
"devDependencies": { "devDependencies": {
"@csstools/postcss-global-data": "^4.0.0", "@csstools/postcss-global-data": "^4.0.0",
@@ -30,6 +25,7 @@
"@sveltejs/adapter-static": "^3.0.10", "@sveltejs/adapter-static": "^3.0.10",
"@sveltejs/kit": "^2.63.0", "@sveltejs/kit": "^2.63.0",
"@sveltejs/vite-plugin-svelte": "^7.1.2", "@sveltejs/vite-plugin-svelte": "^7.1.2",
"@types/node": "^26.5.0",
"diff": "^9.0.0", "diff": "^9.0.0",
"eslint": "^10.9.0", "eslint": "^10.9.0",
"eslint-config-prettier": "^10.1.8", "eslint-config-prettier": "^10.1.8",
+1 -1
View File
@@ -22,7 +22,7 @@ export default defineConfig({
], ],
webServer: { webServer: {
command: "pnpm build && node scripts/serve-static.mjs --port 4173", command: "pnpm build && node scripts/serve-static.mjs --port 4173",
url: "http://127.0.0.1:4173/preview", url: "http://127.0.0.1:4173/",
reuseExistingServer: !process.env.CI, reuseExistingServer: !process.env.CI,
timeout: 180_000, timeout: 180_000,
}, },
+39 -21
View File
@@ -29,13 +29,16 @@ importers:
version: 0.4.2 version: 0.4.2
'@sveltejs/adapter-static': '@sveltejs/adapter-static':
specifier: ^3.0.10 specifier: ^3.0.10
version: 3.0.10(@sveltejs/kit@2.70.3(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.9(@typescript-eslint/types@8.67.0))(vite@8.2.1))(svelte@5.56.9(@typescript-eslint/types@8.67.0))(typescript@6.0.3)(vite@8.2.1)) version: 3.0.10(@sveltejs/kit@2.70.3(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.9(@typescript-eslint/types@8.67.0))(vite@8.2.1(@types/node@26.5.0)))(svelte@5.56.9(@typescript-eslint/types@8.67.0))(typescript@6.0.3)(vite@8.2.1(@types/node@26.5.0)))
'@sveltejs/kit': '@sveltejs/kit':
specifier: ^2.63.0 specifier: ^2.63.0
version: 2.70.3(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.9(@typescript-eslint/types@8.67.0))(vite@8.2.1))(svelte@5.56.9(@typescript-eslint/types@8.67.0))(typescript@6.0.3)(vite@8.2.1) version: 2.70.3(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.9(@typescript-eslint/types@8.67.0))(vite@8.2.1(@types/node@26.5.0)))(svelte@5.56.9(@typescript-eslint/types@8.67.0))(typescript@6.0.3)(vite@8.2.1(@types/node@26.5.0))
'@sveltejs/vite-plugin-svelte': '@sveltejs/vite-plugin-svelte':
specifier: ^7.1.2 specifier: ^7.1.2
version: 7.3.0(svelte@5.56.9(@typescript-eslint/types@8.67.0))(vite@8.2.1) version: 7.3.0(svelte@5.56.9(@typescript-eslint/types@8.67.0))(vite@8.2.1(@types/node@26.5.0))
'@types/node':
specifier: ^26.5.0
version: 26.5.0
diff: diff:
specifier: ^9.0.0 specifier: ^9.0.0
version: 9.0.0 version: 9.0.0
@@ -89,10 +92,10 @@ importers:
version: 8.67.0(eslint@10.9.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) version: 8.67.0(eslint@10.9.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)
vite: vite:
specifier: ^8.0.16 specifier: ^8.0.16
version: 8.2.1 version: 8.2.1(@types/node@26.5.0)
vitest: vitest:
specifier: ^4.1.11 specifier: ^4.1.11
version: 4.1.11(vite@8.2.1) version: 4.1.11(@types/node@26.5.0)(vite@8.2.1(@types/node@26.5.0))
packages: packages:
@@ -439,6 +442,9 @@ packages:
'@types/json-schema@7.0.15': '@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
'@types/node@26.5.0':
resolution: {integrity: sha512-dVSGpriSoCgz8WnDNTuSSuSv1PC/ALXihO4ulRZt7Md8k9mlbdin3lGOcDE8SnWOgf513ByWlXd7BK4azmyg/A==}
'@types/trusted-types@2.0.7': '@types/trusted-types@2.0.7':
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
@@ -1450,6 +1456,9 @@ packages:
engines: {node: '>=14.17'} engines: {node: '>=14.17'}
hasBin: true hasBin: true
undici-types@8.9.0:
resolution: {integrity: sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==}
unicorn-magic@0.4.0: unicorn-magic@0.4.0:
resolution: {integrity: sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==} resolution: {integrity: sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==}
engines: {node: '>=20'} engines: {node: '>=20'}
@@ -1799,15 +1808,15 @@ snapshots:
dependencies: dependencies:
acorn: 8.18.0 acorn: 8.18.0
'@sveltejs/adapter-static@3.0.10(@sveltejs/kit@2.70.3(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.9(@typescript-eslint/types@8.67.0))(vite@8.2.1))(svelte@5.56.9(@typescript-eslint/types@8.67.0))(typescript@6.0.3)(vite@8.2.1))': '@sveltejs/adapter-static@3.0.10(@sveltejs/kit@2.70.3(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.9(@typescript-eslint/types@8.67.0))(vite@8.2.1(@types/node@26.5.0)))(svelte@5.56.9(@typescript-eslint/types@8.67.0))(typescript@6.0.3)(vite@8.2.1(@types/node@26.5.0)))':
dependencies: dependencies:
'@sveltejs/kit': 2.70.3(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.9(@typescript-eslint/types@8.67.0))(vite@8.2.1))(svelte@5.56.9(@typescript-eslint/types@8.67.0))(typescript@6.0.3)(vite@8.2.1) '@sveltejs/kit': 2.70.3(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.9(@typescript-eslint/types@8.67.0))(vite@8.2.1(@types/node@26.5.0)))(svelte@5.56.9(@typescript-eslint/types@8.67.0))(typescript@6.0.3)(vite@8.2.1(@types/node@26.5.0))
'@sveltejs/kit@2.70.3(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.9(@typescript-eslint/types@8.67.0))(vite@8.2.1))(svelte@5.56.9(@typescript-eslint/types@8.67.0))(typescript@6.0.3)(vite@8.2.1)': '@sveltejs/kit@2.70.3(@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.9(@typescript-eslint/types@8.67.0))(vite@8.2.1(@types/node@26.5.0)))(svelte@5.56.9(@typescript-eslint/types@8.67.0))(typescript@6.0.3)(vite@8.2.1(@types/node@26.5.0))':
dependencies: dependencies:
'@standard-schema/spec': 1.1.0 '@standard-schema/spec': 1.1.0
'@sveltejs/acorn-typescript': 1.0.13(acorn@8.18.0) '@sveltejs/acorn-typescript': 1.0.13(acorn@8.18.0)
'@sveltejs/vite-plugin-svelte': 7.3.0(svelte@5.56.9(@typescript-eslint/types@8.67.0))(vite@8.2.1) '@sveltejs/vite-plugin-svelte': 7.3.0(svelte@5.56.9(@typescript-eslint/types@8.67.0))(vite@8.2.1(@types/node@26.5.0))
'@types/cookie': 0.6.0 '@types/cookie': 0.6.0
acorn: 8.18.0 acorn: 8.18.0
cookie: 0.6.0 cookie: 0.6.0
@@ -1819,20 +1828,20 @@ snapshots:
set-cookie-parser: 3.1.2 set-cookie-parser: 3.1.2
sirv: 3.0.2 sirv: 3.0.2
svelte: 5.56.9(@typescript-eslint/types@8.67.0) svelte: 5.56.9(@typescript-eslint/types@8.67.0)
vite: 8.2.1 vite: 8.2.1(@types/node@26.5.0)
optionalDependencies: optionalDependencies:
typescript: 6.0.3 typescript: 6.0.3
'@sveltejs/load-config@0.2.3': {} '@sveltejs/load-config@0.2.3': {}
'@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.9(@typescript-eslint/types@8.67.0))(vite@8.2.1)': '@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.9(@typescript-eslint/types@8.67.0))(vite@8.2.1(@types/node@26.5.0))':
dependencies: dependencies:
deepmerge: 4.3.1 deepmerge: 4.3.1
magic-string: 1.2.0 magic-string: 1.2.0
obug: 2.1.4 obug: 2.1.4
svelte: 5.56.9(@typescript-eslint/types@8.67.0) svelte: 5.56.9(@typescript-eslint/types@8.67.0)
vite: 8.2.1 vite: 8.2.1(@types/node@26.5.0)
vitefu: 1.1.3(vite@8.2.1) vitefu: 1.1.3(vite@8.2.1(@types/node@26.5.0))
'@types/chai@5.2.3': '@types/chai@5.2.3':
dependencies: dependencies:
@@ -1849,6 +1858,10 @@ snapshots:
'@types/json-schema@7.0.15': {} '@types/json-schema@7.0.15': {}
'@types/node@26.5.0':
dependencies:
undici-types: 8.9.0
'@types/trusted-types@2.0.7': {} '@types/trusted-types@2.0.7': {}
'@typescript-eslint/eslint-plugin@8.67.0(@typescript-eslint/parser@8.67.0(eslint@10.9.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.9.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': '@typescript-eslint/eslint-plugin@8.67.0(@typescript-eslint/parser@8.67.0(eslint@10.9.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.9.0(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)':
@@ -1951,13 +1964,13 @@ snapshots:
chai: 6.2.2 chai: 6.2.2
tinyrainbow: 3.1.1 tinyrainbow: 3.1.1
'@vitest/mocker@4.1.11(vite@8.2.1)': '@vitest/mocker@4.1.11(vite@8.2.1(@types/node@26.5.0))':
dependencies: dependencies:
'@vitest/spy': 4.1.11 '@vitest/spy': 4.1.11
estree-walker: 3.0.3 estree-walker: 3.0.3
magic-string: 0.30.21 magic-string: 0.30.21
optionalDependencies: optionalDependencies:
vite: 8.2.1 vite: 8.2.1(@types/node@26.5.0)
'@vitest/pretty-format@4.1.11': '@vitest/pretty-format@4.1.11':
dependencies: dependencies:
@@ -2847,6 +2860,8 @@ snapshots:
typescript@6.0.3: {} typescript@6.0.3: {}
undici-types@8.9.0: {}
unicorn-magic@0.4.0: {} unicorn-magic@0.4.0: {}
uri-js@4.4.1: uri-js@4.4.1:
@@ -2855,7 +2870,7 @@ snapshots:
util-deprecate@1.0.2: {} util-deprecate@1.0.2: {}
vite@8.2.1: vite@8.2.1(@types/node@26.5.0):
dependencies: dependencies:
lightningcss: 1.33.0 lightningcss: 1.33.0
picomatch: 4.0.5 picomatch: 4.0.5
@@ -2863,16 +2878,17 @@ snapshots:
rolldown: 1.2.4 rolldown: 1.2.4
tinyglobby: 0.2.17 tinyglobby: 0.2.17
optionalDependencies: optionalDependencies:
'@types/node': 26.5.0
fsevents: 2.3.3 fsevents: 2.3.3
vitefu@1.1.3(vite@8.2.1): vitefu@1.1.3(vite@8.2.1(@types/node@26.5.0)):
optionalDependencies: optionalDependencies:
vite: 8.2.1 vite: 8.2.1(@types/node@26.5.0)
vitest@4.1.11(vite@8.2.1): vitest@4.1.11(@types/node@26.5.0)(vite@8.2.1(@types/node@26.5.0)):
dependencies: dependencies:
'@vitest/expect': 4.1.11 '@vitest/expect': 4.1.11
'@vitest/mocker': 4.1.11(vite@8.2.1) '@vitest/mocker': 4.1.11(vite@8.2.1(@types/node@26.5.0))
'@vitest/pretty-format': 4.1.11 '@vitest/pretty-format': 4.1.11
'@vitest/runner': 4.1.11 '@vitest/runner': 4.1.11
'@vitest/snapshot': 4.1.11 '@vitest/snapshot': 4.1.11
@@ -2889,8 +2905,10 @@ snapshots:
tinyexec: 1.3.0 tinyexec: 1.3.0
tinyglobby: 0.2.17 tinyglobby: 0.2.17
tinyrainbow: 3.1.1 tinyrainbow: 3.1.1
vite: 8.2.1 vite: 8.2.1(@types/node@26.5.0)
why-is-node-running: 2.3.0 why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 26.5.0
transitivePeerDependencies: transitivePeerDependencies:
- msw - msw
@@ -1,5 +1,5 @@
import { CATEGORY_IDS } from "./categories"; import { CATEGORY_IDS } from "./categories";
import { TOOLS, type ToolEntry } from "../registry-new"; import { TOOLS, type ToolEntry } from "./registry";
export type PreviewGroup = { export type PreviewGroup = {
id: string; id: string;
@@ -1,10 +1,10 @@
<script lang="ts"> <script lang="ts">
import MetaList from "$lib/components/kit/MetaList.svelte"; import MetaList from "$lib/components/MetaList.svelte";
import SchemaActions from "$lib/components/kit/SchemaActions.svelte"; import SchemaActions from "$lib/components/SchemaActions.svelte";
import SchemaResultTile from "$lib/components/kit/SchemaResultTile.svelte"; import SchemaResultTile from "$lib/components/SchemaResultTile.svelte";
import SchemaSourceTile from "$lib/components/kit/SchemaSourceTile.svelte"; import SchemaSourceTile from "$lib/components/SchemaSourceTile.svelte";
import type { PixelImage } from "$lib/core/types"; import type { PixelImage } from "$lib/core/types";
import type { InputMode, ResultKind } from "$lib/registry-new"; import type { InputMode, ResultKind } from "$lib/registry";
interface Props { interface Props {
inputMode: InputMode; inputMode: InputMode;
@@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { toDataUrl } from "$lib/core/io"; import { toDataUrl } from "$lib/core/io";
import type { PixelImage } from "$lib/core/types"; import type { PixelImage } from "$lib/core/types";
import type { InputMode } from "$lib/registry-new"; import type { InputMode } from "$lib/registry";
import SchemaTextSource from "./SchemaTextSource.svelte"; import SchemaTextSource from "./SchemaTextSource.svelte";
interface Props { interface Props {
@@ -1,13 +1,13 @@
<script lang="ts"> <script lang="ts">
import SchemaFields from "$lib/components/kit/SchemaFields.svelte"; import SchemaFields from "$lib/components/SchemaFields.svelte";
import SchemaPreview from "$lib/components/kit/SchemaPreview.svelte"; import SchemaPreview from "$lib/components/SchemaPreview.svelte";
import { debounce } from "$lib/core/debounce"; import { debounce } from "$lib/core/debounce";
import { ToolError } from "$lib/core/errors"; import { ToolError } from "$lib/core/errors";
import { decodeFile, encode } from "$lib/core/io"; import { decodeFile, encode } from "$lib/core/io";
import type { PixelImage } from "$lib/core/types"; import type { PixelImage } from "$lib/core/types";
import { execute } from "$lib/executor";
import { t } from "$lib/i18n/t"; import { t } from "$lib/i18n/t";
import { execute } from "$lib/preview/executor"; import type { ToolEntry } from "$lib/registry";
import type { ToolEntry } from "$lib/registry-new";
import { import {
defaultSchemaParams, defaultSchemaParams,
sanitizeSchemaParams, sanitizeSchemaParams,
@@ -14,7 +14,7 @@
let { title, id, description, index, icon }: Props = $props(); let { title, id, description, index, icon }: Props = $props();
</script> </script>
<a class="tool-card" href={resolve("/preview/tools/[id]", { id })}> <a class="tool-card" href={resolve("/tools/[id]", { id })}>
{#if icon}<span class="tool-icon"><Icon {icon} size={19} /></span>{/if} {#if icon}<span class="tool-icon"><Icon {icon} size={19} /></span>{/if}
<span class="tool-copy"> <span class="tool-copy">
<strong>{title}</strong> <strong>{title}</strong>
@@ -35,10 +35,6 @@
padding: var(--space-s) var(--space-m); padding: var(--space-s) var(--space-m);
cursor: pointer; cursor: pointer;
} }
.lang-div {
color: var(--color-text);
font-family: var(--font-sans);
}
.lang-btn.active { .lang-btn.active {
background: var(--color-text); background: var(--color-text);
color: var(--color-background); color: var(--color-background);
@@ -3,9 +3,9 @@
</script> </script>
<nav class="nav"> <nav class="nav">
<a href={resolve("/preview")}>Home page</a> <a href={resolve("/")}>Home page</a>
<a href={resolve("/preview/list-tools")}>Catalog</a> <a href={resolve("/list-tools")}>Catalog</a>
<a href={resolve("/preview/kit")}> UI Kit </a> <a href={resolve("/kit")}> UI Kit </a>
</nav> </nav>
<style> <style>
@@ -1,7 +1,7 @@
import { ToolError } from "$lib/core/errors"; import { ToolError } from "$lib/core/errors";
import type { PixelImage } from "$lib/core/types"; import type { PixelImage } from "$lib/core/types";
import type { ToolContext, ToolEntry, ToolResult } from "$lib/registry";
import { sanitizeSchemaParams } from "$lib/registry-schema"; import { sanitizeSchemaParams } from "$lib/registry-schema";
import type { ToolContext, ToolEntry, ToolResult } from "$lib/registry-new";
/** Вход единой точки исполнения. `source`/`text` — по контракту `tool.input`. */ /** Вход единой точки исполнения. `source`/`text` — по контракту `tool.input`. */
export type ExecuteContext = { export type ExecuteContext = {
@@ -1,7 +1,7 @@
/// <reference lib="webworker" /> /// <reference lib="webworker" />
import { ToolError } from "$lib/core/errors"; import { ToolError } from "$lib/core/errors";
import type { PixelImage } from "$lib/core/types"; import type { PixelImage } from "$lib/core/types";
import { getTool } from "$lib/registry-new"; import { getTool } from "$lib/registry";
import { sanitizeSchemaParams } from "$lib/registry-schema"; import { sanitizeSchemaParams } from "$lib/registry-schema";
type WorkerRequest = { type WorkerRequest = {
+1 -1
View File
@@ -1,4 +1,4 @@
import type { CategoryId } from "../old/categories"; import type { CategoryId } from "../v1/categories";
export const LOCALES = ["ru", "en"] as const; export const LOCALES = ["ru", "en"] as const;
export type Locale = (typeof LOCALES)[number]; export type Locale = (typeof LOCALES)[number];
+2 -2
View File
@@ -1,7 +1,7 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { TOOLS } from "../old/registry"; import { TOOLS } from "../v1/registry";
import { normalizeForSearch, scoreDoc, type SearchDoc } from "./matching";
import { setLocale } from "./locale.svelte"; import { setLocale } from "./locale.svelte";
import { normalizeForSearch, scoreDoc, type SearchDoc } from "./matching";
import { toolSearchDoc } from "./tool-strings"; import { toolSearchDoc } from "./tool-strings";
describe("normalizeForSearch", () => { describe("normalizeForSearch", () => {
+1 -2
View File
@@ -1,8 +1,7 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { TOOLS } from "../old/registry"; import { isChainable, TOOLS } from "../v1/registry";
import { normalizeForSearch, scoreDoc } from "./matching"; import { normalizeForSearch, scoreDoc } from "./matching";
import { toolSearchDoc } from "./tool-strings"; import { toolSearchDoc } from "./tool-strings";
import { isChainable } from "../old/registry";
function hits(q: string): string[] { function hits(q: string): string[] {
const nq = normalizeForSearch(q); const nq = normalizeForSearch(q);
+3 -3
View File
@@ -1,10 +1,10 @@
import { afterEach, describe, expect, it, vi } from "vitest"; import { afterEach, describe, expect, it, vi } from "vitest";
import { setLocale } from "./locale.svelte"; import { TOOLS } from "../v1/registry";
import { t } from "./t";
import { LOCALE_TAGS } from "./dict"; import { LOCALE_TAGS } from "./dict";
import { setLocale } from "./locale.svelte";
import { normalizeForSearch, scoreDoc } from "./matching"; import { normalizeForSearch, scoreDoc } from "./matching";
import { t } from "./t";
import { toolSearchDoc } from "./tool-strings"; import { toolSearchDoc } from "./tool-strings";
import { TOOLS } from "../old/registry";
afterEach(() => { afterEach(() => {
setLocale("ru"); setLocale("ru");
+2 -2
View File
@@ -1,6 +1,6 @@
import type { ParamDef, ToolEntry } from "$lib/old/registry"; import type { ParamDef, ToolEntry } from "$lib/v1/registry";
import type { SearchDoc } from "./matching";
import { getMergedDict } from "./locale.svelte"; import { getMergedDict } from "./locale.svelte";
import type { SearchDoc } from "./matching";
import { ru } from "./ru"; import { ru } from "./ru";
/** /**
+1 -1
View File
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { TOOLS } from "../old/registry"; import { TOOLS } from "../v1/registry";
import { en } from "./en"; import { en } from "./en";
import { ru } from "./ru"; import { ru } from "./ru";
+2 -3
View File
@@ -1,7 +1,6 @@
import { describe, expect, it } from "vitest";
// @ts-expect-error node types are not wired into svelte-check; vitest resolves fine
import { readFileSync } from "node:fs";
import { Color } from "@panmdaa/colors"; import { Color } from "@panmdaa/colors";
import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
declare const process: { cwd(): string }; declare const process: { cwd(): string };
@@ -1,8 +1,8 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { PREVIEW_GROUPS } from "../preview/catalog"; import { TOOLS } from ".";
import { TOOLS } from "../registry-new"; import { PREVIEW_GROUPS } from "../catalog";
import { defaultSchemaParams, sanitizeSchemaParams } from "../registry-schema";
import type { PixelImage } from "../core/types"; import type { PixelImage } from "../core/types";
import { defaultSchemaParams, sanitizeSchemaParams } from "../registry-schema";
import type { ToolResult } from "./types"; import type { ToolResult } from "./types";
function asImage(result: ToolResult): PixelImage { function asImage(result: ToolResult): PixelImage {
@@ -1,7 +1,7 @@
import type { CategoryId } from "../categories";
import { ToolError } from "../core/errors"; import { ToolError } from "../core/errors";
import type { OutputMime } from "../core/io"; import type { OutputMime } from "../core/io";
import type { PixelImage } from "../core/types"; import type { PixelImage } from "../core/types";
import type { CategoryId } from "../preview/categories";
import type { ToolSchema } from "../registry-schema"; import type { ToolSchema } from "../registry-schema";
/** Формат скачивания, отличный от PNG (bmp/jpeg/webp). */ /** Формат скачивания, отличный от PNG (bmp/jpeg/webp). */

Some files were not shown because too many files have changed in this diff Show More