# Extensions Plugin system with three tiers: Browser JS (client-side), Starlark sandbox (server-side, v0.29.0), Sidecar containers (server-side, future). Currently only Browser tier is implemented. ### User Extensions **Auth:** Authenticated user ``` GET /extensions → {"data": [...UserExtension]} ?tier=browser (optional filter by tier) POST /extensions/:id/settings ← {"is_enabled": bool, "settings": {...}} :id = extension UUID → {"ok": true} GET /extensions/:id/manifest → {"data": } :id = ext_id (manifest id) GET /extensions/tools → {"data": [...tool schema objects]} ``` **Notes:** - `GET /extensions` returns `UserExtension` objects: the base extension fields plus `user_enabled` and `user_settings` overrides. - System extensions (`is_system: true`) cannot be disabled by users. Attempting to set `is_enabled: false` on a system extension returns 403. - `GET /extensions/tools` returns raw tool schema JSON from all enabled browser extensions' `manifest.tools[]` arrays. ### Admin Extension Management **Auth:** Admin role ``` GET /admin/extensions → {"data": [...Extension]} POST /admin/extensions ← {ext_id*, name*, version?, tier?, description?, author?, manifest?, is_system?, is_enabled?} → {"data": Extension} (201) PUT /admin/extensions/:id ← {name?, version?, description?, :id = extension UUID author?, is_system?, is_enabled?, manifest?} → {"data": Extension} DELETE /admin/extensions/:id → {"ok": true} :id = extension UUID ``` **Install defaults:** `version` → `"0.0.0"`, `tier` → `"browser"`, `manifest` → `{}`, `scope` → `"global"`. **Tier validation:** `tier` must be one of: `browser`, `starlark`, `sidecar`. **Duplicate rejection:** If `ext_id` is already installed, returns 409. ### Asset Serving **Auth:** None (public — script tags can't send Authorization headers) ``` GET /extensions/:id/assets/*path → application/javascript :id = ext_id (manifest id) ``` Returns the inline `_script` field from the extension's manifest. The `*path` segment is accepted but currently ignored (all requests return the same script). Disabled extensions return 404. ### Builtin Seeding On startup, `SeedBuiltinExtensions()` scans `extensions/builtin/` for subdirectories containing `manifest.json` + `script.js`. Each is upserted as a system extension: - **New ext_id** → `Create` with `is_system: true` - **Same version** → skip (idempotent) - **Different version** → `Update` manifest, name, description, author ---