Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 16 additions & 15 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
"tinypool": "^2.0.0",
"tree-sitter-wasms": "^0.1.13",
"web-tree-sitter": "^0.25.10",
"zod": "^3.25.76"
"zod": "^4.1.12"
},
"devDependencies": {
"@biomejs/biome": "^2.2.6",
Expand Down
38 changes: 25 additions & 13 deletions src/config/configLoad.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,26 +157,33 @@ export const mergeConfigs = (

const baseConfig = defaultConfig;

// If the output file path is not provided in the config file or CLI, use the default file path for the style
if (cliConfig.output?.filePath == null && fileConfig.output?.filePath == null) {
const style = cliConfig.output?.style || fileConfig.output?.style || baseConfig.output.style;
baseConfig.output.filePath = defaultFilePathMap[style];

logger.trace('Default output file path is set to:', baseConfig.output.filePath);
}

const mergedConfig = {
cwd,
input: {
...baseConfig.input,
...fileConfig.input,
...cliConfig.input,
},
output: {
...baseConfig.output,
...fileConfig.output,
...cliConfig.output,
},
output: (() => {
const mergedOutput = {
...baseConfig.output,
...fileConfig.output,
...cliConfig.output,
git: {
...baseConfig.output.git,
...fileConfig.output?.git,
...cliConfig.output?.git,
},
};

if (mergedOutput.filePath == null) {
const style = mergedOutput.style ?? baseConfig.output.style;
mergedOutput.filePath = defaultFilePathMap[style];
logger.trace('Default output file path is set to:', mergedOutput.filePath);
}

return mergedOutput;
})(),
include: [...(baseConfig.include || []), ...(fileConfig.include || []), ...(cliConfig.include || [])],
ignore: {
...baseConfig.ignore,
Expand All @@ -193,6 +200,11 @@ export const mergeConfigs = (
...fileConfig.security,
...cliConfig.security,
},
tokenCount: {
...baseConfig.tokenCount,
...fileConfig.tokenCount,
...cliConfig.tokenCount,
},
};

try {
Expand Down
120 changes: 59 additions & 61 deletions src/config/configSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,67 +74,55 @@ export const repomixConfigBaseSchema = z.object({

// Default config schema with default values
export const repomixConfigDefaultSchema = z.object({
input: z
.object({
maxFileSize: z
.number()
.int()
.min(1)
.default(50 * 1024 * 1024), // Default: 50MB
})
.default({}),
output: z
.object({
filePath: z.string().default(defaultFilePathMap.xml),
style: repomixOutputStyleSchema.default('xml'),
parsableStyle: z.boolean().default(false),
headerText: z.string().optional(),
instructionFilePath: z.string().optional(),
fileSummary: z.boolean().default(true),
directoryStructure: z.boolean().default(true),
files: z.boolean().default(true),
removeComments: z.boolean().default(false),
removeEmptyLines: z.boolean().default(false),
compress: z.boolean().default(false),
topFilesLength: z.number().int().min(0).default(5),
showLineNumbers: z.boolean().default(false),
truncateBase64: z.boolean().default(false),
copyToClipboard: z.boolean().default(false),
includeEmptyDirectories: z.boolean().optional(),
includeFullDirectoryStructure: z.boolean().default(false),
tokenCountTree: z.union([z.boolean(), z.number(), z.string()]).default(false),
git: z
.object({
sortByChanges: z.boolean().default(true),
sortByChangesMaxCommits: z.number().int().min(1).default(100),
includeDiffs: z.boolean().default(false),
includeLogs: z.boolean().default(false),
includeLogsCount: z.number().int().min(1).default(50),
})
.default({}),
})
.default({}),
input: z.object({
maxFileSize: z
.number()
.int()
.min(1)
.default(50 * 1024 * 1024), // Default: 50MB
}),
output: z.object({
filePath: z.string().default(defaultFilePathMap.xml),
style: repomixOutputStyleSchema.default('xml'),
parsableStyle: z.boolean().default(false),
headerText: z.string().optional(),
instructionFilePath: z.string().optional(),
fileSummary: z.boolean().default(true),
directoryStructure: z.boolean().default(true),
files: z.boolean().default(true),
removeComments: z.boolean().default(false),
removeEmptyLines: z.boolean().default(false),
compress: z.boolean().default(false),
topFilesLength: z.number().int().min(0).default(5),
showLineNumbers: z.boolean().default(false),
truncateBase64: z.boolean().default(false),
copyToClipboard: z.boolean().default(false),
includeEmptyDirectories: z.boolean().optional(),
includeFullDirectoryStructure: z.boolean().default(false),
tokenCountTree: z.union([z.boolean(), z.number(), z.string()]).default(false),
git: z.object({
sortByChanges: z.boolean().default(true),
sortByChangesMaxCommits: z.number().int().min(1).default(100),
includeDiffs: z.boolean().default(false),
includeLogs: z.boolean().default(false),
includeLogsCount: z.number().int().min(1).default(50),
}),
}),
include: z.array(z.string()).default([]),
ignore: z
.object({
useGitignore: z.boolean().default(true),
useDefaultPatterns: z.boolean().default(true),
customPatterns: z.array(z.string()).default([]),
})
.default({}),
security: z
.object({
enableSecurityCheck: z.boolean().default(true),
})
.default({}),
tokenCount: z
.object({
encoding: z
.string()
.default('o200k_base')
.transform((val) => val as TiktokenEncoding),
})
.default({}),
ignore: z.object({
useGitignore: z.boolean().default(true),
useDefaultPatterns: z.boolean().default(true),
customPatterns: z.array(z.string()).default([]),
}),
security: z.object({
enableSecurityCheck: z.boolean().default(true),
}),
tokenCount: z.object({
encoding: z
.string()
.default('o200k_base')
.transform((val) => val as TiktokenEncoding),
}),
});

// File-specific schema. Add options for file path and style
Expand Down Expand Up @@ -166,7 +154,17 @@ export type RepomixConfigFile = z.infer<typeof repomixConfigFileSchema>;
export type RepomixConfigCli = z.infer<typeof repomixConfigCliSchema>;
export type RepomixConfigMerged = z.infer<typeof repomixConfigMergedSchema>;

export const defaultConfig = repomixConfigDefaultSchema.parse({});
// Pass empty objects to let Zod apply all default values
// Zod v4 requires explicit nested objects since we removed outer .default({})
export const defaultConfig = repomixConfigDefaultSchema.parse({
input: {},
output: {
git: {},
},
ignore: {},
security: {},
tokenCount: {},
});
Comment thread
yamadashy marked this conversation as resolved.

// Helper function for type-safe config definition
export const defineConfig = (config: RepomixConfigFile): RepomixConfigFile => config;
6 changes: 5 additions & 1 deletion src/mcp/prompts/packRemoteRepositoryPrompts.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
// @ts-nocheck - Zod v3 compatibility for MCP SDK (imported by mcpAction.ts)
// Note: @ts-expect-error would be preferable, but the type incompatibility extends
// beyond .shape to the entire handler function signature, causing 9+ type errors per file.
// This will be resolved when MCP SDK supports Zod v4.
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';
import { z } from 'zod/v3';

/**
* Register Repomix-related prompts to the MCP server
Expand Down
12 changes: 9 additions & 3 deletions src/mcp/tools/attachPackedOutputTool.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
// @ts-nocheck - Zod v3 compatibility for MCP SDK (imported by mcpAction.ts)
// Note: @ts-expect-error would be preferable, but the type incompatibility extends
// beyond .shape to the entire handler function signature, causing 9+ type errors per file.
// This will be resolved when MCP SDK supports Zod v4.
import fs from 'node:fs/promises';
import path from 'node:path';
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
import { z } from 'zod';
import { z } from 'zod/v3';
import { defaultFilePathMap } from '../../config/configSchema.js';
import type { ProcessedFile } from '../../core/file/fileTypes.js';
import {
Expand Down Expand Up @@ -255,8 +259,10 @@ This tool accepts either a directory containing a repomix output file or a direc
Supports multiple formats: XML (structured with <file> tags), Markdown (human-readable with ## headers and code blocks), JSON (machine-readable with files as key-value pairs), and Plain text (simple format with separators).
Calling the tool again with the same file path will refresh the content if the file has been updated.
It will return in that case a new output ID and the updated content.`,
inputSchema: attachPackedOutputInputSchema.shape,
outputSchema: attachPackedOutputOutputSchema.shape,
// biome-ignore lint/suspicious/noExplicitAny: Zod v3 compatibility for MCP SDK
inputSchema: attachPackedOutputInputSchema.shape as any,
// biome-ignore lint/suspicious/noExplicitAny: Zod v3 compatibility for MCP SDK
outputSchema: attachPackedOutputOutputSchema.shape as any,
annotations: {
readOnlyHint: true,
destructiveHint: false,
Expand Down
12 changes: 9 additions & 3 deletions src/mcp/tools/fileSystemReadDirectoryTool.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
// @ts-nocheck - Zod v3 compatibility for MCP SDK (imported by mcpAction.ts)
// Note: @ts-expect-error would be preferable, but the type incompatibility extends
// beyond .shape to the entire handler function signature, causing 9+ type errors per file.
// This will be resolved when MCP SDK supports Zod v4.
import fs from 'node:fs/promises';
import path from 'node:path';
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
import { z } from 'zod';
import { z } from 'zod/v3';
import { logger } from '../../shared/logger.js';
import { buildMcpToolErrorResponse, buildMcpToolSuccessResponse } from './mcpToolRuntime.js';

Expand All @@ -28,8 +32,10 @@ export const registerFileSystemReadDirectoryTool = (mcpServer: McpServer) => {
title: 'Read Directory',
description:
'List the contents of a directory using an absolute path. Returns a formatted list showing files and subdirectories with clear [FILE]/[DIR] indicators. Useful for exploring project structure and understanding codebase organization.',
inputSchema: fileSystemReadDirectoryInputSchema.shape,
outputSchema: fileSystemReadDirectoryOutputSchema.shape,
// biome-ignore lint/suspicious/noExplicitAny: Zod v3 compatibility for MCP SDK
inputSchema: fileSystemReadDirectoryInputSchema.shape as any,
// biome-ignore lint/suspicious/noExplicitAny: Zod v3 compatibility for MCP SDK
outputSchema: fileSystemReadDirectoryOutputSchema.shape as any,
annotations: {
readOnlyHint: true,
destructiveHint: false,
Expand Down
Loading
Loading