Creating Plugins With AI
Use BTT's Plugin Creator / Editor skills to create or change a plugin. Before generating any code, the assistant should load the matching reference from your running BTT. That reference contains the API and examples available in that build.
Choose the Reference
| Plugin | Reference tool |
|---|---|
| Launcher | retrieve_launcher_plugin_reference |
| Action | retrieve_action_plugin_reference |
| Floating Menu Widget | retrieve_floating_menu_widget_plugin_reference |
| Stream Deck | retrieve_stream_deck_plugin_reference |
| Touch Bar | retrieve_touch_bar_plugin_reference |
| Trigger | retrieve_trigger_plugin_reference |
| JSON Action | retrieve_json_action_plugin_reference |
JSON action plugins combine existing BTT actions with form fields, and they can include scripting or network actions. Choose Swift if the plugin needs native views or a persistent object with lifecycle callbacks.
Swift Workflow
- Read the matching reference. For an existing plugin, read its current source and keep its identifier and configuration keys unchanged.
- Use the exact protocol signatures from
BTTSwiftPluginHeader.h. Keep metadata in the first 50 lines and the principal class declaration on one line. For SwiftUI state, use the compatibleStateproperty-wrapper alias so the source also compiles with standalone Command Line Tools whose macOS 27 SDK cannot loadSwiftUIMacros. See Swift Source Plugins. - For a new file, call
compile_swift_pluginwithsource_codeandplugin_file_name. For an existing file, make targeted edits and then call it withswift_file_path. - Read the compiler diagnostics and fix any errors, including “nearly matches optional requirement” warnings. Those warnings can mean that BTT never calls the method.
- After
SUCCESS:, configure the plugin in BTT and check that it behaves as expected. A successful compile and load doesn't tell you whether the configuration is saved correctly, or whether keyboard handling, timers, and hardware events work.
The compile tool handles file-watcher suppression. Adding BTT-AI-Managed to the source doesn't suppress prompts in the current loader. Passing source_code directly also avoids an extra layer of JavaScript string escaping.
For Launcher plugins, check stable result IDs, saved-instance editing, async results, keyboard commands, and surface cleanup. Parse arguments with the per-item host query helper in both previews and actions, and leave context.query as the full input. A surface refresh only updates chrome and layout. To change the content, update the retained view or observable model.
JSON Workflow
- Build a valid JSON object that contains metadata, flat form definitions, and an action array. Use a stable
BTTPluginIdentifierand unique field IDs. - Look up each action with
lookup_btt_action_definition. Keep the exact key locations and value encodings. - Put
@@@fieldID@@@placeholders inside JSON strings. Substitution inserts escaped text, not typed JSON or evaluated expressions. - Validate a concrete copy of the action array with
validate_btt_trigger_json, using realistic form values. Check the metadata and form definitions separately. - Save the
.bttjsonpluginfile, select it in BTT, save its configuration, and check that it runs correctly. JSON plugins don't usecompile_swift_plugin.
See JSON Action Plugins for supported fields, missing-value behavior, and a complete example.
Tool Availability
Which tools are available depends on the active skills and the installed BTT version. If the reference or compile tools are missing, enable the matching creator/editor skill. Inside BTT's run_javascript, ai.getAvailableTools() lists the tool functions available in that JavaScript context. Other AI clients should use their connected BTT tool list. Don't assume a helper exists if it isn't listed.
For trigger and action configuration around the plugin, follow the JSON configuration workflow.