From 2a4c3ddb3d7dc03589333a6be346a5bfae571e29 Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Tue, 29 Sep 2026 18:39:36 +0000 Subject: [PATCH 1/2] The full build also copies the maps into the sibling DX Life site, when it is there `bun run build` now ends with `sync-dropin --from-config --if-present`. It copies public/dx-maps into the ONE configured host path (vite.doxa-maps-build-config.json dropin.dest, default ../doxa-life/public, or DOXA_DROPIN_DEST). No site at that path: it prints "skipped" and exits 0. Nothing else on the filesystem is searched for repos or sites. DOXA_DROPIN=off skips it even when the site is there. Without --if-present, a missing host is still an error, as before. Tested: no host skips (exit 0); a host gets 1,209 files; DOXA_DROPIN=off copies nothing; the plain command still refuses a missing host. The container's /cdn build (build-cdn.sh) does not run this chain. On this box ../doxa-life does not exist beside the doxa-maps checkouts (DX Life lives in root-dx-life), so the step is a no-op for the fleet's builds. --- internal/sync-dropin.mjs | 9 ++++++++- package.json | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/internal/sync-dropin.mjs b/internal/sync-dropin.mjs index 424974e9f..a8d5030c1 100644 --- a/internal/sync-dropin.mjs +++ b/internal/sync-dropin.mjs @@ -39,7 +39,7 @@ * Refuses to CREATE : the drop-in folder is the host's decision, not this script's. * Gate: `node internal/public-hygiene-check.mjs --strict` must pass before a public push. * - * Usage: node internal/sync-dropin.mjs [--from public] [--tree doxa-maps] [--keep-staging] + * Usage: node internal/sync-dropin.mjs [--from public] [--tree doxa-maps] [--keep-staging] [--if-present] * [--only a,b | --from-config] [--prune] [--protect a.txt,other] [--dry-run] * e.g. bun run dropin (= --from-config, into dropin.dest: ../doxa-life/public) * Prints: copied · unchanged · deleted (stale inside the allowlist) · pruned (outside it) · @@ -96,6 +96,13 @@ if (PRUNE && basename(dest) === 'public') { console.error(`[sync-dropin] refusing --prune into ${dest}: it is a site's web-root, and --prune would delete every file of the site outside the drop-in. Sync without --prune (bun run dropin); stale files INSIDE the drop-in are still removed.`) process.exit(1) } +// --if-present (the full build's last step): the configured host is OPTIONAL. Its absence is a skip, not an error. +// Only the ONE configured path is checked (dropin.dest, or DOXA_DROPIN_DEST): nothing on the filesystem is searched +// for other repos or sites. DOXA_DROPIN=off skips it even when the host is there. +if (args.includes('--if-present')) { + if (process.env.DOXA_DROPIN === 'off') { console.log('[sync-dropin] skipped: DOXA_DROPIN=off'); process.exit(0) } + if (!existsSync(dest) || !statSync(dest).isDirectory()) { console.log(`[sync-dropin] skipped: no host at the configured path ${dest}`); process.exit(0) } +} if (!existsSync(dest) || !statSync(dest).isDirectory()) { console.error(`[sync-dropin] dest does not exist or is not a directory: ${dest} — create the drop-in folder in the host first`); process.exit(1) } if (!existsSync(FROM)) { console.error(`[sync-dropin] source missing: ${FROM} — run \`bun run build\` first`); process.exit(1) } diff --git a/package.json b/package.json index f091e9ded..dcc06cb56 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "build": "bash internal/build-lock.sh", "build:bundle": "bun x vite build", "build:bundles": "node internal/run-parallel.mjs --bundles", - "build:unlocked": "bun run gates:pre && bun run library-index && bun run check:library-index && bun run clean && bun run token && bun run build:bundles && bun run tree && bun run gates:post", + "build:unlocked": "bun run gates:pre && bun run library-index && bun run check:library-index && bun run clean && bun run token && bun run build:bundles && bun run tree && bun run gates:post && node internal/sync-dropin.mjs --from-config --if-present", "build:watch": "bun x vite build --watch", "cap:sync": "./node_modules/.bin/cap sync android", "cap:verify": "test -f deployment/capacitor/android/app/src/main/assets/public/index.html && echo \"OK webDir copied\" || (echo \"FAIL: empty assets/public -> blank white screen. Check webDir.\" && exit 1)", From 10be43d2b158612300c11279ec2ec60171d230e9 Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Tue, 29 Sep 2026 18:37:32 +0000 Subject: [PATCH 2/2] README: a vibe-coder section (Studio, build, embed) and an agent section (what this repo is for) For vibe coders: run the Plugin Studio, build one map or all of them (and the automatic copy into a sibling DX Life site), and embed a map: every map's own embed.script in manifest.json, loaded from DX Life's public/dx-maps. For agents: the repo builds mobilization maps, and each goal (reach a city, mobilize for people groups, plan outreach, prayer packets and resources) is mapped to the production maps that serve it, with the skill, the plugin rules, the landing rules and the freeze on experimental maps. --- README.md | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/README.md b/README.md index eea5bfc93..0cae5374d 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,59 @@ capabilities, three outputs, one shared library, one build. | **Shared library, private plugins** — reuse without breaking each other | `bun run check:library-index` | | **One agent per plugin, one shepherd, one working `main`** | [agent swarm](#build-it-with-an-agent-swarm) | +## For vibe coders: build, open the Studio, embed a map + +**1. Open the Plugin Studio** (every map, live, updating as you or your agent edit): + +```bash +bun install --frozen-lockfile +bun run dev # open the address it prints: that page is the Plugin Studio +``` + +**2. Build.** The built maps are already in the repo. After a change, rebuild just that map, or all of them: + +```bash +BUNDLE= bun x vite build # one map (seconds) +BUILD_ALLOW=1 bun run build # every map (~4 min); the output is public/dx-maps/ +``` + +When the DX Life site's repo sits next to this one (`../doxa-life`), the full build also copies the maps into +its `public/`. That is the one path set in `vite.doxa-maps-build-config.json` (`dropin.dest`); nothing else on +your computer is searched. No site there: the step says so and skips. `DOXA_DROPIN=off` turns it off, and +`bun run dropin` copies on demand. + +**3. Embed a map.** Every map has its own embed script: its `embed.script` in `public/dx-maps/manifest.json` (an +`embed.iframe` too). A snippet is two parts, the map's script and its tag: + +```html + + +``` + +On DX Life, the maps are served from its own `public/dx-maps/`, so a page loads `/dx-maps//.js` and +places the map's tag. Copy each snippet from the manifest: its `integrity` hash changes with every build. More: +[the three routes](#where-the-folder-goes-three-routes) and [how a page shows a map](#how-a-page-shows-a-map). + +## For agents: what this repo is for + +This repo builds **mobilization maps**: maps that help disciples, churches and leaders reach their city and the +people groups of the world. When you work here, the goal is one of these: + +| Goal | The production maps that serve it | +|---|---| +| **Reach a city** | Cities with Internet (`cities-internet`); Regions (`regions-dashboard`) and the country map (`country-map`) | +| **Mobilize for people groups** | Big Picture (`dashboard-plus-grid`); Research Map + Grid (`research-map-plus-grid`) | +| **Plan outreach** | Gospel Resources (`gospel-resources`): what exists in each language; Regions, by country | +| **Pray: packets and prayer resources** | UPG-100 (`my-upg-100-list`): prayer packets; Prayer Progress (`doxa-simple-map`) | + +- **Start with the skill:** [`skills/plugin-designer`](./skills/plugin-designer) teaches the patterns, the shared + library and the checks. +- **One plugin per folder** in `plugin-designs/`; shared code goes in `library/` only if it stays reusable for + every other plugin. +- **Land on `development`**, one change at a time through the lock, with `bun run gates:pre` passing. `main` is + production and moves only on a publish. +- These 8 maps are in production. The experimental maps are frozen: leave them as they are. + *Click any ▸ to read more. Everything below is folded so you can scroll the pictures first.* ---