{"links":[{"kind":"tag","source":"note:panic-recover","target":"tag:golang"},{"kind":"tag","source":"note:panic-recover","target":"tag:systems"},{"kind":"tag","source":"note:oklch","target":"tag:web"},{"kind":"tag","source":"note:zettelkasten","target":"tag:graphs"},{"kind":"tag","source":"note:zettelkasten","target":"tag:notes"},{"kind":"wiki","source":"note:zettelkasten","target":"note:force-layouts"},{"kind":"tag","source":"note:force-layouts","target":"tag:graphs"},{"kind":"tag","source":"note:force-layouts","target":"tag:web"},{"kind":"wiki","source":"note:force-layouts","target":"note:oklch"},{"kind":"wiki","source":"note:force-layouts","target":"note:zettelkasten"},{"kind":"tag","source":"note:tmux-snippets","target":"tag:tmux"},{"kind":"wiki","source":"note:tmux-snippets","target":"note:tmux"},{"kind":"tag","source":"note:xterm-js","target":"tag:terminals"},{"kind":"tag","source":"note:xterm-js","target":"tag:web"},{"kind":"wiki","source":"note:xterm-js","target":"note:pty"},{"kind":"tag","source":"note:tmux","target":"tag:terminals"},{"kind":"tag","source":"note:tmux","target":"tag:tmux"},{"kind":"wiki","source":"note:tmux","target":"note:pty"},{"kind":"wiki","source":"note:tmux","target":"note:tmux-snippets"},{"kind":"tag","source":"note:pty","target":"tag:systems"},{"kind":"tag","source":"note:pty","target":"tag:terminals"},{"kind":"wiki","source":"note:pty","target":"note:tmux"},{"kind":"wiki","source":"note:pty","target":"note:xterm-js"}],"nodes":[{"date":"2026-08-14","excerpt":"recover() is scoped to the goroutine that panicked. A deferred recover in main does nothing for a panic in a goroutine you spawned — that panic unwinds its own stack, finds no recover, and takes the whole process down. …","id":"note:panic-recover","slug":"panic-recover","tags":["Golang","Systems"],"title":"recover() only works in the panicking goroutine","type":"note","url":"/notes/panic-recover/"},{"date":"2026-08-14","excerpt":"Every colour on this site is oklch(L C H) — lightness, chroma, hue. The reason is that lightness in OKLCH is perceptual, so two colours with the same L look equally bright to the eye. In HSL they do not: hsl(60 100% 50%) …","id":"note:oklch","slug":"oklch","tags":["Web"],"title":"Why this site's colours are oklch","type":"note","url":"/notes/oklch/"},{"date":"2026-08-14","excerpt":"The rule I am trying to hold to: one note, one idea, and a title that states the idea rather than naming the topic. “tmux is a server, not a wrapper” is a note. “tmux” is a folder pretending to be a note.\nThe reason is …","id":"note:zettelkasten","slug":"zettelkasten","tags":["Graphs","Notes"],"title":"Atomic notes","type":"note","url":"/notes/zettelkasten/"},{"date":"2026-08-14","excerpt":"A force layout has no idea what a good drawing looks like. It only knows three local rules: nodes repel each other, linked nodes are pulled together by a spring, and something weak drags everything toward the centre so …","id":"note:force-layouts","slug":"force-layouts","tags":["Graphs","Web"],"title":"Force-directed layouts","type":"note","url":"/notes/force-layouts/"},{"date":"2026-08-14","excerpt":"A snippet manager for tmux only needs three things: somewhere to keep the snippets, a way to pick one, and a way to inject it.\nInjection is the interesting constraint. send-keys types into the target pane as if you had …","id":"note:tmux-snippets","slug":"tmux-snippets","tags":["Tmux"],"title":"Snippet plugin design","type":"note","url":"/notes/tmux-snippets/"},{"date":"2026-08-14","excerpt":"xterm.js is a terminal emulator — it parses escape sequences and paints cells. It does not know where the bytes come from, which is what makes it composable: you own the transport.\nThe shape that works: a WebSocket …","id":"note:xterm-js","slug":"xterm-js","tags":["Terminals","Web"],"title":"xterm.js in the browser","type":"note","url":"/notes/xterm-js/"},{"date":"2026-08-14","excerpt":"The mental model that made tmux click: tmux the command is a client. The first invocation starts a long-lived server process, and every pane in every session is a pty owned by that server, not by your shell.\nThis is why …","id":"note:tmux","slug":"tmux","tags":["Terminals","Tmux"],"title":"tmux is a server, not a wrapper","type":"note","url":"/notes/tmux/"},{"date":"2026-08-14","excerpt":"A pty is a pair of character devices that pretend to be a terminal. The master end is held by whatever wants to drive a terminal; the slave end is what the child process opens as its controlling terminal, so the child …","id":"note:pty","slug":"pty","tags":["Systems","Terminals"],"title":"Pseudoterminals","type":"note","url":"/notes/pty/"},{"id":"tag:golang","posts":[{"title":"Why is my Golang server (not) crashing?","url":"/posts/golang-silent-panic/"}],"slug":"golang","title":"Golang","type":"tag","url":"/tags/golang/"},{"id":"tag:graphs","posts":[],"slug":"graphs","title":"Graphs","type":"tag","url":"/tags/graphs/"},{"id":"tag:notes","posts":[],"slug":"notes","title":"Notes","type":"tag","url":"/tags/notes/"},{"id":"tag:systems","posts":[{"title":"Why is my Golang server (not) crashing?","url":"/posts/golang-silent-panic/"}],"slug":"systems","title":"Systems","type":"tag","url":"/tags/systems/"},{"id":"tag:terminals","posts":[{"title":"Tmux Snippets (take your commands with you everywhere!)","url":"/posts/tmux-snippets-plugin/"}],"slug":"terminals","title":"Terminals","type":"tag","url":"/tags/terminals/"},{"id":"tag:tmux","posts":[{"title":"Tmux Snippets (take your commands with you everywhere!)","url":"/posts/tmux-snippets-plugin/"}],"slug":"tmux","title":"Tmux","type":"tag","url":"/tags/tmux/"},{"id":"tag:web","posts":[],"slug":"web","title":"Web","type":"tag","url":"/tags/web/"}]}