fix(adapters): bound parsing and publish review artifacts safely

This commit is contained in:
haelyra committed 2026-10-10 18:38:26 -04:00
1 parent b327efcad3
commit 7682bb5b49
10 files changed
+349 -104

No files matched your search

+35 -12
View File
@@ -89,6 +89,26 @@ Options:
`);
}
function isIdenticalExistingAgent(target, markdown) {
let fd;
try {
fd = fs.openSync(target, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW || 0) | (fs.constants.O_NONBLOCK || 0));
} catch (error) {
if (error.code === 'ENOENT') return false;
throw error;
}
try {
if (!fs.fstatSync(fd).isFile()
|| (!fs.constants.O_NOFOLLOW && fs.lstatSync(target).isSymbolicLink())
|| fs.readFileSync(fd, 'utf8') !== markdown) {
throw new Error(`refusing to overwrite existing agent: ${target}`);
}
return true;
} finally {
fs.closeSync(fd);
}
}
function main() {
let args;
try {
@@ -135,6 +155,7 @@ function main() {
if (args.out) {
const dir = path.resolve(args.out);
const identicalOutputs = new Set();
if (!args.dryRun) {
if (fs.existsSync(dir) && fs.lstatSync(dir).isSymbolicLink()) {
throw new Error('output directory must not be a symlink');
@@ -143,14 +164,7 @@ function main() {
// cannot be replaced simply because they share an ECC dispatch name.
for (const r of results) {
const target = path.join(dir, `${r.id}.md`);
let stat;
try { stat = fs.lstatSync(target); } catch (error) {
if (error.code !== 'ENOENT') throw error;
}
if (stat && (!stat.isFile() || stat.isSymbolicLink()
|| fs.readFileSync(target, 'utf8') !== r.markdown)) {
throw new Error(`refusing to overwrite existing agent: ${target}`);
}
if (isIdenticalExistingAgent(target, r.markdown)) identicalOutputs.add(target);
}
fs.mkdirSync(dir, { recursive: true });
}
@@ -158,10 +172,19 @@ function main() {
const target = path.join(dir, `${r.id}.md`);
if (args.dryRun) {
progress(`[dry-run] would write ${target}`);
} else if (!fs.existsSync(target)) {
// Exclusive creation prevents a file/symlink appearing after preflight
// from being overwritten. Identical existing output stays untouched.
fs.writeFileSync(target, r.markdown, { flag: 'wx' });
} else if (identicalOutputs.has(target)) {
// Existing output may have changed while the rest of the batch was checked.
if (!isIdenticalExistingAgent(target, r.markdown)) {
throw new Error(`existing agent disappeared after preflight: ${target}`);
}
} else {
// Exclusive descriptor creation rejects a raced file or symlink.
const fd = fs.openSync(target, 'wx', 0o600);
try {
fs.writeFileSync(fd, r.markdown);
} finally {
fs.closeSync(fd);
}
progress(`wrote ${target}`);
}
}
+4 -3
View File
@@ -133,9 +133,10 @@ function extractTopLevelList(yamlSource, key) {
break;
}
const match = line.match(/^\s*-\s+(.+?)\s*$/);
if (match) {
results.push(unquoteYamlScalar(match[1]));
const trimmed = line.trim();
if (trimmed.startsWith('-') && trimmed.length > 1 && /\s/.test(trimmed[1])) {
const value = trimmed.slice(1).trim();
if (value) results.push(unquoteYamlScalar(value));
}
}
+8 -5
View File
@@ -109,19 +109,22 @@ function formatToolLine(tools) {
}
function adaptColor(line) {
const match = line.match(/^(\s*)color\s*:\s*(.+?)\s*$/);
if (!match) {
const trimmed = line.trimStart();
const colon = trimmed.indexOf(':');
if (colon < 0 || trimmed.slice(0, colon).trimEnd() !== 'color') {
return null;
}
const value = match[2].replace(/^["']|["']$/g, '');
const rawValue = trimmed.slice(colon + 1).trim();
if (!rawValue) return null;
const indent = line.slice(0, line.length - trimmed.length);
const value = rawValue.replace(/^["']|["']$/g, '');
if (VALID_COLORS.has(value)) {
return { line, changed: false };
}
const remapped = COLOR_MAP.get(value);
if (remapped) {
return { line: `${match[1]}color: ${remapped}`, changed: true };
return { line: `${indent}color: ${remapped}`, changed: true };
}
return { line: null, changed: true };