feat(admin/plugins): install/update/uninstall UI + verbatim capability review — closes #253 - #385
Merged
Merged
Conversation
tayebmokni
enabled auto-merge (squash)
May 18, 2026 19:31
…closes #253 Wires up the user-facing plugins screen on the admin Next.js app: - apps/admin/src/app/plugins/page.tsx — list view (RSC) over GET /api/v1/plugins, defensive fetch with empty/error fallback. - apps/admin/src/app/plugins/PluginListClient.tsx — interactive table with search, status-filter chips, per-row Activate / Deactivate / Uninstall actions, and a confirmation modal for the destructive path. - apps/admin/src/app/plugins/[name]/page.tsx + PluginDetailView.tsx — detail view: manifest summary, declared capabilities with operator- voice descriptions, dependency status with satisfied chips, install timestamps, last-error block when state=errored. - apps/admin/src/app/plugins/install/page.tsx + InstallForm.tsx — upload form (bundle, manifest.json, JSON paste) with the verbatim CapabilityReview centerpiece. Install action requires an explicit consent checkbox. - apps/admin/src/app/plugins/actions.ts — server actions wrapping /api/v1/plugins/{install,activate,deactivate,delete} with friendly "endpoint not deployed yet" fallback for issues #340 / #341. - apps/admin/src/app/plugins/components/CapabilityReview.tsx — the review screen itself; renders every cap in manifest order, flags sensitive ones, surfaces unknown ids as "Unrecognised". - apps/admin/src/app/plugins/components/PluginStatusBadge.tsx — state pill shared by list + detail. - apps/admin/src/app/plugins/capability-registry.ts — TS mirror of packages/go/plugins/capabilities/registry.go::builtinCapabilityDefs, extended with operator-voice phrasing for the consent UI. Adds 33 Vitest tests covering list rendering, status filtering, search, the uninstall confirmation flow (cancel + confirm), the disabled-while- active uninstall path, the detail capability rendering, the dependency satisfied/unsatisfied chips, the install file-upload + paste flows, the consent-gated submit, and the capability registry mirror. Sidebar gets a /plugins entry alongside Users and Settings; Sidebar.test is updated to match. Signed-off-by: Mohamed Tayeb Mokni <tayeb.mokni@gmail.com>
tayebmokni
force-pushed
the
feat/253-plugin-admin-ui
branch
from
May 18, 2026 20:12
4f1cb91 to
52c12d3
Compare
4 tasks
tayebmokni
pushed a commit
that referenced
this pull request
May 23, 2026
Adds the public-facing browse/install surface that sits next to the existing plugins manager (PR #385). The catalogue is fed by the marketplace data model from PR #396; the install path reuses the plugin lifecycle.Install runtime so consent semantics stay identical across manual and catalogue flows. Backend (apps/api/internal/admin/marketplace): - GET /api/v1/admin/marketplace/listings (category/q/sort) - GET /api/v1/admin/marketplace/listings/{slug} - GET /api/v1/admin/marketplace/listings/{slug}/versions - GET /api/v1/admin/marketplace/listings/{slug}/ratings - POST /api/v1/admin/marketplace/listings/{slug}/ratings (1..5 stars) - POST /api/v1/admin/marketplace/listings/{slug}/install - Read endpoints require an authenticated principal; install + rating POST gated on plugins.install (CapInstallPlugins). - Install dispatches to lifecycle.Install with the resolved version's wasm bytes via a BundleFetcher abstraction; success and failure both append a plugin_install_events row. Admin UI (apps/admin/src/app/marketplace): - page.tsx + MarketplaceClient — grid w/ search, category chips, and sort-by recent/stars/popular. - [slug]/page.tsx + ListingDetailView — description, version history, compat matrix, rating aggregate + submission form. - [slug]/install/page.tsx + InstallConfirm — reuses the CapabilityReview component from #385 (no duplication) and the consent checkbox before firing the install action. - components/RatingStars (read-only + interactive variants), components/MarketplaceCard. Tests: - Backend: filter/sort, slug detail/404, install dispatch + event capture, capability gate, rating range checks. - Frontend: grid render, URL push for search/sort/category, capability review reuse + consent gating, install success path. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: Mohamed Tayeb Mokni <tayeb.mokni@gmail.com>
tayebmokni
added a commit
that referenced
this pull request
May 23, 2026
## Summary - Adds `apps/api/internal/admin/marketplace` (handler + tests) exposing browse, detail, versions, ratings, and install endpoints over the data model from PR #396. Install dispatches to `lifecycle.Manager.Install` via a bundle-fetcher seam and records `plugin_install_events` rows. - Adds `apps/admin/src/app/marketplace/*` (Next.js App Router): catalogue grid with category chips + search + sort, listing detail with version history / compat matrix / ratings form, and an install confirmation screen that **reuses the `CapabilityReview` component from PR #385** rather than duplicating consent UX. - Sidebar gets a new `Marketplace` entry next to `Plugins`. ## Test plan - [x] `cd apps/api && go vet ./internal/admin/marketplace/...` - [x] `cd apps/api && go test -race -count=1 ./internal/admin/marketplace/...` (all green; covers list filters, slug 404, install dispatch + event capture, capability gate on install + rating, rating range checks) - [x] `pnpm --filter @gonext/admin typecheck` - [x] `pnpm --filter @gonext/admin test` (37 files / 255 tests pass — new tests: `MarketplaceClient.test.tsx`, `RatingStars.test.tsx`, `InstallConfirm.test.tsx` asserts the shared `CapabilityReview` is reused) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: Mohamed Tayeb Mokni <tayeb.mokni@gmail.com> Co-authored-by: Mohamed Tayeb Mokni <tayeb.mokni@gmail.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
5 tasks
tayebmokni
added a commit
that referenced
this pull request
May 26, 2026
…brand (#437) ## Summary Restyles every screen in the GoNext plugin marketplace admin (PR #420) and installed-plugins admin (PR #385) to the **"Living systems"** brand foundation that landed via PR #432. Tokens from `src/styles/tokens.css` are honoured throughout — no hex literals, no legacy `--color-accent`. Each page lands the brand's signature italic-serif accent inside a heavy Archivo headline. - **`/marketplace` — catalogue.** Headline reads `Marketplace catalogue.` with the italic-accent on the noun, an emerald eyebrow, and a Geist lead. Filter chips toggle to `--emerald-soft` when active; sort chips swap to a solid `--ink` fill. MarketplaceCard sits on `--paper-2` with a paper-3 thumb glyph well, Archivo display title, monospace slug, lavender-soft capability chip, and emerald rating stars. Cards lift to `--sh-md` on hover via a 2px transform — the marketplace moodboard's hover gesture. - **`/marketplace/[slug]` — listing detail.** Headline pairs the Archivo title with an italic-serif accent on the author name. Version history is a paper-2 table with mono row IDs + SHA digests; the compat matrix lives on `--paper-3` sunken surface to read as reference data. Ratings render as a horizontal review carousel of cream cards with emerald stars. - **`/marketplace/[slug]/install` — confirmation.** Headline: `Install <name>.` with the listing name in italic-serif. The meta strip uses the brand's card chrome with mono version label and uppercase eyebrow labels. Install CTA is the emerald brand button. Success panel uses the italic-accent pattern with an emerald left-border. - **Shared `CapabilityReview` (also rendered by `/plugins/install`).** Each capability row is its own paper-2 card with a 22px circular marker. Sensitive caps swap to `--lavender-soft` background + solid lavender marker; once the consent box is ticked every non-unknown marker flips to an **emerald checkmark** — the row visibly confirms it has been reviewed. - **`/plugins` — installed plugins list.** Headline: `Installed plugins.` with the italic-accent on `plugins`. Status filter chips and `PluginStatusBadge` share the brand's semantic palette: emerald for active (alive), paper-3 / fg-muted for inactive (quietly present), lavender-soft for installed, warning-soft for pending uninstall, danger-soft for errored. Badge gains a leading `currentColor` dot so the row is legible without colour. ## Test plan - [x] `pnpm --filter @gonext/admin lint` — clean (only pre-existing `<img>` warnings in unrelated `media/` files) - [x] `pnpm --filter @gonext/admin typecheck` — clean - [x] `pnpm --filter @gonext/admin test:ci` — **349 tests pass**, including new snapshot tests for `MarketplaceCard` and every `PluginStatusBadge` state - [x] `pnpm --filter @gonext/admin build` — succeeds, marketplace + plugins routes ship under their existing bundle budgets - [x] Snapshot pins lock the brand contract — future drift will fail the snapshot and demand a deliberate update ## Tokens audit Every colour, type ramp, radius, shadow, motion, and spacing in the diff resolves to a `var(--*)` from `tokens.css`. The few raw values that remain are intentional: the modal backdrop scrim is `rgba(14, 26, 20, 0.55)` (the ink ramp tinted at 55%, no token covers backdrop overlays) and the icon-well letter sizes are pixel-precise display measurements. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Mohamed Tayeb Mokni <tayeb.mokni@gmail.com> Co-authored-by: Mohamed Tayeb Mokni <tayeb.mokni@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
apps/admin/src/app/plugins/: a list view, per-plugin detail view, and the install flow centred on a verbatim capability review that lists every requested permission in plain English with explicit operator consent before the install fires./api/v1/plugins/{install,activate,deactivate,:name}with friendly "endpoint not yet deployed" fallbacks for the in-flight REST work (issues fix(ci): vet/test workspace modules only, not transitive deps #340 / feat(auth): login flow + 2FA — closes #124 #341).packages/go/plugins/capabilities/registry.go::builtinCapabilityDefsinto a TS lookup so the consent UI renders meaningful descriptions ("Send transactional email on behalf of this site") before the host receives the install request. Sensitive caps are visually flagged; unknown ids surface as "Unrecognised" so out-of-band manifests can’t be silently consented to.File layout
Sidebargains a/pluginslink alongsideUsersandSettings.Verification
pnpm install --frozen-lockfile=false— cleanpnpm --filter @gonext/admin test— 87 / 87 passing (33 new tests across 6 new test files)pnpm --filter @gonext/admin typecheck— cleanpnpm --filter @gonext/admin lint— no errorsTest plan
reasonerroredplugins surface the last-error block as a role="alert"title=hint)🤖 Generated with Claude Code