Memory files

Break down large AGENTS.md files into smaller, reusable components using a simple import syntax.

Overview

FeatureDescriptionBenefit
File importsInclude content from other filesOrganize complex context files
Path flexibilitySupport for relative and absolute pathsWork with any file structure
Nested importsFiles can import other filesCreate hierarchical structures
Safety featuresCircular import detection and security checksPrevent 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.md

Supported path formats

Path FormatExampleDescription
Same directory@./file.mdImport from current directory
Parent directory@../file.mdImport from parent directory
Subdirectory@./components/file.mdImport from nested directory
Absolute path@/absolute/path/to/file.mdImport using full path

Working with imports

Basic import example

# My AGENTS.md

Welcome to my project!

@./getting-started.md

## Features

@./features/overview.md

Nested imports

Files can import other files, creating a hierarchical structure:

# main.md

@./header.md
@./content.md
@./footer.md

Where header.md might contain:

# Project Header

@./shared/title.md

This creates a tree structure of imports:

main.md
 ├── header.md
 │    └── shared/title.md
 ├── content.md
 └── footer.md

Safety 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.md

Comparison with /memory command

FeatureMemory Import Processor/memory Command
StructureHierarchical treeFlat, linear document
File boundariesSeamless integrationMarked with comments
Import syntax@./path/to/file.mdN/A (loads all AGENTS.md files)
ControlFine-grained inclusionAutomatic directory scanning
Primary useModular context filesProject-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 imports
  • basePath: The directory path where the current file is located
  • debugMode: 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[]
): boolean

Validates import paths to ensure they are safe and within allowed directories.

Parameters:

  • importPath: The import path to validate
  • basePath: The base directory for resolving relative paths
  • allowedDirectories: 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

IssuePossible CausesSolution
Import not workingFile doesn't exist or path is incorrectVerify file path and existence
Circular import warningsFiles importing each otherRestructure your imports to avoid cycles
Permission errorsFiles not readableCheck file permissions
Path resolution issuesRelative path confusionTry 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
How is this topic?