{"version":3,"file":"index.cjs","names":["readAsset","path","fs","v"],"sources":["../../../src/installSkills/index.ts"],"sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { readAsset } from 'utils:asset';\nimport { v } from '@intlayer/config/logger';\nimport { getMarkdownMetadata } from '@intlayer/core/markdown';\n\n/**\n * Metadata for each available documentation skill.\n */\nexport const SKILLS_METADATA = {\n  Config: 'Intlayer configuration documentation',\n  Content: 'Reference for all Intlayer content node types (t, enu, etc.)',\n  Usage: 'How to use Intlayer in your project',\n  CLI: 'Intlayer CLI commands and usage',\n  Compiler:\n    'Intlayer Compiler setup and usage for automatic content extraction without .content files',\n  RemoteContent: 'How to use Intlayer with Remote/CMS/Server-side content',\n  NextJS: 'Next.js-specific usage (Server & Client components)',\n  React: 'React-specific syntax and hooks usage',\n  Vue: 'Vue-specific composables and syntax',\n  Svelte: 'Svelte-specific stores and syntax',\n  Angular: 'Angular-specific syntax and Injectable Function usage',\n  Preact: 'Preact-specific syntax and hooks usage',\n  Solid:\n    'Integrates Intlayer internationalization with SolidJS components. Use when the user asks to \"setup SolidJS i18n\", use the \"useIntlayer\" hook in Solid, or manage locales in a SolidJS application.',\n  Astro: 'Astro-specific usage and getIntlayer',\n} as const;\n\nexport type Skill = keyof typeof SKILLS_METADATA;\n\nexport const SKILLS = Object.keys(SKILLS_METADATA) as Skill[];\n\nexport const getInitialSkills = (\n  deps: Record<string, string>\n): (keyof typeof SKILLS_METADATA)[] => {\n  const skills: (keyof typeof SKILLS_METADATA)[] = [\n    'Usage',\n    'Content',\n    'Config',\n    'CLI',\n    'Compiler',\n  ];\n\n  if (deps.next) skills.push('NextJS');\n  if (deps.react || !deps.next) skills.push('React');\n  if (deps.preact) skills.push('Preact');\n  if (deps['solid-js']) skills.push('Solid');\n  if (deps.vue || deps.nuxt) skills.push('Vue');\n  if (deps.svelte || deps['@sveltejs/kit']) skills.push('Svelte');\n  if (deps.astro) skills.push('Astro');\n\n  return skills;\n};\n\nexport interface PlatformMetadata {\n  label: string;\n  dir: string;\n  check?: () => boolean;\n}\n\n/**\n * Metadata and configuration for each supported platform.\n */\nexport const PLATFORMS_METADATA: Record<string, PlatformMetadata> = {\n  Cursor: {\n    label: 'Cursor',\n    dir: '.cursor/skills',\n    check: () =>\n      process.env.CURSOR === 'true' || process.env.TERM_PROGRAM === 'cursor',\n  },\n  Windsurf: {\n    label: 'Windsurf',\n    dir: '.windsurf/skills',\n    check: () =>\n      process.env.WINDSURF === 'true' ||\n      process.env.TERM_PROGRAM === 'windsurf',\n  },\n  Trae: {\n    label: 'Trae',\n    dir: '.trae/skills',\n    check: () =>\n      process.env.TRAE === 'true' || process.env.TERM_PROGRAM === 'trae',\n  },\n  TraeCN: {\n    label: 'Trae CN',\n    dir: '.trae/skills',\n    check: () => process.env.TRAE_CN === 'true',\n  },\n  VSCode: {\n    label: 'VS Code',\n    dir: '.vscode/skills',\n    check: () =>\n      process.env.VSCODE === 'true' || process.env.TERM_PROGRAM === 'vscode',\n  },\n  OpenCode: {\n    label: 'OpenCode',\n    dir: '.opencode/skills',\n    check: () => process.env.OPENCODE === 'true',\n  },\n  Claude: {\n    label: 'Claude Code',\n    dir: '.claude/skills',\n    check: () => process.env.CLAUDE === 'true',\n  },\n  GitHub: {\n    label: 'GitHub Copilot Workspace',\n    dir: '.github/skills',\n    check: () =>\n      process.env.GITHUB_ACTIONS === 'true' || !!process.env.GITHUB_WORKSPACE,\n  },\n  Antigravity: {\n    label: 'Antigravity',\n    dir: '.agent/skills',\n  },\n  Augment: {\n    label: 'Augment',\n    dir: '.augment/skills',\n  },\n  OpenClaw: {\n    label: 'OpenClaw',\n    dir: 'skills',\n  },\n  Cline: {\n    label: 'Cline',\n    dir: '.cline/skills',\n  },\n  CodeBuddy: {\n    label: 'CodeBuddy',\n    dir: '.codebuddy/skills',\n  },\n  CommandCode: {\n    label: 'Command Code',\n    dir: '.commandcode/skills',\n  },\n  Continue: {\n    label: 'Continue',\n    dir: '.continue/skills',\n  },\n  Crush: {\n    label: 'Crush',\n    dir: '.crush/skills',\n  },\n  Droid: {\n    label: 'Droid',\n    dir: '.factory/skills',\n  },\n  Goose: {\n    label: 'Goose',\n    dir: '.goose/skills',\n  },\n  IFlow: {\n    label: 'iFlow CLI',\n    dir: '.iflow/skills',\n  },\n  Junie: {\n    label: 'Junie',\n    dir: '.junie/skills',\n  },\n  KiloCode: {\n    label: 'Kilo Code',\n    dir: '.kilocode/skills',\n  },\n  Kiro: {\n    label: 'Kiro CLI',\n    dir: '.kiro/skills',\n  },\n  Kode: {\n    label: 'Kode',\n    dir: '.kode/skills',\n  },\n  MCPJam: {\n    label: 'MCPJam',\n    dir: '.mcpjam/skills',\n  },\n  MistralVibe: {\n    label: 'Mistral Vibe',\n    dir: '.vibe/skills',\n  },\n  Mux: {\n    label: 'Mux',\n    dir: '.mux/skills',\n  },\n  OpenHands: {\n    label: 'OpenHands',\n    dir: '.openhands/skills',\n  },\n  Pi: {\n    label: 'Pi',\n    dir: '.pi/skills',\n  },\n  Qoder: {\n    label: 'Qoder',\n    dir: '.qoder/skills',\n  },\n  Qwen: {\n    label: 'Qwen Code',\n    dir: '.qwen/skills',\n  },\n  RooCode: {\n    label: 'Roo Code',\n    dir: '.roo/skills',\n  },\n  Zencoder: {\n    label: 'Zencoder',\n    dir: '.zencoder/skills',\n  },\n  Neovate: {\n    label: 'Neovate',\n    dir: '.neovate/skills',\n  },\n  Pochi: {\n    label: 'Pochi',\n    dir: '.pochi/skills',\n  },\n  Other: {\n    label: 'Other',\n    dir: 'skills',\n  },\n} as const;\n\nexport type Platform = keyof typeof PLATFORMS_METADATA;\n\nexport const PLATFORMS = Object.keys(PLATFORMS_METADATA) as Platform[];\n\n/**\n * Maps specific skill keys to special filenames if they differ from standard snake_case.\n */\nconst SKILL_FILENAME_MAP: Partial<Record<Skill, string>> = {};\n\n/**\n * Helper to convert CamelCase to kebab-case for directory naming\n */\nconst camelToKebabCase = (str: string) =>\n  str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();\n\n/**\n * Reads the raw markdown content for a specific skill from the assets folder.\n */\nconst getSkillContent = (skill: Skill): string => {\n  const baseName = SKILL_FILENAME_MAP[skill] ?? camelToKebabCase(skill);\n  const fileName = `./skills/${baseName}.md`;\n\n  try {\n    return readAsset(fileName);\n  } catch {\n    console.warn(\n      `Warning: Could not read asset for skill: ${skill} at ${fileName}`\n    );\n    return '';\n  }\n};\n\n/**\n * Reads the licence content from the assets folder.\n */\nconst getLicenceContent = (): string => {\n  try {\n    return readAsset('./LICENCE.md');\n  } catch {\n    console.warn('Warning: Could not read LICENCE.md asset');\n    return '';\n  }\n};\n\nconst ALLOWED_FETCH_HOSTS = new Set(['intlayer.org']);\n\n/**\n * Fetches the content of a URL using native fetch.\n */\nconst fetchUrlContent = async (url: string): Promise<string> => {\n  const parsed = new URL(url);\n  if (\n    parsed.protocol !== 'https:' ||\n    !ALLOWED_FETCH_HOSTS.has(parsed.hostname)\n  ) {\n    throw new Error(`Blocked fetch to disallowed host: ${parsed.hostname}`);\n  }\n  const response = await fetch(url, { redirect: 'error' });\n  if (!response.ok) {\n    throw new Error(`Failed to fetch ${url}: ${response.statusText}`);\n  }\n  return response.text();\n};\n\n/**\n * Installs skills using the \"Agent Skills\" directory standard.\n * Standard: <PROJECT_ROOT>/<CONFIG_DIR>/skills/<SKILL_NAME>/SKILL.md\n */\nexport const installSkills = async (\n  projectRoot: string,\n  platform: Platform,\n  skills: Skill[]\n): Promise<string> => {\n  // Determine destination directory\n  const relativeDir = PLATFORMS_METADATA[platform].dir ?? 'skills';\n  const skillsBaseDir = path.join(projectRoot, relativeDir);\n\n  // Ensure the base directory exists\n  await fs.mkdir(skillsBaseDir, { recursive: true });\n\n  const createdSkills: string[] = [];\n  const licenceContent = getLicenceContent();\n\n  for (const skill of skills) {\n    const baseName = SKILL_FILENAME_MAP[skill] ?? camelToKebabCase(skill);\n    const skillName = `intlayer-${baseName}`;\n    const skillContent = getSkillContent(skill);\n\n    if (!skillContent) continue;\n\n    // Extract unique URLs\n    const urls = Array.from(\n      new Set(skillContent.match(/https:\\/\\/intlayer\\.org\\/[^\\s)]+\\.md/g) || [])\n    );\n\n    // Agent Standard: .../skills/<skill-name>/SKILL.md\n    const skillDir = path.join(skillsBaseDir, skillName);\n    const referenceDir = path.join(skillDir, 'references');\n\n    // Ensure directories exist\n    await fs.mkdir(referenceDir, { recursive: true });\n\n    // Write License\n    if (licenceContent) {\n      await fs.writeFile(\n        path.join(skillDir, 'LICENCE.md'),\n        licenceContent,\n        'utf-8'\n      );\n    }\n\n    let updatedSkillContent = skillContent;\n\n    // Parallel download of references\n    const downloadPromises = urls.map(async (url) => {\n      try {\n        const content = await fetchUrlContent(url);\n        const metadata = getMarkdownMetadata<{ slugs?: string[] }>(content);\n\n        let fileName = '';\n\n        // Determine filename from slugs or URL path\n        if (Array.isArray(metadata.slugs)) {\n          fileName = metadata.slugs.filter((slug) => slug !== 'doc').join('_');\n        } else {\n          const urlPath = new URL(url).pathname;\n          fileName = urlPath\n            .split('/')\n            .filter((part) => part && part !== 'doc')\n            .map((part) => part.replace('.md', '')) // Clean extension for joining\n            .join('_');\n        }\n\n        // Ensure it ends with .md\n        fileName = fileName ? `${fileName}.md` : 'index.md';\n        const localRefPath = `references/${fileName}`;\n\n        return {\n          url,\n          localRefPath,\n          fileName,\n          content,\n          success: true,\n        };\n      } catch (error) {\n        console.warn(\n          `Warning: Failed to download ref ${url} for skill ${skill}`,\n          error\n        );\n        return { url, success: false };\n      }\n    });\n\n    const results = await Promise.all(downloadPromises);\n\n    // Process results: Write files and update content string\n    for (const res of results) {\n      if (res.success && res.fileName && res.content && res.localRefPath) {\n        // Write the reference file\n        await fs.writeFile(\n          path.join(referenceDir, res.fileName),\n          res.content,\n          'utf-8'\n        );\n\n        // Update the main content to point to local file\n        updatedSkillContent = updatedSkillContent.replaceAll(\n          res.url,\n          res.localRefPath\n        );\n      }\n    }\n\n    // Write the main SKILL.md\n    const filePath = path.join(skillDir, 'SKILL.md');\n    await fs.writeFile(filePath, updatedSkillContent, 'utf-8');\n    createdSkills.push(`${skillName}/SKILL.md`);\n  }\n\n  if (createdSkills.length === 0) {\n    return `No skill files were created. Check your asset paths.`;\n  }\n\n  return `${v} Created ${createdSkills.length} skills in ${skillsBaseDir}`;\n};\n"],"mappings":"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"}