"use client" import { useState, useEffect } from "react" import TerminalVisualizer from "@/components/terminal-visualizer" // Types for the layout tree type PaneNode = { type: "pane" id: number } type SplitNode = { type: "split-h" | "split-v" ratio: number children: [LayoutNode, LayoutNode] } export type LayoutNode = PaneNode | SplitNode const ASCII_ART = ` _________________________________________ / \\ | root@mytmux:~ $ tmux new -s dev | | [0] nvim ---------------- [1] server -- | | | | | | | | import { life } | npm run | | | | from 'tmux'; | dev | | | | | | | | | // TODO: Sleep | | | | |________________________|____________| | | [2] logs ------------------------------ | | | > ready in 200ms | | | | > watching files... | | | |_____________________________________| | \\_________________________________________/ ` export default function Home() { const [layout, setLayout] = useState({ type: "pane", id: 0 }) const [nextId, setNextId] = useState(1) const [activePaneId, setActivePaneId] = useState(0) const [generatedConfig, setGeneratedConfig] = useState("") // Helper to find and split the active node function findAndSplitNode( node: LayoutNode, activeId: number, direction: "h" | "v", nextIdVal: number, ): { found: boolean; nextId: number; newNode?: LayoutNode } { if (node.type === "pane") { if (node.id === activeId) { const oldId = node.id const newId = nextIdVal // Create new split node const newNode: SplitNode = { type: direction === "h" ? "split-h" : "split-v", ratio: 0.5, children: [ { type: "pane", id: oldId }, { type: "pane", id: newId }, ], } return { found: true, nextId: nextIdVal + 1, newNode } } return { found: false, nextId: nextIdVal } } else { // Recursively check children // We need to clone the node to avoid mutating state directly if we were modifying in place, // but here we are rebuilding the tree structure where needed. // Check left/top child const leftResult = findAndSplitNode(node.children[0], activeId, direction, nextIdVal) if (leftResult.found) { return { found: true, nextId: leftResult.nextId, newNode: { ...node, children: [leftResult.newNode as LayoutNode, node.children[1]], }, } } // Check right/bottom child const rightResult = findAndSplitNode(node.children[1], activeId, direction, nextIdVal) if (rightResult.found) { return { found: true, nextId: rightResult.nextId, newNode: { ...node, children: [node.children[0], rightResult.newNode as LayoutNode], }, } } return { found: false, nextId: nextIdVal } } } function splitPane(direction: "h" | "v") { const result = findAndSplitNode(layout, activePaneId, direction, nextId) if (result.found && result.newNode) { setNextId(result.nextId) setLayout(result.newNode) } } function resetLayout() { setLayout({ type: "pane", id: 0 }) setNextId(1) setActivePaneId(0) } // Generate config whenever layout changes useEffect(() => { let config = `# ~/.tmux.conf setup\n` config += `# Generated by mytmux.life\n\n` config += `new-session -s development -n editor\n` function traverse(node: LayoutNode) { if (node.type === "split-h") { config += `split-window -h\n` traverse(node.children[1]) // Right child config += `select-pane -L\n` // Go back left traverse(node.children[0]) // Left child } else if (node.type === "split-v") { config += `split-window -v\n` traverse(node.children[1]) // Bottom child config += `select-pane -U\n` // Go back up traverse(node.children[0]) // Top child } } traverse(layout) config += `\n# Select the initially active pane\n` config += `select-pane -t ${activePaneId}\n` setGeneratedConfig(config) }, [layout, activePaneId]) return (
{/* Hero Section */}
SYSTEM ONLINE

Master Your
<Terminal />

Stop wasting time switching windows. mytmux.life helps you architect the perfect terminal development environment.

{/* ASCII Art / Decorative Element */}
{ASCII_ART}
{/* Configurator Section */}

ENVIRONMENT_CONFIGURATOR

Visually design your session layout. Click actions to split the active pane.

{/* Controls & Output */}

> ACTIONS

ACTIVE_PANE_ID: {activePaneId}

> GENERATED_CONFIG

{generatedConfig}
{/* Visualizer Canvas */}
CANVAS_RENDER_TARGET
{/* Documentation / Info Section */}

01. MULTIPLEXING

Run multiple terminal sessions inside one single window. Detach them and leave them running in the background, then reattach later.

02. WINDOWS & PANES

Organize your workspace into windows (tabs) and panes (splits). Keep your editor, server logs, and git commands visible at once.

03. CONFIGURATION

Tmux is highly scriptable. Bind keys, change status bar colors, and create custom layouts to fit your specific workflow needs.

{/* Cheat Sheet */}

QUICK_REFERENCE_CARD

{[ { cmd: "Ctrl+b %", desc: "Split pane vertically" }, { cmd: 'Ctrl+b "', desc: "Split pane horizontally" }, { cmd: "Ctrl+b o", desc: "Swap to next pane" }, { cmd: "Ctrl+b c", desc: "Create new window" }, { cmd: "Ctrl+b n", desc: "Next window" }, { cmd: "Ctrl+b d", desc: "Detach session" }, ].map((item, i) => (
{item.desc} {item.cmd}
))}
) }