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` in the REPL. -- +-- Extensions return an *entry* `{ name, activate }`. The file is always +-- eval'd, but `activate()` runs only if `name` is permitted by the +-- `[extensions]` policy — so registration is deferred into activate(). +-- One entry may register any number of tools/commands. +-- -- Slash-command handlers run synchronously and act by side effect (here, -- writing to stdout). `args` is the trimmed text after the command name; -- it is an empty string when none was given. The return value is ignored. local panto = require("panto") -panto.ext.register_command { +return { name = "greet", - description = "Print a greeting. Optional args name who to greet.", - handler = function(args) - local who = args ~= "" and args or "world" - io.write("\n[greet] hello, " .. who .. "!\n") + activate = function() + panto.ext.register_command { + name = "greet", + description = "Print a greeting. Optional args name who to greet.", + handler = function(args) + local who = args ~= "" and args or "world" + io.write("\n[greet] hello, " .. who .. "!\n") + end, + } end, } -- cgit v1.3