marimo/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-data'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-marimo:marimo-ml so operators can
iterate on the streets-map style against the in-pod martin tile
server (/ov-marimo:osm-data-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-marimo: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-marimo:marimo-ml — image composing this layer/ov-marimo:osm-data-layer — companion martin tile server/ov-marimo:notebook-osm — uses an inline style; maputnik can author richer ones/ov-infrastructure:supervisord — service runtimetools
OpenCharly CLI (charly) binary installed into container/VM images for in-container use. Use when working with charly binary deployment inside containers, native D-Bus support, or the full charly toolchain (charly binary + virtualization + gocryptfs + socat).
development
Operator CachyOS workstation profile — a kind:local template + target:local deploy that installs the full dev stack (30 candies) onto a CachyOS host via ShellExecutor. Lives in the overthinkos/cachyos submodule. MUST be invoked before editing or applying the charly-cachyos workstation profile.
tools
Fedora box with the full charly toolchain using shared candies. Rootless-first — runs as uid=1000 with passwordless sudo (no root, no cap_add: ALL). Same candy list as charly-arch. Includes NVIDIA GPU runtime. MUST be invoked before building, deploying, configuring, or troubleshooting the charly-fedora box.
tools
Arch Linux box with the full charly toolchain. Rootless-first — runs as uid=1000 with passwordless sudo (no root, no cap_add: ALL). Composes /charly-coder:charly-mcp so the box is reachable as an MCP gateway on port 18765. NVIDIA GPU runtime composed in. MUST be invoked before building, deploying, configuring, or troubleshooting the charly-arch box.