scai
Version:
> **A local-first AI CLI for understanding, querying, and iterating on large codebases.** > **100% local • No token costs • No cloud • No prompt injection • Private by design**
64 lines (63 loc) • 1.9 kB
JavaScript
import fs from "fs";
import { log } from "../utils/log.js";
import { SCAI_HOME, PROMPT_LOG_PATH, RUN_LOG_PATH } from "../constants.js";
/**
* Ensures SCAI_HOME exists before writing logs.
*/
function ensureHomeDir() {
if (!fs.existsSync(SCAI_HOME))
fs.mkdirSync(SCAI_HOME, { recursive: true });
}
/**
* Creates a formatted header for visual clarity in logs.
*/
function formatHeader(title) {
const divider = "=".repeat(68);
return `\n\n${divider}\n📂 ${title}\n${divider}\n`;
}
/**
* Overwrites the prompt log with a new prompt.
*/
export function logPrompt(prompt) {
try {
ensureHomeDir();
const entry = formatHeader("Prompt Updated") + prompt + "\n";
fs.writeFileSync(PROMPT_LOG_PATH, entry, "utf-8");
log(`📝 Prompt written to ${PROMPT_LOG_PATH}`);
}
catch (err) {
log("❌ Failed to write prompt log:", err);
}
}
/**
* Appends module input/output data to a separate log file.
* Automatically stringifies objects.
*/
export function logInputOutput(stepName, type, content) {
try {
ensureHomeDir();
const contentStr = typeof content === "string" ? content.trim() : JSON.stringify(content, null, 2);
const entry = formatHeader(`${type.toUpperCase()} | ${stepName}`) +
contentStr +
"\n" +
"=".repeat(68) +
"\n";
fs.appendFileSync(RUN_LOG_PATH, entry, "utf-8");
}
catch (err) {
log(`❌ Failed to append ${type} for ${stepName}:`, err);
}
}
/**
* Clears the per-run input/output log so each run starts clean while keeping
* the same file path available for tools like `tail -f`.
*/
export function clearRunLog() {
try {
ensureHomeDir();
fs.writeFileSync(RUN_LOG_PATH, "", { flag: "w" });
}
catch (err) {
log(`❌ Failed to clear run log at ${RUN_LOG_PATH}:`, err);
}
}