Skip to content

feat(plugins): hosted Tabularium registry + connection catalogue (fully BC)#299

Open
NewtTheWolf wants to merge 11 commits into
TabularisDB:mainfrom
NewtTheWolf:feat/registry-integration
Open

feat(plugins): hosted Tabularium registry + connection catalogue (fully BC)#299
NewtTheWolf wants to merge 11 commits into
TabularisDB:mainfrom
NewtTheWolf:feat/registry-integration

Conversation

@NewtTheWolf

Copy link
Copy Markdown
Collaborator

What

Wires up the hosted Tabularium registry (registry.tabularis.dev) and rebuilds
the New Connection flow around a driver catalogue — without breaking the old
registry format.

45 files · +4578 / −523

Backend

  • Hosted registry + merge — new HTTP API catalogue merged with the legacy
    registry (union, API wins on id conflict), so old plugins (duckdb, …) stay
    visible. (registry.rs, commands.rs)
  • Deep-link installtabularis://install handler, version-aware via
    semver: Install / Update / already-installed. (deep_link.rs)
  • Tracked downloads — assets resolve through the registry redirect endpoint
    (/latest unpinned, /releases/{version} pinned) so installs get counted.
    (tabularium.rs)
  • Removable BC layer — all compat code in compat.rs, tagged
    COMPAT(registry-ga): at every call site. Legacy registry.json install +
    listing and legacy manifest.json still work; deletable once all plugins
    have migrated.

Frontend

  • Connection catalogue as step 1 of New Connection: search, paradigm
    facets, engine cards, version picker, install-gated uninstalled drivers with
    inline install. (ConnectionCatalogue, EngineCard, InstallGate, …)
  • PluginInstallConfirmModal renders the deep-link action (install / update /
    already-installed).
  • i18n across all 7 locales.

Compatibility

Fully backwards-compatible: the legacy registry format and manifest.json are
still consumed. The in-repo plugins/registry.json seed is replaced by
tabularium-extensions.schema.json; the legacy format is read from the hosted
source via the BC layer.

Tests

Backend 688 ✓ · Frontend 2535 ✓

tabularium-sdk 0.2 exposes verified/extensions fields used by the
registry integration. semver is used for version-aware install
classification (install vs update vs already-installed).
…C layer

Integrate the hosted Tabularium registry (registry.tabularis.dev) alongside
the legacy static registry.json, with version-aware deep-link install.

- Merge new HTTP API catalogue with legacy registry.json (union, API wins
  on id conflict) so old plugins (duckdb, ...) stay visible.
- Semver-aware install classification: install / update / already-installed.
- Tracked asset downloads via the registry redirect endpoint:
  /api/plugins/{slug}/latest for unpinned, /releases/{version} for pinned.
- Host manifest parser migrated to .tabularium (JSON), legacy manifest.json
  read as fallback.

All backwards-compat code lives in plugins/compat.rs and is marked with
`COMPAT(registry-ga):` at every call site, so it can be removed mechanically
once all plugins have migrated to the hosted registry.
Redesign the New Connection flow around a searchable driver catalogue that
merges built-in drivers with registry plugins.

- EngineCard, ConnectionCatalogue (search + paradigm facets + grid),
  DriverVersionPicker, InstallBanner, InstallGate components.
- useConnectionCatalogue hook + connectionCatalogue normalization model.
- Catalogue is step 1 of the New Connection wizard; uninstalled drivers are
  install-gated with inline driver install.
PluginInstallConfirmModal now renders the install action returned by the
preview command: Install, Update (when a newer version exists), or an
already-installed banner for an up-to-date plugin.

- useDeepLinkInstall hook drives the tabularis://install flow.
- PluginsTab consumes the registry base URL per plugin for its registry link.
Add registry/catalogue and deepLink (updateConfirm, alreadyInstalled)
strings across all 7 locales.
- NewConnectionModal: remove unused PluginManifest import.
- PluginInstallConfirmModal: key the modal by request in App.tsx so each
  request remounts with fresh state, replacing the synchronous state reset
  inside the effect (react-hooks/set-state-in-effect). Loading state now
  initialises from the keyed mount; the effect only sets state in its async
  callbacks.
Comment thread src-tauri/src/plugins/commands.rs Outdated
Comment thread src-tauri/src/plugins/registry.rs Outdated
Comment thread src/hooks/useConnectionCatalogue.ts Outdated
Comment thread src/components/modals/PluginInstallConfirmModal.tsx Outdated
@kilo-code-bot

kilo-code-bot Bot commented Jun 7, 2026

Copy link
Copy Markdown

Code Review Summary

