// Framebrick Agent Skills installer (https://framebrick.co/install). Read it before you run it: it only downloads 3 SKILL.md files. const fs = require("node:fs"); const os = require("node:os"); const path = require("node:path"); const crypto = require("node:crypto"); const SITE = process.env.FRAMEBRICK_SITE || "https://framebrick.co"; // FRAMEBRICK_SITE: test against another copy of the site const SKILLS = ["framebrick","framebrick-blocks","framebrick-templates"]; const args = process.argv.slice(2); const flag = (name) => args.includes(name); const value = (name) => (args.includes(name) ? args[args.indexOf(name) + 1] : undefined); if (flag("--help") || flag("-h")) { console.log("Usage: curl -fsSL " + SITE + "/install | node - [--project | --dir ] [--only name,name] [--dry-run]"); console.log("Skills: " + SKILLS.join(", ")); console.log("Default folder: ~/.claude/skills (Claude Code). --project writes ./.claude/skills. --dir writes any folder an agent reads skills from."); process.exit(0); } const root = value("--dir") ? path.resolve(value("--dir")) : flag("--project") ? path.resolve(".claude", "skills") : path.join(os.homedir(), ".claude", "skills"); const only = value("--only") ? value("--only").split(",").map((s) => s.trim()) : SKILLS; const unknown = only.filter((name) => !SKILLS.includes(name)); if (unknown.length) { console.error("Unknown skill: " + unknown.join(", ") + ". Available: " + SKILLS.join(", ")); process.exit(1); } const dry = flag("--dry-run"); (async () => { console.log((dry ? "Dry run: " : "") + "Installing " + only.length + " Framebrick skill(s) into " + root); for (const name of only) { const response = await fetch(SITE + "/skills/" + name + "/SKILL.md"); if (!response.ok) throw new Error(name + ": " + response.status + " from " + SITE); const text = await response.text(); if (!text.startsWith("---\nname: " + name)) throw new Error(name + ": the file is not a skill (no front matter)"); const target = path.join(root, name, "SKILL.md"); const sha = crypto.createHash("sha256").update(text).digest("hex").slice(0, 12); if (!dry) { fs.mkdirSync(path.dirname(target), { recursive: true }); fs.writeFileSync(target, text); } console.log(" " + (dry ? "would write " : "wrote ") + target + " (" + text.length + " bytes, sha256 " + sha + ")"); } console.log(dry ? "Nothing was written." : "Done. Restart your agent so it picks the skills up."); })().catch((error) => { console.error(String(error.message || error)); process.exit(1); });