feat: Site audit and Crawls screens with their MCP tools

- golem15.seo.issues (Site audit): current issues errors first, labels,
  summary and fix columns, filters, P7 issue_details, Check this address
  again, Ignore, Stop ignoring, bulk Ignore, ignored rows badged
- golem15.seo.crawls (Crawls): newest first, P6 crawl_summary with one
  status callout, staging and rendered-comparison lines, stats strip and
  per-kind table; Cancel; a running crawl refuses delete
- Start crawl toolbar action on both, refusing already_running and
  no_site_url; navigation Site audit (gauge) and Crawls (globe)
- routes and MCP tools start/cancel/list/get/delete crawls, list_issues
  with filters (open by default), recheck_url, ignore and unignore
- AdminOperations maps both controllers; toolbar actions get their own
  operation kind
- TestCrawlAdmin, TestCrawlTools, TestIssueKindLabels
This commit is contained in:
Jakub Zych
2026-11-04 15:34:22 +01:00
parent edc03cae4b
commit c4f0b4f94c
32 changed files with 2778 additions and 20 deletions

View File

@@ -2,6 +2,8 @@ plugin:
name: SEO
description: Search engine metadata for every content type, URL rules and global SEO settings.
nav:
audit: "Site audit"
crawls: "Crawls"
pages: Pages
robots: robots.txt
notfound: 404 log
@@ -522,10 +524,142 @@ schema:
currency_invalid: "Use a three-letter currency code, e.g. PLN."
merged: "Saved. Your custom JSON-LD replaces :props in the generated :node node."
crawls:
start: "Start crawl"
list_title: "Crawls"
name: "Crawl"
started_at: "Started"
finished_at: "Finished"
status: "Status"
pages: "Pages"
issues: "Issues"
trigger: "Started by"
duration: "Duration"
site: "Site address"
st_queued: "Queued"
st_running: "Running"
st_finished: "Finished"
st_failed: "Failed"
st_cancelled: "Cancelled"
pages_limit: ":count (limit reached)"
by_admin: "Manual: :name"
by_schedule: "Schedule"
by_mcp: "MCP: :client"
trigger_admin: "Manual"
trigger_schedule: "Schedule"
trigger_mcp: "MCP"
preview_title: "Crawl"
preview: "Crawl of :url"
running_title: "In progress"
running_text: ":done pages fetched so far, up to :limit. Reload the page to see the progress."
queued_text: "Waiting for a free worker. It starts within a minute."
failed_title: "The crawl failed"
failed_text: ":error. Pages fetched before the failure and their issues are kept."
cancelled_text: "Cancelled by :name at :time."
limit_text: "The crawl stopped at the limit of :limit pages. Raise the limit in SEO settings › Site audit to crawl the whole site."
staging_text: "On this environment every page carries noindex from the non-production lock; the crawl does not report it."
render_skipped: "The comparison with the JavaScript-rendered pages was skipped: no Chrome path is configured (golem15.seo.crawl_chrome_path). The raw-HTML checks ran."
render_done:
one: ":count page was compared with its JavaScript-rendered version."
other: ":count pages were compared with their JavaScript-rendered versions."
render_failed: "The comparison with the JavaScript-rendered pages stopped: :error. The raw-HTML checks ran."
stat_pages: "Pages fetched"
stat_errors: "Errors"
stat_warnings: "Warnings"
stat_notices: "Notices"
stat_duration: "Duration"
kinds_problem: "Problem"
kinds_severity: "Severity"
kinds_count: "Addresses"
no_issues: "This crawl found no issues."
cancel: "Cancel crawl"
cancel_confirm: "Cancel this crawl? Pages fetched so far and their issues are kept."
cancelled: "Crawl cancelled."
delete_selected_confirm:
one: "Delete :count crawl? Its pages and issues are deleted with it."
other: "Delete :count crawls? Their pages and issues are deleted with them."
delete_running: "A running crawl cannot be deleted. Cancel it first."
list_empty: "No crawls yet. A crawl fetches the site like a search engine and lists what it finds in SEO › Site audit."
started: Crawl started. Follow it in SEO › Crawls; the issues appear in Site audit when it finishes.
already_running: A crawl is already running (started :time). Wait for it, or cancel it in SEO › Crawls.
no_site_url: The site address for crawls is not configured (golem15.seo.site_url). Ask the administrator to set it.
issues:
list_title: "Site audit"
name: "Issue"
severity: "Severity"
kind: "Problem"
kind_code: "Problem code"
url: "Address"
summary: "Details"
source: "Found by"
fix: "Fix"
found: "Found"
locale: "Language"
sev_error: "Error"
sev_warning: "Warning"
sev_notice: "Notice"
source_crawl: "Crawl"
source_cms: "CMS data check"
fix_tool: "MCP: :tool"
fix_code: "Site templates (code)"
state_ignored: "Ignored"
filter_severity: "Severity"
filter_kind: "Problem"
filter_source: "Found by"
filter_fix: "Fix"
filter_status: "Status"
filter_fix_tool: "Fixable through MCP"
filter_fix_code: "Needs a code change"
status_open: "Open"
status_ignored: "Ignored"
preview: "Issue details"
found_heading: "What was found"
fix_heading: "How to fix"
fix_tool_text: "Ask your MCP client to fix it with the tool “:tool”, or change it in the admin: :where."
fix_code_text: "This comes from the site's templates, not from CMS data. Ask the site's developer to change :what."
open_page: "Open the page"
rich_results: "Check in Google's Rich Results Test"
linked_from: "Linked from"
orphan_suggestions: "Pages that could link here"
orphan_suggestions_page: "Page"
orphan_suggestions_phrase: "Shared phrase"
orphan_none: "No suggestions: no other page mentions this page's title or focus keyphrase."
and_more: "and :count more"
recheck: "Check this address again"
recheck_confirm: "Fetch “:url” again now and update its issues?"
rechecked:
one: "Checked again: :count issue remains for this address."
other: "Checked again: :count issues remain for this address."
recheck_fixed: "Checked again: no issues remain for this address."
ignore: "Ignore issue"
ignore_confirm: "Ignore this issue? It stays hidden in later crawls until you stop ignoring it."
ignore_selected: "Ignore issues"
ignore_selected_confirm:
one: "Ignore :count issue? It stays hidden in later crawls."
other: "Ignore :count issues? They stay hidden in later crawls."
ignored:
one: ":count issue is ignored."
other: ":count issues are ignored."
unignore: "Stop ignoring"
unignore_confirm: "Show this issue in the audit again?"
unignored:
one: ":count issue is shown again."
other: ":count issues are shown again."
list_empty: "No issues. Problems found by the last crawl and by the CMS data checks appear here. Start a crawl to check the site again."
detail_h1: "H1 headings"
detail_skips: "Skipped levels"
detail_missing: "Missing properties"
detail_error: "Error"
detail_anchors: "Links"
detail_alternates: "Alternates"
detail_images: "Images"
detail_target: "Target"
detail_what: "Missing or to change"
where_record: "the SEO tab of the page"
where_robots: "SEO › robots.txt"
where_settings: "SEO settings"
where_redirects: "SEO › Redirects"
where_pages: "SEO › Pages"
where_rules: "SEO › URL rules"
kind_orphan_page: "Orphan page (no internal links)"
sum_orphan_page: ":count suggestions"
kind_h1_in_content: "H1 in the content"

