From db19a14fd4b28da48c30fc42684a57c736dcb574 Mon Sep 17 00:00:00 2001 From: gionnibgud Date: Tue, 21 Jul 2026 17:13:21 +0200 Subject: [PATCH] docs: align route-prefix examples with the Host's /api/plugins/ (plural) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every illustrative route prefix said /api/plugin// (singular): spec §7.3, two mentions in best-practices.md, and examples/full-plugin throughout (routes.py, screen.js, settings.html). The Host serves plugin routes under /api/plugins/ — ~90 occurrences across core's plugins/, zero singular — so a newcomer copying the official example registered routes whose derived client paths 404 against a real install. best-practices.md was also internally inconsistent: its other four route-prefix mentions already used the plural form. PATCH-level per CONTRIBUTING's bump table: the normative requirement (§7.4, derive every route path from the plugin id) is unchanged; the singular form only ever appeared in examples and prose. No schema change, no version bump — entry added under CHANGELOG [Unreleased]. Closes #20 Co-Authored-By: Claude Opus 4.8 Signed-off-by: gionnibgud --- CHANGELOG.md | 10 ++++++++++ examples/full-plugin/routes.py | 4 ++-- examples/full-plugin/screen.js | 4 ++-- examples/full-plugin/settings.html | 2 +- spec/best-practices.md | 4 ++-- spec/plugin-spec-v1.md | 2 +- 6 files changed, 18 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5a97ec..8a62a78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,16 @@ for how the document, manifest, and per-plugin versions relate. ## [Unreleased] +### Fixed +- **Route-prefix examples now match the Host.** Every illustrative route prefix said + `/api/plugin//…` (singular) in §7.3, twice in `best-practices.md`, and throughout + `examples/full-plugin` (`routes.py`, `screen.js`, `settings.html`), while the feedBack Host + serves plugin routes under **`/api/plugins/…`** (plural) — and the rest of + `best-practices.md` already used the plural form. All examples and prose now use + `/api/plugins//…`. The normative rule (§7.4: derive every route path from the plugin + `id`) is unchanged — the singular form only ever appeared in examples, never as a + requirement. Closes [#20](https://github.com/got-feedBack/feedBack-plugin-spec/issues/20). + ### Added - **Module `script` entries.** §3 (Anatomy), §4.1/§4.3, new §6.8 (Splitting client code), and `schemas/plugin.schema.json` document the optional **`scriptType`** manifest key: `"module"` loads diff --git a/examples/full-plugin/routes.py b/examples/full-plugin/routes.py index d8e97e0..9a29322 100644 --- a/examples/full-plugin/routes.py +++ b/examples/full-plugin/routes.py @@ -35,11 +35,11 @@ def _read() -> dict: return dict(_DEFAULTS) # Everything below only runs after the plugin has validated its own state. - @app.get(f"/api/plugin/{PLUGIN_ID}/settings") + @app.get(f"/api/plugins/{PLUGIN_ID}/settings") def get_settings() -> JSONResponse: return JSONResponse(_read()) - @app.post(f"/api/plugin/{PLUGIN_ID}/settings") + @app.post(f"/api/plugins/{PLUGIN_ID}/settings") async def set_settings(request: Request) -> JSONResponse: incoming = await request.json() if not isinstance(incoming, dict): diff --git a/examples/full-plugin/screen.js b/examples/full-plugin/screen.js index b084ed9..d0134ab 100644 --- a/examples/full-plugin/screen.js +++ b/examples/full-plugin/screen.js @@ -3,7 +3,7 @@ // The exact runtime API the Host exposes to a plugin screen is Host-provided and // out of scope for spec v0.1.0 (see spec §6.1). This file shows the *shape* of a // screen module: it renders into its own root element and talks only to its own -// namespaced routes (/api/plugin/full-plugin/...). Keep all DOM and CSS scoped to +// namespaced routes (/api/plugins/full-plugin/...). Keep all DOM and CSS scoped to // the plugin's root so nothing leaks into the rest of the app. const PLUGIN_ID = "full-plugin"; @@ -17,7 +17,7 @@ export async function mount(root) { `; try { - const res = await fetch(`/api/plugin/${PLUGIN_ID}/settings`); + const res = await fetch(`/api/plugins/${PLUGIN_ID}/settings`); const settings = await res.json(); root.querySelector('[data-role="color"]').textContent = settings.color; } catch (err) { diff --git a/examples/full-plugin/settings.html b/examples/full-plugin/settings.html index 4bd7ba7..dbb4d96 100644 --- a/examples/full-plugin/settings.html +++ b/examples/full-plugin/settings.html @@ -2,7 +2,7 @@ Settings panel for the full-plugin example. The Host renders this markup in the plugin's settings slot, grouped under settings.category ("graphics"). Scope any styles/scripts to the panel; persist values through the plugin's own routes - (/api/plugin/full-plugin/settings), not by writing files directly from the client. + (/api/plugins/full-plugin/settings), not by writing files directly from the client. -->