This repository has been archived on 2026-05-23. You can view files and clone it. You cannot open issues or pull requests or push a commit.
2026-05-23 16:00:57 +02:00
2026-03-25 12:42:19 +01:00
2026-05-09 19:43:23 +02:00
2026-03-25 12:42:19 +01:00
2026-04-26 22:00:17 +02:00
2026-04-26 22:00:17 +02:00
2026-03-25 12:42:19 +01:00
2026-05-09 19:43:23 +02:00
2026-04-26 22:00:17 +02:00
2026-04-26 22:00:17 +02:00
2026-05-09 19:43:23 +02:00

Tribes Plugin Template

DEPRECATED! Use the generator (tribes-plugin-new) instead.

Template for creating Tribes plugins.

Getting Started

  1. Click "Use this template" on GitHub to create your own repo
  2. Clone and rename:
git clone https://github.com/you/your-plugin.git
cd your-plugin
./scripts/rename.sh your_plugin YourPlugin
  1. Edit manifest.json — set description, capabilities, requirements
  2. Implement your plugin in lib/your_plugin/plugin.ex
  3. Run validation, smoke checks, and tests:
mix deps.get
mix tribes.plugin.validate
scripts/plugin smoke
scripts/plugin test

If you are using the shared tribes devenv, run through the local helper instead:

devenv shell -- plugin validate
devenv shell -- plugin smoke
devenv shell -- plugin test
devenv shell -- plugin precommit

Development

For local development alongside a Tribes checkout:

# Symlink into the host plugins directory once
cd /path/to/tribes
ln -s /path/to/your-plugin plugins/your_plugin

# Start Tribes dev server
iex --sname dev -S mix phx.server

Then edit the plugin in its own repo. In development, the host now watches symlinked external plugins and automatically:

  • runs mix compile for Elixir/HEEx or manifest changes
  • runs npm run build --prefix assets when assets/package.json is present
  • reloads the plugin in the running Tribes VM
  • triggers a Phoenix browser reload after the rebuild finishes

That means the normal edit/compile loop is:

cd /path/to/your-plugin
mix deps.get

# in another terminal
cd /path/to/tribes
iex --sname dev -S mix phx.server

Inside the plugin repo's devenv shell, the plugin helper forwards to the host devenv automatically:

plugin validate
plugin smoke
plugin test
plugin precommit

If your plugin does not need a custom frontend pipeline, you can skip assets/package.json and write browser-ready files directly under assets/js and assets/css; the host dev watcher will copy them into priv/static for you in development. The default template uses TypeScript under assets/ts.

Project Structure

your_plugin/
├── manifest.json           # Plugin metadata (Nix build + runtime)
├── mix.exs                 # Dependencies
├── config/                 # Host-backed test config
├── lib/
│   ├── your_plugin/
│   │   ├── plugin.ex       # Tribes.Plugin entry point
│   │   └── application.ex  # OTP supervision tree (optional)
│   └── your_plugin_web/
│       └── live/            # LiveView pages
├── assets/                 # TS/CSS (one bundle per plugin)
│   ├── ts/                 # TypeScript browser entry points
│   ├── package.json        # Optional build script used by dev + Guix packaging
│   ├── tsconfig.json       # TypeScript compiler settings
│   └── package-lock.json   # Optional, recommended for reproducible builds
├── priv/
│   ├── static/             # Built assets for release
│   └── repo/migrations/    # Ecto migrations
├── scripts/
│   ├── plugin             # Shared devenv/non-devenv test wrapper
│   └── rename.sh
└── test/

Manifest

manifest.json declares your plugin's identity and capabilities:

{
  "name": "your_plugin",
  "entry_module": "Tribes.Plugins.YourPlugin.Plugin",
  "host_api": "1",
  "otp_app": "your_plugin",
  "provides": ["some_capability@1"],
  "requires": ["ui@1"],
  "enhances_with": ["inference@1"]
}
  • entry_module — must be Tribes.Plugins.*.Plugin
  • otp_app — required and must match name
  • provides — capabilities this plugin makes available
  • requires — hard plugin/API contracts beyond the host_api foundation (build fails without them)
  • enhances_with — optional dependencies (plugin degrades gracefully)

The default template includes ui@1 because the generated LiveView renders inside the host chrome through Tribes.Plugin.Layouts.app. Keep ui@1 when a plugin uses host chrome, imports Tribes.UI.Components, or uses use Tribes.UI:

"requires": ["ui@1"]

host_api is the versioned foundation contract. It provides the supported Phoenix, Ash, PubSub, data, and cluster-event APIs for plugins. Do not add separate framework capability requirements for APIs that belong to that foundation.

See the Plugin System docs for the full specification.

The default template assumes the plugin owns a top-level page such as /your_plugin and any views beneath it. Render normal plugin pages with Tribes.Plugin.Layouts.app so they live inside the Tribes chrome/navigation; only omit it for intentionally unwrapped fullscreen surfaces.

Plugin Data

If your plugin adds Ash resources that should replicate cluster-wide, use extensions: [AshNostrSync] on those resources and follow the host defaults:

  • persisted attributes sync by default unless explicitly excluded
  • synced resources should use one UUID primary key by default
  • AshNostrSync requires exactly one primary key; composite keys are not supported
  • synced resources get extension-managed deleted_at soft-delete support by default
  • destroy actions can use soft_delete() when they should tombstone rows
  • soft_delete?(false) is the opt-out if a synced resource should not use the default tombstone model

Keep resource-specific side effects explicit in actions. AshNostrSync owns the default tombstone/filter/projection behavior, but your plugin still decides which actions are semantic deletes and what else they should do.

Testing

The template starts with two host-backed test layers:

  • Contract tests (test/your_plugin/plugin_contract_test.exs) — manifest and runtime spec stay aligned
  • Page tests (test/your_plugin/home_page_test.exs) — the plugin renders through the real host page pipeline

Run them with:

mix tribes.plugin.validate
scripts/plugin smoke
scripts/plugin test

Use plugin test / plugin precommit for host-backed tests. The helper invokes Mix with the host database/services and host plugin-manager paths, including built-in providers such as tribes_ui. Raw mix test in a plugin checkout is guarded and prints this guidance; mix raw_test / mix raw_precommit are available only for unusual manual debugging when you have set the same host environment yourself.

Building for Release

MIX_ENV=prod mix compile
devenv shell -- npm run build --prefix assets

mkdir -p dist/your_plugin
cp -r _build/prod/lib/your_plugin/ebin dist/your_plugin/
cp -r priv dist/your_plugin/
cp manifest.json dist/your_plugin/

For Guix-based deployment, package your plugin in the guix-tribes channel and enable it from the node config.

Licence

TODO: Choose a licence.

S
Description
Tribes Plugin Template
Readme 539 KiB
Languages
Elixir 88%
Shell 8.8%
Nix 1.8%
TypeScript 0.8%
CSS 0.6%