devez-vibe 1.2.2 → 1.2.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 +0 -0
- package/bridge/claude-agent-sdk-bridge.mjs +40 -9
- package/package.json +1 -1
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
|
-
|
|
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,24 @@ 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.
|
|
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
|
-
|
|
709
|
-
|
|
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
|
|
722
|
+
// 이 턴에서 다룬 적 없는 작업은 이전 턴의 것이므로 원래 turnId를 지켜 준다.
|
|
723
|
+
turnId: previous.get(id)?.turnId ?? turnId,
|
|
713
724
|
});
|
|
714
725
|
}
|
|
726
|
+
// TaskList는 세션 전체 목록을 돌려주므로, 지난 턴에 끝난 작업까지 되살아나지 않게 걷어낸다.
|
|
727
|
+
// 다만 전부 걷어내 목록이 비면 계획 카드가 통째로 사라지므로, 그때는 정리를 다음 TaskCreate에 맡긴다.
|
|
728
|
+
const listed = new Map(session.tasks);
|
|
729
|
+
pruneFinishedTasks(session.tasks, turnId);
|
|
730
|
+
if (session.tasks.size === 0) session.tasks = listed;
|
|
715
731
|
emitPlan(session);
|
|
716
732
|
}
|
|
717
733
|
}
|
|
@@ -732,6 +748,8 @@ function planStatus(status) {
|
|
|
732
748
|
}
|
|
733
749
|
|
|
734
750
|
function emitPlan(session) {
|
|
751
|
+
// 빈 계획을 보내면 화면의 계획 카드가 사라진다. 보여줄 작업이 없을 때는 마지막 계획을 그대로 둔다.
|
|
752
|
+
if (session.tasks.size === 0) return;
|
|
735
753
|
notify("turn/plan/updated", {
|
|
736
754
|
threadId: session.id,
|
|
737
755
|
turnId: session.turn?.id,
|
|
@@ -742,9 +760,11 @@ function emitPlan(session) {
|
|
|
742
760
|
});
|
|
743
761
|
}
|
|
744
762
|
|
|
763
|
+
// Claude의 Task 번호는 세션 전체에서 누적되므로 모델이 붙인 `4. `를 그대로 쓰면
|
|
764
|
+
// 다음 계획이 4번부터 시작한다. 지금 보여줄 목록 기준으로 항상 1번부터 다시 매긴다.
|
|
745
765
|
function numberedTaskSubject(subject, index) {
|
|
746
|
-
const text = String(subject || "작업").trim();
|
|
747
|
-
return
|
|
766
|
+
const text = String(subject || "작업").trim().replace(/^\d+[.)]\s*/, "").trim();
|
|
767
|
+
return `${index + 1}. ${text || "작업"}`;
|
|
748
768
|
}
|
|
749
769
|
|
|
750
770
|
// 서브에이전트는 자기 메시지를 부모 Task 툴콜의 `parent_tool_use_id`와 함께 흘려보낸다.
|
|
@@ -1151,8 +1171,12 @@ function historyTurns(messages) {
|
|
|
1151
1171
|
tasks.set(temporary.id, temporary);
|
|
1152
1172
|
}
|
|
1153
1173
|
} else if (pending.name === "TaskList" && Array.isArray(message.tool_use_result?.tasks)) {
|
|
1174
|
+
const known = new Map(tasks);
|
|
1154
1175
|
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 });
|
|
1176
|
+
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 });
|
|
1177
|
+
const listed = new Map(tasks);
|
|
1178
|
+
pruneFinishedTasks(tasks, turn.id);
|
|
1179
|
+
if (tasks.size === 0) for (const [id, task] of listed) tasks.set(id, task);
|
|
1156
1180
|
} else if (pending.item) {
|
|
1157
1181
|
const output = toolOutput(block.content, message.tool_use_result);
|
|
1158
1182
|
Object.assign(pending.item, pending.item.type === "commandExecution"
|
|
@@ -1215,7 +1239,14 @@ async function dispatch(method, params = {}) {
|
|
|
1215
1239
|
if (!info) throw new Error(`Claude 세션을 찾을 수 없습니다: ${id}`);
|
|
1216
1240
|
const messages = await getSessionMessages(id, { dir: params.cwd, includeSystemMessages: true });
|
|
1217
1241
|
const lastModel = [...messages].reverse().find((message) => message.type === "assistant")?.message?.model;
|
|
1218
|
-
|
|
1242
|
+
// The transcript's own model outranks the host's fallback, which is only what
|
|
1243
|
+
// a new session would have opened on.
|
|
1244
|
+
const { session, account, usage } = await createSession({
|
|
1245
|
+
...params,
|
|
1246
|
+
cwd: info.cwd || params.cwd,
|
|
1247
|
+
model: params.model || lastModel || params.fallbackModel,
|
|
1248
|
+
effort: params.effort || params.fallbackEffort,
|
|
1249
|
+
}, id);
|
|
1219
1250
|
const tokenUsage = historyTokenUsage(messages, session.models, session.model);
|
|
1220
1251
|
// Seed the live session so the next turn keeps reporting a full context.
|
|
1221
1252
|
session.lastContextUsage = tokenUsage?.last || null;
|