202 Commits

Author SHA1 Message Date
myron 90e4ded7c9 Fix 8 issues from code review
- ha-poller: replace recursive main() retry with while loop (stack overflow fix)
- ha-poller: advance last_push on empty HA response (log spam fix)
- ha-poller: use datetime.now(timezone.utc) instead of deprecated utcnow()
- ping-probe: always call update_status() unconditionally so offline devices register as offline
- agent.php: heartbeat reads status from payload instead of hardcoding 'online'
- phone-probe: delegate JSON building to python3 (bash concatenation injection fix)
- netscan + phone-probe: read registration key from /etc/jarvis-agent/reg-key
- admin/index.php: sync ha_list skipDomains with ha.php (14 missing domains added)
- facts_collector: self-check JARVIS via 127.0.0.1 instead of Cloudflare hairpin
2026-06-29 20:58:22 -05:00
myron c1275d47a6 Add PVE1 probe scripts to repo (netscan, ping-probe, phone-probe)
Scripts were running on PVE1 but not tracked in git. Pulling current
versions that push to http://10.48.200.211 (was old DO server IP).
2026-06-29 19:44:39 -05:00
myron 08fbfaa3e4 Seed kb_intents/preferences, fix usage_patterns column, update schema, fix site URL
- db/seed_kb.sql: 25 intent patterns + user prefs (Myron / Mr. Blair)
- usage_patterns: renamed last_used→last_seen to match chat.php
- facts_collector: JARVIS self-check URL was port 1972 (DO), now correct URL
- db/schema.sql: reflects current live DB schema

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 18:15:53 -05:00
myron 1f25b5d04d Fix facts_collector JARVIS site URL (was :1972 DO port, now correct URL)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 18:13:12 -05:00
myron 84cd2ded50 Add HA poller, fix domain filters, create missing DB tables, update schema
- jarvis-ha-poller.py: new service polling HA entities → JARVIS (running on VM211)
- ha.php: add camera/siren/remote/todo/lawn_mower to skipDomains
- db/schema.sql: add tasks, appointments, usage_patterns tables; fix registered_agents enum (windows/macos) + version column

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 15:44:28 -05:00
myron 89a82a1573 Add Windows agent installer, fix Linux install URL
- install-windows.ps1: one-liner PowerShell installs Python, pywin32,
  downloads agent, creates config, installs Windows Service (auto-start)
- install.sh: fix JARVIS_URL from hardcoded LAN IP to https://jarvis.orbishosting.com
- install.sh: fix ssl_verify default to true for external agents

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 13:56:37 -05:00
myron e68bb7d165 feat: HA filter — remove floodlights, water heater, scenes, media players 2026-06-22 03:58:57 +00:00
myron 2f4b4ef5c3 feat: HA tab — filter scenes/media_player, nightly full resync cron, remove JS polling
- ha.php skipDomains: added media_player, scene
- ha.php skipKeywords: konnected, energy/power/voltage/current, full camera list
- stats_cache.php: same filter updates, removed scene/media_player from sync
- Removed JS setInterval polling; entity state kept fresh by HA agent push
- Added nightly 3am cron for full HA entity resync
2026-06-22 03:56:47 +00:00
myron 21e0b81a98 feat: HA tab — filter konnected/energy/camera/media_player, add 30s auto-refresh
- Added to skipDomains: media_player
- Added to skipKeywords: konnected, energy/power/voltage/current,
  camera controls (infrared, email, FTP, push, siren, hub ringtone, manual record),
  system noise (CEC scanner, ESPHome builder, Echo DND)
- Auto-refresh every 30s when HA tab is active
2026-06-22 03:53:06 +00:00
myron 95d49f15cb fix: kiosk voice reliability — stopListening on exit, exitVoiceMode kiosk guard
- stopListening() called in both toggleKiosk exit and _onFsChange so mic
  stops when leaving kiosk (was staying live indefinitely)
- exitVoiceMode() now returns early if kiosk-mode active so the 30-min
  idle timer and face-detection loop cannot kill the always-on mic
