From b7ba1f501fc704b699dec67d46e69d6892432a38 Mon Sep 17 00:00:00 2001 From: Ku6epXBOCTuK Date: Mon, 12 Oct 2026 05:39:39 +0500 Subject: [PATCH] feat: update brand name, add domain --- .github/workflows/deploy.yml | 2 +- .gitignore | 3 - AGENTS.md | 4 - README.md | 2 +- cog.toml | 2 +- docs/README.md | 12 +-- docs/archive/README.md | 4 +- docs/backlog.md | 3 - docs/plan-seo.md | 74 +++++++++--------- docs/roadmap.md | 9 ++- package.json | 2 +- .../__tests__/no-hardcoded-user-text.test.ts | 12 +-- web/eslint.config.js | 8 +- web/scripts/gen-og.mjs | 20 +++-- web/src/lib/components/Seo.svelte | 3 +- web/src/lib/components/layout/Footer.svelte | 3 +- web/src/lib/components/layout/TopBar.svelte | 6 +- web/src/lib/components/layout/TopNav.svelte | 1 - web/src/lib/i18n/dict.ts | 2 + web/src/lib/i18n/en.ts | 7 +- web/src/lib/i18n/ru.ts | 7 +- web/src/lib/seo.ts | 12 ++- web/src/routes/pipeline/+page.svelte | 2 +- web/src/routes/tools/[slug]/+page.svelte | 4 +- web/static/CNAME | 1 + web/static/favicon.svg | 2 +- web/static/og/default.png | Bin 33836 -> 33738 bytes web/stylelint.config.js | 2 +- 28 files changed, 96 insertions(+), 113 deletions(-) create mode 100644 web/static/CNAME diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index ac3b4bc..93ef2f8 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -49,7 +49,7 @@ jobs: working-directory: web run: pnpm build env: - BASE_PATH: /easy-png-tools + PUBLIC_SITE_ORIGIN: "https://easy-image-tools.com" PUBLIC_GA_ENABLED: "true" - name: Upload Pages artifact diff --git a/.gitignore b/.gitignore index c21ad10..e197db7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,3 @@ node_modules web/audit/cdp-audit*.txt css-lint.txt web/coverage - -# Локальные планы с приватной информацией (выбранное имя домена) — не коммитить -docs/plan-domain.local.md diff --git a/AGENTS.md b/AGENTS.md index 8634e1a..08dd471 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -41,14 +41,10 @@ | Направления развития, фазы 1–11 | `docs/roadmap.md` | | SEO/GEO-план (адреса, `noindex`, sitemap) | `docs/plan-seo.md` | | API/PWA/шрифты | `docs/plan-platform.md` | -| Переименование бренда и покупка домена | `docs/plan-domain.local.md` † | | Сырые UX-находки по инструментам (вход аудита) | `docs/tools-audit.md` | | Архивирование и удаление старых документов | `docs/archive/README.md` | | Индекс остальных документов | `docs/README.md` | -† `docs/plan-domain.local.md` вне git, в клоне отсутствует — в этом случае -задачу ищут по `docs/plan-seo.md` §6. - ## Инварианты, которые линтер не проверяет - **Сначала искать.** Новая константа, тип или утилита не заводится, пока не diff --git a/README.md b/README.md index c3aa3aa..e9d56a2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# easy-png-tools +# easy-image-tools Browser-based image utility toolkit — no server, no data upload, everything runs locally in your browser. diff --git a/cog.toml b/cog.toml index 2afe0dd..a96add6 100644 --- a/cog.toml +++ b/cog.toml @@ -8,7 +8,7 @@ pre_bump_hooks = ["node scripts/sync-version.mjs {{version}}"] path = "CHANGELOG.md" template = "remote" remote = "github.com" -repository = "easy-png-tools" +repository = "easy-image-tools" owner = "Ku6epXBOCTuK" [commit_types] diff --git a/docs/README.md b/docs/README.md index 07e5e93..7f0d00b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -28,17 +28,10 @@ | `docs/plan-fields-audit-fixes.md` | Разбивка аудита на волны правок | draft | | `docs/plan-seo.md` | SEO/GEO-план | active | | `docs/plan-platform.md` | API/PWA/шрифты-план | active | -| `docs/plan-domain.local.md` | Чек-лист переименования бренда и покупки домена | active | | `docs/checklist-manual-testing.md` | Ручная приёмка production UI | active | | `web/eslint-plugins/README.md` | Правка lint-правил, токенов и их конфигов | active | | `docs/archive/README.md` | Архивирование и удаление старых документов | active | -`docs/plan-domain.local.md` **исключён из git** через `.gitignore`: выбранное -имя домена не должно попасть в историю до покупки. В клоне файла нет — это -ожидаемо, и ссылки на него в `plan-seo.md` и `backlog.md` не разрешаются. Строка -в таблице оставлена, чтобы задачу R1/R2 можно было найти по индексу; сам -чек-лист лежит только на машине разработчика. - ## Правила - У каждой темы ровно один владелец: остальные документы ссылаются на него, а не @@ -64,8 +57,7 @@ - Поиск по `docs/` задевает `docs/archive/`: там вынесены завершённые планы и исследования, поэтому grep по `docs/` даёт больше шума, чем пользы. Для правок production-кода архив не нужен: grep по `docs/*.md` без `archive/`. -- Проверка ссылок в документации не автоматизирована; ожидаемо неразрешимыми - считаются ссылки на `docs/plan-domain.local.md` (файл вне git). Всё остальное - неразрешимое — ошибка. +- Проверка ссылок в документации не автоматизирована; любая неразрешимая ссылка + — ошибка. - Протокол «остановиться и показать изменения» — `docs/agent-workflow.md`, раздел 6. diff --git a/docs/archive/README.md b/docs/archive/README.md index 5044904..a71fb46 100644 --- a/docs/archive/README.md +++ b/docs/archive/README.md @@ -41,9 +41,7 @@ 5. Найти оставшиеся входящие ссылки: `git grep -n "" -- 'docs/*.md' AGENTS.md README.md web/eslint-plugins/README.md`. Шаг 4 ломает их, и агент без этого шага напишет в новом документе ссылку на - удалённый файл. Ожидаемо неразрешимыми остаются ссылки на - `docs/plan-domain.local.md` — он вне git, это не ошибка (`docs/README.md`, - раздел «Правила»). + удалённый файл. 6. Не менять архивный документ под новые требования. ## Удаление diff --git a/docs/backlog.md b/docs/backlog.md index 73e34af..e8063e3 100644 --- a/docs/backlog.md +++ b/docs/backlog.md @@ -230,9 +230,6 @@ ## SEO/GEO -- [ ] переименование бренда + домен: чек-лист в локальном файле - `plan-domain.local.md` (в git не входит, в клоне отсутствует; подробности - и порядок — `docs/plan-seo.md` §6, R1/R2) - [ ] снять `noindex` со страниц инструментов, когда будут sitemap, canonical и контент (S1h; блокирует индексацию всего сайта) — `docs/plan-seo.md` §4 - [ ] форматные страницы по конкурентным слагам (`crop-jpeg`, …) — только по diff --git a/docs/plan-seo.md b/docs/plan-seo.md index c32e9a5..a747986 100644 --- a/docs/plan-seo.md +++ b/docs/plan-seo.md @@ -30,14 +30,14 @@ ## 0. Решения -- **Бренд: переименовать до индексации** (новое имя и домен сознательно не - записаны в этом репозитории — чек-лист в локальном файле - `plan-domain.local.md`, см. §6, он вне git: выбранное имя не должно утекать в - историю коммитов до покупки домена). Легенда честная: «started as PNG tools, - now all formats» — это контент-плюс, а не баг. Адреса страниц - (`/tools/crop-png`) и localStorage-ключи не переименовывать (см. решение про - `slug` ниже). Точка истины по бренду: константа в i18n + README; хардкод в - компонентах недопустим. +- **Бренд: `easy-image-tools`, домен `easy-image-tools.com`.** Переименование до + индексации выполнено (R1): хардкод убран, точка истины — константа `brand` в + i18n + README (хардкод в компонентах недопустим). Домен зарегистрирован + 2026-10-11 (R2); остался перевод прода на него (DNS, HTTPS, снятие + `BASE_PATH`, `PUBLIC_SITE_ORIGIN`, 301 со старого GitHub Pages) — теперь это + блокер S1-domain (§4). Легенда честная: «started as PNG tools, now all + formats» — это контент-плюс, а не баг. Адреса страниц (`/tools/crop-png`) и + localStorage-ключи не переименовывать (localStorage-ключи бренда не содержат). - **Форматы: формат = выбор в UI, не отдельные страницы.** Download-кнопка каждого инструмента — с селектором PNG/JPG/WebP/BMP (+quality для lossy). Райз «выбор формата/качества в Download» вытащен из backlog №7 в S1f: механика уже @@ -203,12 +203,14 @@ `convert-png-to-webp`, `png-to-bmp` остаются самостоятельными лендингами со своим контентом (§5). -#### S1-domain: с доменом (после покупки + DNS) +#### S1-domain: свой домен (подключён; §6 R2-cut) -- [ ] **[S1a]** Перевести прод на собственный домен: убрать `BASE_PATH` из - `deploy.yml`, задать `PUBLIC_SITE_ORIGIN`, перенаправить - `https://<юзер>//…` на корневые URL (301). Делается одновременно с - S1d (canonical), чтобы Google проиндексировал сразу с правильным доменом. +- [x] **[S1a]** Перевести прод на собственный домен — **сделано 2026-10-11**: + `BASE_PATH` убран из `deploy.yml`, задан `PUBLIC_SITE_ORIGIN`, добавлен + `web/static/CNAME`. Редирект `https://<юзер>//…` → корневые URL + (301) делает сам GitHub Pages при включённом кастомном домене. Делается + одновременно с S1d (canonical), чтобы Google проиндексировал сразу с + правильным доменом. - [ ] **[S1b]** Скрипт `web/scripts/gen-sitemap.mjs`: генерирует `sitemap.xml` в `build/` из `PAGES` реестра (`web/src/lib/registry`) + статических страниц. Взять адреса у страниц, а не у инструментов: страниц может быть @@ -314,14 +316,14 @@ > Группы здесь — по категории страницы в реестре (`registry/pages/`), а не по > смыслу: `round-corners-png` лежит в `alpha`, `add-text-png` и > `watermark-tile-png` — в `text`. - +> > **Открытый вопрос по интенту «сжать до N КБ».** Лимит размера теперь живёт в > кнопке Download (`fitWithinBytes` в `web/src/lib/core/io.ts`); интенты вида > «compress png to 500kb / 1mb» — high-volume и лимит-ориентированные, селектор > в Download их не закрывает как посадочная. Решение (отдельная страница / приём > в контенте существующих / ничего) требует вордстата; имя страницы не выбрано. > Прорабатывать вместе с вопросом «из формата в PNG» выше. - +> > **Открытый вопрос по интентам «из формата в PNG».** У конкурента есть > `jpg-to-png`, `webp-to-png`, `gif-to-png` как отдельные страницы; у нас таких > инструментов нет и создавать их не хочется — загрузка файла уже принимает @@ -398,28 +400,28 @@ with PNG, JPG, WebP» в тексте + селектор формата в Downl интенты, которые подтверждены вордстатом, и сразу с контентом S2 (страница без текста — потраченный URL). -## 6. Переименование бренда и домен (сделать до S1-domain, дёшево сейчас) +## 6. Переименование бренда и домен -Выбранное имя и домен **в этом репозитории не записаны**: детальный чек-лист -лежит в локальном файле `plan-domain.local.md` рядом с этим планом, он исключён -из git через `.gitignore`, чтобы имя не попало в историю коммитов до покупки -домена. Агент, работающий из клона, этого файла не увидит — при необходимости -попросить чек-лист у пользователя. +Бренд — `easy-image-tools`, домен — `easy-image-tools.com`. -- [ ] **[R1]** Механический переезд бренда на новое имя. Список файлов и строк с - хардкодом — в локальном плане (раздел «Где живёт бренд в коде»); здесь - только SEO-ограничения. **НЕ трогать:** адреса страниц инструментов - (`/tools/crop-png`) и localStorage-ключи — `theme` и `locale` лежат без - префикса бренда, поэтому переименование с ними не столкнётся (проверено в - `theme.svelte.ts` и `i18n/locale.svelte.ts`); историю `docs/archive`. - Бренд должен стать i18n-константой, а не тремя независимыми хардкодами. -- [ ] **[R2]** Купить выбранный домен (кандидаты и пробы — в локальном плане) и - перевести прод на него без `BASE_PATH` (§0). Домен нужен до S1-domain: - canonical и sitemap генерятся от `PUBLIC_SITE_ORIGIN`. -- **Порядок:** R1+R2 можно делать параллельно с текущими quality-задачами (не - блокируют). R2 (домен) — блокер для S1-domain (canonical + sitemap), а - S1-domain — блокер для S1h (снятие `noindex`). После индексации переименование - = переезд с 301, потеря позиций и ссылок — не делать. +- [x] **[R1]** Переезд бренда выполнен (2026-10-11): хардкод в компонентах + убран, бренд — i18n-константа `t("brand")` (точка истины — словари + `brand` + README). Репозиторий переименован в `easy-image-tools`, remote + обновлён, привязанные к репо ссылки/пути переключены: `BASE_PATH` в + `deploy.yml`, GitHub-URL в `TopBar.svelte`, `repository` в `cog.toml`. + **НЕ трогать:** адреса страниц инструментов (`/tools/crop-png`), + localStorage-ключи (бренда не содержат), историю `docs/archive`. +- [x] **[R2]** Домен `easy-image-tools.com` зарегистрирован (2026-10-11); + `SITE_URL` в `web/src/lib/seo.ts` переключён на него. +- [x] **[R2-cut]** Прод переведён на домен без `BASE_PATH` (§0) — **сделано + 2026-10-11**: DNS + HTTPS, `PUBLIC_SITE_ORIGIN` = + `https://easy-image-tools.com` в `deploy.yml`, `web/static/CNAME`. 301 со + старого GitHub Pages делает сам GitHub при включённом кастомном домене. + Canonical и sitemap генерятся от `PUBLIC_SITE_ORIGIN`. +- **Порядок:** R1(код), покупка домена и cutover (R2-cut) сделаны. Осталось + S1-domain (canonical + sitemap: S1b/S1c/S1d), а S1-domain — блокер для S1h + (снятие `noindex`). Переименование делали до индексации (до S1h): после снятия + `noindex` это был бы переезд с 301 и потеря позиций — не делать. ## 7. Что осознанно НЕ делаем @@ -443,5 +445,3 @@ with PNG, JPG, WebP» в тексте + селектор формата в Downl - `docs/roadmap.md` — фазы 2–8 (ядро TS→Rust/wasm, CLI), фаза 11 (пайплайн); фазы 9–10 — API и PWA. - `docs/plan-platform.md` — планы API и PWA (общее ядро, оффлайн-режим). -- `plan-domain.local.md` — локальный чек-лист переименования и покупки домена; - **в git не входит** (`.gitignore`), в клоне отсутствует. diff --git a/docs/roadmap.md b/docs/roadmap.md index c38fd45..dcc77cc 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -1,10 +1,11 @@ -# План развития: easy-png-tools +# План развития: easy-image-tools > **Статус: active.** Фаза 1 выполнена — сайт живёт на типизированном реестре, > production UI — корневые маршруты. Текущий фокус: SEO S1-free -> (`docs/plan-seo.md`) + открытые задачи (`docs/backlog.md`). Домен нужен для -> SEO (S1-domain). Фазы 2–8 — будущие; 9–10 спланированы в -> `docs/plan-platform.md`; 11 — пайплайн. +> (`docs/plan-seo.md`) + открытые задачи (`docs/backlog.md`). Домен +> `easy-image-tools.com` зарегистрирован; остался cutover для индексации +> (S1-domain). Фазы 2–8 — будущие; 9–10 спланированы в `docs/plan-platform.md`; +> 11 — пайплайн. > > **Идентификаторы.** Ссылаться на фазу этого документа. Пространства > идентификаторов задач: `FA-*` — правки полей и раскладки diff --git a/package.json b/package.json index 936cde9..e69bb73 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "easy-png-tools", + "name": "easy-image-tools", "version": "0.8.0", "description": "", "main": "index.js", diff --git a/web/eslint-plugins/__tests__/no-hardcoded-user-text.test.ts b/web/eslint-plugins/__tests__/no-hardcoded-user-text.test.ts index 1ec9ff5..a17e428 100644 --- a/web/eslint-plugins/__tests__/no-hardcoded-user-text.test.ts +++ b/web/eslint-plugins/__tests__/no-hardcoded-user-text.test.ts @@ -22,7 +22,7 @@ const ruleTester = new RuleTester({ }, }); -const OPTIONS = [{ allowWords: ["easy-png-tools"] }]; +const OPTIONS = [{ allowWords: ["easy-image-tools"] }]; ruleTester.run("no-hardcoded-user-text", asRuleModule(rule), { valid: [ @@ -62,12 +62,12 @@ ruleTester.run("no-hardcoded-user-text", asRuleModule(rule), { }, // Brand configured as an allowed word. { - code: "easy-png-tools", + code: "easy-image-tools", filename: "Component.svelte", options: OPTIONS, }, { - code: "
easy-png-toolsv0.1.0
", + code: "
easy-image-toolsv0.1.0
", filename: "Component.svelte", options: OPTIONS, }, @@ -130,7 +130,7 @@ ruleTester.run("no-hardcoded-user-text", asRuleModule(rule), { { // Without the option the brand word is reported: the exclusion is // configuration, not a hardcoded constant inside the rule. - code: "easy-png-tools", + code: "easy-image-tools", filename: "Component.svelte", errors: [{ messageId: "hardcodedText" }], }, @@ -156,8 +156,8 @@ describe("hasUserWords", () => { }); it("accepts configured brand words", () => { - expect(hasUserWords("easy-png-tools", ["easy-png-tools"])).toBe(false); - expect(hasUserWords("easy-png-tools")).toBe(true); + expect(hasUserWords("easy-image-tools", ["easy-image-tools"])).toBe(false); + expect(hasUserWords("easy-image-tools")).toBe(true); }); it("accepts formats and units next to real copy", () => { diff --git a/web/eslint.config.js b/web/eslint.config.js index 0268fc6..e69b509 100644 --- a/web/eslint.config.js +++ b/web/eslint.config.js @@ -178,13 +178,7 @@ export default tseslint.config( i18n: i18nPlugin, }, rules: { - "i18n/no-hardcoded-user-text": [ - "warn", - { - // The product name is a brand, not translatable text. - allowWords: ["easy-png-tools"], - }, - ], + "i18n/no-hardcoded-user-text": "warn", }, }, { diff --git a/web/scripts/gen-og.mjs b/web/scripts/gen-og.mjs index 7c420bf..b10053f 100644 --- a/web/scripts/gen-og.mjs +++ b/web/scripts/gen-og.mjs @@ -1,6 +1,4 @@ // Generates static/og/default.png: the default 1200x630 OG card. -// Run: pnpm --dir web gen:og. The card is rendered in a browser (text, -// icons); per-tool cards will reuse this harness (docs/plan-seo.md S1e). import { mkdirSync } from "node:fs"; import { chromium } from "playwright"; @@ -13,26 +11,26 @@ function cardHtml() { return `
EP
-
easy-png-tools
-
PNG utilities right in your browser
-
Convert · Crop · Resize — locally, no uploads
+ ">EIT
+
easy-image-tools
+
Image utilities right in your browser
+
Convert · Crop · Resize — locally, no uploads
${IMAGE_ICON}
`; diff --git a/web/src/lib/components/Seo.svelte b/web/src/lib/components/Seo.svelte index e513123..d256133 100644 --- a/web/src/lib/components/Seo.svelte +++ b/web/src/lib/components/Seo.svelte @@ -1,4 +1,5 @@
- easy-png-tools {versionLabel} + {t("brand")} {versionLabel} © 2026
diff --git a/web/src/lib/components/layout/TopBar.svelte b/web/src/lib/components/layout/TopBar.svelte index 1bd1131..4e9d9e7 100644 --- a/web/src/lib/components/layout/TopBar.svelte +++ b/web/src/lib/components/layout/TopBar.svelte @@ -18,8 +18,8 @@
- EP - easy-png-tools + EIT + {t("brand")} {#if crumb} {crumb} {/if} @@ -28,7 +28,7 @@
{t("header.catalog")} {t("header.chains")} - {t("header.uiKit")}