Skill: iDevice
SkillWeb & browsingCreating or modifying interactive devices in public/files/perm/idevices/base/. Every change must ship with colocated Vitest `*.test.js` coverage for edition and export logic, keep patch coverage ≥ 90% on changed lines, include a Playwright spec exercising the iDevice in the workarea and preview, and pass `make fix`, `make test-unit`, `make test-integration`, and `make test-e2e` before submission.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Skill: iDevice skill
What this skill tells your AI
The instructions your AI receives, as published by exelearning/exelearning in .agents/skills/idevice/SKILL.md and read by ahel’s review.
Parent: AGENTS.md | Related: frontend-module, exporter
When to Use
Creating or modifying interactive devices (iDevices) in public/files/perm/idevices/base/.
Key Files
public/files/perm/idevices/base/<name>/— iDevice root directorypublic/files/perm/idevices/base/<name>/config.xml— metadata (title, css-class, category, icon)public/files/perm/idevices/base/<name>/edition/— editor UI (JS + CSS)public/files/perm/idevices/base/<name>/export/— export rendering (JS + CSS)public/files/perm/idevices/base/<name>/*-icon.svg— icon assetpublic/app/workarea/idevices/idevicesList.js— iDevice registrypublic/app/workarea/idevices/idevicesManager.js— iDevice lifecycle management
Reference iDevices (well-tested, good to study): checklist, rubric, geogebra-activity
Structure
public/files/perm/idevices/base/<name>/
├── config.xml # Metadata: title, css-class, category, icon
├── <name>-icon.svg # Icon
├── edition/
│ ├── <name>.js # Editor JS
│ ├── <name>.test.js # Editor tests
│ └── <name>.css # Editor styles (optional)
└── export/
├── <name>.js # Export rendering JS
├── <name>.test.js # Export tests
└── <name>.css # Export styles (optional)
Testing — Round-Trip Is Mandatory
Every iDevice must have a round-trip test: save data → load data → verify all fields are preserved. This is the #1 source of iDevice bugs — fields silently disappear when loadData() doesn't restore what save() stored. Example: PR #1581.
Edition Test Pattern
import { describe, it, expect, beforeEach } from 'vitest';
describe('my-idevice edition', () => {
let idevice;
beforeEach(async () => {
document.body.innerHTML = '<div id="idevice-container"></div>';
idevice = await global.loadIdevice('public/files/perm/idevices/base/my-idevice/edition/my-idevice.js');
});
it('round-trip: save then load preserves all fields', () => {
// Set up editor state
idevice.init(container, { title: 'Test', content: '<p>Hello</p>' });
// Save
const saved = idevice.save();
// Load into fresh instance
idevice.init(container, {});
idevice.loadData(saved);
// Verify ALL fields
expect(idevice.getTitle()).toBe('Test');
expect(idevice.getContent()).toContain('Hello');
});
});
Export Test Pattern
function loadExportIdevice(code) {
const modifiedCode = code
.replace(/var\s+\$myidevice\s*=/, 'global.$myidevice =')
.replace(/\$\(function\s*\(\)\s*\{\s*\}\);?\s*$/g, '');
(0, eval)(modifiedCode);
return global.$myidevice;
}
Commands
npx vitest run public/files/perm/idevices/base/<name>/edition/<name>.test.js
npx vitest run public/files/perm/idevices/base/<name>/export/<name>.test.js
make fix
Gotchas
- Round-trip data loss — the #1 iDevice bug. If
save()stores a field,loadData()must restore it. Always testload(save(data)) === datafor every field. Example: PR #1581. - Legacy metadata formats — old iDevices may store data in fewer fields than current format. Tests must verify both old and new formats work.
- Extra wrapper divs on re-import —
IdeviceRendererwraps text in<div class="exe-text">. If your iDevice stores this HTML and re-imports it, wrappers accumulate. Normalize on import. Example: PR #1559. - Missing
config.xmlor wrong<css-class>— must match folder name convention. - Both
edition/andexport/are required — missing either causes silent failures. - Icon naming — must follow
<name>-icon.svgpattern. - Use
escape()for metadata persistence — some iDevices useescape()for special characters in saved data. Be consistent with the existing pattern.
Done When
-
config.xmlwith correct title, css-class, category, icon -
edition/<name>.jswith.test.jsincluding round-trip test -
export/<name>.jswith.test.js - Icon SVG present (
<name>-icon.svg) - Legacy format compatibility tested if modifying an existing iDevice
- Tests pass via
npx vitest run -
make fixpasses clean
Signals
- GitHub stars
- 142
- Forks
- 32
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
idevice- Source
- github.com/exelearning/exelearning