Skip to content

Project context

Before the first prompt, malac reads what the project says about itself, so a new session starts out knowing the rules, the layout and what earlier sessions learned. That context has four parts:

Part Where Who writes it
Instruction files AGENTS.md, and the files other agents use You
Docs map README, docs/** and the like, one line each You
Project index .malac/index.md, regenerated, not committed malac, without a model
Project knowledge .malac/MALAC.md, committed malac, as it learns

/context in a session, or malac context in a shell, shows everything that was loaded and why anything was skipped. See what was loaded.

Context is read when a tab loads. After changing instruction files, open a new tab for the folder (Ctrl+T in the terminal UI), or run malac daemon restart.

malac reads the instruction files of every agent you might have used in a repository, so you don’t have to translate them. They come from ~/.malac/ (AGENTS.md, MALAC.md, CLAUDE.md), from ~/.claude/CLAUDE.md, and from every directory between the repository root and the working directory:

File Written for
AGENTS.md The open standard, read first
MALAC.md malac
CLAUDE.md, CLAUDE.local.md Claude Code
GEMINI.md Gemini CLI
.github/copilot-instructions.md, .github/instructions/*.instructions.md GitHub Copilot
.cursorrules, .cursor/rules/*.mdc Cursor
.windsurfrules, .windsurf/rules/*.md Windsurf
.clinerules, .clinerules/ Cline

[context] instruction_files adds more, after these. A project config may name only files inside the project.

  • Read once. A file whose text another one already has is skipped, so a CLAUDE.md symlinked to (or copied from) AGENTS.md costs nothing.
  • Imports. A line that is only @path, as CLAUDE.md and GEMINI.md use, pulls in that file when it is inside the project.
  • Rules apply as their tool defines them. A Cursor rule with alwaysApply: true goes into the prompt. One with globs (or a Copilot file with applyTo, a Windsurf rule with trigger: glob) is listed with its patterns, and the agent reads it before touching matching files. One with only a description is listed for the agent to read when it fits.
  • A budget. All instruction files together get 40,000 characters (max_instruction_chars). When they need more, configured files and AGENTS.md keep their text first, then MALAC.md, CLAUDE.md, GEMINI.md, Copilot’s, Cursor’s, Windsurf’s and Cline’s, and deeper directories before shallower ones. The rest is cut from the middle or skipped, and /context says so.

Use AGENTS.md for instructions. It is the format most coding agents read, so one file serves malac and your teammates’ agents alike. If someone on the team uses Claude Code, make CLAUDE.md a symlink to it rather than a second copy:

ln -s AGENTS.md CLAUDE.md

Keep it short and concrete: the commands to build and test, where things are, the conventions the code does not make obvious, and what not to touch.

AGENTS.md
- Build with `cargo build`; run `cargo clippy --all-targets` and `cargo test` before calling a change done.
- The HTTP handlers are in `crates/server/src/api/`; the database layer is `crates/store`.
- Never edit files under `vendor/` or generated code in `src/gen/`.
- Commit messages: imperative mood, no trailing period.

A part of the repository with its own rules gets its own AGENTS.md, which applies when malac works in that folder, on top of the root’s.

malac lists the project’s Markdown docs in the prompt: the README, ARCHITECTURE, CONTRIBUTING, docs/** and decision records, each with its path, title and first sentence. The agent knows where to look without reading them all. [context] docs = false turns the map off.

.malac/index.md maps the repository without a model:

  • the directory tree with file counts and languages,
  • manifests with their package names, workspace members and scripts, and the entry points,
  • the top-level symbols of every source file, for Rust, TypeScript and JavaScript, Python, Go, Java, Kotlin, Swift, C#, C and C++, Ruby, PHP, shell, Elixir and Lua,
  • the headings of the Markdown files,
  • a Notes section, where agents record where something lives or how parts connect, for the next session.

The agent reads it through the project_index tool before searching broadly, which saves a round of grep in every new session. The index follows .gitignore, rereads only files whose modification time or size changed, and refreshes in the background when a session starts and it is more than five minutes old. Regenerating it keeps the Notes.

malac index # update it now
malac index --rebuild # from scratch
malac index --print # and print it

The index and its cache (.malac/index.cache.json) can be regenerated at any time, so malac writes a .malac/.gitignore that keeps them out of git. It is built only inside a repository; [context] index = false turns it off, and index_max_files (5,000) caps how many files’ symbols it lists.

.malac/MALAC.md is what malac learned about the project: how to build, test and run it, its conventions, the gotchas and the decisions behind them. Each entry is a project memory in .malac/memory/, saved with a kind, and MALAC.md lists them by kind:

# Project knowledge
What malac has learned about this project: …
<!-- malac:memories (generated from memory/; edit those files or ask malac) -->
## Commands
- **integration-tests** — integration tests need `docker compose up -d db` first
## Gotchas
- **migrations-order** — migrations run in file-name order, so new ones need a later timestamp
<!-- /malac:memories -->

malac rewrites the part between the markers when it saves or forgets a memory; text outside them is yours and stays. Commit both .malac/MALAC.md and .malac/memory/: the knowledge then reaches your other machines and your teammates with the next pull.

Knowledge is not instructions. malac keeps MALAC.md itself, but it does not write AGENTS.md unasked; when it learns something that belongs there, it proposes the change. Structured project settings go in .malac/config.toml, plugins in .malac/plugins.toml. [context] knowledge = false leaves MALAC.md out of the prompt.

When the working directory is one part of a larger repository, say frontend/ with backend/ and infra/ beside it, the agent is told so and given the other parts. It reads and changes them when the task reaches them, such as an API both sides use, and suggests opening the repository root when the task is really about the whole stack. The VS Code extension offers the root when you open a folder inside a larger repository, and clients get the same hint from the daemon as project.suggest_root in the protocol.

For work across the stack, open the root. A subdirectory still sees the root’s instruction files, index and knowledge. A layout that works well:

shop/
├── AGENTS.md shared commands and conventions
├── .malac/
│ ├── MALAC.md project knowledge, committed
│ └── memory/
├── frontend/
│ └── AGENTS.md the frontend's own rules
├── backend/
│ └── AGENTS.md
└── infra/

One repository, one folder per part, an AGENTS.md at the root for what every part shares and one per part for the rest. A tab at shop/ then sees everything, and a tab at shop/frontend/ sees the root’s rules plus the frontend’s.

/context answers without a model call. malac context prints the same in a shell, --json as JSON, and --cwd <dir> for another folder:

  • where the directory sits in its repository,
  • the instruction files loaded, with their size and whether they were cut, the rules listed for later, and the files skipped and why,
  • the docs map, the index and MALAC.md,
  • the skills, slash commands, agent types and plugins in use,
  • warnings, such as a plugin whose hooks are not approved yet.

The agent sees the same report through malac_settings (show: "context").

[context]
instruction_files = ["docs/agent-rules.md"] # more instruction files
max_instruction_chars = 40000
docs = true
index = true
index_max_files = 5000
knowledge = true

See [context] in the configuration reference.

malac is created by lobirus and released under the MIT license. About malac