zipRepository() — mcp Function Reference
Architecture documentation for the zipRepository() function in zip-repository.ts from the mcp codebase.
Entity Profile
Dependency Diagram
graph TD 1fd46af5_c3e2_8998_1eb2_098430ff3629["zipRepository()"] 1721f7fd_bb7b_c8c3_9b4b_5677293ae256["resolveOrFetchGraph()"] 1721f7fd_bb7b_c8c3_9b4b_5677293ae256 -->|calls| 1fd46af5_c3e2_8998_1eb2_098430ff3629 9003922a_3c12_9d09_182b_1d8c2e1893be["precacheForDirectory()"] 9003922a_3c12_9d09_182b_1d8c2e1893be -->|calls| 1fd46af5_c3e2_8998_1eb2_098430ff3629 9a818de6_4969_c29c_0dd7_dab4f6d4fbdb["error()"] 1fd46af5_c3e2_8998_1eb2_098430ff3629 -->|calls| 9a818de6_4969_c29c_0dd7_dab4f6d4fbdb d9b9a00b_7ed2_f6c8_1ca7_1e298c76a167["buildIgnoreFilter()"] 1fd46af5_c3e2_8998_1eb2_098430ff3629 -->|calls| d9b9a00b_7ed2_f6c8_1ca7_1e298c76a167 69fc7a46_28f6_6b72_2725_66c381e53322["debug()"] 1fd46af5_c3e2_8998_1eb2_098430ff3629 -->|calls| 69fc7a46_28f6_6b72_2725_66c381e53322 ee32b175_3040_f03e_0439_e4935b9ba1ca["estimateDirectorySize()"] 1fd46af5_c3e2_8998_1eb2_098430ff3629 -->|calls| ee32b175_3040_f03e_0439_e4935b9ba1ca acd13495_08c9_df51_1b17_173570f3e5ea["formatBytes()"] 1fd46af5_c3e2_8998_1eb2_098430ff3629 -->|calls| acd13495_08c9_df51_1b17_173570f3e5ea e5352615_c5fb_64a2_cc5c_a248578cbc8a["warn()"] 1fd46af5_c3e2_8998_1eb2_098430ff3629 -->|calls| e5352615_c5fb_64a2_cc5c_a248578cbc8a 5c9096db_a74b_41f3_ba88_9738d6d799b5["addFilesRecursively()"] 1fd46af5_c3e2_8998_1eb2_098430ff3629 -->|calls| 5c9096db_a74b_41f3_ba88_9738d6d799b5 style 1fd46af5_c3e2_8998_1eb2_098430ff3629 fill:#6366f1,stroke:#818cf8,color:#fff
Relationship Graph
Source Code
src/utils/zip-repository.ts lines 176–340
export async function zipRepository(
directoryPath: string,
options: ZipOptions = {}
): Promise<ZipResult> {
const maxSizeBytes = options.maxSizeBytes || MAX_ZIP_SIZE_BYTES;
// Validate directory exists
try {
const stats = await fs.stat(directoryPath);
if (!stats.isDirectory()) {
const errorMsg = `Path is not a directory: ${directoryPath}`;
logger.error(errorMsg);
throw new Error(errorMsg);
}
} catch (error: any) {
if (error.code === 'ENOENT') {
const errorMsg = `Directory does not exist: ${directoryPath}`;
logger.error(errorMsg);
throw new Error(errorMsg);
}
if (error.code === 'EACCES') {
const errorMsg = `Permission denied accessing directory: ${directoryPath}`;
logger.error(errorMsg);
throw new Error(errorMsg);
}
// Re-throw unknown errors with logging
logger.error('Failed to validate directory:', directoryPath);
logger.error('Error:', error.message);
throw error;
}
// Parse gitignore files
const ignoreFilter = await buildIgnoreFilter(
directoryPath,
options.additionalExclusions,
options.includeGitignore
);
// Estimate directory size before starting ZIP creation
logger.debug('Estimating directory size...');
const estimatedSize = await estimateDirectorySize(directoryPath, ignoreFilter);
logger.debug('Estimated size:', formatBytes(estimatedSize));
// Check if estimated size exceeds limit
if (estimatedSize > maxSizeBytes) {
throw new Error(
`Directory size (${formatBytes(estimatedSize)}) exceeds maximum allowed size (${formatBytes(maxSizeBytes)}). ` +
`Consider excluding more directories or analyzing a subdirectory.`
);
}
// Create temp file path
const tempDir = tmpdir();
const zipFileName = `supermodel-${randomBytes(8).toString('hex')}.zip`;
const zipPath = join(tempDir, zipFileName);
logger.debug('Creating ZIP:', zipPath);
logger.debug('Source directory:', directoryPath);
// Create ZIP archive
let fileCount = 0;
let totalSize = 0;
const output = createWriteStream(zipPath);
const archive = archiver('zip', {
zlib: { level: 6 } // Balanced compression
});
// Track errors
let archiveError: Error | null = null;
archive.on('error', (err) => {
logger.error('Archive error:', err.message);
archiveError = err;
});
archive.on('warning', (err) => {
if (err.code === 'ENOENT') {
logger.warn('File not found (skipping):', err.message);
} else {
logger.warn('Archive warning:', err.message);
}
});
// Track progress
archive.on('entry', (entry) => {
fileCount++;
totalSize += entry.stats?.size || 0;
// Check size limit
if (totalSize > maxSizeBytes) {
const errorMsg =
`ZIP size exceeds limit (${formatBytes(maxSizeBytes)}). ` +
`Current size: ${formatBytes(totalSize)}. ` +
`Consider excluding more directories or analyzing a subdirectory.`;
logger.error(errorMsg);
archive.abort();
archiveError = new Error(errorMsg);
}
});
// Pipe to file
archive.pipe(output);
// Add files recursively with filtering
// Initialize progress state if progress callback is provided
const progressState: ProgressState | undefined = options.onProgress
? { filesProcessed: 0, bytesProcessed: 0, lastReportedCount: 0, lastFile: '' }
: undefined;
await addFilesRecursively(archive, directoryPath, directoryPath, ignoreFilter, options, progressState);
// Finalize archive
await archive.finalize();
// Wait for output stream to finish
await new Promise<void>((resolve, reject) => {
output.on('close', () => {
if (archiveError) {
reject(archiveError);
} else {
resolve();
}
});
output.on('error', (err) => {
logger.error('Output stream error:', err.message);
reject(err);
});
});
// Check for errors during archiving
if (archiveError) {
logger.error('Archiving failed, cleaning up partial ZIP');
// Clean up partial ZIP
await fs.unlink(zipPath).catch(() => {});
throw archiveError;
}
// Get final file size
const zipStats = await fs.stat(zipPath);
const zipSizeBytes = zipStats.size;
logger.debug('ZIP created successfully');
logger.debug('Files included:', fileCount);
logger.debug('ZIP size:', formatBytes(zipSizeBytes));
// Create cleanup function
const cleanup = async () => {
try {
await fs.unlink(zipPath);
logger.debug('Cleaned up ZIP:', zipPath);
} catch (error: any) {
if (error.code !== 'ENOENT') {
logger.warn('Failed to cleanup ZIP:', error.message);
}
}
};
return {
path: zipPath,
cleanup,
fileCount,
sizeBytes: zipSizeBytes,
};
}
Domain
Subdomains
Calls
Source
Frequently Asked Questions
What does zipRepository() do?
zipRepository() is a function in the mcp codebase.
What does zipRepository() call?
zipRepository() calls 7 function(s): addFilesRecursively, buildIgnoreFilter, debug, error, estimateDirectorySize, formatBytes, warn.
What calls zipRepository()?
zipRepository() is called by 2 function(s): precacheForDirectory, resolveOrFetchGraph.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free