My corner of the internet: a floating macOS terminal running tmux, as my
landing page. Window 1:josh boots fastfetch (Apple logo, with a few real
per-visitor lines) and drops you into an interactive fake shell, josh, with a
curated filesystem to explore. Window 2:josh opens my about file with cat.
Static site, no backend. The shell, filesystem, and easter eggs all run in the browser, so the origin just serves files (and Cloudflare caches them at the edge).
- Vite + Vue 3 + TypeScript
- Custom DOM terminal (no xterm.js)
- The filesystem and command interpreter are plain, framework-free TS modules
npm install
npm run dev # http://localhost:5173
npm run build # type-check + bundle to dist/
npm run preview # serve the built dist/ locallysrc/
fs.ts the fake filesystem (the thing I grow over time)
shell.ts command interpreter: ls/cd/cat/tree/fastfetch/josh/...
fastfetch.ts boot banner (Apple logo + system info; browser/memory/locale are real)
josh.ts josh's version + changelog (josh --version)
util.ts esc() + colored-span helpers
App.vue desktop: wallpaper, menubar, window, tmux state, Ctrl-Space prefix
components/
MenuBar.vue faux macOS menubar + clock
TmuxStatus.vue top tmux status bar (centered, clickable windows)
ShellWindow.vue the interactive terminal (every window is one)
- Add files / easter eggs: edit
src/fs.ts. New nodes are picked up byls/cd/cat/treeautomatically. Prefix a name with.to hide it behindls -a. - Add a command: add a
casetorun()insrc/shell.ts. - Ship a change: bump
JOSH_VERSIONinsrc/josh.tsand prepend a changelog entry, sojosh --versionalways shows what's new. - Add a tmux window: append a name to
windowsinApp.vueand add a<ShellWindow>to.panes. Every window must be a real shell (one with a focused input) so it keeps the keyboard for prefix navigation.
- type
helpfor the command list Ctrl-Spacethen1/2/n/pswitches windows (or click them). The>_by the session name means the prefix is armed. Mirrors theC-SPACEprefix in my tmux config (tap it, release Ctrl, then the number).Ctrl-lclears,Ctrl-ccancels the line, up/down walk history- drag the titlebar to move; double-click it (or the green light) to zoom; drag any edge or corner to resize
npm run build produces a static dist/. Options:
- Cloudflare Pages: point it at this repo, build command
npm run build, output directorydist. - Any static origin behind Cloudflare. Example Caddy config:
hlink.dev { root * /var/www/hlink/dist file_server encode zstd gzip }