Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 92 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -995,12 +995,84 @@ When running as an MCP server, Repomix provides the following tools:

## ⚙️ Configuration

Create a `repomix.config.json` file in your project root for custom configurations.
Repomix supports multiple configuration file formats for flexibility and ease of use.

### Configuration File Formats

Repomix will automatically search for configuration files in the following priority order:

1. **TypeScript** (`repomix.config.ts`, `repomix.config.mts`, `repomix.config.cts`)
2. **JavaScript/ES Module** (`repomix.config.js`, `repomix.config.mjs`, `repomix.config.cjs`)
3. **JSON** (`repomix.config.json5`, `repomix.config.jsonc`, `repomix.config.json`)

#### JSON Configuration

Create a `repomix.config.json` file in your project root:

```bash
repomix --init
```

This will create a `repomix.config.json` file with default settings.

#### TypeScript Configuration

TypeScript configuration files provide the best developer experience with full type checking and IDE support.

**Installation:**

To use TypeScript or JavaScript configuration with `defineConfig`, you need to install Repomix as a dev dependency:

```bash
npm install -D repomix
```

**Example:**

```typescript
// repomix.config.ts
import { defineConfig } from 'repomix';

export default defineConfig({
output: {
filePath: 'output.xml',
style: 'xml',
removeComments: true,
},
ignore: {
customPatterns: ['**/node_modules/**', '**/dist/**'],
},
});
```

**Benefits:**
- ✅ Full TypeScript type checking in your IDE
- ✅ Excellent IDE autocomplete and IntelliSense
- ✅ Use dynamic values (timestamps, environment variables, etc.)

**Dynamic Values Example:**

```typescript
// repomix.config.ts
import { defineConfig } from 'repomix';

// Generate timestamp-based filename
const timestamp = new Date().toISOString().slice(0, 19).replace(/[:.]/g, '-');

export default defineConfig({
output: {
filePath: `output-${timestamp}.xml`,
style: 'xml',
},
});
```

#### JavaScript Configuration

JavaScript configuration files work the same as TypeScript, supporting `defineConfig` and dynamic values.

### Configuration Options

Here's an explanation of the configuration options:

