🪞 신뢰성 기반 — 대규모 안정성 릴리즈
OpenCode의 session.prompt / session.promptAsync API는 fire-and-forget이며 경합 조건을 가지고 있습니다. 프롬프트가 내구적으로 수락되기 전에 해결될 수 있으며, 디스패치가 완료된 것처럼 보인 후에도 늦은 session.error가 도착할 수 있습니다. 이 플러그인의 13개 이상의 내부 훅 호출자(백그라운드 부모 웨이크, 런타임 폴백 재시도, 모델 제안 재시도, 팀 메일박스 라이브 전달, 세션 복구 연속, 할일 연속, Ralph Loop, Atlas 바위, CLI 실행 재개, Claude Code 훅 주입, 동기 및 백그라운드 서브에이전트 프롬프트)과 결합되면, 동일한 단일 사용자 메시지가 완전히 분리된 두 개의 어시스턴트 응답을 생성할 수 있었습니다 — 두 개의 모델 호출, 두 개의 스트림, 두 개의 청구. 사람들이 알아챘습니다. 반복적으로.
OpenCode의 API를 플러그인에서 수정할 수 없습니다. 하지만 플러그인 측에서 이를 해킹할 수 있습니다. v4.2.0이 정확히 그 해킹을 제공합니다:
🚪 prompt-async-gate
src/shared/prompt-async-gate.ts — 플러그인의 모든 raw session.prompt / promptAsync 호출의 유일한 프로덕션 소유자입니다.
sessionID로 키된 예약 맵 — 각 세션별, 각 디스패치 윈도우당 단 하나의 소스만 승리
Promise.race를 통한 30초 디스패치 타임아웃. 정지된 게이트는 더 이상 게이트가 아닙니다
- 250ms 디스패치 후 홀드 — throw 대 resolve 상관없이 "반환하기 전에 내구적으로 수락됨" 위험을 포괄
- TypeScript AST 감사 (
prompt-async-route-audit.test.ts) CI 실패 — 게이트 외부의 raw 프롬프트 API에 접촉하는 새 코드가 있으면 실패합니다. 분해 할당, 괄호 액세스, 선택적 체이닝, 타입-캐스트 별칭 감지
🛡️ messages-transform synthetic-turn 중복 경로 추가
게이트를 스트레스 테스트하는 동안, 우리는 또 다른 중복-응답 경로를 발견했습니다: messages-transform.ts가 메시지 히스토리가 어시스턴트로 끝날 때마다 무조건 synthetic [internal] Continue from the previous assistant state. 사용자 턴을 추가하고 있었습니다. 모델은 이를 "사용자가 말함: 계속"으로 해석했고 추가 응답을 생성했습니다. 이제 metadata.compaction_continue === true에 제한되어 있습니다 — 정당한 포스트-컴팩션 복구에서만 발동하고, 정상 포스트-어시스턴트 흐름에서는 절대 발동하지 않습니다.
OMO/OpenCode가 메시지 후 임의로 중복 스트리밍 응답을 생성하는 것을 봐 왔다면: 이 릴리즈가 수정입니다.
🤖 모든 연속 훅, 감사 및 잠금
게이트가 적용되면 우리는 플러그인이 제공하는 모든 연속 훅을 감시했습니다:
todo-continuation-enforcer — session.compacted가 활성 할일 카운트다운을 중단했으므로, 컴팩션 후 OMO가 에이전트를 깨워 할일을 마치도록 잊었습니다. 수정됨: 카운트다운이 컴팩션을 견디고, 가드는 이제만 시작됩니다
unstable-agent-babysitter — 활성 세션 존중(입력 중 추진 없음), 표시 이름 정규화(더 이상 잘못된 에이전트로의 리마인더 없음)
ralph-loop — 새로운 사용자 프롬프트가 도착할 때 연속 지연, 검증-재시도 소유권 보호로 겹치는 검증이 루프를 모두 주장할 수 없음
background-agent 부모-웨이크 — 신속한 부모 웨이크 경합 병합
atlas 바위 — K=3 진전 없음 턴 후 하드-정지. 차단된 작업은 플랜 파일을 편집해야 함(텍스트 전용 차단자 보고서 거부됨)
🔌 v4.2.0 나머지
- LSP → Tier-1 MCP: Native
src/tools/lsp/ 제거됨. LSP는 이제 벤더된 lsp-tools-mcp 서브모듈로 지원하는 내장 stdio MCP 서버로 제공됩니다. 6개의 모든 기존 lsp_* 도구 이름이 OpenCode의 MCP 네임스페이싱을 통해 보존됩니다. 신규: lsp_status 도구. 게다가 fix(mcp): always register lsp server로 실수로 비활성화되지 않습니다
- 워크스페이스 마이그레이션
.sisyphus/ → .omo/: 플러그인 부트스트랩 시 자동 마이그레이션. 전환 중 레거시 경로는 여전히 인식됨
- 리포 레이아웃 정리:
web/이 packages/web/로 이동. 플랫폼 바이너리 디렉토리가 packages/{platform}/에서 packages/oh-my-opencode-{platform}/로 일관성을 위해 이름 변경됨
- Anthropic GA 1M 컨텍스트 잠금 해제: Claude Opus 4.6/4.7 및 Sonnet 4.6은 이제 캐시 항목이 없을 때 1M 컨텍스트 리미트를 반환합니다. 이전에는 200K에서 정체되어 800K를 테이블 위에 남겨두었습니다
- OpenCode 1.14+ 호환성:
bash로 git 명령을 실행하는 모든 사용자에게 영향을 미친 frozen output.args 충돌 수정. 9개의 OMO 훅 사이트가 새 replaceToolArgs 헬퍼를 사용하도록 리팩토링됨. 감사 테스트 회귀 방지
- 로컬라이즈된 제공자 오류: 중국어(Zhipu/GLM) 및 Volcano Engine 할당량/레이트 제한 패턴이 이제 폴백을 위해 올바르게 분류됨
- 셸 + 플랫폼 호환성: git-master env 접두사의 csh/tcsh
setenv 구문. Windows ComSpec 존중. 설정 마이그레이션은 Windows에서 fsync을 위해 r+ 모드를 사용합니다
- Exa MCP Bearer 인증: SSE 리다이렉트가
?exaApiKey= 쿼리 파라미터를 삭제했습니다. 이제 Authorization: Bearer 헤더를 사용합니다
anthropic-effort 클램프: 사전 설정 effort=max는 더 이상 Opus + GitHub Copilot / Anthropic-OAuth 사용자를 충돌시키지 않습니다
- 50 MB 로그 로테이션:
oh-my-opencode.log → .1 → .2. 더 이상 제한 없는 디스크 성장 없음
config.skills.paths 발견: 호스트 설정의 커스텀 스킬 디렉토리가 이제 OMO의 명령 + 에이전트 로더로 연결됨
🧹 품질 정리
src/ 전체에서 LSP 경고 제로 — 모든 테스트 모의 객체는 이제 실제 타입 fixture를 사용하고, as any / @ts-ignore / as unknown as 이스케이프 해치는 없습니다. 프로덕션 regex 제어 문자 경고 수정됨
submodules: recursive 추가됨 publish-main CI 체크아웃에 벤더된 lsp-tools-mcp가 실제로 CI 러너에서 빌드되도록
📊 릴리즈 통계
- 357+ 커밋 v4.1.2 이후 (272개 비-머지 + 85개 머지 PR)
- 560+ 파일 변경, +23,000 삽입 / −7,900 삭제
- 11명의 커뮤니티 기여자가 이 릴리즈에 28개의 PR 제공 (아래 전체 감사 목록)
- 7,155개 테스트 통과 / 0 실패 v4.2.0 HEAD에서
- 3개의 새로운 정적 가드 회귀 방지: prompt-async-route 감사, mock.module 라이프사이클 감사, merge-conflict 가드
⚠️ 알려진 문제 (v4.2.1로 연기됨)
위임-작업 조기-실패 폴백 — 위임된 자식 세션이 히스토리가 유지되기 전에 매우 첫 promptAsync 호출에서 실패할 때, 설정된 폴백 모델로 진행하지 못할 수 있습니다. 추적 이슈 #4059.
마이너 호환성 및 안정성 릴리즈
이 릴리즈는 호환성 관련 동작 변경 및 운영 강화를 포함합니다. 업그레이드하거나 퍼블리시하기 전에 아래 요약을 읽으십시오.
- 패키지 감지, 플러그인/설정 호환성 및 설치 표면 전반의 이름 변경 전환 업데이트.
- 위임-작업 계약 및 런타임 등록 동작을 포함한 작업 및 도구 동작 업데이트.
- 작업-시스템 기본 동작 정렬로 생략된 설정이 런타임 경로 전반에서 일관되게 동작합니다.
- 설치 및 퍼블리시 워크플로우 강화, 더 안전한 릴리즈 시퀀싱 및 패키지/설치 수정 포함.
커밋 요약
- 881e990 fix(test/session-recovery): replace mock.calls[0][0] with typed accessor
- 9ddf131 fix(test/runtime-fallback): add git_master to config fixture
- 394567a fix(ci): initialize submodules in publish-main checkout
- ae278eb fix(mcp): always register lsp server
- bf96794 chore(web): move site under packages
- 5e9a26c chore(packages): align platform package dirs
- 3e3beef fix(mcp): point CI lsp submodule path at packages
- e906173 fix(ralph-loop): guard verification retry ownership
- 9c19bd8 fix(ralph-loop): defer during fresh user prompts
- cf901d4 chore(workspace): drop stale root plans
- 7187db6 chore(mcp): move lsp submodule under packages
- bcbab05 fix(todo-continuation-enforcer): preserve countdown across compaction
- f898116 test(todo-continuation-enforcer): lock compaction countdown state
- ca3ea0b fix(messages-transform): narrow assistant-tail recovery trigger
- 44ee5e6 test(messages-transform): lock assistant-tail continuation guard
- f20294a fix(unstable-agent-babysitter): normalize reminder agent names
- 0ee45aa fix(unstable-agent-babysitter): respect active sessions
- af1ad4d fix(background-agent): coalesce parent wake races
- c712b71 test(tmux): isolate pane close logic tests
- 3b54d58 Merge pull request #4132 from code-yeongyu/fix/3446-atlas-runaway-loop
- 6dc31b2 fix(atlas): scope no-tool-progress counter to active plan path before stall
- ed5a3f9 Merge pull request #4142 from code-yeongyu/fix/prompt-dispatch-gate
- 428a18c test(prompt-gate): tighten dispatch route regressions
- e1554c0 fix(ralph-loop): preserve prompt dispatch holds through activity
- 66cb72b fix(prompt-gate): bind session messages receiver
- 1a66b96 docs: note Atlas stalled continuation fix
- d3b4c02 fix(atlas): stop stalled boulder continuations
- fff99ae fix(atlas): track no-tool-progress state
- 0994c10 fix(atlas): require blocked plan checkbox edits
- d44cd1c fix(background-agent): preserve parent agent on retry wakes
- 3b50b7c Merge pull request #4143 from code-yeongyu/fix/shell-env-csh-support
- 82b0672 fix(git-master): emit csh-compatible setenv syntax for csh/tcsh shells
- b296140 test(shell-env): add csh/tcsh detection and buildEnvPrefix coverage
- bc2ed01 Merge pull request #4141 from code-yeongyu/fix/3396-config-skills-paths-discovery
- b0f432d Merge pull request #4136 from code-yeongyu/fix/4059-blocker4-reland
- c8c06d6 Merge pull request #4020 from scw1109/fix/default-agent-sort-order
- c37725b Merge pull request #4139 from code-yeongyu/fix/3450-anthropic-context-limit-revisited
- ecb8760 fix: wire host config.skills.paths into command skill discovery
- 971be27 docs(known-issues): mark blocker-4 resolved
- d5b1d36 docs(changelog): add 4.2.1 blocker-4 entry
- 1412795 fix: wire host config.skills.paths into agent skill discovery
- 043e84b fix: add adaptHostSkillConfig utility for host config.skills.paths
- f5e063b fix: only call setDefaultAgentForSort when user explicitly sets default_agent
- f17623d test(shared): isolate logge
(이하 생략)