Memory files
Break down large AGENTS.md files into smaller, reusable components using a simple import syntax.
Overview
| Feature | Description | Benefit |
|---|---|---|
| File imports | Include content from other files | Organize complex context files |
| Path flexibility | Support for relative and absolute paths | Work with any file structure |
| Nested imports | Files can import other files | Create hierarchical structures |
| Safety features | Circular import detection and security checks | Prevent common problems |
Why use memory imports
- Maintainability: Break large context files into logical, focused components
- Reusability: Share common instructions across multiple projects
- Organization: Create a clear hierarchy of context information
- Collaboration: Enable team members to work on different parts of context files
- Versioning: Track changes to individual components more effectively
Basic usage
Import syntax
Use the @ symbol followed by the path to the file you want to import:
# Main AGENTS.md file
This is the main content.
@./components/instructions.md
More content here.
@./shared/configuration.mdSupported path formats
| Path Format | Example | Description |
|---|---|---|
| Same directory | @./file.md | Import from current directory |
| Parent directory | @../file.md | Import from parent directory |
| Subdirectory | @./components/file.md | Import from nested directory |
| Absolute path | @/absolute/path/to/file.md | Import using full path |
Working with imports
Basic import example
# My AGENTS.md
Welcome to my project!
@./getting-started.md
## Features
@./features/overview.mdNested imports
Files can import other files, creating a hierarchical structure:
# main.md
@./header.md
@./content.md
@./footer.mdWhere header.md might contain:
# Project Header
@./shared/title.mdThis creates a tree structure of imports:
main.md
├── header.md
│ └── shared/title.md
├── content.md
└── footer.mdSafety features
The memory import processor includes several safety mechanisms to prevent common issues:
Circular import detection
The processor automatically detects and prevents circular imports. If file-a.md imports file-b.md and file-b.md tries to import file-a.md, the processor detects this circular reference and prevents it.
Example circular import:
file-a.md
↓
file-b.md
↓
file-a.md (circular - blocked)File access security
The validateImportPath function ensures that imports are only allowed from specified directories, preventing access to sensitive files outside the allowed scope.
Maximum import depth
To prevent infinite recursion, the processor has a configurable maximum import depth (default: 5 levels). Imports can be nested up to 5 levels deep.
Error handling
The processor handles common errors gracefully:
Missing files
If a referenced file doesn't exist, the import will fail with an error comment in the output:
<!-- Error importing ./non-existent-file.md: File not found -->File access errors
Permission issues or other file system errors are handled with appropriate error messages:
<!-- Error importing ./protected-file.md: Permission denied -->Advanced features
Code region detection
The import processor uses the marked library to detect code blocks and inline code spans, ensuring that @ imports inside code regions are ignored:
# My document
This is a real import:
@./real-import.md
```markdown
# Code example
This is not a real import:
@./fake-import.md
### Import tree visualization
The processor generates an import tree that shows the hierarchy of imported files. This tree preserves the order of imports and shows the complete import chain for debugging purposes.
**Example import tree:**
```text
Memory Files
└── project: AGENTS.md
├── components/instructions.md
│ └── components/common/header.md
└── shared/configuration.md
└── shared/settings/defaults.mdComparison with /memory command
| Feature | Memory Import Processor | /memory Command |
|---|---|---|
| Structure | Hierarchical tree | Flat, linear document |
| File boundaries | Seamless integration | Marked with comments |
| Import syntax | @./path/to/file.md | N/A (loads all AGENTS.md files) |
| Control | Fine-grained inclusion | Automatic directory scanning |
| Primary use | Modular context files | Project-wide context |
API reference
Core functions
processImports()
async function processImports(
content: string,
basePath: string,
debugMode?: boolean,
importState?: ImportState
): Promise<ProcessImportsResult>Processes import statements in AGENTS.md content.
Parameters:
content: The content to process for importsbasePath: The directory path where the current file is locateddebugMode: Whether to enable debug logging (default: false)importState: State tracking for circular import prevention
Returns: Object containing processed content and import tree
validateImportPath()
function validateImportPath(
importPath: string,
basePath: string,
allowedDirectories: string[]
): booleanValidates import paths to ensure they are safe and within allowed directories.
Parameters:
importPath: The import path to validatebasePath: The base directory for resolving relative pathsallowedDirectories: Array of allowed directory paths
Returns: Whether the import path is valid
findProjectRoot()
async function findProjectRoot(startDir: string): Promise<string>Finds the project root by searching for a .git directory upwards from the given start directory.
Parameters:
startDir: The directory to start searching from
Returns: The project root directory (or the start directory if no .git is found)
Interface definitions
interface ProcessImportsResult {
content: string; // The processed content with imports resolved
importTree: MemoryFile; // Tree structure showing the import hierarchy
}
interface MemoryFile {
path: string; // The file path
imports?: MemoryFile[]; // Direct imports, in the order they were imported
}Best practices
Organization strategies
- Use descriptive file names that clearly indicate the content's purpose
- Create a logical folder structure for your imported files
- Keep imports shallow - avoid deeply nested import chains when possible
- Document your structure with comments explaining the import hierarchy
- Use relative paths when possible for better portability between environments
Performance considerations
- Minimize the number of imports to reduce processing time
- Keep individual files focused on specific topics or components
- Test your imports regularly to ensure all referenced files exist and are accessible
- Consider caching for frequently used but rarely changed imports
Troubleshooting
Common issues
| Issue | Possible Causes | Solution |
|---|---|---|
| Import not working | File doesn't exist or path is incorrect | Verify file path and existence |
| Circular import warnings | Files importing each other | Restructure your imports to avoid cycles |
| Permission errors | Files not readable | Check file permissions |
| Path resolution issues | Relative path confusion | Try using absolute paths |
Debugging techniques
Enable debug mode to see detailed logging of the import process:
const result = await processImports(content, basePath, true);This outputs detailed information about:
- Files being processed
- Import paths being resolved
- Circular references detected
- Error conditions encountered