repomix
Version:
A tool to pack repository contents to single file for AI consumption
187 lines (177 loc) ⢠7.03 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import crypto from 'node:crypto';
import fs from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import { generateTreeString } from '../../core/file/fileTreeGenerate.js';
// Map to store generated output files
const outputFileRegistry = new Map();
// Register an output file
export const registerOutputFile = (id, filePath) => {
outputFileRegistry.set(id, filePath);
};
// Get file path from output ID
export const getOutputFilePath = (id) => {
return outputFileRegistry.get(id);
};
/**
* Creates a temporary directory for MCP tool operations
*/
export const createToolWorkspace = () => __awaiter(void 0, void 0, void 0, function* () {
try {
const tmpBaseDir = path.join(os.tmpdir(), 'repomix', 'mcp-outputs');
yield fs.mkdir(tmpBaseDir, { recursive: true });
const tempDir = yield fs.mkdtemp(`${tmpBaseDir}/`);
return tempDir;
}
catch (error) {
const message = error instanceof Error ? error.message : String(error);
throw new Error(`Failed to create temporary directory: ${message}`);
}
});
/**
* Generate a unique output ID
*/
export const generateOutputId = () => {
return crypto.randomBytes(8).toString('hex');
};
/**
* Creates a result object with metrics information for MCP tools
*/
export const formatPackToolResponse = (context_1, metrics_1, outputFilePath_1, ...args_1) => __awaiter(void 0, [context_1, metrics_1, outputFilePath_1, ...args_1], void 0, function* (context, metrics, outputFilePath, topFilesLen = 5) {
// Generate output ID and register the file
const outputId = generateOutputId();
registerOutputFile(outputId, outputFilePath);
// Calculate total lines from the output file
const outputContent = yield fs.readFile(outputFilePath, 'utf8');
const totalLines = outputContent.split('\n').length;
// Get top files by character count
const topFiles = Object.entries(metrics.fileCharCounts)
.map(([filePath, charCount]) => ({
path: filePath,
charCount,
tokenCount: metrics.fileTokenCounts[filePath] || 0,
}))
.sort((a, b) => b.charCount - a.charCount)
.slice(0, topFilesLen);
// Directory Structure
const directoryStructure = generateTreeString(metrics.safeFilePaths, []);
// Create JSON string with all the metrics information
const jsonResult = JSON.stringify(Object.assign(Object.assign(Object.assign({}, (context.directory ? { directory: context.directory } : {})), (context.repository ? { repository: context.repository } : {})), { outputFilePath,
outputId, metrics: {
totalFiles: metrics.totalFiles,
totalCharacters: metrics.totalCharacters,
totalTokens: metrics.totalTokens,
totalLines,
topFiles,
} }), null, 2);
return buildMcpToolSuccessResponse({
description: `
š Successfully packed codebase!\nPlease review the metrics below and consider adjusting compress/includePatterns/ignorePatterns if the token count is too high and you need to reduce it before reading the file content.
For environments with direct file system access, you can read the file directly using path: ${outputFilePath}
For environments without direct file access (e.g., web browsers or sandboxed apps), use the \`read_repomix_output\` tool with this outputId: ${outputId} to access the packed codebase contents.
The output retrieved with \`read_repomix_output\` has the following structure:
\`\`\`xml
This file is a merged representation of the entire codebase, combining all repository files into a single document.
<file_summary>
(Metadata and usage AI instructions)
</file_summary>
<directory_structure>
src/
cli/
cliOutput.ts
index.ts
(...remaining directories)
</directory_structure>
<files>
<file path="src/index.js">
// File contents here
</file>
(...remaining files)
</files>
<instruction>
(Custom instructions from output.instructionFilePath)
</instruction>
\`\`\`
You can use grep with \`path="<file-path>"\` to locate specific files within the output.
`,
result: jsonResult,
directoryStructure: directoryStructure,
outputId: outputId,
outputFilePath: outputFilePath,
totalFiles: metrics.totalFiles,
totalTokens: metrics.totalTokens,
});
});
export const convertErrorToJson = (error) => {
const timestamp = new Date().toISOString();
if (error instanceof Error) {
return {
errorMessage: error.message,
details: {
stack: error.stack,
name: error.name,
cause: error.cause,
code: 'code' in error
? error.code
: 'errno' in error
? error.errno
: undefined,
timestamp,
type: 'Error',
},
};
}
return {
errorMessage: String(error),
details: {
name: 'UnknownError',
timestamp,
type: 'Unknown',
},
};
};
/**
* Creates a successful MCP tool response with type safety
* @param structuredContent - Object containing both machine-readable data and human-readable description
* @returns CallToolResult with both text and structured content
*/
export const buildMcpToolSuccessResponse = (structuredContent) => {
const textContent = structuredContent !== undefined ? JSON.stringify(structuredContent, null, 2) : 'null';
return {
content: [
{
type: 'text',
text: textContent,
},
],
structuredContent: structuredContent,
};
};
/**
* Creates an error MCP tool response with type safety
* @param structuredContent - Object containing error message and details
* @returns CallToolResult with error flag, text content, and structured content
*/
export const buildMcpToolErrorResponse = (structuredContent) => {
const textContent = structuredContent !== undefined ? JSON.stringify(structuredContent, null, 2) : 'null';
return {
isError: true,
content: [
{
type: 'text',
text: textContent,
},
],
structuredContent: structuredContent,
};
};
//# sourceMappingURL=mcpToolRuntime.js.map