diff options
| author | T <t@tjp.lol> | 2026-05-27 17:07:49 -0600 |
|---|---|---|
| committer | T <t@tjp.lol> | 2026-05-27 18:05:12 -0600 |
| commit | 48651e123ef0cf1d02eac781902517c0628b310a (patch) | |
| tree | f8f87205b2ca716f406ae69288ebef622659dd9e /build.zig | |
| parent | f72b5793a5c7e7891e4904be73c0bc6bc038fa18 (diff) | |
real coding agent tools
Diffstat (limited to 'build.zig')
| -rw-r--r-- | build.zig | 51 |
1 files changed, 48 insertions, 3 deletions
@@ -316,9 +316,18 @@ fn generateLuarocksEmbed( /// `$PANTO_HOME/agent/` on first run, where the runtime's extension /// loader finds it as the "system" layer (below user and project). /// -/// Mirrors `generateLuarocksEmbed`'s addCopyDirectory trick so the -/// emitted `@embedFile("agent_src/<rel>")` references resolve relative -/// to the generated zig file. +/// Unlike `generateLuarocksEmbed`, the agent tree lives in-repo and +/// its contents change as we add/edit tools. `addDirectoryArg` on a +/// local source dir does NOT hash directory contents into the cache +/// key (only the path string), so editing a file under `agent/` +/// wouldn't invalidate this step's cache. To make cache invalidation +/// correct, we enumerate the tree at *build-script execution time* +/// and call `addFileInput` for every file we find. Each file then +/// participates in the cache key. +/// +/// `addCopyDirectory` (below) still does the actual staging of the +/// tree alongside the generated zig file so `@embedFile("agent_src/...")` +/// references resolve. fn generateAgentEmbed(b: *std.Build) std.Build.LazyPath { const tool = b.addExecutable(.{ .name = "gen-agent-embed", @@ -336,12 +345,48 @@ fn generateAgentEmbed(b: *std.Build) std.Build.LazyPath { run.addDirectoryArg(b.path("agent")); const gen_file = run.addOutputFileArg("embedded_agent.zig"); + // Enumerate every file under `agent/` and register it as an + // explicit cache input. This is what makes `zig build` notice + // edits to e.g. `agent/tools/read.lua` without a manual + // `rm -rf .zig-cache`. + addAgentTreeFileInputs(b, run, "agent") catch |err| { + std.debug.panic("failed to enumerate agent/ tree: {t}", .{err}); + }; + const wf = b.addWriteFiles(); const out_zig = wf.addCopyFile(gen_file, "embedded_agent.zig"); _ = wf.addCopyDirectory(b.path("agent"), "agent_src", .{}); return out_zig; } +/// Recursively walk `subpath` under the build root and call +/// `addFileInput` on every regular file. Used to give the agent-embed +/// codegen accurate cache invalidation. Dotfiles (any path segment +/// starting with `.`) are skipped to match the codegen's filter. +fn addAgentTreeFileInputs( + b: *std.Build, + run: *std.Build.Step.Run, + subpath: []const u8, +) !void { + const io = b.graph.io; + var dir = b.build_root.handle.openDir(io, subpath, .{ .iterate = true }) catch |err| switch (err) { + error.FileNotFound => return, + else => return err, + }; + defer dir.close(io); + + var walker = try dir.walk(b.allocator); + defer walker.deinit(); + + while (try walker.next(io)) |entry| { + if (entry.kind != .file) continue; + if (entry.basename.len == 0 or entry.basename[0] == '.') continue; + if (std.mem.indexOf(u8, entry.path, "/.") != null) continue; + const rel = b.pathJoin(&.{ subpath, entry.path }); + run.addFileInput(b.path(rel)); + } +} + /// Codegen step: emit a Zig module that exposes every Lua public header /// from the Lua source tarball as embedded bytes. The bootstrap stages /// these under `$PANTO_HOME/rocks/lua-X.Y.Z/include/` so luarocks can |
