From 154038044276766df6d88fa397639ac9493984a5 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 18 Jun 2026 20:17:23 +0000 Subject: [PATCH] Add Weather integration adapter Implements testConnection against wttr.in's JSON API using the configured location, no API key required. listResources is intentionally omitted since weather conditions don't map to the resource-health model. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01BbJV5nm8KPVH1oNJYKpnoF --- backend/src/integrations/registry.ts | 3 ++- backend/src/integrations/weather.ts | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 backend/src/integrations/weather.ts diff --git a/backend/src/integrations/registry.ts b/backend/src/integrations/registry.ts index 2f9f0b6..f64c189 100644 --- a/backend/src/integrations/registry.ts +++ b/backend/src/integrations/registry.ts @@ -4,6 +4,7 @@ import { docker } from './docker.js' import { proxmox } from './proxmox.js' import { netbird } from './netbird.js' import { cloudflare } from './cloudflare.js' +import { weather } from './weather.js' const notImplemented: IntegrationAdapter = { async testConnection() { @@ -18,5 +19,5 @@ export const adapterRegistry: Record = { netbird, cloudflare, aws: notImplemented, - weather: notImplemented, + weather, } diff --git a/backend/src/integrations/weather.ts b/backend/src/integrations/weather.ts new file mode 100644 index 0000000..0ad2e0b --- /dev/null +++ b/backend/src/integrations/weather.ts @@ -0,0 +1,19 @@ +import type { IntegrationAdapter } from './types.js' + +export const weather: IntegrationAdapter = { + async testConnection(config) { + const location = config.location + if (!location) return { ok: false, message: 'Missing location' } + try { + const res = await fetch(`https://wttr.in/${encodeURIComponent(location)}?format=j1`, { + headers: { 'User-Agent': 'curl' }, + }) + if (!res.ok) return { ok: false, message: `HTTP ${res.status}` } + const body = (await res.json()) as { current_condition?: unknown[] } + if (!body.current_condition?.length) return { ok: false, message: 'Location not found' } + return { ok: true, message: 'Connected' } + } catch (err) { + return { ok: false, message: err instanceof Error ? err.message : 'Connection failed' } + } + }, +}