Skip to content

Wmux

v2.9.0 Feature

This release adds 3 notable features for engineering teams evaluating rollout.

Published 1mo CLI & Terminal
✓ No known CVEs patched
Read the diff → Tool health → What is this tool? →

✓ No known CVEs patched in this version

Topics

agentic-ai ai-agent ai-agents ai-coding browser-automation claude
+12 more
claude-code coding-agent developer-tools electron gemini mcp-server multi-agent powershell terminal-multiplexer tmux tmux-alternative windows

Affected surfaces

auth rbac breaking_upgrade

Summary

AI summary

Updates Migration Notes, M0-b, and M0-c across a mixed release.

Full changelog

[2.9.0] — 2026-05-14 — Substrate 3.0 — Phase 0 + M0

wmux의 substrate identity 를 v3.0 으로 끌고 가기 위한 첫 번째 ship unit. v2.8.x 에서 이미 ~50% 가 출하돼 있던 substrate 표면 (PaneMetadata, EventBus, bootId, asOfSeq, system.capabilities, MCP host, mcp.claimWorkspace) 위에 (a) 그 표면의 contract 를 명문화한 Phase 0 문서, (b) main process 측 metadata authority 인 MetadataStore 와 그 wire 통합 (M0-a~f), (c) v2.8.x dogfood 중 노출된 스크롤백 손상 + reconcile race + logSink durable write 안정성 픽스를 한꺼번에 ship. 메인 PR 은 #34 (Substrate 3.0 — Phase 0 + M0, v2.9.0 ship unit) 이고 후속 마이그레이션 도구는 #35 (chopped-dump recovery tool) 로 따라간다. 외부 RFC 협의는 #15 (@alphabeen) 에서 진행됐고 그 OCC + mergeMode 디자인이 코드로 착지.

