Deepnar Workstation — Deepesh Sonar's portfolio as an interactive browser workstation: files, terminal, knowledge graph, pixel companion.
See the codenext.js · typescript · tailwind · zustand · xterm.js · d3-force · canvas

Live demo: coming with the first Vercel deploy (this repo has not been deployed yet — no URL is claimed until then).
An interactive portfolio that behaves like a small research workstation, not a page of cards. You enter a guest session, open the workstation, and explore the work as files, terminal sessions, a knowledge graph, and git lanes.
“heyy” — pry, the small blue pixel companion who lives in the workstation. he notices your cursor sometimes, ignores it sometimes, and keeps his own opinions about your buffers.
Normal portfolios flatten everything into identical cards. This one keeps the shape of the work: projects live in a filesystem, research has an evaluation log, open source is a lane of real merged PRs, history is a graph you can drag around. If you can use a terminal and a file tree, you already know how to use this site.
ctrl+k
finder, ? help. Mobile gets the same workstation with a drawer + bottom
sheet instead of squeezed columns.] / [ / Enter / 0)./ assistant answers from a local
content index with cited buffers. No model calls, no hallucinated pages.scripts/gen-cursors.mjs is the single pipeline; lint enforces it).

npm install
npm run dev # http://localhost:3000
npm run lint # typecheck + secret scan + cursor check
npm run build # static production build
npm start # serve the production build
Boot → greeter → [ enter guest session ] → desktop → open workstation.
ls · tree · cd · cat · open · find · grep · ask · neofetch:e <path> · :bd · :bnext · :bprev?open=~/projects/ice/README.md1 workstation · 2 orbit · 3 signalThe site works fully with no environment variables. One optional feature needs them:
| var | where | why |
|---|---|---|
NEXT_PUBLIC_UPSTASH_URL | browser | Orbit global leaderboard (REST) |
NEXT_PUBLIC_UPSTASH_TOKEN | browser | same — public by design (v1), see below |
Copy .env.example to .env.local if you want the leaderboard locally.
Without them, Orbit keeps a local best score and everything else is
unaffected. There is deliberately no GITHUB_TOKEN: GitHub metadata is
synced at authoring time (npm run sync-github with local gh auth →
committed src/generated/github.json → builds ship the JSON).
src/app/ next.js routes (static: / + /_not-found)
src/workstation/ explorer · buffers · dock · terminal · palette · agent
src/system/ boot/greeter/desktop · pry (pet) · sound · store wiring
src/apps/ signal graph · orbit game
src/vfs/ virtual filesystem (the site's content tree)
src/content/ verified data only (about · projects · research · oss)
src/lib/ zustand stores · terminal engine · deterministic assistant
public/evidence/ certificates · dipex · egd sheets (intentionally public)
public/research/ papers (intentionally public)
scripts/ tests · screenshots · cursor pipeline · banner · secret scan
Content rule: src/content/ holds verified data, the VFS presents it, and
nothing from private CV source material ships (see .env.example +
scan-secrets). Full decisions: ARCHITECTURE.md.
localStorage.~/home/deepnar/… paths in the UI are the site's virtual filesystem,
not the author's machine.prefers-reduced-motion (seeds the motion default
and neuters CSS animation), skip-link first in tab order, Escape closes
overlays, focusable graph canvas.Static site — no server runtime. Push to GitHub → import in Vercel →
npm ci / npm run build / default output. Set the two Upstash vars for the
leaderboard. Social metadata is fixed to the production URL in
src/app/layout.tsx — no env var needed.
public/cursors/LICENSE.catppuccin +
ATTRIBUTION.md); hotspots re-derived from upstream v2.0.0 metadata.next/font/google (JetBrains Mono, OFL).lucide-react (ISC). Terminal: xterm.js (MIT).public/achievements/ATTRIBUTION.md).public/ are the author's own documents,
published deliberately.TypeScript
81.6%
JavaScript
16.2%
CSS
2.2%
Deepnar Workstation — Deepesh Sonar's portfolio as an interactive browser workstation: files, terminal, knowledge graph, pixel companion.
See the codenext.js · typescript · tailwind · zustand · xterm.js · d3-force · canvas

