devez-vibe 1.2.2 → 1.2.3

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
@@ -465,7 +465,14 @@ async function createSession(params, resumeId) {
465
465
  throw error;
466
466
  }
467
467
  session.models = Array.isArray(initialization.models) ? initialization.models : [];
468
- session.effort = supportedEffort(modelCapabilities(session.models, params.model), params.effort);
468
+ const capabilities = modelCapabilities(session.models, params.model);
469
+ // A resumed session can only name its model as the resolved id the transcript
470
+ // recorded (`claude-opus-4-5-...`), which matches nothing in the host's model
471
+ // list. Report the catalog value instead so the picker lands on that model.
472
+ if (capabilities?.value && capabilities.value !== "default") {
473
+ session.model = visibleModel(capabilities.value);
474
+ }
475
+ session.effort = supportedEffort(capabilities, params.effort);
469
476
  const account = initialization.account || await safeAccount(agentQuery);
470
477
  const usage = await safeUsage(agentQuery);
471
478
  return { session, initialization, account, usage };
@@ -703,15 +710,21 @@ function updatePlanFromToolResult(session, pending, message) {
703
710
  session.tasks.set(temporary.id, temporary);
704
711
  }
705
712
  } else if (pending.name === "TaskList" && Array.isArray(value?.tasks || value)) {
706
- session.tasks.clear();
713
+ const turnId = session.turn?.id;
714
+ const previous = session.tasks;
715
+ session.tasks = new Map();
707
716
  for (const task of value.tasks || value) {
708
- session.tasks.set(String(task.id), {
709
- id: String(task.id),
717
+ const id = String(task.id);
718
+ session.tasks.set(id, {
719
+ id,
710
720
  subject: task.subject || task.description || "작업",
711
721
  status: task.status || "pending",
712
- turnId: session.turn?.id,
722
+ // 이 턴에서 다룬 적 없는 작업은 이전 턴의 것이므로 원래 turnId 지켜 준다.
723
+ turnId: previous.get(id)?.turnId ?? turnId,
713
724
  });
714
725
  }
726
+ // TaskList는 세션 전체 목록을 돌려주므로, 지난 턴에 끝난 작업까지 되살아나지 않게 걷어낸다.
727
+ pruneFinishedTasks(session.tasks, turnId);
715
728
  emitPlan(session);
716
729
  }
717
730
  }
@@ -742,9 +755,11 @@ function emitPlan(session) {
742
755
  });
743
756
  }
744
757
 
758
+ // Claude의 Task 번호는 세션 전체에서 누적되므로 모델이 붙인 `4. `를 그대로 쓰면
759
+ // 다음 계획이 4번부터 시작한다. 지금 보여줄 목록 기준으로 항상 1번부터 다시 매긴다.
745
760
  function numberedTaskSubject(subject, index) {
746
- const text = String(subject || "작업").trim();
747
- return /^\d+\.\s/.test(text) ? text : `${index + 1}. ${text}`;
761
+ const text = String(subject || "작업").trim().replace(/^\d+[.)]\s*/, "").trim();
762
+ return `${index + 1}. ${text || "작업"}`;
748
763
  }
749
764
 
750
765
  // 서브에이전트는 자기 메시지를 부모 Task 툴콜의 `parent_tool_use_id`와 함께 흘려보낸다.
@@ -1151,8 +1166,10 @@ function historyTurns(messages) {
1151
1166
  tasks.set(temporary.id, temporary);
1152
1167
  }
1153
1168
  } else if (pending.name === "TaskList" && Array.isArray(message.tool_use_result?.tasks)) {
1169
+ const known = new Map(tasks);
1154
1170
  tasks.clear();
1155
- for (const task of message.tool_use_result.tasks) tasks.set(String(task.id), { id: String(task.id), subject: task.subject || "작업", status: task.status || "pending", turnId: turn.id });
1171
+ for (const task of message.tool_use_result.tasks) tasks.set(String(task.id), { id: String(task.id), subject: task.subject || "작업", status: task.status || "pending", turnId: known.get(String(task.id))?.turnId ?? turn.id });
1172
+ pruneFinishedTasks(tasks, turn.id);
1156
1173
  } else if (pending.item) {
1157
1174
  const output = toolOutput(block.content, message.tool_use_result);
1158
1175
  Object.assign(pending.item, pending.item.type === "commandExecution"
@@ -1215,7 +1232,14 @@ async function dispatch(method, params = {}) {
1215
1232
  if (!info) throw new Error(`Claude 세션을 찾을 수 없습니다: ${id}`);
1216
1233
  const messages = await getSessionMessages(id, { dir: params.cwd, includeSystemMessages: true });
1217
1234
  const lastModel = [...messages].reverse().find((message) => message.type === "assistant")?.message?.model;
1218
- const { session, account, usage } = await createSession({ ...params, cwd: info.cwd || params.cwd, model: params.model || lastModel }, id);
1235
+ // The transcript's own model outranks the host's fallback, which is only what
1236
+ // a new session would have opened on.
1237
+ const { session, account, usage } = await createSession({
1238
+ ...params,
1239
+ cwd: info.cwd || params.cwd,
1240
+ model: params.model || lastModel || params.fallbackModel,
1241
+ effort: params.effort || params.fallbackEffort,
1242
+ }, id);
1219
1243
  const tokenUsage = historyTokenUsage(messages, session.models, session.model);
1220
1244
  // Seed the live session so the next turn keeps reporting a full context.
1221
1245
  session.lastContextUsage = tokenUsage?.last || null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devez-vibe",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "Stable terminal UI for Codex and Claude Agent SDK",
5
5
  "keywords": [
6
6
  "codex",