import { existsSync, mkdirSync, readFileSync, writeFileSync, } from "node:fs"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const projectRoot = join(__dirname, ".."); const draftDir = join(projectRoot, "schema", "draft"); const version = process.argv[2]; function replaceRequired( content: string, search: string, replacement: string, source: string, ): string { if (!content.includes(search)) { throw new Error(`Expected release metadata not found in ${source}`); } return content.replace(search, replacement); } if (!version || !/^\d{4}-\d{2}-\d{2}$/.test(version)) { throw new Error("Usage: npm run snapshot:schema -- YYYY-MM-DD"); } const releaseDir = join(projectRoot, "schema", version); if (existsSync(releaseDir)) { throw new Error(`Release schema already exists: ${releaseDir}`); } mkdirSync(releaseDir, { recursive: false }); const schema = JSON.parse( readFileSync(join(draftDir, "schema.json"), "utf-8"), ) as Record; schema.$id = `https://modelcontextprotocol.io/ext-tasks/${version}/schema.json`; writeFileSync( join(releaseDir, "schema.json"), JSON.stringify(schema, null, 2) + "\n", "utf-8", ); const schemaTypes = replaceRequired( readFileSync(join(draftDir, "schema.ts"), "utf-8"), " * - Run `npm run generate:schemas` to regenerate schemas from these types", " * - This released snapshot is immutable; make changes in schema/draft/ instead", "schema/draft/schema.ts", ); writeFileSync(join(releaseDir, "schema.ts"), schemaTypes, "utf-8"); const specSchema = JSON.parse( readFileSync(join(draftDir, "spec.schema.json"), "utf-8"), ) as Record; if (typeof specSchema.$comment !== "string") { throw new Error("Draft spec.schema.json is missing its provenance $comment"); } specSchema.$comment = replaceRequired( specSchema.$comment, "DO NOT EDIT MANUALLY. Update with: npm run fetch:spec-schema", `Immutable ${version} snapshot. Do not edit; update schema/draft/ instead`, "schema/draft/spec.schema.json", ); writeFileSync( join(releaseDir, "spec.schema.json"), JSON.stringify(specSchema, null, 2) + "\n", "utf-8", ); const specTypes = replaceRequired( readFileSync(join(draftDir, "spec.types.ts"), "utf-8"), " * DO NOT EDIT THIS FILE MANUALLY. Update with: npm run fetch:spec-schema", ` * Immutable ${version} snapshot. Do not edit; update schema/draft/ instead`, "schema/draft/spec.types.ts", ); writeFileSync(join(releaseDir, "spec.types.ts"), specTypes, "utf-8"); console.log(`Created immutable schema snapshot: ${releaseDir}`);