{"id":39200718,"url":"https://github.com/coryhubbell/development-translation-bridge","last_synced_at":"2026-07-04T04:00:38.367Z","repository":{"id":323562101,"uuid":"1093757900","full_name":"coryhubbell/Development-Translation-Bridge","owner":"coryhubbell","description":"Universal WordPress page builder translation system across 14 frameworks","archived":false,"fork":false,"pushed_at":"2026-07-03T01:42:00.000Z","size":1364,"stargazers_count":25,"open_issues_count":0,"forks_count":9,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-07-03T02:07:15.816Z","etag":null,"topics":["avada","beaver-builder","bootstrap5","bricks-builder","cli","converter","divi","elementor","gutenberg","kadence","migration","oxygen-builder","page-builder","php","python","translation","wordpress","wordpress-theme","wpbakery"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/coryhubbell.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-10T19:55:19.000Z","updated_at":"2026-07-03T01:42:02.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/coryhubbell/Development-Translation-Bridge","commit_stats":null,"previous_names":["coryhubbell/wordpress-boostrap-claude","coryhubbell/wordpress-bootstrap-claude","coryhubbell/development-translation-bridge"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/coryhubbell/Development-Translation-Bridge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coryhubbell%2FDevelopment-Translation-Bridge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coryhubbell%2FDevelopment-Translation-Bridge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coryhubbell%2FDevelopment-Translation-Bridge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coryhubbell%2FDevelopment-Translation-Bridge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/coryhubbell","download_url":"https://codeload.github.com/coryhubbell/Development-Translation-Bridge/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coryhubbell%2FDevelopment-Translation-Bridge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35109212,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-04T02:00:05.987Z","response_time":113,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["avada","beaver-builder","bootstrap5","bricks-builder","cli","converter","divi","elementor","gutenberg","kadence","migration","oxygen-builder","page-builder","php","python","translation","wordpress","wordpress-theme","wpbakery"],"created_at":"2026-01-17T22:54:43.934Z","updated_at":"2026-07-04T04:00:38.360Z","avatar_url":"https://github.com/coryhubbell.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DevelopmentTranslation Bridge\n\n**Move a WordPress site from one page builder to another — without rebuilding\nit by hand.** Translation Bridge converts content between 14 frameworks —\nElementor, DIVI, Gutenberg, Bricks, Oxygen, Avada, WPBakery, Beaver Builder,\nKadence, Thrive, Bootstrap, plus native support for the ground-up rewrites\n(DIVI 5, Elementor 4 Atomic Editor, Oxygen 6).\n\n[![CI](https://github.com/coryhubbell/Development-Translation-Bridge/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/coryhubbell/Development-Translation-Bridge/actions/workflows/ci.yml)\n[![Version](https://img.shields.io/badge/version-4.13.0-blue.svg)](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.13.0)\n[![Status](https://img.shields.io/badge/status-production--ready-success.svg)](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.13.0)\n[![PHP](https://img.shields.io/badge/PHP-8.1%2B-777BB4.svg)](#requirements)\n[![Python](https://img.shields.io/badge/Python-3.9%2B-3776AB.svg)](#requirements)\n[![License](https://img.shields.io/badge/license-GPL--2.0%2B-green.svg)](LICENSE)\n[![Frameworks](https://img.shields.io/badge/frameworks-14-brightgreen.svg)](#supported-frameworks)\n[![Translation pairs](https://img.shields.io/badge/pairs-182-success.svg)](#supported-frameworks)\n\n**[Quick start](#quick-start) · [CLI reference](#cli) · [Python API](#python-api)\n· [REST API](#rest-api) · [Architecture](#architecture) · [Latest release notes](https://github.com/coryhubbell/Development-Translation-Bridge/releases/latest)**\n\n![Visual Interface translating a Bootstrap hero section into Gutenberg blocks, with live preview](docs/images/admin-visual-interface.png)\n\n*The bundled Visual Interface (WordPress Admin → Visual Interface): Monaco-powered\nside-by-side editing, framework selectors, live preview, and one-click\ntranslate/check/AI actions.*\n\n---\n\n## What it does\n\nTranslation Bridge takes content in any supported page builder's native format\n(Elementor JSON, DIVI shortcodes, Gutenberg blocks, etc.) and re-emits it in\nanother framework's format. It runs as either a WordPress plugin (with a REST\nAPI), a standalone CLI, or a Python library.\n\nTypical situations it solves:\n\n- **Builder migration.** A site built on Elementor needs to become\n  Gutenberg-native (or Bricks, or anything else) — convert the pages instead\n  of rebuilding them.\n- **Version rewrites.** DIVI 4 → DIVI 5, Elementor 3 → Elementor 4 Atomic,\n  Oxygen 4 → Oxygen 6: the successor formats are supported natively, so\n  legacy content can be modernized in place.\n- **Clean HTML output.** Emit framework-free Bootstrap 5 HTML from any\n  builder — useful for handoffs, static exports, and AI/agentic content\n  pipelines.\n- **No silent data loss.** Elements without a native equivalent in the target\n  framework are preserved and visibly annotated rather than dropped.\n\nTwo transformation paths — pick by your source format:\n\n```mermaid\nflowchart TD\n    IN([\"Your content\"]) --\u003e Q{\"Source format?\"}\n    Q --\u003e|\"Any of the 14 frameworks\u003cbr/\u003e(JSON, block markup,\u003cbr/\u003eshortcodes, HTML)\"| T[\"\u003cb\u003etransform\u003c/b\u003e — Python v4 engine\u003cbr/\u003e100% metadata preserved · ~0.5s/page\"]\n    Q --\u003e|\"Shortcodes / HTML\u003cbr/\u003e(DIVI 4, WPBakery, Avada, ...)\"| L[\"\u003cb\u003etranslate\u003c/b\u003e — PHP v3 engine\u003cbr/\u003eHTML intermediate · ~30s/page\"]\n    T --\u003e OUT([\"Any of the 14 target frameworks\"])\n    L --\u003e OUT\n```\n\n| Path | Engine | Approach | Metadata | Speed | Best for |\n|---|---|---|---|---|---|\n| `transform` | Python (v4) | JSON-native | **100%** | ~0.5s/page | **All 14 frameworks parse as sources** (JSON, block markup, shortcodes, and HTML) |\n| `translate` | PHP (v3) | HTML intermediate | ~42% | ~30s/page | Any framework, including shortcode-based (WPBakery, DIVI 4, Avada) |\n\nThe `transform` path is the recommended default; `translate` is retained for\nHTML-based frameworks that don't have a JSON canonical form.\n\n---\n\n## Supported frameworks\n\n14 frameworks → 182 translation pairs (`N × (N-1)`).\n\n| Framework key | CMS version targeted | Format | Notes |\n|---|---|---|---|\n| `bootstrap` | Bootstrap 5.3.x | HTML | Universal output, AI-friendly |\n| `elementor` | Elementor 3.30.0 | JSON | Section → Column → Widget |\n| `elementor-4` | Elementor 4.0.0 | JSON | Atomic Editor (`e-div-block`, `e-flexbox`, `e-heading`...) |\n| `divi` | DIVI 4.27.0 | Shortcodes | `[et_pb_*]` |\n| `divi-5` | DIVI 5.0.0 | Block markup | `\u003c!-- wp:divi/* --\u003e` |\n| `oxygen` | Oxygen 4.8.3 | JSON | Legacy `ct_*` schema |\n| `oxygen-6` | Oxygen 6.0.0 | JSON tree | Breakdance-derived `EssentialElements\\*` namespace |\n| `gutenberg` | WordPress 6.9.0 | Block markup | Canonical core blocks |\n| `bricks` | Bricks 2.3.5 | JSON | Flat element registry with `parent` ids |\n| `kadence` | Kadence Blocks 3.7.2 | Block markup | `kadence/*` blocks + `core/*` fallthrough |\n| `thrive` | Thrive Architect 10.8.10 | TCB HTML | `data-css` tokens + `tve_custom_style` |\n| `wpbakery` | WPBakery 8.7.3 | Shortcodes | `[vc_*]` |\n| `beaver-builder` | Beaver Builder 2.10.2 | JSON | |\n| `avada` | Avada 7.15.3 | Shortcodes | `[fusion_*]` |\n\n### Schema verification status\n\nThe `oxygen-6`, `divi-5`, and `elementor-4` paths shipped in v4.3.0 as\ndocumentation-based proxies; they have since been **verified and corrected\nagainst real evidence**:\n\n- **`elementor-4`** — verified against the open-source\n  [elementor/elementor](https://github.com/elementor/elementor) repository\n  (`modules/atomic-widgets`): settings now use the real typed-prop system\n  (`$$type` envelopes, `html-v3` content, `link.destination`,\n  `Style_Definition` variants) and only real atomic element types are emitted.\n- **`divi-5`** — verified against the Divi 5 block-format docs: content lives\n  in the top-level `content` attribute group with unicode-escaped HTML and\n  the responsive `desktop.value` wrapper.\n- **`oxygen-6`** — node shape verified against a **real Breakdance element\n  export** (committed at `tests/fixtures/oxygen6/`): integer ids,\n  `data`-nested type/properties, `_parentId` back-references, and\n  `content.content` field grouping. Oxygen 6 shares ~80% of Breakdance's\n  codebase; if Oxygen 6 ships its own element namespace, the parser's\n  namespace-agnostic lookup already handles it and the emitter's prefix is a\n  single constant.\n\n`tests/Unit/ProxySchemaVerificationTest.php` pins all of the above, including\nparsing the real export end-to-end.\n\n---\n\n## Current release: v4.13.0 (production-ready)\n\n**v4.13.0 completes RFC 5.0 Phase 2.** The legacy component vocabulary now\ntranslates through one shared, spec-aligned module per engine —\n`translation_bridge.interchange` is the exact Python mirror of\n`DEVTB_Component::to_universal()`, and the conformance suite asserts both\nengines translate the component shape identically on real fixtures. Full\nnotes:\n[v4.13.0 release](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.13.0)\nand [`RELEASE_NOTES_V4.13.0.md`](RELEASE_NOTES_V4.13.0.md).\n\n### What 4.13.0 added (RFC 5.0 Phase 2 complete)\n\n- **Shared interchange module:** `src/translation_bridge/interchange.py` —\n  component-shaped dicts translate to canonical universal elements with\n  PHP-identical semantics; the Gutenberg converter's ad-hoc adapter is\n  replaced by delegation to it.\n- **Exact-mirror conformance gate:**\n  `component_to_element(to_array()) == to_universal()` for every component\n  of all three real fixtures, on every CI run.\n- **Round-trip vocabulary completed in both engines:** `icon_list`,\n  `wp_gallery`, `selected_icon`, `alert_*`, and CTA links survive\n  universal ⇄ component conversion.\n- **Better legacy output:** `row`/`column` components become real\n  `core/columns` blocks; the schema-canonical `nav` widgetType is accepted.\n\n### What 4.12.0 added (RFC 5.0 Phases 1–2)\n\n- **The spec:** `schema/universal-element.schema.json` +\n  [`docs/RFC-5.0-engine-consolidation.md`](docs/RFC-5.0-engine-consolidation.md).\n- **Conformance in CI:** three real fixtures parsed by both engines must\n  produce schema-valid, content-equivalent documents.\n- **Universal interchange in PHP:** `DEVTB_Universal`,\n  `parse_to_universal()` / `translate_universal()`, and `universal` as a\n  REST source/target.\n- **Cross-engine proof:** Python-parsed → PHP-converted and PHP-parsed →\n  Python-converted, both content-preserving. Purely additive.\n\n### What 4.11.0 added (Python parsers final tranche)\n\n- **Seven new parsers:** DIVI 4, WPBakery, and Avada (shared shortcode\n  tokenizer with self-closing-leaf handling); Kadence (extends the\n  Gutenberg parser); Beaver Builder (flat node registry); Thrive and\n  Bootstrap (shared HTML walker).\n- **13 new transform pairs** and CLI resolution; verified against the\n  committed DIVI kitchen-sink fixture and the repo's real Bootstrap hero\n  example. Purely additive.\n\n### What 4.10.0 added (Python parsers tranche 2)\n\n- **`Oxygen6Parser`** — the Breakdance-verified node shape, all envelope\n  variants, design breakpoints canonicalizing; parses the committed real\n  export fixture end to end.\n- **`Divi5Parser`** — `wp:divi/*` markup per the verified format, with\n  tablet/phone/hover wrappers canonicalizing.\n- **`GutenbergParser`** — core block markup as a lossless source; unknown\n  blocks preserved verbatim.\n- Shared block tokenizer, parse-direction responsive helpers, seven new\n  transform pairs, CLI aliases. Purely additive.\n\n### What 4.9.0 added (responsive canonicalization completion)\n\n- **Elementor v3:** `_tablet`/`_mobile`/`_hover` setting suffixes\n  canonicalize on parse and re-emit on convert, in both engines.\n- **Bricks:** `:tablet_portrait`/`:mobile_portrait` setting-key suffixes\n  canonicalize and re-emit in both engines; `mobile_landscape` passes\n  through verbatim.\n- **Cross-framework transfer in every direction** — e.g. Elementor tablet\n  overrides become Bricks `:tablet_portrait` keys, and either can land in\n  DIVI 5 wrappers, Elementor 4 variants, or Oxygen `media` bags. Purely\n  additive: non-responsive content converts byte-identically.\n\n### What 4.8.0 added (e2e fidelity smoke gates)\n\n- **Two new gates:** Elementor → Bricks (flat-format integrity + content\n  survival) and DIVI → Gutenberg (new 17-module DIVI kitchen-sink fixture;\n  content survival + block integrity, both Gutenberg converters).\n- **Seven content drops fixed:** Bricks converters (Python widget branches,\n  PHP gallery arrays) and Gutenberg converters (container recursion,\n  universal attribute vocabulary, button labels, toggle panels, testimonial\n  citations).\n- `make e2e-smoke` runs all three gates locally; `make verify` and CI\n  include them.\n\n### What 4.7.0 added (JSON source parsers)\n\n- **Three new source parsers** on the lossless Python engine, built on\n  schemas verified in earlier releases: `BricksParser` (real 2.x flat page\n  format), `OxygenParser` (all four classic storage shapes, with unit\n  normalization and responsive `media` canonicalization), and\n  `Elementor4Parser` (typed-prop unwrapping + style-variant\n  canonicalization).\n- **CLI wiring:** `devtb transform bricks|oxygen|elementor4 \u003ctarget\u003e\n  file.json` works end to end; five new transform pairs registered\n  (each source → `gutenberg` / `bootstrap`).\n- **Shared `UniversalDocument` primitives** so the next source parser is a\n  much smaller diff.\n- Purely additive — no existing transform or converter behavior changed.\n\n### What 4.6.0 added (classic Oxygen hardening)\n\n- **All four real storage shapes parse** — the nested `ct_builder_json` root\n  tree, the `ct_builder_json` wrapper, the flat `ct_parent` list, and\n  `ct_builder_shortcodes` strings. (Previously only the flat list parsed —\n  the committed fixture itself was unreadable.)\n- **Real element vocabulary** — `ct_link`, `ct_new_columns`/`ct_column`,\n  `oxy_rich_text`, `oxy_testimonial_box`, `oxy_map`, `oxy_nav_menu`, and the\n  rest of the genuine `ct_*`/`oxy_*` set; nine fabricated names earlier\n  releases emitted still parse as aliases but are never emitted again.\n- **One output shape across engines** — PHP and Python now emit the identical\n  real root-tree format with correct `ct_id`/`ct_parent` linkage (previously\n  three mutually incompatible shapes).\n- **Style + responsive fidelity** — full `options.original` passthrough\n  (the old allow-list silently dropped `gap`, `border` shorthand, and more),\n  unit normalization both ways (Oxygen unitless ↔ CSS px), and\n  `options.media` breakpoint overrides round-tripping via the canonical\n  responsive model.\n- **Deterministic output** — `time()`-based selectors removed; conversions\n  are byte-reproducible.\n\n### What 4.5.0 added (responsive breakpoint round-tripping)\n\n- **Canonical responsive model** — breakpoints `desktop`/`tablet`/`phone`,\n  states `default`/`hover` — carried in component metadata, implemented on\n  both engines (`DEVTB_Responsive_Helper` in PHP,\n  `translation_bridge.responsive` in Python).\n- **DIVI 5:** per-breakpoint content values and hover states parse into\n  canonical form and re-emit as full multi-breakpoint wrappers.\n- **Elementor 4:** style-definition variants canonicalize per\n  breakpoint/state (`mobile` ↔ `phone`) and re-emit as one variant each.\n- **Oxygen 6:** design-tree `breakpoint_*` leaves flatten to canonical props\n  and re-nest on emit — design data now round-trips at all.\n- **Cross-framework transfer:** responsive styling moves between frameworks\n  (e.g. Oxygen 6 design breakpoints → Elementor 4 variants), tested in both\n  directions. Purely additive — elements without responsive data emit\n  byte-identical output to v4.4.0.\n\n### What 4.4.0 added (real-format schema verification)\n\nThe three next-generation framework paths shipped in v4.3.0 as\ndocumentation-based proxies; v4.4.0 corrects each against real evidence:\n\n- **Elementor 4 — verified against the open-source elementor repo**\n  (`modules/atomic-widgets`). Settings now use the real typed-prop system:\n  every value wrapped in a `{\"$$type\": ..., \"value\": ...}` envelope,\n  `html-v3` content props, the `paragraph` settings key,\n  `link.destination`/`isTargetBlank`, the nested `image.src` shape, and\n  `Style_Definition` variants referenced via the `classes` prop. Emissions\n  use only real atomic element types — `e-svg`, `e-youtube`,\n  `e-self-hosted-video`, `e-divider` replace the invented\n  `e-icon`/`e-video`/`e-list`.\n- **DIVI 5 — verified against the Divi 5 block-format docs.** Content moved\n  to the top-level `content` attribute group (was `module.content`), and\n  block attrs now unicode-escape HTML exactly like WP core's\n  `serialize_block_attributes()`, so content can never break the\n  block-comment delimiters. The responsive `desktop.value` wrapper was\n  confirmed correct as shipped.\n- **Oxygen 6 — verified against a real Breakdance export** (committed,\n  scrubbed, at `tests/fixtures/oxygen6/`). Nodes carry integer ids with the\n  element payload nested under `data`, `_parentId` back-references, a\n  `tree.root` envelope, `content.content` field grouping, the plural `tags`\n  heading key, and real element names (`CodeBlock`, `TextLink`,\n  `PricingTable`, `ProgressBar`).\n- **Back-compat preserved:** parsers accept both the real shapes and the old\n  proxy shapes, so v4.3.x output still translates. Nine new\n  schema-verification tests pin the real formats — including parsing the\n  real export end-to-end.\n- **Release engineering:** Dependabot across five ecosystems, reproducible\n  zip packaging (`scripts/build-release-package.sh` + tag-triggered\n  releases), the four-job CI pipeline, and `make verify`.\n\n### What 4.3.4 added (Elementor → Gutenberg widget coverage)\n\n- **Widget coverage on both engines.** ~70 of the 90+ universal widget types\n  the Elementor parser produces were previously silently collapsing onto\n  `core/paragraph` with empty content. Compound widgets (`tabs`, `accordion`,\n  `card`, `cta`, `counter`, `testimonial`, `pricing-table`, `alert`) now\n  expand into native block groups with a `devtb-\u003ctype\u003e-converted` className.\n  Widgets with no native Gutenberg equivalent (`form`, `slider`, `countdown`,\n  `portfolio`, `toc`, `map`, `progress`, `rating`, unknown widgets) are\n  preserved as `core/html` with a visible `data-devtb-source` annotation —\n  no silent data loss.\n- **Type-map expansion** for 1:1 mappings the parser produced but the\n  converter was missing (`social-icons`, `nav`, `blockquote`, `icon`).\n- **Settings denormalization** (typography, color, spacing, border,\n  className, anchor) restored on the Python side — these were silently\n  dropped before.\n- **Four new transforms registered:** `elementor_to_gutenberg`,\n  `html_to_gutenberg`, `divi_to_gutenberg`, `bricks_to_gutenberg`.\n- **CI gate:** kitchen-sink fixture (30 widget types, every dispatch class)\n  now runs through both engines on every push and PR via the new\n  `Python tests + Gutenberg e2e smoke` job. The smoke caught two real\n  fidelity bugs (counter title, blockquote author) that the targeted unit\n  tests didn't reach — both fixed before tagging.\n\nFull notes: [v4.3.4 release](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.3.4)\nand [`RELEASE_NOTES_V4.3.4.md`](RELEASE_NOTES_V4.3.4.md).\n\n### What 4.3.0 added (framework coverage milestone)\n\n- **3 new frameworks:** `divi-5`, `elementor-4`, `oxygen-6` — native parser +\n  converter pairs for the block-based / atomic rewrites.\n- **Bricks correctness fix:** PHP converter now emits the flat 2.x page\n  format (string `parent` ids, child id arrays) matching real Bricks output.\n  Previous nested-children output was wrong against every Bricks version.\n- **Automatic routing:** legacy DIVI and Elementor parsers detect their\n  successor format and route to the new parser instead of attempting an\n  incompatible parse.\n- **Framework matrix:** 11 → 14 frameworks, 110 → 182 translation pairs.\n\n### What 4.3.1 → 4.3.3 added (production-readiness chain)\n\n- **CLI translation fatal fixed** (`v4.3.1`): the inline autoloader mangled\n  namespaced class names — replaced with a shared autoloader used by CLI,\n  PHPUnit, and (defense-in-depth) WordPress.\n- **Matrix consistency across all surfaces** (`v4.3.1`): REST API, CLI,\n  file-handler, config class, admin TypeScript, Monaco language map — all now\n  derive from `DEVTB_Converter_Factory::get_framework_info()`. Stale `claude`\n  pseudo-framework purged from every consumer.\n- **Test suite green** (`v4.3.1`): 41 errors + 3 failures → **0 / 0** (284\n  tests, 4,133 assertions). PHP 8.5 deprecation count → 0.\n- **PHP 8.1+ floor declared** (`v4.3.1`): matches the tested runtime; PHP 7.4\n  EOL'd 2022-11.\n- **Security** (`v4.3.1`): CVE-2026-24765 (unsafe deserialization in PHPT\n  coverage) cleared by phpunit bump to 9.6.34.\n- **User-facing copy synced to 14 / 182** (`v4.3.2`): style.css framework\n  list, ASCII banner, admin help text, CLI help text.\n- **`functions.php` admin pages factory-driven** (`v4.3.3`): five hardcoded\n  9-framework call sites (admin home, Frameworks matrix table, Settings\n  select, System Status rows, Framework Details card) now consume the factory\n  directly. Adding a 15th framework later only requires updating the factory.\n\nv4.3.1 → v4.3.3 notes: [v4.3.3 release](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.3.3) — see also [`CODEX_REVIEW.md`](CODEX_REVIEW.md) for file-by-file rationale.\n\n---\n\n## Quick start\n\n### Requirements\n\n- PHP **8.1+** (for the `translate` path, theme install, and REST API)\n- Python **3.9+** (for the `transform` path and CLI); local verification is pinned to **3.11** via `.python-version`\n- Node **20.19.0**, **22.13.0+**, or **24+** + npm (only to rebuild the React admin UI from source)\n- Composer 2.0+ and pip (only if installing from source)\n\n### Install\n\n```bash\ngit clone https://github.com/coryhubbell/Development-Translation-Bridge.git\ncd Development-Translation-Bridge\n\n# PHP dependencies\nmake composer-install\n\n# Python package\npip install -e .\n\n# Build the React admin UI (required for the Visual Interface in production).\n# admin/dist/ is gitignored, so this step is needed after every clone or pull\n# that touches admin/. In WP_DEBUG mode the Vite dev server is used instead;\n# see admin/README.md for the dev workflow.\ncd admin\nnpm ci\nnpm run build\ncd ..\n\n# Make the CLI executable\nchmod +x devtb\n```\n\nRelease assets named `development-translation-bridge-*.zip` are packaged for\nWordPress theme installation. They are built reproducibly by\n[`scripts/build-release-package.sh`](scripts/build-release-package.sh), and\npushing a `v*` tag publishes the release automatically (zip + generated\nchangelog) via the release workflow. Clone the repository when you need the\nstandalone CLI, Python package, tests, or development tooling.\n\nTo run the full local release gate before opening or updating a PR:\n\n```bash\nmake verify\n```\n\n### Translate a file\n\n```bash\n# JSON-native transform (recommended for JSON-based frameworks)\n./devtb transform elementor bootstrap input.json -o output.html\n\n# HTML-intermediate translate (works with shortcode-based frameworks)\n./devtb translate divi avada input.html -o output.html\n\n# Transform an entire site export\n./devtb transform-site elementor bootstrap ./export-kit/\n\n# Analyze content without converting\n./devtb analyze elementor input.json\n```\n\n### From Python\n\n```python\nfrom translation_bridge.converters.bootstrap import BootstrapConverter\nfrom translation_bridge.converters.elementor4 import Elementor4Converter\n\n# Parse Elementor JSON, emit Bootstrap HTML\nelementor_data = [...]  # parsed JSON\nhtml = BootstrapConverter().convert(elementor_data)\n\n# Build Atomic Editor JSON from any parsed universal data\natomic_json = Elementor4Converter().convert(elementor_data)\n```\n\n### As a WordPress plugin\n\n```bash\n# Activate by copying or symlinking into wp-content/themes/\nln -s \"$PWD\" /path/to/wp-content/themes/development-translation-bridge\n\n# Then activate \"DevelopmentTranslation Bridge\" in WordPress Admin → Themes.\n```\n\nThe REST API mounts at `/wp-json/devtb/v2/*` after activation (see\n[REST API](#rest-api) below).\n\n---\n\n## CLI\n\nThe `devtb` CLI is a bash wrapper that routes commands to the Python (v4) or\nPHP (v3) engine depending on the command.\n\n```text\nCOMMANDS (v4 Python — JSON-native, lossless):\n  transform \u003csource\u003e \u003ctarget\u003e \u003cfile\u003e      Transform a file (100% metadata preserved)\n  transform-site \u003csource\u003e \u003ctarget\u003e \u003cdir\u003e  Transform every file in a directory\n  analyze \u003cframework\u003e \u003cfile\u003e              Inspect parsed content without converting\n\nCOMMANDS (v3 PHP — HTML intermediate):\n  translate \u003csource\u003e \u003ctarget\u003e \u003cfile\u003e      Translate between frameworks\n  translate-all \u003csource\u003e \u003cfile\u003e           Translate to every supported framework\n  list-frameworks                         List supported frameworks\n  validate \u003cframework\u003e \u003cfile\u003e             Validate file format\n\nOPTIONS:\n  -h, --help                              Show this help message\n  -v, --version                           Show version information\n  -n, --dry-run                           Preview without writing files\n  -d, --debug                             Show debug information\n  -o, --output \u003cfile\u003e                     Specify output file path\n```\n\nRun `./devtb --help` for the current up-to-date command list.\n\n### Common workflows\n\n```bash\n# Migrate Elementor → Bricks\n./devtb transform elementor bricks page.json -o page-bricks.json\n\n# Modernize legacy DIVI 4 → DIVI 5 block markup\n./devtb translate divi divi-5 page.html -o page-divi5.html\n\n# Detect format, then route to the right path\n./devtb analyze elementor mystery.json  # tells you elType, version, etc.\n\n# Generate every framework's version from one input\n./devtb translate-all bootstrap landing.html\n```\n\n---\n\n## Python API\n\nDirect module imports for programmatic use:\n\n```python\nfrom translation_bridge.converters.bootstrap import BootstrapConverter\nfrom translation_bridge.converters.elementor   import ElementorConverter\nfrom translation_bridge.converters.elementor4  import Elementor4Converter\nfrom translation_bridge.converters.divi        import DiviConverter\nfrom translation_bridge.converters.divi5       import Divi5Converter\nfrom translation_bridge.converters.gutenberg   import GutenbergConverter\nfrom translation_bridge.converters.bricks      import BricksConverter\nfrom translation_bridge.converters.oxygen      import OxygenConverter\nfrom translation_bridge.converters.oxygen6    import Oxygen6Converter\nfrom translation_bridge.converters.wpbakery    import WPBakeryConverter\nfrom translation_bridge.converters.beaver      import BeaverConverter\nfrom translation_bridge.converters.avada       import AvadaConverter\nfrom translation_bridge.converters.kadence     import KadenceConverter\nfrom translation_bridge.converters.thrive      import ThriveConverter\n\n# Each converter has the same surface:\nconverter = BricksConverter()\noutput_json = converter.convert(parsed_data)       # serialized\noutput_list = converter.convert_to_dict(parsed_data)  # python objects\nframework_name = converter.get_framework()          # \"bricks\"\n```\n\nSite-level conversions:\n\n```python\nfrom translation_bridge.parsers.elementor_site import ElementorSiteParser\nfrom translation_bridge.converters.styles      import StylesConverter\nfrom translation_bridge.converters.templates   import TemplateConverter\n\nsite = ElementorSiteParser().parse_kit(\"./export-kit/\")\ntokens = StylesConverter().extract_tokens(site.settings)\ntemplate_parts = TemplateConverter().build(site.templates)\n```\n\n---\n\n## REST API\n\nAfter activating the WordPress theme/plugin, endpoints mount at\n`/wp-json/devtb/v2/*`.\n\n### Endpoints\n\n| Method | Path | Purpose |\n|---|---|---|\n| GET | `/status` | Health check + version info |\n| GET | `/frameworks` | List supported frameworks |\n| POST | `/translate` | Translate a single payload |\n| POST | `/batch-translate` | Queue a batch translation job |\n| GET | `/job/{job_id}` | Poll a batch job's status |\n| POST | `/validate` | Validate a payload for a framework |\n| POST | `/save` | Persist a translation result |\n| GET, PUT, DELETE | `/translations/{id}` | CRUD on saved translations |\n| GET | `/translations/history` | List recent translations |\n| GET | `/translations/{id}/versions` | Version history for a translation |\n| GET, POST | `/api-keys` | List or create API keys |\n| DELETE | `/api-keys/{key}` | Revoke an API key |\n\n### Authentication\n\nAPI keys are encrypted at rest (AES-256-CBC) and required for every endpoint\nexcept `/status` and `/frameworks`. Pass via header:\n\n```http\nAuthorization: Bearer \u003capi-key\u003e\n```\n\nGenerate keys via the WordPress admin UI or `POST /wp-json/devtb/v2/api-keys`.\n\n### Quick examples\n\n```bash\n# Health check\ncurl https://example.com/wp-json/devtb/v2/status\n\n# List frameworks\ncurl https://example.com/wp-json/devtb/v2/frameworks\n\n# Translate\ncurl -X POST https://example.com/wp-json/devtb/v2/translate \\\n  -H \"Authorization: Bearer $DEVTB_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"source\":\"elementor\",\"target\":\"bootstrap\",\"content\":\"...\"}'\n```\n\nFull endpoint reference: [`docs/api-v2.md`](docs/api-v2.md).\n\n---\n\n## Architecture\n\nEvery framework plugs into the same hub-and-spoke pipeline: parse into a\nuniversal component tree, map, then convert out. Adding one framework adds\n13 × 2 new translation pairs — no per-pair code.\n\n```mermaid\nflowchart LR\n    A[\"Source content\u003cbr/\u003e(Elementor JSON,\u003cbr/\u003eDIVI shortcodes, ...)\"] --\u003e B[\"Parser\u003cbr/\u003e(one per framework)\"]\n    B --\u003e C[\"Universal\u003cbr/\u003eComponent[]\u003cbr/\u003e(typed tree)\"]\n    C --\u003e D[\"Mapping engine\u003cbr/\u003e(styles, tokens,\u003cbr/\u003eelement maps)\"]\n    D --\u003e E[\"Converter\u003cbr/\u003e(one per framework)\"]\n    E --\u003e F[\"Target content\u003cbr/\u003e(any of 14\u003cbr/\u003eframeworks)\"]\n```\n\nEach framework provides a paired **parser** (input → universal components)\nand **converter** (universal components → output). Parsers and converters\nregister independently with `DEVTB_Parser_Factory` and\n`DEVTB_Converter_Factory`, so a framework can be a source, a target, or both.\n\n### Project layout\n\n```\ntranslation-bridge/\n├── core/\n│   ├── interface-parser.php\n│   ├── interface-converter.php\n│   ├── class-parser-factory.php\n│   ├── class-converter-factory.php\n│   ├── class-mapping-engine.php\n│   └── class-translator.php\n├── parsers/        # one per framework (PHP)\n├── converters/     # one per framework (PHP)\n├── models/         # DEVTB_Component\n└── utils/          # CSS, JSON, HTML, shortcode helpers\n\nsrc/translation_bridge/\n├── parsers/        # Python parsers\n├── converters/     # Python converters\n├── transforms/     # Zone Theory engine (v4)\n└── cli.py          # Python CLI entry point\n\nincludes/\n├── class-devtb-api-v2.php        # REST API\n├── class-devtb-auth.php          # API key + permission checks\n├── class-devtb-encryption.php    # AES-256-CBC for keys at rest\n├── class-devtb-rate-limiter.php\n├── class-devtb-job-queue.php     # async batch translations\n└── class-devtb-webhook.php\n```\n\nDetailed architecture notes live in [`docs/TRANSLATION_BRIDGE.md`](docs/TRANSLATION_BRIDGE.md).\n\n---\n\n## Testing\n\nPHP (via PHPUnit):\n\n```bash\nmake test-php                  # full suite\nvendor/bin/phpunit --filter FrameworkConversionsTest  # 182-pair matrix\n```\n\nPython (via pytest):\n\n```bash\npython3 -m pytest tests/python -q\n```\n\nFull local release gate:\n\n```bash\nmake verify\n```\n\nAs of v4.13.0:\n- PHP: **339 tests / 5,673 assertions / 0 errors / 0 failures / 0 deprecations**,\n  including 18 widget-coverage tests (`tests/Unit/GutenbergWidgetCoverageTest.php`),\n  9 real-format schema-verification tests (`tests/Unit/ProxySchemaVerificationTest.php`),\n  8 responsive round-trip tests (`tests/Unit/ResponsiveRoundTripTest.php`),\n  and 9 classic-Oxygen hardening tests (`tests/Unit/OxygenClassicHardeningTest.php`).\n- Python: 237 tests across converters, parsers (all 14 frameworks parse natively), transforms, responsive helpers, the shared component interchange, dual-engine conformance (including the exact-mirror gate), and project alignment checks.\n- End-to-end fidelity smoke gates (`make e2e-smoke`), each running through\n  both engines as CI gates on every push and PR: Elementor → Gutenberg\n  (`tests/smoke_gutenberg_e2e.py`), Elementor → Bricks\n  (`tests/smoke_bricks_e2e.py`, flat-format + content survival), and\n  DIVI → Gutenberg (`tests/smoke_divi_e2e.py`, content survival + block\n  integrity).\n\nThe 41 pre-existing errors and 3 failures that v4.1 / v4.2 / v4.3.0 inherited\n(class-autoload mismatches and missing WP-function mocks) were all resolved in\nv4.3.1 via the shared autoloader + WP function stubs. The full suite is now\ngreen, including `composer audit`.\n\n### Continuous integration\n\nEvery push and PR to `main` / `develop` runs four jobs\n([`.github/workflows/ci.yml`](.github/workflows/ci.yml)):\n\n| Job | What it runs |\n|---|---|\n| **PHP tests** | PHPUnit across PHP **8.1 – 8.5**, plus composer validate, syntax check, `composer audit`, PHPCS (WordPress standards), and Codecov coverage upload |\n| **Python tests + Gutenberg e2e smoke** | Full pytest suite, then three e2e fidelity gates through both engines: Elementor → Gutenberg, Elementor → Bricks, and DIVI → Gutenberg kitchen-sink fixtures |\n| **Admin build** | ESLint, `tsc --noEmit`, and a production Vite build on Node **20.19.0 / 22.13.0 / 24** |\n| **Release package smoke** | Builds and inspects the WordPress theme zip via `scripts/build-release-package.sh`, so packaging breakage is caught before tagging |\n\nDependency freshness is automated with\n[Dependabot](.github/dependabot.yml): weekly update PRs for Composer, npm\n(`admin/`), and pip, and monthly for GitHub Actions and Docker Compose images.\n`composer audit` gates every CI run, and `make verify` additionally runs\n`npm audit --omit=dev` on the admin UI.\n\n---\n\n## Docker (development)\n\nA local stack is available for plugin development:\n\n```bash\ndocker-compose up -d\n\n# WordPress:    http://localhost:8080\n# phpMyAdmin:   http://localhost:8081\n```\n\nThe stack pins WordPress 7.0 (PHP 8.4 + Apache), MySQL 9.7, and phpMyAdmin\n5.2 — image versions are kept fresh by Dependabot's monthly\n`docker-compose` updates. Ports and database credentials are overridable via\nenvironment variables (`WORDPRESS_PORT`, `MYSQL_PORT`, `MYSQL_USER`, ...);\nsee [`docker-compose.yml`](docker-compose.yml) for the full list and\n[`DOCKER_SETUP.md`](DOCKER_SETUP.md) for a walkthrough.\n\nThe plugin is mounted from the working tree, so edits are reflected\nimmediately.\n\n---\n\n## Documentation\n\nTopical guides under [`docs/`](docs):\n\n| File | Topic |\n|---|---|\n| [`getting-started.md`](docs/getting-started.md) | First-run setup walkthrough |\n| [`api-v2.md`](docs/api-v2.md) | Full REST API reference |\n| [`api-development.md`](docs/api-development.md) | Building against the API |\n| [`TRANSLATION_BRIDGE.md`](docs/TRANSLATION_BRIDGE.md) | Architecture deep-dive |\n| [`FRAMEWORK_MAPPINGS.md`](docs/FRAMEWORK_MAPPINGS.md) | Per-framework element maps |\n| [`CONVERSION_EXAMPLES.md`](docs/CONVERSION_EXAMPLES.md) | Real translation examples |\n| [`bootstrap-components.md`](docs/bootstrap-components.md) | Bootstrap output reference |\n| [`claude-integration.md`](docs/claude-integration.md) | AI-assisted editing workflows |\n| [`PLUGIN_CONVERSION.md`](docs/PLUGIN_CONVERSION.md) | Plugin migration cookbook |\n\nA consolidated version history lives in [`CHANGELOG.md`](CHANGELOG.md);\ndetailed notes for major releases live at [`RELEASE_NOTES_V*.md`](.) and in\n[GitHub Releases](https://github.com/coryhubbell/Development-Translation-Bridge/releases).\n\n---\n\n## Version history\n\n| Version | Date | Highlights |\n|---|---|---|\n| [v4.13.0](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.13.0) **(latest)** | 2026-07-03 | RFC 5.0 Phase 2 complete: shared component interchange in Python, exact-mirror conformance gate, round-trip vocabulary completed in both engines |\n| [v4.12.0](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.12.0) | 2026-07-03 | RFC 5.0 Phases 1–2: canonical schema, dual-engine conformance in CI, universal interchange in the PHP engine + REST |\n| [v4.11.0](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.11.0) | 2026-07-03 | Python parsers final tranche: all 14 frameworks parse natively — the 4.7+ roadmap is complete |\n| [v4.10.0](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.10.0) | 2026-07-03 | Python parsers tranche 2: Oxygen 6, DIVI 5, and Gutenberg sources — all JSON/block-markup formats parse natively in Python |\n| [v4.9.0](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.9.0) | 2026-07-03 | Responsive canonicalization completed: Elementor v3 suffixes + Bricks breakpoint keys join the canonical model; cross-framework transfer in every direction |\n| [v4.8.0](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.8.0) | 2026-07-03 | E2e fidelity smoke gates for Elementor → Bricks and DIVI → Gutenberg; seven content drops caught and fixed |\n| [v4.7.0](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.7.0) | 2026-07-03 | JSON source parsers: Bricks, classic Oxygen, and Elementor 4 Atomic now ride the lossless `transform` path as sources |\n| [v4.6.0](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.6.0) | 2026-07-03 | Classic Oxygen hardening: all real storage shapes parse, real `ct_*`/`oxy_*` vocabulary, unified root-tree output, full style passthrough, responsive `media` round-tripping |\n| [v4.5.0](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.5.0) | 2026-07-03 | Responsive breakpoint round-tripping: canonical desktop/tablet/phone + hover model for `divi-5` / `elementor-4` / `oxygen-6`, with cross-framework transfer |\n| [v4.4.0](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.4.0) | 2026-07-02 | `divi-5` / `elementor-4` / `oxygen-6` schemas verified against real formats (elementor repo, Divi 5 docs, real Breakdance export); Dependabot, reproducible packaging, four-job CI, `make verify` |\n| [v4.3.4](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.3.4) | 2026-05-20 | Elementor → Gutenberg widget coverage hotfix (compound widgets, marker fallback, settings denormalization); e2e smoke harness now a CI gate |\n| [v4.3.3](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.3.3) | 2026-05-19 | `functions.php` admin pages now factory-driven; eliminates drift surface for framework lists |\n| [v4.3.2](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.3.2) | 2026-05-19 | User-facing copy errata (style.css, admin help, CLI help); 9 → 14 / 72 → 182 |\n| [v4.3.1](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.3.1) | 2026-05-19 | Production-readiness: CLI fatal fix, matrix consistency, test suite green, PHP 8.1 floor, CVE-2026-24765 cleared |\n| [v4.3.0](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.3.0) | 2026-05-19 | DIVI 5, Elementor 4 Atomic, Oxygen 6 native parsers; Bricks flat-output fix |\n| [v4.2.0](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.2.0) | 2026-05-18 | Kadence + Thrive converters; CMS version re-association; correctness audit |\n| [v4.1.0](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.1.0) | 2026-01-17 | 8 Python converters; site-level parser; styles \u0026 template extraction |\n| [v4.0.0](https://github.com/coryhubbell/Development-Translation-Bridge/releases/tag/v4.0.0) | 2025-Q4 | JSON-native transform engine; Zone Theory; 100% metadata preservation |\n\n---\n\n## Roadmap\n\nThe 4.x line is feature-complete on framework coverage and production-ready\nas of v4.13.0. Release verification is automated end to end — Dependabot\nkeeps dependencies fresh, `make verify` mirrors the release gate locally, and\nthe four-job CI pipeline (including release-package smoke) runs on every push\nand PR. The v4.3.0 proxy schemas were verified against real formats in v4.4.0\n(see [Schema verification status](#schema-verification-status)), and v4.5.0\nadded responsive breakpoint round-tripping: tablet/phone breakpoints and\nhover states survive round trips for all three paths and transfer across\nframeworks through a canonical responsive model.\n\nOn Oxygen: classic Oxygen (4.x) support is fully hardened — real `ct_*`/`oxy_*`\nvocabulary, every storage shape (JSON tree, wrapper, flat list, shortcodes),\nfull style passthrough with unit normalization, and responsive `media`\nround-tripping. The `oxygen-6` path intentionally tracks the verified\nBreakdance-derived schema (~80% shared codebase) rather than chasing\nOxygen 6-specific deltas.\n\n### Next (4.7+)\n\nCandidate work for upcoming 4.x releases, roughly in priority order:\n\n1. ~~**More JSON source parsers for the lossless `transform` path.**~~\n   **Done in v4.7.0:** Bricks, classic Oxygen, and Elementor 4 Atomic now\n   parse into the universal shape and ride the 100%-metadata Python engine as\n   sources (`devtb transform bricks|oxygen|elementor4 \u003ctarget\u003e file.json`).\n2. ~~**E2e fidelity smoke gates for more targets.**~~ **Done in v4.8.0:**\n   Elementor → Bricks and DIVI → Gutenberg kitchen-sink gates now run through\n   both engines on every push/PR alongside the original Elementor → Gutenberg\n   gate — and caught seven real content drops on their first run.\n3. ~~**Responsive canonicalization for the remaining frameworks.**~~\n   **Done in v4.9.0:** Elementor v3's `_tablet`/`_mobile`/`_hover` setting\n   suffixes and Bricks' `:breakpoint` setting keys now canonicalize on parse\n   and re-emit on convert, so responsive data survives round trips and\n   transfers across frameworks (e.g. Elementor tablet overrides become\n   Bricks `:tablet_portrait` keys).\n4. ~~**Python parsers for the remaining frameworks.**~~ **Done in v4.11.0:**\n   all 14 frameworks now parse natively in Python — JSON, block markup,\n   shortcodes, and HTML — completing the parser half of the 5.x engine\n   consolidation.\n\n### 5.x — engine consolidation (Phase 1 underway)\n\nThe 5.x line consolidates both engines onto a single shared schema and\nretires the lossy HTML-intermediate path. The plan lives in\n[`docs/RFC-5.0-engine-consolidation.md`](docs/RFC-5.0-engine-consolidation.md);\nthe canonical interchange shape is normatively specified in\n[`schema/universal-element.schema.json`](schema/universal-element.schema.json).\n\n- **Phase 1 (shipped, unreleased):** the schema spec,\n  `DEVTB_Component::to_universal()` on the PHP side, and a dual-engine\n  conformance suite — shared real fixtures parsed by BOTH engines must\n  produce schema-valid, content-equivalent universal documents.\n- **Phase 2 (core shipped, unreleased):** `DEVTB_Universal` bridges both\n  directions; the translator gains `parse_to_universal()` /\n  `translate_universal()`; the REST `/translate` endpoint accepts\n  `universal` as source or target; cross-engine interchange is\n  conformance-tested both ways (a Python-parsed document converts in PHP\n  and vice versa).\n- **Phase 3:** every `translate` pair re-routes through the lossless path.\n- **Phase 4:** 5.0 — one schema, two conforming runtimes.\n\n---\n\n## Contributing\n\nContributions welcome. Useful starting points:\n\n- **Add a new framework:** create a parser/converter pair in\n  `translation-bridge/{parsers,converters}/`, register in both factories, add\n  the framework key to `FrameworkConversionsTest::$frameworks` with a sample\n  input, and follow the existing structural-assertion pattern. The\n  [Bricks flat-format work in v4.3](https://github.com/coryhubbell/Development-Translation-Bridge/commit/a9e0a06)\n  is a good reference.\n- **Share real exports:** real page exports from any supported builder make\n  great regression fixtures — open an issue with the JSON dump if you have\n  one that behaves unexpectedly.\n- **Fix a converter bug:** see the audit-finding pattern in\n  [RELEASE_NOTES_V4.2.0.md](RELEASE_NOTES_V4.2.0.md) — these were caught by\n  running real CMS exports through the round-trip and diffing.\n\nPRs should keep the framework matrix green (`vendor/bin/phpunit --filter\nFrameworkConversionsTest` and `pytest tests/python`).\n\n---\n\n## License\n\nGPL-2.0-or-later. See [LICENSE](LICENSE).\n\n---\n\n## Links\n\n- **Latest release:** https://github.com/coryhubbell/Development-Translation-Bridge/releases/latest\n- **All releases:** https://github.com/coryhubbell/Development-Translation-Bridge/releases\n- **Issues:** https://github.com/coryhubbell/Development-Translation-Bridge/issues\n- **Source:** https://github.com/coryhubbell/Development-Translation-Bridge\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoryhubbell%2Fdevelopment-translation-bridge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcoryhubbell%2Fdevelopment-translation-bridge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoryhubbell%2Fdevelopment-translation-bridge/lists"}