diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 84280cd..5e9b7da 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,6 @@ jobs: check: uses: fizzyedit/plugin-build-action/.github/workflows/check.yml@v7 with: - zig-version: "0.16.0" + zig-version: "0.17.0" # secrets: # build_env: ${{ secrets.MY_BUILD_ENV }} # as in release.yml, if the build needs one diff --git a/build.zig.zon b/build.zig.zon index 60b50a5..4c2f626 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -1,15 +1,15 @@ .{ .name = .chat, .version = "0.1.0", - .minimum_zig_version = "0.16.0", + .minimum_zig_version = "0.17.0", .paths = .{ "build.zig", "build.zig.zon", "plugin.zig", "plugin.zig.zon", "src", "README.md" }, .fingerprint = 0x659df2aa189488bc, .dependencies = .{ .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.30/fizzy-sdk-v0.2.30.tar.gz", + .hash = "fizzy-0.2.30-SGBwY1QnJwDznUMVnSLATxXgH2e8_Vz7eMwLj9UQ0sVU", }, }, } diff --git a/plugin.zig.zon b/plugin.zig.zon index 225fe42..91bf5d6 100644 --- a/plugin.zig.zon +++ b/plugin.zig.zon @@ -1,7 +1,7 @@ .{ .id = "chat", .name = "Chat", - .version = "0.1.0", - .min_sdk_version = "0.2.26", + .version = "0.1.1", + .min_sdk_version = "0.2.30", .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..cd9d78a 100644 --- a/src/AcpClient.zig +++ b/src/AcpClient.zig @@ -507,7 +507,7 @@ fn findMcp(arena: std.mem.Allocator) ?[]const u8 { const host = sdk.host(); const dir = host.pluginInstallDir("agent") orelse return null; defer host.allocator.free(dir); - const name = if (@import("builtin").os.tag == .windows) "fizzy-mcp.exe" else "fizzy-mcp"; + const name = if (@import("builtin").target.os.tag == .windows) "fizzy-mcp.exe" else "fizzy-mcp"; const path = std.fs.path.join(arena, &.{ dir, name }) catch return null; std.Io.Dir.accessAbsolute(dvui.io, path, .{ .execute = true }) catch return null; return path; diff --git a/src/Agent.zig b/src/Agent.zig index 1e5ebf0..8a48a63 100644 --- a/src/Agent.zig +++ b/src/Agent.zig @@ -54,7 +54,7 @@ pub fn start(gpa: std.mem.Allocator, io: Io, argv: []const []const u8, cwd: []co } fn spawn(gpa: std.mem.Allocator, io: Io, argv: []const []const u8, cwd: []const u8) !std.process.Child { - if (comptime builtin.os.tag == .macos) { + if (comptime builtin.target.os.tag == .macos) { return core.darwin_spawn.spawn(gpa, .{ .argv = argv, .cwd = cwd, @@ -172,7 +172,7 @@ fn readStderr(self: *Agent) void { /// `name` on this process's PATH, then the login shell's; null for a path or when not found /// (the spawn then fails with the name as given). As `core/lsp/Client.zig`'s `resolveExecutable`. fn resolveExecutable(gpa: std.mem.Allocator, io: Io, name: []const u8) ?[]u8 { - if (comptime builtin.os.tag == .windows) return null; + if (comptime builtin.target.os.tag == .windows) return null; if (std.mem.indexOfScalar(u8, name, '/') != null) return null; const inherited: ?[]const u8 = if (std.c.getenv("PATH")) |p| std.mem.span(p) else null; if (findInPath(gpa, io, inherited, name)) |found| return found; diff --git a/src/Transcript.zig b/src/Transcript.zig index 2cd3f78..b5fcb6e 100644 --- a/src/Transcript.zig +++ b/src/Transcript.zig @@ -465,12 +465,13 @@ pub fn load(self: *Transcript, bytes: []const u8, images_dir: []const u8, io: st var arena_state: std.heap.ArenaAllocator = .init(self.gpa); defer arena_state.deinit(); const arena = arena_state.allocator(); - const source = try arena.dupeZ(u8, bytes); + const source = try arena.dupeSentinel(u8, bytes, 0); const Probe = struct { version: u32 = 1 }; - const probe = std.zon.parse.fromSliceAlloc(Probe, arena, source, null, .{ .ignore_unknown_fields = true }) catch Probe{}; + var diag: std.zon.parse.Diagnostics = undefined; + const probe = std.zon.parse.fromSlice(Probe, .{ .gpa = arena, .arena = arena, .source = source, .diagnostics = &diag, .ignore_unknown_fields = true }) catch Probe{}; if (probe.version < format_version) return self.loadV1(arena, source); - const saved = try std.zon.parse.fromSliceAlloc(Saved, arena, source, null, .{ .ignore_unknown_fields = true }); + const saved = try std.zon.parse.fromSlice(Saved, .{ .gpa = arena, .arena = arena, .source = source, .diagnostics = &diag, .ignore_unknown_fields = true }); for (saved.messages) |m| { try self.messages.append(self.gpa, .{ .author = m.author }); const msg = &self.messages.items[self.messages.items.len - 1]; @@ -556,7 +557,8 @@ fn loadV1(self: *Transcript, arena: std.mem.Allocator, source: [:0]const u8) !Lo title: []const u8 = "", entries: []const struct { kind: Kind, text: []const u8, status: Status = .pending, detail: []const u8 = "" } = &.{}, }; - const old = try std.zon.parse.fromSliceAlloc(V1, arena, source, null, .{ .ignore_unknown_fields = true }); + var diag: std.zon.parse.Diagnostics = undefined; + const old = try std.zon.parse.fromSlice(V1, .{ .gpa = arena, .arena = arena, .source = source, .diagnostics = &diag, .ignore_unknown_fields = true }); var current: ?chat.MessageId = null; for (old.entries) |e| switch (e.kind) { .user => current = try self.post(.person, &.{.{ .text = e.text }}), diff --git a/src/api.zig b/src/api.zig index bb8bef2..236ef02 100644 --- a/src/api.zig +++ b/src/api.zig @@ -182,8 +182,9 @@ pub const NewChat = struct { folder: []const u8 = "" }; /// Parse a command's arguments, in `arena`. pub fn parse(comptime T: type, arena: std.mem.Allocator, zon: []const u8) !T { - const src = try arena.dupeZ(u8, std.mem.trim(u8, zon, " \t\r\n")); - return std.zon.parse.fromSliceAlloc(T, arena, src, null, .{ .ignore_unknown_fields = true }); + const src = try arena.dupeSentinel(u8, std.mem.trim(u8, zon, " \t\r\n"), 0); + var diag: std.zon.parse.Diagnostics = undefined; + return std.zon.parse.fromSlice(T, .{ .gpa = arena, .arena = arena, .source = src, .diagnostics = &diag, .ignore_unknown_fields = true }); } /// Write a command's arguments.