import { promises as fsp } from 'node:fs'; import path from 'node:path'; import { writeFile } from './write-file'; import { SkillFilesResponse } from './fetch-skill-files'; const generateClaudeMd = (productModuleName: string): string => { return `# ${productModuleName} - AI Agent Instructions ## MANDATORY: Read Documentation Before ANY Change Before making any change to code, schemas, or configuration: 1. **Read \`docs/overview.md\` FIRST** — it maps every task type to the specific rule files you need 2. **Read only the relevant \`.cursor/rules/*.mdc\` files** for your task (the overview tells you which ones) 3. Only then start implementing changes Do NOT read all rule files. The overview tells you exactly which 2-4 files you need for any given task. --- ## Quick Task Map | Task Type | Rule files to read (in \`.cursor/rules/\`) | |-----------|-------------------------------------------| | Writing hooks in \`code/\` | \`product-module-code--product-module-code-basics.mdc\` + the relevant hook file | | Updating \`.root-config.json\` | \`configuration-guide--root-config-critical-updates.mdc\` + relevant settings file | | Quote/application schemas | \`schema-form--schema-form-overview-and-rules.mdc\` + \`schema-form--schema-form-forbidden-properties-and-anti-patterns.mdc\` | | Claim workflow schemas | \`claim-blocks--claim-blocks-overview-and-wrapper.mdc\` + relevant block type file | | CLI commands | \`workbench-cli--workbench-cli-safety-and-core-sync.mdc\` | | Embed config changes | \`embed-config--embed-config-overview-and-global-settings.mdc\` + relevant section file | For the full task map with all files, see \`docs/overview.md\`. --- ## Key Rules (MUST FOLLOW) 1. **No import/export statements** - All functions are available globally 2. **Always update .root-config.json** - When adding alteration hooks, scheduled functions, or fulfillment types 3. **Always use -f flag** - Use \`npx @rootplatform/cli push -f\` for draft updates 4. **Validate all inputs** - Use Joi validation schemas 5. **Currency values in cents** - Always integers, never floating point (R100 = 10000) 6. **Ask before pushing** - ALWAYS confirm with user before running push commands --- ## CLI Commands | Command | Description | |---------|-------------| | \`npx @rootplatform/cli push -f\` | Push changes to draft | | \`npx @rootplatform/cli test\` | Run unit tests | | \`npx @rootplatform/cli publish\` | Publish draft to live | | \`node preview/server.js\` | Start preview server | --- ## Project Structure | Folder/File | Purpose | |-------------|---------| | \`code/\` | Product module JavaScript (NO import/export) | | \`workflows/\` | JSON schemas (quote, application, claims) | | \`workflows/alteration-hooks/\` | Alteration hook schemas | | \`documents/\` | HTML templates for policy documents | | \`.root-config.json\` | Product module configuration | | \`docs/overview.md\` | Documentation index (read this first) | | \`.cursor/rules/\` | Full reference docs (rule files by domain) | `; }; export const writeSkillFiles = async (params: { directory: string; skillFiles: SkillFilesResponse; productModuleName: string; }): Promise => { const { directory, skillFiles, productModuleName } = params; const cursorRulesDir = path.join(directory, '.cursor', 'rules'); const docsDir = path.join(directory, 'docs'); await fsp.mkdir(cursorRulesDir, { recursive: true }); await fsp.mkdir(docsDir, { recursive: true }); // Write overview doc if (skillFiles.overview) { await writeFile(path.join(docsDir, 'overview.md'), skillFiles.overview); } // Write CLAUDE.md await writeFile(path.join(directory, 'CLAUDE.md'), generateClaudeMd(productModuleName)); // Write skill files as .cursor/rules/{domain}--{filename} for (const skill of skillFiles.skills) { const targetFilename = `${skill.domain}--${skill.filename}`; await writeFile(path.join(cursorRulesDir, targetFilename), skill.content); } };