Status: No Issues Found | Recommendation: Merge

All 4 previously identified issues have been resolved in commit 4d4368c.

Resolved Issues
File Line Issue Status
src-tauri/src/plugins/commands.rs 45 Static registry plugins no longer receive broken detail-page links ✅ Fixed
src-tauri/src/plugins/registry.rs 185 Detail fetches now use futures::future::join_all for parallelism ✅ Fixed
src/hooks/useConnectionCatalogue.ts 71 Replaced in operator with Object.prototype.hasOwnProperty.call ✅ Fixed
src/components/modals/PluginInstallConfirmModal.tsx 70 Empty version string now treated as nullish via `
Files Reviewed (4 files)
  • src-tauri/src/plugins/commands.rs
  • src-tauri/src/plugins/registry.rs
  • src/hooks/useConnectionCatalogue.ts
  • src/components/modals/PluginInstallConfirmModal.tsx

Reviewed by kimi-k2.6-20260420 · 4,340,194 tokens

…y version)

- commands.rs: only set registry_base_url for a real Tabularium API, not a
  legacy `.json` base (avoids broken `…/registry.json/plugins/<id>` links).
- registry.rs: fetch plugin details concurrently via join_all instead of N
  sequential round-trips.
- useConnectionCatalogue: use hasOwnProperty instead of `in` so plugin ids
  like "constructor"/"toString" aren't matched against Object.prototype.
- PluginInstallConfirmModal: treat empty `?version=` as no pin (|| null) for
  both the preview fetch and the displayed target version.
Comment thread src-tauri/src/plugins/compat.rs
Comment thread src/utils/connectionCatalogue.ts Outdated
…catalogue sort

Addresses PR review (debba):
- Restore plugins/registry.json instead of deleting it. LEGACY_REGISTRY_URL
  points at this file on main; deleting it would 404 after merge, silently
  dropping un-migrated plugins from resolve_registry's merge and breaking
  already-shipped app versions that use it as their only registry source.
  Prune only when the whole COMPAT(registry-ga) layer is removed.
- Sort engine groups builtins-first then other-last (then alphabetical), so the
  catalogue leads with the SQL section and pushes the metadata-less 'Other'
  section to the end instead of opening on a wall of legacy plugins.
…-ready CI

- scaffold emits .tabularium (was manifest.json); keep id=slug/name=display
  so the host identity/display split is preserved
- add `migrate [path]` to convert legacy manifest.json plugins to .tabularium;
  drops a redundant id (id===name), refuses without a semver version
- `migrate --ci` regenerates release.yml from the registry-ready template
  (BIN_NAME from manifest.executable); without --ci the workflow is left as-is,
  only its manifest.json reference is renamed
- release.yml template: stash artifacts + single release job publishing
  .tabularium as a standalone asset (Tabularium registry resolves the manifest
  from release assets); assets/ dir support; action version bumps
- plugin-api: doc comments reference .tabularium
- bump @tabularis/create-plugin 0.1.1 -> 0.2.0
@NewtTheWolf

NewtTheWolf commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator Author

@debba small follow-up on this branch (2cbb015) — I aligned packages/ with the new .tabularium host contract and added tooling so plugin authors can keep up:

@tabularis/create-plugin (0.1.1 → 0.2.0)

  • Scaffold now emits .tabularium instead of manifest.json. id=slug / name=display are deliberately kept, because the host falls back to name as the identity when id is absent (otherwise the display name would become the slug).
  • New command migrate [path]: converts existing manifest.json plugins → .tabularium, drops a redundant id (only when id===name), and refuses without a semver version (registry requirement). justfile/README/release.yml references are carried along.
  • migrate --ci: additionally regenerates release.yml from the registry-ready template (BIN_NAME derived from manifest.executable). Without --ci the CI structure is left untouched — only its manifest.json reference is renamed so the build keeps working.

Registry-ready release workflow (template)
The previous template workflow only bundled .tabularium inside the platform zips. But the hosted Tabularium registry resolves the manifest from the release assets (since 0.8.0), not from the git ref. The workflow now stashes the artifacts and, in a separate release job, uploads the zips plus .tabularium as a standalone asset (modeled on my firestore plugin CI). I deliberately left out the Codeberg publish — that's a hosting choice, not generic.

@tabularis/plugin-api: doc comments updated to reference .tabularium only.

Tests: 32 green (8 new for migrate, incl. --ci regeneration + edge cases), tsc/build clean, generated YAML validated. Happy to hear if the migrate defaults (id handling, CI only with --ci) look right to you.

@debba

debba commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

That's awesome! Thanks @NewtTheWolf !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants