diff --git a/README.md b/README.md index 1836207a4..4ddfd9ce7 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ +# Goal + +Made by Vibe Coders for Vibe Coders to prepare the way of the Lord and make His paths straight. + +Isaiah 40:3 “...Prepare the way for the LORD in the wilderness; make a straight highway for our God in the desert." + # dx-maps — one build, maps that embed everywhere **Write a map once in `plugin-designs//`, run one build, and drop it on any site** — @@ -12,22 +18,40 @@ capabilities, five deployment methods, 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 × 5 deployment methods** | `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 green `main`** | [agent swarm](#build-it-with-an-agent-swarm) | +| **One agent per plugin, one shepherd, one working `main`** | [agent swarm](#build-it-with-an-agent-swarm) | + +*Click any ▸ to read more. Everything below is folded so you can scroll the pictures first.* --- ## The 5 plugin capabilities A capability is **how much a plugin nests**, from one element (1) to an app of apps (5). Every -screenshot is a real bundle from this repo's build. +screenshot is a real plugin from this repo's build. ### Capability 5 — app shell: the Research Gallery -One plugin, one element (``), and every tab inside it is a real plugin from a lower -tier that you can still embed on its own. `plugin-designs/doxa-maps-spa/` +**One plugin that holds every map as a tab** — and each tab is still a plugin you can embed on its own. ![Capability 5 — the Research Gallery app shell (doxa-maps-spa)](documentation/readme-images/cap5-doxa-maps-spa.png) +
+More about capability 5 — the app shell + +An app shell is the outer frame of a whole app: a rail of tabs down the side, a header, and +navigation. Each tab loads a **real plugin** from a lower capability, only when you open it, so the +app stays fast. Nothing is copied into the shell: when a plugin improves, the shell shows the +improvement on the next build. + +- **Where it lives:** `plugin-designs/doxa-maps-spa/` — one element, ``. +- **Changing the tabs:** the order and grouping are one list, `NAV_MODEL` in `doxa-maps-spa.vue`. +- **New plugins show up by themselves:** any plugin that isn't placed in a section lands on the + folded **Experimental** shelf, read from the built `manifest.json` — no code to edit. +- **A second app shell ships too:** the Plugin Studio (below), + which holds *every* plugin for developers. + +
+
What the Research Gallery is made of — seven production maps, an Experimental shelf, all five capabilities in one plugin @@ -63,36 +87,90 @@ Research Gallery capability 5 ### Capability 4 — composite: plugins wired together -Nests lower-tier plugins and wires them with props and events. `plugin-designs/my-upg-100-list/` +**Several plugins glued into one**, talking to each other — and each piece still embeddable alone. ![Capability 4 — the UPG-100 composite (my-upg-100-list)](documentation/readme-images/cap4-upg100-mfe.png) -| List (cap 1, embeddable alone) | Poster wall (cap 1, embeddable alone) | +| List (capability 1, embeddable alone) | Poster wall (capability 1, embeddable alone) | |---|---| | ![UPG-100 list leaf](documentation/readme-images/cap4-upg100-list.png) | ![UPG-100 poster-wall leaf](documentation/readme-images/cap4-upg100-poster-wall.png) | -### Capability 3 — multi-view: many views, one element +
+More about capability 4 — composites -`plugin-designs/doxa-research-map/` +A composite takes plugins that already exist and places them together — side by side, stacked, or +as views you switch between — and ships the set as **one new element**. The pieces talk through +**props** (settings passed in) and **events** (messages sent out): click a region in one piece and +another piece updates. Nothing is copied, so each piece can still be embedded on its own. + +- **Example:** `plugin-designs/my-upg-100-list/` — the UPG-100 list and its poster wall, joined into + `upg-100-mfe`. Big Picture, Simple Research and Regions are composites too. +- **How to declare one:** a `.meta.json` beside it with `"type": "nested-elements-mfe"` and a + `"composes"` list of the plugins inside. +- **The layouts that do the placing:** `VerticalTabsLayout` and `StackLayout` in `library/layouts/`. + +
+ +### Capability 3 — multi-view: many screens, one element + +**One plugin with several screens inside** — tabs you switch between. ![Capability 3 — the monolithic research map (doxa-research-map)](documentation/readme-images/cap3-monolithic-research.png) +
+More about capability 3 — multi-view + +All the screens live in one plugin, so they share code and data and switch instantly. The trade-off: +you embed the whole thing — you can't embed just one of its tabs. When you need that, split the tabs +into separate plugins and join them with a composite (capability 4). + +- **Example:** `plugin-designs/doxa-research-map/` — Prayer, Engagement, People Groups, Regions, + Languages and Religions in one map. +- **How to declare one:** a `.meta.json` with `"type": "monolithic"`. + +
+ ### Capability 2 — presets: one plugin, many maps -One `root.vue` plus a preset table. `plugin-designs/doxa-simple-map/` +**The same map code, several ready-made versions** — each with its own page and embed code. | Prayer | Engagement | Adoption | |--------|------------|----------| | ![Capability 2 — prayer preset (doxa-simple-map)](documentation/readme-images/cap2-prayer.png) | ![Capability 2 — engagement preset (doxa-simple-map)](documentation/readme-images/cap2-engagement.png) | ![Capability 2 — adoption preset (doxa-simple-map)](documentation/readme-images/cap2-adoption.png) | +
+More about capability 2 — presets + +You write one map, then list its versions in a small table: a name and the settings for each. The +build turns every row into its own standalone page and embed snippet — same code, different map. +Adding a version means adding a row, not writing code. + +- **Example:** `plugin-designs/doxa-simple-map/` — Prayer, Engagement and Adoption from one map. +- **How to make one:** add `.instances.json` beside the plugin: + `{ "instances": [{ "id": "prayer", "title": "Prayer", "props": { … } }] }`. + +
+ ### Capability 1 — single element -One folder, one `.vue`, one element. `plugin-designs/all-people-groups/` +**One folder, one map, one tag** you can paste into any page. ![Capability 1 — a single-element plugin (all-people-groups)](documentation/readme-images/cap1-single-element.png) -> Which bundle sits at which tier is generated, not remembered: -> [documentation/reference-capability-exemplars.md](./documentation/reference-capability-exemplars.md). +
+More about capability 1 — single element + +The simplest plugin, and where every map starts: a folder with three files — the map's `.vue`, an +`index.js` that registers its tag, and an `index.html` for previewing it. The build turns it into +one custom HTML tag, like ``, that works on any web page. + +- **Example:** `plugin-designs/all-people-groups/` — every people group on one map. +- **How to make one:** copy `plugin-designs/template-bundle/` to `plugin-designs//` and + rename it. The studio finds it automatically. +- **Which plugin is the example of each capability** is generated, not remembered: + [documentation/reference-capability-exemplars.md](./documentation/reference-capability-exemplars.md). + +
--- @@ -100,28 +178,62 @@ One folder, one `.vue`, one element. `plugin-designs/all-people-groups/` ### 1. iframe — the prayer map on any site ✅ production -One ` ``` -![Method 1 — the prayer map embedded in a host page's iframe](documentation/readme-images/deploy1-iframe.png) +Host the built `public/doxa-maps/` folder anywhere (it works from any address), then point the +iframe at it. + +
### 2. Mobile app — UPG-100 on a phone ✅ built -The UPG-100 prayer lists and posters, shipped on their own as a Capacitor app: one poster per row, -print options that wrap to fit. `bun run check:mobile` · `bun run phone` (needs Android SDK + JDK 17) +**The same maps, wrapped as a phone app.**

