editFiles
uses node:path
tcm edit of files kept as written: each into a file of its own, named as it is (or file). A Markdown
file's first line says where it goes back; another's is saved with --into.
import type { Codebase } from "#codebase/tcmts/cli/codebase"; import { fileContent, fileName, formatOf } from "#codebase/tcmts/cli/files"; import { dim } from "#codebase/tcmts/cli/style"; import { scratchShown, shellWord, shownPath, UsageError } from "#codebase/tcmts/cli/ui"; import fs from "node:fs"; import path from "node:path"; export function editFiles( cb: Codebase, targets: string[], file: string | undefined, force: boolean, ) { if (file && targets.length > 1) throw new UsageError("--file names one file: edit files one at a time"); for (const t of targets) { const h = cb.lookupOne(t); const rec = cb.store.getDef(h)!; if (rec.kind !== "file") throw new UsageError(`${t} is code, the others files: edit them apart`); const name = cb.store.pathsOf(h)[0] ?? t; const ns = name.slice(0, Math.max(0, name.lastIndexOf("."))); const format = formatOf(rec); // as it's named, here (or in a session's own directory) const out = file ?? path.join( cb.sessionDir ?? process.cwd(), fileName(name.slice(name.lastIndexOf(".") + 1), rec), ); const content = fileContent(cb, rec, ns); const body = format === "md" ? Buffer.concat([Buffer.from(`<!-- tcm: path ${name} -->\n`), content]) : content; // the codebase's own config, where `tcm edit` writes: never over it, --force or not if ( ["package.json", "tsconfig.json", ".mcp.json"].some( (f) => path.resolve(out) === path.join(cb.lay.root, f), ) ) throw new UsageError( `${path.basename(out)} here is the codebase's own: edit ${name} with --file <other>`, ); if (fs.existsSync(out) && !force && !fs.readFileSync(out).equals(body)) throw new UsageError( `${path.basename(out)} exists; pass --force to overwrite it, or --file <other>`, ); fs.writeFileSync(out, body); // (where it went whole, as tcm_edit reads it; how to save it as it's named in a session) console.log( `wrote ${name} to ${shownPath(out)}${format === "md" ? "" : dim(` (saved with \`tcm update ${shellWord(scratchShown(out, cb.sessionDir))} --into ${ns}\`)`)}`, ); } }
uses
- tcmts.cli.codebase.Codebase
- tcmts.cli.files.fileContent
- tcmts.cli.files.fileName
- tcmts.cli.files.formatOf
- tcmts.cli.style.dim
- tcmts.cli.ui.UsageError
- tcmts.cli.ui.scratchShown
- tcmts.cli.ui.shellWord
- tcmts.cli.ui.shownPath