2026-06-21 14:26:54 +00:00
myron 51b598dd5d fix: kiosk voice — use startListening() directly, no TTS greeting blocking mic 2026-06-21 05:20:56 +00:00
myron 6f0459be85 feat: kiosk auto-starts voice mode and blocks sleep — isolated patches only 2026-06-21 05:17:55 +00:00
myron a6d4365f16 feat: kiosk mode CSS hiding (safe) — no voice JS patches 2026-06-21 05:15:38 +00:00
myron 383de0146c revert: restore all files to 52ddee3 — kiosk JS patches broke JARVIS completely 2026-06-21 05:10:30 +00:00
myron aaf9f9d56a revert: restore safe JS, keep only kiosk-mode CSS class toggle — voice patches caused JS crash 2026-06-21 05:03:56 +00:00
myron aa88a2f73b fix: missing quotes around kiosk-mode string caused ReferenceError breaking all buttons 2026-06-21 04:59:21 +00:00
myron f1d73e7b6a feat: kiosk always-on mic — auto-start voice on kiosk entry, no sleep, no wake word needed 2026-06-21 04:55:29 +00:00
myron 572f1b1816 feat: show HTTPS redirect banner on Silk/tablet when loaded via HTTP (mic/camera fix) 2026-06-21 04:45:40 +00:00
myron 1838e02d56 feat: hide network status panel in kiosk mode; bump cache version 2026-06-21 04:41:33 +00:00
myron 178040c18b chore: bump asset version to 20260621 to bust Silk browser cache 2026-06-21 04:30:28 +00:00
myron 45845a1f61 feat: kiosk-mode hides server, agents, guardian panels + HA/agents/memory/proxmox from bottom bar
- Adds body.kiosk-mode class on fullscreen entry/exit
- Hides: #server-panel, #tab-agents, #tab-guardian, tab buttons
- Hides bottom bar: Home Assistant, Agents, Memory, Proxmox
- Falls back to INTEL tab if agents/guardian was active on kiosk entry
- All elements remain visible in normal/tablet mode
2026-06-21 04:07:32 +00:00
myron 52ddee3e78 Fire HD 8 tablet mode: auto-detect Silk UA, optimised layout + touch targets 2026-06-19 16:17:48 +00:00
myron ab1aa16ac8 Add kiosk mode button for Fire tablet Silk browser 2026-06-19 16:02:51 +00:00
myron 1979c5f667 fix: install-agent.sh default URL updated to http://10.48.200.211 (JARVIS VM) 2026-06-18 12:34:32 +00:00
myron 1b071f4f67 fix: repair broken define in webhook.php (missing closing quote from prior sed) 2026-06-18 04:44:36 +00:00
myron 5cbaeda730 docs: update INFRASTRUCTURE-REFERENCE and CLAUDE.md for JARVIS VM migration
- JARVIS moved from DO to PVE1 VM 211 (10.48.200.211, 8c/16GB)
- Access: http://jarvis.orbishosting.com:1972 (FortiGate VIP)
- Stack: nginx + PHP 8.3 + MariaDB + Redis + Arc Reactor
- Ollama VM IP: 10.48.200.95 → 10.48.200.210 (Reolink owns .95)
- FusionPBX SSH now direct via Tailscale (100.74.46.120)
- DO role: websites only (JARVIS fully removed)
- Agent URLs updated: http://10.48.200.211 (LAN direct)
- DO agent uses Tailscale: http://100.77.178.42

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 04:38:02 +00:00
myron 5140573be0 fix: update system.php service list for JARVIS VM (nginx/php-fpm/mariadb/redis/arc/agent) 2026-06-18 04:18:07 +00:00
myron b7aea1371c feat: add DO server (web host) monitoring block to JARVIS Server panel
- /api/do now includes do_server key with jarvis-do agent metrics
  (CPU, RAM, disk, uptime from Tailscale-connected DO server agent)
- Front page JARVIS SERVER panel has WEB HOST section with live
  CPU/RAM/DISK bars from DO server agent data
- Panel title updated to show 10.48.200.211 (JARVIS VM IP)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 04:08:54 +00:00
myron 49694e76e1 fix: update service monitor for JARVIS VM (nginx/php-fpm/mariadb instead of OLS/mysql) 2026-06-18 04:01:36 +00:00
myron 04510ac39f fix: update facts_collector for JARVIS VM (not DO web host)
- Site checks use external URLs instead of 127.0.0.1 loopback (JARVIS
  no longer shares a server with the websites)
- JARVIS site URL updated to port 1972
- Fixed syntax error in DO server ping exec call
- Removed Host header injection (not needed for external checks)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 03:53:44 +00:00
myron 38ab8d2977 migrate: update all references from DO server to PVE1 JARVIS VM
- config.php: JARVIS_IP → 10.48.200.211, HA_URL → direct LAN 10.48.200.97
- facts_collector/stats_cache: Proxmox API → direct 10.48.200.90 (not DDNS)
- chat.php: system context updated to reflect PVE1/nginx instead of DO/OLS
- do_server.php: display IP → 10.48.200.211 (reads /proc for JARVIS VM stats)
- jarvis-app.js: service labels nginx/mariadb instead of lshttpd
- jarvis-overlays.js: network map JARVIS node IP → 10.48.200.211
- index.html: DO SERVER labels → JARVIS VM, cache bust v=20260618a
- jarvis-agents.js: agent install URL uses window.location.origin

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 02:25:36 +00:00
myron ca66152f45 perf: fix facts_collector blocking cron that was saturating PHP workers
Three issues caused periodic worker saturation:
1. Network section pinged 5 private LAN IPs (10.48.200.x) unreachable
   from DO — each failed after 1s timeout = 5s wasted per run.
   Replaced with a fast DB query on registered_agents.
