nothumanallowed 13.5.175 → 13.5.176

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nothumanallowed",
3
- "version": "13.5.175",
3
+ "version": "13.5.176",
4
4
  "description": "NotHumanAllowed — 38 AI agents, 80 tools, Studio (visual agentic workflows). Email, calendar, browser automation, screen capture, canvas, cron/heartbeat, Alexandria E2E messaging, GitHub, Notion, Slack, voice chat, free AI (Liara), 28 languages. Zero-dependency CLI.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/constants.mjs CHANGED
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'url';
5
5
  const __filename = fileURLToPath(import.meta.url);
6
6
  const __dirname = path.dirname(__filename);
7
7
 
8
- export const VERSION = '13.5.175';
8
+ export const VERSION = '13.5.176';
9
9
  export const BASE_URL = 'https://nothumanallowed.com/cli';
10
10
  export const API_BASE = 'https://nothumanallowed.com/api/v1';
11
11
 
@@ -302,6 +302,12 @@ TOOLS:
302
302
  Returns: title, excerpt, and body text (max 8000 chars). Only fetches text/html/json/xml.
303
303
  Use this when the user provides a specific URL to read, summarize, or analyze.
304
304
 
305
+ 49. get_weather(location: string, lang?: string)
306
+ Get current weather and 3-day forecast for any city or location. No API key needed.
307
+ Returns: temperature (°C/°F), feels like, humidity, wind speed, UV index, weather condition, and 3-day forecast.
308
+ ALWAYS use this for weather requests ("meteo", "tempo", "weather", "temperatura", "piove", "sole", "forecast").
309
+ Examples: get_weather("Viterbo"), get_weather("Rome, Italy"), get_weather("New York")
310
+
305
311
  --- BROWSER AUTOMATION ---
306
312
 
307
313
  49. browser_open(url: string, waitForLoad?: boolean)
@@ -599,7 +605,7 @@ note_add · note_list
599
605
  github_issues · github_prs · github_notifications · github_create_issue
600
606
  notion_search · notion_page
601
607
  slack_channels · slack_messages · slack_send
602
- web_search · fetch_url
608
+ web_search · fetch_url · get_weather
603
609
  browser_open · browser_screenshot · browser_click · browser_type · browser_extract · browser_js · browser_wait · browser_scroll · browser_key · browser_close
604
610
  cron_add · cron_list · cron_remove
605
611
  screen_capture · screen_analyze
@@ -1876,6 +1882,62 @@ export async function executeTool(action, params, config) {
1876
1882
  return lines.join('\n');
1877
1883
  }
1878
1884
 
1885
+ // ── Weather ──────────────────────────────────────────────────────────
1886
+ case 'get_weather': {
1887
+ const location = (params.location || '').trim();
1888
+ if (!location) return 'A location is required (e.g. "Rome", "Viterbo, Italy").';
1889
+ try {
1890
+ const encodedLoc = encodeURIComponent(location);
1891
+ const wttrRes = await fetch(`https://wttr.in/${encodedLoc}?format=j1`, {
1892
+ headers: { 'User-Agent': 'nha-cli/1.0' },
1893
+ signal: AbortSignal.timeout(8000),
1894
+ });
1895
+ if (!wttrRes.ok) return `Weather service returned ${wttrRes.status} for "${location}". Try a different location name.`;
1896
+ const w = await wttrRes.json();
1897
+ const cur = w.current_condition?.[0];
1898
+ const area = w.nearest_area?.[0];
1899
+ if (!cur) return `No weather data found for "${location}".`;
1900
+
1901
+ const cityName = area?.areaName?.[0]?.value || location;
1902
+ const country = area?.country?.[0]?.value || '';
1903
+ const desc = cur.weatherDesc?.[0]?.value || '';
1904
+ const tempC = cur.temp_C;
1905
+ const feelsC = cur.FeelsLikeC;
1906
+ const humidity = cur.humidity;
1907
+ const windKmph = cur.windspeedKmph;
1908
+ const windDir = cur.winddir16Point;
1909
+ const uvIndex = cur.uvIndex;
1910
+ const visibility = cur.visibility;
1911
+ const cloudcover = cur.cloudcover;
1912
+
1913
+ const lines = [
1914
+ `📍 ${cityName}${country ? ', ' + country : ''}`,
1915
+ `🌡️ ${tempC}°C (feels like ${feelsC}°C) — ${desc}`,
1916
+ `💧 Humidity: ${humidity}% | 💨 Wind: ${windKmph} km/h ${windDir}`,
1917
+ `☀️ UV Index: ${uvIndex} | 👁️ Visibility: ${visibility} km | ☁️ Cloud: ${cloudcover}%`,
1918
+ ];
1919
+
1920
+ // 3-day forecast
1921
+ const forecast = w.weather || [];
1922
+ if (forecast.length > 0) {
1923
+ lines.push('');
1924
+ lines.push('📅 3-day forecast:');
1925
+ for (const day of forecast.slice(0, 3)) {
1926
+ const date = day.date;
1927
+ const maxC = day.maxtempC;
1928
+ const minC = day.mintempC;
1929
+ const dayDesc = day.hourly?.[4]?.weatherDesc?.[0]?.value || '';
1930
+ const rain = day.hourly?.[4]?.chanceofrain || '0';
1931
+ lines.push(` ${date}: ${minC}°C → ${maxC}°C ${dayDesc} 🌧️ ${rain}% rain`);
1932
+ }
1933
+ }
1934
+
1935
+ return lines.join('\n');
1936
+ } catch (e) {
1937
+ return `Weather lookup failed: ${e.message}. Try using web_search("weather ${location}") as fallback.`;
1938
+ }
1939
+ }
1940
+
1879
1941
  // ── Cron / Heartbeat ───────────────────────────────────────────────
1880
1942
  case 'cron_add': {
1881
1943
  const { addCronJob } = await import('./ops-daemon.mjs');