devez-vibe 1.9.51 → 1.9.53

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
@@ -1949,6 +1949,15 @@ async function createSession(params, resumeId) {
1949
1949
  clearUsageLimitWait(session);
1950
1950
  if (session.turn) finishTurn(session, new Error("Claude 연결이 종료되었습니다."));
1951
1951
  clearSubagents(session);
1952
+ // A crashed CLI (Windows reports an access violation as exit code
1953
+ // 3221225477) leaves a query that rejects every later request. Dropping
1954
+ // the session makes the next prompt fail as missing, which the host answers
1955
+ // by resuming it from the transcript instead of the user reopening it.
1956
+ if (sessions.get(session.id) === session) {
1957
+ sessions.delete(session.id);
1958
+ session.queue.close();
1959
+ session.query.close();
1960
+ }
1952
1961
  });
1953
1962
  session.consumer = consumer;
1954
1963
  let initialization;
@@ -2766,7 +2775,7 @@ function upsertStructuredSubagent(session, message) {
2766
2775
  return running;
2767
2776
  }
2768
2777
 
2769
- function finishStructuredSubagent(session, message, kind, text) {
2778
+ function finishStructuredSubagent(session, message) {
2770
2779
  const taskId = firstLine(message.task_id || "", 80);
2771
2780
  const toolUseId = firstLine(message.tool_use_id || "", 80);
2772
2781
  const wasTranscriptHidden = taskId
@@ -2779,7 +2788,6 @@ function finishStructuredSubagent(session, message, kind, text) {
2779
2788
  const running = (toolUseId && findSubagent(session, toolUseId))
2780
2789
  || (taskId && findSubagent(session, taskId));
2781
2790
  if (!running) return wasHidden;
2782
- emitSubagentLine(session, running.id, { kind, text });
2783
2791
  session.subagents.delete(running.id);
2784
2792
  emitSubagents(session);
2785
2793
  return true;
@@ -2879,25 +2887,14 @@ function processSubagentSystemMessage(session, message) {
2879
2887
  if (!running) return false;
2880
2888
  const tool = firstLine(message.last_tool_name || "", 80);
2881
2889
  if (tool) running.tool = tool;
2882
- const summary = firstLine(message.summary || "", 200);
2883
- if (summary && summary !== running.lastSummary) {
2884
- running.lastSummary = summary;
2885
- emitSubagentLine(session, running.id, { kind: "result", text: summary });
2886
- }
2887
2890
  emitSubagents(session);
2888
2891
  return true;
2889
2892
  }
2890
2893
  if (message.subtype === "task_updated") {
2891
2894
  const taskId = firstLine(message.task_id || "", 80);
2892
2895
  const patch = message.patch || {};
2893
- const status = patch.status;
2894
- if (["completed", "failed", "killed"].includes(status)) {
2895
- return finishStructuredSubagent(
2896
- session,
2897
- message,
2898
- status === "completed" ? "result" : "error",
2899
- firstLine(patch.error || status, 200),
2900
- );
2896
+ if (["completed", "failed", "killed"].includes(patch.status)) {
2897
+ return finishStructuredSubagent(session, message);
2901
2898
  }
2902
2899
  const running = taskId && findSubagent(session, taskId);
2903
2900
  if (!running) return false;
@@ -2914,13 +2911,7 @@ function processSubagentSystemMessage(session, message) {
2914
2911
  session.ambientSubagentTasks ||= new Set();
2915
2912
  session.ambientSubagentTasks.add(firstLine(message.task_id, 80));
2916
2913
  }
2917
- const status = firstLine(message.status || "completed", 40);
2918
- return finishStructuredSubagent(
2919
- session,
2920
- message,
2921
- status === "completed" ? "result" : "error",
2922
- firstLine(message.summary || status, 200),
2923
- );
2914
+ return finishStructuredSubagent(session, message);
2924
2915
  }
2925
2916
  if (message.subtype === "background_tasks_changed") {
2926
2917
  syncBackgroundSubagents(session, message.tasks);
@@ -2929,61 +2920,24 @@ function processSubagentSystemMessage(session, message) {
2929
2920
  return false;
2930
2921
  }
2931
2922
 
2932
- // 서브에이전트가 실제로 무엇을 했는지는 자식 메시지에만 남는다. 열람용 기록은 여기서
2933
- // 한 줄씩 흘려보내고, 목록 행에 쓸 현재 도구만 따로 갱신한다.
2923
+ // 서브에이전트가 지금 무슨 도구를 돌리는지는 자식 메시지에만 남는다. 목록 행에 쓸
2924
+ // 현재 도구만 갱신한다.
2934
2925
  // 메시지의 agent_id는 그 하위 에이전트 작업의 task_id라 재개 뒤에도 같은 행을 찾는다.
2935
- function messageSubagent(session, message) {
2936
- return findSubagent(session, message.parent_tool_use_id)
2937
- || (message.agent_id ? findSubagent(session, message.agent_id) : undefined);
2938
- }
2939
-
2940
2926
  function recordSubagentMessage(session, message) {
2941
- const running = messageSubagent(session, message);
2927
+ const running = findSubagent(session, message.parent_tool_use_id)
2928
+ || (message.agent_id ? findSubagent(session, message.agent_id) : undefined);
2942
2929
  if (!running) return;
2943
2930
  running.lastSeenAt = Date.now();
2944
2931
  const content = Array.isArray(message.message?.content) ? message.message.content : [];
2945
2932
  let toolChanged = false;
2946
2933
  for (const block of content) {
2947
- if (block.type === "text") {
2948
- const text = String(block.text || "").trim();
2949
- if (text) emitSubagentLine(session, running.id, { kind: "text", text });
2950
- } else if (block.type === "tool_use") {
2951
- running.tool = subagentToolLabel(block);
2952
- toolChanged = true;
2953
- emitSubagentLine(session, running.id, {
2954
- kind: "tool",
2955
- text: running.tool,
2956
- toolUseId: block.id,
2957
- });
2958
- }
2934
+ if (block.type !== "tool_use") continue;
2935
+ running.tool = subagentToolLabel(block);
2936
+ toolChanged = true;
2959
2937
  }
2960
2938
  if (toolChanged) emitSubagents(session);
2961
2939
  }
2962
2940
 
2963
- function recordSubagentResult(session, message) {
2964
- const running = messageSubagent(session, message);
2965
- if (!running) return;
2966
- running.lastSeenAt = Date.now();
2967
- const content = Array.isArray(message.message?.content) ? message.message.content : [];
2968
- for (const block of content) {
2969
- if (block.type !== "tool_result") continue;
2970
- emitSubagentLine(session, running.id, {
2971
- kind: block.is_error ? "error" : "result",
2972
- text: firstLine(toolOutput(block.content, message.tool_use_result), 200),
2973
- toolUseId: block.tool_use_id,
2974
- });
2975
- }
2976
- }
2977
-
2978
- function emitSubagentLine(session, parentToolUseId, line) {
2979
- notify("turn/subagent/line", {
2980
- threadId: session.id,
2981
- turnId: session.turn?.id,
2982
- parentToolUseId,
2983
- line,
2984
- });
2985
- }
2986
-
2987
2941
  function subagentToolLabel(block) {
2988
2942
  const name = block.name || "Tool";
2989
2943
  const input = block.input || {};
@@ -3167,10 +3121,6 @@ function finishNotifiedSubagents(session, notifications) {
3167
3121
  }
3168
3122
  }
3169
3123
  if (!running) continue;
3170
- emitSubagentLine(session, running.id, {
3171
- kind: notification.status === "completed" ? "result" : "error",
3172
- text: notification.summary || notification.status || "완료됨",
3173
- });
3174
3124
  session.subagents.delete(running.id);
3175
3125
  emitSubagents(session);
3176
3126
  }
@@ -3181,11 +3131,8 @@ function processUser(session, message) {
3181
3131
  // prompts. Re-processing their notification XML would invent a new turn.
3182
3132
  if (message.isReplay === true) return;
3183
3133
  // 자식 tool_result의 tool_use_id는 부모 세션의 것과 다른 공간이므로, 부모 흐름에
3184
- // 섞이기 전에 서브에이전트 기록으로 보낸다.
3185
- if (message.parent_tool_use_id) {
3186
- recordSubagentResult(session, message);
3187
- return;
3188
- }
3134
+ // 섞이지 않게 버린다.
3135
+ if (message.parent_tool_use_id) return;
3189
3136
  const notifications = taskNotifications(message);
3190
3137
  if (notifications.length) {
3191
3138
  if (!session.turn) {
@@ -4482,6 +4429,15 @@ async function dispatch(method, params = {}) {
4482
4429
  }
4483
4430
  return {};
4484
4431
  }
4432
+ // 하위 에이전트 행의 x. 행은 도구 호출 id로 알려도 stop_task는 작업 id를 받으므로,
4433
+ // task_started가 아직 오지 않은 행은 멈출 수 없다. 행은 종료 통지가 거둔다.
4434
+ if (method === "session/stopTask") {
4435
+ const session = lookupSession(params.sessionId);
4436
+ const running = session && findSubagent(session, String(params.id || ""));
4437
+ if (!running?.taskId) throw new Error("아직 멈출 수 있는 작업 정보가 없습니다. 잠시 후 다시 시도하세요.");
4438
+ await session.query.stopTask(running.taskId);
4439
+ return {};
4440
+ }
4485
4441
  if (method === "session/compact") {
4486
4442
  return startPrompt({ ...params, input: [{ type: "text", text: "/compact" }] });
4487
4443
  }
@@ -5571,6 +5527,24 @@ async function runSelfTest() {
5571
5527
  await dispatch("session/interrupt", { sessionId: limitSession.id });
5572
5528
  resumeAfterUsageLimit(limitSession, cancelledWait, cancelledWait.resetsAt);
5573
5529
  if (limitSession.turn || retryInputs.length !== 1) throw new Error("Cancelled usage limit resumed");
5530
+ // 행의 x는 행 id가 아니라 SDK 작업 id로 멈춘다. 작업 id를 아직 모르는 행은 거절한다.
5531
+ const stoppedTasks = [];
5532
+ const stopSession = {
5533
+ id: "stop-task-self-test",
5534
+ query: { async stopTask(taskId) { stoppedTasks.push(taskId); } },
5535
+ subagents: new Map([
5536
+ ["toolu_stop", { id: "toolu_stop", toolUseId: "toolu_stop", taskId: "agent-stop" }],
5537
+ ["toolu_pending", { id: "toolu_pending", toolUseId: "toolu_pending", taskId: "" }],
5538
+ ]),
5539
+ };
5540
+ sessions.set(stopSession.id, stopSession);
5541
+ await dispatch("session/stopTask", { sessionId: stopSession.id, id: "toolu_stop" });
5542
+ const pendingStop = await dispatch("session/stopTask", { sessionId: stopSession.id, id: "toolu_pending" })
5543
+ .then(() => null, (error) => error);
5544
+ sessions.delete(stopSession.id);
5545
+ if (stoppedTasks.join() !== "agent-stop" || !pendingStop) {
5546
+ throw new Error(`Claude per-task stop self-test failed: ${stoppedTasks}`);
5547
+ }
5574
5548
  // Ultracode rides with each prompt's effort; a steer that becomes a turn keeps it.
5575
5549
  const flagCalls = [];
5576
5550
  const ultracodeSession = {
@@ -6498,9 +6472,7 @@ async function runSelfTest() {
6498
6472
  && event.params.item.text === "automatic summary one")
6499
6473
  || !lifecycleEvents.some((event) => event.method === "item/completed"
6500
6474
  && event.params?.item?.type === "agentMessage"
6501
- && event.params.item.text === "automatic summary two")
6502
- || !lifecycleEvents.some((event) => event.method === "turn/subagent/line"
6503
- && event.params?.line?.kind === "error")) {
6475
+ && event.params.item.text === "automatic summary two")) {
6504
6476
  throw new Error(`Claude subagent lifecycle events self-test failed: ${lifecycleMethods}`);
6505
6477
  }
6506
6478
  const openingSession = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devez-vibe",
3
- "version": "1.9.51",
3
+ "version": "1.9.53",
4
4
  "type": "module",
5
5
  "description": "Stable terminal UI for Codex and Claude Agent SDK",
6
6
  "keywords": [