P2 — implement plugin download and installation from the zara-plugins registry #229

Open
opened 2026-09-02 17:27:44 +00:00 by nsaspy · 0 comments
Owner

Context

The public plugin registry is live: https://github.com/lost-rob0t/zara-plugins

  • machine-readable catalog at the repository root: plugins.json (schema 1), validated on every change by scripts/validate-registry.py and wired as a flake check;
  • first published plugin: zara-avatar 0.1.0 (service plugin, API version 1), self-contained with installer CLI, renderer, and 225 deterministic tests;
  • Nix flake exposes per-plugin packages (#zara-avatar), an aggregate (#zara-plugins), and install apps (nix run github:lost-rob0t/zara-plugins#zara-avatar -- install).

Zara already discovers, loads, and supervises external plugins (zara/plugins/manager.py, zara/plugins/api.py): *.py files in the configured search paths ([modules].search_paths, default ~/.zarathushtra/plugins), create_plugin() / PluginMetadata services plus legacy register_tools() modules, PluginMetadata.api_version compatibility gating, and per-plugin config namespaces under [plugins.<name>].

What is missing is the client side: a Zara user cannot discover or install a registry plugin without cloning the registry repo manually.

Goal

A native zara plugin command surface that turns the registry into an app-store-style flow while keeping installation explicit and trust-on-purpose (plugins are code executed with Zara's privileges).

Proposed commands

  • zara plugin list — render the catalog from plugins.json (cached; --refresh re-fetches).
  • zara plugin search <query> — filter by name/tag/description.
  • zara plugin info <name> — registry metadata + locally installed state + PluginDiagnostic (loaded/running/failed/incompatible).
  • zara plugin install <name> — download the plugin directory at the registry revision, verify api_version compatibility, place the entrypoint into the plugin search path, print per-plugin follow-up steps (e.g. zara-avatar's renderer install and [plugins.zara-avatar] config).
  • zara plugin remove <name> and zara plugin update [<name>].

Contract details

  • Registry source: registry_raw URL from plugins.json (raw.githubusercontent on main); integrity anchored to the git revision actually fetched — record registry commit + time in the cache document.
  • Downloads must be HTTPS only, size- and count-bounded, and must never execute fetched code during install; installation = copying files, nothing more.
  • Verify after install: re-discovered PluginMetadata.name/version/api_version must match the registry entry before reporting success (reuse PluginManager.discover() diagnostics; mismatch → fail loudly).
  • Keep the bundled-plugin-installer path (per-plugin tools/<name> install, e.g. zara-avatar's renderer setup) as an explicit follow-up step, not something zara plugin install runs implicitly.
  • Config: installed plugins need no registry-specific config beyond existing [plugins.<name>] namespaces.

Acceptance criteria

  • All commands work offline-first (cache) with --refresh hitting the network only on demand; no network in tests.
  • Deterministic pytest coverage (TDD contract): registry fetch/cache (mocked transport), install happy path, api_version mismatch refusal, corrupted registry refusal, remove, update, diagnostics reporting.
  • nix flake check and scripts/test-all.sh pass on the exact candidate head.
  • Wiki documentation for the plugin lifecycle.
## Context The public plugin registry is live: https://github.com/lost-rob0t/zara-plugins - machine-readable catalog at the repository root: `plugins.json` (schema 1), validated on every change by `scripts/validate-registry.py` and wired as a flake check; - first published plugin: **zara-avatar** 0.1.0 (service plugin, API version `1`), self-contained with installer CLI, renderer, and 225 deterministic tests; - Nix flake exposes per-plugin packages (`#zara-avatar`), an aggregate (`#zara-plugins`), and install apps (`nix run github:lost-rob0t/zara-plugins#zara-avatar -- install`). Zara already discovers, loads, and supervises external plugins (`zara/plugins/manager.py`, `zara/plugins/api.py`): `*.py` files in the configured search paths (`[modules].search_paths`, default `~/.zarathushtra/plugins`), `create_plugin()` / `PluginMetadata` services plus legacy `register_tools()` modules, `PluginMetadata.api_version` compatibility gating, and per-plugin config namespaces under `[plugins.<name>]`. What is missing is the client side: a Zara user cannot discover or install a registry plugin without cloning the registry repo manually. ## Goal A native `zara plugin` command surface that turns the registry into an app-store-style flow while keeping installation explicit and trust-on-purpose (plugins are code executed with Zara's privileges). ## Proposed commands - `zara plugin list` — render the catalog from `plugins.json` (cached; `--refresh` re-fetches). - `zara plugin search <query>` — filter by name/tag/description. - `zara plugin info <name>` — registry metadata + locally installed state + `PluginDiagnostic` (loaded/running/failed/incompatible). - `zara plugin install <name>` — download the plugin directory at the registry revision, verify `api_version` compatibility, place the entrypoint into the plugin search path, print per-plugin follow-up steps (e.g. zara-avatar's renderer install and `[plugins.zara-avatar]` config). - `zara plugin remove <name>` and `zara plugin update [<name>]`. ## Contract details - Registry source: `registry_raw` URL from `plugins.json` (raw.githubusercontent on `main`); integrity anchored to the git revision actually fetched — record registry commit + time in the cache document. - Downloads must be HTTPS only, size- and count-bounded, and must never execute fetched code during install; installation = copying files, nothing more. - Verify after install: re-discovered `PluginMetadata.name`/`version`/`api_version` must match the registry entry before reporting success (reuse `PluginManager.discover()` diagnostics; mismatch → fail loudly). - Keep the bundled-plugin-installer path (per-plugin `tools/<name> install`, e.g. zara-avatar's renderer setup) as an explicit follow-up step, not something `zara plugin install` runs implicitly. - Config: installed plugins need no registry-specific config beyond existing `[plugins.<name>]` namespaces. ## Acceptance criteria - All commands work offline-first (cache) with `--refresh` hitting the network only on demand; no network in tests. - Deterministic pytest coverage (TDD contract): registry fetch/cache (mocked transport), install happy path, api_version mismatch refusal, corrupted registry refusal, remove, update, diagnostics reporting. - `nix flake check` and `scripts/test-all.sh` pass on the exact candidate head. - Wiki documentation for the plugin lifecycle.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
nsaspy/zara#229
No description provided.