@oh-my-pi/pi-agent-core/compaction의 createFileOps, computeFileLists, formatFileOperations, upsertFileOperations, isUrlSchemePath, FileOperations가 deprecated 처리되었습니다. 이제 이들은 @oh-my-pi/snapcompact를 re-export하며, 호출하는 쪽에서는 이를 직접 import해야 합니다.estimateTokens export)가 1토큰당 4바이트로 추측하는 대신 o200k_base로 텍스트를 계산하도록 변경되었습니다. 기존에는 코드가 많은 세션에서 해당 프로바이더의 과금 대비 11–48% 과소 집계되었고, 이런 프로바이더로 전환한 후 컴팩션이 늦게 발동하는 문제가 있었습니다 (#17607 by @will-bogusz)PI_TOKENIZER_ACCURATE를 제거했습니다. 이제 모든 모델을 네이티브 토크나이저로 계산합니다 (#17607 by @will-bogusz)/login mistral이 Mistral Vibe CLI처럼 브라우저를 통해 로그인하고, 발급된 API 키를 저장합니다. 이 키의 사용량은 종량제 API 크레딧이 아닌 요금제의 Vibe Code 쿼터에서 차감됩니다. MISTRAL_API_KEY도 계속 동작합니다 (#13875 by @Gauthier-Huguenin, #17672 by @abilliontokens에서 이어서 작업)dropsForeignReasoningPayload(turn, model)를 추가했습니다. 이 함수는 transformMessages가 턴의 thinking 서명과 redacted thinking을 model로 전송하는 과정에서 확실히 제거하는지 알려줍니다. 또한 Factory Droid의 Gemini 와이어용으로 isFactoryDroidGeminiWire(model)와 keepsFactoryGeminiReasoning(turn)을 추가했습니다 (#17607 by @will-bogusz)formatError와 providers/aws-sigv4의 asStrict가 deprecated 처리되었습니다. formatError는 이제 auth-gateway/http의 codedErrorResponse / noStoreErrorResponse의 alias이며, asStrict는 @oh-my-pi/pi-utils의 asStrictBytes로 대체되었습니다/login mistral에서 MISTRAL_API_KEY 옆에 Mistral Vibe 브라우저 로그인 옵션이 표시됩니다 (#13875 by @Gauthier-Huguenin, #17672 by @abilliontokens에서 이어서 작업)compat/revision에 revisionAtLeast를 추가하고, discovery/openai-compatible에서 withOpenAICompatibleDiscoveryTimeout을 export했습니다cl100k 토크나이저를 사용하도록 변경되어, 토크나이저가 없는 모델의 기본값인 o200k_base 대신 cl100k_base로 컨텍스트 추정이 계산됩니다 (#17607 by @will-bogusz)retain과 learn이 scope: "global"로 메모리를 저장할 수 있게 되어, 모든 프로젝트에서 이를 불러올 수 있습니다. 새 hindsight.globalScope 설정으로 옵트인하며(기본값 off), global 또는 per-project-tagged 스코프가 필요합니다 (#17706 by @alphastorm, #15030에서 가져옴 by @kithawk).btw.inject를 추가했습니다(기본값 off, /settings → Interaction → "/btw Steering Inject"). /btw에 steering 프롬프트를 요청하면 분홍색 레일 뒤에 표시되는 <inject> 블록으로 초안이 작성됩니다. Alt+I(app.btw.inject)를 누르면 인라인 답변 또는 BTW 기록 시트에서 메인 세션으로 보내며(에이전트 실행 중이면 steer로, 아니면 새 턴으로), 현재 실행의 각 답변마다 한 번만 전송됩니다. 전송되면 블록이 초록색으로 바뀌고 각 줄에 ➤가 표시되며, 아래에 "Injected into main session"이 나타납니다. 메인 세션이 연결이 끊기거나 전송을 거부하면 블록이 다시 대기 상태로 돌아가고, 같은 키로 재시도할 수 있습니다 (#17618 by @apullin)OTEL_EXPORTER_OTLP_METRICS_ENDPOINT)가 설정되어 있으면, 컴포저 예측이 서비스 모델별로 내용 없는 omp.composer.prediction.* 메트릭을 내보냅니다. 결과별 요청 수(offered, skipped, stale, cancelled, timeout, error)와 소요 시간, 표시된 예측 수(실제로 화면에 그려지는 첫 프레임 기준), Tab 또는 Right로 수락되었는지에 따른 표시된 예측 수, 처음 표시부터 수락까지의 시간을 포함합니다 (#17739 by @wolfiesch)Minimized: git 120.4KB → 3.2KB) (#16586 by @will-bogusz)attempts를 노출합니다(JS await handle.attempts(), Python handle.attempts). 시도된 각 fallback 후보를 순서대로 모델, 전송된 reasoning effort, 결과, 실패 시 오류와 함께 보여줍니다 (#17782 by @xiangnan0811)composer.predictionAlternatives를 추가했습니다(기본값 off, /settings → Interaction → "Prediction Alternatives", Composer Predictions가 켜져 있을 때 표시). 동일한 단일 예측 요청으로 가장 가능성이 높은 순서대로 최대 4개의 서로 다른 다음 메시지를 반환합니다. 몇 글자를 입력하면 일치하는 첫 번째 항목의 고스트 텍스트가 나타나며, 하나를 삽입한 뒤 Tab을 다시 누르면 목록에서 다른 항목을 고를 수 있습니다. 예측 메트릭에는 제공된 대안 수(omp.composer.prediction.choices)가 포함되며, 수락된 예측은 소멸될 때 확정되고 마지막에 삽입된 대안의 순위(omp.composer.prediction.rank)를 기록합니다 (#17796 by @wolfiesch)/review와 /annotate code-review가 체크아웃 폴더에서 동작합니다. /review owner/repo#123은 어디에서든 GitHub PR을 리뷰합니다. /review ./repo [#123 | !7] [focus]는 해당 체크아웃에서 리뷰합니다(#N은 GitHub PR, !N은 GitLab MR). 저장소 밖에서는 로컬 및 열린 PR 메뉴 항목이 사용할 하위 저장소를 묻습니다/resume과 omp --resume이 ~/.omp/agent/history.db에서 읽은 제목이 있는 세션을 즉시 엽니다. 이후 전체 스캔이 끝나면 프롬프트, 상태, 제목 없는 세션을 채웁니다. 첫 스캔은 이전 세션의 제목도 함께 저장하므로, 다음 열기부터 바로 목록에 표시됩니다symbolPreset: ascii에서 상태 글리프는 3열 너비입니다([+], [-], [#], [ ]). 상태 스피너는 [|] [/] [-] [\]로 애니메이션됩니다 (#17732 by @JustasMasiulis)browser.close({ all: true })를 호출해도 부모의 탭이 닫히지 않습니다. 호출한 에이전트의 탭만 해제합니다. 탭은 이제 대화 ID가 아니라 탭을 연 에이전트에 속하므로, /new, /resume, fork, branch 이후에도 고정(frozen), 유휴 종료, close-all 해제가 적용되고, 세션이 끝나면 닫혀서 누수되지 않습니다 (#15975, #16133 by @harshaygadekar)lsp request가 payload: "null"을 자동 생성된 문서 파라미터로 대체하지 않고 JSON null로 전송합니다 (#17715)../c를 누르면 재개할 내용이 없다고 알려줍니다 (#17828).upstream 리모트가 origin의 fork 부모가 아닌 체크아웃에서 pr://<n>, issue://<n>, 저장소 없는 github 도구 호출이 upstream 프로젝트 대신 origin으로 해석됩니다. gh repo set-default는 여전히 우선합니다omp -p 텍스트 모드가 자동 재시도마다 오류와 함께 출력합니다(예: "Couldn't reach api.anthropic.com … check your network"). 턴이 재시도되는 동안 Working...만 보여주던 문제를 수정했습니다 (#17529 by @Mannan-Goyal)omp --export와 /export가 Error: Out of memory로 실패하지 않으며, 메모리를 훨씬 적게 사용합니다. HTML을 하나의 문자열로 만드는 대신 디스크에 스트리밍합니다 (#17741)async.enabled가 켜진(기본값) 상태에서 네이티브 security_scan이 백그라운드 security-reviewer 워커를 기다리고 그 결과를 게시합니다. 이전에는 0개의 결과와 "The scan session ended without publishing a canonical result"와 함께 partial로 끝났습니다 (#17788)tab.waitForSelector, tab.evaluate, tab.goto가 20초 후 실패하지 않습니다. 실행된 Chrome과 마찬가지로 호출 자체의 timeout까지 실행되며, omp의 60초 프로토콜 timeout까지 허용됩니다. Chrome이 응답하지 않는 명령은 자신과 탭의 이름을 표시합니다 (#17778 by @will-bogusz)tab.click(selector, { button, count })와 frame.click이 옵션을 무시하고 왼쪽 클릭을 한 번만 수행하던 문제를 수정했습니다. 그래서 컨텍스트 메뉴를 열려던 우클릭이 요소를 왼쪽 클릭하고 있었습니다. cmux 탭은 누를 수 없는 버튼이나 횟수를 거부합니다 (#17767 by @will-bogusz)fill이 바쁜 머신에서 새 텍스트를 Slate 편집기의 기존 텍스트 앞에 넣는 문제가 없어졌습니다. 포커스가 래퍼나 페이지로 옮겨가는 rich-text 편집기는 성공으로 보고하지 않고 거부합니다 (#17742 by @will-bogusz)Target closed로 실패하던 문제를 수정했습니다. 이제 Chrome이 omp를 분리했다는 것과 탭이 재연결되었는지를 페이지 자체에서 발생한 호출과 같이 알려줍니다 (#17768 by @will-bogusz)persist: true로 연 탭은 세션이 끝나도(omp -p 실행 종료, subagent 완료) 열린 상태로 남습니다. 그래서 사용자를 위해 남겨 둔 페이지가 그대로 있습니다. omp가 연 다른 탭은 여전히 닫히며, 세션 정리와 경합하는 명시적 close는 여전히 해당 페이지를 닫습니다 (#17751 by @will-bogusz)xd:// 디바이스 마운트를 유지하므로, 이전의 Claude thinking을 잃지 않습니다 (#17746 by @will-bogusz)%pip를 취소해도 설치 프로세스가 Linux 컨테이너와 사용 가능한 /proc이 없는 chroot에 남던 문제를 수정했습니다 (#16552 by @will-bogusz)read 페이지를 수정했습니다. tools.outputMaxColumns에서 잘린 줄은 전체 길이가 아니라 표시된 너비를 페이지 크기에 계산하므로, 페이징이 그런 줄 앞에서 멈추거나 그 줄을 넘어가지 못하는 문제가 없어졌습니다. 첫 번째로 잘린 줄이 :raw read가 반환하는 크기보다 크면, 잘림 안내가 그 바이트 상한을 명시합니다. 페이지 크기 때문에 범위 중간에서 멈춘 multi-range read는 어디서 계속할지 알려줍니다 (#16595 by @will-bogusz)write가 긴 줄이 tools.outputMaxColumns에서 잘린 read의 출력을 받아들여 잘린 줄로 파일을 덮어쓰던 문제를 수정했습니다. 이제 다른 잘린 read와 마찬가지로 불완전한 read로 보고 거부합니다 (#16595 by @will-bogusz)models.yml이 커스텀 모델이나 override에서 tokenizer: cl100k를 허용합니다 (#17607 by @will-bogusz)read, bash 도구, extension, eval이 omp가 열어 둔 ~/.omp/agent/agent.db를 읽을 때 파일이 손상되어(저장된 로그인이 지워짐) 발생하던 문제를 수정했습니다. write와 tts는 omp가 열어 둔 데이터베이스를 덮어쓰지 않도록 거부합니다 (#15586)macOSFrontApp()을 추가했습니다. 이 함수는 macOS가 현재 전면에 둔 앱을 읽고, 사용자의 입력을 기다리지 않고 keepInFront 옵션으로 잠시 다시 전면에 둘 수 있습니다 (#16284 by @will-bogusz)parseKey/matchesKey가 Ghostty 등 kitty 프로토콜 터미널이 수정자 없는 F1/F2/F4에 보내는 파라미터 없는 CSI P/CSI Q/CSI S(및 CSI 1 <letter>) 형식을 인식합니다. 수정자가 붙은 F2–F9가 다른 키(예: Ctrl+PageDown을 Ctrl+F8로)와 더 이상 일치하지 않습니다 (#17812).installSqliteLockShim()(Linux)을 추가했습니다. 이 함수는 Bun의 SQLite 레코드 잠금을 파일의 다른 close가 해제할 수 없는 open-file-description 잠금으로 옮깁니다. heldFileKind(path)도 추가했는데, 이는 이 프로세스가 열고 잠근 파일을 보고합니다. 둘 다 @oh-my-pi/pi-natives/sqlite-locks에도 있으며, 첫 호출 시 addon을 로드합니다 (#15586)archiveIncludesThinking()을 추가했습니다. 컴팩션이 요약의 legend 또는 아카이브 텍스트에서 reasoning을 재생할 수 있는지 알려줍니다. viewSummary()도 추가했습니다. 이 함수는 템플릿이 작성하지 않은 요약을 고유의 문장대로 유지하고, 그 뒤에 뷰 텍스트에 대한 템플릿 안내를 덧붙입니다 (#17745 by @will-bogusz)¶think: 범위를 선언하지 않을 때, viewWithoutFrames와 viewWithoutThinking이 reasoning을 제외하는 읽는 쪽에 아카이브의 reasoning을 남기고 그런 요약을 템플릿의 요약으로 바꾸던 문제를 수정했습니다 (#17745 by @will-bogusz)buildExecutionFrame은 로더를 새 bottomBorder에 직접 설정하므로, 호출자는 더 이상 이를 행으로 추가하지 않고 직접 dispose해야 합니다. buildStatusFooter는 더 이상 status나 exitCode를 받지 않으며, executionStatusLabel은 완료된 실행의 exit N / cancelled 표시를 해당 border에 반환합니다 (#17732 by @JustasMasiulis)SessionSelectorOptions.loadAllSessions와 SessionPickerHost.loadAllSessions는 SessionListing으로 resolve되며, allSessions는 이를 받습니다. 그래서 모든 프로젝트 범위에서 전체 목록 전에 예비 행을 표시할 수 있습니다Editor.prediction이 Editor.predictions로 대체되었습니다. 이는 다음 프롬프트에 대한 모든 예측을 가장 가능성 높은 순서대로 반환하며, Editor.onPredictionAccepted는 삽입된 예측의 목록 내 인덱스를 받습니다 (#17796 by @wolfiesch)SessionSelectorOptions.completeSessions(및 SessionPickerOptions.completeSessions)는 picker의 예비 행을 전체 목록이 완료되면 교체하며, 그 사이의 검색어, 선택된 세션, 삭제/이름 변경 내용을 유지합니다/btw 답변은 steering 프롬프트를 분홍색 레일 뒤의 블록으로 표시할 수 있습니다(Tern에서는 톤이 적용된 카드). Alt+I(app.btw.inject, 재매핑 가능)로 메인 세션에 보내며, 전송되면 위치를 옮기지 않고 각 줄에 ➤가 붙은 초록색으로 바뀝니다 (#17618 by @apullin)utils에 singleLine과 finiteWidth를 추가했습니다Loader.inlineText()는 현재 스피너 프레임과 메시지를 하나의 스타일 적용된 줄로 반환합니다. DynamicBorder.setLabel()은 rule에 라벨(또는 렌더마다 다시 읽는 함수)을 설정합니다 (#17732 by @JustasMasiulis)[+], 오류는 [-], 중단은 [#], 대기는 [ ]이며(실행 중 [~], 경고 [!], 정보 [i]와 함께), 상태 스피너는 [|] [/] [-] [\]로 애니메이션됩니다 (#17732 by @JustasMasiulis)status.done, theme.status.done, ToolUIStatus의 done 값을 사용하지 않습니다. 이들은 status.success / success의 alias로 남아 있습니다(명시적인 symbols.overrides["status.done"]은 여전히 theme.status.done에 적용됩니다) (#17732 by @JustasMasiulis)✔, ASCII [+])를 표시합니다. Task 행, 판정, 헤더, 백그라운드 작업, launch 및 supervised-process 행, Eval 셀, Vibe, Wait, process 작업 행, Yield, 일반 도구 카드는 별도의 • 완료 점을 표시했고, 완료된 Read는 ●(ASCII [x])를 표시했습니다. 실행 중인 Task agent 행은 대기 또는 실행 글리프를 표시하며, 병합이 실패한 Task는 경고 글리프를 표시합니다 (#17732 by @JustasMasiulis)preview / streaming 라벨을 콘텐츠 아래 행 대신 카드의 하단 border에 표시합니다. streaming은 콘텐츠가 완전히 도착하면 끝납니다 (#17732 by @JustasMasiulis)! 셸과 $ Python 실행은 스피너를 표시한 뒤, 자체 행 대신 프레임의 하단 border에 exit N 또는 cancelled를 표시합니다. 스피너는 도구 헤더가 사용하는 상태 스피너입니다 (#17732 by @JustasMasiulis)request 응답)에 오류 글리프(✘, ASCII [-])가 포함되어 있으면, "No issues"라는 진단으로 표시되고 나머지 줄이 버려지던 문제 대신 응답으로 표시됩니다 (#17732 by @JustasMasiulis)Editor.onPredictionAccepted와 Editor.onPredictionShown이 Tab 또는 Right로 컴포저 예측의 나머지 부분이 삽입될 때와, 프레임이 이를 그릴 때(터미널에서 최소 한 셀, 또는 네이티브 editor 노드의 고스트) 보고합니다 (#17739 by @wolfiesch)OutputMeta.minimized를 추가했습니다(bash minimizer 필터, 원본 및 축소된 바이트 수, 원본 출력 artifact). bash 결과 카드에 Minimized 항목으로 표시됩니다 (#16586 by @will-bogusz)tools/output-meta에 isColumnTruncationNotice와 hasColumnTruncationClause를 추가했습니다. 이는 formatOutputNotice가 단독으로 또는 더 긴 안내 안에서 출력하는 [Some lines truncated to …] 절과 일치합니다. LimitsMeta.columnTruncated.rawByteCap도 추가했는데, 이는 잘린 첫 줄의 :raw read가 멈추는 바이트 상한을 안내에 표시하게 합니다 (#16595 by @will-bogusz)Editor.predictions가 둘 이상일 때, 고스트 텍스트는 초안이 접두사로 가지는 첫 번째 예측을 따릅니다. 입력한 초안이 더 짧은 예측과 같으면 더 긴 예측의 고스트를 유지합니다. 버퍼가 고스트 없이 예측 중 하나와 같아지면(Tab, Right 또는 목록에서 삽입한 직후 항상), 흐린 ⇥ N more 힌트가 나타납니다. Tab을 눌러 전체 목록을 보고, Enter, Tab 또는 Right로 전체 줄을 교체하거나(절대 제출하지 않음) Esc로 현재 내용을 유지합니다 (#17796 by @wolfiesch)Component.nativeTrailers()를 추가했습니다. 이는 transcript 블록이 그 바로 뒤에 자체 네이티브 블록을 추가할 수 있게 합니다. 후행 블록은 블록이 접혀 있어도 계속 보입니다.isPidAlive(signal-0 liveness probe)와 asStrictBytes(WebCrypto용으로 자체 ArrayBuffer로 좁혀진 Uint8Array)를 추가했습니다ensureSqliteLockShim()을 추가했습니다. openSqliteDatabase/openSqliteDatabaseSync는 저장소를 열기 전에 이를 호출합니다. 그래서 Linux에서 프로세스의 SQLite 잠금은 파일의 다른 close가 해제할 수 없는 open-file-description 잠금이 됩니다 (#15586)assertNotHeldOpen(path)(@oh-my-pi/pi-utils/held-file)를 추가했습니다. 이 함수는 이 프로세스가 열고 있는 SQLite 데이터베이스나 -shm에 대해 EBUSY를 던집니다 (#15586)acp 런타임 검증기(zNewSessionResponse, zSessionNotification 등)는 단일 Invalid <label> 대신 실패한 각 필드의 경로와 사유를 error.issues에 보고합니다. ValidationError의 issue 경로는 PropertyKey[] 타입입니다 (#17699)packEnvelope, unpackEnvelope, rewriteEnvelopePeer를 추가했습니다분량 관계로 이후 내용은 번역에서 제외했습니다. 전체 내용은 위 원문 링크에서 확인하세요.