Repository Public Research preview
1// Copies the dependency-free audit engine from the MCP package into the skill, so both run the2// same code, and generates the finding-code reference from the engine's registry.3import { copyFileSync, mkdirSync, readdirSync, writeFileSync } from "node:fs";4import { CODES } from "./mcp/lib/codes.mjs";5import { roleOf } from "./mcp/lib/audits.mjs";67const src = new URL("./mcp/", import.meta.url), dst = new URL("./skill/manuscript-peer-review/", import.meta.url);8mkdirSync(new URL("scripts/lib/", dst), { recursive: true });9mkdirSync(new URL("references/", dst), { recursive: true });10const files = readdirSync(new URL("lib/", src)).filter((f) => f.endsWith(".mjs")).sort();11for (const f of files) copyFileSync(new URL(`lib/${f}`, src), new URL(`scripts/lib/${f}`, dst));12copyFileSync(new URL("../anthropic/mcp/LICENSE", import.meta.url), new URL("LICENSE", dst));13copyFileSync(new URL("../anthropic/mcp/LICENSE", import.meta.url), new URL("LICENSE", src));1415const ROLE = { referee: "Referee", editor: "Editor", table_figure_editor: "Table and figure editor", integrity_auditor: "Integrity auditor", replication_auditor: "Replication auditor" };16const SECTIONS = [17 ["outline", "Structure (`outline`)"], ["audit_citations", "Citations (`citations`)"], ["audit_cross_references", "Cross-references (`refs`)"],18 ["audit_numbers", "Numbers (`numbers`)"], ["audit_statistics_reporting", "Statistics reporting (`stats`)"], ["audit_tables", "Tables and figures (`tables`)"],19 ["audit_claims", "Claims (`claims`)"], ["audit_style", "Style and leftovers (`style`)"], ["audit_replication", "Replication statements (`replication`)"],20];21let md = "<!-- Generated by build-skill.mjs from the engine's code registry. Do not edit by hand. -->\n# Finding codes\n\n";22md += "Every finding of the audit scripts carries one of these codes. \"Heuristic\" means the check is a pattern match on wording: read the line before you report it. \"Exact\" means the check is mechanical (a key is missing, a division is wrong), though the parser can still be fooled by macros.\n\n";23md += "Severity: **error** = breaks the document or is wrong as written; **warning** = likely to draw a referee comment; **info** = worth a look. `warning|info` = warning when the manuscript looks empirical, info otherwise.\n";24for (const [audit, title] of SECTIONS) {25 md += `\n## ${title}\n\n| Code | Severity | Kind | Role | Meaning | Before reporting it |\n|---|---|---|---|---|---|\n`;26 for (const [code, c] of Object.entries(CODES)) if (c.audit === audit) md += `| \`${code}\` | ${c.severity} | ${c.heuristic ? "heuristic" : "exact"} | ${ROLE[roleOf(code)]} | ${c.meaning.replace(/\|/g, "\\|")} | ${c.verify.replace(/\|/g, "\\|")} |\n`;27}28writeFileSync(new URL("references/finding-codes.md", dst), md);29console.log(`skill engine synced: ${files.length} files, ${Object.keys(CODES).length} codes`);30