| name | openhome-abilities |
| description | Create, improve, package, and publish OpenHome abilities, especially Local Connect abilities with local helpers and community-ready GitHub repositories. |
OpenHome Abilities
Use this plugin when the user wants to create, improve, upload, package, document,
or publish an OpenHome ability or capability.
Default Workspace
- Put new ability repositories under
~/Code/Openhome/<ability-slug>.
- Use one GitHub repository per shareable ability.
- Prefer obvious public repo names like
openhome-izone, openhome-hue,
or openhome-home-assistant.
- Keep reusable implementation artifacts in the ability repo, not in temporary
home-directory scratch files.
Docs Refresh
OpenHome SDK and dashboard behaviour can change. For new or non-trivial ability
work, refresh against the official docs:
https://docs.openhome.com/ability
https://docs.openhome.com/building-abilities/how-to-build
https://docs.openhome.com/building-abilities/local-connect
https://docs.openhome.com/api-sdk/api-reference
https://github.com/openhome-dev/abilities/tree/dev/templates
Use official docs and templates as the source of truth when there is a conflict.
Ability Shape
The OpenHome dashboard expects custom ability uploads to be a zip with exactly
one top-level directory. Do not upload loose files at the zip root.
Correct zip shape:
example-ability/
main.py
__init__.py
README.md
Wrong zip shape:
main.py
__init__.py
README.md
The files inside that one top-level directory normally come from the repo's
ability/ directory:
main.py
__init__.py
- optional
README.md
In main.py:
- Keep the exact
#{{register capability}} registration tag.
- Use
MatchingCapability, CapabilityWorker, and AgentWorker following the
official templates.
- Set
self.worker and self.capability_worker in call().
- Start async work with
self.worker.session_tasks.create(self.run()).
- Call
resume_normal_flow() in a finally block so OpenHome returns to its
normal conversation flow even after errors.
- Read the full request with
wait_for_complete_transcription().
- Keep spoken responses short and natural.
Local Connect Pattern
For hardware, LAN services, or local files, prefer OpenHome Local Connect via
CapabilityWorker.exec_local_command() instead of trying to reach the local
network directly from the cloud ability.
Recommended pattern:
- Ability gathers transcription and context.
- Ability asks the model for a strict JSON plan.
- Ability passes the JSON plan to a local helper as base64.
- Local helper validates names, ranges, and supported operations.
- Local helper performs the local action and returns JSON.
Do not let the language model generate shell commands. Keep shell commands fixed
and pass only structured data.
Safety And Confirmation
Before the final dashboard Save Ability action, confirm with the user because
it uploads files to OpenHome and creates or updates a cloud ability.
Confirm before any generated ability performs real-world actions unless the user
explicitly asked for that action. Status reads and dry runs are fine.
For smart-home abilities, ask for confirmation before:
- broad inferred changes
- turning off a whole system while zones/devices are active
- closing or disabling multiple areas
- long timers
- weather or optimisation routines that infer settings
Voice UX
Dashboard trigger words matter. Use natural trigger words with at least four
alphabetic characters. Avoid short triggers like AC, because the dashboard
validation can reject them.
Good trigger word examples:
aircon
air conditioning
climate
climate control
heater
cooling
ducted air
Write ability prompts for casual speech, not command-line syntax. Include:
- turn on/off
- status questions
- specific device or zone names
- "make it warmer/cooler" style relative requests translated to absolute values
- quiet/boost modes where the device supports them
- timers
- "only this room" or "all zones" phrasing when relevant
- fallback questions when a name is ambiguous
Dashboard Gotchas
- The dashboard rejects custom zips that do not contain a single top-level
directory. Always run
unzip -l dist/<package>.zip and confirm the first path
component is one directory containing main.py.
- The custom upload button may not visibly change if the same zip filename is
picked twice. Rebuild or copy the package to a fresh filename before retrying.
- The dashboard can show a "No API Keys Selected" modal for abilities that do
not need keys. Proceed only after confirming the ability genuinely needs no
third-party keys.
- Use category
Skill for request/response abilities. Use daemon categories
only for background behaviour.
- Upload a real icon/image. Keep it committed in the repo.
Scaffold Helper
To create a starter repo:
python3 ~/.codex/plugins/openhome-abilities/scripts/scaffold_openhome_ability.py \
openhome-example \
--name "Example Ability" \
--description "Voice control for an example OpenHome integration." \
--local-helper
Then implement the domain-specific local helper and ability prompt before
publishing.
Verification
Before saying an ability is ready:
- Run
python3 -m py_compile over Python files.
- Run the repo's tests.
- Run helper self-tests or read-only status checks where available.
- Run the package script and inspect the zip with
unzip -l; verify it has one
top-level directory and no loose root-level files.
- If using GitHub, push the public repository and include the URL.
- If using the OpenHome dashboard, verify the form shows the custom zip filename
before asking the user to approve saving.