devez-vibe 1.10.2 → 1.10.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/dvz.exe CHANGED
Binary file
@@ -3051,7 +3051,7 @@ function syncBackgroundSubagents(session, tasks) {
3051
3051
  }
3052
3052
 
3053
3053
  // CLI는 진행 요약을 고정 영어 지시로 만들어 language 설정도 따르지 않는다. 한국어
3054
- // 요청 세션이면 Haiku로 옮겨 보이고, 같은 문구는 한 번만 옮긴다. 실패하면 원문을 쓴다.
3054
+ // 요청 세션이면 Haiku로 옮겨 보이고, 같은 문구는 한 번만 옮긴다. 옮기지 못하면 앞 설명을 둔다.
3055
3055
  const summaryTranslations = new Map();
3056
3056
 
3057
3057
  function translateSummary(session, summary) {
@@ -3059,14 +3059,22 @@ function translateSummary(session, summary) {
3059
3059
  if (!translation) {
3060
3060
  if (summaryTranslations.size >= 200) summaryTranslations.clear();
3061
3061
  translation = haikuReply(
3062
- `다음 진행 상황 문구를 '~하는 중' 꼴의 한국어 한 줄로 옮긴다. 파일·함수 이름은 그대로 두고 결과만 쓴다.\n${summary}`,
3062
+ `아래 진행 상황 문구의 한국어 번역문만 한 줄로 쓴다. 원문을 되풀이하거나 화살표·따옴표·설명을 붙이지 않는다. 파일·함수 이름은 그대로 두고 '~하는 중' 꼴로 끝낸다.\n${summary}`,
3063
3063
  session,
3064
- ).then((reply) => firstLine(reply, SUBAGENT_DESCRIPTION_LIMIT) || summary, () => summary);
3064
+ ).then(koreanSummary, () => "");
3065
3065
  summaryTranslations.set(summary, translation);
3066
3066
  }
3067
3067
  return translation;
3068
3068
  }
3069
3069
 
3070
+ // Haiku가 가끔 "원문 → 번역"으로 답한다. 한글이 든 줄의 한글 부분부터 쓰고, 한글이 없으면 버린다.
3071
+ function koreanSummary(reply) {
3072
+ const line = String(reply).split("\n").find((text) => /[가-힣]/.test(text)) || "";
3073
+ const parts = line.split(/\s*(?:→|->|=>)\s*/);
3074
+ const text = parts.slice(parts.findIndex((part) => /[가-힣]/.test(part))).join(" → ");
3075
+ return firstLine(text.replace(/^["'“]+|["'”]+$/g, ""), SUBAGENT_DESCRIPTION_LIMIT);
3076
+ }
3077
+
3070
3078
  function processSubagentSystemMessage(session, message) {
3071
3079
  if (String(message.subtype || "").startsWith("task_")) {
3072
3080
  const taskId = firstLine(message.task_id || "", 80);
@@ -3110,7 +3118,7 @@ function processSubagentSystemMessage(session, message) {
3110
3118
  if (session.lastKoreanRequest && !/[가-힣]/.test(summary)) {
3111
3119
  // 옮기는 동안은 앞 설명을 두고, 그사이 새 요약이 왔거나 줄이 끝났으면 버린다.
3112
3120
  translateSummary(session, summary).then((text) => {
3113
- if (running.latestSummary !== summary || session.subagents.get(running.id) !== running) return;
3121
+ if (!text || running.latestSummary !== summary || session.subagents.get(running.id) !== running) return;
3114
3122
  running.description = text;
3115
3123
  emitSubagents(session);
3116
3124
  });
@@ -4827,11 +4835,11 @@ async function dispatch(method, params = {}) {
4827
4835
  if (session) closeLiveSession(session);
4828
4836
  return { released: true, busy: false };
4829
4837
  }
4830
- // 순정 /clear처럼 백그라운드 작업만 남은 세션은 같은 프로세스에서 새 대화로
4831
- // 넘긴다. 작업과 그 완료 통지는 새 대화가 이어받는다.
4838
+ // 순정 /clear처럼 살아 있는 세션은 같은 프로세스에서 새 대화로 넘겨 CLI와 MCP
4839
+ // 연결을 다시 쓴다. 남은 백그라운드 작업과 그 완료 통지도 새 대화가 이어받는다.
4832
4840
  if (method === "session/clear") {
4833
4841
  const session = lookupSession(params.sessionId);
4834
- if (!session || !sessionHasLiveWork(session)) {
4842
+ if (!session || (!session.queue && !sessionHasLiveWork(session))) {
4835
4843
  if (session) closeLiveSession(session);
4836
4844
  return { released: true, busy: false };
4837
4845
  }
@@ -4853,6 +4861,11 @@ async function dispatch(method, params = {}) {
4853
4861
  clearTimeout(timer);
4854
4862
  session.clearWaiter = null;
4855
4863
  session.clearPending = false;
4864
+ // CLI가 /clear에 답하지 않아도 남은 작업이 없으면 연결을 닫고 새 대화를 연다.
4865
+ if (!id && !sessionHasLiveWork(session)) {
4866
+ closeLiveSession(session);
4867
+ return { released: true, busy: false };
4868
+ }
4856
4869
  if (!id) return { released: false, busy: true };
4857
4870
  emitSubagents(session);
4858
4871
  return {
@@ -6714,6 +6727,19 @@ async function runSelfTest() {
6714
6727
  || koreanRow.description !== "노트를 고치는 중") {
6715
6728
  throw new Error(`Claude Korean summary translation self-test failed: ${JSON.stringify([whileTranslating, afterLateTranslation, koreanRow.description])}`);
6716
6729
  }
6730
+ // 원문을 되풀이한 번역은 한국어 부분만, 한글이 없는 번역은 버리고 앞 설명을 둔다.
6731
+ summaryTranslations.set("Reading empty", Promise.resolve(""));
6732
+ koreanProgress("Reading empty");
6733
+ await new Promise((resolve) => setImmediate(resolve));
6734
+ const replies = [
6735
+ ["Reading a.md and b.md → a.md와 b.md를 읽는 중", "a.md와 b.md를 읽는 중"],
6736
+ ["Reading a.md\na.md를 읽는 중", "a.md를 읽는 중"],
6737
+ ["\"a.md를 읽는 중\"", "a.md를 읽는 중"],
6738
+ ["Reading a.md", ""],
6739
+ ].filter(([reply, expected]) => koreanSummary(reply) !== expected);
6740
+ if (koreanRow.description !== "노트를 고치는 중" || replies.length) {
6741
+ throw new Error(`Claude Korean summary cleanup self-test failed: ${JSON.stringify([koreanRow.description, replies])}`);
6742
+ }
6717
6743
  clearSubagents(koreanSummarySession);
6718
6744
  summaryTranslations.clear();
6719
6745
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devez-vibe",
3
- "version": "1.10.2",
3
+ "version": "1.10.4",
4
4
  "type": "module",
5
5
  "description": "Stable terminal UI for Codex and Claude Agent SDK",
6
6
  "keywords": [