docs: design spec for the next.jarviscli.dev site
This commit is contained in:
parent
13800ddf01
commit
9be9438599
2 changed files with 140 additions and 0 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -12,3 +12,4 @@ node_modules/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.idea/
|
.idea/
|
||||||
*.iml
|
*.iml
|
||||||
|
.superpowers/
|
||||||
|
|
|
||||||
139
docs/superpowers/specs/2026-08-15-next-plugins-site-design.md
Normal file
139
docs/superpowers/specs/2026-08-15-next-plugins-site-design.md
Normal file
|
|
@ -0,0 +1,139 @@
|
||||||
|
# next.jarviscli.dev Design
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Build a public, browsable, installable plugin site for revenge-next-plugs at
|
||||||
|
`next.jarviscli.dev`, plus a token-gated admin panel for editing plugin
|
||||||
|
metadata and managing release channels. Currently that domain serves only a
|
||||||
|
bare `/index.json` install feed (Next's client-side install protocol) with no
|
||||||
|
HTML site at all.
|
||||||
|
|
||||||
|
Explicitly framed by the user as "a better advancement of classic's website"
|
||||||
|
(the equivalent site already built this session for the Vendetta-compat
|
||||||
|
`revenge-plugins` repo, at `rp.jarviscli.dev`) - reusing classic's proven
|
||||||
|
patterns where they fit, deliberately diverging where classic falls short.
|
||||||
|
|
||||||
|
## Audience
|
||||||
|
|
||||||
|
Both: end users browsing/installing plugins, and the repo owner using it as
|
||||||
|
an admin/management dashboard. Not a documentation site for other Next
|
||||||
|
plugin developers - out of scope for this design.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
A single Cloudflare Worker (extending the existing `revenge-next-plugs`
|
||||||
|
Worker, which currently only has a static `[assets]` binding) serves:
|
||||||
|
|
||||||
|
- `/` - public plugin browse page
|
||||||
|
- `/plugins/<id>` - plugin detail page, with per-plugin Open Graph metadata
|
||||||
|
- `/index.json` - the real install feed Next's client reads (format
|
||||||
|
unchanged from today, so nothing on the client side needs to change)
|
||||||
|
- `/admin` - token-gated admin UI
|
||||||
|
- `/api/admin/*` - admin write endpoints (protected server-side)
|
||||||
|
|
||||||
|
Two D1 tables hold live-editable state, read on every request and merged
|
||||||
|
with the base data already produced by the existing build pipeline
|
||||||
|
(`./gradlew packageAllPlugins` -> `build/dist/<id>.zip` + a base
|
||||||
|
`index.json`, generated exactly as today):
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE plugin_overrides (
|
||||||
|
id TEXT PRIMARY KEY, -- e.g. "dev.everestmcarthur.custom-tags"
|
||||||
|
name TEXT, description TEXT, tagline TEXT, note TEXT,
|
||||||
|
category TEXT, accent TEXT, status TEXT,
|
||||||
|
how_it_works TEXT, features TEXT, commands TEXT, limitations TEXT,
|
||||||
|
hidden INTEGER NOT NULL DEFAULT 0,
|
||||||
|
is_draft INTEGER NOT NULL DEFAULT 0,
|
||||||
|
manifest TEXT, -- only used when is_draft = 1
|
||||||
|
main_js TEXT, -- only used when is_draft = 1
|
||||||
|
updated_at TEXT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE plugin_channels (
|
||||||
|
plugin_id TEXT NOT NULL,
|
||||||
|
channel TEXT NOT NULL, -- 'alpha' | 'beta' | 'stable'
|
||||||
|
version TEXT NOT NULL,
|
||||||
|
updated_at TEXT NOT NULL,
|
||||||
|
PRIMARY KEY (plugin_id, channel)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
`is_draft = 1` plugins mirror classic's overlay system: a plugin that exists
|
||||||
|
entirely through the admin panel (manifest + JS stored directly in D1), never
|
||||||
|
touching git, for quick one-off testing.
|
||||||
|
|
||||||
|
No Durable Object / WebSocket live-broadcast (classic has one, for
|
||||||
|
multi-tab-sees-edits-instantly). Deliberately dropped: with one admin and two
|
||||||
|
plugins today, that's real infrastructure for a scenario that isn't
|
||||||
|
happening. A page refresh after saving covers it. Can be added later if that
|
||||||
|
stops being true.
|
||||||
|
|
||||||
|
## Channels
|
||||||
|
|
||||||
|
Every plugin version can be promoted to `alpha`, `beta`, or `stable` via the
|
||||||
|
admin panel. This is purely an admin-side staging mechanism for this site -
|
||||||
|
**the public site and the public `/index.json` only ever expose the version
|
||||||
|
currently on `stable`**, surfaced as `"latest"` in the install feed (matching
|
||||||
|
Next's current client-side protocol exactly, so installing a plugin from the
|
||||||
|
site behaves identically to today). Alpha/beta versions are visible only in
|
||||||
|
the admin panel. This is intentionally decoupled from whatever channel
|
||||||
|
system Next's core client eventually builds - the site's job is only to
|
||||||
|
control what gets exposed as `"latest"` for public install.
|
||||||
|
|
||||||
|
## Pages
|
||||||
|
|
||||||
|
**`/` (browse):** cards per visible (`hidden = 0`) plugin - icon, name,
|
||||||
|
tagline, channel badge, author, version, install button. Filter chips by
|
||||||
|
category. Visual direction: dark background, functional (not decorative) use
|
||||||
|
of a single purple accent - reserved for badges/interactive elements only,
|
||||||
|
never used as a glowing background gradient. Real header with nav. See the
|
||||||
|
approved mockup at `.superpowers/brainstorm/263484-1786809105/content/glass-refined.html`.
|
||||||
|
|
||||||
|
**`/plugins/<id>` (detail):** full description, how-it-works, features,
|
||||||
|
commands, limitations, source/issue links, install button. **Server-rendered
|
||||||
|
`<meta>` tags** (not client-side JS - link unfurlers don't execute JS):
|
||||||
|
`og:title` = plugin name, `og:description` = plugin's tagline/short
|
||||||
|
description, matching `twitter:card` tags. This directly fixes a real gap in
|
||||||
|
classic's site, where plugin links unfurl showing the site-wide branding
|
||||||
|
("revenge-plugins" / what Revenge is) instead of the linked plugin's own
|
||||||
|
info - classic's plugin pages never got their own `<meta>` tags. Not
|
||||||
|
proposing a fix to classic here (out of scope), just not repeating the
|
||||||
|
mistake.
|
||||||
|
|
||||||
|
**`/admin`:** gated by a single secret token (`ADMIN_TOKEN` Worker secret,
|
||||||
|
same mechanism as classic - compared server-side, entered once in the
|
||||||
|
browser and kept client-side for subsequent requests). Once authenticated:
|
||||||
|
edit any `plugin_overrides` field per plugin, toggle `hidden`, set
|
||||||
|
`alpha`/`beta`/`stable` -> version per plugin, create an `is_draft` plugin.
|
||||||
|
|
||||||
|
## Error handling
|
||||||
|
|
||||||
|
- D1 unreachable: Worker serves the base static (build-time) data with no
|
||||||
|
overrides applied, rather than failing the request. The site stays up;
|
||||||
|
admin edits just don't show until D1 recovers.
|
||||||
|
- Promoting a version to a channel that doesn't exist in the built index is
|
||||||
|
rejected with a clear error (mirrors the existing check in
|
||||||
|
`generate-index.ts` for `repo.config.json` channel overrides: "Channel
|
||||||
|
override .../... points at unpublished version").
|
||||||
|
- Missing or incorrect admin token: clean 401 on every `/api/admin/*`
|
||||||
|
endpoint, no partial access.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
Extends the existing `.github/scripts/verify-deploy.mjs` post-deploy smoke
|
||||||
|
test:
|
||||||
|
|
||||||
|
- `/index.json` parses and every advertised `sha256` matches the real zip
|
||||||
|
bytes (existing check, unchanged).
|
||||||
|
- A plugin detail page's `og:title`/`og:description` actually reflect that
|
||||||
|
plugin's own name/description, not a site-wide fallback.
|
||||||
|
- An unauthenticated request to an admin write endpoint returns 401 (catches
|
||||||
|
the gate silently ending up open after a deploy).
|
||||||
|
|
||||||
|
## Out of scope
|
||||||
|
|
||||||
|
- Documentation/reference site for other Next plugin developers.
|
||||||
|
- Exposing channel selection to end users (Next core may build this
|
||||||
|
separately; this site's public feed only ever shows `stable`).
|
||||||
|
- Live multi-tab broadcast of admin edits (Durable Object/WebSocket).
|
||||||
|
- Any changes to classic's (`revenge-plugins`) site.
|
||||||
Loading…
Add table
Reference in a new issue