// skill-structure.test.mjs — Verifies SKILL.md frontmatter and commands/ deletion. import { test } from 'node:test'; import { strict as assert } from 'node:assert'; import { existsSync, readFileSync } from 'node:fs'; import { join, dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; const __dirname = dirname(fileURLToPath(import.meta.url)); const PLUGIN_ROOT = join(__dirname, '..'); test('SKILL.md exists at expected path', () => { const skillPath = join(PLUGIN_ROOT, 'skills', 'graceful-handoff', 'SKILL.md'); assert.ok(existsSync(skillPath), `SKILL.md missing at ${skillPath}`); }); test('commands/ directory is deleted (hard cut to skills/)', () => { const commandsDir = join(PLUGIN_ROOT, 'commands'); assert.ok(!existsSync(commandsDir), 'commands/ directory still exists — should be deleted in v2.0'); }); test('SKILL.md has disable-model-invocation: true', () => { const skillPath = join(PLUGIN_ROOT, 'skills', 'graceful-handoff', 'SKILL.md'); const content = readFileSync(skillPath, 'utf-8'); assert.match(content, /^disable-model-invocation: true$/m); }); test('SKILL.md has model: claude-sonnet-4-6', () => { const skillPath = join(PLUGIN_ROOT, 'skills', 'graceful-handoff', 'SKILL.md'); const content = readFileSync(skillPath, 'utf-8'); assert.match(content, /^model: claude-sonnet-4-6$/m); }); test('SKILL.md has Bash sub-scoped allowed-tools', () => { const skillPath = join(PLUGIN_ROOT, 'skills', 'graceful-handoff', 'SKILL.md'); const content = readFileSync(skillPath, 'utf-8'); assert.match(content, /Bash\(git:\*\)/); assert.match(content, /Bash\(node:\*\)/); }); test('SKILL.md does not pre-approve curl or wget', () => { const skillPath = join(PLUGIN_ROOT, 'skills', 'graceful-handoff', 'SKILL.md'); const content = readFileSync(skillPath, 'utf-8'); // Frontmatter only — find the allowed-tools line const allowedToolsLine = content.match(/^allowed-tools:.*$/m); assert.ok(allowedToolsLine, 'allowed-tools line missing'); assert.doesNotMatch(allowedToolsLine[0], /\bcurl\b/); assert.doesNotMatch(allowedToolsLine[0], /\bwget\b/); }); test('SKILL.md body references handoff-pipeline.mjs', () => { const skillPath = join(PLUGIN_ROOT, 'skills', 'graceful-handoff', 'SKILL.md'); const content = readFileSync(skillPath, 'utf-8'); assert.match(content, /handoff-pipeline\.mjs/); }); test('SKILL.md body has Tidsbudsjett (time budget) note', () => { const skillPath = join(PLUGIN_ROOT, 'skills', 'graceful-handoff', 'SKILL.md'); const content = readFileSync(skillPath, 'utf-8'); assert.match(content, /Tidsbudsjett/); });