2026-09-22
한국 시간(KST) 기준으로 하루를 나눴습니다. 커밋은 커미터 시각(committer date), PR은 생성·병합 시각으로 분류했습니다. 조회: 2026-10-06 KST. 공개 저장소에서 조회한 활동만 포함합니다. 9월 22일부터 KST 기준으로 바꿨습니다. 9월 21일까지의 기록은 UTC 날짜로 나눴으므로, 이날은 겹치지 않도록 09:00 KST 이후 활동만 담았습니다.
요약 (AI 작성)
이날은 KST 기준으로 바꾼 첫날이라 09:00 KST 이후 활동만 담았습니다.
maru 편집기는 SSH 세션에서 어디에 저장할지 묻고 원격 쪽 파일에 저장하는 경로를 얻었고(#3853), 저장 충돌 확인 상자에 선택지와 네이티브 다시 읽기(#3847), 비교(#3848)를 더했습니다. 미저장 편집은 백업으로 남아 크래시 뒤에도 살아남고 저장이나 수락된 닫기에서 지워지며(#3858), 크래시가 삼킨 편집을 되살리는 후속 PR #3866도 이날 열렸습니다. LSP 쪽은 구현·타입 정의·선언으로 이동하는 팔레트 명령(#3846)과 인레이 힌트(#3859)가 들어왔고, 힌트가 구문 색과 줄바꿈 경계의 열 위치를 어긋나게 하던 결함도 함께 고쳤습니다. 에이전트 탭의 턴 목록은 디스크에 저장되어 앱을 다시 켜도 남습니다(#3852).
maru 터미널 코어는 DECSET 2031 / DSR 996 색 구성 통지를 구현해, 테마 전환이 이를 구독한 앱에 전달되도록 했습니다(#3857). session-host는 출력 revision을 metadata 이벤트에서 빼서 불필요한 메타데이터 갱신을 없앴고(커밋이 밝힌 수치는 활성 32세션 조건에서 앱 CPU −35%), idle로 내려간 host 뒤에 새 Term이 in-process로 조용히 열리던 문제를 고쳤으며, 재접속 비용 측정과 oversized 세션의 형제 격리 테스트를 더했습니다. 이 밖에 밀린 pane을 고지 행으로 남기는 에이전트 훅 개선, 리소스 팝오버 합계 수정, 빌드 판정 61자리를 문자열에서 구조 판정으로 옮기면서 모듈 주입을 못 읽던 결함을 고친 작업(#3849), 상태바·마커 프리뷰·원격 에이전트를 그룹 파일로 떼어낸 app-runtime 리팩터링, 판정자 이름 정리가 이어졌습니다.
@ohah/pdf는 실문서 100편을 pymupdf·pdf.js·mupdf 결과와 맞대어 잡은 글자 추출·글꼴·그림 결함을 고치고 v0.2.1과 v0.2.2를 배포했습니다. v0.2.2에는 퍼저가 찾은 예측기의 범위 밖 읽기와 큰 QuadPoints에서 끝없이 돌던 문제의 수정도 들어갔습니다. hwpjs는 EMF의 Path·이미지·폴리라인·베지어·사각형 좌표를 장치 공간으로 옮기고, 아핀 타원과 호의 기하, 원뿔 곡선 구간, 파이 경계, 3차 베지어의 평가와 분할을 추가했습니다.
zntc는 async generator 함수와 메서드, 클래스 메서드의 다운레벨 변환, yield* 위임의 반환값, 상태 기계 루프의 반복별 let 바인딩, 본문이 다른 함수로 옮겨질 때의 arguments 캡처, es5 generator 안 for-of와 for-await 처리, public class field 변환을 고쳤고, minify 때 헬퍼에 축약명을 적용했습니다. 블로그 저장소에서는 9월 14일 이후 기록과 개발기를 보충하고 의존성 갱신, 미사용 eslint 제거, Node 26 고정, dist 추적 해제를 했습니다.
공개 커밋 107개, 해당일 생성 또는 병합된 PR 37개를 정리했습니다. PR 생성 32개·병합 35개는 같은 PR이 양쪽에 포함될 수 있습니다.
커밋
ohah/hwpjs
- feat(emf): subdivide cubic bezier segments
- feat(emf): evaluate cubic bezier segments
- feat(emf): build exact ellipse conic segments
- docs(emf): align arc evaluation coverage
- feat(emf): evaluate arc conic segments
- feat(emf): assemble pie device boundaries
- feat(emf): build exact arc conic segments
- feat(emf): evaluate arc endpoints in device space
- feat(emf): build affine arc device geometry
- feat(emf): build affine ellipse device geometry
- feat(emf): connect rectangle records to device space
- feat(emf): map rectangle corners to device space
- feat(emf): map image rectangles to device space
- feat(emf): map image source points to device space
- feat(emf): map Path segments to device space
- feat(emf): map cardinal spans to device space
- feat(emf): map Bezier segments to device space
- feat(emf): map polyline segments to device space
- feat(emf): map world points to device space
- feat(emf): map image source rectangles
- feat(emf): assemble image parallelograms
- feat(emf): assemble Path fill boundaries
ohah/maru
- refactor(naming): 센티넬 일곱을 주제 이름으로 — 원장이 99 에서 92 로
- fix(session-host): 크기 pin 은 «사본 둘 + 판정자» 가 한 묶음이다 — 셋을 함께 올린다
- fix(session-host): U4a 가 키운 RemoteRuntime 크기 pin 을 다시 잰다 (main 빨강 수정)
- fix(editor): 인레이 힌트가 선 줄의 «색»이 힌트 폭만큼 밀려 있었다 — syntax_colors 도 같은 열 규칙을 지난다(1층·2층 공통); 열 선택 클릭도 힌트를 안다; 가짜 서버는 부른 문서에만 힌트를 낸다 (§4.1h·§8.2n)
- docs(editor): §8.2n 관측점·적대적 기록(변이 54 · 결함 하나 · 등가 셋)
- fix(editor): 변이 러너가 도는 동안의 편집으로 새어 들어온 A10 변이(주석 처리된 폭 누적)를 되돌린다
- test(editor): INL2 힌트 줄 seek 무시 · INL10 행 수 캐시가 힌트 세대로 다시 선다 (적대적 A8·D3)
- test(editor): INL9 — 줄 예산(렌더·hit·L3)·줄 끝 힌트 열·그려진 caret 막대 열·호버 앵커 열 (적대적 C7·C8·C14·C15·D7·D10)
- test(editor): INL13(창 밖 스크롤 되묻기)·INL11 ⑷(refresh 뒤 오류에도 dirty)·INL12 회귀 변이, 등가 변이 주석(A5·A8/A9·A10)
- fix(editor): 랩 경계에 걸친 인레이 힌트 — 행 시작 걸음이 머물 때 힌트 첨자도 되돌린다(다음 행이 힌트 폭만큼 앞 byte 에서 시작하던 결함, INL12); §8.2a·§8.2n·§4.1h 되먹임
- test(editor): INL9 줄 끝 힌트·설정 블롭 0·L3 폭 상한, LSPB9 설정 블롭 1, 가짜 서버 범위 끝 -32603(rust-analyzer 꼴)
- feat(editor): LSP 2단 ⑬ — 인레이 힌트: 줄 워커 하나로 가상 텍스트를 끼운다(열 규칙 확장, 레이어 없음); rust-analyzer 의 refresh 를 받고, tsgo 를 죽이던
initializedparams\[\]를 고친다 (§4.1h·§8.2n) - refactor(naming): release adapter P5d 판정자 넷을 주제 이름으로 — 원장이 103 에서 99 로
- fix(session-host): 재시작이 성공하면 방금 건 «연결 실패» notice 를 내린다 (적대적 3회차)
- fix(session-host): host 가 idle 로 내려간 뒤 새 Term 이 in-process 로 조용히 열린다 — 죽은 spawn host 를 치우고 한 번 다시 붙는다
- fix(debug-fixtures): MARU_FORCE_SYS_APPEARANCE_LATER 의 시간 기준 — awakeMs 는 부팅 기준이라 «나중에» 가 «즉시» 였다
- feat(editor): 미저장 편집이 크래시를 넘어 살아남는다 — 백업이 남고, 저장·수락된 닫기에 사라진다 (U4a)
- refactor(naming): kernel cwd 판정자 셋을 주제 이름으로 — 원장이 106 에서 103 으로
- build(wasm): 코어 변경(2031)에 맞춰 커밋된 maru-vt.wasm 재생성 (check-wasm-sync)
- style(terminal-core): zig fmt — 빈 줄 하나 (fmt-check)
- test(boundary): build-graph 판정자의 고정 수 — test-color-scheme-notify step 만큼 +1
- feat(terminal-core): 색 구성 통지 DECSET 2031 / DSR 996 — 라이브 테마 전환이 구독한 앱(Claude Code)에 CSI ? 997 ; n 으로 닿는다
- docs(app-session): 「pub 순증」 열은 행마다 정의가 다르다 — F16 을 검산해 비교 기준을 못 박는다
- fix(app-runtime): F18 이 MP1 판정자에 낸 구멍을 메우고, pub 순증을 39 → 74 로 정정한다
- refactor(app-runtime): F17~F19 — 상태바·마커 프리뷰·원격 에이전트를 그룹 파일로
- refactor(app-runtime): 제품 타입이 들고 있던 test 픽스처 아홉을 파일 스코프로 — pub 순증 0
- fix(editor): 왕복 중 두 번째 저장이 첫 요청의 보류를 지웠다 + 판정자 셋 (U3 적대적 6~10회차)
- test(editor): 적대적 다섯 회차 — 헬퍼가 한 번도 안 돌았고, 저쪽 파일의 탭은 «편집기»였다 (U3)
- feat(editor): SSH 세션에서 «어디에» 쓸지 묻고, 저쪽에 저장한다 (U3)
- docs(editor): 저쪽에 저장한 뒤 그 문서는 «저쪽의 그 파일»이다 (U3 사용자 결정)
- docs(editor): U3 의 «저쪽»은 전송이 아니라 «종류»가 없다 — 판 15 로 올린다 (U3 적대적 1회차)
- test(session-host): 재접속 비용과 oversized 형제 격리를 실측한다
- test(agent-turn): AT7 적대적 4~6회 — 경로 인용·id 불일치·NotDir·dedup·꽉 찬 맵 판정자, 판정자 이중 해제 수정, Store 를 힙에
- fix(agent-turn): AT7 — 캐시 base 가 상대경로면 영속을 끈다 (openDirAbsolute 의 assert 로 keep-alive 스모크가 abort)
- feat(agent-turn): AT7 조각 3 — 턴 링 영속화 배선: 봉인 뒤 쓰기·첫 턴 전 되살리기·tree 존재 확인·workspace.v1 의 최근 세션·7일 sweep
- feat(agent-turn): AT7 조각 1·2 — 턴 링·봉인 턴의 디스크 모양(turn_persist, 순수)과 저장소(turn_store — 0700/0600·임시→rename·blob 도달성 sweep·7일)
- docs(agent-turn): AT7 턴 목록 영속화 — 계약 §6 재작성(ref 고정 폐기 → 캐시 파일·검증·7일)과 계획 재실측·착수 전 공격
- perf(session-host): 출력 revision 을 metadata 이벤트에서 뺀다 — 활성 32 세션 앱 CPU −35 %
- refactor(naming): reconnect worker 판정자 둘을 주제 이름으로 — 원장이 108 에서 106 으로
- test(naming): 판정자 이름의 작업 슬라이스 ID 를 원장으로 못 박아 «줄어들기만» 하게 한다
- test(chrome): 네 버튼의 «폭»을 재고 굳힌다 — 불변이라 적었지만 재지 않았다 (C1b 자기 감사)
- test(editor): 적대적 다섯 회차 — 비교가 낡는 두 자리와 네 번째 버튼의 판정자 (C1b)
- feat(editor): 저장 충돌에 «비교»를 더한다 — 확인 상자의 네 번째 자리 (C1b)
- docs(editor): 비교의 자리 — 새로 고치는 곳은 하나, 버퍼 주인은 경로가 아니다 (C1b 적대적 1회차)
- test(editor): 구현·타입 정의·선언 적대적 6~12회차 — 새 변이 28, 판정자 보강 여섯(미지원 문구·구현 되묻기·요청 실패 문구·종류별 provider(REF4)·i18n 두 언어 표·타입 정의 프롬프트), 등가 셋 기록 (§8.2m)
- feat(editor): LSP 2단 ⑫ — 구현·타입 정의·선언으로: 팔레트 명령 셋이 참조 피커와 같은 길로 온다(0 알림·1 이동·2+ 피커, 종류별 프롬프트·문구); provider 가 없는 종류는 묻지 않고 알린다(tsgo 는 declaration 을 물으면 -32600); id 칸 13~15e8 (§8.2m)
- refactor(build): 환경변수 5 자리도 구조 판정으로 — 「뜻이 다를 것 같다」가 짐작이었다
- refactor(build): 매달기 13 · 실행 인자 8 · 필터 4 자리를 구조 판정으로 옮긴다
- refactor(build): 뷰를 상대 경로로 열고 「이 스텝이 있는가」 31 자리를 구조 판정으로 옮긴다
- fix(status-bar): 리소스 팝오버의 합이 안 맞던 것 — 자르는 자리가 정렬보다 앞이었다
- refactor(build): tests/boundary/ 판정자 스무 개를 표로 — 등록과 「매달기」가 3천 줄 떨어져 있었다
- fix(build): 뷰가 «모듈 주입» 을 못 보고 있었다 — 등록 468건 중 1건만 그렇게 읽혔다
- test(agent-hooks): RA7 조각 5 적대적 3회 — 그려지는 글자·꽉 찬 경계·원격 Term 둘 판정자, 픽스처 정수 오버플로 수정
- feat(agent-hooks): RA7 조각 5 — 밀린 pane 은 «+N pane 밀림» 고지 행으로 남고, pane 행 문구가 기본 폭에 온전히 들어간다
- test(editor): 적대적 다섯 회차 — 판정자 넷을 세우고 하네스 결함 하나를 고친다 (C1a)
- feat(editor): 저장 충돌을 «고르게» 한다 + 네이티브 다시 읽기를 만든다 (C1a)
- docs(editor): 저장 충돌의 선택 — 셋을 담으려면 «네 번째 자리»가 필요하다 (C1 적대적 1회차)
ohah/ohah.github.io
- chore: git 이 추적하던 dist/ 652개 파일 추적 해제
- chore(deps): lodash·lodash-es 와 mermaid 우회 alias 제거
- chore: 미사용 eslint 제거 + 프로젝트 Node 26 고정(mise.toml)
- docs: pdf·hwpjs 개발기 태그·날짜를 9/21로
- chore(deps): 의존성 최신 버전으로 일괄 갱신
- docs: 9/14~9/21 최신화 — today-commit 8일·타임라인·maru 3-7·hwpjs/pdf/zts 후속
ohah/pdf
- chore: 0.2.2 — 실문서 100편 그리기 맞대기에서 잡은 결함 열여섯, 퍼저가 찾은 둘
- fix: 퍼저가 찾은 둘 — 예측기 /Colors 4294967295 로 밖을 읽고, 구불선 QuadPoints 가 크면 끝없이 돌았다
- docs: README 에 실문서 100편 맞대기 결과 한 줄
- fix: 실문서 100편 그리기 맞대기에서 잡은 결함 열여섯 — 우리↔mupdf 7.43%→3.12%
- fix: 실문서 100편 그리기 맞대기에서 잡은 글꼴·그림 결함들
- chore: 0.2.1 — 실문서 100편에서 잡은 글자 뽑기 결함 아홉
- fix: 실문서 100편에서 pymupdf·pdf.js 와 맞대 잡은 글자 뽑기 결함 아홉
ohah/zntc
- fix(transformer): #4716 상태 기계 루프의 반복별 let 바인딩을 복원한다
- fix(transformer): #4709 es5 generator 안 for-of 를 iterator 프로토콜로 돌린다
- fix(transformer): #4703 es5 state machine 의 catch 좌변을 참조 노드로 만든다
- fix(transformer): #4707 es5 async generator 안 for-await 의 await 을 __await 로 표시한다
- fix(transformer): #4705 async generator 의 yield/return 재개 의미론을 스펙에 맞춘다
- fix(transformer): #4700 yield* 위임의 .return(v) 완료값을 보존한다
- fix(transformer): #4699 본문이 다른 함수로 옮겨질 때 arguments 를 캡처한다
- fix(transformer): #4699 클래스 메서드의 async/generator 를 타겟에 맞춰 낮춘다
- perf(bundler): minify 시 __publicField / __asyncDelegator 축약명 적용
- fix(transformer): #4628 async generator 메서드 다운레벨 (최상위 함수만 덮던 수정 보완)
- fix(bundler): #4630 es5 타겟에서 interop 산출물의 ES6 문법 제거
- fix(transformer): #4629 public class field 를 자기 비트로 낮춘다 (es2015~es2021)
- fix(transformer): #4628 async generator 를 자기 비트로 게이트 + yield* 위임 수정
- test(compat): addon 탐색에 CI 복사본 경로 폴백 추가
- refactor(compat): UnsupportedFeatures 비트 폭을 u64 로 넓히고 폭을 단일 진실원으로
PR (해당일 생성/머지)
상태는 조회 시점 기준입니다. merged는 아래 대상 브랜치에 병합됐다는 뜻이며, 기능 브랜치 병합과 main 반영을 구분합니다. 같은 PR이 생성일과 병합일 양쪽 기록에 나타날 수 있습니다.