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 a dir spec naming a file); { type => 'dir', path, glob } a directory of flat *.md skills; { type => 'dir', path } without glob (--skills DIR, a string in skills:) 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.

https://raudssus.de/