Skip to main content
Follow along with the runnable example. This guide walks through the App control example in corti-examples — bootstrap your build from it or use it as reference.
The Commands guide dispatches recognized commands to text actions in an editor. App control applies the same declare → event → dispatch loop to the application itself — switching tabs, opening panels, clicking buttons, confirming dialogs. The reusable idea is an app-control registry: the application-layer analog of the EditorAdapter. Your app registers its actionable UI as named controls; command dispatch resolves a spoken target to a control and runs it — gated by whether that control is available right now.
This guide assumes you’ve read Commands — declaring commands in the config and handling the command event work exactly the same here.

Register your app’s controls

Each actionable piece of UI registers itself as a control with a spoken label, a kind, a run effect, and optionally isAvailable() (for contextual commands) and getState() (for app awareness).
JavaScript
The registry resolves a spoken target to a control by matching its label, aliases, or id — stripping filler words like the, panel, button so “open the details panel” resolves to the details control.

Declare the commands

Declare the command set as usual. Use enum variables for finite target sets (tabs, panels) and verb-led full phrases for buttons — they recognize more reliably than a generic click {button} slot and are more natural to speak.
JavaScript

Route commands to controls

Handle the command event and route each id to registry.run(target, arg). The registry resolves the target, checks isAvailable(), and runs the control — so contextual gating (e.g. confirm only while a dialog is open) lives with the control, not the command handler.
JavaScript

Application awareness

Because every control exposes isAvailable() and getState(), the registry can produce a live snapshot of what’s on screen and actionable — useful for a debug overlay, or to make commands contextual.
JavaScript
Availability gating prevents surprising actions — a spoken “confirm” does nothing unless a dialog is actually open. Register controls with accurate isAvailable() and the command surface adapts to app state for free.

Web or native

The registry is DOM-agnostic — it only knows label, run, and the availability/state hooks. The same registerresolverun contract can be implemented by a desktop or OS host over an IPC bridge, so your command-and-control logic runs unchanged against a web UI or a native application.

Next steps

Commands

The declare → event → dispatch loop these app-control commands build on.

Dictation Box

Move text between a scratch box and your form fields by voice.

Example code

The complete, runnable App control example in corti-examples.
Please contact us for help or questions.