modify-stream-deck
Skill2 starsChanged 2 months agoMITView on GitHub
Inspect, back up, repair, and customize Elgato Stream Deck profiles, buttons, hotkeys, multi-actions, toggles, labels, and icons. Use when a user asks to configure Stream Deck keys, make a button type and submit text, launch an app or URL, trigger dictation, fix a button that behaves differently from a physical keypress, or package a repeatable Stream Deck layout. Skip Stream Deck SDK plugin development unless the task also requires profile wiring.
We split this skill into the rules it gives an agent
16 rules. About 0 are common, 11 are distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈11
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 18
Create or select a 144 × 144 icon with a short label and one dominant symbol.
- Very specific: line 19
Write a declarative spec and preview it with apply --dry-run.
- Distinctive: line 22
Do not live-fire a button in a consequential field.
- Distinctive: line 28
Treat button presses as real user input.
- Distinctive: line 29
Keep credentials, account identifiers, device serials, profile UUIDs, logs, and live manifests out of public examples.
- Distinctive: line 30
Prefer built-in Stream Deck actions.
- Very specific: line 32
Do not assume Stream Deck can reproduce a physical keypress.
- Very specific: line 33
Every generated V3 action, including steps inside a Multi Action lane, needs a complete action shell with ActionID, Plugin, and Resources.
- Distinctive: line 35
If the app rewrites the file, restore the backup and use the visible Stream Deck editor instead of racing the process.
- Distinctive: line 46
Read references/profile-format.md when diagnosing profile discovery, pages, image paths, or raw V3 action JSON.
- Distinctive: line 50
If generated keys render but show ⚠️ when pressed:
- Very specific: line 52
Check whether a V3 Multi Action incorrectly stores steps in the legacy Settings.Routine and Settings.RoutineAlt fields.
- Distinctive: line 85
NO plus physical Return;
- Distinctive: line 86
NO plus a hands-free dictation toggle.
- Very specific: line 113
every generated action shell contains the matching runtime Plugin descriptor.
- Distinctive: line 116
every referenced icon exists and is 144 × 144.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Modify Stream Deck
Safely change the user's live Stream Deck profile while preserving unrelated buttons and a recoverable pre-change copy.
Workflow
- Confirm the requested device, page, button coordinates, and press behavior. Infer coordinates only after inspecting the active page.
- Locate the profile root. On macOS, start at
~/Library/Application Support/com.elgato.StreamDeck/ProfilesV3. - Inspect the bundle manifest and page manifests. Run
scripts/streamdeck_profile.py discoverorinspect; never choose a page from its UUID alone. - Translate each requested press into explicit actions. Use
submit_textfor “type text, then press Enter.” Do not rely on the Text action'sisSendingEnterflag in terminal and coding-agent prompt fields. - For focus-safe dictation, build background start and stop app wrappers with
scripts/create_background_protocol_app.py, then useopensteps for those app bundles. Do not send a dictation URL directly when the user wants to keep typing into the focused field. - Create or select a 144 × 144 icon with a short label and one dominant symbol. Give toggle states different colors or symbols.
- Write a declarative spec and preview it with
apply --dry-run. Read references/spec-format.md for the accepted action types. - Apply with
--restart-app. The helper copies the entire.sdProfilebundle before the atomic manifest replacement. - Validate JSON, preserved coordinates, installed image dimensions, V3 Multi Action lanes, and
Plugindescriptors. Stream Deck can render a key's icon yet show ⚠️ when its runtime action shape is invalid. - Do not live-fire a button in a consequential field. Use a blank text editor or ask the user to press it. A successful JSON write does not prove the receiving app accepted the keystrokes.
Safety rules
- Back up the full profile bundle before every write. Stop if a backup cannot be created.
- Preserve every coordinate outside the requested set. Compare before and after summaries.
- Treat button presses as real user input. Never test Enter, delete, send, publish, payment, or destructive shortcuts against the user's active app.
- Keep credentials, account identifiers, device serials, profile UUIDs, logs, and live manifests out of public examples.
- Prefer built-in Stream Deck actions. Add a custom plugin only when built-ins cannot express the behavior.
- Preserve the frontmost app and focused control when an action should type or dictate there. URL schemes can activate their owning app and move focus.
- Do not assume Stream Deck can reproduce a physical keypress. Modifier-only combinations and Apple's
Fnmodifier are not reliable Hotkey-action inputs. - Every generated V3 action, including steps inside a Multi Action lane, needs a complete action shell with
ActionID,Plugin, andResources. - Prepare and validate the replacement manifest before stopping Stream Deck. Replace it atomically, then allow the app to reload.
- If the app rewrites the file, restore the backup and use the visible Stream Deck editor instead of racing the process.
Action choices
- Type only:
text. - Type and submit:
submit_text, which runs Text followed by a physical Return hotkey. - Single shortcut:
hotkey. - Open a page or app protocol:
urloropen. - Several ordered actions:
sequence. - Alternate between start and stop:
toggle_sequencewith separate icons.
Read references/profile-format.md when diagnosing profile discovery, pages, image paths, or raw V3 action JSON. Read references/spec-format.md before writing a new spec or adding an action type.
⚠️ on press
If generated keys render but show ⚠️ when pressed:
- Check whether a V3 Multi Action incorrectly stores steps in the legacy
Settings.RoutineandSettings.RoutineAltfields. - Move the two sequences into top-level
Actionslanes. Each lane has anActionsarray. - Give each nested step a complete V3 shell with
ActionID,Plugin,Resources,Settings,State,States, andUUID. - Compare provider metadata against the installed Stream Deck version, restart Stream Deck, and ask the user to test one harmless key.
Stream Deck 7.4 rendered icons for legacy V2 Routine data inside a V3 profile, then rejected every affected key at execution time. The helper now writes V3 action lanes and complete nested steps.
Focus-preserving dictation
For supported dictation apps, create one background application for the start URL and one for the stop URL:
python3 scripts/create_background_protocol_app.py \
--display-name "Dictation Start" \
--url "example-dictation://start-hands-free" \
--output-dir "$HOME/Applications"
python3 scripts/create_background_protocol_app.py \
--display-name "Dictation Stop" \
--url "example-dictation://stop-hands-free" \
--output-dir "$HOME/Applications"Each compiled .app is a background-only wrapper that runs open -g -u. It sends the protocol without taking the frontmost application or focused control. Use open steps that target those wrappers in both toggle lanes. Keep the user's physical Fn shortcut unchanged.
Do not use a modifier-only shortcut. Stream Deck has no normal key event to send. Do not use a push-to-talk binding for a toggle: Stream Deck releases the key immediately, so dictation stops immediately. A .command file selected by Stream Deck's Open action was not reliable in Stream Deck 7.5; use the compiled .app wrapper instead.
For a button that types before dictation, put the Text step first and the background Start app second. Do not add app activation, window selection, or textbox discovery.
Bundled example
assets/four-button-coding.json demonstrates a privacy-safe layout:
- YES plus physical Return;
- NO plus physical Return;
- NO plus a hands-free dictation toggle;
- a standalone TALK/STOP toggle.
The example uses placeholder coordinates and background wrappers at ~/Applications/Dictation Start.app and ~/Applications/Dictation Stop.app. Build the wrappers with the registered start and stop URLs for the user's dictation app. Inspect the user's page and adjust coordinates to avoid overwriting buttons they want to keep.
Commands
python3 scripts/streamdeck_profile.py discover
python3 scripts/streamdeck_profile.py inspect --manifest /path/to/page/manifest.json
python3 scripts/streamdeck_profile.py apply \
--manifest /path/to/page/manifest.json \
--spec assets/four-button-coding.json \
--dry-run
python3 scripts/streamdeck_profile.py apply \
--manifest /path/to/page/manifest.json \
--spec assets/four-button-coding.json \
--restart-appCompletion gate
Finish only when:
- the pre-change
.sdProfilebackup exists; - the edited manifest parses;
- requested coordinates contain the intended action UUIDs and settings;
- every generated action shell contains the matching runtime
Plugindescriptor; - Multi Actions use top-level V3 action lanes instead of legacy
Settings.Routinefields; - untouched coordinates match the pre-change manifest;
- every referenced icon exists and is 144 × 144;
- Stream Deck is running and its recent log has no profile-load error;
- focus-safe dictation wrappers exist and the generated Open Application actions point to them, if the request includes dictation;
- the user has one safe, concrete button test to perform.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

