aiwg
Version:
Deployment tool and support utility for AI context. Copies agents, skills, commands, rules, and behaviors into the paths each AI platform reads (Claude Code, Codex, Copilot, Cursor, Warp, OpenClaw, and 6 more) so one source of truth works across 10 platfo
67 lines (61 loc) • 1.84 kB
JavaScript
/**
* Fix MD047: Ensure files end with a single trailing newline.
*
* Usage:
* node tools/lint/fix-md47-finalnewline.mjs [--target <path>|.] [--write]
*/
import fs from 'fs';
import path from 'path';
function parseArgs() {
const args = process.argv.slice(2);
let target = process.cwd();
let write = false;
for (let i = 0; i < args.length; i++) {
const a = args[i];
if (a === '--target' && args[i + 1]) target = path.resolve(args[++i]);
else if (a === '--write') write = true;
}
return { target, write };
}
function listMdFiles(dir) {
const out = [];
function walk(d) {
for (const e of fs.readdirSync(d, { withFileTypes: true })) {
if (e.name === 'node_modules' || e.name === '.git' || e.name === '.claude') continue;
const p = path.join(d, e.name);
if (e.isDirectory()) walk(p);
else if (e.isFile() && e.name.toLowerCase().endsWith('.md')) out.push(p);
}
}
walk(dir);
return out;
}
function fixFile(file, write) {
const buf = fs.readFileSync(file);
if (buf.length === 0) {
if (write) fs.writeFileSync(file, '\n');
return true;
}
const text = buf.toString('utf8');
if (!text.endsWith('\n')) {
if (write) fs.writeFileSync(file, text + '\n', 'utf8');
return true;
}
// Ensure only one trailing newline
const trimmed = text.replace(/\n+$/,'\n');
if (trimmed !== text) {
if (write) fs.writeFileSync(file, trimmed, 'utf8');
return true;
}
return false;
}
(function main(){
const { target, write } = parseArgs();
const files = listMdFiles(target);
let changed = 0;
for (const f of files) {
if (fixFile(f, write)) { changed++; console.log(`${write ? 'fixed' : 'would-fix'} ${path.relative(process.cwd(), f)}`); }
}
console.log(`${write ? 'Fixed' : 'Would fix'} ${changed} file(s).`);
})();