diff --git a/app/backend/internal/api/system.go b/app/backend/internal/api/system.go index fac4de0..b075867 100644 --- a/app/backend/internal/api/system.go +++ b/app/backend/internal/api/system.go @@ -40,6 +40,9 @@ type hostMonitoringResponse struct { UptimeSeconds int64 `json:"uptime_seconds"` DockerAvailable bool `json:"docker_available"` Docker map[string]any `json:"docker,omitempty"` + // Scope names what the telemetry actually measures: the physical host for + // native dockerd, or the Docker Desktop VM when the daemon runs in one. + Scope string `json:"scope"` CollectedAt string `json:"collected_at"` } @@ -159,6 +162,7 @@ func handleGetHostMonitoring(c *gin.Context) { Storage: storage, Load: load, UptimeSeconds: uptime, + Scope: "host", CollectedAt: time.Now().UTC().Format(time.RFC3339), } @@ -173,6 +177,10 @@ func handleGetHostMonitoring(c *gin.Context) { "images": info.Images, "driver": info.Driver, "server": info.ServerVersion, + "os": info.OperatingSystem, + } + if strings.Contains(strings.ToLower(info.OperatingSystem), "docker desktop") { + response.Scope = "docker-desktop-vm" } } } diff --git a/app/frontend/src/features/projects/pages/ProjectsPage.tsx b/app/frontend/src/features/projects/pages/ProjectsPage.tsx index c2d9873..6f399f6 100644 --- a/app/frontend/src/features/projects/pages/ProjectsPage.tsx +++ b/app/frontend/src/features/projects/pages/ProjectsPage.tsx @@ -181,6 +181,7 @@ export function ProjectsPage() { const totalServices = projects.reduce((sum, p) => sum + p.stats.service_count, 0); const runningServices = projects.reduce((sum, p) => sum + p.stats.running_services, 0); const host = hostQuery.data; + const hostLabel = host?.scope === 'docker-desktop-vm' ? 'VM' : 'HOST'; const cpuPct = isDemoMode ? 14 : host && host.cpu.cores > 0 ? Math.min(100, Math.round((host.load.load1m / host.cpu.cores) * 100)) : null; @@ -243,7 +244,7 @@ export function ProjectsPage() { {/* Host stat row */}
-
HOST.CPU
+
{hostLabel}.CPU
{cpuPct ?? '—'}%
{isDemoMode ? (
@@ -259,13 +260,13 @@ export function ProjectsPage() {
-
HOST.MEM
+
{hostLabel}.MEM
{memPct ?? '—'}%
85 ? 'r' : 'y'} style={{ width: `${memPct ?? 0}%` }} />
{isDemoMode ? '9.8G / 13G' : host ? `${fmtGB(host.memory.used)} / ${fmtGB(host.memory.total)}` : 'no telemetry'}
-
HOST.DISK
+
{hostLabel}.DISK
{diskPct ?? '—'}%
{isDemoMode ? '338G of 465G · high' : host ? `${fmtGB(host.storage.used)} of ${fmtGB(host.storage.total)}` : 'no telemetry'}
diff --git a/app/frontend/src/generated/api-types.ts b/app/frontend/src/generated/api-types.ts index e2af875..53d0133 100644 --- a/app/frontend/src/generated/api-types.ts +++ b/app/frontend/src/generated/api-types.ts @@ -8299,7 +8299,13 @@ export interface components { images?: number; driver?: string; server?: string; + os?: string; }; + /** + * @description What the telemetry measures — `host` for a native daemon, `docker-desktop-vm` when Docker runs inside a Desktop VM. + * @enum {string} + */ + scope?: "host" | "docker-desktop-vm"; /** Format: date-time */ collected_at?: string; }; diff --git a/app/frontend/src/lib/api-client.ts b/app/frontend/src/lib/api-client.ts index fb1f06f..f98757e 100644 --- a/app/frontend/src/lib/api-client.ts +++ b/app/frontend/src/lib/api-client.ts @@ -225,7 +225,9 @@ export type HostMonitoring = { images?: number; driver?: string; server?: string; + os?: string; }; + scope: 'host' | 'docker-desktop-vm'; collectedAt: string; }; @@ -888,6 +890,7 @@ function normalizeHostMonitoring(payload: RawHostMonitoring): HostMonitoring { uptimeSeconds: payload.uptime_seconds ?? 0, dockerAvailable: Boolean(payload.docker_available), docker: payload.docker, + scope: payload.scope === 'docker-desktop-vm' ? 'docker-desktop-vm' : 'host', collectedAt: payload.collected_at ?? '', }; } diff --git a/app/frontend/vite.config.d.ts b/app/frontend/vite.config.d.ts deleted file mode 100644 index 340562a..0000000 --- a/app/frontend/vite.config.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare const _default: import("vite").UserConfig; -export default _default; diff --git a/app/frontend/vite.config.js b/app/frontend/vite.config.js deleted file mode 100644 index 51bc166..0000000 --- a/app/frontend/vite.config.js +++ /dev/null @@ -1,51 +0,0 @@ -import { defineConfig } from 'vite'; -import react from '@vitejs/plugin-react'; -import path from 'path'; -// https://vite.dev/config/ -export default defineConfig({ - plugins: [react()], - resolve: { - alias: { - "@": path.resolve(__dirname, "./src"), - }, - }, - build: { - // Enable code splitting and optimization - rollupOptions: { - output: { - manualChunks: { - // Split vendor libraries - vendor: ['react', 'react-dom', '@tanstack/react-query'], - ui: ['@radix-ui/react-dialog', '@radix-ui/react-dropdown-menu', 'lucide-react'], - utils: ['date-fns', 'clsx', 'tailwind-merge'] - }, - // Optimize chunk naming for better caching - chunkFileNames: 'assets/js/[name]-[hash].js', - entryFileNames: 'assets/js/[name]-[hash].js', - assetFileNames: 'assets/[ext]/[name]-[hash].[ext]' - } - }, - // Enable source maps for production debugging - sourcemap: true, - // Optimize bundle size - minify: 'terser', - // Set appropriate chunk size limit for better caching - chunkSizeWarningLimit: 1000 - }, - // Optimize dependencies during build - optimizeDeps: { - include: ['react', 'react-dom', '@tanstack/react-query', 'date-fns'] - }, - // Development server optimization - server: { - fs: { - // Allow serving files from project root - allow: ['..'] - } - }, - // Preview server optimization - preview: { - port: 4173, - strictPort: true - } -}); diff --git a/app/frontend/vite.config.ts b/app/frontend/vite.config.ts index a361aa8..60f2eb8 100644 --- a/app/frontend/vite.config.ts +++ b/app/frontend/vite.config.ts @@ -30,7 +30,9 @@ export default defineConfig({ // Split vendor libraries vendor: ['react', 'react-dom', '@tanstack/react-query'], ui: ['@radix-ui/react-dialog', '@radix-ui/react-dropdown-menu', 'lucide-react'], - utils: ['date-fns', 'clsx', 'tailwind-merge'] + utils: ['date-fns', 'clsx', 'tailwind-merge'], + canvas: ['@xyflow/react'], + charts: ['recharts'] }, // Optimize chunk naming for better caching chunkFileNames: 'assets/js/[name]-[hash].js', diff --git a/docs/api/openapi.yaml b/docs/api/openapi.yaml index c8a3929..e47cd1d 100644 --- a/docs/api/openapi.yaml +++ b/docs/api/openapi.yaml @@ -6052,6 +6052,12 @@ components: type: string server: type: string + os: + type: string + scope: + type: string + description: What the telemetry measures — `host` for a native daemon, `docker-desktop-vm` when Docker runs inside a Desktop VM. + enum: [host, docker-desktop-vm] collected_at: type: string format: date-time