mcpField
C
create-interface-skill

create-interface-skill

github.com/humansignalDesign & UI3146 installsUpdated 2w ago
Repository

About create-interface-skill

create-interface-skill guides creation of HumanSignal labeling interfaces as JSX modules for Label Studio. It is for interface authors and emphasizes schemas, domain-specific reference modules, and compatibility with the labeling shell.

Key features

  1. 01Create a single-file JSX interface module
  2. 02Define input and output schemas
  3. 03Use domain-specific interface references
  4. 04Follow theme and accessibility requirements
  5. 05Sync interfaces through label-studio-sdk

Use cases

  1. 01Build a text classification interface
  2. 02Create named-entity or spatial annotation screens
  3. 03Implement audio or video timeline labeling

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/humansignal/create-interface-skill --skill create-interface-skill

After installing, type/create-interface-skillin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

README.md
agents/
openai.yaml
references/
example-audio.md
examples.md
example-classification.md
example-spatial.md
example-ner.md
core-contract.md
schemas-spatial.md
reference.md
schemas.md
video-timeline.md
text-spans.md
styling-a11y.md
video-frames.md
spatial-bounding.md

Details

From the project README

Create Labeling Interface

Create a HumanSignal Interface: one JSX source file (Screen.jsx) whose final expression is a parenthesized object literal with a default React component and optional exports such as getResults, parseResults, paramsSchema, outputSchema, and hotkeys.

This is the JSX-based Interfaces runtime. Do not use the older <ReactCode> XML tag format unless the user explicitly asks for ReactCode.

Source of truth

The files under references/ are rendered from the same modules the in-app "Create with Agent" assistant sends to its model. They are authoritative. Follow their module contract, schema rules, pre-submit checklist, region contract, and styling/accessibility requirements exactly.

Mandatory read order

  1. Read references/core-contract.md end-to-end. It is the base contract for every interface, including the pre-submit checklist.
  2. Read references/schemas.md and references/styling-a11y.md. Every interface needs schemas and must support light and dark mode through design-system tokens.
  3. Read the domain module(s) matching the request, and the matching complete example to adapt:
ReferenceCovers
references/core-contract.mdResponse/output format, defensive coding, pre-submit checklist, edit tools, dynamic screen module, params, accessibility basics, and task-data access.
references/text-spans.mdAbsolute-offset text highlighting, NER/entity spans, and selection-offset helpers.
references/spatial-bounding.mdSpatial region persistence, ShellRegion shape, visibility/lock state, AnnotationResult shape, image navigation & selection tools (select, pan, zoom, fit / 100%), and ranking/ordering (legacy DIY only when Interface Components are off).
references/video-frames.mdSeek-safe HTML5 video FPS probing and stable frame counters for timeline navigation (FIT-2803).
references/schemas.mdinputSchema, outputSchema syntax, required output fields, dependsOn, and parseResults.
references/schemas-spatial.mdMulti-select image URLs, spatial keypoint schemas, and PDF OCR / bounding box schemas.
references/example-classification.mdA full Sentiment Analysis / Text Classification screen module example.
references/example-ner.mdA full Named Entity Recognition (NER) screen module example.
references/example-audio.mdAudio/waveform time-span regions with shell relation anchors and correct serialization (FIT-2247).
references/example-spatial.mdA full Image Bounding Box / Spatial screen module example.
references/video-timeline.mdProbe real fps on load via EditorDeps.video, keep frame counts monotonic, and never clip annotation frames to a 24fps fallback (FIT-2804).
references/styling-a11y.mdTheme-aware tokens, typography, spacing, components, layout, and interaction/accessibility rules.
  1. Read only the references/reference.md sections you need (start with Schemas & sample data whenever the UI reads task.data). Open references/examples.md only when reference.md sends you there.

Runtime notes for local authoring

  • Injected globals. Beyond the React / hooks / getField globals listed in core-contract, the sandbox injects EditorUI (the @humansignal/ui namespace) and EditorDeps (e.g. EditorDeps.audioDecoder.WasmStreamingDecoder, EditorDeps.video.probeFrameRate).
  • Do not reference window.InterfaceComponents (AudioCanvas, useComponentHotkeys) — they are gated behind fflag_interfaces_components, which is off. Build audio interfaces with EditorDeps.audioDecoder.WasmStreamingDecoder as shown in core-contract and example-audio, and ignore any InterfaceComponents recipes in reference.md.
  • EditorUI two-path trap. EditorUI is injected only inside the runtime iframe, not in the admin-time eval that extracts paramsSchema. A top-level EditorUI reference throws EditorUI is not defined and silently breaks paramsSchema in Labeling Settings. Reference it inside render only, or omit it and use inline styles with design tokens.
  • Shell-owned behavior. The labeling shell owns Submit/Update, undo/redo/reset, the Regions/Info/Relations panels, region visibility, and comments. Drive them through the props and callbacks in core-contract and spatial-bounding (addRegion, updateRegion, deleteRegion, selectRegion, selectedRegionIds, hidden/locked state). Do not re-implement them in the screen: a custom Delete button, local-only region state, or ignoring hidden state breaks the shell's panels and history.
  • Compiler extraction. The compiler turns the last parenthesized object literal into the module export. If the file does not end with a bare ({ default: ... }), the editor rejects it with "Module missing 'default' function export."
  • No persistent storage. localStorage / sessionStorage are in-memory shims that reset on every iframe remount; persist only through the mutation callbacks and annotation results.
  • Sample data. Keep task.json compact and use the exact default task-data paths from every dataField in paramsSchema / inputSchema.
  • Saving to Label Studio. Create or update the interface only with label-studio-sdk interface sync <dir> --title "<Title>" --publish (new interface; add --workspace <id> when needed) or label-studio-sdk interface sync <dir> --message "<change>" (existing one, tracked by the sidecar file; that creates an unpublished draft, so add --publish when new projects should use it). sync extracts inputSchema / outputSchema / paramsSchema from the module and stores them with the code. Never POST / PATCH /api/interfaces/ yourself: the server cannot read the schemas from the code, so a hand-built request saves an empty output_schema / input_schema without any error, and projects created from the interface lose their Data Manager annotation filters. After syncing, confirm GET /api/interfaces/<id>/ returns a non-empty output_schema.

Comments

Markdown supported