From 2b18f54d4d303d77e5acb6b0848801d902d6af24 Mon Sep 17 00:00:00 2001 From: NellInc Date: Mon, 21 Sep 2026 12:51:25 +0100 Subject: [PATCH 1/6] feat: add opt-in Jev incident advice with personal OpenRouter keys --- index.html | 3 +- src/components/AICommandCenter.tsx | 25 ++- .../__tests__/AICommandCenter.test.tsx | 16 ++ src/components/mobile/MobilePanel.test.tsx | 73 +++++++ src/components/mobile/MobilePanel.tsx | 83 +++++-- src/components/ui/JevAdvisoryPanel.test.tsx | 130 +++++++++++ src/components/ui/JevAdvisoryPanel.tsx | 206 ++++++++++++++++++ src/utils/jevClient.test.ts | 156 +++++++++++++ src/utils/jevClient.ts | 135 ++++++++++++ 9 files changed, 801 insertions(+), 26 deletions(-) create mode 100644 src/components/mobile/MobilePanel.test.tsx create mode 100644 src/components/ui/JevAdvisoryPanel.test.tsx create mode 100644 src/components/ui/JevAdvisoryPanel.tsx create mode 100644 src/utils/jevClient.test.ts create mode 100644 src/utils/jevClient.ts diff --git a/index.html b/index.html index 83686e83..6ff1c30d 100644 --- a/index.html +++ b/index.html @@ -6,6 +6,7 @@ CSP connect-src third-party domains and their runtime consumers: - https://0.peerjs.com PeerJS multiplayer signalling - https://generativelanguage.googleapis.com Gemini cloud AI (GeminiSettingsModal) + - https://openrouter.ai opt-in Jev advisory (jevClient.ts) - https://cdn.jsdelivr.net asset/CDN fetches - https://huggingface.co + https://*.hf.co @mlc-ai/web-llm model weights (Qwen3-4B-q4f16_1-MLC); HF LFS blobs @@ -24,7 +25,7 @@ style-src 'self' 'unsafe-inline'; font-src 'self'; img-src 'self' data: blob: https://www.millos.net; - connect-src 'self' blob: ws: wss: https://0.peerjs.com https://generativelanguage.googleapis.com https://cdn.jsdelivr.net https://huggingface.co https://*.huggingface.co https://*.hf.co https://raw.githubusercontent.com; + connect-src 'self' blob: ws: wss: https://openrouter.ai https://0.peerjs.com https://generativelanguage.googleapis.com https://cdn.jsdelivr.net https://huggingface.co https://*.huggingface.co https://*.hf.co https://raw.githubusercontent.com; worker-src 'self' blob:; object-src 'none'; base-uri 'self'; diff --git a/src/components/AICommandCenter.tsx b/src/components/AICommandCenter.tsx index 35d9d3d9..39664799 100644 --- a/src/components/AICommandCenter.tsx +++ b/src/components/AICommandCenter.tsx @@ -20,6 +20,7 @@ import { useAIConfigStore } from '../stores/aiConfigStore'; import { useShallow } from 'zustand/react/shallow'; import { applyDecisionEffects, reactToAlert } from '../utils/aiEngine'; import { GeminiSettingsModal } from './GeminiSettingsModal'; +import { JevAdvisoryPanel } from './ui/JevAdvisoryPanel'; import { ActionPlanTimeline } from './ui/ActionPlanTimeline'; import { DecisionHistoryPanel } from './ui/DecisionHistoryPanel'; import { StrategicPriorityCards } from './ui/StrategicPriorityCards'; @@ -51,7 +52,7 @@ export const AICommandCenter: React.FC = ({ embedded = false, }) => { const [isThinking, setIsThinking] = useState(false); - const [activeTab, setActiveTab] = useState<'decisions' | 'strategic'>('decisions'); + const [activeTab, setActiveTab] = useState<'decisions' | 'strategic' | 'advisory'>('decisions'); const [selectedDecision, setSelectedDecision] = useState(null); const [systemStatus, setSystemStatus] = useState({ @@ -315,6 +316,20 @@ export const AICommandCenter: React.FC = ({