Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions scripts/generate-skill-references.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
* shape. The agent reads these alongside the hand-written reference to get
* the exact current field surface without us re-documenting fields in prose.
*
* Usage: node scripts/generate-skill-references.mjs
* Usage: node scripts/generate-skill-references.mjs [--out <dir>]
*
* `--out` writes the tree under <dir> instead of the repo (and leaves the
* SKILL.md version stamps alone), so the drift test never rewrites files
* other tests are reading.
*
* Output is idempotent: re-running produces byte-identical files. The
* openapi-drift test (`test/skills/openapi-drift.test.ts`) depends on this.
Expand All @@ -22,6 +26,8 @@ import { preprocessSpec } from './lib/preprocess.mjs';
const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = join(__dirname, '..');
const SPEC_PATH = join(ROOT, 'docs/openapi/monitoring-api.json');
const outFlag = process.argv.indexOf('--out');
const OUT_ROOT = outFlag === -1 ? ROOT : process.argv[outFlag + 1];

/**
* Map each skill + resource to the OpenAPI schema names we care about.
Expand Down Expand Up @@ -244,12 +250,12 @@ function stampVersions() {
}

function main() {
stampVersions();
if (OUT_ROOT === ROOT) stampVersions();
const spec = loadSpec();

let total = 0;
for (const [skill, resources] of Object.entries(RESOURCES)) {
const outDir = join(ROOT, 'skills', skill, 'references', '_generated');
const outDir = join(OUT_ROOT, 'skills', skill, 'references', '_generated');
if (existsSync(outDir)) rmSync(outDir, { recursive: true, force: true });
mkdirSync(outDir, { recursive: true });

Expand Down
22 changes: 14 additions & 8 deletions test/skills/openapi-drift.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {expect, test} from 'vitest'
import {execSync} from 'node:child_process'
import {readFileSync, readdirSync} from 'node:fs'
import {mkdtempSync, readFileSync, readdirSync, rmSync} from 'node:fs'
import {tmpdir} from 'node:os'
import {dirname, join} from 'node:path'
import {fileURLToPath} from 'node:url'

Expand All @@ -16,12 +17,17 @@ const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..', '..')
* changes (via spec-propagate from mono), the drift check fires.
*/
test('generated skill references are in sync with OpenAPI spec', () => {
const before = snapshotGenerated()
const before = snapshotGenerated(ROOT)

// Regenerate.
execSync('node scripts/generate-skill-references.mjs', {cwd: ROOT, stdio: 'pipe'})

const after = snapshotGenerated()
// Regenerate into a temp dir: other tests read the committed copies.
const out = mkdtempSync(join(tmpdir(), 'skill-refs-'))
let after: Record<string, string>
try {
execSync(`node scripts/generate-skill-references.mjs --out ${JSON.stringify(out)}`, {cwd: ROOT, stdio: 'pipe'})
after = snapshotGenerated(out)
} finally {
rmSync(out, {recursive: true, force: true})
}

const diffs: string[] = []
for (const [path, content] of Object.entries(after)) {
Expand All @@ -37,9 +43,9 @@ test('generated skill references are in sync with OpenAPI spec', () => {
).toEqual([])
})

function snapshotGenerated(): Record<string, string> {
function snapshotGenerated(root: string): Record<string, string> {
const out: Record<string, string> = {}
const skillsDir = join(ROOT, 'skills')
const skillsDir = join(root, 'skills')
for (const skill of readdirSync(skillsDir)) {
if (!skill.startsWith('devhelm-')) continue
const gen = join(skillsDir, skill, 'references', '_generated')
Expand Down
Loading