The official registry and submission hub for Dot X plugins.
This repository serves as the official plugin marketplace for Dot X.
-
Source Register (
plugins-source.json)- The single source of truth for developer submissions
- Developers submit PRs to modify this file
- Contains plugin metadata: id, name, author, description, repo, tags
-
Final Register (
dist/marketplace-registry.json)- The read-only registry consumed by Dot X
- Generated automatically by GitHub Actions
- Hosted via GitHub Pages
- Includes integrity hashes and verified permissions
-
GitHub Actions Workflows
- PR Validation: Validates submissions before merge
- Registry Generation: Automatically builds and deploys the registry
- SHA-256 hash calculated at approval time
- Hash covers the raw
<plugin-name>.dotxpluginbytes - App verifies hash before installation
- Any byte change invalidates the hash and blocks installation
- Tracks approved permissions for each plugin version
- If permissions expand during scheduled updates, creates a security review PR
- Requires human approval for permission changes
- Your plugin must be published as a GitHub Release
- The latest release must include:
<plugin-name>.dotxplugin- A self-contained plugin package
- The
idfield in yourmanifest.jsonmust match theidyou specify inplugins-source.json
The Dot X marketplace installer downloads exactly one package asset per release:
<plugin-name>.dotxplugin
The archive root must contain:
manifest.json- the entry file declared by
manifest.json->main
The archive may also contain additional files and directories, such as:
bin/windows-x64/...bin/windows-arm64/...bin/macos-x64/...bin/macos-arm64/...bin/linux-x64/...assets/...data/...
-
Fork this repository
-
Add your plugin to
plugins-source.json:{ "$schema": "./schemas/plugins-source.schema.json", "plugins": [ { "id": "my-awesome-plugin", "name": "My Awesome Plugin", "author": "Your Name", "description": "A plugin that does awesome things", "repo": "https://github.com/username/my-awesome-plugin", "tags": ["productivity", "ui"], "funding_url": "https://github.com/sponsors/username" } ] } -
Create a Pull Request
- The PR validation workflow will automatically:
- Validate JSON schema
- Verify the GitHub repo and latest release exist
- Select
<plugin-name>.dotxpluginand verify it is a valid plugin package - Open the package and verify root
manifest.jsonand the declared entry file - Verify the
idinmanifest.jsonmatches your submission - Post a comment listing detected permissions
- The PR validation workflow will automatically:
-
Wait for Review
- Maintainers will review your submission
- Once approved and merged, the registry will be automatically updated
Your manifest.json must be included inside <plugin-name>.dotxplugin and should follow this structure:
{
"id": "my-awesome-plugin",
"name": "My Awesome Plugin",
"version": "1.0.0",
"description": "Plugin description",
"author": "Your Name",
"dotxVersion": ">=1.0.0",
"main": "main.js",
"permissions": [
"env"
],
"license": "MIT"
}Required Fields:
id- Must match theidinplugins-source.jsonname- Display name for your pluginversion- Plugin version (semver)description- Short descriptionauthor- Author namedotxVersion- Minimum Dot X version requirement (e.g., ">=1.0.0")permissions- Array of permission strings
Common Permissions:
env- Environment variable accessnet- Network accessread- File system read accesswrite- File system write accessrun- Subprocess executionffi- Foreign function interface access
Note: The registry automatically uses the latest release from your repository. Make sure the latest release includes <plugin-name>.dotxplugin containing root manifest.json and the file declared by manifest.main.
Before you publish a GitHub Release, make sure:
- Your plugin is built to the entry file declared by
manifest.main. manifest.jsonreferences the compiled entrypoint with a relative path, such as"main": "main.js"or"main": "dist/main.js".- Place
manifest.json, the declared entry file, and any required binaries/assets into a staging directory. - Create
<plugin-name>.dotxpluginfrom that staging directory, withmanifest.jsonat the archive root. - The
idinmanifest.jsonmatches theidinplugins-source.json. - The latest release is the one you want Dot X to install from.
If you currently publish from GitHub Releases, you do not need a different hosting setup. You only need to make sure the release contains a self-contained zip package.
{
plugins: Array<{
id: string; // Unique plugin ID (must match manifest.json)
name: string; // Display name
author: string; // Author name
description: string; // Plugin description
repo: string; // GitHub repository URL
tags: string[]; // Array of tags
funding_url?: string; // Optional funding/sponsorship URL
}>
}{
generated_at: string;
plugins: Array<{
id: string; // Plugin ID
name: string; // Display name
description: string; // Description
repo: string; // Repository URL
version: string; // Plugin version from packaged manifest.json
dotxVersion: string | null; // Minimum Dot X version from manifest
tags: string[]; // Tags
author: string; // Author
funding_url?: string; // Optional funding URL
package_url: string; // URL to <plugin-name>.dotxplugin asset
package_format: "zip"; // Package format
package_integrity_hash: string; // SHA-256 hash of <plugin-name>.dotxplugin bytes
package_size?: number; // Package size in bytes
approved_permissions: string[]; // Approved permissions
likes: number; // Like count
downloads: number; // Download count
}>
}Trigger: Pull requests targeting plugins-source.json
Actions:
- Validates JSON schema
- Verifies GitHub repo and latest release exist
- Selects
<plugin-name>.dotxpluginand verifies it is a valid plugin package - Opens the package and verifies root
manifest.jsonand the declared entry file - Verifies
manifest.jsonid matches the submission - Extracts permissions from the packaged manifest
- Posts PR comment with permission summary
Triggers:
- Scheduled: Every 4 hours
- Push to main branch (when
plugins-source.jsonchanges) - Manual dispatch
Actions:
- Loads source and existing registry
- For each plugin:
- Fetches the latest GitHub release
- Selects
<plugin-name>.dotxplugin, downloads it, hashes the raw archive, opens the package, and extractsversion, permissions, anddotxVersion - If packaged version unchanged: updates mutable fields (name, description, tags, etc.) only
- If packaged version changed: updates the registry entry to the new package metadata
- Creates security review PR if permissions expanded during scheduled update
- Fetches the latest
likesanddownloadsfrom Supabase and merges them intodist/marketplace-registry.json - Deploys to GitHub Pages
- Commits changes to repository
The registry is available at:
https://<user>.github.io/dot-x-plugins/marketplace-registry.json
The registry prevents "Trojanning" attacks through immutable hashes, hash verification, and permission tracking. Permission expansions detected during scheduled updates automatically trigger a security review PR requiring human approval.
-
Install dependencies:
npm install
-
Validate schema:
node .github/scripts/validate-schema.js
-
Test registry generation (requires GITHUB_TOKEN):
GITHUB_TOKEN=your_token node .github/scripts/generate-registry.js
-
Apply the stats schema and deploy the functions with the Supabase CLI:
npx supabase db push npx supabase functions deploy set-plugin-like npx supabase functions deploy record-plugin-download
Contributions are welcome! Please:
- Follow the existing code style
- Ensure all workflows pass
- Update documentation as needed
- Test your changes locally when possible
MIT. See LICENSE.