+ {intentQueue.filter((i: any) => i.status !== 'ready').length} analyzing
+
+ )}
+=======
+<<<<<<< HEAD
+ {intentQueue.length > 0 && (
+
+
Intent Fabrication
+ {intentQueue.slice(-3).map((draft: any) => (
+
+
+ {draft.text}
+ {draft.status}
+
+
+ Conf: {Math.round(draft.confidence * 100)}%
+ {draft.predictedOutcome || 'Simulating...'}
+
+ {(draft.status === 'analyzing' || draft.status === 'policy-check') && (
+
+ )}
+
+ ))}
+
+ )}
+
+ {messages.map(message => (
+
+=======
@@ -91,6 +163,7 @@ export function CommandPanel() {
? 'bg-neuro-bg/70 border-neuro-border/60 text-neuro-text-primary'
: 'bg-gradient-to-r from-cyan-500/20 to-blue-500/10 border-cyan-400/30 text-neuro-text-primary'
)}>
+>>>>>>> main
{message.role === 'assistant' ? 'System' : 'User'}
{message.timestamp}
@@ -100,12 +173,26 @@ export function CommandPanel() {
))}
+<<<<<<< HEAD
+=======
+>>>>>>> main
Intent Presets
{COMMAND_PRESETS.map(preset => (
+<<<<<<< HEAD
+
+ ))}
+
+
+
+
Safety Constraints
+
+
Multi-stage intent arbitration active.
+
Policy lattice enforcement enabled.
+=======
+>>>>>>> main
+<<<<<<< HEAD
+ setInput(e.target.value)} onKeyDown={e => e.key === 'Enter' && submitMessage(input)} placeholder="Transmit intent, directive, or negotiation request..." className="flex-1 rounded-xl border border-neuro-border/60 bg-neuro-bg/80 px-4 py-3 text-sm text-neuro-text-primary placeholder:text-neuro-text-muted focus:outline-none focus:ring-1 focus:ring-cyan-400/50" />
+
+
+=======
setInput(event.target.value)}
@@ -150,6 +243,7 @@ export function CommandPanel() {
>
+>>>>>>> main
);
diff --git a/web-ui/src/components/webmode/panels/ConfigMatrixPanel.tsx b/web-ui/src/components/webmode/panels/ConfigMatrixPanel.tsx
index 2bc0293..4057b5c 100644
--- a/web-ui/src/components/webmode/panels/ConfigMatrixPanel.tsx
+++ b/web-ui/src/components/webmode/panels/ConfigMatrixPanel.tsx
@@ -1,6 +1,31 @@
'use client';
import { useMemo } from 'react';
+<<<<<<< HEAD
+import { useWebModeContext } from '@/components/webmode/WebModeProvider';
+import { configSchema } from '@/lib/webmode/config-schema';
+import { AlertTriangle, Lock, RefreshCw } from 'lucide-react';
+import { cn } from '@/lib/utils';
+
+function getValue(source: any, path: string) {
+ if (!source) return undefined;
+ return path.split('.').reduce((acc: any, key: string) => (acc ? acc[key] : undefined), source);
+}
+
+export function ConfigMatrixPanel() {
+ const { config, updateConfig, controlMode } = useWebModeContext();
+
+ const conflicts = useMemo(() => {
+ const list: string[] = [];
+ if (config.stealth?.enabled && config.neurorift?.sandboxLevel === 'hardened') {
+ list.push('Warning: Stealth Mode optimal with Sealed sandbox (currently Hardened).');
+ }
+ if (config.aiBehavior?.selfEvolution && config.agentModes?.supervision === 'strict') {
+ list.push('Constraint: Self-Evolution dampened by Strict supervision.');
+ }
+ return list;
+ }, [config]);
+=======
import { configSchema } from '@/lib/webmode/config-schema';
import { useWebModeContext } from '@/components/webmode/WebModeProvider';
@@ -10,11 +35,62 @@ function getValue(source: any, path: string) {
export function ConfigMatrixPanel() {
const { config, updateConfig } = useWebModeContext();
+>>>>>>> main
const sections = useMemo(() => configSchema, []);
return (
+<<<<<<< HEAD
+ {conflicts.length > 0 && (
+
+
+
+
Policy Conflicts Detected
+
+ {conflicts.map((c, i) => (
+
{c}
+ ))}
+
+ )}
+
+ {sections.map(section => (
+
+
+
+
{section.title}
+
{section.description}
+
+ {controlMode === 'read' &&
}
+
+
+
+ {section.fields.map(field => {
+ const value = getValue(config, field.path);
+ const isLocked = controlMode === 'read';
+ return (
+
+
+ {field.label}{isLocked && }
+ {typeof value === 'number' ? value.toFixed(2) : String(value)}
+
+
+ {field.type === 'slider' && (
+
+
updateConfig(field.path, Number(e.target.value))} disabled={isLocked} className="w-full h-1 bg-neuro-border/50 rounded-lg appearance-none cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3 [&::-webkit-slider-thumb]:bg-cyan-400 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:shadow-[0_0_10px_cyan]" />
+
+
+ )}
+
+ {field.type === 'toggle' && (
+
+ )}
+
+ {field.type === 'select' && (
+
diff --git a/web-ui/src/components/webmode/panels/ExecutionTimelinePanel.tsx b/web-ui/src/components/webmode/panels/ExecutionTimelinePanel.tsx
index 23d10fa..654ffa1 100644
--- a/web-ui/src/components/webmode/panels/ExecutionTimelinePanel.tsx
+++ b/web-ui/src/components/webmode/panels/ExecutionTimelinePanel.tsx
@@ -1,5 +1,34 @@
'use client';
+<<<<<<< HEAD
+import { Clock } from 'lucide-react';
+import { cn } from '@/lib/utils';
+
+const TIMELINE = [
+ { id: 1, label: 'Boot Sequence', status: 'complete', time: '0ms' },
+ { id: 2, label: 'Bus Sync', status: 'complete', time: '200ms' },
+ { id: 3, label: 'Agent Registration', status: 'complete', time: '450ms' },
+ { id: 4, label: 'Policy Lattice Compile', status: 'active', time: '800ms' },
+ { id: 5, label: 'Intent Router Online', status: 'pending', time: '—' },
+];
+
+export function ExecutionTimelinePanel() {
+ return (
+
+
+
+ Execution Timeline
+
+
+ {TIMELINE.map(step => (
+
+
+
{step.label}
+
{step.time}
+
+ ))}
+
+=======
import { useNeuroRift } from '@/lib/hooks';
import { cn } from '@/lib/utils';
@@ -29,6 +58,7 @@ export function ExecutionTimelinePanel() {
))}
+>>>>>>> main
);
}
diff --git a/web-ui/src/components/webmode/panels/IntentFlowPanel.tsx b/web-ui/src/components/webmode/panels/IntentFlowPanel.tsx
index e924c95..31dde87 100644
--- a/web-ui/src/components/webmode/panels/IntentFlowPanel.tsx
+++ b/web-ui/src/components/webmode/panels/IntentFlowPanel.tsx
@@ -1,5 +1,18 @@
'use client';
+<<<<<<< HEAD
+import { Workflow } from 'lucide-react';
+
+export function IntentFlowPanel() {
+ return (
+
+
+
+ Intent Flow
+
+
+ Submit an intent to visualize the negotiation flow.
+=======
import { ArrowRight, Shield, Wand2, Layers } from 'lucide-react';
const steps = [
@@ -30,6 +43,7 @@ export function IntentFlowPanel() {
Intent routing is declarative and policy-driven. Execution is triggered only after negotiation, scoring, and enforcement checks succeed.
+>>>>>>> main
);
diff --git a/web-ui/src/components/webmode/panels/ManualToolPanel.tsx b/web-ui/src/components/webmode/panels/ManualToolPanel.tsx
new file mode 100644
index 0000000..614846a
--- /dev/null
+++ b/web-ui/src/components/webmode/panels/ManualToolPanel.tsx
@@ -0,0 +1,124 @@
+
+import React, { useState, useEffect, useRef } from 'react';
+import { useWebModeContext } from '../WebModeProvider';
+import { Play, Square, Terminal, Loader2 } from 'lucide-react';
+
+export function ManualToolPanel() {
+ const { adapter } = useWebModeContext();
+ const [selectedTool, setSelectedTool] = useState('nmap');
+ const [args, setArgs] = useState('');
+ const [isRunning, setIsRunning] = useState(false);
+ const [executionId, setExecutionId] = useState
(null);
+ const [output, setOutput] = useState([]);
+ const outputRef = useRef(null);
+
+ const tools = ['nmap', 'nuclei', 'subfinder', 'ffuf', 'custom'];
+
+ const handleRun = async () => {
+ try {
+ setIsRunning(true);
+ setOutput([]);
+ const id = await adapter.runTool(selectedTool, args);
+ setExecutionId(id);
+ } catch (e) {
+ setOutput(prev => [...prev, `Error starting tool: ${e}`]);
+ setIsRunning(false);
+ }
+ };
+
+ const handleStop = async () => {
+ if (executionId) {
+ await adapter.cancelTool(executionId);
+ setIsRunning(false);
+ setOutput(prev => [...prev, '\n[Stopped by user]']);
+ }
+ };
+
+ useEffect(() => {
+ if (!isRunning || !executionId) return;
+
+ const interval = setInterval(async () => {
+ try {
+ const status = await adapter.getToolStatus(executionId);
+ setOutput([...status.stdout, ...status.stderr]);
+
+ if (status.status !== 'running') {
+ setIsRunning(false);
+ setExecutionId(null);
+ }
+ } catch (e) {
+ console.error("Failed to poll status", e);
+ }
+ }, 1000);
+
+ return () => clearInterval(interval);
+ }, [isRunning, executionId, adapter]);
+
+ useEffect(() => {
+ if (outputRef.current) {
+ outputRef.current.scrollTop = outputRef.current.scrollHeight;
+ }
+ }, [output]);
+
+ return (
+
+
+
+
+ MANUAL OPERATOR PLANE
+
+ {isRunning &&
EXECUTING}
+
+
+
+
+
+
setArgs(e.target.value)}
+ placeholder="--flags target"
+ disabled={isRunning}
+ className="flex-1 bg-black/50 border border-white/20 rounded px-3 py-1.5 text-sm font-mono text-cyan-100 focus:outline-none focus:border-cyan-500/50 placeholder-white/20"
+ />
+ {!isRunning ? (
+
+ ) : (
+
+ )}
+
+
+
+ {output.length === 0 ? (
+
Ready for input...
+ ) : (
+ output.map((line, i) => (
+
{line}
+ ))
+ )}
+
+
+
+ );
+}
diff --git a/web-ui/src/components/webmode/panels/MemoryPulsePanel.tsx b/web-ui/src/components/webmode/panels/MemoryPulsePanel.tsx
index ebf1fc9..60dc608 100644
--- a/web-ui/src/components/webmode/panels/MemoryPulsePanel.tsx
+++ b/web-ui/src/components/webmode/panels/MemoryPulsePanel.tsx
@@ -1,5 +1,98 @@
'use client';
+<<<<<<< HEAD
+import { useState, useEffect } from 'react';
+import { Brain, TrendingUp, TrendingDown, Minus, AlertTriangle } from 'lucide-react';
+import { useWebModeContext } from '@/components/webmode/WebModeProvider';
+import { cn } from '@/lib/utils';
+
+interface MemoryDisplay {
+ id: string;
+ label: string;
+ value: number;
+ trend: 'up' | 'down' | 'stable';
+ type: string;
+ decayRate: number;
+ barColor: string;
+ icon: string;
+}
+
+const DEFAULT_METRICS: MemoryDisplay[] = [
+ { id: 'episodic', label: 'Episodic Memory', value: 0.72, trend: 'down', type: 'episodic', decayRate: 0.03, barColor: 'bg-gradient-to-r from-violet-500 to-fuchsia-500', icon: '🧠' },
+ { id: 'working', label: 'Working Context', value: 0.89, trend: 'up', type: 'preference', decayRate: 0.01, barColor: 'bg-gradient-to-r from-cyan-400 to-blue-500', icon: '⚡' },
+ { id: 'prefs', label: 'Preferences', value: 0.45, trend: 'stable', type: 'reinforcement', decayRate: 0.005, barColor: 'bg-gradient-to-r from-emerald-500 to-teal-400', icon: '🎯' },
+];
+
+const TrendIcon = ({ trend }: { trend: string }) => {
+ if (trend === 'up') return ;
+ if (trend === 'down') return ;
+ return ;
+};
+
+export function MemoryPulsePanel() {
+ const { config } = useWebModeContext();
+ const [metrics, setMetrics] = useState(DEFAULT_METRICS);
+ const [cadence, setCadence] = useState(0);
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setMetrics(prev => prev.map(m => ({
+ ...m,
+ value: Math.max(0.05, Math.min(0.99, m.value + (Math.random() - 0.52) * m.decayRate * 2)),
+ })));
+ setCadence(p => (p + 1) % 4);
+ }, 2500);
+ return () => clearInterval(interval);
+ }, []);
+
+ return (
+
+
+
+
+ Memory Pulse
+
+
+ {[0, 1, 2, 3].map(i => (
+
+ ))}
+
+
+
+
+ {metrics.map(metric => (
+
+
+
+ {metric.icon}
+ {metric.label}
+
+
+
+ {Math.round(metric.value * 100)}%
+
+
+
+ {/* Progress Bar */}
+
+
+ {/* Details on hover */}
+
+
+
Decay: {(metric.decayRate * 100).toFixed(1)}%/cycle
+ {metric.value > 0.85 && (
+
High Influence
+ )}
+
+
+
+ ))}
+
+=======
import { useWebModeContext } from '@/components/webmode/WebModeProvider';
export function MemoryPulsePanel() {
@@ -29,6 +122,7 @@ export function MemoryPulsePanel() {
))}
Memory is local-only and influences planning without transmission.
+>>>>>>> main
);
}
diff --git a/web-ui/src/components/webmode/panels/OnlineModePanel.tsx b/web-ui/src/components/webmode/panels/OnlineModePanel.tsx
index 902d977..58d9574 100644
--- a/web-ui/src/components/webmode/panels/OnlineModePanel.tsx
+++ b/web-ui/src/components/webmode/panels/OnlineModePanel.tsx
@@ -1,20 +1,105 @@
'use client';
+<<<<<<< HEAD
+import { useEffect, useState } from 'react';
+import { Globe, ShieldAlert, ShieldCheck } from 'lucide-react';
+=======
import { useMemo } from 'react';
import { Globe, ShieldAlert } from 'lucide-react';
+>>>>>>> main
import { useWebModeContext } from '@/components/webmode/WebModeProvider';
import { cn } from '@/lib/utils';
export function OnlineModePanel() {
+<<<<<<< HEAD
+ const { config, updateConfig, controlMode } = useWebModeContext();
+ const [latency, setLatency] = useState(12);
+
+ useEffect(() => {
+ if (!config.onlineMode.enabled) return;
+ const interval = setInterval(() => {
+ setLatency((prev: number) => Math.max(8, Math.min(45, prev + (Math.random() - 0.5) * 5)));
+ }, 2000);
+ return () => clearInterval(interval);
+=======
const { config, updateConfig } = useWebModeContext();
const publicUrl = useMemo(() => {
if (!config.onlineMode.enabled) return null;
return `https://nr-${Math.floor(Math.random() * 9999)}.tunnel.neurorift.ai`;
+>>>>>>> main
}, [config.onlineMode.enabled]);
return (
+<<<<<<< HEAD
+ {/* Header Toggle */}
+
+
+
+
+
+
+
Secure Tunnel
+
{config.onlineMode.enabled ? 'Encrypted Link Active' : 'Offline / Isolated'}
+
+
+
+
+
+ {config.onlineMode.enabled && (
+
+ {/* Tunnel Visualization */}
+
+
+
+
+
+ AES-256 • {Math.round(latency)}ms
+
+
+
+
+
+
+ {/* Scopes & Access */}
+
+
+
Exposure Scopes
+ {['API Access', 'Chat Interface', 'Full Dashboard'].map(scope => (
+
+ ))}
+
+
+
Access Policy
+
+
+
+ MFA enforcement recommended for remote admin sessions.
+
+
+
+
+ )}
+=======
@@ -57,6 +142,7 @@ export function OnlineModePanel() {
Remote exposure requires explicit approval and never bypasses NeuroRift enforcement.
+>>>>>>> main
);
}
diff --git a/web-ui/src/components/webmode/panels/PermissionsPanel.tsx b/web-ui/src/components/webmode/panels/PermissionsPanel.tsx
index 7a6d3f0..47d0036 100644
--- a/web-ui/src/components/webmode/panels/PermissionsPanel.tsx
+++ b/web-ui/src/components/webmode/panels/PermissionsPanel.tsx
@@ -1,5 +1,106 @@
'use client';
+<<<<<<< HEAD
+import { useState } from 'react';
+import { ShieldCheck, CheckCircle, XCircle, AlertTriangle } from 'lucide-react';
+import { useWebModeContext } from '@/components/webmode/WebModeProvider';
+import { cn } from '@/lib/utils';
+
+const MOCK_PERMISSIONS = [
+ {
+ id: 'perm-1', title: 'Scope Expansion: External DNS', description: 'Agent requests access to external DNS resolution for reconnaissance.',
+ riskLevel: 'medium' as const, origin: 'operator', status: 'pending' as const, stage: 1, totalStages: 2,
+ policyDelta: '+DNS:external.resolve → operator.network',
+ },
+ {
+ id: 'perm-2', title: 'Config Mutation: Sandbox Level', description: 'Self-evolution engine proposes sandbox relaxation for model fine-tuning.',
+ riskLevel: 'high' as const, origin: 'evolution-engine', status: 'pending' as const, stage: 1, totalStages: 3,
+ policyDelta: 'neurorift.sandboxLevel: hardened → strict',
+ },
+];
+
+const RISK_COLORS: Record
= {
+ low: 'text-emerald-400 border-emerald-500/30',
+ medium: 'text-amber-400 border-amber-500/30',
+ high: 'text-rose-400 border-rose-500/30',
+ critical: 'text-red-500 border-red-500/50',
+};
+
+export function PermissionsPanel() {
+ const { resolvePermission, permissionQueue } = useWebModeContext();
+ const [enforcementFlash, setEnforcementFlash] = useState(null);
+
+ const displayPerms = permissionQueue.length > 0 ? permissionQueue : MOCK_PERMISSIONS;
+
+ const handleAction = (id: string, approved: boolean) => {
+ setEnforcementFlash(id);
+ setTimeout(() => {
+ resolvePermission(id, approved);
+ setEnforcementFlash(null);
+ }, 600);
+ };
+
+ return (
+
+
+
+ Permission Decisions
+ {displayPerms.length > 0 && (
+ {displayPerms.length} pending
+ )}
+
+
+
+ {displayPerms.map(req => (
+
+ {enforcementFlash === req.id && (
+
+ )}
+
+
+
{req.title}
+
{req.description}
+
+
{req.riskLevel}
+
+
+ {/* Risk Vectors */}
+
+
Risk Vectors
+
+ Scope Expansion
+ Config Mutation
+
+
+
+ {/* Policy Delta */}
+ {req.policyDelta && (
+
{req.policyDelta}
+ )}
+
+ {/* Stage + Actions */}
+
+
+ {Array.from({ length: req.totalStages }).map((_, i) => (
+
+ ))}
+
{req.stage}/{req.totalStages}
+
+
+
+
+
+
+
+ ))}
+
+=======
import { useNeuroRift } from '@/lib/hooks';
import { cn } from '@/lib/utils';
@@ -27,6 +128,7 @@ export function PermissionsPanel() {
))}
+>>>>>>> main
);
}
diff --git a/web-ui/src/components/webmode/panels/SessionManagerPanel.tsx b/web-ui/src/components/webmode/panels/SessionManagerPanel.tsx
new file mode 100644
index 0000000..d718141
--- /dev/null
+++ b/web-ui/src/components/webmode/panels/SessionManagerPanel.tsx
@@ -0,0 +1,100 @@
+
+import React, { useState, useEffect } from 'react';
+import { useWebModeContext } from '../WebModeProvider';
+import { Folder, PlayCircle, Trash2, Database, RefreshCw } from 'lucide-react';
+import { Session } from '@/lib/webmode/adapter/interface';
+
+export function SessionManagerPanel() {
+ const { adapter } = useWebModeContext();
+ const [sessions, setSessions] = useState