A plugin is a zip with this layout:
my_plugin/
├── manifest.json # required - id, version, capabilities, …
├── __main__.py # required - your handler code (the entry point)
├── requirements.txt # optional - pip deps to install in the sandbox
├── dashboard_manifest.json # optional - declarative dashboard
└── dashboard/ # optional - iframe-mode dashboard (HTML/CSS/JS)
└── index.html
Limits: 25 MB zipped, 100 MB uncompressed, at most 500 files and 10 MB per single file. manifest.json and __main__.py must sit at the zip root; anything malformed is rejected by the upload validator (run yourbot validate locally to see the same errors before you upload).