#11 Smart Morning Briefing: auto-speaks once per day before noon — fetches
tasks, appointments, active alerts, and weather, composes a ~2-sentence TTS
summary. Stored in localStorage (jarvis_brief_YYYY-MM-DD) to fire only once.
#12 Quick Command Palette (Ctrl+K): frosted-glass overlay with 20 pre-loaded
commands across 6 groups (Network/Agents/Planner/Media/Smart Home/System).
Fuzzy filter as you type, arrow-key navigation, Enter to fire. Matches are
highlighted. Backdrop click or Escape to close.
#13 Live Boot Animation: stat bars and numbers now count from 0 on first render
via tickTo() change. Arc Reactor rings spin in with staggered delays (0.08s
per ring) on login using boot-spin CSS class + @keyframes arcBootSpin.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Mobile UI: 3-button bottom nav with panel switcher
- Chat history search: search modal with keyword query
- News filtering: category filter with localStorage persistence
- Proactive reminders: planner/appointment alerts at login and every 5 min
- Proactive alerts: polls every 60s, speaks new critical/warning alerts
- Agent sparklines: 2h CPU+MEM sparkline on each online agent card
- Tier source badge: KB/GROQ/CLAUDE/OLLAMA pill shown after each reply
- VM suggestions: 24h resource analysis via voice command
- HA scene control: fuzzy-match scene activation via voice
- Jellyfin control: pause/stop/next/previous via voice and KB
- Pattern suggestions: usage_patterns table + proactive chips every 30 min
- Multi-step commands: compound "X and Y" command parsing (Tier 0.5)
- Arc Reactor health: warning=amber/1.2s, critical=red/0.6s pulse encoding
- Cross-session history: last 6 turns loaded from prior session
- Restart agent: voice command to restart any JARVIS agent
- New endpoints: history.php, metrics.php, suggestions.php, jellyfin.php
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ha.php: GET scenes action returns live scene list from HA; POST scene_activate triggers by entity_id
- chat.php: ha_scene intent fetches all scenes live, fuzzy token-matches against message, calls scene.turn_on; falls back to listing available scenes if no match
- KB intents: 14 patterns covering good night/morning/goodbye/kitchen lights/ocean dawn/porch + generic activate/run/trigger/set scene
Scenes available: Good Night, Good Morning, Good Morning Work, Goodbye, Kitchen Lights On/Off, Front Porch Lights, Office Ocean Dawn, Master Bedroom
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Proactive alerts (#1): polls every 60s; baselines on load so old alerts are silent; speaks new critical/warning alerts aloud if voice active; adds chat bubble for all new alerts
- Jellyfin control (#2): pause/stop/next/previous via voice — auto-detects active session; 12 KB intents; jellyfin.php control action uses Jellyfin General Commands API
- Agent sparklines (#6): metrics.php returns 2h CPU+MEM history per agent; SVG polyline sparklines rendered in each agent card (cyan=CPU, green=MEM); non-blocking fetch so existing view shows instantly
- Agent health CCR (#7): updated hourly cloud routine to current 13-agent roster, removed ollama-ai and alien-pc, added all active agents with correct IPs/IDs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Voice commands (#3): say "restart the homebridge agent" or "restart mediastack agent" → queues restart_service to that agent; lists options if no hostname matched; 6 KB intents added
- Persistent context (#4): chat.php now loads last 6 turns from most recent prior session before current session history, giving JARVIS memory across page reloads
- Proactive reminders (#5): 3s after login, auto-announces overdue tasks / tasks due today / upcoming appointments; 5-min interval checks for appointments starting within 15 min and speaks alert once
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Instead of crash-looping with KeyError when config has old key names,
load_config() now detects and migrates automatically:
- server_url -> jarvis_url
- api_key -> registration_key
- adds hostname from gethostname() if missing
- adds ssl_verify (false if URL is a bare IP)
- falls back to /opt/jarvis-agent/config.json if /etc path missing
Migrated config is saved in place so the fix is permanent.
Agents self-update within 24h via the existing update_url mechanism.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two issues:
1. NM_OPEN_RE regex was too narrow — phrases like "show me the network",
"open the network", "show network status" did not match, so they fell
through to the API which returned text but never opened the map.
Broadened regex to catch natural network-related phrases.
2. When the network_scan intent IS triggered via API, the map never opened
because the API response handler only processed reply/arc_job.
chat.php now returns open_network_map:true for network_scan intent,
and the client calls openNetMap() when that flag is present.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Detects nordlynx WireGuard interface on hosts that run NordVPN and
includes active/inactive status in the metrics payload. JARVIS alerts.php
will generate a critical alert and auto-restart nordvpnd if it goes down.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After writing the updated script, _stop_event.set() caused a clean exit
(code 0). SCM failure recovery only fires on non-zero exit, so the service
stayed down permanently after every auto-update.
Fix: set _update_restart=True before signalling stop; SvcDoRun() checks
the flag after main() returns and calls sys.exit(1), which triggers the
sc.exe failure recovery chain (restart/5s/10s/30s configured at install).
The LocalSystem service account cannot access per-user Python installs
(AppData\Local\Programs\Python\...). When a per-user install is detected,
automatically install Python system-wide before proceeding.
- Detect per-user Python (AppData in path) and trigger system-wide install
- Extract system Python install logic into Install-PythonSystemWide function
- Check winget exit code before marking install successful
- Split pip install and postinstall into separate steps; pip failure is fatal,
postinstall failure is a warning (service DLLs may already be registered)
- Use $LASTEXITCODE check on pip rather than try/catch (external process)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the scheduled-task approach (required user to stay logged in) with a
proper Windows Service using pywin32. The service runs as LocalSystem, starts
at boot, and auto-restarts on failure — no PowerShell window needed.
Agent changes (jarvis-agent-windows.py):
- Add Windows Service class via pywin32 (JarvisAgentService)
- Cleanly handles SvcStop by setting a threading.Event
- main() loop uses _stop_event.wait() instead of time.sleep() so stop is immediate
- self_update() signals the stop event when running as a service (SCM restarts it)
- __main__ block dispatches to SCM entry point or HandleCommandLine (install/stop/remove)
- Falls back to direct run if pywin32 not installed (for debugging)
Installer changes (install-windows.ps1):
- pip install pywin32 + postinstall (registers service runner DLLs)
- Python search prefers system-wide install (accessible by LocalSystem)
- Downloads Python 3.11 directly from python.org for Win 8.1 machines without winget
- Removes legacy JARVIS-Agent scheduled task if present
- Registers JARVISAgent service with --startup auto
- Configures sc.exe failure recovery (restart at 5s/10s/30s)
- Updated management commands in summary (Start-Service, Stop-Service, etc.)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- guardian_loop + sitrep: SELECT metric_data (not metrics_json which does not exist)
- guardian_loop: metrics are flat (cpu_percent at top level), not nested under system key
- guardian_loop + sitrep: filter metric_type=system to avoid parsing proxmox blobs
- guardian_loop: disk.mount key (not mountpoint) + fallback for both key names
- sitrep: same metric_data + root-level key fixes
- _guardian_inject_chat (x2): INSERT into conversations.content (not message)
- /guardian/chat endpoint (x2): SELECT content (not message) from conversations
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add version column to registered_agents table
- Agents send version on registration (Linux 3.1, Windows 3.0, macOS 3.0)
- workers_list API returns latest_versions per platform
- Workers tab: VERSION column with green check (up-to-date) or red (outdated)
- Outdated agents highlight row and show blue UPDATE button
- Up-to-date agents show dimmed UPDATE button
- Update button dispatches update command immediately
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Proxmox: skip if data < 10 min old (was: every 3 min unconditionally)
- Ollama: skip if data < 15 min old (model list rarely changes)
- Site health: skip if data < 5 min old (was: 7 HTTP calls every 3 min)
- Home Assistant: removed entirely (HA agent pushes 212 entities every 30s)
Fast local reads (CPU/mem/network pings) still run every 3 min. External
HTTP calls now fire only when data is actually stale. Saves ~140 site-check
HTTP calls/hour and ~60 Proxmox API calls/hour in steady state.
When deploy/reactor.py changes in a push, the deploy runner now copies it
to the runtime location and restarts jarvis-arc.service automatically.
Eliminates the two-copy drift problem — repo is now canonical.
Old installer wrote to /opt/jarvis-agent/config.json with server_url/api_key/
heartbeat_interval keys and pre-registered with JARVIS. Agent v3.0 expects:
- Config at /etc/jarvis-agent/config.json with jarvis_url/registration_key/
hostname/poll_interval/heartbeat_every keys
- api_key stored by agent itself in /var/lib/jarvis-agent/state.json
- Agent self-registers at startup using registration_key
Also adds: imagemagick install (headless screenshot support), apk support
for Alpine/WireGuard, copies to /usr/local/bin/jarvis-agent.py.
Previously agents only registered when api_key was missing (first run).
After updating to v3.0 with screenshot capability, restarted agents never
refreshed their capabilities in the DB. Now register() is called every
startup — server does UPDATE on existing agent_id so api_key is preserved.
self_update(cfg) and shell allow_shell_commands check both referenced cfg
from run() scope, but execute_command() is a standalone function. Fixed by
calling load_config() locally in each branch that needs it.
A ParseError or fatal in any endpoint file now returns JSON 500 for that
endpoint only. switch replaced with data-driven map. All other endpoints
continue working normally when one is broken.
Arc Reactor was running from /opt/jarvis-arc with no version tracking.
Added to deploy/ so all fixes (metrics_json→metric_data, flat JSON parsing,
disk mount key fix) are captured. WG configs are runtime-generated secrets
and must not be committed.
Swap: replace grid-column reassignment with named grid-template-areas
(grid-column approach caused leftPanel to disappear and mis-position).
"left center right" <-> "right center left" cleanly swaps both columns.
Collapsible: clicking any panel-title collapses/expands that panel.
Chevron rotates -90deg when collapsed. State persists in localStorage.
All interactive elements in title bars (+ buttons etc) still work.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Broke entire JS block — side panels, data loading, everything.
synthesis.length>1500 ternary had bare newlines inside single quotes.
Replaced with \n escape sequences.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
const ts = ts() in loadVision caused TDZ ReferenceError crashing gallery.
visionRunScreenshot now fetches online agents from agents_list API when
no screenshots exist yet (previously showed No agents online falsely).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ARC REACTOR tab had HTML and PHP API handlers but no JS load function,
causing ReferenceError on every tab click. Adds all three missing functions.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Rename memory section CAT_COLORS to MEM_CAT_COLORS to avoid SyntaxError
that prevented doLogin from being defined, locking users out of admin.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- DB: missions, mission_steps, mission_runs tables
- reactor.py v7.0.0: handle_run_mission, _execute_mission, mission_trigger_loop (schedule/guardian_event/email_keyword triggers), {{template}} substitution across steps, full CRUD REST endpoints
- arc.php: missions/mission_get/mission_runs/mission_create/mission_update/mission_delete/mission_run/mission_toggle actions
- admin/index.php: Mission Ops tab with visual workflow builder (trigger config, step cards with ↑↓, JSON payload editor, continue-on-failure flag), run history with step-level detail, enable/disable toggle
- index.html: MISSIONS tab with collapsible mission cards, RUN NOW button per mission, live run result feedback
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- chat.php: Add Tier 0.9a (gmail_triage), Tier 0.9b (remote_exec) detection;
refactor arc submit into arcSubmitJob() helper; natural-language triggers for
email triage (check my email, triage inbox) and remote exec (restart X on Y,
run X on Y, get logs from X on Y)
- arc.php: Add triage and triage_action endpoints (read/update email_triage table)
- index.html: Add COMMS tab with triage card UI (filter bar, category badges,
draft reply viewer, copy/dismiss actions); loadComms() with 8s polling;
onArcJobStarted() routes gmail_triage jobs to COMMS tab
- admin/index.php: Add GMAIL TRIAGE section under COMMUNICATIONS nav; triage_list/
triage_action/triage_run PHP actions; loadTriage() JS with full table + draft
modal; triageRunNow() submits gmail_triage job to Arc Reactor