업그레이드 영향:

  • 와이어 contract 는 v2.x 와 backwards-compatible 이다 (expectedVersion, mergeMode, pane.metadata.changedversion 모두 additive optional).
  • 디스크에 새로 등장하는 폴더: userData/wmux/scrollback/corrupted/scrollback/*.txt.bak[.1..3] 회전 슬롯. 둘 다 자동 관리.
  • v2.8.x 사용자가 첫 부팅 때 일부 패널 스크롤백이 비어 보일 수 있다 — 이미 디스크에 chopped 형태로 저장돼 있던 dump 가 v2.9.0 detector 에 의해 격리되기 때문. 데이터는 격리 폴더에 보존되며 scripts/recover-scrollback.mjs 로 사람이 읽을 수 있는 텍스트로 복원 가능. 자세한 가이드는 docs/upgrade-v2.9.0.md 참조.

Added

  • Substrate 3.0 contract documentationdocs/PROTOCOL.md (substrate wire contract: layered status, namespacing, optimistic concurrency, mergeMode, cursor opaqueness, snapshot reconciliation, permission enforcement sketch, Named Pipe token security model), docs/api/{inventory,versioning,stability}.md (모든 RPC/MCP/event 의 stability tier + semver + 자동 업데이트 호환 정책), docs/internal/{m0-design,paneSlice-callsite-inventory}.md (M0 race specs + paneSlice 변경 blast-radius).
  • MetadataStore 모듈 (M0-a) — main process 의 PaneMetadata authority. get / set / clear / snapshot / hydrate / serialize / migrate / onPaneDeleted, per-pane monotonic version, expectedVersion 기반 OCC, 세 가지 mergeMode (merge / replace / replaceShared). 31 unit test 가 CRUD + version + mergeMode 트랜잭션 + OCC + 검증 + snapshot + persistence + EventBus emission 을 cover, codex full-stack review 가 catch 한 3건 (replaceShared 의 custom 보호, 누적 size cap, updatedAt 추가 후 cap 적용) regression test 포함.
  • pane.resolveActiveLeaf IPC 채널 (M0-b) — caller 가 paneId 를 생략하면 main 이 renderer 에 active leaf id 를 query (read-only, paneSlice 쓰기 0) 한 뒤 MetadataStore 에 commit. codex P1 review 가 잡은 split-store read-after-write 구멍 닫힘.
  • MetadataStore.snapshot()pane.list 통합 (M0-c)pane.list envelope 가 store snapshot 으로 anchored, asOfSeq 가 snapshot lineage 를 반영. renderer 가 더 이상 metadata 를 자체 합성하지 않음.
  • SessionManager.saveMetadataSync 와이어 (M0-e) — MetadataStore 의 persist callback 이 metadata.json 에 atomic write, launch 시 store 가 그 파일에서 hydrate. codex P2 review 가 잡은 strict field validation 포함.
  • Wire format 추가 (M0-f)pane.setMetadata 가 optional expectedVersion + mergeMode, reply / event / list 가 optional version 필드. v2.x subscriber 영향 없음 (모두 additive).
  • Optional version 필드 on pane.metadata.changed events.
  • PR template with CHANGELOG + stability-tier sections.
  • atomicWriteText / atomicReadText (sync + async) — core.ts 의 JSON 변종과 짝이 되는 텍스트 변종. rotation chain + quarantine 파이프라인 공유. JSON 변종이 parseable payload 를 전제하기 때문에 raw-bytes contract 가 필요한 스크롤백을 위해 sibling 으로 분리.
  • Cols-collapse corruption detector (src/main/scrollback/corruption.ts) — chopped dump 의 on-disk 시그니처 (median 비공백 행 길이 ≤ 3자, CRLF 바이트 비율 ≥ 0.3) 휴리스틱 검출기. 단일 패스 스캔, allocation 최소. 15 unit test 가 production v2.8.4 fixture (median=1, max=60 까지 outlier 살아남은 chopped 파일) 와 false-positive 저항 (정상 출력, sparse 세션, narrow pane, ANSI-rich 로그, 단일 긴 줄) cover.
  • scrollbackDump util 모듈 (src/renderer/utils/scrollbackDump.ts) — renderer 의 dump serializer 를 AppLayout.tsx 에서 분리. eligibility 가드 (cols < 12 / rows ≤ 0 / terminal.element.offsetWidth === 0 / detached) 가 unit-testable. 13 test 가 각 가드 branch + happy path 를 pin.
  • scripts/recover-scrollback.mjs (#35) — read-only 마이그레이션 CLI. v2.8.x → v2.9.0 첫 부팅에서 corrupted/ 로 격리된 chopped dump 를 reverse-reflow 로 사람이 읽을 수 있는 텍스트로 복원. node:util parseArgs 기반, dry-run / verbose / 입출력 dir 오버라이드 지원. 19 unit test (detector parity + 순수 transform + processFile e2e + CLI plumbing). 출력은 별도 폴더로만 쓰고 격리 원본은 절대 수정하지 않음.
  • docs/upgrade-v2.9.0.md (#35) — v2.8.x → v2.9.0 사용자 마이그레이션 가이드. corrupted/ 폴더의 의미, 첫 부팅 시 무엇을 보게 되는지, 복원 스크립트 사용법, 복원 한계, 롤백 절차, FAQ.

Changed

  • README opening 이 LSP-for-terminals substrate 프레이밍 으로 시작 (AI agent 가치 제안과 tmux 대체 키워드는 보존).
  • pane.{set,get,clear}Metadata 핸들러 (M0-b)MetadataStore 로 라우팅. paneSlice 는 더 이상 RPC metadata path 에 의해 mutate 되지 않음.
  • paneSlice 가 mirror-only (M0-d) — 컴파일-타임 write protection 추가. M0-b 가 이미 모든 write path 를 우회시켜 M0-d 는 거의 no-op.
  • pane.list envelope (M0-c)MetadataStore.snapshot() 으로 anchored. snapshot lineage 를 asOfSeq 가 반영.
  • SessionManager (M0-e)metadata.jsonMetadataStore persist callback 으로 atomic write, launch 시 store 를 그 파일에서 hydrate.
  • SCROLLBACK_DUMP IPC 핸들러 가 직접 writeFileSync 대신 atomicWriteTextSync 사용. rotation chain (.bak / .bak.1 / .bak.2 / .bak.3) 활성화. pre-write corruption 시그니처 검출 시 payload 거부 (defense in depth — renderer 가드 회귀 대비).
  • SCROLLBACK_LOAD IPC 핸들러atomicReadTextSync + validate hook 으로 load. chopped 시그니처 매칭 시 primary 를 corrupted/{ts}.bak 으로 격리 후 .bak 체인 fallback 으로 시도. 구조화 CORRUPT_FILE 로그를 stderr 로 emit. 손상 파일이 fresh xterm 에 복원돼서 다음 5초 dump 가 chopped 상태를 다시 디스크에 쓰는 자기증식 루프를 끊음.
  • vitest.config.tsscripts/__tests__/**/*.test.mjs 도 include — 운영 도구 (마이그레이션 스크립트 등) 가 같은 test runner 아래에서 회귀 보호됨.

