진행 중 · 2026년 5월 25일
DalkkakAI
솔로 창업자가 여러 스타트업을 병렬로 운영하기 위한 네이티브 macOS 멀티-페인 터미널 멀티플렉서 + Claude Code 워크스페이스.
- 역할
- Solo (Claude Code 페어 프로그래밍)
- 스택
- Tauri 2 · Rust · React 19 · TypeScript · xterm.js · portable-pty · tmux
여러 "스타트업" 워크스페이스에 걸쳐 다중 터미널 페인을 띄우고, 각 페인은 영구 tmux 세션으로 백업되어 앱 재시작 후에도 claude, dev 서버, 로그 tail이 살아남는 네이티브 macOS 앱. 내가 직접 쓰려고 만들었음 — 맥북 데스크톱 12개를 동시에 띄워놓고 작업하다 Mission Control 전환에 시간을 다 쓰고 있었음.
무엇을 하는가
- 멀티-페인 터미널 그리드 (react-mosaic + xterm.js) + 페인별 PTY
- 각 페인은
dalkkak-<id>키의 tmux 세션 → 앱보다 오래 삶 - 멀티-스타트업 사이드바, 스타트업별 layout,
⌘1..9/⌘⇧[/⌘⇧]단축키 - localStorage에 layout JSON 영속화, 실행 시 자동 reattach
- 2-layer 관측: Claude Code hooks →
logs/*.jsonl, Rusttracing→ daily-rolling runtime 로그
왜
이 제품의 핵심 동작은 사용자 본인의 로컬 claude 바이너리를 조작하는 것. 브라우저 탭은 이걸 못 함 — 즉 web-only로는 본질적 문제를 해결 불가능. Tauri (Rust 백엔드 + 시스템 WebKit) 로 ~10MB 번들에 파일 시스템 + 프로세스 트리 소유권 유지. Warp / iTerm / BridgeMind 가 모두 "1 프로젝트 = 1 윈도우" 가정인 것과 달리 멀티-스타트업이 first-class라는 점이 차별화 지점.
출시된 것 (v0.1.0)
Phase 1: 멀티-페인 + tmux 영속화 + 멀티-스타트업 사이드바. 규모: Rust 309줄, TypeScript 14 파일. Unsigned beta, macOS Apple Silicon 전용.
아직 안 한 것
Phase 2 (Claude Code 출력 augmentation), Phase 3 (cross-startup operator layer), Phase 4 (signed release + marketplace) 는 로드맵만 있음. 사용자: 0명. Dogfood 테스트 — 12개 데스크톱을 1주일 동안 이 앱으로 대체 — 아직 미실시.
짚을 만한 엔지니어링 포인트
- Lifecycle decouple. xterm + PTY를 React 바깥 module-level registry로 빼냄. Mosaic split/stack 으로 인한 remount가 이들을 건드리지 않음. VS Code Server의 터미널 호스팅 패턴. (로그)
- Subprocess env hygiene. Tauri GUI 앱은 최소 PATH + 거의 빈 환경변수를 상속. 명시적
TERM,LANG, PATH augmentation 없이는claude --resume이 15초 멈추고 tmux가 silent하게 실패함. (로그 1, 로그 2) - Bug-as-asset. 출시된 모든 버그에 6-섹션 post-mortem (symptom / root cause / fix / instruction-blame / avoidability / lessons),
CLAUDE.mdRULE #6로 강제.
프로젝트 로그
이 프로젝트를 만들면서 남긴 트러블슈팅 · 회고 · 업데이트의 시간순 기록.
Pivoting v1 (Python/FastAPI) to v2 (Tauri + Rust + React)
기술 회고2026년 5월 25일 · 1 분
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/.
Focus-based split + keyboard shortcuts — iTerm's 50-year pattern, not a new one
사용성 회고2026년 5월 26일 · 1 분
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
기술 회고2026년 5월 26일 · 2 분
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
기술 회고2026년 5월 26일 · 1 분
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
트러블슈팅2026년 5월 26일 · 2 분
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
기술 회고2026년 5월 26일 · 1 분
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
트러블슈팅2026년 5월 26일 · 1 분
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
기술 회고2026년 5월 26일 · 1 분
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
트러블슈팅2026년 5월 26일 · 1 분
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.
Set up cross-repo blog log aggregation, then deduped CLAUDE.md against myself
업데이트2026년 5월 27일 · 1 분
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
기술 회고2026년 5월 27일 · 2 분
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
비즈니스2026년 5월 27일 · 1 분
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
기술 회고2026년 5월 27일 · 1 분
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
기술 회고2026년 5월 27일 · 1 분
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
기술 회고2026년 5월 27일 · 1 분
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.