UNPKG

file-concat-tool

Version:

A tool for generating context windows for AI prompting by recursively searching for .ts and .tsx files and concatenating their contents into a text file.

116 lines (100 loc) 3.9 kB
#!/usr/bin/env node const fs = require("fs"); const path = require("path"); const chalk = require("chalk"); /** * Recursively searches the root directory for source files with specified extensions, * while ignoring the "node_modules" directory and files containing "config" in their name. * * @param {string} rootDir - The directory to search in. * @returns {string[]} - An array of found file paths. */ function findSourceFiles(rootDir) { const filesList = []; const allowedExtensions = [ '.ts', '.tsx', // TypeScript '.js', '.jsx', // JavaScript '.html', // HTML '.css', // CSS '.scss', // Sass // add more extensions here as needed (e.g., '.py', '.java', '.go') ]; function walk(dir) { const entries = fs.readdirSync(dir, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(dir, entry.name); if (entry.isDirectory()) { if (entry.name === "node_modules") continue; walk(fullPath); } else if (entry.isFile()) { const name = entry.name.toLowerCase(); if (name.includes("config")) continue; const ext = path.extname(name); if (allowedExtensions.includes(ext)) { filesList.push(fullPath); } } } } walk(rootDir); return filesList; } /** * Writes the paths and contents of found files into a text file. * * @param {string[]} filePaths - Array of file paths. * @param {string} outputFile - Path to the output file. */ function writeFilesToTxt(filePaths, outputFile) { let outputContent = `Generated by file-concat-tool by noluyorAbi\n`; outputContent += `https://www.npmjs.com/package/file-concat-tool\n\n`; filePaths.forEach((filePath) => { try { const content = fs.readFileSync(filePath, "utf8"); outputContent += `=== File: ${filePath} ===\n` + content + "\n\n"; console.log(chalk.gray(` • ${filePath}`)); } catch (error) { console.error(chalk.red(`Error reading file ${filePath}: ${error.message}`)); } }); fs.writeFileSync(outputFile, outputContent, "utf8"); console.log(chalk.green(`\n✔ Contents written to ${outputFile}`)); } /** * Updates the Git exclude file ('.git/info/exclude') to ignore the output file. * Does nothing if the project is not a Git repo or the exclude file doesn't exist. * * @param {string} rootDir - The root directory of the project. * @param {string} outputFile - The output file name to ignore. */ function updateGitExclude(rootDir, outputFile) { const gitDir = path.join(rootDir, ".git"); const excludePath = path.join(gitDir, "info", "exclude"); if (!fs.existsSync(gitDir) || !fs.existsSync(excludePath)) { console.log(chalk.yellow("No Git repository detected or exclude file missing, skipping exclude update.")); return; } let excludeContent = fs.readFileSync(excludePath, "utf8"); if (!excludeContent.includes(outputFile)) { fs.appendFileSync(excludePath, `\n${outputFile}\n`, "utf8"); console.log(chalk.green(`✔ Added ${outputFile} to git exclude.`)); } else { console.log(chalk.blue(`⚑ ${outputFile} already in git exclude.`)); } } /** * Main function that searches the directory and writes the results to a text file. */ function main() { const rootDirectory = process.cwd(); const outputTxt = "source_files_content.txt"; console.log(chalk.cyan.bold(`\n🕵️‍♂️ Searching for source files in:`), chalk.white(rootDirectory)); const files = findSourceFiles(rootDirectory); console.log(chalk.cyan(`Found ${files.length} file${files.length === 1 ? '' : 's'}.`)); console.log(chalk.cyan(`\n✍️ Writing contents to ${outputTxt}...\n`)); writeFilesToTxt(files, outputTxt); // Update Git exclude if applicable updateGitExclude(rootDirectory, outputTxt); console.log(chalk.magenta.bold(`\n🎉 Done!`)); } main();