Skip to main content
This guide walks you through the complete process of contributing an ability, from forking the repository to getting your PR merged.

Step 1: Fork and Clone

Start by forking the repository on GitHub, then clone your fork:
git clone https://github.com/YOUR_USERNAME/abilities.git
cd abilities

Set Up Upstream Remote

Set up the upstream remote to stay in sync with the original repo:
git remote add upstream https://github.com/OpenHome-dev/abilities.git
Then make sure you have the dev branch locally and start from it:
git fetch upstream
git checkout dev
git pull upstream dev
Why upstream? This ensures you’re always branching from the latest dev on the original repo, not a potentially stale dev on your fork.

Step 2: Create Your Ability Branch

Branch off dev (not main):
git checkout -b add-your-ability-name dev
Use a descriptive branch name like:
  • add-dad-jokes
  • add-pomodoro-timer
  • fix-weather-error-handling
Always branch from dev, never from main. This is critical for our branching strategy.

Step 3: Pick a Template

Choose the template closest to what you’re building:
TemplateUse When
templates/basic-template/Simple ask → respond → done
templates/api-template/You’re calling an external API
templates/loop-template/Interactive / multi-turn conversation
Copy it to the community folder:
cp -r templates/basic-template community/your-ability-name

Step 4: Build Your Ability

Edit main.py in your new folder. Every ability must:
1

Extend MatchingCapability

Your main class should inherit from MatchingCapability
2

Implement register_capability()

Copy the boilerplate exactly from the template - this reads the platform-managed config.json
3

Implement call()

Set up worker + capability_worker and launch your async logic
4

Call resume_normal_flow()

Must be called on every exit path (success, error, user cancellation)
5

Add error handling

Wrap API calls and external operations in try/except blocks
6

Use proper logging

Use self.worker.editor_logging_handler instead of print()
Trigger words are configured in the OpenHome dashboard, not in code. The register_capability boilerplate reads a platform-managed config.json at runtime - you never create or edit that file.

Key Resources

Step 5: Write Your README

Create community/your-ability-name/README.md with this structure:
# Your Ability Name

![Community](https://img.shields.io/badge/OpenHome-Community-orange?style=flat-square)
![Author](https://img.shields.io/badge/Author-@yourusername-lightgrey?style=flat-square)

## What It Does
One or two sentences explaining what this ability does.

## Suggested Trigger Words
- "trigger phrase one"
- "another trigger"

## Setup
- Any API keys needed and where to get them
- Any other setup steps

## How It Works
Brief description of the conversation flow.

## Example Conversation
> **User:** "trigger phrase one"
> **AI:** "Response example..."
> **User:** "follow up"
> **AI:** "Another response..."

Step 6: Test It

Before submitting, thoroughly test your ability:
1

Zip your ability folder

Create a zip file of your entire ability directory
2

Upload to Live Editor

Go to app.openhome.com → Abilities → Add Custom Ability
3

Configure trigger words

Set your trigger words in the dashboard
4

Test all paths

Verify success paths, error handling, and exit commands (“stop”, “exit”, “cancel”)
Make sure resume_normal_flow() is called on all exit paths. Missing this is one of the most common review issues.

Step 7: Sync with Dev Before Submitting

Before you push, make sure your branch is current with the latest dev from upstream:
git fetch upstream
git rebase upstream/dev
If you prefer merge over rebase:
git fetch upstream
git merge upstream/dev
Resolve any conflicts, then continue.

Step 8: Submit Your PR

Commit and push your changes:
git add community/your-ability-name/
git commit -m "Add your-ability-name community ability"
git push origin add-your-ability-name
Open a Pull Request on GitHub:
  • Base branch: dev (not main)
  • Compare branch: add-your-ability-name
  • Fill out the PR template completely
PRs targeting main will be closed and you’ll be asked to re-open against dev.

What Happens After You Submit

1

Automated checks run

validate-ability, path-check, security-scan, and linting must all pass
2

Maintainer review

A maintainer reviews your submission, typically within 3-5 business days
3

Feedback round

You may be asked to make changes. Push additional commits to the same branch - the PR updates automatically
4

Merge to dev

Once approved, a maintainer squash-merges your PR into dev
5

Promotion to main

Periodically, the maintainer team validates dev and merges it into main
6

Marketplace availability

Your ability becomes available to all users on the Marketplace
You don’t need to do anything after step 4. The dev → main promotion is handled by maintainers.

PR Requirements Summary

Your PR must include:
  • All files in community/your-ability-name/ (not in official/)
  • main.py following the SDK pattern
  • README.md with complete documentation
  • PR targeting dev branch
  • All automated checks passing

Common Issues and Fixes

Check the automated check output for specific errors. Common issues:
  • Blocked imports detected
  • Missing resume_normal_flow() calls
  • Using print() instead of editor_logging_handler
  • Files in wrong directory
Sync your branch with upstream dev:
git fetch upstream
git rebase upstream/dev
# Resolve conflicts
git push origin add-your-ability-name --force
Close the PR and create a new one targeting dev. Or change the base branch in the PR settings (top of the PR page).
  • Ensure your zip includes the root folder
  • Check that main.py has no syntax errors
  • Verify trigger words are configured in dashboard
  • Check logs in the Live Editor for errors

Need Help?

If you get stuck at any point:
  • Ask in Discord for quick help
  • Check the SDK Reference
  • Look at existing abilities in community/ for examples
  • Open an issue if you think you’ve found a bug

Build docs developers (and LLMs) love