All skills
dmccreary avatar

/add-xapi-events-to-microsim

@d493f4f

Use when the user wants an existing MicroSim or chapter quiz to record what students do with it. Typical requests are "add xAPI events", "add tracking or analytics", "make this sim feed the LRS or LRS-Lite", "instrument chapter 5's sims", or "what should this sim record?". Use it even if they never say "xAPI". Not for building a new MicroSim (use microsim-generator) or for LRS backend work.

  • 27 files
  • 234.6 KB
  • Updated 5 days ago
  • GitHub

Use this Skill: https://skilld.dev/gh/dmccreary/claude-skills/add-xapi-events-to-microsim

This session only. Nothing lands on disk.

referencesadaptersleaflet.md

≈715 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Adapter: Leaflet maps

Status: UNVERIFIED. Drafted from the Leaflet 1.9 API. Pilot: food-science/docs/sims/world-fermented-foods-map. There are 48 sims.

Applies when: main.html loads leaflet.js (L.map).

Getting the map

Leaflet has an official hook, so no constructor wrapping is needed. Register it before the sim creates its map (a script loaded after leaflet.js and before the sim):

window.__lrsMaps = [];
L.Map.addInitHook(function () { window.__lrsMaps.push(this); });

Markers: hook L.Marker.addInitHook the same way, or iterate map.eachLayer(l => l instanceof L.Marker && …) after the sim has added them.

Events

Student act Event Class Call
Click a marker / feature marker.on('click') or the layer's click 2 placeItem(name).study('click')
Open a popup (the usual designed act) map.on('popupopen', e), e.popup._source is the marker 2 use either click or popupopen, not both (one act)
Zoom zoomend, map.getZoom() 1 zoomEv.input(map.getZoom()), min/max = map.getMinZoom()/getMaxZoom()
Pan moveend usually not evidence on its own
Layer control toggle overlayadd / overlayremove / baselayerchange 3a `press('show'

zoomend and moveend also fire on programmatic setView, fitBounds and flyTo, including the initial view at load and every "fly to this place" button the sim offers. Filter them with a user-intent flag:

let userGesture = false;
map.getContainer().addEventListener('pointerdown', () => { userGesture = true; }, true);
map.getContainer().addEventListener('wheel',       () => { userGesture = true; }, { capture: true, passive: true });
map.on('zoomend', function () {
  if (!userGesture) return;                // setView / fitBounds / flyTo from code
  userGesture = false;
  zoomEv.input(map.getZoom());
});

The zoom +/- control buttons are inside the container, so they count as user gestures. That's correct.

Object keys and concepts

  • A place: #place-{slug(name)}, from the data's name field, never from coordinates or marker order.
  • Map places are usually examples, not concepts. Most sims map every place to the page concept or a small set of category concepts (e.g. by food type). Do that only when the learning graph has those categories.

Traps

  • Tile loading generates no events you care about. Ignore load/tileload.
  • A marker click that opens a popup fires both click and popupopen. Pick one.
  • Leaflet needs its container height set explicitly. Put the xAPI panel outside the map container.

check-xapi actions

[
  {"wait_for": ".leaflet-marker-icon"},
  {"click": ".leaflet-marker-icon", "nth": 0},
  {"click": ".leaflet-control-zoom-in"},
  {"wait": 400}
]

Source: SKILL.md on GitHub

No third-party reports yet.

Signed by skilld at d493f4f. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 19 hours ago.

Activeupdated 5 days ago
metadata
{
  "ibook.version": "0.2",
  "ibook.preferred-model": "opus"
}

README badge

README badge for dmccreary/claude-skills/add-xapi-events-to-microsim