Add VPN configuration tools and agent documentation

Created comprehensive VPN setup tooling for Peaceful Spirit L2TP/IPsec connection
and enhanced agent documentation framework.

VPN Configuration (PST-NW-VPN):
- Setup-PST-L2TP-VPN.ps1: Automated L2TP/IPsec setup with split-tunnel and DNS
- Connect-PST-VPN.ps1: Connection helper with PPP adapter detection, DNS (192.168.0.2), and route config (192.168.0.0/24)
- Connect-PST-VPN-Standalone.ps1: Self-contained connection script for remote deployment
- Fix-PST-VPN-Auth.ps1: Authentication troubleshooting for CHAP/MSChapv2
- Diagnose-VPN-Interface.ps1: Comprehensive VPN interface and routing diagnostic
- Quick-Test-VPN.ps1: Fast connectivity verification (DNS/router/routes)
- Add-PST-VPN-Route-Manual.ps1: Manual route configuration helper
- vpn-connect.bat, vpn-disconnect.bat: Simple batch file shortcuts
- OpenVPN config files (Windows-compatible, abandoned for L2TP)

Key VPN Implementation Details:
- L2TP creates PPP adapter with connection name as interface description
- UniFi auto-configures DNS (192.168.0.2) but requires manual route to 192.168.0.0/24
- Split-tunnel enabled (only remote traffic through VPN)
- All-user connection for pre-login auto-connect via scheduled task
- Authentication: CHAP + MSChapv2 for UniFi compatibility

Agent Documentation:
- AGENT_QUICK_REFERENCE.md: Quick reference for all specialized agents
- documentation-squire.md: Documentation and task management specialist agent
- Updated all agent markdown files with standardized formatting

Project Organization:
- Moved conversation logs to dedicated directories (guru-connect-conversation-logs, guru-rmm-conversation-logs)
- Cleaned up old session JSONL files from projects/msp-tools/
- Added guru-connect infrastructure (agent, dashboard, proto, scripts, .gitea workflows)
- Added guru-rmm server components and deployment configs

Technical Notes:
- VPN IP pool: 192.168.4.x (client gets 192.168.4.6)
- Remote network: 192.168.0.0/24 (router at 192.168.0.10)
- PSK: rrClvnmUeXEFo90Ol+z7tfsAZHeSK6w7
- Credentials: pst-admin / 24Hearts$

Files: 15 VPN scripts, 2 agent docs, conversation log reorganization,
guru-connect/guru-rmm infrastructure additions

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-18 11:51:47 -07:00
parent b0a68d89bf
commit 6c316aa701
272 changed files with 37068 additions and 2 deletions

View File

@@ -0,0 +1,112 @@
import { ReactNode } from "react";
import { Link, useLocation, useNavigate } from "react-router-dom";
import { LayoutDashboard, Server, Terminal, Settings, LogOut, Menu, X, Building2, MapPin } from "lucide-react";
import { useState } from "react";
import { useAuth } from "../hooks/useAuth";
import { Button } from "./Button";
interface LayoutProps {
children: ReactNode;
}
const navItems = [
{ path: "/", label: "Dashboard", icon: LayoutDashboard },
{ path: "/clients", label: "Clients", icon: Building2 },
{ path: "/sites", label: "Sites", icon: MapPin },
{ path: "/agents", label: "Agents", icon: Server },
{ path: "/commands", label: "Commands", icon: Terminal },
{ path: "/settings", label: "Settings", icon: Settings },
];
export function Layout({ children }: LayoutProps) {
const [sidebarOpen, setSidebarOpen] = useState(false);
const location = useLocation();
const navigate = useNavigate();
const { user, logout } = useAuth();
const handleLogout = () => {
logout();
navigate("/login");
};
return (
<div className="min-h-screen bg-[hsl(var(--background))]">
{/* Mobile header */}
<div className="lg:hidden flex items-center justify-between p-4 border-b border-[hsl(var(--border))]">
<span className="font-bold text-lg">GuruRMM</span>
<Button variant="ghost" size="icon" onClick={() => setSidebarOpen(!sidebarOpen)}>
{sidebarOpen ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />}
</Button>
</div>
<div className="flex">
{/* Sidebar */}
<aside
className={`fixed inset-y-0 left-0 z-50 w-64 bg-[hsl(var(--card))] border-r border-[hsl(var(--border))] transform transition-transform duration-200 lg:translate-x-0 lg:static ${
sidebarOpen ? "translate-x-0" : "-translate-x-full"
}`}
>
<div className="flex flex-col h-full">
<div className="p-6 hidden lg:block">
<h1 className="text-xl font-bold">GuruRMM</h1>
</div>
<nav className="flex-1 px-4 space-y-1 mt-4 lg:mt-0">
{navItems.map((item) => {
const isActive = location.pathname === item.path;
return (
<Link
key={item.path}
to={item.path}
onClick={() => setSidebarOpen(false)}
className={`flex items-center gap-3 px-3 py-2 rounded-md text-sm font-medium transition-colors ${
isActive
? "bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))]"
: "text-[hsl(var(--foreground))] hover:bg-[hsl(var(--muted))]"
}`}
>
<item.icon className="h-5 w-5" />
{item.label}
</Link>
);
})}
</nav>
<div className="p-4 border-t border-[hsl(var(--border))]">
<div className="flex items-center gap-3 mb-3">
<div className="h-8 w-8 rounded-full bg-[hsl(var(--primary))] flex items-center justify-center text-[hsl(var(--primary-foreground))] text-sm font-medium">
{user?.name?.[0] || user?.email?.[0] || "U"}
</div>
<div className="flex-1 min-w-0">
<p className="text-sm font-medium truncate">{user?.name || user?.email}</p>
<p className="text-xs text-[hsl(var(--muted-foreground))] truncate">
{user?.role}
</p>
</div>
</div>
<Button
variant="ghost"
className="w-full justify-start"
onClick={handleLogout}
>
<LogOut className="h-4 w-4 mr-2" />
Sign out
</Button>
</div>
</div>
</aside>
{/* Overlay for mobile */}
{sidebarOpen && (
<div
className="fixed inset-0 bg-black/50 z-40 lg:hidden"
onClick={() => setSidebarOpen(false)}
/>
)}
{/* Main content */}
<main className="flex-1 p-6 lg:p-8">{children}</main>
</div>
</div>
);
}