Skip to content

Releases: NertiPL/nerti-abilities-for-oxygen

0.15.1 — dwie paczki abilities na jednej witrynie kładły ją białą stroną

Choose a tag to compare

@NertiPL NertiPL released this 23 Aug 11:39

Fatal error: Cannot declare class ACFW_Pack, because the name is already in use

Rejestr ACFW_Pack był od początku pisany tak, żeby paczki się nim dzieliły — pierwsza deklaruje klasę, reszta ją zastaje — i miał na to strażnika if ( class_exists( 'ACFW_Pack' ) ) return;. Strażnik nie miał szansy zadziałać ani razu.

Klasa zadeklarowana bezwarunkowo na najwyższym poziomie pliku jest wiązana przez PHP na etapie kompilacji tego pliku (early binding), czyli zanim wykona się jakikolwiek kod w środku. Kiedy druga paczka kompilowała swój bootstrap.php, nazwa była już zajęta i PHP przerywało kompilację — do class_exists() nigdy nie dochodziło. Dlatego komunikat brzmi „Cannot declare class", a nie „Cannot redeclare class": to błąd kompilacji, nie wykonania.

Klasa zadeklarowana wewnątrz bloku if nie podlega early bindingowi — powstaje dopiero, gdy wykonanie do niej dojdzie. Dopiero wtedy strażnik cokolwiek znaczy.

Zmierzone 2026-08-23 na laboria.local, gdzie stoją trzy paczki z tym samym rejestrem. Na witrynie z jedną paczką usterka nie występuje, dlatego przeżyła do teraz.

Ta sama poprawka jest potrzebna w każdej innej paczce z tym rejestrem — dopóki którakolwiek deklaruje klasę bezwarunkowo, to ONA wywróci witrynę, kiedy skompiluje się jako druga.

0.15.0 — puste pole w zakładce Design to nie brak stylu

Choose a tag to compare

@NertiPL NertiPL released this 23 Aug 11:19

Wiedza z przeniesienia Laborii, przepisana z notatek projektu do paczki — czyli tam, gdzie agent pracujący na cudzej witrynie w ogóle ją zobaczy.

bdox/house-rules rozdział 9

Kontrolka zostawiona pusta nie wyłącza stylu — oddaje decyzję wartości domyślnej, a te są widoczne. Tabela zmierzona 2026-08-23 na żywej instalacji: kolor hoveru odnośnika, podkreślenie odnośnika, kolor przycisku, interlinia. Plus trzy rzeczy, które wypełniają się same: @media spoza zarejestrowanych breakpointów jest po cichu pomijane przy raporcie sukcesu, animacji wejścia nie zapisze edit-post (jest oxygen/set-element-animations, a offset: 0 znaczy 120 px), a insert-stylesheet zastępuje właściwości selektora zamiast je doklejać.

Dwie nowe reguły w bdox/element-defaults, obie obowiązkowe

a:hover bije twoją klasę. Globalna reguła hoveru ma specyficzność (0,1,1), płaska klasa projektu (0,1,0). Klasa wygrywa w spoczynku i przegrywa w chwili, gdy kursor dojedzie — odnośnik zmienia kolor na globalny. Objaw widać tylko pod kursorem, więc przechodzi przez przegląd. Poprawka: nigdy nie ustawiaj koloru odnośnika bez hoveru w tym samym ruchu, najlepiej przez design.text_colors.link na Section albo Div, bo to kontrolka, którą klient też widzi.

Podkreślenie odnośnika, którego nikt nie napisał. Reguła globalna daje odnośnikowi wyłącznie kolor, .bde-text-link tylko display:flex, a normalize.css Oxygena rusza w a jedynie background-color. Zostaje domyślne podkreślenie przeglądarki, niezależnie od tego, czy Modern Normalize jest włączony. Przyciski są wyjątkiem — .button-atom--* ustawiają text-decoration: none, i dlatego odnośnik „ostylowany na przycisk" ręcznie zawsze wygląda inaczej niż prawdziwy Button.

