The agent-swarm diagram and its README section, redrawn to how changes land today

delegation-model.svg, re-rendered to delegation-model.png at 2x (only IHDR, IDAT, IEND):
- development, not main, is at the centre, behind a landing lock that takes one landing at a
  time; the plugin ring and the three outputs are kept (the desktop output working).
- A coordinator and a gate-keeper replace the single overseer; the legend gains them.
- "How a change lands" has four steps: own branch; a second reader; one at a time (in the
  lock: merge development, rebuild, run every check, push only if nothing fails); promote
  to main (only when the owner approves, after full checks on that version).
- The outputs band adds: the dev preview follows development, the published site follows
  main.
README, the same section, so the text matches the picture: the summary table row, the
section's intro, the image's alt text, the kitchen list (now five points) and the glossary
("landing lock" replaces "merge queue"). No tool or personal names.
This commit is contained in:
Doxa Maps 2026-09-30 22:39:35 +00:00
parent 703f3efbc6
commit 6deb2569be
3 changed files with 103 additions and 84 deletions

View file

@ -64,7 +64,7 @@ capabilities, three outputs, one shared library, one build.
| **One app nests every map** — and each stays embeddable on its own | [capability 5](#capability-5--app-shell-the-research-gallery) · `bun run check:composite-reg` |
| **5 capabilities, every one shippable in every output** | `bun run verify:5-caps` |
| **Shared library, private plugins** — reuse without breaking each other | `bun run check:library-index` |
| **One agent per plugin, one shepherd, one working `development`** | [agent swarm](#build-it-with-an-agent-swarm) |
| **One owner per plugin, a second reader for every change, one landing at a time** | [agent swarm](#build-it-with-an-agent-swarm) |
## For vibe coders: build, open the Studio, embed a map
@ -689,11 +689,12 @@ your own page, set `"locale"` in its `profile-config`. Arabic reads right to lef
## Build it with an agent swarm
**Many AI agents can build many plugins at once without breaking each other's work.** Every plugin
has one agent building it, and one shepherd agent makes sure every agent does its job well. All the
plugins live in one project with one shared library, and changes are added to `development`, the shared
working version, one at a time. `main` is the production version, and it moves only when a release is published.
has one agent that owns it, a second agent reads every change before it lands, a coordinator puts the
landings in order, and a gate-keeper checks each one. All the plugins live in one project with one shared
library, and changes are added to `development`, the shared working version, one at a time. `main` is the
production version: it moves only by a promotion the owner approves, after a full check run on that exact version.
![The delegation model: main at the centre guarded by a merge queue, inside the Plugin Studio; eight plugins around it; one agent per plugin; and one shepherd over all the agents](documentation/readme-images/delegation-model.png)
![The delegation model: development at the centre behind a landing lock, inside the Plugin Studio; eight plugins around it, each owned by one agent; a coordinator and a gate-keeper over the agents; below, how a change lands in four steps, and the three outputs](documentation/readme-images/delegation-model.png)
<details>
<summary><b>What problem does this solve? (in plain words)</b></summary>
@ -704,15 +705,17 @@ map breaks at once**. And when several agents work in the same project at the sa
each other — two agents edit the same file, one change quietly erases another, or half-finished work
lands in the version everyone else is using.
So the project works like a busy kitchen with one head chef:
So the project works like a busy kitchen:
1. **Each agent works in its own copy of the project** — its own counter, so nobody bumps anybody.
2. **Before adding its work, each agent catches up**: it pulls in everyone else's latest work and
fixes any clashes with its own. The agent fixes the clash, not the next person.
3. **Only one agent adds work at a time.** They wait in a line (the *merge queue*), the checks run,
and only then does the change go into `development`. `development` always works.
4. **A shepherd agent watches everyone**: plugins built in the studio, shared parts really shared,
and every change going through the line.
1. **Each agent works in its own branch and copy of the project** — its own counter, so nobody bumps
anybody. One owner per plugin, and one per shared file.
2. **A second agent reads every change** by its content before it may land.
3. **Only one change lands at a time.** Whoever holds the *landing lock* merges in everyone else's
latest work and fixes any clash itself, rebuilds the maps from the merged source and runs every
check; the change goes into `development` only if nothing fails. `development` always works.
4. **A coordinator puts the landings in order, and a gate-keeper checks each one** by its content.
5. **`main` moves only by a promotion** the owner approves, after a full check run on that exact
version. The dev preview follows `development`; the published site follows `main`.
That's how many plugins get built at the same time, in one project, without the maps breaking.
@ -729,7 +732,7 @@ That's how many plugins get built at the same time, in one project, without the
| **worktree** | a private copy of the project for one agent to work in |
| **merge conflict** | two changes touched the same lines; someone has to decide how to combine them |
| **rebase** | catching your work up with everyone else's latest before adding it |
| **merge queue** | the line agents wait in, so only one change goes into `main` at a time |
| **landing lock** | only one change lands on `development` at a time; its holder merges, rebuilds and runs every check first |
</details>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 812 KiB

After

Width:  |  Height:  |  Size: 858 KiB

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1500" height="2030" viewBox="0 0 1500 2030" font-family="Inter, 'Helvetica Neue', Arial, sans-serif">
<svg xmlns="http://www.w3.org/2000/svg" width="1500" height="2086" viewBox="0 0 1500 2086" font-family="Inter, 'Helvetica Neue', Arial, sans-serif">
<defs>
<marker id="aA" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="8" markerHeight="8" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="#2563eb"/></marker>
<marker id="aS" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="#7c3aed"/></marker>
@ -9,8 +9,8 @@
<path id="agL" d="M 194,850 A 556,556 0 0 1 1306,850"/>
<path id="mqL" d="M 679,884 A 71,71 0 0 0 821,884"/>
</defs>
<rect width="1500" height="2030" fill="#ffffff"/>
<text x="750" y="54" text-anchor="middle" font-size="34" font-weight="800" fill="#0f172a">How dx-maps is built: one studio, one agent per plugin, one shepherd</text>
<rect width="1500" height="2086" fill="#ffffff"/>
<text x="750" y="54" text-anchor="middle" font-size="34" font-weight="800" fill="#0f172a">How dx-maps is built: one owner per plugin, one landing at a time</text>
<circle cx="750" cy="850" r="540" fill="none" stroke="#2563eb" stroke-width="1.6" stroke-dasharray="3 7" opacity=".75"/>
<circle cx="750" cy="850" r="355" fill="none" stroke="#15803d" stroke-width="2.2" opacity=".85"/>
<circle cx="750" cy="850" r="606" fill="none" stroke="#7c3aed" stroke-width="2" stroke-dasharray="8 7" opacity=".6"/>
@ -29,8 +29,8 @@
<circle cx="750" cy="850" r="120" fill="#fef2f2" stroke="#dc2626" stroke-width="3" stroke-dasharray="10 6"/>
<path id="mqT" d="M 646,850 A 104,104 0 0 1 854,850" fill="none"/>
<path id="mqB" d="M 644,850 A 106,106 0 0 0 856,850" fill="none"/>
<text font-size="13" font-weight="800" fill="#b91c1c" letter-spacing="1.6"><textPath href="#mqT" startOffset="50%" text-anchor="middle">MERGE QUEUE · GUARD</textPath></text>
<text font-size="12" font-weight="700" fill="#b91c1c" letter-spacing="1.2"><textPath href="#mqB" startOffset="50%" text-anchor="middle">ONE AGENT AT A TIME</textPath></text>
<text font-size="13" font-weight="800" fill="#b91c1c" letter-spacing="1.6"><textPath href="#mqT" startOffset="50%" text-anchor="middle">LANDING LOCK</textPath></text>
<text font-size="12" font-weight="700" fill="#b91c1c" letter-spacing="1.2"><textPath href="#mqB" startOffset="50%" text-anchor="middle">ONE LANDING AT A TIME</textPath></text>
<rect x="617" y="846" width="26" height="20" rx="4" fill="#dc2626"/>
<path d="M 622,846 v -6 a 8,8 0 0 1 16,0 v 6" fill="none" stroke="#dc2626" stroke-width="3.5"/>
<circle cx="630" cy="856" r="3" fill="#fff"/>
@ -38,9 +38,9 @@
<path d="M 862,846 v -6 a 8,8 0 0 1 16,0 v 6" fill="none" stroke="#dc2626" stroke-width="3.5"/>
<circle cx="870" cy="856" r="3" fill="#fff"/>
<circle cx="750" cy="850" r="72" fill="#166534" stroke="#14532d" stroke-width="3"/>
<text x="750" y="852" text-anchor="middle" font-size="34" font-weight="800" fill="#fff">main</text>
<text x="750" y="876" text-anchor="middle" font-size="12.5" fill="#dcfce7">the one branch</text>
<text x="750" y="892" text-anchor="middle" font-size="12.5" fill="#dcfce7">always green</text>
<text x="750" y="850" text-anchor="middle" font-size="18" font-weight="800" fill="#fff">development</text>
<text x="750" y="872" text-anchor="middle" font-size="12.5" fill="#dcfce7">every change</text>
<text x="750" y="888" text-anchor="middle" font-size="12.5" fill="#dcfce7">lands here</text>
<text font-size="16" font-weight="800" fill="#15803d" letter-spacing="3"><textPath href="#plL" startOffset="50%" text-anchor="middle">PLUGINS</textPath></text>
<text font-size="16" font-weight="800" fill="#2563eb" letter-spacing="3"><textPath href="#agL" startOffset="18%" text-anchor="middle">AGENTS</textPath></text>
<line x1="862.1" y1="579.3" x2="822.7" y2="674.5" stroke="#15803d" stroke-width="1.4" opacity=".45"/>
@ -117,67 +117,83 @@
<circle cx="543.4" cy="351.1" r="40" fill="#ecfeff" stroke="#0891b2" stroke-width="2.5"/>
<text x="543.4" y="349.1" text-anchor="middle" font-size="12" font-weight="700" fill="#155e75">roaming</text>
<text x="543.4" y="364.1" text-anchor="middle" font-size="12" font-weight="700" fill="#155e75">agent</text>
<circle cx="750" cy="244" r="60" fill="#f5f3ff" stroke="#7c3aed" stroke-width="3.5"/>
<text x="750" y="251" text-anchor="middle" font-size="19" font-weight="800" fill="#4c1d95">shepherd</text>
<text x="834" y="192" font-size="17" fill="#4c1d95">one shepherd makes sure all plugin agents</text>
<text x="834" y="216" font-size="17" fill="#4c1d95">are doing their job building the plugins well</text>
<text x="750" y="1502" text-anchor="middle" font-size="20" font-weight="800" fill="#1e3a8a">each plugin has one agent responsible for building it</text>
<rect x="36" y="110" width="300" height="280" rx="14" fill="#f8fafc" stroke="#e2e8f0" stroke-width="2"/>
<circle cx="64" cy="144" r="12" fill="#166534" stroke="#14532d" stroke-width="2.5"/>
<text x="88" y="149" font-size="15" fill="#334155">main — the one branch</text>
<circle cx="64" cy="180" r="12" fill="#fef2f2" stroke="#dc2626" stroke-width="2.5"/>
<text x="88" y="185" font-size="15" fill="#334155">merge queue — one at a time</text>
<circle cx="64" cy="216" r="12" fill="#fffbeb" stroke="#d97706" stroke-width="2.5"/>
<text x="88" y="221" font-size="15" fill="#334155">Plugin Studio — the one repo</text>
<circle cx="64" cy="252" r="12" fill="#f0fdf4" stroke="#15803d" stroke-width="2.5"/>
<text x="88" y="257" font-size="15" fill="#334155">plugin (badge = capability)</text>
<circle cx="64" cy="288" r="12" fill="#ecfeff" stroke="#0891b2" stroke-width="2.5"/>
<text x="88" y="293" font-size="15" fill="#334155">Experimental shelf</text>
<circle cx="64" cy="324" r="12" fill="#eff6ff" stroke="#2563eb" stroke-width="2.5"/>
<text x="88" y="329" font-size="15" fill="#334155">agent — builds one plugin</text>
<circle cx="64" cy="360" r="12" fill="#f5f3ff" stroke="#7c3aed" stroke-width="2.5"/>
<text x="88" y="365" font-size="15" fill="#334155">shepherd — oversees all</text>
<rect x="60" y="1536" width="1380" height="218" rx="20" fill="#fef2f2" stroke="#fca5a5" stroke-width="2"/>
<text x="750" y="1578" text-anchor="middle" font-size="22" font-weight="800" fill="#7f1d1d">How main is protected — so many plugins can be built at once</text>
<rect x="80.0" y="1602" width="410" height="130" rx="14" fill="#fff" stroke="#dc2626" stroke-width="2"/>
<circle cx="116.0" cy="1638" r="20" fill="#dc2626"/>
<text x="116.0" y="1645" text-anchor="middle" font-size="20" font-weight="800" fill="#fff">1</text>
<text x="148.0" y="1645" font-size="20" font-weight="800" fill="#0f172a">Work in your own copy</text>
<text x="102.0" y="1686" font-size="16" fill="#475569">each agent builds its own plugin,</text>
<text x="102.0" y="1710" font-size="16" fill="#475569">in its own private copy of the project</text>
<text x="517.5" y="1677" text-anchor="middle" font-size="30" font-weight="800" fill="#dc2626">→</text>
<rect x="545.0" y="1602" width="410" height="130" rx="14" fill="#fff" stroke="#dc2626" stroke-width="2"/>
<circle cx="581.0" cy="1638" r="20" fill="#dc2626"/>
<text x="581.0" y="1645" text-anchor="middle" font-size="20" font-weight="800" fill="#fff">2</text>
<text x="613.0" y="1645" font-size="20" font-weight="800" fill="#0f172a">Catch up, fix the clashes</text>
<text x="567.0" y="1686" font-size="16" fill="#475569">pull in everyone else's latest work and</text>
<text x="567.0" y="1710" font-size="16" fill="#475569">fix any clashes before adding yours</text>
<text x="982.5" y="1677" text-anchor="middle" font-size="30" font-weight="800" fill="#dc2626">→</text>
<rect x="1010.0" y="1602" width="410" height="130" rx="14" fill="#fff" stroke="#dc2626" stroke-width="2"/>
<circle cx="1046.0" cy="1638" r="20" fill="#dc2626"/>
<text x="1046.0" y="1645" text-anchor="middle" font-size="20" font-weight="800" fill="#fff">3</text>
<text x="1078.0" y="1645" font-size="20" font-weight="800" fill="#0f172a">Add changes one at a time</text>
<text x="1032.0" y="1686" font-size="16" fill="#475569">the queue lets ONE agent in at a time;</text>
<text x="1032.0" y="1710" font-size="16" fill="#475569">the checks must pass, main stays working</text>
<circle cx="690" cy="248" r="56" fill="#f5f3ff" stroke="#7c3aed" stroke-width="3.5"/>
<text x="690" y="254" text-anchor="middle" font-size="14" font-weight="800" fill="#4c1d95">coordinator</text>
<circle cx="812" cy="248" r="56" fill="#f1f5f9" stroke="#334155" stroke-width="3.5"/>
<text x="812" y="254" text-anchor="middle" font-size="14" font-weight="800" fill="#1e293b">gate-keeper</text>
<text x="884" y="192" font-size="17" fill="#4c1d95">a coordinator puts the landings in order;</text>
<text x="884" y="216" font-size="17" fill="#1e293b">a gate-keeper checks each one by its content</text>
<text x="750" y="1502" text-anchor="middle" font-size="20" font-weight="800" fill="#1e3a8a">one owner per plugin, in its own branch · a second reader for every change</text>
<rect x="36" y="110" width="304" height="280" rx="14" fill="#f8fafc" stroke="#e2e8f0" stroke-width="2"/>
<circle cx="64" cy="142" r="11" fill="#166534" stroke="#14532d" stroke-width="2.5"/>
<text x="88" y="147" font-size="15" fill="#334155">development — shared branch</text>
<circle cx="64" cy="174" r="11" fill="#fef2f2" stroke="#dc2626" stroke-width="2.5"/>
<text x="88" y="179" font-size="15" fill="#334155">landing lock — one at a time</text>
<circle cx="64" cy="206" r="11" fill="#fffbeb" stroke="#d97706" stroke-width="2.5"/>
<text x="88" y="211" font-size="15" fill="#334155">Plugin Studio — the one repo</text>
<circle cx="64" cy="238" r="11" fill="#f0fdf4" stroke="#15803d" stroke-width="2.5"/>
<text x="88" y="243" font-size="15" fill="#334155">plugin (badge = capability)</text>
<circle cx="64" cy="270" r="11" fill="#ecfeff" stroke="#0891b2" stroke-width="2.5"/>
<text x="88" y="275" font-size="15" fill="#334155">Experimental shelf</text>
<circle cx="64" cy="302" r="11" fill="#eff6ff" stroke="#2563eb" stroke-width="2.5"/>
<text x="88" y="307" font-size="15" fill="#334155">agent — owns one plugin</text>
<circle cx="64" cy="334" r="11" fill="#f5f3ff" stroke="#7c3aed" stroke-width="2.5"/>
<text x="88" y="339" font-size="15" fill="#334155">coordinator — orders landings</text>
<circle cx="64" cy="366" r="11" fill="#f1f5f9" stroke="#334155" stroke-width="2.5"/>
<text x="88" y="371" font-size="15" fill="#334155">gate-keeper — checks landings</text>
<rect x="60" y="1536" width="1380" height="232" rx="20" fill="#fef2f2" stroke="#fca5a5" stroke-width="2"/>
<text x="750" y="1578" text-anchor="middle" font-size="22" font-weight="800" fill="#7f1d1d">How a change lands — one at a time, so many plugins can be built at once</text>
<rect x="80.0" y="1600" width="305" height="148" rx="14" fill="#fff" stroke="#dc2626" stroke-width="2"/>
<circle cx="114.0" cy="1634" r="18" fill="#dc2626"/>
<text x="114.0" y="1641" text-anchor="middle" font-size="19" font-weight="800" fill="#fff">1</text>
<text x="142.0" y="1641" font-size="19" font-weight="800" fill="#0f172a">Own branch</text>
<text x="100.0" y="1680" font-size="15" fill="#475569">each owner builds its plugin</text>
<text x="100.0" y="1702" font-size="15" fill="#475569">in its own branch and copy;</text>
<text x="100.0" y="1724" font-size="15" fill="#475569">one owner per shared file</text>
<text x="405.0" y="1682" text-anchor="middle" font-size="26" font-weight="800" fill="#dc2626">→</text>
<rect x="425.0" y="1600" width="305" height="148" rx="14" fill="#fff" stroke="#dc2626" stroke-width="2"/>
<circle cx="459.0" cy="1634" r="18" fill="#dc2626"/>
<text x="459.0" y="1641" text-anchor="middle" font-size="19" font-weight="800" fill="#fff">2</text>
<text x="487.0" y="1641" font-size="19" font-weight="800" fill="#0f172a">Second reader</text>
<text x="445.0" y="1680" font-size="15" fill="#475569">another agent reads every</text>
<text x="445.0" y="1702" font-size="15" fill="#475569">change by its content</text>
<text x="445.0" y="1724" font-size="15" fill="#475569">before it may land</text>
<text x="750.0" y="1682" text-anchor="middle" font-size="26" font-weight="800" fill="#dc2626">→</text>
<rect x="770.0" y="1600" width="305" height="148" rx="14" fill="#fff" stroke="#dc2626" stroke-width="2"/>
<circle cx="804.0" cy="1634" r="18" fill="#dc2626"/>
<text x="804.0" y="1641" text-anchor="middle" font-size="19" font-weight="800" fill="#fff">3</text>
<text x="832.0" y="1641" font-size="19" font-weight="800" fill="#0f172a">One at a time</text>
<text x="790.0" y="1680" font-size="15" fill="#475569">in the lock: merge development,</text>
<text x="790.0" y="1702" font-size="15" fill="#475569">rebuild, run every check;</text>
<text x="790.0" y="1724" font-size="15" fill="#475569">push only if nothing fails</text>
<text x="1095.0" y="1682" text-anchor="middle" font-size="26" font-weight="800" fill="#dc2626">→</text>
<rect x="1115.0" y="1600" width="305" height="148" rx="14" fill="#fff" stroke="#dc2626" stroke-width="2"/>
<circle cx="1149.0" cy="1634" r="18" fill="#dc2626"/>
<text x="1149.0" y="1641" text-anchor="middle" font-size="19" font-weight="800" fill="#fff">4</text>
<text x="1177.0" y="1641" font-size="19" font-weight="800" fill="#0f172a">Promote to main</text>
<text x="1135.0" y="1680" font-size="15" fill="#475569">main is production: it moves</text>
<text x="1135.0" y="1702" font-size="15" fill="#475569">only when the owner approves,</text>
<text x="1135.0" y="1724" font-size="15" fill="#475569">after full checks on that version</text>
<line x1="750" y1="956" x2="750" y2="1786" stroke="#334155" stroke-width="2.5" stroke-dasharray="2 5" opacity=".0"/>
<rect x="60" y="1780" width="1380" height="230" rx="20" fill="#f8fafc" stroke="#cbd5e1" stroke-width="2"/>
<text x="750" y="1824" text-anchor="middle" font-size="22" font-weight="800" fill="#0f172a">main → ONE build → one web folder → three outputs</text>
<rect x="80.0" y="1852" width="420" height="130" rx="14" fill="#fff" stroke="#15803d" stroke-width="2.5"/>
<text x="290.0" y="1874" text-anchor="middle" font-size="13" font-weight="800" fill="#64748b">OUTPUT 1</text>
<text x="290.0" y="1906" text-anchor="middle" font-size="22" font-weight="800" fill="#0f172a">The web folder</text>
<text x="290.0" y="1932" text-anchor="middle" font-size="15" fill="#475569">iframe · JS embed · WordPress (for fun)</text>
<rect x="190.0" y="1946" width="200" height="26" rx="13" fill="#15803d" opacity=".13"/>
<text x="290.0" y="1964" text-anchor="middle" font-size="12" font-weight="800" fill="#15803d">PRODUCTION</text>
<rect x="540.0" y="1852" width="420" height="130" rx="14" fill="#fff" stroke="#15803d" stroke-width="2.5"/>
<text x="750.0" y="1874" text-anchor="middle" font-size="13" font-weight="800" fill="#64748b">OUTPUT 2</text>
<text x="750.0" y="1906" text-anchor="middle" font-size="22" font-weight="800" fill="#0f172a">Mobile app</text>
<text x="750.0" y="1932" text-anchor="middle" font-size="15" fill="#475569">the same folder, wrapped by Capacitor</text>
<rect x="650.0" y="1946" width="200" height="26" rx="13" fill="#15803d" opacity=".13"/>
<text x="750.0" y="1964" text-anchor="middle" font-size="12" font-weight="800" fill="#15803d">BUILT</text>
<rect x="1000.0" y="1852" width="420" height="130" rx="14" fill="#fff" stroke="#15803d" stroke-width="2.5"/>
<text x="1210.0" y="1874" text-anchor="middle" font-size="13" font-weight="800" fill="#64748b">OUTPUT 3</text>
<text x="1210.0" y="1906" text-anchor="middle" font-size="22" font-weight="800" fill="#0f172a">Desktop app</text>
<text x="1210.0" y="1932" text-anchor="middle" font-size="15" fill="#475569">the same folder, wrapped by Tauri</text>
<rect x="1110.0" y="1946" width="200" height="26" rx="13" fill="#15803d" opacity=".13"/>
<text x="1210.0" y="1964" text-anchor="middle" font-size="12" font-weight="800" fill="#15803d">WORKING</text>
<rect x="60" y="1812" width="1380" height="254" rx="20" fill="#f8fafc" stroke="#cbd5e1" stroke-width="2"/>
<text x="750" y="1856" text-anchor="middle" font-size="22" font-weight="800" fill="#0f172a">main → ONE build → one web folder → three outputs</text>
<text x="750" y="1882" text-anchor="middle" font-size="16" fill="#475569">the dev preview follows development · the published site follows main</text>
<rect x="80.0" y="1908" width="420" height="130" rx="14" fill="#fff" stroke="#15803d" stroke-width="2.5"/>
<text x="290.0" y="1930" text-anchor="middle" font-size="13" font-weight="800" fill="#64748b">OUTPUT 1</text>
<text x="290.0" y="1962" text-anchor="middle" font-size="22" font-weight="800" fill="#0f172a">The web folder</text>
<text x="290.0" y="1988" text-anchor="middle" font-size="15" fill="#475569">iframe · JS embed · WordPress (for fun)</text>
<rect x="190.0" y="2002" width="200" height="26" rx="13" fill="#15803d" opacity=".13"/>
<text x="290.0" y="2020" text-anchor="middle" font-size="12" font-weight="800" fill="#15803d">PRODUCTION</text>
<rect x="540.0" y="1908" width="420" height="130" rx="14" fill="#fff" stroke="#15803d" stroke-width="2.5"/>
<text x="750.0" y="1930" text-anchor="middle" font-size="13" font-weight="800" fill="#64748b">OUTPUT 2</text>
<text x="750.0" y="1962" text-anchor="middle" font-size="22" font-weight="800" fill="#0f172a">Mobile app</text>
<text x="750.0" y="1988" text-anchor="middle" font-size="15" fill="#475569">the same folder, wrapped by Capacitor</text>
<rect x="650.0" y="2002" width="200" height="26" rx="13" fill="#15803d" opacity=".13"/>
<text x="750.0" y="2020" text-anchor="middle" font-size="12" font-weight="800" fill="#15803d">BUILT</text>
<rect x="1000.0" y="1908" width="420" height="130" rx="14" fill="#fff" stroke="#15803d" stroke-width="2.5"/>
<text x="1210.0" y="1930" text-anchor="middle" font-size="13" font-weight="800" fill="#64748b">OUTPUT 3</text>
<text x="1210.0" y="1962" text-anchor="middle" font-size="22" font-weight="800" fill="#0f172a">Desktop app</text>
<text x="1210.0" y="1988" text-anchor="middle" font-size="15" fill="#475569">the same folder, wrapped by Tauri</text>
<rect x="1110.0" y="2002" width="200" height="26" rx="13" fill="#15803d" opacity=".13"/>
<text x="1210.0" y="2020" text-anchor="middle" font-size="12" font-weight="800" fill="#15803d">WORKING</text>
</svg>

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 20 KiB