UNPKG

scai

Version:

> **AI-powered CLI for local code analysis, commit message suggestions, and natural-language queries.** > **100% local • No token cost • Private by design • GDPR-friendly** — made in Denmark/EU with ❤️.

79 lines (78 loc) 3.42 kB
// File: src/modules/writeFileModule.ts import fs from "fs/promises"; import path from "path"; import chalk from "chalk"; import { normalizePath } from "../utils/contentUtils.js"; import { logInputOutput } from "../utils/promptLogHelper.js"; export const writeFileStep = { name: "writeFile", description: "Writes all materialized file outputs from codeTransformModule to disk. " + "This is a terminal side-effect step and does not depend on plan steps.", groups: ["finalize"], run: async (input) => { var _a; console.log(">>> writeFileStep starting"); const context = input.context; const mode = input.data?.mode ?? "overwrite"; const writtenFiles = []; const errors = []; if (!context) { console.error("writeFileStep: Missing execution context"); return { query: input.query, data: { writeMode: mode, writtenFiles, errors: ["Missing execution context"] } }; } console.log("writeFileStep: context exists"); console.log("writeFileStep: mode =", mode); console.log("writeFileStep: existing touchedFiles =", context.plan?.touchedFiles); const artifacts = context.execution?.codeTransformArtifacts?.files ?? []; console.log("writeFileStep: found codeTransformArtifacts.files =", artifacts.length); if (artifacts.length) { console.log("writeFileStep: filePaths =", artifacts.map(f => f.filePath)); } else { console.warn("writeFileStep: No artifacts found to write"); } for (const f of artifacts) { console.log("Processing artifact:", f.filePath); const filePath = normalizePath(f.filePath); if (!filePath) { const msg = `Invalid filePath: ${f.filePath}`; console.error(msg); errors.push(msg); continue; } if (typeof f.content !== "string" || !f.content.trim()) { const msg = `No content to write for ${filePath}`; console.error(msg); errors.push(msg); continue; } try { await fs.mkdir(path.dirname(filePath), { recursive: true }); await fs.writeFile(filePath, f.content, "utf-8"); console.log(chalk.green(`✅ Wrote file: ${filePath}`)); writtenFiles.push(filePath); } catch (err) { const msg = err?.message ?? String(err); console.error(chalk.red(`❌ Failed writing ${filePath}: ${msg}`)); errors.push(`${filePath}: ${msg}`); } } // mark files as touched if not already context.plan ?? (context.plan = {}); (_a = context.plan).touchedFiles ?? (_a.touchedFiles = []); for (const file of writtenFiles) { if (!context.plan.touchedFiles.includes(file)) { context.plan.touchedFiles.push(file); } } console.log("writeFileStep: touchedFiles after run =", context.plan.touchedFiles); const output = { query: input.query, data: { writeMode: mode, writtenFiles, errors } }; logInputOutput("writeFile", "output", output.data); console.log(">>> writeFileStep complete"); return output; } };