ExternalConfigs.Catalog (fnord v0.9.29)

View Source

Builds the external-configs section of the coordinator's system prompt.

Emits a single combined "available skills" message that groups:

  • fnord's own enabled skills (via Skills.list_enabled/0)
  • project-enabled Cursor skills
  • project-enabled Claude Code skills

Also emits a compact "available Cursor rules" listing covering modes other than :always (agent-requested and auto-attached rules), plus one full-body message per :always rule.

All messages are system-role messages; they are filtered out when the conversation is persisted to disk (see Services.Conversation).

Summary

Functions

Build all prompt messages for the current project's external configs. Returns an ordered list of system-message strings, each intended to be appended to the conversation as its own system message.

Build all prompt messages for the given project. Same shape as build_messages/0, but skips the Store.get_project/0 lookup. Intended for callers that already have the project in hand (tests, the injector's matching path).

Render the system-message body that is injected when an auto-attached rule matches a file the model has just read or written. Includes the triggering file's path so the model can cite it back to the user.

Convenience wrapper: build_messages/0 with each string already wrapped as a system-role message. Intended for sub-agents that build their own messages list and need to inherit the external-configs catalog so their LLM call knows about the parent session's enabled sources.

Types

skills_section()

@type skills_section() ::
  {String.t(), [%{name: String.t(), description: String.t() | nil}]}

Functions

build_messages()

@spec build_messages() :: [String.t()]

Build all prompt messages for the current project's external configs. Returns an ordered list of system-message strings, each intended to be appended to the conversation as its own system message.

Safe when no project is selected, when the project has source_root = nil, or when no toggles are enabled; in those cases it returns [].

build_messages(project)

@spec build_messages(Store.Project.t()) :: [String.t()]

Build all prompt messages for the given project. Same shape as build_messages/0, but skips the Store.get_project/0 lookup. Intended for callers that already have the project in hand (tests, the injector's matching path).

render_auto_attached_rule(rule, file_path)

@spec render_auto_attached_rule(ExternalConfigs.CursorRule.t(), String.t()) ::
  String.t()

Render the system-message body that is injected when an auto-attached rule matches a file the model has just read or written. Includes the triggering file's path so the model can cite it back to the user.

system_messages()

@spec system_messages() :: [map()]

Convenience wrapper: build_messages/0 with each string already wrapped as a system-role message. Intended for sub-agents that build their own messages list and need to inherit the external-configs catalog so their LLM call knows about the parent session's enabled sources.

Sub-agents get the same skills catalog, cursor rules catalog listing, and always-apply rule bodies the coordinator got at its own bootstrap. They do NOT inherit mid-stream auto-attach injections from the parent conversation; those live in Services.Conversation which sub-agents don't read from. The rule bodies remain reachable via the paths listed in the catalog.