Declared outputs¶
[profile] output is the list of keys and buttons a profile is permitted to
press. Amri holds every profile to this set. Any key it tries to emit that is not
allowed is dropped before it reaches your virtual input.
Why it exists¶
A profile can run Lua, and Lua can build a key name at runtime. Without a limit, an imported profile could press any key on your machine. The output list is the answer: it is the profile's declared vocabulary of keys, and Amri enforces it at the edge where keystrokes are injected. This is part of how Amri keeps an untrusted profile safe to run. See Trust and grants.
The allowed set is the union of two things:
- Keys Amri can see. When a key name is written plainly in a command, for
example
amri.input.tap('m'), Amri reads it at load time and allows it automatically. You do not have to declare these. - Keys you declare. Everything listed in
[profile] output.
The gotcha: computed keys must be declared¶
If a key name is built from a capture, a variable, or a
value map, Amri cannot see it ahead of time. It only exists once
the command runs. A key like that must appear in [profile] output, or it is
silently not pressed. The command runs, no error is shown, and nothing happens.
This is the most common reason a working-looking command does nothing.
Wrong. The key is assembled at runtime and never declared:
[profile]
output = [] # nothing declared
[[command]]
name = "select_slot"
lua = "amri.input.tap('num_' .. slot)" # 'num_1', 'num_2', ... — dropped
[command.trigger]
pattern = "slot {slot:1..9}"
Right. Declare every key the command can produce:
[profile]
output = ["num_1", "num_2", "num_3", "num_4", "num_5",
"num_6", "num_7", "num_8", "num_9"]
[[command]]
name = "select_slot"
lua = "amri.input.tap('num_' .. slot)"
[command.trigger]
pattern = "slot {slot:1..9}"
Plain keys are allowed automatically
You only need to declare keys that are computed. A literal such as
amri.input.tap('mute') is read at load time and allowed without listing it.
Listing it anyway is fine, and makes the profile a complete record of what it
can press.
The starter profile¶
The shipped starter profile declares its full output list, and its comments explain why. The volume and page commands choose their key inside a bundled Lua helper, so those key names are computed and have to be declared:
[profile]
output = [
"volume_up", "volume_down",
"page_up", "page_down",
"mute", "play_pause", "next_track", "previous_track",
]
The media keys (mute, play_pause, and so on) are written as plain literals in
their commands, so Amri would allow them anyway. They are listed to keep the
field a complete, copy-pasteable example.