summaryrefslogtreecommitdiff
path: root/src/luarocks_runtime.zig
diff options
context:
space:
mode:
authort <t@tjp.lol>2026-06-01 08:21:00 -0600
committert <t@tjp.lol>2026-06-01 11:20:56 -0600
commit1beefefc69beee214430eb5bd2528a4f5692d2a8 (patch)
treea459dbde5da17babe7d872999341d2006ebfe02e /src/luarocks_runtime.zig
parent5c016cfdbcb122e2b4f0496ef946642d68953c4b (diff)
Rename system extension layer to base for clarity
Replace all references to the "system" layer with "base" to better reflect its role as the foundational extension/tool layer in panto's hierarchy. The layer hierarchy now consistently uses: project > user > base. Includes: - Update agent README and build.zig documentation - Refactor tool registry and config module to support layered lookups - Add TestHarness abstraction for cleaner test setup - Improve JSON serialization with wire-encoded tool names - Add glob pattern matching for tool/extension discovery
Diffstat (limited to 'src/luarocks_runtime.zig')
-rw-r--r--src/luarocks_runtime.zig66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/luarocks_runtime.zig b/src/luarocks_runtime.zig
index 0114b64..e652096 100644
--- a/src/luarocks_runtime.zig
+++ b/src/luarocks_runtime.zig
@@ -137,6 +137,7 @@ pub fn bootstrap(
try panto_home.ensureDirsExist(layout, io);
try stageLuaHeaders(allocator, io, layout);
try stageAgentTree(allocator, io, layout);
+ try stageDefaultConfig(allocator, io, layout);
const lua_wrapper_path = try writeLuaWrapper(allocator, io, layout, panto_executable_path);
defer allocator.free(lua_wrapper_path);
try writeLuarocksConfig(allocator, io, layout, lua_wrapper_path);
@@ -236,6 +237,71 @@ fn stageAgentTree(
}
}
+/// The default base `config.toml`, materialized at `$PANTO_HOME/config.toml`
+/// on first run if absent. It declares OpenAI and Anthropic providers whose
+/// API keys come from the conventional env vars — so a provider simply
+/// doesn't appear unless its key is exported. Edit or override at the user
+/// (`~/.config/panto/config.toml`) or project (`./.panto/config.toml`) layer.
+const default_base_config =
+ \\# panto base config (auto-generated on first run).
+ \\#
+ \\# This is the lowest-precedence layer. Override anything here from
+ \\# ~/.config/panto/config.toml (user)
+ \\# ./.panto/config.toml (project)
+ \\# Tables merge across layers; scalars and arrays from a higher layer
+ \\# replace the lower one wholesale.
+ \\#
+ \\# A provider whose API key (or its api_key_env_var) is missing at
+ \\# runtime is silently dropped — so these defaults disappear unless
+ \\# you've exported the corresponding key.
+ \\
+ \\[providers.openai]
+ \\style = "openai_chat"
+ \\base_url = "https://api.openai.com/v1"
+ \\api_key_env_var = "OPENAI_API_KEY"
+ \\
+ \\[providers.anthropic]
+ \\style = "anthropic_messages"
+ \\base_url = "https://api.anthropic.com"
+ \\api_key_env_var = "ANTHROPIC_API_KEY"
+ \\
+ \\# Pick the default model with `<provider>:<alias>`. The alias is
+ \\# resolved against models.toml; an unknown alias is used verbatim as
+ \\# the wire model name.
+ \\#
+ \\# [defaults]
+ \\# model = "anthropic:claude-sonnet-4-20250514"
+ \\
+ \\# Tool/extension availability (glob patterns). Empty allow = allow all.
+ \\# [tools]
+ \\# allow = ["std.*"]
+ \\# deny = []
+ \\
+;
+
+/// Materialize the default base config at `$PANTO_HOME/config.toml`,
+/// but only if no file exists there yet. We never overwrite — the base
+/// config is user-editable, and a stale-but-edited file must win over the
+/// shipped default.
+fn stageDefaultConfig(
+ allocator: Allocator,
+ io: Io,
+ layout: panto_home.Layout,
+) !void {
+ _ = allocator;
+ var home = try Io.Dir.cwd().openDir(io, layout.home, .{});
+ defer home.close(io);
+
+ home.access(io, "config.toml", .{}) catch |err| switch (err) {
+ error.FileNotFound => {
+ try home.writeFile(io, .{ .sub_path = "config.toml", .data = default_base_config });
+ return;
+ },
+ else => return err,
+ };
+ // Exists already — leave it untouched.
+}
+
/// Write `contents` into `dir/name` only if the existing file differs.
/// Creates the file if absent.
fn writeIfDifferent(