0.14.0 — Nerti Abilities for Oxygen

Choose a tag to compare

@NertiPL NertiPL released this 23 Aug 11:07

Wydanie o jednym temacie: żeby agent wiedział, gdzie co jest, i żeby płacił za to mniej tokenów.

Nazwa

Repozytorium i wtyczka nazywają się teraz nerti-abilities-for-oxygen. Stara nazwa unofficial-abilities-for-breakdance-elements opisywała paczkę sprzed ośmiu wydań — dziś są w niej WooCommerce, kopie zapasowe i katalog wtyczek. GitHub trzyma przekierowanie ze starej nazwy, ale slug katalogu wtyczki się zmienił: na witrynie, gdzie stała poprzednia wersja, zainstaluj nową i usuń starą.

Żeby nie trzeba było zgadywać

bdox/house-rules rozdział 8 — gdzie co siedzi w Essential Elements. Tabela zmierzona na BEFO 1.1.0.beta.4, nie wymyślona. Dwie pułapki, na których przewraca się każdy, kto zgaduje:

  • padding Section siedzi w design.spacing.padding, a padding Div i Grid w design.container.padding — marginesy natomiast u obu w spacing,
  • kolor nagłówka nie schodzi kaskadą z rodzica, bo ustawienia globalne przypisują go wprost do h1h6; odpowiedzią jest design.text_colors.headings na Section albo Div, nie klasa CSS na wrapperze.

Plus przyciski: design.button.style to primary | secondary | custom | text, a dwadzieścia przycisków ustawionych na custom to dwadzieścia miejsc do zmiany, kiedy klient poprosi o inny odcień.

bdox/design-map z groups_only: true — dwie–trzy linie na element zamiast wszystkich kontrolek, wiele slugów w jednym wołaniu. Najpierw dowiadujesz się, GDZIE kontrolka siedzi, potem pytasz o jej wnętrze.

bdox/setup-report mówi, które grupy abilities się włączyły i dlaczego. Paczka rejestruje się po tym, co zastanie — mapa WooCommerce tylko na sklepie, kopie zapasowe tylko przy UpdraftPlusie. To jest słuszne, ale niewidoczne: agent, który nie znajduje bdox/woo-map, nie ma jak odróżnić braku wtyczki od zepsutej paczki.

Wydajność odpowiedzi

bdox/setup-report i bdox/regenerate-css nie wysypują już listingu katalogu. Witryna z 89 dokumentami buildera ma 178 skompilowanych plików CSS; to było ~6 kB JSON-a w odpowiedzi na wywołanie, które agent robi przy każdej rozgrzewce, i nie mówiło niczego poza „pliki istnieją". Teraz wraca werdykt: pliki globalne z rozmiarami, liczba plików postowych, suma bajtów i lista pustych — bo to zerobajtowy arkusz jest objawem. Pełny listing pod verbose: true.

0.13.1 — store-toolbox znowu widzi abilities kopii zapasowej

Choose a tag to compare

@NertiPL NertiPL released this 23 Aug 10:55

Poprawka do 0.13.0: bdox/store-toolbox sprawdzal udp_ab_definicje() — funkcje ze starego pliku piaskownicy, ktora w 0.13.0 zmienila nazwe razem z przeniesieniem kopii zapasowych do paczki. Raport meldowal backup_ability: false na witrynie, ktora te abilities ma.

0.13.0 — jeden ZIP, komplet abilities

Choose a tag to compare

@NertiPL NertiPL released this 23 Aug 10:53

Jeden plik ZIP na nowy projekt. Grupy abilities włączają się same, zależnie od tego, co zastaną na witrynie.

Nowe

updraft/backup-now i updraft/list-backups wchodzą do paczki. Dotąd były osobnym plikiem piaskownicy Agent Connectora, który trzeba było wgrywać ręcznie na każdej witrynie. Teraz instalują się razem z resztą i rejestrują się tylko tam, gdzie UpdraftPlus jest aktywny — tak samo jak bdox/woo-map rejestruje się tylko na sklepie.

