유대선
프로젝트로
·기술 회고·3

The web-enablement spine: how far work goes off the desktop

A strategy sanity-check turned into building a small, self-hostable backend — desktop keeps coding + the live terminal, the cloud/web does everything else, BYO preserved. Eight commits, verified by running. The honest part: it's identity-safe plumbing whose value is still gated on a second user.

It started as a question — does the operating-memory "brain upgrade" even make sense? — and ended with a running web app rendering the desktop home from a Hono server. In between, the real question surfaced: how far can DalkkakAI's work go off the desktop without breaking what it is?

The boundary that made it tractable

The product was 100% local: Tauri + tmux + bring-your-own Claude, zero backend. The naive answer to "put it on the web/cloud" is to run the agent in the cloud — which is the Gitpod path we'd already rejected (custody of the user's tokens and repo, arbitrary code execution on our boxes, the exact inversion of "local-first, your secrets never leave your machine").

The unlock was finding the actual line. It isn't "coding vs non-coding." It's "does this need local execution, the live terminal, or local files?"

What got built (in a worktree, verified by running)

Eight commits on an isolated branch, build-green at every step:

  1. A WidgetStore injected storage seam, so a widget persists through ctx.store instead of localStorage directly.
  2. Widgets extracted to a shared @ddalkkak/widgets package — 14 files git mv'd with zero internal edits — so desktop and web import the same UI.
  3. A @ddalkkak/server with a Ticket store and an SVN-style compare-and-set lock, plus the shared @ddalkkak/platform-client contract.
  4. A @ddalkkak/web PWA whose home renders the real desktop StartupView — header, NEEDS YOU, the 7 work zones, the records timeline — entirely from GET /home.
  5. A Hono ticket API where the lock was proven over real HTTP: alice claims → 200; bob claims the same ticket → 409 ALREADY_CLAIMED.
  6. Desktop → server push: pure mappers (graph node → record, blocked pane → NEEDS YOU signal) and POST /home/push. Live-demoed — a push replaced the seed and /home returned the pushed state.

Desktop 130 tests, server 14 tests, web build, all typecheck. The web home was screenshotted in a real browser and matched the desktop.

The honest part

It's local, in-memory, unauthenticated. The NEEDS-YOU and records are seeded or pushed in a demo; the live Tauri-app push interval is a one-step hookup that needs the running app. Supabase auth, Postgres, and a Fly deploy are all still ahead, and those need real infrastructure.

And the bigger honesty, unchanged from the start of the session: there is no moat today and zero paying users. This is identity-safe plumbing built for a product that one person uses. The architecture is clean and it preserves the soul of the thing — but the next move isn't another commit. It's putting this demo in front of a real second user and asking whether they'd use it. Beautiful infrastructure for an audience of one is the failure mode to avoid, not the win to celebrate.