{
  "id": "weather",
  "name": "Weather Panel",
  "category": "web",
  "tags": ["weather", "forecast", "temperature", "rain", "sun", "local"],
  "description": "Current weather and forecast for any city using Open-Meteo API (no key needed).",
  "triggers": ["weather", "forecast", "temperature", "rain check", "weather panel", "local weather"],
  "defaultSize": { "w": 4, "h": 5 },
  "source": "function WeatherPanel() {\n  const [city, setCity] = React.useState('REPLACE_WITH_CITY');\n  const [weather, setWeather] = React.useState(null);\n  const [loading, setLoading] = React.useState(false);\n\n  React.useEffect(() => {\n    if (!city) return;\n    setLoading(true);\n    fetch(`https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(city)}&count=1`)\n      .then(r=>r.json())\n      .then(geo=>{\n        const lat = geo.results?.[0]?.latitude;\n        const lon = geo.results?.[0]?.longitude;\n        if (!lat) return setLoading(false);\n        return fetch(`https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lon}&current=temperature_2m,weather_code&daily=temperature_2m_max,temperature_2m_min,weather_code&timezone=auto`);\n      })\n      .then(r=>r?.json())\n      .then(d=>{setWeather(d);setLoading(false);})\n      .catch(()=>setLoading(false));\n  }, [city]);\n\n  const wmo = {0:'☀️',1:'🌤️',2:'⛅',3:'☁️',45:'🌫️',48:'🌫️',51:'🌧️',53:'🌧️',55:'🌧️',61:'🌧️',63:'🌧️',65:'🌧️',71:'❄️',73:'❄️',75:'❄️',95:'⛈️'};\n\n  return (\n    <div style={{padding:16,fontFamily:'system-ui',height:'100%',display:'flex',flexDirection:'column'}}>\n      <div style={{display:'flex',gap:8,marginBottom:12}}>\n        <input value={city} onChange={e=>setCity(e.target.value)} onKeyDown={e=>e.key==='Enter'&&setCity(e.target.value)}\n          style={{flex:1,padding:'8px 12px',borderRadius:8,border:'1px solid #ccc',fontSize:14}}\n          placeholder=\"City name…\"/>\n        <button onClick={()=>setCity(city)}\n          style={{padding:'8px 16px',borderRadius:8,background:'#007AFF',color:'#fff',border:'none',cursor:'pointer'}}>\n          Search\n        </button>\n      </div>\n      {loading && <div style={{textAlign:'center',color:'#888'}}>Loading…</div>}\n      {weather && (\n        <div style={{flex:1}}>\n          <div style={{textAlign:'center',marginBottom:16}}>\n            <div style={{fontSize:48}}>{wmo[weather.current?.weather_code] || '🌡️'}</div>\n            <div style={{fontSize:36,fontWeight:200}}>{weather.current?.temperature_2m}°C</div>\n          </div>\n          <div style={{display:'flex',gap:8,overflow:'auto'}}>\n            {weather.daily?.time?.slice(0,5).map((t,i)=> (\n              <div key={i} style={{flex:1,textAlign:'center',padding:8,background:'#f5f5f5',borderRadius:8,minWidth:60}}>\n                <div style={{fontSize:11,color:'#888'}}>{new Date(t).toLocaleDateString('en',{weekday:'short'})}</div>\n                <div style={{fontSize:20}}>{wmo[weather.daily.weather_code[i]] || '🌡️'}</div>\n                <div style={{fontSize:12}}>{weather.daily.temperature_2m_max[i]}° / {weather.daily.temperature_2m_min[i]}°</div>\n              </div>\n            ))}\n          </div>\n        </div>\n      )}\n    </div>\n  );\n}\nrender(<WeatherPanel/>);",
  "placeholders": [
    { "name": "REPLACE_WITH_CITY", "description": "City name for weather lookup", "default": "San Francisco" }
  ]
}
