Context for developing and debugging Hubitat Elevation apps, drivers, and hub environment — sandbox constraints, lifecycle idioms, capability contracts, plus grounded deploy/log-tail/lint mechanisms.
—
—
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
High
Do not use without reviewing
Process steps in order. Do not skip ahead.
The always-on Hubitat rules (sandbox-constraints, app-lifecycle, driver-lifecycle, logging-conventions, state-vs-attributes, groovy-gotchas) are already in context — apply them while generating. The capability contract lives in skills/_reference/capabilities.json; the import allow-list in skills/_reference/allowed-imports.txt.
Establish, asking the user only for what is not already clear:
name, namespace (unique — typically the user's handle), authorProceed to Step 2.
For a driver, for each declared capability read its required commands and attributes from skills/_reference/capabilities.json (capabilities.<Name>.commands[].name, .attributes[].name). Every required command becomes a Groovy method. Marker capabilities (Actuator, Sensor) add no methods.
For an app, decide the preference inputs (see skills/_reference/input-types.md) and the events to subscribe to.
Proceed to Step 3.
Emit one Groovy file wiring in, per the rules:
metadata { definition(...) { capability lines, custom command/attribute } preferences { logEnable/txtEnable } }; installed(), updated() (with runIn(1800, logsOff) when logging), logsOff(); a method for every required command; configure()/refresh() if those capabilities are declared; a parse(String description) with the protocol-appropriate decode and a log.debug of raw input when a protocol is involved.definition(...), preferences { page { section { inputs } } }, installed() { updated() }, updated() { unsubscribe(); initialize() }, initialize() with the subscriptions, and a handler method for each subscription. Guard chatty logs on logEnable/txtEnable.Write the file to the path the user wants (default <name>.groovy). Proceed to Step 4.
Run the sandbox linter on the generated file and resolve anything it flags:
python3 .tessl/plugins/jbaruch/hubitat-dev/skills/_scripts/hub_lint.py <file.groovy>Contract and finding shape: skills/_scripts/hub_lint.py module docstring. A correct skeleton should lint clean; if a missing-command or unresolved-handler appears, a required method or handler is absent — add it. If no findings, say so and proceed.
The skeleton exists locally but is not on any hub. Offer to deploy it with Skill(skill: "deploy"). Finish here.