34 lines
2.1 KiB
JavaScript
34 lines
2.1 KiB
JavaScript
import { readFileSync, writeFileSync } from "node:fs";
|
|
import { resolve } from "node:path";
|
|
const root = resolve(import.meta.dirname, "..");
|
|
const source = readFileSync(resolve(root, "skills/paperclip/references/api-reference.md"), "utf8");
|
|
const key = (method, path) => `${method} ${path.replace(/:[A-Za-z][A-Za-z0-9_]*|\{[^}]+\}/g, "{}")}`;
|
|
const entries = {};
|
|
let section = "Paperclip API Reference";
|
|
for (const line of source.split("\n")) {
|
|
if (/^#{2,5} /.test(line)) section = line.replace(/^#+ /, "");
|
|
const table = /^\|\s*(GET|POST|PATCH|PUT|DELETE)\s*\|\s*`([^`]+)`\s*\|\s*(.*?)\s*\|/.exec(line);
|
|
if (table) entries[key(table[1], table[2])] = { section, description: table[3] };
|
|
}
|
|
for (const match of source.matchAll(/^(GET|POST|PATCH|PUT|DELETE) (\/api\/[^\s]+)\n(\{[^\n]*\}|\{\n[\s\S]*?\n\})/gm)) {
|
|
try {
|
|
const body = JSON.parse(match[3]);
|
|
const id = key(match[1], match[2]);
|
|
// Runtime consumers look up endpoint templates from OpenAPI. Narrative
|
|
// URLs with literal resource IDs must not create unreachable entries.
|
|
if (!entries[id]) continue;
|
|
// Keep examples for each interaction kind / issue disposition, so new
|
|
// question or waiting examples do not displace existing confirmation flows.
|
|
const variant = body.kind ?? body.status ?? "";
|
|
const examples = entries[id].examples ??= [];
|
|
if (examples.filter(({ body: example }) => (example.kind ?? example.status ?? "") === variant).length < 2) {
|
|
examples.push({ body });
|
|
}
|
|
} catch { /* Narrative/pseudocode blocks are not executable examples. */ }
|
|
}
|
|
const destination = resolve(root, "server/src/services/native-runtime/runner-api-reference.ts");
|
|
const output = `// Generated by scripts/generate-runner-api-reference.mjs from the legacy skill reference.\nexport const runnerApiReference: Record<string, { section: string; description?: string; examples?: { body: unknown }[] }> = ${JSON.stringify(entries, null, 2)};\n`;
|
|
if (process.argv.includes("--check")) {
|
|
if (readFileSync(destination, "utf8") !== output) throw new Error("Runner API skill enrichment is stale");
|
|
} else writeFileSync(destination, output);
|