devez-vibe 1.7.64 → 1.7.65

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
@@ -3146,11 +3146,45 @@ function transcriptEntries(raw) {
3146
3146
  if (seen.has(entry.uuid)) continue;
3147
3147
  seen.add(entry.uuid);
3148
3148
  }
3149
+ // The transcript file spells the SDK's tool_use_result as toolUseResult.
3150
+ if (entry.tool_use_result === undefined && entry.toolUseResult !== undefined) entry.tool_use_result = entry.toolUseResult;
3149
3151
  messages.push(entry);
3150
3152
  }
3151
3153
  return messages;
3152
3154
  }
3153
3155
 
3156
+ // Pages the transcript published with the Artifact tool, oldest first and each
3157
+ // URL at its latest publish, so a resumed session gets its row under the status
3158
+ // line back the way the CLI rehydrates its own footer.
3159
+ function publishedArtifacts(messages) {
3160
+ const inputs = new Map();
3161
+ const artifacts = new Map();
3162
+ for (const message of messages) {
3163
+ for (const block of contentBlocks(message.message)) {
3164
+ if (block.type === "tool_use" && block.name === "Artifact") inputs.set(block.id, block.input || {});
3165
+ if (block.type !== "tool_result" || !inputs.has(block.tool_use_id)) continue;
3166
+ const result = message.tool_use_result;
3167
+ if (typeof result?.url !== "string") continue;
3168
+ artifacts.delete(result.url);
3169
+ artifacts.set(result.url, {
3170
+ url: result.url,
3171
+ title: String(result.title || ""),
3172
+ path: String(result.path || inputs.get(block.tool_use_id).file_path || ""),
3173
+ });
3174
+ }
3175
+ }
3176
+ return [...artifacts.values()];
3177
+ }
3178
+
3179
+ // Sent after the resume reply, which the host has already cleared its row for.
3180
+ function restoreArtifacts(id, messages) {
3181
+ const artifacts = publishedArtifacts(messages);
3182
+ if (!artifacts.length) return;
3183
+ setImmediate(() => {
3184
+ for (const artifact of artifacts) notify("turn/artifact/published", { threadId: id, ...artifact });
3185
+ });
3186
+ }
3187
+
3154
3188
  async function transcriptMessagesAt(path) {
3155
3189
  let raw;
3156
3190
  try {
@@ -3381,6 +3415,7 @@ async function dispatch(method, params = {}) {
3381
3415
  if (existing) {
3382
3416
  const messages = await sessionMessages(id, existing.cwd);
3383
3417
  if (!existing.tasks.size) existing.tasks = historyState(messages).tasks;
3418
+ restoreArtifacts(id, messages);
3384
3419
  return {
3385
3420
  id,
3386
3421
  thread: { id, turns: [] },
@@ -3414,6 +3449,7 @@ async function dispatch(method, params = {}) {
3414
3449
  session.lastContextUsage = tokenUsage?.last || null;
3415
3450
  session.lastContextWindow = tokenUsage?.modelContextWindow || 0;
3416
3451
  session.tasks = historyState(messages).tasks;
3452
+ restoreArtifacts(id, messages);
3417
3453
  return {
3418
3454
  id,
3419
3455
  thread: { id, turns: [] },
@@ -3644,6 +3680,25 @@ async function runSelfTest() {
3644
3680
  || JSON.stringify(restoredPrompts) !== JSON.stringify(["compact 이전 질문", "compact 이후 질문"])) {
3645
3681
  throw new Error(`Claude compacted transcript self-test failed: ${JSON.stringify({ restored: restored.length, restoredPrompts })}`);
3646
3682
  }
3683
+ // A resumed transcript lists its Artifact pages once each at their latest
3684
+ // publish, read through the file's toolUseResult spelling.
3685
+ const artifactTranscript = [
3686
+ JSON.stringify({ type: "assistant", uuid: "art-1", message: { role: "assistant", content: [{ type: "tool_use", id: "toolu_a1", name: "Artifact", input: { file_path: "C:\\tmp\\first.html" } }] } }),
3687
+ JSON.stringify({ type: "user", uuid: "art-1r", message: { role: "user", content: [{ type: "tool_result", tool_use_id: "toolu_a1", content: "ok" }] }, toolUseResult: { url: "https://claude.ai/code/artifact/one", title: "One" } }),
3688
+ JSON.stringify({ type: "assistant", uuid: "art-2", message: { role: "assistant", content: [{ type: "tool_use", id: "toolu_a2", name: "Artifact", input: { file_path: "C:\\tmp\\second.html" } }] } }),
3689
+ JSON.stringify({ type: "user", uuid: "art-2r", message: { role: "user", content: [{ type: "tool_result", tool_use_id: "toolu_a2", content: "ok" }] }, toolUseResult: { url: "https://claude.ai/code/artifact/two", path: "C:\\tmp\\second.html", title: "Two" } }),
3690
+ JSON.stringify({ type: "assistant", uuid: "art-3", message: { role: "assistant", content: [{ type: "tool_use", id: "toolu_a3", name: "Artifact", input: { action: "read", url: "https://claude.ai/code/artifact/one" } }] } }),
3691
+ JSON.stringify({ type: "user", uuid: "art-3r", message: { role: "user", content: [{ type: "tool_result", tool_use_id: "toolu_a3", content: "<html>" }] }, toolUseResult: { content: "<html>" } }),
3692
+ JSON.stringify({ type: "assistant", uuid: "art-4", message: { role: "assistant", content: [{ type: "tool_use", id: "toolu_a4", name: "Artifact", input: { file_path: "C:\\tmp\\first.html" } }] } }),
3693
+ JSON.stringify({ type: "user", uuid: "art-4r", message: { role: "user", content: [{ type: "tool_result", tool_use_id: "toolu_a4", content: "ok" }] }, toolUseResult: { url: "https://claude.ai/code/artifact/one", path: "C:\\tmp\\first.html", title: "One", updated: true } }),
3694
+ ].join("\n");
3695
+ const restoredArtifacts = publishedArtifacts(transcriptEntries(artifactTranscript));
3696
+ if (JSON.stringify(restoredArtifacts) !== JSON.stringify([
3697
+ { url: "https://claude.ai/code/artifact/two", title: "Two", path: "C:\\tmp\\second.html" },
3698
+ { url: "https://claude.ai/code/artifact/one", title: "One", path: "C:\\tmp\\first.html" },
3699
+ ])) {
3700
+ throw new Error(`Claude artifact resume self-test failed: ${JSON.stringify(restoredArtifacts)}`);
3701
+ }
3647
3702
  // A model that left the CLI's list resolves to its family's newest entry, so a
3648
3703
  // Fable 5 transcript resumes on Fable 5.1 instead of the host's default.
3649
3704
  const successorModels = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devez-vibe",
3
- "version": "1.7.64",
3
+ "version": "1.7.65",
4
4
  "description": "Stable terminal UI for Codex and Claude Agent SDK",
5
5
  "keywords": [
6
6
  "codex",