promptfusion
Version:
A CLI tool to concatenate all text files in your CWD with headers for GPT prompt engineering.
82 lines (78 loc) • 3.1 kB
JavaScript
// src/promptfusion.ts
import fs from "fs";
import path from "path";
import { isWithinTokenLimit } from "gpt-tokenizer";
import * as globby from "globby";
import clipboardy from "clipboardy";
import prettyFileTree from "pretty-file-tree";
var TOKEN_LIMIT = 32e4;
var MEDIA_FILE_EXTENSIONS = [".webp", ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".mp4", ".mp3", ".avi", ".mov", ".wmv", ".flac", ".wav"];
var SKIP_FILES = ["yarn.lock", "package-lock.json", ".gitignore"];
function shouldSkipFile(filePath) {
const extension = path.extname(filePath).toLowerCase();
const basename = path.basename(filePath);
return MEDIA_FILE_EXTENSIONS.includes(extension) || SKIP_FILES.includes(basename);
}
async function processFile(filePath) {
console.log("[promptfusion]:", filePath);
const relativeFilePath = path.relative(process.cwd(), filePath);
const fileHeader = `Title: ${path.basename(filePath)}
Path: ${relativeFilePath}
`;
if (shouldSkipFile(filePath)) {
return fileHeader;
} else {
const fileContent = fs.readFileSync(filePath, "utf8");
return fileHeader + fileContent + "\n\n";
}
}
async function concatenateFiles(inputDir, outputFile, mapOnly) {
const dirMap = await generateDirectoryMap(inputDir);
if (mapOnly) {
console.log("Directory map generated.");
clipboardy.writeSync(dirMap);
return;
}
const filePaths = await globby.globby(["**/*", "!**/.git/**"], { cwd: inputDir, gitignore: true, onlyFiles: true, dot: true });
let combinedContent = dirMap + "\n\n";
for (const filePath of filePaths) {
const fullFilePath = path.join(inputDir, filePath);
const contentWithHeader = await processFile(fullFilePath);
if (!isWithinTokenLimit(combinedContent + contentWithHeader, TOKEN_LIMIT)) {
console.warn("Warning: The combined content exceeds the GPT-4 token limit.");
console.warn(`Token limit exceeded while processing file: ${fullFilePath}`);
process.exit(1);
}
combinedContent += contentWithHeader;
}
if (outputFile) {
fs.writeFileSync(outputFile, combinedContent);
console.log(`Files have been successfully combined into ${outputFile}!`);
} else {
try {
clipboardy.writeSync(combinedContent);
console.log("Content has been copied to the clipboard.");
} catch (error) {
console.error("Failed to copy content to the clipboard. Error:", error);
}
}
}
async function generateDirectoryMap(dirPath) {
const paths = await globby.globby(["**", "!**/.git/**", "!node_modules/**"], {
cwd: dirPath,
gitignore: true,
onlyDirectories: false,
onlyFiles: false,
dot: true
});
return prettyFileTree(paths);
}
// src/cli.ts
var args = process.argv.slice(2);
var directoryPath = args.find((arg) => !arg.startsWith("--")) || process.cwd();
var outputPathIndex = args.indexOf("--output");
var outputPath = outputPathIndex > -1 ? args[outputPathIndex + 1] : null;
var shouldMap = args.includes("--map");
console.log("running promptfusion...");
concatenateFiles(directoryPath, outputPath, shouldMap).catch((err) => console.error(err));