Adds a new "openWebUi" integration kind (under a new "ai" category) and an
AI Chat widget for chatting with models served by Open WebUI.
- Integration: Bearer API key auth, model list, native chat history CRUD, and
token-by-token streaming chat completions (SSE).
- Widget: in-input model picker, streaming responses, and an in-widget history
panel. Reconstructs conversations from Open WebUI's message tree with a flat
fallback.
- Streaming is delivered over the WebSocket subscription link.
- Adds integration and widget documentation.
Adds a Docker button to the user avatar dropdown menu (admin-only)
that opens a 1400px modal containing the same Docker container table
as /manage/tools/docker.
Closes#2165
* fix(manage/about): bypass self-fetch to prevent ECONNREFUSED crash
The /manage/about page fetched its own API routes over HTTP
(http://$HOSTNAME:3000/api/about/...). When the server could not
reach itself (misconfigured HOSTNAME, restricted container networking,
reverse-proxy setups), fetch threw ECONNREFUSED and the whole page
crashed with a full-page Next.js error (issue #6008).
All four routes were force-static serving static JSON / a direct fs
read, so the HTTP round-trip was unnecessary. Replace the fetches
with direct JSON imports and a direct getDependenciesAsync() call,
eliminating the self-network dependency entirely.
Also add a manage-level error.tsx boundary (Next.js 16 convention) so
that any future runtime error in a manage page renders a friendly,
localised fallback inside the existing layout (sidebar stays usable)
instead of the ugly default full-page error.
Exploration draft by an LLM.
Refs #6008
* style: auto-fix lint and format
* refactor: use @static-data path alias, simplify error ternary
- Add @static-data/* tsconfig path alias to replace 7-level relative
imports (../../../../../../../static-data/...) with clean alias
imports across the about page and all 3 API route handlers.
- Simplify error.tsx: replace ternary with && short-circuit.
- Preserve CI lint bot's .sort() -> .toSorted() fix.
Refs #6008
* feat(analytics): migrate from Umami to PostHog server-side analytics
Replace @umami/node with posthog-node for all server-side telemetry.
Add singleton PostHog client, feature tracking POC, DAU heartbeat,
and tRPC analytics router. Cron job is now locked (no manual trigger,
no custom interval). Update consent copy to explain what we collect
and why.
* style: auto-fix lint and format
* refactor(analytics): simplify + add client-side posthog-js init
- Inline constants.ts and track.ts into client.ts (single source)
- Remove dead exports (shutdownPostHogAsync, getPostHogClient)
- Flatten all DB queries into one Promise.all (no waterfall)
- Derive integration/widget totals from group-by (drop redundant counts)
- Add posthog-js with dynamic import, gated on enableGeneral
- Move Analytics component to body, pass consent from server settings
* style: auto-fix lint and format
* feat(cron): add hidden flag to cron jobs, hide analytics from task panel
The analytics job runs silently in the background — users don't need
to see or interact with it. Hidden jobs are filtered out of getAllAsync
so they never appear in the management UI.
* refactor(analytics): simplify to single toggle, always collect all data
Remove granular enableWidgetData/enableIntegrationData/enableUserData
toggles. Analytics is now a single on/off switch. When enabled, all
anonymous usage data is collected in one flat Promise.all call.
Side effect: existing users with enableGeneral=true who had granular
flags off will now send all data. This is by design — the granular
controls added complexity without meaningful privacy benefit since
the data is already anonymous counts.
* style: auto-fix lint and format
- Remove ternary operators from new code (widget-integration-select,
TabsContainer, mock data, members page)
- Remove stale /docs/management/tools/backup from sitemap type
- Add value prop to error-state Select in beszel-system-stats
The Gotify integration (merged from dev) declares a documentationUrl but
had no docs page, failing the docs-coverage validation plugin once gotify
was added to the integration doc-slug map.
Merging dev introduced the Gotify integration and ArchiveTeam Warrior
widget/integration, which require entries in the doc-slug maps and the
generated documentation sitemap. Also remove a misplaced non-null
assertion in the group members page flagged by oxlint.
- Throw TRPCError instead of returning null when no integration
- Sort beszelRouter import alphabetically in mcp.ts
- Replace ternary with lookup table for background color
- Mention integration_all in MCP server instructions
Register beszelRouter in the MCP server with .meta({ mcp: enabled })
on getSystems, getAlerts, and getSystemStats procedures. AI assistants
can now query Beszel-monitored systems, view alerts, and fetch
historical metrics through the MCP protocol.
Ref #5968
The SWC HTML minifier rejects slightly invalid HTML that browsers
tolerate, breaking the build on every page. Disable it while keeping
all other Docusaurus Faster optimizations.
Also fix broken relative links in after-the-installation.mdx and
donate.mdx by using absolute paths.
GitHub Pages redirects non-trailing-slash URLs with 301, causing
Algolia crawler to ignore all sitemap entries. Setting trailingSlash
to true aligns generated URLs with what GitHub Pages actually serves.
* fix(boards): add permissions to board summary schema to fix manage page crash
The getAllBoards query fetches userPermissions and groupPermissions
from the DB, but boardSummarySchema (the output validator) did not
include them. tRPC stripped the fields, causing a TypeError when
getBoardPermissionsAsync called .some() on undefined.
* fix(backup): cast Buffer to Uint8Array for NextResponse body
Node 24 narrowed the BodyInit type, making Buffer incompatible.
Wrapping in Uint8Array satisfies the type constraint.
* fix(lint): remove forbidden non-null assertions across backup and board code
Replace non-null assertions with safe guards, optional chaining, and
for-of iteration so oxlint passes in CI. Also remove unused Collapse import.