Ta paczka nie modyfikuje UpdraftPlusa. Woła jego własny publiczny hak backupu, dokładnie tak jak przycisk „Backup Now" w panelu.

Opis backup-now mówi teraz wprost to, czego wcześniej nie mówił: przy dziesiątkach gigabajtów mediów pełna kopia idzie kilkadziesiąt minut, więc przy zmianie treści, selektorów albo ustawień globalnych właściwym zakresem jest database — kończy się w kilkadziesiąt sekund i jest prawdziwym punktem powrotu dla tej klasy zmian. Zmierzone na sklepie z ~25 GB uploads.

Zmienione

Nazwa wtyczki: „Nerti Abilities for Oxygen (Elements, WooCommerce, Backups)". Paczka dawno przestała dotyczyć samych Breakdance Elements. Slug katalogu i repozytorium zostają bez zmian — to po nich WordPress rozpoznaje aktualizacje, a przemianowanie zerwałoby je na każdej witrynie, gdzie paczka już stoi.

README ma kolejność instalacji na nowym projekcie i listę zdejmowania przed oddaniem strony. Kolejność zdejmowania nie jest dowolna: najpierw skończ budować, potem chowaj elementy przed klientem (ta sama opcja chowa je też przed agentem), potem ostatni bdox/regenerate-css, potem włącz cache stron, a dopiero na końcu usuń tę wtyczkę i Agent Connectora.

Komplet abilities w tej wersji

bdox/house-rules · bdox/design-map · bdox/woo-map · bdox/store-toolbox · bdox/element-visibility · bdox/element-defaults · bdox/setup-report · bdox/regenerate-css · bdox/get-global-settings · bdox/patch-global-settings · bdox/audit-compiled-css · bdox/merge-css-selector · bdox/builder-hidden-elements · bdox/set-image · updraft/backup-now · updraft/list-backups

0.12.1 — woo-map rejestruje sie na sklepie

Choose a tag to compare

@NertiPL NertiPL released this 23 Aug 10:17

Poprawka do 0.12.0: warunek class_exists( 'WooCommerce' ) wykonywal sie przy wczytywaniu pliku wtyczki, a WordPress wczytuje unofficial-abilities-... PRZED woocommerce (kolejnosc z active_plugins). Na sklepie warunek byl falszywy i bdox/woo-map po cichu nie powstawala. Sprawdzenie przeniesione na hak wp_abilities_api_init z priorytetem 5.

0.12.0 — kazda ability wolana bez argumentow, i sklep opisany tam, gdzie sie go buduje

Choose a tag to compare

@NertiPL NertiPL released this 23 Aug 10:12

Zmierzone na Oxygen 6.2.0-beta.6 + Breakdance Elements for Oxygen 1.1.0.beta.4 + Breakdance WooCommerce for Oxygen 1.1.0.beta.1, WordPress 7.1, PHP 8.1.34.

Naprawione — dotyczyło każdej ability w paczce

mcp-adapter-execute-ability z parameters: {} dochodzi do WP_Ability::execute() jako null, nie jako pusty obiekt. execute() woła najpierw normalize_input() (podstawia input_schema['default'], gdy wejście jest nullem), a dopiero potem validate_input(). Bez zadeklarowanego default null przechodzi normalizację nietknięty i walidacja odrzuca go komunikatem „input nie jest typu object".

Skutek: bdox/regenerate-css, bdox/setup-report, bdox/element-visibility i bdox/builder-hidden-elements nie dawały się wywołać tak, jak każe ich własny opis — bez parametrów. Poprawka siedzi w bdox_pack_ability(), więc obejmuje też każdą ability dopisaną później.

