doxa-maps/skills/plugin-designer/references/workflow.md
Doxa Maps 1ca78d6d5d A laptop that follows the table says when it needs credentials, and the last main defaults say development
The joining page, DEPLOY and the laptop sync default moved to development in the
commit before this one. This finishes the move and closes what a fresh clone's
friend test found.

- landing-preconditions diffs against origin/development when no landing branch
  is exported, instead of main.
- CLOUD-DEVELOPMENT-ENVIRONMENT, the plugin-designer skill (SKILL.md, workflow,
  glossary) and the shared dev server's notes land on and follow development;
  the skill says never to push to main.
- The sync fetches with the laptop's own credentials. git runs with prompts off,
  so on a clone with no credential helper it failed every interval with a bare
  "fetch-failed / remote: Unauthorized", which read as a broken server. That case
  is now its own state, needs-credentials: the log (once, not every tick) and
  /api/dev-sync say "dev-sync needs git credentials for <remote>". The joining
  page and .env.example say so, and that a fresh clone starts on main and must
  switch to development before the sync can fast-forward it.

Measured in scratch repos: the private remote with no helper gives
needs-credentials and one warning over two ticks; a local remote with no
DX_SYNC_BRANCH follows development and fast-forwards; a missing remote stays
fetch-failed.
2026-09-29 00:59:14 +00:00

100 lines
4.3 KiB
Markdown

# The workflow: empty folder to landed on development
## 1. Develop in the Plugin Studio
```bash
bun install # once
bun run dev # the Plugin Studio at http://localhost:5173/
```
- Your plugin appears in the studio as soon as its folder exists; edits reload live.
- One screen on its own: `http://localhost:5173/__leaf/<your-plugin>/<screen>`.
- Test the universal props from the studio header: switch the **engine**, the **language**
(include Arabic), and the **token** (none, a token, a token service). Your plugin must work in
every combination — that is the point of the header.
- `bun run check:dev-assets` checks that every map's data files load under the dev server.
Your plugin's rail entry comes from `<profile>.meta.json` `"label"`, and
`bun run check:studio-rail` fails a bare id. Give it a human name.
## 2. Build
```bash
BUNDLE=<your-plugin> bun x vite build # just your bundle → public/dx-maps/<your-plugin>/
BUILD_ALLOW=1 bun run build # every bundle, the tree, the manifest, the studio
```
The full build rewrites **every** plugin's output. It refuses to run without `BUILD_ALLOW=1`, and
on a team one agent owns it. **Build only your own bundle unless you are that agent.**
`public/dx-maps/manifest.json` then lists your plugin with ready-to-paste embed snippets.
## 3. Check
Run the gates that cover what you touched. The ones most often relevant:
| Gate | What it protects |
|---|---|
| `bun run check:i18n-parity` | every new key exists in all 11 catalogues |
| `bun run check:i18n-never-translated` | a key that was copied rather than translated |
| `bun run check:capability-derived` | your declared `type` agrees with what you compose |
| `bun run check:studio-rail` | your rail entry is a label, not a bare id |
| `bun run check:embed-targets` | the embed targets in the manifest exist |
| `bun run check:dev-assets` | data files load under the dev server |
`package.json` holds the full list; they are all prefixed `check:`.
## 4. Land it on development
`development` is where everyone lands; `main` is production and moves only when `development` is merged
into it, so never push to `main`.
Three commands, in this order, every time:
```bash
git add -A && git commit -m "what you changed"
git pull --rebase origin development
git push origin HEAD:development
```
**A rejected push is normal, not an error.** Someone landed first: run the middle command again and
push again. In a ten-writer stress test at a far faster rate than a human works, 95% of pushes were
rejected and retried, **zero** became merge conflicts, averaging 1.1 retries per edit
(`documentation/HOWTO-join-the-table.md`).
That result is the one-folder-per-person rule paying off: everyone pushes to one branch, so you
collide on *who goes first*, never on the same lines. A real conflict means two people edited one
file — stop and talk to them; that is a coordination problem, not a git problem.
**Stage only your own files.** `git add -A` is safe when you own your folder and nothing else is
dirty; check `git status` first if you are unsure. Never commit another agent's uncommitted work.
## 5. Done means
- `BUNDLE=<your-plugin> bun x vite build` succeeds, and your plugin is in `manifest.json`.
- It works in the Plugin Studio under **both engines**, **with and without a token**, in
**English and Arabic**.
- Every new string is in all 11 catalogues (`bun run check:i18n-parity`).
- Your layer expressions parse under MapLibre (SKILL.md section 5, rule 7).
- You changed nothing in `library/` or in another plugin's folder, or you handed that change to the
build owner.
## Working when your agent runs on a server
If your coding agent runs somewhere other than your laptop, one line in `.env` or `.env.local`
makes your local dev server follow the branch the agent pushes to:
```
DX_SYNC_REMOTE=origin
```
A full repo URL works too. It only ever fast-forwards, and only when all three are true: you are on
that branch, you have no unsaved edits, and you have no local commits. Otherwise it leaves your
files alone and says `main is N commits ahead` in the log. So **push your own work often**, or you
will drift. `documentation/CLOUD-DEVELOPMENT-ENVIRONMENT.md` covers this and the shared-container
alternative.
## Related
- `glossary.md` — the vocabulary
- `targets.md` — capabilities and where a plugin runs
- `backend.md` — databases and migrations