| Option | Description | Default |
Expand Down Expand Up @@ -1041,10 +1113,29 @@ The configuration file supports [JSON5](https://json5.org/) syntax, which allows
- Unquoted property names
- More relaxed string syntax

### Schema Validation

You can enable schema validation for your configuration file by adding the `$schema` property:

```json
{
"$schema": "https://repomix.com/schemas/latest/schema.json",
"output": {
"filePath": "repomix-output.xml",
"style": "xml"
}
}
```

This provides auto-completion and validation in editors that support JSON schema.

### Example Configuration

Example configuration:

```json5
{
"$schema": "https://repomix.com/schemas/latest/schema.json",
"input": {
"maxFileSize": 50000000
},
Expand Down
17 changes: 10 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
"handlebars": "^4.7.8",
"iconv-lite": "^0.7.0",
"istextorbinary": "^9.5.0",
"jiti": "^2.6.1",
"jschardet": "^3.1.4",
"json5": "^2.2.3",
"log-update": "^7.0.1",
Expand Down
44 changes: 0 additions & 44 deletions repomix.config.json

This file was deleted.

60 changes: 60 additions & 0 deletions repomix.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Note: Normally you would import from 'repomix', but since this is the repomix project itself,
// we import directly from the source index file.
// For your projects, use: import { defineConfig } from 'repomix';
import { defineConfig } from './src/index.js';

export default defineConfig({
input: {
maxFileSize: 50000000,
},
output: {
filePath: 'repomix-output.xml',
style: 'xml',
parsableStyle: false,
compress: false,
headerText: `This repository contains the source code for the Repomix tool.
Repomix is designed to pack repository contents into a single file,
making it easier for AI systems to analyze and process the codebase.

Key Features:
- Configurable ignore patterns
- Custom header text support
- Efficient file processing and packing

Please refer to the README.md file for more detailed information on usage and configuration.
`,
instructionFilePath: 'repomix-instruction.md',
fileSummary: true,
directoryStructure: true,
files: true,
removeComments: false,
removeEmptyLines: false,
topFilesLength: 5,
showLineNumbers: false,
includeEmptyDirectories: true,
truncateBase64: true,
// Display token count tree for files/directories with 50000+ tokens
// Can be boolean (true/false) or number (minimum token threshold)
tokenCountTree: 50000,
git: {
sortByChanges: true,
sortByChangesMaxCommits: 100,
includeDiffs: true,
includeLogs: true,
includeLogsCount: 50,
},
},
include: [],
ignore: {
useGitignore: true,
useDefaultPatterns: true,
// ignore is specified in .repomixignore
customPatterns: [],
},
security: {
enableSecurityCheck: true,
},
tokenCount: {
encoding: 'o200k_base',
},
});
56 changes: 52 additions & 4 deletions src/config/configLoad.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import * as fs from 'node:fs/promises';
import path from 'node:path';
import { pathToFileURL } from 'node:url';
import { createJiti } from 'jiti';
import JSON5 from 'json5';
import pc from 'picocolors';
import { RepomixError, rethrowValidationErrorIfZodError } from '../shared/errorHandle.js';
Expand All @@ -15,7 +17,17 @@ import {
} from './configSchema.js';
import { getGlobalDirectory } from './globalDirectory.js';

const defaultConfigPaths = ['repomix.config.json5', 'repomix.config.jsonc', 'repomix.config.json'];
const defaultConfigPaths = [
'repomix.config.ts',
'repomix.config.mts',
'repomix.config.cts',
'repomix.config.js',
'repomix.config.mjs',
'repomix.config.cjs',
'repomix.config.json5',
'repomix.config.jsonc',
'repomix.config.json',
];

const getGlobalConfigPaths = () => {
const globalDir = getGlobalDirectory();
Expand Down Expand Up @@ -83,15 +95,51 @@ export const loadFileConfig = async (rootDir: string, argConfigPath: string | nu
return {};
};

const getFileExtension = (filePath: string): string => {
const match = filePath.match(/\.(ts|mts|cts|js|mjs|cjs|json5|jsonc|json)$/);
return match ? match[1] : '';
};

const loadAndValidateConfig = async (filePath: string): Promise<RepomixConfigFile> => {
try {
const fileContent = await fs.readFile(filePath, 'utf-8');
const config = JSON5.parse(fileContent);
let config: unknown;
const ext = getFileExtension(filePath);

switch (ext) {
case 'ts':
case 'mts':
case 'cts':
case 'js':
case 'mjs':
case 'cjs': {
// Use jiti for TypeScript and JavaScript files
// This provides consistent behavior and avoids Node.js module cache issues
const jiti = createJiti(import.meta.url, {
moduleCache: false, // Disable cache to ensure fresh config loads
interopDefault: true, // Automatically use default export
});
config = await jiti.import(pathToFileURL(filePath).href);
break;
}

case 'json5':
case 'jsonc':
case 'json': {
// Use JSON5 for JSON/JSON5/JSONC files
const fileContent = await fs.readFile(filePath, 'utf-8');
config = JSON5.parse(fileContent);
break;
}

default:
throw new RepomixError(`Unsupported config file format: ${filePath}`);
}

return repomixConfigFileSchema.parse(config);
} catch (error) {
rethrowValidationErrorIfZodError(error, 'Invalid config schema');
if (error instanceof SyntaxError) {
throw new RepomixError(`Invalid JSON5 in config file ${filePath}: ${error.message}`);
throw new RepomixError(`Invalid syntax in config file ${filePath}: ${error.message}`);
}
if (error instanceof Error) {
throw new RepomixError(`Error loading config from ${filePath}: ${error.message}`);
Expand Down
3 changes: 3 additions & 0 deletions src/config/configSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,6 @@ export type RepomixConfigCli = z.infer<typeof repomixConfigCliSchema>;
export type RepomixConfigMerged = z.infer<typeof repomixConfigMergedSchema>;

export const defaultConfig = repomixConfigDefaultSchema.parse({});

// Helper function for type-safe config definition
export const defineConfig = (config: RepomixConfigFile): RepomixConfigFile => config;
Loading
Loading