2. pve_api_get() had no CURLOPT_CONNECTTIMEOUT — added 3s limit so
   unreachable Proxmox fails fast instead of blocking the full 8s.
3. Ollama curl timeout reduced from 5s→3s total, added 2s connect limit.

Cron interpreter also changed from lsphp85 to php8.3 in crontab
(done directly on server) — lsphp85 adds ~8s LSAPI startup overhead
and consumes a PHP worker slot; php8.3 runs standalone.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 19:40:13 +00:00
myron 0b7f2d013b refactor: Phase 3 — split jarvis-protocols.js into 3 panel files
A single SyntaxError in the 1668-line monolith kills every panel
(proven by the apostrophe bug on 2026-06-17). Split into:

  panels/jarvis-arc.js       (608 lines) — Arc Reactor, Intel, Comms, Guardian
  panels/jarvis-agents.js    (715 lines) — Missions, Directives, Memory,
                                           Clearance, Agents tab, Sites, Vision
  panels/jarvis-assistant.js (345 lines) — Chat History, Suggestions,
                                           Mobile, Command Palette, Topo map

A parse error in any one file now fails only that group of panels.
escHtml() stays in jarvis-arc.js (loads first) and remains global.
All other dependencies (api, speak, addMessage) come from jarvis-app.js.
Version param bumped to ?v=20260617b to force Cloudflare cache miss.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 19:10:31 +00:00
myron 8085a113d5 fix: sync public_html/agent/jarvis-agent.py with agent source
public_html/agent/ is what agents download for self-update.
It was 5 days out of date — missing the version-in-heartbeat fix
and all other v3.1 changes. Now mirrors agent/jarvis-agent.py exactly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 18:45:54 +00:00
myron b85e8dd16f fix: include version in heartbeat payload so Workers tab shows real versions
Heartbeat was sending {} — version only appeared in registration.
Agents that never re-register (most of them) stayed NULL in the DB.
Now every heartbeat carries {"version": AGENT_VERSION} so agent.php
can update the column on every check-in.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 18:36:51 +00:00
myron 188f6f8f10 fix: persist agent version on every heartbeat
update_agent_seen() now updates version column when agents include it
in their heartbeat payload. Previously version was only stored on
registration, leaving the Workers tab showing NULL for agents that
hadn't re-registered since v3.1.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 17:19:56 +00:00
myron 7f6397b514 perf: route Guardian and Vision text analysis to Groq instead of Claude
Guardian anomaly alerts and SITREP are pure text reasoning — Groq's
llama-3.3-70b-versatile handles them at near-zero cost with lower
latency. Vision Protocol image analysis stays on Claude (claude-opus-
4-8) because Groq has no vision models. Text-only sysinfo snapshots
(no image captured) also move to Groq.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 17:06:15 +00:00
myron dd2f48193b fix: add data-cfasync=false to face-api.js to suppress Rocket Loader
One untagged script tag is enough for Cloudflare Rocket Loader to
activate its bootstrap and inject mainScript.js, which declares
mainScriptFlag. When mainScript.js loads twice (script + eval), it
throws SyntaxError: Identifier 'mainScriptFlag' has already been
declared. All script tags now have data-cfasync=false.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 14:43:29 +00:00
myron 1e57a7c90c fix: check sites locally to avoid Cloudflare CDN timeouts
facts_collector was checking https://jarvis.orbishosting.com from the
DO server itself — traffic routes through Cloudflare CDN which can
return 524 timeouts. All sites are hosted on this same OLS instance,
so check via http://127.0.0.1 with a Host header instead. This gives
direct OLS response without CDN overhead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 14:30:40 +00:00
myron 2f57908a50 fix: storeFact always bumps updated_at; fix $fresh() wrong column name
ON DUPLICATE KEY UPDATE was not touching updated_at, so if a site's
status didn't change MySQL never fired the ON UPDATE trigger and the
row timestamp stayed 6 days stale. do_server.php's 15-min freshness
window then returned empty sites.

