nervネルフ

Configuration

Lua, and a program rather than a data file: it may probe the machine, loop and branch. One entry point for what you name, and three directories for what you install.

plate 11load order, and where a project file is refused

The entry point

-- ~/.config/magi/init.lua — what you name explicitly.
-- What you *install* is discovered: see writing a tool.
magi.load("tools.lua")

magi.model   = "openrouter/anthropic/claude-sonnet-4.6"
magi.confine = true                     -- refuse paths outside the session root
magi.allow   = { … }                    -- answered in advance, not under pressure

What it takes

settingdoes
magi.modelwhich model, as magi models prints it
magi.memory · magi.tools · magi.melchioras a string, which program fills that role — see swapping a program
magi.confinewhether read, write and edit refuse paths outside the session's directory
magi.allowpermissions granted in advance, so they are not asked about
magi.trusteddirectories whose .magi.lua is as good as this file
magi.envenvironment every process magi starts is given, on top of what it inherits
magi.projectwhat this session is called, in the name other sessions see
magi.agent_talkhow far one session may reach another
magi.uievery colour, glyph and measurement the screen draws with
magi.casper · magi.melchior · magi.balthasaras a table, settings handed to that sibling, in its vocabulary — one place to edit rather than two. For the tools role the table is named after whichever program fills it.

A project's own file

A .magi.lua arrives with a checkout. Cloning a repository and running magi in it must not be enough to add a tool — a tool names a command to run — or to widen what runs without asking.

a project file mayand may not
choose a model the machine already offersdeclare a tool
set ordinary settingstouch confine, allow or trusted — fatal, not a warning
load its own filesname its own directory as trusted
tune a sibling through its settings tablename the program that fills a role — fatal, since it would run with the session’s authority

The one way past it is from your own configuration: naming a directory in magi.trusted makes its project file as good as yours. A decision made once, in advance, in the file only you can edit. Without a way to say yes, the rule would be worked around instead of used.

What magi does not keep, it says so about. A declaration for something a sibling owns, or a setting nested past what can be described, is reported on stderr rather than dropped. A config line that did nothing used to look exactly like one that worked.

Configuring a sibling through magi

magi asks each sibling what it takes, hands over what your config named, and reports anything the far side would not accept — a coordinator and a sibling disagreeing about what a name means is worth a line on stderr.

magi.balthasar = { promote_floor = 0.6 }
magi.melchior  = { max_tokens = 8192 }
magi.casper    = { tools = { dino = { off = true }, birdy = { hidden = true } } }
$ balthasar needs      # what it will accept, in its own words
$ melchior needs
$ casper needs

A setting the far side does not recognise comes back named rather than as a generic refusal, because "refused" is not something a coordinator can act on. Its own vocabulary, not magi's: renaming a setting on one side shows up as a line on stderr instead of failing silently on the other.

A program spawned per call is told on every spawn. configure sets something in the process that answers it — the whole of what a sibling needs when it is asked once and then runs for the session. casper is one process per call, so what magi decided rides on every spawn instead. Otherwise casper would report the setting taken and the next call would be a fresh process that had never heard of it.