How to Develop Extensions¶
Extensions are installable packages built with the Zelos SDK. They connect devices, decode protocols, and add custom UI to Zelos. Users install an extension from the marketplace instead of writing integration code, then stream, visualize, and control their systems right away.
This page is the starting point. It explains the two kinds of extension, how identity works, and the workflow from a new project to a marketplace release. Each step links to a page with the details.
Choose an Extension Type¶
| Agent extension | App extension | |
|---|---|---|
| Runs | As a Python process under the Zelos Agent | As a sandboxed web page in a desktop app tab |
| Built with | Python and zelos-sdk |
TypeScript, React, Vite, and @zeloscloud/app-extension-sdk |
| Good for | Device drivers, protocol decoders, data streaming, actions | Custom dashboards and workflow UI inside Zelos |
| Declared as | [host] type = "agent" |
[host] type = "app" |
| Guide | Develop Agent Extensions | Develop App Extensions |
What Extensions Can Do¶
Acquire data:
- Decode bus protocols such as CAN and CAN FD, Modbus, MQTT, OPC UA, Ethernet with Protobuf, and serial.
- Talk to test equipment such as HIL systems, data acquisition hardware, and oscilloscopes.
- Stream from custom hardware and sensors.
- Parse proprietary file formats and logs.
Control devices:
- Run commands on hardware through actions.
- Automate test sequences.
- Change parameters while the system runs.
Process data:
- Transform and filter data streams.
- Compute derived signals.
- Combine signals from several sources.
Extend the app:
- Add a custom tab with its own UI that reads signals, runs actions, and writes
.trzfiles through the app bridge.
Create Your First Extension¶
In the Zelos App:
- Open the Extensions view.
- Open the Marketplace section menu and select Create Extension.
- Pick Agent Extension or App Extension.
- Enter an Extension Name in kebab-case, for example
sensor-monitor, and an optional Description. - Click Create Extension, then pick the folder to create the project in.
The app generates the project from the official templates and installs it locally as local.<name>.
From the CLI:
The CLI also installs the new project locally. See each guide for the options.
Development Workflow¶
- Create a project from a template, as above.
- Develop it. Agent projects run with
just dev. App projects run in a browser withnpm run dev. - Install it locally with
zelos extensions install-local .to run it inside Zelos. - Configure it through a JSON Schema form. See Configuration.
- Package it with
zelos extensions package .. See Package and Publish Extensions. - Release it from a
v*tag. The generated GitHub workflow builds the archive and creates the release. - Publish the repository on marketplace.zeloscloud.io.
Reference¶
| Page | Covers |
|---|---|
| Manifest Reference | Every extension.toml field, defaults, and validation errors |
| Extension Configuration | config.schema.json, form widgets, load_config() |
| Package and Publish Extensions | Archives, size limits, platform-specific builds, releases, the marketplace, updates |
| Extension Runtime and Lifecycle | Install, Python environment, environment variables, logs, shutdown, crashes, security |
| Develop Agent Extensions | The Python project, entry point, local testing |
| Develop App Extensions | The web project, bridge SDK, sandbox |
Extension Identity¶
Zelos derives every extension ID. Do not set an id field in the manifest.
Marketplace extensions use owner.repo, from the GitHub repository. For example, acme/canbus-decoder becomes acme.canbus-decoder.
Local extensions use local.<slug>, from the manifest name. For example, name = "Sensor Monitor" becomes local.sensor-monitor. Zelos uses the project directory name only when the name produces an empty slug.
ID Rules¶
An extension ID has exactly two parts separated by a dot. Each part:
- Uses only lowercase letters, digits, and hyphens.
- Does not start or end with a hyphen.
- Is not empty.
| ID | Valid |
|---|---|
acme.canbus-decoder |
Yes |
john-doe.mqtt-bridge |
Yes |
local.sensor-01 |
Yes |
Acme.CANBus |
No: uppercase letters |
acme.-canbus |
No: leading hyphen |
acme..canbus |
No: empty part |
The marketplace does not rewrite repository names. Name the repository with lowercase letters, digits, and hyphens so its ID is valid.
Local ID Slugs¶
For a local install, Zelos builds the slug from the manifest name:
- Convert to lowercase.
- Replace each run of characters other than ASCII letters and digits with one hyphen.
- Trim hyphens from the ends.
- Prefix with
local..
name = "Sensor Monitor" -> local.sensor-monitor
name = "My Extension v2" -> local.my-extension-v2
name = "CAN__BUS___Tool" -> local.can-bus-tool
Two local projects with the same name get the same ID, and the second install replaces the first. Give each project a distinct name.
Configuration¶
Agent extensions take user configuration through a JSON Schema file, config.schema.json. The Zelos App renders it as a form, and your code reads the saved values with load_config(). See Extension Configuration for the schema format, every widget, and how validation works.
Where Extensions Run¶
Agent extensions run as separate Python processes under the Zelos Agent, in their own uv-managed virtual environments with Python 3.10 through 3.14. They run as the agent's OS user and start from a minimal environment. See Extension Runtime and Lifecycle.
App extensions run as sandboxed web pages in desktop app tabs. A packaged app extension has no network access and talks to Zelos only through the bridge SDK. See Develop App Extensions.
Troubleshooting¶
| Problem | Where to look |
|---|---|
| The manifest is rejected | Common Validation Errors |
| Packaging fails, or the release does not appear in the marketplace | Package and Publish: Troubleshooting |
| The extension does not start, or crashes | Runtime: Troubleshooting |
| A configuration form field is wrong | Configuration: Troubleshooting |
| An app extension does not connect | App Extensions: Troubleshooting |