Method 2 — the UPG-100 list at phone size

+
+More about method 2 — mobile app + +[Capacitor](https://capacitorjs.com) wraps the built maps into an Android app — the same files, +no new code. Shown here: the UPG-100 prayer lists and posters, one poster per row, with print +options that fit a phone. + +```bash +bun run check:mobile # checks the app is wired up correctly — needs no Android tools +bun run phone # builds the app and installs it on a phone or emulator +``` + +`bun run phone` needs the Android SDK, JDK 17 and `adb`. Only Android is set up; iOS is not yet. + +
+ ### 3. JavaScript embed — the Research Gallery on dx-life ✅ production -The whole capability-5 app on the dx-life research page, from one ` @@ -130,93 +242,187 @@ every build: ``` -![Method 3 — the Research Gallery JS-embedded on the dx-life research page](documentation/readme-images/deploy3-js-embed-dxlife.png) + -### 4. WordPress / Disciple Tools plugin — 🧪 proof of concept +### 4. WordPress / Disciple Tools — 🧪 proven, not yet in production -A shortcode + block plugin in `deployment/wordpress/`; its contract test passes -(`bun run check:wp-embed`). Proven, not production-ready. +**We got a JAMstack map running inside WordPress and Disciple Tools.** -![Method 4 — WordPress / Disciple Tools plugin, proof of concept](documentation/readme-images/deploy4-wordpress.png) +![Method 4 — WordPress / Disciple Tools, proven but not yet in production](documentation/readme-images/deploy4-wordpress.png) -### 5. Desktop app (Tauri) — 🧪 proof of concept +
+More about method 4 — WordPress / Disciple Tools -A desktop binary and `.deb` build from `deployment/src-tauri/` (`bun run check:tauri`). Proven, -not production-ready. +It works, but it isn't yet a production feature of the map bundler. Two ways to try it: -![Method 5 — desktop app (Tauri), proof of concept](documentation/readme-images/deploy5-desktop.png) +- **Easiest:** paste a method 1 or method 3 snippet into a WordPress **Custom HTML** block. +- **As a plugin:** install `deployment/wordpress/doxa-maps-embed/` in `wp-content/plugins/`. It adds + a `[doxa_map]` shortcode and a block for the block editor. + +`bun run check:wp-embed` confirms the plugin writes the right HTML, without needing WordPress +installed. + +
+ +### 5. Desktop app (Tauri) — 🧪 proven, not yet in production + +**We got the JAMstack map app running as a desktop app.** + +![Method 5 — desktop app (Tauri), proven but not yet in production](documentation/readme-images/deploy5-desktop.png) + +
+More about method 5 — desktop app + +[Tauri](https://tauri.app) wraps the same built maps into a desktop program: it produced a Linux +app and a `.deb` installer. It isn't in the dx bundler for production yet — and the Research Gallery +could become a strong desktop app. + +```bash +bun run check:tauri # checks the desktop setup — needs no Rust tools +bun run tauri:build # builds the app — needs Rust, the Tauri CLI and webview libraries +``` + +
WordPress and Tauri marks from [Simple Icons](https://simpleicons.org) (CC0); the trademarks belong to their owners. -> **Mapbox token:** the dev server bakes one in; built pages take `?tk=pk.…`, a pasted token, or a -> token endpoint. Or skip Mapbox entirely: `provider: "maplibre"` on any instance renders on MapLibre -> with no key. Every command and prerequisite: -> [documentation/README-SECTION-3-cli-commands.md](./documentation/README-SECTION-3-cli-commands.md). - --- ## Build it with an agent swarm -Every plugin has **one agent** responsible for building it, working in its own git worktree. The -plugins live together in the **Plugin Studio** — one repo, one shared library — and **one shepherd** -makes sure every agent is doing its job well. Changes land on `main` through a **merge queue** (the -model behind GitHub's merge queue and GitLab's merge trains): one at a time, rebased and gated. +**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 `main` — the one +official version — one at a time. -![The delegation model: the Plugin Studio at the centre, a ring of plugins around it, one agent per plugin outside that, and one shepherd over all the agents](documentation/readme-images/delegation-model.png) +![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) + +
+What problem does this solve? (in plain words) + +All the maps here share **one project, one library and one build step**. That's what makes them +work together, and it's also the danger: if one agent's change breaks the shared library, **every +map breaks at once**. And when several agents work in the same project at the same time, they step on +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: + +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 `main`. `main` always works. +4. **A shepherd agent watches everyone**: plugins built in the studio, shared parts really shared, + and every change going through the line. + +That's how many plugins get built at the same time, in one project, without the maps breaking. + +
+ +
+The words, if you're new to git + +| Word | In plain terms | +|---|---| +| **repo** | the project folder, with its full history | +| **main** | the one official version of the project that everyone builds from | +| **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 | + +
+ +
+The commands (for the curious) ```bash -# one worktree + one agent per plugin +# one private copy (worktree) + one agent per plugin git worktree add -b regions/work ../dx-maps-regions main git worktree add -b upg100/work ../dx-maps-upg100 main -# one dev server per agent, each on its own port +# one preview server per agent, each on its own port bun x vite --port 5301 --strictPort -# land through the queue: one at a time, rebased, gated +# add work through the line: one at a time, caught up first, checks must pass flock /tmp/dx-maps-main.lock sh -c ' git fetch origin && git rebase origin/main && bun run gates:pre && git push origin HEAD:main' ``` -One agent owns the full build (it wipes the shared output first); everyone else checks their own -bundle with `BUNDLE= bun x vite build`. How to contribute, and the bar for shared code: -[documentation/CONTRIBUTING.md](./documentation/CONTRIBUTING.md). -Diagram source: [`delegation-model.svg`](./documentation/readme-images/src/delegation-model.svg). +One agent owns the full build (it rebuilds everyone's output); the others check just their own +plugin with `BUNDLE= bun x vite build`. How to contribute, and the bar for shared code: +[documentation/CONTRIBUTING.md](./documentation/CONTRIBUTING.md). Diagram source: +[`delegation-model.svg`](./documentation/readme-images/src/delegation-model.svg). + +
--- ## The Plugin Studio — ★ where you work -Every plugin in one place, sorted by capability. Pick any plugin to run it live, see what it is -composed of, and copy its embed code. Tell your agent which plugins to **group**, and it composes -them into a higher-capability plugin with props, events and a layout — that is how the Research -Gallery was built. *(The studio is being redesigned; this screenshot tracks it.)* +**Every plugin in one place, sorted by capability.** Pick any plugin to run it live, fold open the +plugins inside it, and copy its embed code. Tell your agent which plugins to **group**, and it builds +a higher-capability plugin from them — that's how the Research Gallery was built. ![Capability 5 — the developer studio (plugin-studio)](documentation/readme-images/cap5-plugin-studio.png) ### Get it running -You need **git**, **[Bun](https://bun.sh)** and **Node ≥ 18**. +You need **git**, **[Bun](https://bun.sh)** and **Node ≥ 18**, plus a free +**[Mapbox](https://account.mapbox.com) public token** (it starts with `pk.`) so the maps have a +background. ```bash git clone https://git.nuxtbase.app/doxa-open/doxa-maps.git cd doxa-maps bun install --frozen-lockfile +cp .env.example .env # then paste your pk. token after VITE_MAPBOX_TOKEN= bun run dev # → http://localhost:5173/ is the Plugin Studio ``` -No build needed first — the built tree is committed. To start a plugin, copy +No build needed first — the built maps are already in the repo. To start a plugin, copy `plugin-designs/template-bundle/` to `plugin-designs//`; the studio finds it automatically. +
+Make changes to the studio itself + +The studio is a plugin like any other: `plugin-designs/plugin-studio/plugin-studio.vue`. + +1. Run `bun run dev` and open http://localhost:5173/ — that page *is* the studio. +2. Edit `plugin-studio.vue` (or ask your agent to). The page updates as you save. +3. When it looks right, build just the studio and refresh its security hashes: + + ```bash + BUNDLE=plugin-studio bun x vite build + bun run fix:sri + ``` + +4. Check it opens every plugin: `bun run smoke:studio` (with `bun run dev` running). + +
+ +
+No Mapbox token? And other map settings + +- **No token:** set `"provider": "maplibre"` on any plugin (or add `?provider=maplibre` to a map's + page) and it draws with MapLibre, which needs no key. +- **Built pages** take a token from `?tk=pk.…` in the address, from a token you paste once into the + page, or from a token endpoint. +- Every command and prerequisite, per deployment method: + [documentation/README-SECTION-3-cli-commands.md](./documentation/README-SECTION-3-cli-commands.md). + +
+ | Command | What it does | |---|---| -| `bun run dev` | The Plugin Studio, hot-reloading, at http://localhost:5173 | -| `BUNDLE= bun x vite build` | Build one bundle only | -| `BUILD_ALLOW=1 bun run build` | The full deployable tree in `public/doxa-maps/` (~4 min; refuses without the flag, to protect a shared tree) | -| `bun run serve` | Serve the built tree at http://localhost:4173 | -| `bun run check:settled` | Exit 0 = the built tree is safe to measure right now | -| `bun run gates:pre` · `bun run gates:post` | The verification gates | -| `bun run shots` | Regenerate these screenshots (`ONLY=` for one) | +| `bun run dev` | The Plugin Studio, updating as you save, at http://localhost:5173 | +| `BUNDLE= bun x vite build` | Build one plugin only | +| `BUILD_ALLOW=1 bun run build` | Build everything into `public/doxa-maps/` (~4 min; refuses without the flag, to protect a shared project) | +| `bun run serve` | Serve the built maps at http://localhost:4173 | +| `bun run gates:pre` · `bun run gates:post` | The checks that keep `main` working | +| `bun run shots` | Retake these screenshots (`ONLY=` for one) | --- @@ -225,9 +431,9 @@ No build needed first — the built tree is committed. To start a plugin, copy ```text plugin-designs/ YOUR maps — one folder per plugin, a free zone library/ the SHARED toolkit (layouts, components, composables) — a high bar -public/doxa-maps/ the build output: the drop-anywhere tree + manifest.json -deployment/ Capacitor · WordPress · Tauri -internal/ the build generator and the gates +public/doxa-maps/ the build output: the drop-anywhere folder + manifest.json +deployment/ mobile (Capacitor) · WordPress · desktop (Tauri) +internal/ the build and its checks documentation/ tutorial · how-to · reference · architecture — start at documentation/README.md ``` diff --git a/documentation/readme-images/delegation-model.png b/documentation/readme-images/delegation-model.png index 6d8f9ff6c..0b1260421 100644 Binary files a/documentation/readme-images/delegation-model.png and b/documentation/readme-images/delegation-model.png differ diff --git a/documentation/readme-images/deploy4-wordpress.png b/documentation/readme-images/deploy4-wordpress.png index 5464a8d00..b3be4de7b 100644 Binary files a/documentation/readme-images/deploy4-wordpress.png and b/documentation/readme-images/deploy4-wordpress.png differ diff --git a/documentation/readme-images/deploy5-desktop.png b/documentation/readme-images/deploy5-desktop.png index 9c35c1262..f670797ef 100644 Binary files a/documentation/readme-images/deploy5-desktop.png and b/documentation/readme-images/deploy5-desktop.png differ diff --git a/documentation/readme-images/src/delegation-model.svg b/documentation/readme-images/src/delegation-model.svg index f262572af..35682aa88 100644 --- a/documentation/readme-images/src/delegation-model.svg +++ b/documentation/readme-images/src/delegation-model.svg @@ -1,4 +1,4 @@ - + @@ -9,7 +9,7 @@ - + How dx-maps is built: one studio, one agent per plugin, one shepherd @@ -23,14 +23,24 @@ -PLUGIN STUDIO -one repo · every plugin in one place -shared library/ (@map) - - -main -always green -MERGE QUEUE · ONE AT A TIME +PLUGIN STUDIO · ONE REPO + +shared library/ (@map) · every plugin in one place + + + +MERGE QUEUE · GUARD +ONE AGENT AT A TIME + + + + + + + +main +the one branch +always green PLUGINS AGENTS @@ -112,48 +122,74 @@ one shepherd makes sure all plugin agents are doing their job building the plugins well each plugin has one agent responsible for building it - - -Plugin Studio — the one repo - -plugin (badge = capability) - -Experimental shelf - -agent — builds one plugin - -shepherd — oversees all - - -main → ONE build → public/doxa-maps/ → five ways to ship - -METHOD 1 -iframe -any website - -PRODUCTION - -METHOD 2 -Mobile app -Capacitor - -BUILT - -METHOD 3 -JavaScript embed -script + SRI - -PRODUCTION - -METHOD 4 -WordPress -Disciple Tools - -PROOF OF CONCEPT - -METHOD 5 -Desktop -Tauri - -PROOF OF CONCEPT + + +main — the one branch + +merge queue — one at a time + +Plugin Studio — the one repo + +plugin (badge = capability) + +Experimental shelf + +agent — builds one plugin + +shepherd — oversees all + +How main is protected — so many plugins can be built at once + + +1 +Work in your own copy +each agent builds its own plugin, +in its own private copy of the project +→ + + +2 +Catch up, fix the clashes +pull in everyone else's latest work and +fix any clashes before adding yours +→ + + +3 +Add changes one at a time +the queue lets ONE agent in at a time; +the checks must pass, main stays working + + +main → ONE build → public/doxa-maps/ → five ways to ship + +METHOD 1 +iframe +any website + +PRODUCTION + +METHOD 2 +Mobile app +Capacitor + +BUILT + +METHOD 3 +JavaScript embed +script + SRI + +PRODUCTION + +METHOD 4 +WordPress +Disciple Tools + +PROVEN · NOT YET LIVE + +METHOD 5 +Desktop +Tauri + +PROVEN · NOT YET LIVE \ No newline at end of file diff --git a/documentation/readme-images/src/deploy4-wordpress.svg b/documentation/readme-images/src/deploy4-wordpress.svg index ee4679929..1418813a4 100644 --- a/documentation/readme-images/src/deploy4-wordpress.svg +++ b/documentation/readme-images/src/deploy4-wordpress.svg @@ -3,9 +3,10 @@ WordPress / Disciple Tools -A plugin for WordPress sites, including Disciple Tools: -a [doxa_map] shortcode and a block editor block. - -PROOF OF CONCEPT -Contract-tested and working — not yet production-ready. +We got a JAMstack map running inside +WordPress and Disciple Tools. + +PROVEN · NOT YET LIVE +Proven to work — not yet a production +feature of the map bundler. \ No newline at end of file diff --git a/documentation/readme-images/src/deploy5-desktop.svg b/documentation/readme-images/src/deploy5-desktop.svg index 6d3480250..7f4c4baae 100644 --- a/documentation/readme-images/src/deploy5-desktop.svg +++ b/documentation/readme-images/src/deploy5-desktop.svg @@ -3,9 +3,10 @@ Desktop app (Tauri) -The same map tree wrapped as a desktop app: -a native binary and a .deb installer. - -PROOF OF CONCEPT -Contract-tested and working — not yet production-ready. +We got the JAMstack map app running +as a desktop app. + +PROVEN · NOT YET LIVE +Proven, not yet in production. The Research +Gallery could become a strong desktop app. \ No newline at end of file