Skip to main content
Every command has a JSON form: its name and its input. commands() lists them for a model, and run takes a model’s call back to the editor. The examples call the handle editor. See Get the handle.

run()

Runs any command by its name, group.verb, with its input. run({ command: 'menu.select', input: { item: 'FILTER' } }) is menu.select({ item: 'FILTER' }): the same rules, the same Promise, the same errors.
string
required
The command’s name, as commands() lists it: 'history.undo', 'menu.select', 'read.state'. A name the handle doesn’t have rejects with INVALID_COMMAND, and props is ['command'].
unknown
The command’s input, checked against its schema. A command that takes nothing takes no input, or {}.
A read through run waits its turn in the queue, after the commands called before it, and resolves to its value.
run.ts

commands()

Lists every command run takes in this edition:
string
Its name, run’s command.
string
What it does, written for a model to read: what it does, as which control, when it rejects, and an example call.
Record<string, unknown>
Its input as a JSON Schema (draft 2020-12, with no $schema key, which some model providers reject), always an object: one with no properties for a command that takes nothing.
commands() lists menu.select as:
commands.json
The list holds only what this edition runs: in the Free and the Lite, the Full’s commands are left out.

Give a Model the Editor

Map commands() to the model’s tools, and run each tool call it makes with run. This example is for the Claude API’s tool use. For another model’s API, map the same list to its own tool format.
tools.ts
Send tools with the request. For each tool_use block in the model’s reply, send await runTool(block) back in the next user message.
  • An error tells the model what to fix. INVALID_COMMAND names the input’s paths, and each description ends with an example call.
  • Calls run in order. The commands queue, so the calls of one reply run in the order you pass them to runTool, each after the image is on screen and the user’s hand is off.
  • Values are the saved state’s. read.state and read.size tell the model what the image holds and in which px, in the units every command takes.
  • Leave out what the model shouldn’t call. The example filters commands() before it maps it: output.save, output.exportFile and read.screenshot resolve to a File, which doesn’t travel as JSON, and editor.close closes the editor. Filter anything else the same way.
  • Show the model the photo as an image. Call read.screenshot() yourself and send the PNG it gives, in base64, as an image block in the next user message.