Also fixes $fresh() querying WHERE fact_category= (non-existent column)
instead of WHERE category=, which always returned no rows.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 14:24:17 +00:00
myron 2f5e7b5a00 fix: remove missing includes/auth.php require from metrics and suggestions
Both endpoints tried to require a non-existent includes/auth.php and call
AuthMiddleware::requireAuth() — auth is already handled by api.php before
any endpoint file runs. This caused 500 errors on /api/metrics (which
blocked agent sparklines) and /api/suggestions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 14:18:33 +00:00
myron 9623d7323a fix: cache-bust JS files to force Cloudflare to serve fixed jarvis-protocols.js
jarvis-protocols.js had a syntax error (apostrophe in single-quoted string)
that Cloudflare was caching (4h TTL). Adding ?v=20260617 to all JS script
tags forces a cache miss so the browser gets the fixed file immediately.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 14:02:53 +00:00
myron 9169324148 fix: escape apostrophe in jarvis-protocols.js line 1432
'What's playing on Jellyfin' — the apostrophe inside the single-quoted
string caused a SyntaxError that prevented the entire file from loading,
making checkArcStatus and all other panel functions undefined.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 14:02:04 +00:00
myron f8aaaf725c fix: scope session_start() skip to machine-agent calls only
agent/list and agent/status are browser-facing and need $_SESSION loaded
to verify auth. Only skip session_start() for machine-agent sub-actions
(heartbeat, metrics, ha_state, command_result, register) that fire every
10-30s. Previous fix skipped session for all agent/* causing the agents
panel to return 401 to the browser.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 13:49:45 +00:00
myron 025c6d6fec Fix session explosion: skip session_start for agent/netscan/ping endpoints
Agent heartbeats (every 10s from 13 agents) were creating empty session files
because session_start() ran unconditionally. Over months this produced millions
of 0-byte files in the session directory, causing PHP session GC to hang and
making all browser API calls intermittently timeout (panels show offline/empty).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 13:23:53 +00:00
myron f304ada4d3 Fix chat URL routing and agent.php fact_type column error
- sendMessage() was fetching /api.php?action=chat which bypasses the
  /api/* rewrite rule; api.php parsed endpoint as "api.php" → 404.
  Fixed to /api/chat so the rewrite routes it correctly to chat.php.

- agent.php HA entity map INSERT used non-existent fact_type column,
  causing PDOException on every agent heartbeat. Fixed to use the
  correct (category, fact_key, fact_value) columns.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 12:33:09 +00:00
myron 6195f9bd3b feat: implement 7 JARVIS UI enhancements
#1  Voice waveform: Web Audio API drives wave-bar heights in real time
#2  Ambient dim mode: panels fade to 12% after 90s idle
#6  Streaming AI replies: Groq tokens via SSE; frontend ReadableStream
#7  Quick-note capture: N key / "note: text" saves to kb_facts instantly
#8  Cancel in-flight request: AbortController + CANCEL button
#9  Accent color themes: Stark Blue / Widow Red / Hulk Green, localStorage
#10 Browser push notifications: critical alerts when tab is backgrounded

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 11:39:45 +00:00
myron 58070c7f06 Move weather widget from right panel to left panel
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 03:52:50 +00:00
myron 2c712a4fc6 Add live voice transcript, keyboard shortcuts, agent topology map
#3 Live Voice Transcript: Real-time subtitle bar at bottom of screen shows
what JARVIS hears as you speak. Interim results appear word-by-word via
SpeechRecognition.onresult interim events; bar fades 3.2s after final result.

#4 Keyboard Shortcuts: Global keydown handler (skips input fields):
F5=refresh all, Esc=close modals/overlays, M=mute mic toggle,
Space=focus chat input, 1/2/3/4=switch HOME/ALERTS/NEWS/AGENTS tabs.
Shortcut hints added to Ctrl+K palette footer.

#5 Agent Topology Map: TOPOLOGY button in AGENTS tab switches from card
view to animated ring-based canvas showing all agents by type (Proxmox=green
inner ring, HA=yellow mid ring, Linux/Windows=blue outer ring). Live particles
flow hub→agents; offline nodes shown in red. Reads from rendered agent cards.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 03:32:48 +00:00
myron b014fd96ab Fix HA toggle (Rocket Loader) and network map cleanup
HA toggle broken after modularization: separate <script src> files are
deferred by Cloudflare Rocket Loader, so inline onchange handlers fire
before toggleHA() is defined. Fix: add data-cfasync="false" to all
four JARVIS script tags to prevent Rocket Loader interference.

Network map cleanup:
- Deduplicate agent devices by hostname — two homeassistant agents
  (10.48.200.97 and 172.30.32.1) now show as one node; prefer online
  over offline, then most-recently-seen
- Offline agents excluded from inner rings — jellyfin (offline June 3)
  and mini_it12 (offline June 12) no longer appear on the map
- DB-pinned devices (Yealink phones) unaffected; still show in devices ring

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 03:20:37 +00:00