diff --git a/apps/web/pages/index.vue b/apps/web/pages/index.vue
index fe3507c..4c851c2 100644
--- a/apps/web/pages/index.vue
+++ b/apps/web/pages/index.vue
@@ -1,5 +1,12 @@
+
+
+
+ {{ farm.name }}
+ Gateway {{ gateway }}
+
+ Discovered printers ({{ candidates.length }})
+ {{ discoveryNote }}
+
+ -
+ {{ label(c) }} - {{ c.vendor }} at {{ c.address }}
+ - already added
+ - same address as an added printer (check)
+ - not added yet
+
+
+
+
+
+
+
diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts
index 2278115..955be66 100644
--- a/packages/ui/src/index.ts
+++ b/packages/ui/src/index.ts
@@ -4,4 +4,5 @@ export { default as TemperatureGraph } from "./components/TemperatureGraph.vue";
export { default as WebRTCStreamView } from "./components/WebRTCStreamView.vue";
export { default as JobList } from "./components/JobList.vue";
export { default as JobUpload } from "./components/JobUpload.vue";
-export type { AppFarm, AppJob, AppPrinterState, AppTelemetryMessage, PrinterCommand } from "./types";
+export { default as FarmStatus } from "./components/FarmStatus.vue";
+export type { AppDiscoveredCandidate, AppFarm, AppFarmDiscovery, AppJob, AppPrinterState, AppTelemetryMessage, PrinterCommand } from "./types";
diff --git a/packages/ui/src/types.ts b/packages/ui/src/types.ts
index 7257fb3..c3bc1ac 100644
--- a/packages/ui/src/types.ts
+++ b/packages/ui/src/types.ts
@@ -79,3 +79,25 @@ export interface AppJob {
progressPct?: number | null;
createdAt: string;
}
+
+/**
+ * `GET /farms/:id/discovered-printers`. `discovery` is null when the gateway
+ * has never reported a scan - almost always because discovery is off, which
+ * is its default - and that is not the same as a report with no printers.
+ */
+export interface AppDiscoveredCandidate {
+ address: string;
+ vendor: string;
+ name?: string | null;
+ model?: string | null;
+ serial?: string | null;
+ /** The printer row this candidate looks like, and how sure that is. */
+ existingPrinterId?: string | null;
+ matchedOn?: "serial" | "address" | null;
+}
+
+export interface AppFarmDiscovery {
+ farmId: string;
+ gatewayOnline: boolean;
+ discovery: { scannedAt: string; printers: AppDiscoveredCandidate[] } | null;
+}