Nowe

  • bdox/woo-map — atlas elementów sklepu: czym każdy jest, kiedy po niego sięgnąć i jakie grupy z zakładki Design ma, czytane na żywo ze schematu. Rejestruje się tylko, gdy Breakdance WooCommerce for Oxygen jest aktywny. Niesie zasadę, która oszczędza najwięcej pracy: ustawienia globalne mają całą gałąź woocommerce (przyciski, kolory, pola formularzy, plakietka promocji, gwiazdki, komunikaty, tabele, skala odstępów i typografii), która ubiera cały sklep jednym zapisem — zanim ktokolwiek dotknie pojedynczego elementu.
  • bdox/store-toolbox — które wtyczki są potrzebne przy sklepie, które już tu są, których brakuje, i dwie, których nie wolno włączać przy pracującym agencie: wtyczka bezpieczeństwa blokująca REST API i cache stron pokazujący poprzednią wersję strony.

Zmienione

  • bdox/design-map zwija bloki typografii i efektów tekstu do jednej linii. EssentialElements\Wooproductprice miał 70 linii mapy, w większości dwa razy to samo (osobna typografia ceny bieżącej i przekreślonej) — teraz ma 8. expand: true przywraca pełne rozwinięcie.
  • bdox/house-rules — rozdział 6 (trzy poziomy stylowania sklepu) i 7 (wtyczki).
  • Liczby przemierzone: 188 zarejestrowanych elementów, 155 widocznych dla MCP bez paczki, 165 z paczką. Paczka odzyskuje na tej wersji 10 elementów, nie 13 — Section, Heading i Icon same zeszły ze stałej BREAKDANCE_MCP_HIDDEN_ELEMENTS.

0.8.1 — setup-report reads the font the browser got, not the one you sent

Choose a tag to compare

@NertiPL NertiPL released this 21 Aug 21:28

Added

  • bdox/setup-report now reports typography as the browser resolves it, read from the compiled global-settings.css instead of the stored settings tree, with a verdict. Two things fail silently when written and neither shows a symptom in the builder:

    • A Google Font slug is strtolower(preg_replace('/[^a-zA-Z0-9]+/', '', $family)) (plugin/fonts/integrations/google-fonts/google-fonts.php:110) — every non-alphanumeric character is dropped, not hyphenated. gfont-bricolage-grotesque is therefore accepted, stored, and emitted verbatim as the font-family, so the font never loads and every heading falls back to the generic. Measured 2026-08-21 on 6.2.0-beta.5: --bde-heading-font-family:gfont-bricolage-grotesque in the compiled file while set-global-settings reported success. The correct slug is gfont-bricolagegrotesque. A single-word family such as gfont-inter resolves fine, which is exactly why the mistake survives — it only bites on multi-word names.
    • typography.base_size takes effect only in the flat {number, unit, style} shape; the breakpoint map the built-in schema demands validates and does nothing, because the twig reads .style.

    The verdict says unresolved_font_slug in heading_font (naming which keys) or ok. testy/sprawdz-typografie.php covers both branches plus later-declaration-wins and the missing-file case — wp eval-file, six assertions, no framework.

Changed

  • bdox/patch-global-settings description names typography.base_size as the second confirmed key the built-in tool cannot write usefully, and warns about the follow-on: once base_size is stored flat, later oxygen/set-global-settings calls fail their output validation (base_size[number] is not of type object,null) although the write itself went through. Read state back with bdox/get-global-settings. Same root cause as buttons.primary.corner_radius — the builder stores flat, the MCP schema demands a breakpoint map.

0.8.0 — the option that hides elements from the client also hides them from the agent

Choose a tag to compare

@NertiPL NertiPL released this 21 Aug 17:49

Nothing added, nothing removed. Every ability description, the plugin header, the README and UPSTREAM.md were re-measured against Oxygen 6.2.0-beta.5 + Breakdance Elements for Oxygen 1.1.0.beta.1, WordPress 7.1, PHP 8.2.29 and corrected. Three of the pack's stated reasons for existing turned out to be fixed upstream, one was flatly wrong, and one new coupling was found.

