Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const FAQ = lazy(() => import("./pages/faq"));
const Affiliates = lazy(() => import("./pages/affiliates"));
const BlogIndex = lazy(() => import("./pages/blog/index"));
const BlogPost = lazy(() => import("./pages/blog/post"));
const BlogTagArchive = lazy(() => import("./pages/blog/tag/index"));
const AdminPanel = lazy(() => import("./pages/admin/index"));
const AboutPage = lazy(() => import("./pages/about"));
const StatusPage = lazy(() => import("./pages/status"));
Expand Down Expand Up @@ -252,6 +253,7 @@ function App() {
<Route path="/status" component={StatusPage} />
<Route path="/affiliates" component={Affiliates} />
<Route path="/blog" component={BlogIndex} />
<Route path="/blog/tag/:tag" component={BlogTagArchive} />
<Route path="/blog/:slug" component={BlogPost} />
<Route path="/account" component={AccountPage} />
<Route path="/admin" component={AdminPanel} />
Expand Down
58 changes: 58 additions & 0 deletions client/src/blog/images/cx-linux-roadmap.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
export default function CxLinuxRoadmapImage({ className = "" }: { className?: string }) {
const milestones = [
{ label: "v0.1", desc: "CLI + NLP core", done: true, x: 120 },
{ label: "v0.2", desc: "Web Console", done: true, x: 300 },
{ label: "v0.3", desc: "Fleet Mgmt", done: true, x: 480 },
{ label: "v0.4", desc: "Multi-agent", done: false, x: 660 },
{ label: "v0.5", desc: "GUI Layer", done: false, x: 840 },
{ label: "v1.0", desc: "GA Release", done: false, x: 1020 },
];

return (
<svg viewBox="0 0 1200 630" className={className} xmlns="http://www.w3.org/2000/svg" role="img" aria-label="CX Linux 2026 roadmap timeline">
<rect width="1200" height="630" fill="#0D0D0D"/>
{/* Title */}
<text x="600" y="70" textAnchor="middle" fontFamily="sans-serif" fontSize="24" fontWeight="bold" fill="#FFFFFF">CX Linux</text>
<text x="600" y="100" textAnchor="middle" fontFamily="sans-serif" fontSize="16" fill="#00FF9F">2026 Roadmap</text>
{/* Timeline line */}
<line x1="80" y1="315" x2="1120" y2="315" stroke="#333" strokeWidth="3"/>
{/* Progress fill */}
<line x1="80" y1="315" x2="480" y2="315" stroke="#00FF9F" strokeWidth="3"/>
{milestones.map(({ label, desc, done, x }) => (
<g key={label}>
{/* Connector line */}
<line x1={x} y1={done ? 275 : 355} x2={x} y2="315" stroke={done ? "#00FF9F" : "#333"} strokeWidth="1.5" strokeDasharray={done ? "0" : "4 3"}/>
{/* Node */}
<circle cx={x} cy="315" r="14" fill={done ? "#00FF9F" : "#1A1A1A"} stroke={done ? "#00FF9F" : "#555"} strokeWidth="2"/>
{done && (
<path d={`M${x - 6} 315 L${x - 1} 320 L${x + 7} 309`} stroke="#000" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
)}
{!done && (
<circle cx={x} cy="315" r="4" fill="#555"/>
)}
{/* Card */}
<rect
x={x - 56}
y={done ? 188 : 342}
width={112}
height={72}
rx="8"
fill="#141414"
stroke={done ? "#00FF9F" : "#333"}
strokeWidth="1"
opacity={done ? 1 : 0.7}
/>
<text x={x} y={done ? 212 : 366} textAnchor="middle" fontFamily="monospace" fontSize="14" fontWeight="bold" fill={done ? "#00FF9F" : "#666"}>{label}</text>
<text x={x} y={done ? 232 : 386} textAnchor="middle" fontFamily="sans-serif" fontSize="11" fill={done ? "#CCC" : "#555"}>{desc}</text>
<text x={x} y={done ? 248 : 402} textAnchor="middle" fontFamily="sans-serif" fontSize="10" fill={done ? "#00FF9F" : "#444"} opacity="0.8">{done ? "shipped" : "planned"}</text>
</g>
))}
{/* Legend */}
<circle cx="160" cy="530" r="8" fill="#00FF9F"/>
<text x="176" y="535" fontFamily="sans-serif" fontSize="12" fill="#888">Shipped</text>
<circle cx="260" cy="530" r="8" fill="#1A1A1A" stroke="#555" strokeWidth="1.5"/>
<text x="276" y="535" fontFamily="sans-serif" fontSize="12" fill="#888">Planned</text>
<text x="600" y="580" textAnchor="middle" fontFamily="sans-serif" fontSize="13" fill="#555">Building the AI-native OS layer, one release at a time</text>
</svg>
);
}
38 changes: 38 additions & 0 deletions client/src/blog/images/cx-vs-warp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
export default function CxVsWarpImage({ className = "" }: { className?: string }) {
return (
<svg viewBox="0 0 1200 630" className={className} xmlns="http://www.w3.org/2000/svg" role="img" aria-label="CX Linux vs Warp vs Copilot CLI comparison">
<rect width="1200" height="630" fill="#0D0D0D"/>
{/* Three terminal panels */}
{[
{ x: 40, title: "CX Linux", color: "#00FF9F", lines: ["cx \"set up nginx + SSL\"", "→ Analyzing system…", "→ 4 commands ready", "→ Preview + approve", "✓ Done in 30s"] },
{ x: 420, title: "Warp", color: "#7C3AED", lines: ["# nginx setup", "sudo apt install nginx", "# configure manually…", "# certbot…", "# debug config…"] },
{ x: 800, title: "Copilot CLI", color: "#0EA5E9", lines: ["gh copilot suggest", "\"nginx + ssl\"", "→ shows command", "→ no context", "→ manual steps"] },
].map(({ x, title, color, lines }) => (
<g key={title}>
<rect x={x} y={80} width={340} height={440} rx="10" fill="#141414" stroke={color} strokeWidth={title === "CX Linux" ? 2 : 1} opacity={title === "CX Linux" ? 1 : 0.5}/>
<rect x={x} y={80} width={340} height={36} rx="10" fill="#1A1A1A"/>
<rect x={x} y={104} width={340} height={12} fill="#1A1A1A"/>
<circle cx={x + 22} cy={98} r={5} fill={color} opacity="0.6"/>
<circle cx={x + 38} cy={98} r={5} fill={color} opacity="0.3"/>
<circle cx={x + 54} cy={98} r={5} fill={color} opacity="0.2"/>
<text x={x + 170} y={102} textAnchor="middle" fontFamily="sans-serif" fontSize="12" fontWeight="600" fill={color}>{title}</text>
{lines.map((line, i) => (
<text key={i} x={x + 16} y={142 + i * 26} fontFamily="monospace" fontSize="12" fill={i === lines.length - 1 && title === "CX Linux" ? "#00FF9F" : "#888"}>{line}</text>
))}
{/* Score badge */}
<rect x={x + 90} y={440} width={160} height={54} rx="8" fill={color} opacity={title === "CX Linux" ? 0.15 : 0.05} stroke={color} strokeWidth="1"/>
<text x={x + 170} y={465} textAnchor="middle" fontFamily="sans-serif" fontSize="11" fill={color} opacity="0.8">
{title === "CX Linux" ? "OS-level · Multi-step" : title === "Warp" ? "Terminal UX · No AI exec" : "Suggestion only"}
</text>
<text x={x + 170} y={483} textAnchor="middle" fontFamily="sans-serif" fontSize="10" fill="#666">
{title === "CX Linux" ? "Sandbox · Rollback · Context-aware" : title === "Warp" ? "Manual execution required" : "No system context"}
</text>
</g>
))}
{/* Winner badge */}
<rect x="40" y="545" width="340" height="44" rx="8" fill="#00FF9F" opacity="0.12" stroke="#00FF9F" strokeWidth="1.5"/>
<text x="210" y="572" textAnchor="middle" fontFamily="sans-serif" fontSize="14" fontWeight="bold" fill="#00FF9F">🏆 Best for production Linux work</text>
<text x="600" y="600" textAnchor="middle" fontFamily="sans-serif" fontSize="13" fill="#444">CX Linux · Warp · GitHub Copilot CLI — Which AI Terminal Tool Wins?</text>
</svg>
);
}
36 changes: 36 additions & 0 deletions client/src/blog/images/how-we-built-cx.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export default function HowWeBuiltCxImage({ className = "" }: { className?: string }) {
const layers = [
{ y: 120, h: 70, color: "#00FF9F", label: "Natural Language Interface", sub: "NLP · Intent parsing · Context resolution" },
{ y: 210, h: 70, color: "#22D3EE", label: "CX Core Engine", sub: "Planner · Command generator · Safety layer" },
{ y: 300, h: 70, color: "#818CF8", label: "Sandbox Runtime", sub: "Firejail · Snapshots · Rollback" },
{ y: 390, h: 70, color: "#F59E0B", label: "System Interface", sub: "apt · dnf · systemd · hardware detection" },
{ y: 480, h: 60, color: "#6B7280", label: "Linux Kernel", sub: "Debian · Ubuntu · Arch · RHEL" },
];

return (
<svg viewBox="0 0 1200 630" className={className} xmlns="http://www.w3.org/2000/svg" role="img" aria-label="CX Linux architecture diagram">
<rect width="1200" height="630" fill="#0D0D0D"/>
<text x="600" y="60" textAnchor="middle" fontFamily="sans-serif" fontSize="20" fontWeight="bold" fill="#FFFFFF">CX Linux Architecture</text>
<text x="600" y="85" textAnchor="middle" fontFamily="sans-serif" fontSize="13" fill="#555">Layered AI-native operating system design</text>
{/* Layer stack */}
{layers.map(({ y, h, color, label, sub }, i) => (
<g key={label}>
<rect x="200" y={y} width="800" height={h} rx="8" fill="#141414" stroke={color} strokeWidth="1.5" opacity={1 - i * 0.08}/>
{/* Left accent bar */}
<rect x="200" y={y} width="6" height={h} rx="3" fill={color} opacity="0.8"/>
<text x="260" y={y + h / 2 - 8} fontFamily="sans-serif" fontSize="15" fontWeight="600" fill="#FFFFFF">{label}</text>
<text x="260" y={y + h / 2 + 12} fontFamily="sans-serif" fontSize="12" fill="#666">{sub}</text>
{/* Right badge */}
<text x="960" y={y + h / 2 + 5} textAnchor="end" fontFamily="monospace" fontSize="11" fill={color} opacity="0.8">Layer {layers.length - i}</text>
{/* Arrow between layers */}
{i < layers.length - 1 && (
<path d={`M600 ${y + h} L594 ${y + h + 10} L606 ${y + h + 10} Z`} fill="#333"/>
)}
</g>
))}
{/* User bubble on top */}
<ellipse cx="600" cy="108" rx="60" ry="20" fill="#0A1A0F" stroke="#00FF9F" strokeWidth="1"/>
<text x="600" y="113" textAnchor="middle" fontFamily="sans-serif" fontSize="12" fill="#00FF9F">You</text>
</svg>
);
}
50 changes: 50 additions & 0 deletions client/src/blog/images/local-vs-cloud-llm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
export default function LocalVsCloudLlmImage({ className = "" }: { className?: string }) {
return (
<svg viewBox="0 0 1200 630" className={className} xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Local LLM vs Cloud LLM comparison diagram">
<rect width="1200" height="630" fill="#0D0D0D"/>
{/* Divider */}
<line x1="600" y1="60" x2="600" y2="570" stroke="#222" strokeWidth="2" strokeDasharray="6 4"/>
<text x="600" y="40" textAnchor="middle" fontFamily="sans-serif" fontSize="13" fill="#555">vs</text>
{/* LOCAL side */}
<text x="300" y="100" textAnchor="middle" fontFamily="sans-serif" fontSize="20" fontWeight="bold" fill="#FFFFFF">Local LLM</text>
<text x="300" y="122" textAnchor="middle" fontFamily="sans-serif" fontSize="13" fill="#555">Mistral 7B · Runs on your hardware</text>
{/* Server icon */}
<rect x="220" y="148" width="160" height="100" rx="8" fill="#141414" stroke="#333" strokeWidth="1.5"/>
<rect x="232" y="162" width="136" height="18" rx="3" fill="#1E1E1E"/>
<rect x="232" y="186" width="136" height="18" rx="3" fill="#1E1E1E"/>
<rect x="232" y="210" width="80" height="18" rx="3" fill="#1E1E1E"/>
<circle cx="345" cy="221" r="6" fill="#00FF9F" opacity="0.8"/>
<text x="300" y="278" textAnchor="middle" fontFamily="sans-serif" fontSize="12" fill="#666">GPU required (RTX 3060+)</text>
{/* Pros */}
{["✓ 100% offline", "✓ Zero API cost", "✓ No data leaves machine", "✓ Unlimited requests"].map((line, i) => (
<text key={i} x="160" y={330 + i * 24} fontFamily="sans-serif" fontSize="13" fill="#00FF9F" opacity="0.9">{line}</text>
))}
{/* Cons */}
{["✗ Needs GPU (8GB+ VRAM)", "✗ Slower inference"].map((line, i) => (
<text key={i} x="160" y={438 + i * 24} fontFamily="sans-serif" fontSize="13" fill="#888">{line}</text>
))}
{/* CLOUD side */}
<text x="900" y="100" textAnchor="middle" fontFamily="sans-serif" fontSize="20" fontWeight="bold" fill="#FFFFFF">Cloud LLM</text>
<text x="900" y="122" textAnchor="middle" fontFamily="sans-serif" fontSize="13" fill="#555">Claude · GPT-4o · Any OpenAI-compat</text>
{/* Cloud icon */}
<ellipse cx="900" cy="185" rx="70" ry="40" fill="#141414" stroke="#333" strokeWidth="1.5"/>
<ellipse cx="860" cy="196" rx="50" ry="30" fill="#141414" stroke="#333" strokeWidth="1.5"/>
<ellipse cx="940" cy="196" rx="55" ry="30" fill="#141414" stroke="#333" strokeWidth="1.5"/>
<rect x="835" y="210" width="130" height="28" rx="4" fill="#141414" stroke="#333" strokeWidth="1"/>
<text x="900" y="230" textAnchor="middle" fontFamily="monospace" fontSize="11" fill="#0EA5E9">API</text>
<text x="900" y="278" textAnchor="middle" fontFamily="sans-serif" fontSize="12" fill="#666">Works on any machine with internet</text>
{/* Pros */}
{["✓ State-of-the-art models", "✓ No GPU needed", "✓ Fast inference", "✓ Default in CX (easiest)"].map((line, i) => (
<text key={i} x="760" y={330 + i * 24} fontFamily="sans-serif" fontSize="13" fill="#0EA5E9" opacity="0.9">{line}</text>
))}
{/* Cons */}
{["✗ Requires internet", "✗ API cost per request"].map((line, i) => (
<text key={i} x="760" y={438 + i * 24} fontFamily="sans-serif" fontSize="13" fill="#888">{line}</text>
))}
{/* Bottom CX note */}
<rect x="250" y="530" width="700" height="50" rx="8" fill="#0A1A0F" stroke="#00FF9F" strokeWidth="1"/>
<text x="600" y="553" textAnchor="middle" fontFamily="sans-serif" fontSize="13" fill="#00FF9F" fontWeight="600">CX Linux supports both — switch with a single config flag</text>
<text x="600" y="570" textAnchor="middle" fontFamily="sans-serif" fontSize="11" fill="#666">cx config set llm.provider local | cloud | hybrid</text>
</svg>
);
}
52 changes: 52 additions & 0 deletions client/src/blog/images/sandboxed-execution.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
export default function SandboxedExecutionImage({ className = "" }: { className?: string }) {
return (
<svg viewBox="0 0 1200 630" className={className} xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Sandboxed execution security layers">
<rect width="1200" height="630" fill="#0D0D0D"/>
{/* Concentric rings */}
<circle cx="600" cy="315" r="260" fill="none" stroke="#1A1A1A" strokeWidth="60"/>
<circle cx="600" cy="315" r="180" fill="none" stroke="#141414" strokeWidth="50"/>
<circle cx="600" cy="315" r="100" fill="#141414" stroke="#00FF9F" strokeWidth="1.5"/>
{/* Shield icon in center */}
<path d="M600 255 L640 275 L640 320 Q640 345 600 360 Q560 345 560 320 L560 275 Z" fill="#0A1A0F" stroke="#00FF9F" strokeWidth="2"/>
<path d="M588 308 L596 316 L614 296" stroke="#00FF9F" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" fill="none"/>
{/* Ring labels */}
<text x="600" y="172" textAnchor="middle" fontFamily="sans-serif" fontSize="13" fill="#666">Layer 3: Firejail Sandbox</text>
<text x="600" y="245" textAnchor="middle" fontFamily="sans-serif" fontSize="12" fill="#555">Layer 2: Command Preview</text>
<text x="600" y="385" textAnchor="middle" fontFamily="sans-serif" fontSize="12" fill="#555">Layer 1: Snapshot / Rollback</text>
{/* Outer decorative ring */}
<circle cx="600" cy="315" r="270" fill="none" stroke="#00FF9F" strokeWidth="1" opacity="0.15" strokeDasharray="8 6"/>
{/* Binary code text around outer ring */}
{["01001", "10110", "00111", "11001", "01010", "10101"].map((bits, i) => {
const angle = (i / 6) * Math.PI * 2 - Math.PI / 2;
const r = 310;
return (
<text
key={i}
x={600 + r * Math.cos(angle)}
y={315 + r * Math.sin(angle)}
textAnchor="middle"
dominantBaseline="middle"
fontFamily="monospace"
fontSize="11"
fill="#333"
>
{bits}
</text>
);
})}
{/* Side labels */}
<rect x="60" y="200" width="160" height="90" rx="8" fill="#141414" stroke="#333" strokeWidth="1"/>
<text x="140" y="235" textAnchor="middle" fontFamily="sans-serif" fontSize="12" fontWeight="600" fill="#00FF9F">BLOCKED</text>
<text x="140" y="255" textAnchor="middle" fontFamily="sans-serif" fontSize="11" fill="#666">rm -rf /</text>
<text x="140" y="272" textAnchor="middle" fontFamily="sans-serif" fontSize="11" fill="#666">dd if=/dev/zero</text>
<line x1="220" y1="245" x2="330" y2="285" stroke="#FF4444" strokeWidth="1.5" strokeDasharray="4 3" opacity="0.5"/>
<rect x="980" y="200" width="160" height="90" rx="8" fill="#141414" stroke="#333" strokeWidth="1"/>
<text x="1060" y="235" textAnchor="middle" fontFamily="sans-serif" fontSize="12" fontWeight="600" fill="#00FF9F">APPROVED</text>
<text x="1060" y="255" textAnchor="middle" fontFamily="sans-serif" fontSize="11" fill="#666">apt install nginx</text>
<text x="1060" y="272" textAnchor="middle" fontFamily="sans-serif" fontSize="11" fill="#666">systemctl start</text>
<line x1="980" y1="245" x2="870" y2="285" stroke="#00FF9F" strokeWidth="1.5" strokeDasharray="4 3" opacity="0.5"/>
{/* Bottom text */}
<text x="600" y="580" textAnchor="middle" fontFamily="sans-serif" fontSize="16" fontWeight="bold" fill="#FFFFFF">Three Layers of Protection — Nothing Runs Without Your Approval</text>
</svg>
);
}
Loading