Active · May 25, 2026
DalkkakAI
One window for every startup you're running — a native, multi-pane terminal command deck for the solo founder who brings their own AI (Claude Code / Codex). Tauri + Rust, macOS.
- Role
- Solo (AI-pair-programmed with Claude Code)
- Stack
- Tauri 2 · Rust · React 19 · TypeScript · xterm.js · portable-pty · tmux

Project log
Chronological record of troubleshooting, retros, and updates while building this.
Decisions & milestones
Architecture overview — DalkkakAI as of 2026-05-31
SnapshotMay 31, 2026 · 3 min
Tauri 2 desktop app: React 19 renderer hosts xterm panes that attach to PTYs owned by a Rust backend, which spawns each pane into a per-pane tmux session.
ADR-001: hooks (not TUI scraping) for per-session status
DecisionMay 30, 2026 · 6 min
Per-session live status (working / needs-you / done) will be driven by Claude Code hooks emitting structured events, not by scraping the TUI. TUI scraping was proven unreliable (spinner repaints, never crosses \n); hooks are free, structured, and reversible. Verified end-to-end the next day: 37 events across 3 correctly-tagged panes, stale-working bug gone.
Build log
Week of Jun 1, 202611 entries · 1 Update · 2 Troubleshoot · 7 Tech retro · 1 UX retro
Arrow-key startup switching that dodges every macOS and terminal shortcut — and the one tmux flag that fixed scrollback-on-entry
UX retroJun 2, 2026 · 4 min
Switching between startups by Ctrl+number felt clunky for back-and-forth, so the founder asked for arrow keys — under a hard rule: collide with neither a macOS system shortcut nor a terminal one. On a terminal host that rules out almost every arrow chord (⌃-arrows are macOS Spaces, ⌥-arrows are the shell's word-motion), leaving ⌘⌥+arrow as the lone safe slot. Same session, a second friction: tmux scroll mode wouldn't scroll up on entry until the copy cursor climbed to the top edge — fixed with a single `copy-mode -u` flag, verified against a real tmux server.
Claude Code absorbed git worktrees — and what 'just run many sessions' actually costs
Tech retroJun 2, 2026 · 3 min
Running many Claude Code sessions on one repo is DalkkakAI's whole premise — so 'won't concurrent edits clobber each other?' was a question I had to answer honestly. Two tempting beliefs needed correcting: a session is not auto-isolated, and worktree support (now native in Claude Code v2.1.160) is opt-in, not automatic. Plus the forced trade-off nobody mentions: full isolation and live-reflection-in-your-current-checkout are mutually exclusive.
Re-skinning the whole app to a Stark-HUD design language — without touching the file a second session was editing
Tech retroJun 2, 2026 · 2 min
Phase 1 of an app-wide design system: a single hud.css defines design tokens (glow, surface, border, radius, motion, mono) and re-skins the sidebar, toolbar, brand, pane headers, focus glow, splits and context menu to a cohesive Stark-HUD language. The neat trick: the entire main screen is styled by CSS classes, so the re-skin layers on via a stylesheet loaded after App.css — zero edits to App.tsx, which a concurrent session was actively editing (paywall). Conflict avoided by construction.
A JARVIS-style live orchestration HUD — and why WebGL is fine here when it broke the terminal
Tech retroJun 2, 2026 · 2 min
Built a Tony-Stark / JARVIS holographic command center for the portfolio: a WebGL (react-three-fiber) scene — arc-reactor core, startups as emissive nodes on a sphere, energy lines with light packets that run when an agent works, bloom glow, auto-orbit. The same WebGL that broke Korean IME in the terminal is perfectly safe here, because this is a standalone visual canvas, not xterm's text-rendering path. Grounded in how real React JARVIS HUDs are built (particle network + shader-style pulses + bloom) rather than hand-rolled SVG, after two weaker SVG attempts.
Chasing many-pane smoothness: a WebGL renderer pulled for safety, and the error boundary that should have been there all along
Tech retroJun 2, 2026 · 3 min
Running ~9 streaming Claude panes felt laggy, so I reached for the obvious lever — xterm's WebGL renderer. It compiled and the IPC-batching half landed cleanly, but a separate blank-window crash (opening the summary) exposed a deeper gap: the app had no React error boundary, so any single render throw whited out the entire window with zero diagnostics. I disabled WebGL (the riskier lever, prime suspect for a blank at high pane counts), shipped the safe wins, and added the boundary that turns a future blank into a readable, recoverable error.
Startup ≠ pane ≠ tmux session: the three layers behind 'same app, different data'
Tech retroJun 2, 2026 · 5 min
Running the dev build (tauri dev) next to the installed app showed a completely different startup list — same code, different data. Untangling that confusion surfaces DalkkakAI's actual layering: a startup is a frontend localStorage group, a pane is one tmux session, and there is exactly one shared tmux server. Frontend state is per-origin (separate between dev and prod); the tmux backend is shared. That asymmetry is the whole story — and it's why the orphan-session GC must run in prod only.
Why ~14 Cursor windows ran the fans and ~14 tmux panes in DalkkakAI didn't: a process-topology post-mortem
Tech retroJun 1, 2026 · 8 min
Replacing ~14 Cursor (Electron) windows — each a Claude session — with ~14 Claude sessions in one DalkkakAI tmux multiplexer made the heat/fan load disappear. The mechanism is process topology, not the LLM: N per-window Chromium renderer + extension-host trees collapse into one shared WebKit renderer. Honest about the confounds (the before-state is gone, Docker's VM, the machine isn't hot now) and the single-point-of-failure I traded for it.
Why codex was 'command not found' in my own terminal app — but claude wasn't
TroubleshootJun 1, 2026 · 4 min
Prepping a demo, I tried to run codex inside a DalkkakAI pane and got 'command not found' — even though it was installed. The culprit: a leaked npm_config_prefix (from launching the app via pnpm) made nvm refuse to load, so every nvm-global CLI vanished. claude worked only because I'd special-cased it. The fix was to stop polluting the pane's environment, not to special-case codex too.
A clipboard-poisoning paste bug, a per-startup graph, and reviving an orphaned visualization
Tech retroJun 1, 2026 · 2 min
Three things in one pass: fixed a bug where clicking a colored separator line copied dashes and poisoned the clipboard (so every paste showed -----); split the connective graph so each startup shows only its own folder/git activity (the cross-startup dashboard stays separate); and re-wired a node-graph visualization that had been built but never connected to any view.
Shipped the public landing page — mascot art, bilingual, a real-capture carousel, and a demo video
UpdateJun 1, 2026 · 2 min
The DalkkakAI landing page went live at ddalkkak.daeseon.ai: the sloth-robot mascot art used as a hero banner + roomy explainer bands (never faked as screenshots), an English-default page with a one-click Korean toggle, a data-driven screenshot carousel that adapts to however many real captures exist, and a ~1.5-min demo video (poster + click-to-play). Deployed from the local folder via the Vercel CLI onto an existing custom domain.
Chasing wheel-scrollback with tmux mouse mode broke the terminal — and reverting the code didn't undo the live server
TroubleshootJun 1, 2026 · 2 min
Enabling tmux mouse mode to get wheel-scrollback flooded the webview (glitch + lag) and broke copy. The deeper lesson: reverting the CODE didn't reset the running tmux server, and disabling the mouse option didn't exit a pane already stuck in copy-mode.
Week of May 25, 202627 entries · 4 Update · 7 Troubleshoot · 14 Tech retro · 1 UX retro · 1 Business
Let the doer summarize itself — and edit a dotfile without ever corrupting it
Tech retroMay 31, 2026 · 2 min
The post-hoc summary (spawn a fresh claude -p to re-read the transcript) was 20–50s. The founder reframed it: the session's own Claude already did the work — have IT emit the summary as a byproduct. The tricky part was the plumbing: getting the pane's claude to self-summarize meant editing ~/.zshrc, done append-only so it can never break the user's terminal.
Layer 2's wall: a good summary that takes 24 seconds
TroubleshootMay 31, 2026 · 2 min
Built an on-demand '✨ Summarize this session' button that runs the user's own claude -p. The card content came out great (a workflow-designed prompt picks the right kind in plain language) — but it takes 22–54 seconds. Measuring split boot from API time and killed the obvious guesses.
Layer 2 made reliable: read the summary card from the transcript, and show real token usage (no fake $)
Tech retroMay 31, 2026 · 3 min
The in-line session-summary card stopped fighting the mangled TUI stream and started reading the un-mangled transcript JSONL (ADR-004). Same file then powers a per-session token-usage line — real numbers, and deliberately no dollar figure on a subscription.
Usage Pulse P0 shipped: a zero-storage, cross-startup 'pulse' that reads its numbers at view-open
UpdateMay 31, 2026 · 2 min
Built all six Usage Pulse views on the locked spec — effort split, momentum, fan-out, explore-vs-produce, friction, shipped-vs-thrash — backed by one pure Rust roller that persists nothing and never shows a dollar. Verified end-to-end on real data, and caught the spec's one wrong assumption about the hook line.
Designing the usage 'pulse' with a 7-agent workflow that read its own codebase
Tech retroMay 31, 2026 · 3 min
Spec for per-startup / daily AI-usage metrics, designed by a 3-draft → adversarial-critique → synthesis workflow. The verdict: a read-time 'pulse' that persists nothing, sourced from transcripts (not the sparse hook stream), with honest units and counts-only logging.
Locked the blueprint: a solo founder's OS to start → build → manage → operate services
UpdateMay 30, 2026 · 2 min
Confirmed and wrote the connective-layer vision into BLUEPRINT.md §5.5. The 6 core layers are bound by a shared data spine — a living graph of each startup's connection points (identity, structure, issues, flows, billing), kept fresh by agents pushing standard-format records as a byproduct of work, without distorting the work. Mission refined to the start→build→manage→operate lifecycle, security tuned to be consumer-appropriate.
Built the connective layer v0 in one session: designed, verified 4/4, shipped, 16 real nodes captured
UpdateMay 30, 2026 · 2 min
From a confirmed blueprint to a working first slice of the connective layer in one session. A multi-agent design pass produced a 'commits-first' v0; an adversarial pass failed it 3/4, so we applied the prescribed fixes and re-verified 4/4; then built it layer by layer (schema, a single Rust path-allowlist chokepoint, off-thread git-commit capture, a folder-picker grant, a cross-startup graph panel). Dogfood test: granted two repos, 16 confirmed change nodes captured — including this session's own commits.
Korean in a Tauri terminal: tmux underscores, then a WKWebView IME jamo leak I half-fixed
TroubleshootMay 30, 2026 · 2 min
Dogfooding surfaced Korean typing as '__', then as decomposed jamo. The first was tmux running non-UTF-8 (GUI apps inherit no locale) — fixed. The second is WKWebView not firing composition events for a textarea created before its IME is ready — pinned down with runtime.log instrumentation, still unresolved (workaround: split). I also regressed the working split case once by shipping an unguarded fix.
The logging loop's first real save — a launch crash diagnosed from logs, not guesswork
Tech retroMay 30, 2026 · 2 min
We'd just switched to a build → install → app-logs → fix loop instead of babysitting a dev server. The first crash after that change proved the loop: the founder said one sentence — 'it crashed' — and the logs did the rest. SIGABRT pinpointed to a one-line bug in minutes, no guesswork.
Per-session status v1 — and why you can't scrape it from a TUI
TroubleshootMay 30, 2026 · 2 min
Wired the augmentor event stream into a live per-session status strip and dogfooded it across three real Claude panes — then hit a wall: Claude Code repaints its spinner in place, so a line parser catches the status only by luck. The honest conclusion is to use Claude Code hooks, not TUI scraping. Plus a small UX fix: the hidden startup-delete is now a visible button.
The terminal couldn't ls Documents — it was a shared tmux server, not a code bug; gave DalkkakAI its own
TroubleshootMay 30, 2026 · 1 min
A pane's shell hit 'Operation not permitted' in ~/Documents while the new connective-layer git capture read the same repo fine. pgrep showed why: panes attached to the default shared tmux server — a days-old daemon from another terminal, without Documents TCC — while capture ran git directly in the app's granted context. Fix: run DalkkakAI's panes on a dedicated 'tmux -L dalkkak' server (correct TCC context + isolated from the user's other sessions), plus Info.plist usage strings so the bundled app prompts instead of silently denying.
Viz layer v1 — a locked-draft vocabulary + five animated renderers
Tech retroMay 30, 2026 · 2 min
Built the rendering layer that turns the connective layer's raw signals into 0.5-second-glance cards. A workflow-designed viz_kind vocabulary, five animated renderers, and an Activity view that renders real captured commits — all on a typed i18n base (English default).
Set up cross-repo blog log aggregation, then deduped CLAUDE.md against myself
UpdateMay 27, 2026 · 1 min
I had written 6 timeline entries directly into the blog repo, missing that this repo is actually a cross-repo log satellite. Migrated them here, locked the slug in CLAUDE.md RULE #9, then audited and deduped #9 against an existing Project-log section I'd also missed.
DalkkakAI v0.1.0 — Phase 1 shipped as an unsigned beta
Tech retroMay 27, 2026 · 2 min
Multi-pane terminal with tmux persistence and a multi-startup sidebar, in 309 lines of Rust and 14 TypeScript files. Tagged v0.1.0; unsigned, macOS Apple Silicon only, zero users yet.
Rewriting the portfolio docs after a brutal-honesty round on AI vs me
BusinessMay 27, 2026 · 1 min
Asked for a portfolio rating, got a flattered answer back, pushed back hard. Re-rated honestly (AI did most of the typing, I did the architecture / debugging direction / product calls). Rewrote README, added RESUME.md, refreshed CONTEXT.md to match.
StreamParser shipped with hardcoded regexes — they don't match real Claude Code output
Tech retroMay 27, 2026 · 1 min
Phase 2.1 Stage 1 landed a StreamParser that pattern-matches Claude Code output into tool calls / prompts / activity / completion events. It uses fragile hardcoded regexes and captures zero events in real usage. Should pivot to Claude Code hooks.
Should DalkkakAI eventually move to Swift? Walked the blueprint to decide
Tech retroMay 27, 2026 · 1 min
Caught myself flirting with a Swift rewrite for 'Apple-grade UX.' Walked every layer of the BLUEPRINT and concluded the current product as designed has no part that *requires* Swift. Tauri stays unless the blueprint itself pivots.
Two-layer observability — Claude Code hooks for dev-time, Rust tracing for runtime
Tech retroMay 27, 2026 · 1 min
Split observability into two layers with different purposes: Claude Code hooks capture every Bash/Edit/Prompt/Stop during dev, Rust `tracing` captures PTY lifecycle on the user's machine. Codified as CLAUDE.md RULE #8.
Focus-based split + keyboard shortcuts — iTerm's 50-year pattern, not a new one
UX retroMay 26, 2026 · 1 min
First split UX put a button in the toolbar that always split the root. Replaced with focused-pane split + ⌘D / ⌘⇧D / ⌘W, matching what every terminal user has had muscle memory for since the 1970s.
react-mosaic remounts killed running Claude sessions — moved xterm + PTY out of React
Tech retroMay 26, 2026 · 2 min
Splitting a pane changed its path in the mosaic tree, which React treated as an unmount, which fired the cleanup effect, which killed the PTY — and the running `claude` session with it. Fixed by hoisting xterm and the PTY out of React entirely.
Multi-startup sidebar — N startups in one workspace, each with its own layout
Tech retroMay 26, 2026 · 1 min
Phase 1.4 Step 1: introduced the Startup as a first-class concept. Sidebar lists startups, each owns its own pane layout. Right-click for rename / change emoji / delete.
Tauri GUI bundle's minimal PATH made tmux silently exit
TroubleshootMay 26, 2026 · 2 min
Panes printed `[exited]` and seemed to share sessions because `CommandBuilder::new("tmux")` couldn't resolve the binary — the GUI app's inherited PATH didn't include /opt/homebrew/bin.
Phase 1.0 — Tauri 2.x scaffold under apps/desktop
Tech retroMay 26, 2026 · 1 min
Bootstrapped the actual Tauri app under apps/desktop, then deleted the placeholder apps/web and apps/api from the v1 bootstrap. First `pnpm tauri dev` opened a native window.
claude --resume took 15s inside the DalkkakAI PTY
TroubleshootMay 26, 2026 · 1 min
The same `claude --resume` finished instantly in iTerm but hung for ~15 seconds in a freshly spawned DalkkakAI pane. Cause was a near-empty environment in the PTY child.
Phase 1.2 — first PTY pane streaming output to xterm.js
Tech retroMay 26, 2026 · 1 min
Wired portable-pty in Rust to xterm.js in the renderer through Tauri commands + events. Typing `ls` in a freshly opened pane echoed back. First moment the app felt real.
useEffect race ate the layout of every freshly-created startup
TroubleshootMay 26, 2026 · 1 min
New startups appeared in the sidebar fine, but their pane layout disappeared on the next launch. Two effects (Load and Save) were racing on the initial render, and the Load effect's stale closure was overwriting the Save.
Pivoting v1 (Python/FastAPI) to v2 (Tauri + Rust + React)
Tech retroMay 25, 2026 · 1 min
Started DalkkakAI as a web app over a FastAPI backend, then realised the core feature — driving the user's local Claude Code binary — is technically impossible in a browser sandbox. Pivoted to Tauri the same day and froze v1 under old_repo/.