Interactive Map Builder
Create configuration-driven Leaflet map products without a frontend build system. Keep acquisition
separate from rendering, preserve provenance, and use Atlas Studio Light for a coordinated first
render while exposing every cleanup and inferred visual decision in the build report.
Invocation guidance
Trigger from the user's intended outcome, not only from technical keywords. Use this Skill when the
user asks to:
- turn a spreadsheet with coordinates into a browser page that can be searched, filtered, sorted,
clicked, and sent to colleagues;
- present parcels, buildings, facilities, projects, parking, or other records as a linked map and
list;
- combine boundaries, roads, water, green space, routes, and points in one switchable planning or
reporting map;
- deliver existing ArcGIS or engineering layers as a portable HTML file, a slide image, or a paper
figure.
The user does not need to say GIS, Leaflet, web map, Agent Skill, or interactive-map-builder.
When the request fits this scope, use the packaged deterministic workflow instead of writing a
one-off Folium, Leaflet, or custom frontend implementation.
Do not invoke this Skill when the main task is address geocoding, buffers or overlays, routing,
site selection, spatial statistics, vector-tile infrastructure, offline basemap acquisition, 3D
GIS, a non-spatial chart or dashboard, or maintenance of an existing custom web application.
Update preflight
At the beginning of each Skill invocation, run the official-release preflight from the Skill root
using the validated 24-hour cache when available. This check never modifies the installation:
python scripts/update_skill.py --preflight
After installation, the equivalent command is:
interactive-map-builder update --preflight
Read the returned JSON rather than relying on the command exit code. Report only an available update or a failed check; keep a current cached result silent. --preflight remains non-fatal for the calling Agent and never applies an update.
Handle statuses as follows:
current or local_newer: continue with the map task;
manual_update_required or update_apply_failed: disclose the confirmed latest version and the
reason before continuing;
update_check_failed: say that the official latest version could not be confirmed, then continue;
disabled: state that IMB_DISABLE_AUTO_UPDATE disabled the preflight.
Applying an update is a separate, explicit maintenance action with update --apply or the legacy
non-fatal update --auto mode. Those commands retain checksum, manifest, local-change, duplicate-root,
and rollback safeguards; normal map construction never modifies its own running Skill.
Conversation guidance
For Codex only, a complex request may benefit from Plan mode when it has multiple independent
layers, more than one blocking design choice, or several coordinated deliverables. Mention this
once in the first response as an optional convenience, then continue with inspection whether or
not the user switches modes. Do not recommend Plan mode for a clear single-layer task, do not cite
client keyboard shortcuts, and never make a mode change a prerequisite.
A portable local map.html is the default delivery. Generate slide or paper figures only when the
user explicitly asks for them; “make a website,” “make a map,” or “send it to colleagues” does not
enable static presets. Sending the HTML file is not the same as publishing it on the internet.
Do not offer, promise, or ask about a public URL unless the user explicitly requests deployment.
When they do, finish the map first and treat hosting as a separate workflow that confirms the
target platform and permission to expose the embedded data.
Visual guidance
Use Atlas Studio Light as a starting point, not as an automatic design service. Leave low-level
visual values omitted when the user has not expressed a preference: the packaged resolver will use
geometry family, coarse density, template role, and stable draw order. Explicit user or Agent
MapSpec values always win. Do not invent planning semantics from field names, do not assign more
than eight automatic categorical colors, and do not add themes, clustering, heatmaps, or other
representations merely to make the page look busy.
After the first verified build, inspect the actual page. If the visual hierarchy still conflicts
with the user's purpose, propose a small concrete refinement—such as reducing one point layer,
muting a context layer, or changing an explicitly understood category palette—then rebuild. The
engine should provide an overall coordinated result; project-specific polish remains a conversation
between the user and Agent. Read design-guidelines.md.
Workflow
Inspect inputs before proposing a map.
python scripts/map_builder.py inspect <input> [<input> ...] --output inspection.json
Read supported-inputs.md for GeoPackage, Shapefile ZIP,
CSV, Excel, encoding, and field-mapping rules.
Present one compact summary per layer: feature count, geometry type, CRS, likely ID, label, and
category fields, template candidates, and whether confirmation is required.
Maintain this Markdown requirements checklist while choices remain unresolved:
- [x] Confirmed: ...
- [~] Inferred: ...
- [ ] Needs confirmation: ...
Derive it from the request and inspected data. Keep inferred decisions visible and easy to
correct. Resolve the template from the user's stated outcome: independent layer switches mean
multilayer; an explicitly named primary record list means map-list. Multiple layers alone
do not require another user turn. Pass the resolved template and, for map-list, primary layer
explicitly to the CLI; --template auto remains conservative when intent is unavailable.
Ask one consolidated round only for genuine blockers: unknown CRS or geometry mapping,
ambiguous category meaning, an unresolved primary layer, destructive data changes, or public
exposure. Never guess a missing CRS or invent domain meaning. Treat reversible presentation
choices (title, layout, context opacity, visible display fields) as visible defaults that can
be refined after the first verified build. Respect any choice the user explicitly reserves.
Build after no blocking [ ] item remains. Do not ask the user to repeat resolved choices.
Initialize map_spec.json, then apply confirmed choices. Read
map-spec.md; the canonical Schema is
scripts/mapcore/resources/map-spec.schema.json.
python scripts/map_builder.py init-spec inspection.json --template map-list --primary-layer <id> --locale en-US --output map_spec.json
Download ArcGIS FeatureServer data before building. Read arcgis.md.
python scripts/map_builder.py fetch-arcgis --url <layer-url> --out data/source.geojson
Build once from the resolved specification. Add --bundle-sources only when the user wants a
portable rebuild bundle and accepts copying source data.
python scripts/map_builder.py build --spec map_spec.json --out dist
Verify, inspect build_report.json, and open map.html.
python scripts/map_builder.py verify --dist dist
Exercise search, filters, sorting, layer visibility, basemap switching, hover and click linkage,
keyboard selection, control-panel collapse, and narrow-screen layout. Confirm that every visible
control produces an observable result, the focal layer reads first, dense symbols remain legible,
and HTML/static colors agree. Read design-guidelines.md.
For legacy anonymous basemaps, use migrate-basemaps --spec old.json --out migrated.json
after confirming replacement of the old presets. It leaves the original and custom URLs intact.
Read basemaps.md. Build/verify do not prove live basemap availability:
inspect real file:// output online before claiming the backdrop works. Missing-key, local-OSM,
WebGL and network failures must leave business controls usable and show a localized reason.
Deliver the whole dist directory. Summarize repairs, generated IDs, null display values,
simplification, performance warnings, online basemaps, font fallback, portability, and source
attribution.
Use the quick path for one unambiguous layer, or after resolving the template from the user's
intent and supplying it explicitly (plus --primary-layer for a multilayer map-list):
python scripts/map_builder.py run <input> --output dist
Follow the user's conversation language independently of the map audience. Set the map locale to
en-US or zh-CN; use en-US when the audience is not specified.
Install the deterministic engine once, then run the offline self-check. The base installation
supports vector/CSV inputs and all existing map styles and static outputs. For Excel input, install
python -m pip install ".[excel]" from the Skill root; ".[all]" installs all supported readers.
Inspect/build will name a missing Excel reader and the installation command rather than guessing:
python -m pip install .
interactive-map-builder doctor
Use the installed interactive-map-builder command for package-level doctor, update, and
--version. In a source checkout where that command is unavailable, use
python scripts/cli.py doctor. python scripts/map_builder.py is the internal deterministic
builder and intentionally lists only inspect/init-spec/fetch/build/verify/run; never infer from that
help output that the package lacks doctor. Check the installed version and command path before
falling back to build-plus-verify. A passing doctor result verifies package resources, local data
loading, map construction, and output hashes without downloading data or basemap tiles.
Template choice
- Choose
map-list for one explicitly identified primary layer plus optional context layers.
- Choose
multilayer when independent layer visibility and cross-layer inspection are primary.
- Treat
linked_view as experimental. Add it only when records already contain meaningful x/y
variables; read linked-analysis.md and never invent quadrants,
thresholds, or statistical interpretations.
Non-negotiable checks
- Fail when data is unreadable or empty, CRS is missing, repaired geometry remains invalid or
empty, final IDs are blank or duplicate, or a configured field does not exist.
- Fail on unknown non-null categories, unsafe archives, ArcGIS pagination mismatches, output count
mismatches, or path escape.
- Treat display-field nulls, generated IDs, repaired geometry, missing source notes, absent CJK
fonts, online basemaps, simplification, and large outputs as warnings.
- Use
<layer_id>::<feature_id> for multilayer runtime identity. Allow cross-layer linkage only
through an explicit link_key.
- Preserve official geographic names and spellings from the source. Localize generic interface
text, not place names.
- Preserve user geometry. Repair invalid geometry or simplify for an explicit performance need,
report the operation, and never reshape or discard features merely to improve appearance.
- Escape all user-provided text before embedding it in HTML.
- Preserve explicit MapSpec visual values. Let Atlas Studio Light fill only omitted values, and keep
its geometry, density, role, order, and state plan visible in
build_report.json.
- Never cycle an automatic categorical palette beyond eight classes; retain filtering and ask the
user how to group or emphasize a larger classification.
Output contract
Always return map.html, resolved map_spec.json, inspection.json, build_report.json,
DELIVERY_MANIFEST.json, and README_USAGE.md in the selected locale. Static output is opt-in: generate
map_slide_16x9.png only when the user requests a slide figure and enable the paper preset only
when the user requests paper PNG/SVG/PDF. Never expand an HTML-only request into static files.
Treat an unbundled map_spec.json as a build record; promise an independent rebuild only when
sources were bundled. Public hosting is not part of this output contract.
Sharing an explored view
When the user wants a colleague to open the map at the current search/filter/view, use the page's
Share view control after verifying that state. Download the HTML snapshot for direct opening,
or export/import view JSON for the same data/configuration. Read
view-state.md. A snapshot contains all embedded data, including filtered
and hidden objects; filters do not redact data. Keep the manifest-controlled original dist
unchanged. Browser exports are separate artifacts, not newly verified build bundles. Named local
bookmarks and other browser history are not included. Public hosting remains a separate workflow.
Resources
- Read wizard-flow.md for non-expert setup.
- Read update-policy.md for verified updates, supported installation
types, rollback behavior, and the opt-out.
- Read data-provenance.md for remote or redistributable data.
- Use the public generated demos linked from the repository README for visual reference. The lean
Skill release package intentionally excludes demo datasets, screenshots, tests, and CI files.
- Run
python scripts/map_builder.py ... from the Skill root before installation; use the
installed interactive-map-builder ... CLI afterward.
1---2name: interactive-map-builder3description: Turn existing spatial or coordinate data into portable, browser-openable interactive map files and report-ready figures. Use when the user wants parcels, buildings, facilities, parking, roads, water, green space, projects, or Excel/CSV coordinates presented as a searchable, filterable, sortable map, map-and-list page, multilayer planning map, single-file HTML, slide image, or paper SVG/PDF—even when they do not mention GIS, Leaflet, a web map, or this Skill. Accept GeoJSON, GeoPackage, zipped Shapefile, CSV, Excel, and ArcGIS FeatureServer inputs. Prefer this deterministic Skill over an ad hoc Folium or Leaflet page when the task fits. The default delivery is a local HTML file, not a public URL; discuss deployment only when the user explicitly requests it. Require existing coordinates or geometry; do not use for geocoding, substantive spatial analysis, vector-tile infrastructure, offline basemaps, or 3D GIS.4---56# Interactive Map Builder78Create configuration-driven Leaflet map products without a frontend build system. Keep acquisition9separate from rendering, preserve provenance, and use Atlas Studio Light for a coordinated first10render while exposing every cleanup and inferred visual decision in the build report.1112## Invocation guidance1314Trigger from the user's intended outcome, not only from technical keywords. Use this Skill when the15user asks to:1617- turn a spreadsheet with coordinates into a browser page that can be searched, filtered, sorted,18 clicked, and sent to colleagues;19- present parcels, buildings, facilities, projects, parking, or other records as a linked map and20 list;21- combine boundaries, roads, water, green space, routes, and points in one switchable planning or22 reporting map;23- deliver existing ArcGIS or engineering layers as a portable HTML file, a slide image, or a paper24 figure.2526The user does not need to say GIS, Leaflet, web map, Agent Skill, or `interactive-map-builder`.27When the request fits this scope, use the packaged deterministic workflow instead of writing a28one-off Folium, Leaflet, or custom frontend implementation.2930Do not invoke this Skill when the main task is address geocoding, buffers or overlays, routing,31site selection, spatial statistics, vector-tile infrastructure, offline basemap acquisition, 3D32GIS, a non-spatial chart or dashboard, or maintenance of an existing custom web application.3334## Update preflight3536At the beginning of each Skill invocation, run the official-release preflight from the Skill root37using the validated 24-hour cache when available. This check never modifies the installation:3839```powershell40python scripts/update_skill.py --preflight41```4243After installation, the equivalent command is:4445```powershell46interactive-map-builder update --preflight47```4849Read the returned JSON rather than relying on the command exit code. Report only an available update or a failed check; keep a current cached result silent. `--preflight` remains non-fatal for the calling Agent and never applies an update.50Handle statuses as follows:5152- `current` or `local_newer`: continue with the map task;53- `manual_update_required` or `update_apply_failed`: disclose the confirmed latest version and the54 reason before continuing;55- `update_check_failed`: say that the official latest version could not be confirmed, then continue;56- `disabled`: state that `IMB_DISABLE_AUTO_UPDATE` disabled the preflight.5758Applying an update is a separate, explicit maintenance action with `update --apply` or the legacy59non-fatal `update --auto` mode. Those commands retain checksum, manifest, local-change, duplicate-root,60and rollback safeguards; normal map construction never modifies its own running Skill.6162## Conversation guidance6364For Codex only, a complex request may benefit from Plan mode when it has multiple independent65layers, more than one blocking design choice, or several coordinated deliverables. Mention this66once in the first response as an optional convenience, then continue with inspection whether or67not the user switches modes. Do not recommend Plan mode for a clear single-layer task, do not cite68client keyboard shortcuts, and never make a mode change a prerequisite.6970A portable local `map.html` is the default delivery. Generate slide or paper figures only when the71user explicitly asks for them; “make a website,” “make a map,” or “send it to colleagues” does not72enable static presets. Sending the HTML file is not the same as publishing it on the internet.73Do not offer, promise, or ask about a public URL unless the user explicitly requests deployment.74When they do, finish the map first and treat hosting as a separate workflow that confirms the75target platform and permission to expose the embedded data.7677## Visual guidance7879Use Atlas Studio Light as a starting point, not as an automatic design service. Leave low-level80visual values omitted when the user has not expressed a preference: the packaged resolver will use81geometry family, coarse density, template role, and stable draw order. Explicit user or Agent82MapSpec values always win. Do not invent planning semantics from field names, do not assign more83than eight automatic categorical colors, and do not add themes, clustering, heatmaps, or other84representations merely to make the page look busy.8586After the first verified build, inspect the actual page. If the visual hierarchy still conflicts87with the user's purpose, propose a small concrete refinement—such as reducing one point layer,88muting a context layer, or changing an explicitly understood category palette—then rebuild. The89engine should provide an overall coordinated result; project-specific polish remains a conversation90between the user and Agent. Read [design-guidelines.md](references/design-guidelines.md).9192## Workflow93941. Inspect inputs before proposing a map.9596 ```powershell97 python scripts/map_builder.py inspect <input> [<input> ...] --output inspection.json98 ```99100 Read [supported-inputs.md](references/supported-inputs.md) for GeoPackage, Shapefile ZIP,101 CSV, Excel, encoding, and field-mapping rules.1021032. Present one compact summary per layer: feature count, geometry type, CRS, likely ID, label, and104 category fields, template candidates, and whether confirmation is required.1051063. Maintain this Markdown requirements checklist while choices remain unresolved:107108 ```markdown109 - [x] Confirmed: ...110 - [~] Inferred: ...111 - [ ] Needs confirmation: ...112 ```113114 Derive it from the request and inspected data. Keep inferred decisions visible and easy to115 correct. Resolve the template from the user's stated outcome: independent layer switches mean116 `multilayer`; an explicitly named primary record list means `map-list`. Multiple layers alone117 do not require another user turn. Pass the resolved template and, for map-list, primary layer118 explicitly to the CLI; `--template auto` remains conservative when intent is unavailable.119120 Ask one consolidated round only for genuine blockers: unknown CRS or geometry mapping,121 ambiguous category meaning, an unresolved primary layer, destructive data changes, or public122 exposure. Never guess a missing CRS or invent domain meaning. Treat reversible presentation123 choices (title, layout, context opacity, visible display fields) as visible defaults that can124 be refined after the first verified build. Respect any choice the user explicitly reserves.125 Build after no blocking `[ ]` item remains. Do not ask the user to repeat resolved choices.1261274. Initialize `map_spec.json`, then apply confirmed choices. Read128 [map-spec.md](references/map-spec.md); the canonical Schema is129 `scripts/mapcore/resources/map-spec.schema.json`.130131 ```powershell132 python scripts/map_builder.py init-spec inspection.json --template map-list --primary-layer <id> --locale en-US --output map_spec.json133 ```1341355. Download ArcGIS FeatureServer data before building. Read [arcgis.md](references/arcgis.md).136137 ```powershell138 python scripts/map_builder.py fetch-arcgis --url <layer-url> --out data/source.geojson139 ```1401416. Build once from the resolved specification. Add `--bundle-sources` only when the user wants a142 portable rebuild bundle and accepts copying source data.143144 ```powershell145 python scripts/map_builder.py build --spec map_spec.json --out dist146 ```1471487. Verify, inspect `build_report.json`, and open `map.html`.149150 ```powershell151 python scripts/map_builder.py verify --dist dist152 ```1531548. Exercise search, filters, sorting, layer visibility, basemap switching, hover and click linkage,155 keyboard selection, control-panel collapse, and narrow-screen layout. Confirm that every visible156 control produces an observable result, the focal layer reads first, dense symbols remain legible,157 and HTML/static colors agree. Read [design-guidelines.md](references/design-guidelines.md).1581599. For legacy anonymous basemaps, use `migrate-basemaps --spec old.json --out migrated.json`160 after confirming replacement of the old presets. It leaves the original and custom URLs intact.161 Read [basemaps.md](references/basemaps.md). Build/verify do not prove live basemap availability:162 inspect real file:// output online before claiming the backdrop works. Missing-key, local-OSM,163 WebGL and network failures must leave business controls usable and show a localized reason.16416510. Deliver the whole `dist` directory. Summarize repairs, generated IDs, null display values,166 simplification, performance warnings, online basemaps, font fallback, portability, and source167 attribution.168169Use the quick path for one unambiguous layer, or after resolving the template from the user's170intent and supplying it explicitly (plus `--primary-layer` for a multilayer map-list):171172```powershell173python scripts/map_builder.py run <input> --output dist174```175176Follow the user's conversation language independently of the map audience. Set the map locale to177`en-US` or `zh-CN`; use `en-US` when the audience is not specified.178179Install the deterministic engine once, then run the offline self-check. The base installation180supports vector/CSV inputs and all existing map styles and static outputs. For Excel input, install181`python -m pip install ".[excel]"` from the Skill root; `".[all]"` installs all supported readers.182Inspect/build will name a missing Excel reader and the installation command rather than guessing:183184```powershell185python -m pip install .186interactive-map-builder doctor187```188189Use the installed `interactive-map-builder` command for package-level `doctor`, `update`, and190`--version`. In a source checkout where that command is unavailable, use191`python scripts/cli.py doctor`. `python scripts/map_builder.py` is the internal deterministic192builder and intentionally lists only inspect/init-spec/fetch/build/verify/run; never infer from that193help output that the package lacks `doctor`. Check the installed version and command path before194falling back to build-plus-verify. A passing `doctor` result verifies package resources, local data195loading, map construction, and output hashes without downloading data or basemap tiles.196197## Template choice198199- Choose `map-list` for one explicitly identified primary layer plus optional context layers.200- Choose `multilayer` when independent layer visibility and cross-layer inspection are primary.201- Treat `linked_view` as experimental. Add it only when records already contain meaningful x/y202 variables; read [linked-analysis.md](references/linked-analysis.md) and never invent quadrants,203 thresholds, or statistical interpretations.204205## Non-negotiable checks206207- Fail when data is unreadable or empty, CRS is missing, repaired geometry remains invalid or208 empty, final IDs are blank or duplicate, or a configured field does not exist.209- Fail on unknown non-null categories, unsafe archives, ArcGIS pagination mismatches, output count210 mismatches, or path escape.211- Treat display-field nulls, generated IDs, repaired geometry, missing source notes, absent CJK212 fonts, online basemaps, simplification, and large outputs as warnings.213- Use `<layer_id>::<feature_id>` for multilayer runtime identity. Allow cross-layer linkage only214 through an explicit `link_key`.215- Preserve official geographic names and spellings from the source. Localize generic interface216 text, not place names.217- Preserve user geometry. Repair invalid geometry or simplify for an explicit performance need,218 report the operation, and never reshape or discard features merely to improve appearance.219- Escape all user-provided text before embedding it in HTML.220- Preserve explicit MapSpec visual values. Let Atlas Studio Light fill only omitted values, and keep221 its geometry, density, role, order, and state plan visible in `build_report.json`.222- Never cycle an automatic categorical palette beyond eight classes; retain filtering and ask the223 user how to group or emphasize a larger classification.224225## Output contract226227Always return `map.html`, resolved `map_spec.json`, `inspection.json`, `build_report.json`,228`DELIVERY_MANIFEST.json`, and `README_USAGE.md` in the selected locale. Static output is opt-in: generate229`map_slide_16x9.png` only when the user requests a slide figure and enable the paper preset only230when the user requests paper PNG/SVG/PDF. Never expand an HTML-only request into static files.231Treat an unbundled `map_spec.json` as a build record; promise an independent rebuild only when232sources were bundled. Public hosting is not part of this output contract.233234## Sharing an explored view235236When the user wants a colleague to open the map at the current search/filter/view, use the page's237**Share view** control after verifying that state. Download the HTML snapshot for direct opening,238or export/import view JSON for the same data/configuration. Read239[view-state.md](references/view-state.md). A snapshot contains all embedded data, including filtered240and hidden objects; filters do not redact data. Keep the manifest-controlled original `dist`241unchanged. Browser exports are separate artifacts, not newly verified build bundles. Named local242bookmarks and other browser history are not included. Public hosting remains a separate workflow.243244## Resources245246- Read [wizard-flow.md](references/wizard-flow.md) for non-expert setup.247- Read [update-policy.md](references/update-policy.md) for verified updates, supported installation248 types, rollback behavior, and the opt-out.249- Read [data-provenance.md](references/data-provenance.md) for remote or redistributable data.250- Use the public generated demos linked from the repository README for visual reference. The lean251 Skill release package intentionally excludes demo datasets, screenshots, tests, and CI files.252- Run `python scripts/map_builder.py ...` from the Skill root before installation; use the253 installed `interactive-map-builder ...` CLI afterward.