Live demo: coming with the first Vercel deploy (this repo has not been deployed yet — no URL is claimed until then).
An interactive portfolio that behaves like a small research workstation, not a page of cards. You enter a guest session, open the workstation, and explore the work as files, terminal sessions, a knowledge graph, and git lanes.
“heyy” — pry, the small blue pixel companion who lives in the workstation. he notices your cursor sometimes, ignores it sometimes, and keeps his own opinions about your buffers.
Normal portfolios flatten everything into identical cards. This one keeps the shape of the work: projects live in a filesystem, research has an evaluation log, open source is a lane of real merged PRs, history is a graph you can drag around. If you can use a terminal and a file tree, you already know how to use this site.
ctrl+k
finder, ? help. Mobile gets the same workstation with a drawer + bottom
sheet instead of squeezed columns.] / [ / Enter / 0)./ assistant answers from a local
content index with cited buffers. No model calls, no hallucinated pages.scripts/gen-cursors.mjs is the single pipeline; lint enforces it).

npm install
npm run dev # http://localhost:3000
npm run lint # typecheck + secret scan + cursor check
npm run build # static production build
npm start # serve the production build
Boot → greeter → [ enter guest session ] → desktop → open workstation.
ls · tree · cd · cat · open · find · grep · ask · neofetch:e <path> · :bd · :bnext · :bprev?open=~/projects/ice/README.md1 workstation · 2 orbit · 3 signalThe site works fully with no environment variables. One optional feature needs them:
| var | where | why |
|---|---|---|
NEXT_PUBLIC_UPSTASH_URL | browser | Orbit global leaderboard (REST) |
NEXT_PUBLIC_UPSTASH_TOKEN | browser | same — public by design (v1), see below |
Copy .env.example to .env.local if you want the leaderboard locally.
Without them, Orbit keeps a local best score and everything else is
unaffected. There is deliberately no GITHUB_TOKEN: GitHub metadata is
synced at authoring time (npm run sync-github with local gh auth →
committed src/generated/github.json → builds ship the JSON).
src/app/ next.js routes (static: / + /_not-found)
src/workstation/ explorer · buffers · dock · terminal · palette · agent
src/system/ boot/greeter/desktop · pry (pet) · sound · store wiring
src/apps/ signal graph · orbit game
src/vfs/ virtual filesystem (the site's content tree)
src/content/ verified data only (about · projects · research · oss)
src/lib/ zustand stores · terminal engine · deterministic assistant
public/evidence/ certificates · dipex · egd sheets (intentionally public)
public/research/ papers (intentionally public)
scripts/ tests · screenshots · cursor pipeline · banner · secret scan
Content rule: src/content/ holds verified data, the VFS presents it, and
nothing from private CV source material ships (see .env.example +
scan-secrets). Full decisions: ARCHITECTURE.md.
localStorage.~/home/deepnar/… paths in the UI are the site's virtual filesystem,
not the author's machine.prefers-reduced-motion (seeds the motion default
and neuters CSS animation), skip-link first in tab order, Escape closes
overlays, focusable graph canvas.Static site — no server runtime. Push to GitHub → import in Vercel →
npm ci / npm run build / default output. Set the two Upstash vars for the
leaderboard. Social metadata is fixed to the production URL in
src/app/layout.tsx — no env var needed.
public/cursors/LICENSE.catppuccin +
ATTRIBUTION.md); hotspots re-derived from upstream v2.0.0 metadata.next/font/google (JetBrains Mono, OFL).lucide-react (ISC). Terminal: xterm.js (MIT).public/achievements/ATTRIBUTION.md).public/ are the author's own documents,
published deliberately.TypeScript
81.6%
JavaScript
16.2%
CSS
2.2%