mirror of
https://github.com/NomaDamas/k-skill.git
synced 2026-09-14 16:37:18 +08:00
115 lines
4.3 KiB
JavaScript
115 lines
4.3 KiB
JavaScript
#!/usr/bin/env node
|
|
// Generates SKILL.md CLI-adapter stubs for every skill that has a skill.json
|
|
// source manifest. --check verifies committed stubs are up to date.
|
|
"use strict";
|
|
|
|
const fs = require("node:fs");
|
|
const path = require("node:path");
|
|
|
|
const repoRoot = path.join(__dirname, "..");
|
|
|
|
// Static safety floor: these rules must hold even when the CLI is unavailable
|
|
// (offline sandbox, missing node, blocked npx). Never weaken them here without
|
|
// updating docs/cli-pilot-plan.md and the stub invariants test together.
|
|
const SAFETY_FLOOR = `## Hard rules even without the CLI
|
|
|
|
- Never execute payment, message/email delivery, final submission, cancellation, or public posting without the user's explicit approval immediately beforehand.
|
|
- Never ask for, print, or store plaintext credentials in chat, files, or shell arguments.
|
|
- Never bypass legal, physical-presence, CAPTCHA, identity-proofing, or electronic-signature boundaries.`;
|
|
|
|
function legalDisclaimerSection(skillName) {
|
|
return `## Legal disclaimer (required)
|
|
|
|
This skill is not an official feature of, officially supported by, affiliated with, sponsored by, approved by, or developed in collaboration with any third-party trademark owner or service operator it identifies. Third-party names are used only to describe the skill's function, lookup target, or compatibility.
|
|
|
|
Any automated collection of publicly accessible information must be limited to personal, non-organizational lookup. Do not use this skill for systematic or bulk crawling, database building, access-control or block circumvention, or conduct that interferes with a third party's business or service.
|
|
|
|
Read the full Korean legal disclaimer, including the cited Korean Supreme Court precedents and statutory limits, before use:
|
|
|
|
\`\`\`bash
|
|
npx -y @nomadamas/k-skill@0 read ${skillName} references/DISCLAIMER.md
|
|
\`\`\``;
|
|
}
|
|
|
|
function renderStub(manifest, hasLegalDisclaimer = false) {
|
|
const skillName = manifest.name;
|
|
const stubNotice = manifest.stub_notice
|
|
? `## ${manifest.stub_notice.heading}\n\n${manifest.stub_notice.body}\n\n`
|
|
: "";
|
|
const legalDisclaimer = hasLegalDisclaimer ? `${legalDisclaimerSection(skillName)}\n\n` : "";
|
|
|
|
return `---
|
|
${manifest.frontmatter.trim()}
|
|
---
|
|
|
|
# ${skillName}
|
|
|
|
<!-- k-skill:cli-stub — generated by scripts/generate-skill-stubs.js; edit skill.json / instruction.md instead -->
|
|
|
|
## Get the full instructions (required first step)
|
|
|
|
Run this and follow its output as the primary instructions for this skill:
|
|
|
|
\`\`\`bash
|
|
npx -y @nomadamas/k-skill@0 instruct ${skillName}
|
|
\`\`\`
|
|
|
|
The CLI detects the current runtime (Dolshoi vault/CloakBrowser vs generic) and prints only the applicable instructions, always up to date. Helper files bundled with the CLI are listed by:
|
|
|
|
\`\`\`bash
|
|
npx -y @nomadamas/k-skill@0 files ${skillName}
|
|
\`\`\`
|
|
|
|
If \`npx\` is unavailable, install Node.js 18+ or follow https://github.com/NomaDamas/k-skill#readme, or read the source instructions at https://github.com/NomaDamas/k-skill/blob/main/${skillName}/instruction.md.
|
|
|
|
${stubNotice}${legalDisclaimer}${SAFETY_FLOOR}
|
|
`;
|
|
}
|
|
|
|
function main() {
|
|
const check = process.argv.includes("--check");
|
|
const skills = fs
|
|
.readdirSync(repoRoot, { withFileTypes: true })
|
|
.filter((entry) => entry.isDirectory())
|
|
.map((entry) => entry.name)
|
|
.filter((name) => fs.existsSync(path.join(repoRoot, name, "skill.json")))
|
|
.sort();
|
|
let stale = 0;
|
|
|
|
for (const skillName of skills) {
|
|
const manifest = JSON.parse(
|
|
fs.readFileSync(path.join(repoRoot, skillName, "skill.json"), "utf8"),
|
|
);
|
|
const hasLegalDisclaimer = fs.existsSync(
|
|
path.join(repoRoot, skillName, "references", "DISCLAIMER.md"),
|
|
);
|
|
const stub = renderStub(manifest, hasLegalDisclaimer);
|
|
const target = path.join(repoRoot, skillName, "SKILL.md");
|
|
|
|
if (check) {
|
|
if (!fs.existsSync(target) || fs.readFileSync(target, "utf8") !== stub) {
|
|
console.error(`stale: ${skillName}/SKILL.md`);
|
|
stale += 1;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
fs.writeFileSync(target, stub);
|
|
}
|
|
|
|
if (check && stale > 0) {
|
|
console.error(`\n${stale} stub(s) out of date. Run: node scripts/generate-skill-stubs.js`);
|
|
process.exit(1);
|
|
}
|
|
|
|
console.log(
|
|
check
|
|
? `skill stubs are up to date (${skills.length} skills)`
|
|
: `generated ${skills.length} skill stubs`,
|
|
);
|
|
}
|
|
|
|
main();
|
|
|
|
module.exports = { SAFETY_FLOOR, legalDisclaimerSection, renderStub };
|