From 800b2c4b6115845f6bf15d90484b3e80e81a606f Mon Sep 17 00:00:00 2001 From: t Date: Wed, 1 Jul 2026 15:36:20 -0600 Subject: Load extensions via unified policy, entry/activate, rocks and paths Replace the split [tools]/[extensions] config sections and the two-stage load gate with a single model: - [extensions] is now one policy resolved across all layers. Rules from every layer are kept (not clobbered) and resolved by last-match-wins after sorting by (layer, glob specificity, deny-last), so a base layer can carve one name out of an otherwise-denied group and a higher layer's broad rule still wins. Default is allow; whitelist via deny=["**"]. - Registration is deferred: a source returns an entry {name, activate} (or a list, or the sugar tool table), is always eval'd side-effect-free, and only permitted names get activate()d. Identity is the declared name, not the filename. Collapses the old pre/post-load two-stage gate. - The loader runs two passes (eval -> shadow -> filter -> activate) with precedence project>user>base and, within a layer, rocks/agent), user ($XDG_CONFIG_HOME/panto or // $HOME/.config/panto), and project (./.panto). Project shadows @@ -399,10 +410,9 @@ pub fn main(init: std.process.Init) !void { init.environ_map, luarocks_rt.layout.agent_dir, rt, - .{ - .extensions = &app_config.extensions, - .tools = &app_config.tools, - }, + &app_config.extensions, + app_config.ext_paths, + app_config.ext_rocks, ) catch |err| { std.log.err("extension discovery failed: {t}", .{err}); return err; -- cgit v1.3