Context handed to every tool execution.
Carries the working directory the loop should treat as root, the current
permission mode, the session id (if any), and a free-form assigns map for
custom tools to stash arbitrary data the consumer needs (project id,
conversation id, ticket id — whatever the host cares about).
Tools that don't care about context can ignore it, but cwd and phase
are load-bearing for any tool that touches the filesystem or checks
permissions.
Summary
Functions
Whether this context confines tools to allowed_roots.
Build a context. :cwd is required; everything else defaults.
Resolve a user-supplied path against ctx.cwd.
Whether an absolute path lies within one of roots. Compares on path
segments (not string prefixes) so /foo never matches /foobar. A path equal
to a root counts as inside it.
Types
Functions
Whether this context confines tools to allowed_roots.
Build a context. :cwd is required; everything else defaults.
Resolve a user-supplied path against ctx.cwd.
Unconfined (allowed_roots: nil, the default) keeps the historical behaviour:
relative paths are expanded against cwd, .. traversal is rejected, and
absolute paths pass through untouched.
Confined (allowed_roots is a list) expands the path to an absolute one
(handling ../~ lexically), resolves symlinks (see within_roots?/2), and
requires the canonical result to fall inside one of the roots, returning
{:error, {:path_outside_roots, abs}} otherwise — so neither /etc/passwd,
../../secret, nor an in-root symlink pointing outside can escape.
Whether an absolute path lies within one of roots. Compares on path
segments (not string prefixes) so /foo never matches /foobar. A path equal
to a root counts as inside it.
Both path and roots are canonicalized first — every existing symlink
component is resolved to its real target — so a symlink placed inside a root
but pointing outside does not pass, while symlinks that stay inside the roots
(and roots that are themselves symlinks, e.g. macOS /tmp →
/private/tmp) keep working. Symlink loops count as outside.