View File

@@ -2,6 +2,8 @@ plugin:
name: SEO
description: Metadane dla wyszukiwarek we wszystkich typach treści, reguły adresów i globalne ustawienia SEO.
nav:
audit: "Audyt witryny"
crawls: "Skanowania"
pages: Strony
robots: robots.txt
notfound: Dziennik 404
@@ -536,10 +538,154 @@ schema:
currency_invalid: "Użyj trzyliterowego kodu waluty, np. PLN."
merged: "Zapisano. Twój JSON-LD zastępuje :props w wygenerowanym węźle :node."
crawls:
start: "Uruchom skanowanie"
list_title: "Skanowania"
name: "Skanowanie"
started_at: "Rozpoczęto"
finished_at: "Zakończono"
status: "Stan"
pages: "Strony"
issues: "Problemy"
trigger: "Uruchomienie"
duration: "Czas trwania"
site: "Adres witryny"
st_queued: "W kolejce"
st_running: "W toku"
st_finished: "Zakończone"
st_failed: "Nieudane"
st_cancelled: "Anulowane"
pages_limit: ":count (osiągnięto limit)"
by_admin: "Ręcznie: :name"
by_schedule: "Harmonogram"
by_mcp: "MCP: :client"
trigger_admin: "Ręcznie"
trigger_schedule: "Harmonogram"
trigger_mcp: "MCP"
preview_title: "Skanowanie"
preview: "Skanowanie :url"
running_title: "W toku"
running_text: "Dotąd pobrano stron: :done, najwyżej :limit. Odśwież stronę, aby zobaczyć postęp."
queued_text: "Czeka na wolny proces. Rozpocznie się w ciągu minuty."
failed_title: "Skanowanie nie powiodło się"
failed_text: ":error. Strony pobrane przed błędem i ich problemy zostają zachowane."
cancelled_text: "Anulowane przez: :name, :time."
limit_text: "Skanowanie zatrzymało się na limicie :limit stron. Zwiększ limit w Ustawieniach SEO › Audyt witryny, aby przeskanować całą witrynę."
staging_text: "W tym środowisku każda strona ma noindex z blokady nieprodukcyjnej; skanowanie tego nie zgłasza."
render_skipped: "Porównanie ze stronami wyrenderowanymi przez JavaScript pominięto: nie skonfigurowano ścieżki do Chrome (golem15.seo.crawl_chrome_path). Sprawdzenia surowego HTML zostały wykonane."
render_done:
one: "Porównano :count stronę z wersją wyrenderowaną przez JavaScript."
few: "Porównano :count strony z wersją wyrenderowaną przez JavaScript."
many: "Porównano :count stron z wersją wyrenderowaną przez JavaScript."
other: "Porównano :count strony z wersją wyrenderowaną przez JavaScript."
render_failed: "Porównanie ze stronami wyrenderowanymi przez JavaScript zostało przerwane: :error. Sprawdzenia surowego HTML zostały wykonane."
stat_pages: "Pobrane strony"
stat_errors: "Błędy"
stat_warnings: "Ostrzeżenia"
stat_notices: "Uwagi"
stat_duration: "Czas trwania"
kinds_problem: "Problem"
kinds_severity: "Waga"
kinds_count: "Adresy"
no_issues: "To skanowanie nie wykryło problemów."
cancel: "Anuluj skanowanie"
cancel_confirm: "Anulować to skanowanie? Pobrane dotąd strony i ich problemy zostaną zachowane."
cancelled: "Anulowano skanowanie."
delete_selected_confirm:
one: "Usunąć :count skanowanie? Jego strony i problemy zostaną usunięte."
few: "Usunąć :count skanowania? Ich strony i problemy zostaną usunięte."
many: "Usunąć :count skanowań? Ich strony i problemy zostaną usunięte."
other: "Usunąć :count skanowania? Ich strony i problemy zostaną usunięte."
delete_running: "Nie można usunąć trwającego skanowania. Najpierw je anuluj."
list_empty: "Nie było jeszcze skanowań. Skanowanie pobiera witrynę jak wyszukiwarka i wypisuje znalezione problemy w SEO › Audyt witryny."
started: Rozpoczęto skanowanie. Postęp znajdziesz w SEO › Skanowania; problemy pojawią się w Audycie witryny po jego zakończeniu.
already_running: Skanowanie już trwa (rozpoczęte :time). Poczekaj na nie lub anuluj je w SEO › Skanowania.
no_site_url: Adres witryny do skanowania nie jest skonfigurowany (golem15.seo.site_url). Poproś administratora o jego ustawienie.
issues:
list_title: "Audyt witryny"
name: "Problem"
severity: "Waga"
kind: "Problem"
kind_code: "Kod problemu"
url: "Adres"
summary: "Szczegóły"
source: "Wykryte przez"
fix: "Naprawa"
found: "Wykryto"
locale: "Język"
sev_error: "Błąd"
sev_warning: "Ostrzeżenie"
sev_notice: "Uwaga"
source_crawl: "Skanowanie"
source_cms: "Kontrola danych CMS"
fix_tool: "MCP: :tool"
fix_code: "Szablony witryny (kod)"
state_ignored: "Zignorowany"
filter_severity: "Waga"
filter_kind: "Problem"
filter_source: "Wykryte przez"
filter_fix: "Naprawa"
filter_status: "Stan"
filter_fix_tool: "Do naprawy przez MCP"
filter_fix_code: "Wymaga zmiany w kodzie"
status_open: "Otwarte"
status_ignored: "Zignorowane"
preview: "Szczegóły problemu"
found_heading: "Co znaleziono"
fix_heading: "Jak naprawić"
fix_tool_text: "Poproś klienta MCP o naprawę narzędziem „:tool” lub zmień to w panelu: :where."
fix_code_text: "To wynika z szablonów witryny, a nie z danych CMS. Poproś dewelopera witryny o zmianę: :what."
open_page: "Otwórz stronę"
rich_results: "Sprawdź w Teście wyników z elementami rozszerzonymi Google"
linked_from: "Linkowane z"
orphan_suggestions: "Strony, które mogą tu linkować"
orphan_suggestions_page: "Strona"
orphan_suggestions_phrase: "Wspólna fraza"
orphan_none: "Brak propozycji: żadna inna strona nie wspomina tytułu ani frazy kluczowej tej strony."
and_more: "i :count więcej"
recheck: "Sprawdź ten adres ponownie"
recheck_confirm: "Pobrać teraz ponownie „:url” i zaktualizować jego problemy?"
rechecked:
one: "Sprawdzono ponownie: dla tego adresu został :count problem."
few: "Sprawdzono ponownie: dla tego adresu zostały :count problemy."
many: "Sprawdzono ponownie: dla tego adresu zostało :count problemów."
other: "Sprawdzono ponownie: dla tego adresu zostało :count problemu."
recheck_fixed: "Sprawdzono ponownie: dla tego adresu nie ma już problemów."
ignore: "Ignoruj problem"
ignore_confirm: "Zignorować ten problem? Pozostanie ukryty w kolejnych skanowaniach, dopóki nie przestaniesz go ignorować."
ignore_selected: "Ignoruj problemy"
ignore_selected_confirm:
one: "Zignorować :count problem? Pozostanie ukryty w kolejnych skanowaniach."
few: "Zignorować :count problemy? Pozostaną ukryte w kolejnych skanowaniach."
many: "Zignorować :count problemów? Pozostaną ukryte w kolejnych skanowaniach."
other: "Zignorować :count problemu? Pozostaną ukryte w kolejnych skanowaniach."
ignored:
one: "Zignorowano :count problem."
few: "Zignorowano :count problemy."
many: "Zignorowano :count problemów."
other: "Zignorowano :count problemu."
unignore: "Przestań ignorować"
unignore_confirm: "Ponownie pokazywać ten problem w audycie?"
unignored:
one: "Ponownie pokazywany jest :count problem."
few: "Ponownie pokazywane są :count problemy."
many: "Ponownie pokazywanych jest :count problemów."
other: "Ponownie pokazywane jest :count problemu."
list_empty: "Brak problemów. Tutaj pojawiają się problemy z ostatniego skanowania i z kontroli danych CMS. Uruchom skanowanie, aby ponownie sprawdzić witrynę."
detail_h1: "Nagłówki H1"
detail_skips: "Pominięte poziomy"
detail_missing: "Brakujące właściwości"
detail_error: "Błąd"
detail_anchors: "Linki"
detail_alternates: "Wersje językowe"
detail_images: "Obrazy"
detail_target: "Cel"
detail_what: "Brakuje lub do zmiany"
where_record: "zakładka SEO strony"
where_robots: "SEO › robots.txt"
where_settings: "Ustawienia SEO"
where_redirects: "SEO › Przekierowania"
where_pages: "SEO › Strony"
where_rules: "SEO › Reguły adresów"
kind_orphan_page: "Strona osierocona (brak linków wewnętrznych)"
sum_orphan_page: "Propozycje: :count"
kind_h1_in_content: "H1 w treści"