versa/skills/maputnik-layer/SKILL.md
Maputnik — visual editor for MapLibre GL vector-tile styles. Pure-JS SPA built from upstream source via npm at image build time, served as static dist by python -m http.server. Pairs with osm-tools's martin tile server. Use when working with the maputnik layer, the Vite --base=/ build override (critical fix; default --base=/maputnik/ produces 404 asset paths), or the asset-base lock-in eval test.
npx skillsauth add overthinkos/overthink-plugins maputnik-layerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Maputnik is a pure-JS SPA for visually editing MapLibre GL JS style
JSON files. Built from upstream source (felt/maputnik) via npm at
image build time, served as a static dist by Python's stdlib
http.server. Composed by /ov-versa:versa so operators can
iterate on the streets-map style against the in-pod martin tile
server (/ov-versa:osm-tools-layer).
| Property | Value |
|----------|-------|
| Dependencies | supervisord |
| Distros | fedora (sole; needs node + npm + git for build) |
| Build deps | nodejs, npm, git |
| Ports | 8000 (host-mapped to 28000) |
| Service | maputnik (supervisord, restart: always) |
| Static dist | /opt/maputnik/build/ (Vite dist/ renamed) |
service:
- name: maputnik
exec: /usr/bin/python3 -m http.server 8000 --directory /opt/maputnik/build
restart: always
working_directory: /opt/maputnik
Pure stdlib server — no marimo-pixi-env coupling. The system
python3 from supervisord's own RPM dep handles the static serve.
Maputnik's package.json defines "build": "tsc && vite build".
Vite's default base path for builds is --base=/maputnik/. That
default bakes /maputnik/assets/* URL references into the emitted
index.html — but we serve the dist at root (/) via
python -m http.server, so all those baked URLs 404 in the
browser.
Symptom (before fix): the maputnik UI loads at
http://127.0.0.1:28000/ showing a blank page; browser dev-tools
shows asset 404s for /maputnik/assets/index-*.js etc.
Fix in the build cmd:
- cmd: |
set -euo pipefail
git clone --depth 1 https://github.com/maplibre/maputnik /tmp/maputnik
cd /tmp/maputnik
npm ci --no-audit --no-fund
# Override Vite's default --base=/maputnik/ so asset URLs are
# root-relative and resolve against our serve path. The `--`
# forwards the flag through npm to vite.
npm run build -- --base=/
if [ -d dist ]; then
mkdir -p /opt/maputnik
cp -r dist /opt/maputnik/build
else
echo "maputnik build did not produce ./dist directory" >&2
ls -la
exit 1
fi
cd /
rm -rf /tmp/maputnik /root/.npm
user: root
A deploy-scope eval probe greps the served HTML for the (forbidden)
/maputnik/ prefix and fails if present. Locks in the fix against a
future revert to the Vite default:
- id: maputnik-asset-base-not-prefixed
scope: deploy
command: |
! curl -fsS http://localhost:8000/ | grep -q '"/maputnik/'
in_container: true
exit_status: 0
Plus the standard probes (also deploy-scope):
maputnik-running — supervisord program is RUNNINGmaputnik-port-reachable — TCP 8000 reachablemaputnik-http-up — GET / returns 200The streets-map style in /ov-versa:notebook-osm cell 7 is a
small inline JSON. Operators iterating on richer styles can:
http://127.0.0.1:28000/http://127.0.0.1:23000/monacostyle: 'http://...' in the MapLibre constructor)/ov-versa:versa — image composing this layer/ov-versa:osm-tools-layer — companion martin tile server/ov-versa:notebook-osm — uses an inline style; maputnik can author richer ones/ov-infrastructure:supervisord — service runtimedevelopment
Claude Code multi-agent support in Overthink — sub-agents, dynamic workflows, and agent teams, and how each drives the existing `ov eval` disposable beds to test and verify. MUST be invoked before authoring or invoking an ov sub-agent / dynamic workflow / agent team, wiring agent-lifecycle hooks, or asking "which primitive should drive the R10 beds?".
tools
Mounts a virtiofs share tagged `workspace` at /workspace inside a VM guest via a systemd .mount unit. Use when a kind:vm entity shares a host directory into the guest and you need it auto-mounted (and re-mounted at every boot).
development
MUST be invoked before any work involving: the `kind: android` schema kind, a `target: android` deploy, the `apk:` layer package format (installing Android apps declaratively), AndroidDeployTarget, an in-pod emulator OR a remote/physical adb-endpoint device, or nested `pod → android` deployment. The first-class Android device + app surface that sits above `ov eval adb`/`appium`.
tools
Use when committing, branching, pushing, merging, tagging, creating PRs, or approving/merging PRs with gh — the feat/-branch, R10-gated, never-force-push landing workflow across the main repo + the plugins submodule + image/<distro> submodules. Covers sync-to-upstream, branch/worktree pruning, the fork+PR path for contributors without write access, and cross-repo @github landing order.