Fixed

  • The pack claimed oxygen_builder_hidden_elements does not affect MCP. It does. The plugin header, the README and bdox/element-visibility's description all said the option controls the editor panel only. admin/settings-page/tabs/elements.php hangs filter_builder_elements() on the breakdance_builder_elements filter at priority 10, and mcp/schemas/elements.php runs the MCP element list through that same filter. Measured: adding EssentialElements\Button to the option took oxygen-get-element-slugs from 164 to 163 and made get-element-schemas refuse it; removing it restored 164. Rule that follows, now stated in three places: build first, hide last.
  • bdox/builder-hidden-elements reported a number that never moves. It returned builder_panel from count(get_elements_for_builder()), which maps over every registered classname and only feeds the filtered list to addPanelRules — measured 165 both before and after hiding an element. Replaced with mcp_visible_count and hidden_from_mcp, so the ability now reports both sources of truth: the stored option and what MCP can actually address.
  • The "empty list is repopulated on the next request" claim was wrong. Measured: an empty builder_hidden_elements persists across requests. addDefaultHiddenElements() is called from handleVersionChange() and the setup wizard, so the re-fill happens on the next Oxygen update, not the next request. The non-empty placeholder is still correct — the reason changed, not the behaviour.
  • The element counts in the header and README were from beta.2 (162 / 149). Re-measured: 186 registered, 151 MCP-visible without the pack, 164 with it. BREAKDANCE_MCP_HIDDEN_ELEMENTS now holds 14 entries and no longer bans Section, Heading or Icon — those three are hidden purely by the WP option.

