From 25950c5b9e09e825d03ea216680a456f03115c37 Mon Sep 17 00:00:00 2001 From: foxnne Date: Sat, 17 Oct 2026 09:55:08 -0500 Subject: [PATCH] sdk: repin to fizzy SDK 0.2.29, edits credited to the agent A file the agent writes into an open document (`fs/write_text_file`, through `text.write`) is now recorded as that chat's agent's step (`sdk.Author`, fizzyedit/fizzy#474/#475), labelled with the name the agent gave in `initialize` (`agentInfo`), rather than as the person's. Co-Authored-By: Claude Opus 5.5 --- build.zig.zon | 4 ++-- plugin.zig.zon | 2 +- src/AcpClient.zig | 17 +++++++++++++++-- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/build.zig.zon b/build.zig.zon index 60b50a5..b095750 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -8,8 +8,8 @@ .fizzy = .{ // The published SDK, not a path into a checkout: a release has to build from a // clean clone. To build against a local fizzy: `zig build --fork=/sdk`. - .url = "https://github.com/fizzyedit/fizzy/releases/download/sdk-v0.2.26/fizzy-sdk-v0.2.26.tar.gz", - .hash = "fizzy-0.2.26-SGBwY8PFJADYTlbtNoDPd21a3l4Kwv0EF6Zcp--jzU81", + .url = "https://github.com/fizzyedit/fizzy/releases/download/sdk-v0.2.29/fizzy-sdk-v0.2.29.tar.gz", + .hash = "fizzy-0.2.29-SGBwY2sxJgCLLSPt4HLdlMSg7WtcP4K0fdtXI5WwJl2d", }, }, } diff --git a/plugin.zig.zon b/plugin.zig.zon index 225fe42..febdd60 100644 --- a/plugin.zig.zon +++ b/plugin.zig.zon @@ -2,6 +2,6 @@ .id = "chat", .name = "Chat", .version = "0.1.0", - .min_sdk_version = "0.2.26", + .min_sdk_version = "0.2.29", .description = "Talk to any AI agent that speaks the Agent Client Protocol (Claude, Codex, Gemini, Copilot, …) in a fizzy panel, and watch it work in fizzy through the agent plugin's tools.", } diff --git a/src/AcpClient.zig b/src/AcpClient.zig index bfdbe24..0ef40f2 100644 --- a/src/AcpClient.zig +++ b/src/AcpClient.zig @@ -92,6 +92,9 @@ const Session = struct { /// (`session/resume`), or load it, replaying its history (`session/load`). can_resume: bool = false, can_load: bool = false, + /// What `initialize` said the agent is called (`agentInfo`): the label its edits carry beside + /// the person's (`sdk.Author`). Owned; null until it says. + label: ?[]u8 = null, /// A `session/load` is replaying the conversation: the chat has it already, so the replay is /// not shown again. replaying: bool = false, @@ -107,6 +110,7 @@ const Session = struct { if (self.queued) |*q| q.arena.deinit(); if (self.resume_id) |r| self.gpa.free(r); if (self.folder) |f| self.gpa.free(f); + if (self.label) |l| self.gpa.free(l); self.pending.deinit(self.gpa); var it = self.tools.keyIterator(); while (it.next()) |k| self.gpa.free(k.*); @@ -600,6 +604,11 @@ fn answered(s: *Session, what: Pending, result: json.Value) void { const caps = field(result, "agentCapabilities"); s.can_load = if (field(caps, "loadSession")) |v| v == .bool and v.bool else false; s.can_resume = field(field(caps, "sessionCapabilities"), "resume") != null; + const info = field(result, "agentInfo"); + if (str(field(info, "title")) orelse str(field(info, "name"))) |name| { + if (s.label) |l| s.gpa.free(l); + s.label = s.gpa.dupe(u8, name) catch null; + } openSession(s); }, .session_new => { @@ -881,8 +890,12 @@ fn writeFile(s: *Session, id: json.Value, params: json.Value) void { const text = str(field(params, "content")) orelse return write(s, acp.writeError, .{ id, -32602, "no content" }); const host = sdk.host(); const arena = host.arena(); - if (host.docFromPath(path) != null and callText(arena, "text.write", .{ .path = path, .text = text }) != null) { - return write(s, acp.writeResult, .{ id, .{} }); + if (host.docFromPath(path) != null) { + // The edit is this chat's agent's, not the person's: its step carries the agent's name. + const outer = host.act(.{ .kind = .agent, .plugin = "chat", .session = s.chat, .label = s.label orelse "An agent" }); + const written = callText(arena, "text.write", .{ .path = path, .text = text }); + host.endAct(outer); + if (written != null) return write(s, acp.writeResult, .{ id, .{} }); } if (std.fs.path.dirname(path)) |dir| std.Io.Dir.cwd().createDirPath(dvui.io, dir) catch {}; std.Io.Dir.cwd().writeFile(dvui.io, .{ .sub_path = path, .data = text }) catch |err|