π§© Contribute Skills
Adding skills for new apps is the most valuable contribution. Every new app skill makes the framework more useful for everyone. This page covers the process specifically for contributors.
Contribution Types
Section titled βContribution Typesβ| Type | Difficulty | Impact |
|---|---|---|
| Add UI elements for a new app | Easy-Medium | High |
| Write an Action for an existing app | Medium | High |
| Write a Workflow (multi-step) | Medium | High |
| Build a complete app Skill | Medium-Hard | Very High |
Step-by-Step
Section titled βStep-by-Stepβ1. Scaffold the Directory
Section titled β1. Scaffold the Directoryβmkdir -p gitd/skills/whatsapp/actionsmkdir -p gitd/skills/whatsapp/workflowstouch gitd/skills/whatsapp/__init__.pytouch gitd/skills/whatsapp/actions/__init__.pytouch gitd/skills/whatsapp/workflows/__init__.py2. Define UI Elements
Section titled β2. Define UI ElementsβUse the Skill Creator tab (live device stream with element overlay) to identify elements on the target app:
package: com.whatsappapp_version: "2.24.x"
elements: search_icon: resource_id: "com.whatsapp:id/menuitem_search" content_desc: "Search" description: "Search icon in toolbar"
chat_input: resource_id: "com.whatsapp:id/entry" description: "Message text input field"
send_button: resource_id: "com.whatsapp:id/send" content_desc: "Send" description: "Send message button"Always provide at least 2 locator fields per element (e.g., resource_id + content_desc).
3. Write Actions
Section titled β3. Write Actionsβfrom gitd.skills.base import Action, ActionResult
class SendMessage(Action): name = "send_message" description = "Type a message and tap send"
def precondition(self, dev, xml): return dev.find_bounds(xml, resource_id="com.whatsapp:id/entry") is not None
def execute(self, dev, text="Hello", **kwargs): xml = dev.dump_xml() bounds = dev.find_bounds(xml, resource_id="com.whatsapp:id/entry") dev.tap(*dev.bounds_center(bounds)) dev.type_text(text)
xml = dev.dump_xml() bounds = dev.find_bounds(xml, resource_id="com.whatsapp:id/send") if bounds: dev.tap(*dev.bounds_center(bounds)) return ActionResult(success=True) return ActionResult(success=False, error="Send button not found")4. Write Workflows (Optional)
Section titled β4. Write Workflows (Optional)βfrom gitd.skills.base import Workflow
class SendDM(Workflow): name = "send_dm" description = "Send a DM to a contact"
def steps(self): return [ ("open_app", {}), ("search_contact", {"query": self.params["contact"]}), ("send_message", {"text": self.params["message"]}), ]5. Register
Section titled β5. Registerβfrom gitd.skills.base import Skill
def load(): skill = Skill.from_yaml("gitd/skills/whatsapp") from .actions.send_message import SendMessage skill.register_action(SendMessage) from .workflows.send_dm import SendDM skill.register_workflow(SendDM) return skill6. Test
Section titled β6. Testβ# Verify it loadspython3 -c "from gitd.skills.whatsapp import loads = load()print(f'{s.name}: {len(s.elements)} elements, {s.list_actions()}, {s.list_workflows()}')"
# Run on devicepython3 -c "from gitd.skills.whatsapp import loadfrom gitd.bots.common.adb import Devices = load()dev = Device()action = s.get_action('send_message', dev)result = action.run(text='Hello from the bot')print(f'Success: {result.success}')"7. Submit PR
Section titled β7. Submit PRβgit checkout -b skill/whatsappgit add gitd/skills/whatsapp/git commit -m "Add WhatsApp skill: send_message action, send_dm workflow"Include in the PR:
- App name and version tested on
- Device model and Android version
- What actions and workflows are included
- Screenshot of the skill working (appreciated but optional)
Quality Checklist
Section titled βQuality ChecklistβBefore submitting:
-
skill.yamlhasname,version,app_package,description -
elements.yamluses multiple locator fields per element - All actions have
nameanddescription - At least one action has a
postcondition() - Skill loads without errors
- Tested on a real device
- No hardcoded serials or credentials
Even Partial Skills Help
Section titled βEven Partial Skills HelpβEven a skeleton with just skill.yaml and elements.yaml (no actions) is a valid contribution. It saves the next person from starting from scratch and provides the UI element mappings for the app.
Related
Section titled βRelatedβ- Creating Skills Guide β detailed walkthrough
- Elements Reference β how locator chains work
- Code Contributions β general PR guidelines