Changed

  • bdox/merge-css-selector no longer claims to be the only route to !important. Oxygen fixed that in 6.2.0: css-to-properties.php diverts every !important declaration into custom_css with the flag intact, before the typed converters run. Measured on beta.5 — .probe{color:#ff0000 !important;padding:8px} stored padding as a typed property and custom_css as :selector {\n color: #f00 !important;\n}. The ability stays for the two things still broken: the importer replaces a selector's whole property map per breakpoint (measured — a margin-only import wiped both padding and custom_css), and it lowercases custom-property names (--myVar stored as --myvar while var(--myVar) keeps its case, so the reference dies and the import reports success).
  • bdox/patch-global-settings lost its main reason and kept a smaller one. set-global-settings deep-merges since beta.5 (breakdance_mcp_deep_merge_settings) — measured, a typography.base_font_size-only call left colors.palette and typography.body_font intact. What it still cannot do is write a key on an object closed with additionalProperties: false: buttons.primary.background_hover goes through, buttons.primary.typography.color_hover is rejected — and elements/macros/atom-v1-button-css.twig reads exactly that key. The description now says so instead of advertising the merge.
  • bdox/get-global-settings stays, with the real failure. Soflyy fixed the empty-settings case ({"settings":{}} instead of an error), so on a blank site the built-in reader works. On a real one it still returns nothing: output[settings][buttons][primary][corner_radius][unit] is not of type object,null. Observed on a production site and reproduced on the beta.5 lab install with the same stored value. The output schema wants corner_radius breakpoint-keyed; the builder stores it flat as {number, unit, style} — and stores it breakpoint-keyed under button_presets[].styles, so the same control is persisted two different ways.
  • bdox/regenerate-css narrowed its claim. Still no cache-regeneration tool among the 49 the beta.5 server exposes, but Oxygen's own save paths do regenerate (data/save.php:121 calls generateCacheForPost(); save_global_settings() and save_selectors() call generateCacheForGlobalSettings()). The ability is for data changed outside those paths, and for a stale compiled cache.
  • bdox/element-visibility was rewritten to report three lists, not two counts. banned_by_oxygen (the constant), hidden_in_elements_panel (the WP option), restored_by_this_pack, plus still_hidden_from_mcp and an explicit warning about the shared filter. It also stopped comparing element slugs against classnames, which made the old hidden_from_mcp meaningless.
  • The two add_filter calls stay, with the deletion condition written into the code. They exist only because the fundamentals are supposed to replace these elements — and on BEFO 1.1.0.beta.1 the fundamentals do not exist: class_exists() is false for FText, FImage, FRichText, FTextLink, FSvgIcon2, FHtmlCode and EssentialElements\ContainerLink. The native OxygenElements fallbacks exist but have no Design tab — measured via oxygen-get-element-schemas: EssentialElements\{Section,Heading,Text,Image2,Button} expose design, OxygenElements\{Container,Text,Image} do not. The header now names the re-measure condition: after BEFO ≥ 1.1.0.beta.3, check class_exists('EssentialElements\FText') and whether its schema has a design section; only if both hold do the filters get deleted.
  • bdox/set-image re-measured, unchanged. The wpmedia control still schemas media as {id, url, alt} with additionalProperties: false, and both OxygenElements\Image and EssentialElements\Image2 still resolve src as content.image.media.sizes[size].url.
  • typography.css.twig lines 114 and 126 still lack | join(' '), so text-decoration-line still compiles to the literal Array. Recorded in UPSTREAM.md as still open.

The cost of the restore is now written down

Previously unstated: restoring on breakdance_builder_elements also unhides those 13 elements in the builder's Add panel, because get_elements_for_builder() hands the same filtered array to FilteredGets\addPanelRules(), which sets alwaysHide on whatever is missing from it. Measured — pack active: Section, Div, Heading report no alwaysHide; pack filter removed: all three do. Two consequences, now documented in the plugin header, the README and bdox/builder-hidden-elements:

  • While the pack is active the client sees those elements too, which removes exactly the simplification Oxygen was going for.
  • A human who hides one of the 13 in Oxygen → Settings → Elements is silently overruled: the pack restores at priority 20, after the settings page subtracts at priority 10.

Restoring "for MCP only" was considered and rejected. The panel and MCP go through different functions but share one filter, and the filter carries no caller context, so the only discriminator is the admin-ajax action name — a string Oxygen may rename, after which the guard silently stops matching. Instead, the existing bdox_pack_restored_elements filter is documented as the lever: add_filter( 'bdox_pack_restored_elements', '__return_empty_array' ) at handover. Handover order, which is not the build order: build → hide → narrow (or deactivate). Hiding while the pack still restores does nothing.

0.7.0 — media-library images that render

Choose a tag to compare

@NertiPL NertiPL released this 27 Jul 11:06

Added

  • bdox/set-image — point an image element at a media-library attachment so it actually renders, at a named size and with a srcset. The built-in path cannot do this. Measured on Oxygen 6.2.0-beta.2: an OxygenElements\Image with from: media_library and size: "large" renders the builder's 540×540 grey placeholder while edit-post reports success and reads the data back exactly as written. The element resolves its src as content.image.media.sizes[size].url, but the MCP schema declares media with only id, url, alt and additionalProperties: false, so sizes can never be written and the lookup falls through to |default(). attributes.srcset is unreachable the same way, so an API-created image emits no srcset at all.

    Measured end to end on a probe page: before, src="data:image/svg+xml…" and one placeholder; after, src="…-1024x640.png" with a five-candidate srcset and zero placeholders. An unknown size is the one remaining way to get a placeholder, so it is rejected with the list of real sizes.

    alt needed its own handling. The element does not render media.alt from the tree — its template reads get_attachment_alt(media.id) in from_media_library mode and custom_alt in custom mode, so an attachment without _wp_attachment_image_alt renders an <img> with no alt attribute at all. Passing alt switches the element to custom mode, and alt_mode in the response says when the attachment's own alt is empty.

    Upstream report: soflyy/agent-connector-for-wp#79

Changed

  • New helpers bdox_pack_get_tree() / bdox_pack_save_tree() / bdox_pack_map_node(). _oxygen_data is not the tree — it is an object whose single key tree_json_string holds the tree as an encoded string, so decoding one level and subscripting ['root'] yields null. map_node is copy-based rather than a reference finder: an aliasing finder previously duplicated whole subtrees across seventeen pages.