Fixed

  • replaceShared mergeMode 가 caller 의 custom patch 를 덮어쓰던 결함 (codex full-stack review P2) — patch.custom 을 silently ignore 해 tool-namespace clobber 방지. substrate 의 namespace boundary guarantee.
  • MetadataStore size cap (PANE_METADATA_MAX_BYTES) 이 updatedAt 추가 전에 검증되던 결함 (codex P2) — 최종 저장 shape (updatedAt 포함) 에 대해 검증. boundary 안전.
  • MetadataStore custom entry cap 이 patch 에만 적용되던 결함 (codex P2) — 누적 merge 가 cap 을 우회하지 못하도록 post-merge shape 에 대해 검증.
  • Split-store read-after-write hole (M0-b codex P1) — paneId 없이 write 한 뒤 paneId 있는 read 가 stale 을 반환할 수 있던 구멍. 3 개의 metadata 핸들러 모두 pane.resolveActiveLeaf 로 통일.
  • workspaceId ?? '' 가 기억된 scope 를 덮어쓰던 결함 (M0-b codex P2) — coercion 제거; MetadataStore 의 기존 fallback 이 정상 동작.
  • 스크롤백 손상 자기증식 루프 (P0 layered defense) — hidden / zero-width 컨테이너에 대한 fit()cols 를 ~2 로 collapse 시키면, renderer 의 5초 autosave 가 그 reflowed 버퍼를 캡처해 column-of-chars 로 디스크에 dump. 다음 부팅에 fresh xterm 에 복원되고 또 다시 5초 후에 dump 되며 영구적 손상 루프. 픽스는 네 층: (a) dump-time eligibility 가드 (cols < 12 / rows ≤ 0 / offsetWidth === 0 / detached element), (b) font/theme-change fit() 의 visibility 가드 (마지막 unguarded fit 사이트 닫힘), (c) IPC SCROLLBACK_DUMP 의 시그니처 거부, (d) IPC SCROLLBACK_LOAD 의 시그니처 검출 + 격리 + .bak 회전 체인 fallback. 시각 증상은 "재부팅하면 일부 패널 스크롤백이 비어 보임". 자세한 forensic 은 PR #34 참조.
  • 부팅 직후 일부 패널이 input-mute 였던 결함 (reconcile race)daemon.whenReady()daemon.onConnected 가 첫 연결에 같은 reconcile 을 동시에 trigger, 두 walk 가 같은 session 에 대해 race 하면서 한쪽이 ptyId 를 clear. 사용자 증상: 부팅 후 워크스페이스 전환을 한 번 해야 일부 패널이 살아남. 픽스: reconcileInFlightRef 가 중복 trigger 를 drop, workspace snapshot 을 walk 마다 다시 읽어 동시 spawn 이 frozen view 에 가려지지 않음.
  • pty:resize 가 recovery PTY mute race 를 유발하던 결함 — daemon 이 아직 session 을 publish 하기 전에 renderer 가 보낸 pty:resize 가 "session not found" 로 실패하고 recovery PTY 가 muted 상태로 남던 결함. 50 × 20ms retry budget + 진단 로그 추가.
  • IPC session + scrollback 핸들러가 daemon-connect handler-swap cycle 의 unregister 윈도우에 떨어지던 결함 — cold boot 시 scrollback:load 가 "No handler registered" 로 거부되고 다음 5초 autosave 가 빈 버퍼를 디스크에 덮어쓰던 결함. session + scrollback 핸들러를 swap cycle 밖으로 이동.
  • logSink 의 EPIPE 무한 루프 — stdout 이 닫힌 상태에서 console.error 가 logSink 를 호출하고 logSink 가 다시 console.error 를 호출하던 reentrancy 루프. reentrancy 가드 + orig() try/catch 추가. appendFileSync 사용으로 로그가 디스크에 durable.

Migration Notes

  • 자동 마이그레이션. 사용자 액션 불필요한 부분: substrate wire 변경 (모두 additive optional), MetadataStore 통합 (paneSlice consumer 영향 없음), atomic write + .bak rotation (v2.7.x 부터 이미 다른 파일에 적용된 패턴).
  • v2.8.x 의 chopped 스크롤백: 첫 부팅에서 자동 격리된다. 데이터를 v2.9.0 이 버린 게 아니라 v2.8.x 시점에 이미 chopped 형태로 저장돼 있던 것을 v2.9.0 이 검출만 한 것. 사람이 읽을 수 있는 텍스트로의 회수는 node scripts/recover-scrollback.mjs --verbose 로 가능 (자세한 가이드는 docs/upgrade-v2.9.0.md).
  • corrupted/ 폴더: 30 일 / 폴더당 10 파일까지 자동 정리. 수동 삭제도 안전.
  • pane.metadata.changed event subscriber: optional version 필드가 추가됐다. 무시해도 v2.x 와 동일 동작.

Weekly OSS security release digest.

The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.

No spam, unsubscribe anytime.

Share this release

Track Wmux

Get notified when new releases ship.

Sign up free

Beta — feedback welcome: [email protected]