NAME
Langertha::Raider::Context - Internal context of an application: layout mode, Claude memory and settings, skills, agents
VERSION
version 0.504
SYNOPSIS
# Internal to Langertha-Raider -- no API promise.
my $context = Langertha::Raider::Context->new(
root => $root,
config_claude => $options->{claude}, # undef when not set
force_claude => $opt{claude}, # --claude
skill_specs => [ { type => 'dir', path => 'my-skills' } ],
want_agents_md => $opt{openai}, # --openai / --codex
);
$context->apply_env; # settings env into %ENV, once
my @items = $context->prompt_items; # memory, AGENTS.md, skill listing
my $skills = $context->skill_catalog; # Langertha::Raider::Context::Skills
my $agents = $context->agent_catalog; # Langertha::Raider::Context::Agents
my $skill = $context->skill_resolver->resolve('pdf'); # { name, dir, file } or undef
my $more = $context->nested_memory_for('lib/Foo.pm'); # or undef
my @notes = $context->nested_reminders_for('lib/Foo.pm'); # CLAUDE.md, skills
$context->reload; # /reload: read it all again
my $report = $context->report; # for config explain
DESCRIPTION
Internal module. Its interface may change without notice.
Everything ADR 0019 adds to what raider reads from a workspace, behind one object per application: the layout mode (Langertha::Raider::Context::Layout), and in the Claude layout the memory files (Langertha::Raider::Context::Memory), the settings (Langertha::Raider::Context::Settings) and the enabled plugins (Langertha::Raider::Context::Plugins); the AGENTS.md of --openai; and the skill catalogue (Langertha::Raider::Context::Skills) with its roots in the precedence of ADR 0019 §4:
- 1. "skill_specs", in their order.
{ type => 'claude', path }is a directory of skill directories (*/SKILL.md);{ type => 'file', path }one skill file (so is adirspec naming a file);{ type => 'dir', path, glob }a directory of flat *.md skills;{ type => 'dir', path }withoutglob(--skills DIR, a string inskills:) is both. A relative path is relative to "root". - 2. .raider/skills of "root", then ~/.raider/skills.
- 3. Only in the Claude layout: <claude_home>/skills, then .claude/skills and .agents/skills of the project directory ("project_dir" in Langertha::Raider::Context::Layout), then the skills of every installed and enabled plugin as
plugin:skill. - 4. The command roots ("command_roots", ADR 0030 §1), and in the Claude layout the commands of every plugin as
plugin:name. A skill beats a command of its name, wherever the command stands.
Skills can also arrive during a session: the .claude/skills of a subtree a tool touches, and skills with paths: frontmatter once a matching file is touched ("nested_skills_for", ADR 0019 Addendum 1).
A directory that appears twice is read once, at its first place.
The agent catalogue (Langertha::Raider::Context::Agents) has its roots in the precedence of ADR 0020 §1 ("agent_roots").
With "bare" nothing is read at all: mode bare, no memory, no settings, no skills, no agent files (only the built-in agents general-purpose, Explore and Plan), no AGENTS.md.
root
The project directory. Required.
bare
--bare (ADR 0014): no layout, nothing read.
force_claude
--claude: the Claude layout is read in every mode but bare.
config_claude
The effective claude: of the configuration (true, false or undef when not set); the legacy skills: [claude] counts as true. Read by truth, so YAML and JSON booleans work. Decides the Claude layout in a raider project ("claude_layout" in Langertha::Raider::Context::Layout).
skill_specs
The explicit skill directories, highest precedence first, as "skill_specs" in Langertha::Raider::Config normalizes them. Defaults to none.
want_agents_md
True for --openai / --codex or skills: [openai] (also codex, agents): AGENTS.md of "root" is an instructions item (unless the Claude memory already loaded that very file).
home
The user's home directory, by default "home_dir" in Langertha::Raider::Home.
claude_home
The Claude Code directory, by default "claude_home" in Langertha::Raider::Home of "home". Every part gets this one, so they agree.
layout
The Langertha::Raider::Context::Layout of "root".
mode
"mode" in Langertha::Raider::Context::Layout: bare, raider, claude or native.
claude_layout
"claude_layout" in Langertha::Raider::Context::Layout: whether memory, settings, plugins and the Claude skill roots are read.
memory
The Langertha::Raider::Context::Memory in the Claude layout, else undef.
settings
The Langertha::Raider::Context::Settings of the project directory in the Claude layout, else undef.
plugins
The Langertha::Raider::Context::Plugins (installed and enabled by the settings) in the Claude layout, else undef.
skill_roots
The skill roots in precedence order (see "DESCRIPTION"), each { dir, source, layout } as "roots" in Langertha::Raider::Context::Skills takes them, closed by the "command_roots". Roots that do not exist are listed too; the catalogue skips them.
command_roots
my @roots = $context->command_roots;
The command roots (ADR 0030 §1), layout commands, in precedence order: .raider/commands of "root", then ~/.raider/commands; only in the Claude layout <claude_home>/commands, then .claude/commands of the project directory (personal before project, as for the Claude skill roots). They close "skill_roots": a skill beats a command of its name anyway, so only their order among themselves matters. None with "bare".
skill_catalog
The Langertha::Raider::Context::Skills over "skill_roots" and, in the Claude layout, the skill directories and command paths of "plugins" ("command_dirs" in Langertha::Raider::Context::Plugins).
has_listed_skills
True when the catalogue lists at least one skill to the model.
skill_tool_wanted
True when the skill tool is mounted: in the Claude layout always (a nested .claude/skills or a skill with paths: can bring skills in later in the session, as in Claude Code), elsewhere when the catalogue holds a skill the model can invoke, now or once a file activates it.
skill_resolver
The Langertha::Raider::SkillResolver that briefs agents (ADR 0020 §6): the chain of "skill_resolvers".
skill_resolvers
The resolvers of "skill_resolver", first asked first: the skill catalogue (Langertha::Raider::SkillResolver::Catalog over "skill_catalog", skills that are not model-invocable included), then, only in the Claude layout, the skills the skilletor.json files declare, read from their sources without installing (Langertha::Raider::SkillResolver::Skilletor; a source is fetched only when it has no cache yet). A native or bare context has the catalogue alone: skilletor.json is Claude Code configuration.
agent_roots
The agent roots in precedence order (ADR 0020 §1), each { dir, source } as "roots" in Langertha::Raider::Context::Agents takes them: .raider/agents of "root", then ~/.raider/agents; only in the Claude layout .claude/agents of the project directory, then <claude_home>/agents. Roots that do not exist are listed too; the catalogue skips them. None with "bare".
agent_catalog
The Langertha::Raider::Context::Agents over "agent_roots" and, in the Claude layout, the agent paths of "plugins" ("agent_dirs" in Langertha::Raider::Context::Plugins), named plugin:agent.
agents_md
The AGENTS.md instructions item of "want_agents_md", or undef: the file is absent or empty, "bare", or the Claude memory already holds it. A hash with file, label, scope (project), kind (AGENTS.md), text and imports (none), the shape of "items" in Langertha::Raider::Context::Memory.
instruction_items
for my $item ($context->instruction_items) { say $item->{label} }
The memory items of the Claude layout, then "agents_md" -- every instructions file this context puts into the prompt.
prompt_items
my @texts = $context->prompt_items;
The context items of the system prompt, in order, each a string: the Claude memory (under the header Claude Code puts over it, see "memory_header"), the AGENTS.md item, the skill listing ("prompt_text" in Langertha::Raider::Context::Skills). Items without content are left out.
memory_header
The line above the Claude memory files, as Claude Code words it.
apply_env
my @keys = $context->apply_env;
Sets the env of the Claude settings (ADR 0019 §3) in %ENV of this process, so tools and their subprocesses see it, as in Claude Code; a value there replaces the one in the environment. Runs once per object -- later calls only return the keys. Nothing outside the Claude layout. Returns the names of the keys set ("applied_env").
applied_env
The names of the environment variables "apply_env" set, sorted.
reload
$context->reload;
Reads everything again that was read from disk: the layout mode, the memory files, the settings (and their env, applied again -- a key the settings no longer carry gets back the value it had before), the enabled plugins, the skill catalogue and the agent catalogue, as /reload in the REPL does. What was decided from the constructor arguments (--claude, claude:, --bare, the explicit skill directories) stays. The nested CLAUDE.md files already handed out in this session are not handed out again. Returns the object.
nested_memory_for
my $text = $context->nested_memory_for('sub/dir/file.txt');
The CLAUDE.md files below "root" on the way to $path that were not handed out before ("nested_for" in Langertha::Raider::Context::Memory), formatted for a tool result; undef when there is none, outside the Claude layout and for a path outside "root".
nested_skills_for
my $text = $context->nested_skills_for('sub/dir/file.txt');
The skills that became available because a tool touched $path, as a note for a tool result ("announce_text" in Langertha::Raider::Context::Skills), or undef for none: the .claude/skills of the directories below "root" on the way to $path (Claude layout only, each looked at once; their skills come after all others and lose a name that is taken), and the skills whose paths: glob matches $path ("activate_for" in Langertha::Raider::Context::Skills). A skill is announced once per session, a reload included. Nothing for a path outside "root", and nothing with "bare".
nested_reminders_for
my @texts = $context->nested_reminders_for($path);
What a tool result gets for touching $path: "nested_memory_for", then "nested_skills_for" -- each its own text, none for what is empty.
report
my $report = $context->report(engine_class => $class, engine_name => 'openai', agent_models => {});
What config explain shows of the context, plain data (JSON-safe):
{
layout => { mode, reason, claude_layout => 0|1, claude_layout_reason,
project_dir => '/abs' | undef },
memory => [ { label, scope, kind, imports => [ '/abs', ... ] }, ... ],
settings => { # only in the Claude layout
files => [ { label, exists => 0|1, error => undef|'...' }, ... ],
permissions => { allow => N, ask => N, deny => N,
additional_directories => N, default_mode => undef|'...' },
env => [ 'NAME', ... ], # names only, never values
enabled_plugins => [ 'name@market', ... ], # enabled ones
hooks => { PreToolUse => N, ... }, # matcher groups per event
ignored => [ { key, source }, ... ],
},
skills => [ { name, source, listed => 0|1,
paths => [ ... ], # only with paths:
kind => 'command' }, ... ], # only for commands
shadowed_skills => [ { name, source, by }, ... ],
skill_problems => [ { file, reason }, ... ],
plugins => [ { name, key, scope }, ... ],
agents => [ { name, source, file, tools, disallowed, model,
skills, missing_skills, missing_reasons, skill_via,
unknown_tools, ignored_keys }, ... ],
shadowed_agents => [ { name, source, file, by }, ... ],
agent_problems => [ { file, reason }, ... ],
}
memory includes the AGENTS.md item. agents, shadowed_agents and agent_problems are "report" in Langertha::Raider::Context::Agents; the arguments go there, for the model each agent would get. Each agent's missing_skills lists the declared skills "skill_resolver" does not resolve: the agent tool refuses to start that agent (ADR 0020 §6). missing_reasons gives, per missing skill, the reason a resolver knows ("why_unresolved" in Langertha::Raider::SkillResolver, e.g. a skilletor template); skill_via, per declared skill resolved beyond the catalogue, where (skilletor:<source>).
SEE ALSO
SUPPORT
Issues
Please report bugs and feature requests at https://github.com/Getty/langertha-raider/issues.
IRC
Join #langertha on irc.perl.org or message Getty directly.
CONTRIBUTING
Contributions are welcome! Please fork the repository and submit a pull request.
AUTHOR
Torsten Raudssus <torsten@raudssus.de> https://raudssus.de/
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by Torsten Raudssus.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.