@agents-inc/cli 0.74.2 → 0.74.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/{chunk-H4OIZV7U.js → chunk-23OJO4JS.js} +4 -4
  3. package/dist/{chunk-44F6SUEX.js → chunk-2NWQS7N4.js} +2 -2
  4. package/dist/{chunk-CC6TML4P.js → chunk-ALCUVCY5.js} +3 -3
  5. package/dist/{chunk-PCR4DZH3.js → chunk-AV5KJHP2.js} +2 -2
  6. package/dist/{chunk-AXZJ63V5.js → chunk-DUF4UVJB.js} +2 -2
  7. package/dist/{chunk-3U3PDPFQ.js → chunk-GJLM53PH.js} +2 -2
  8. package/dist/{chunk-YNLRLJ6P.js → chunk-N2HO5IT2.js} +6 -4
  9. package/dist/chunk-N2HO5IT2.js.map +1 -0
  10. package/dist/{chunk-6XHBWP2D.js → chunk-OLS55LVJ.js} +2 -2
  11. package/dist/{chunk-ORXRSFEA.js → chunk-SFZQL6DJ.js} +2 -2
  12. package/dist/{chunk-ZMMUR2NZ.js → chunk-TUILIOBW.js} +9 -9
  13. package/dist/{chunk-6H6T3SZI.js → chunk-UVNIFNIN.js} +2 -2
  14. package/dist/{chunk-JDUYWY6S.js → chunk-XYXDEODG.js} +3 -3
  15. package/dist/{chunk-FUWLQBKW.js → chunk-ZD3U734W.js} +5 -4
  16. package/dist/chunk-ZD3U734W.js.map +1 -0
  17. package/dist/{chunk-I7VZ6HVE.js → chunk-ZNXK2J6R.js} +2 -2
  18. package/dist/{chunk-UTJ45YM6.js → chunk-ZWYCZ7BN.js} +2 -2
  19. package/dist/commands/build/plugins.js +2 -2
  20. package/dist/commands/build/stack.js +2 -2
  21. package/dist/commands/compile.js +2 -2
  22. package/dist/commands/config/index.js +2 -2
  23. package/dist/commands/config/path.js +1 -1
  24. package/dist/commands/config/show.js +2 -2
  25. package/dist/commands/diff.js +1 -1
  26. package/dist/commands/doctor.js +1 -1
  27. package/dist/commands/edit.js +12 -12
  28. package/dist/commands/eject.js +1 -1
  29. package/dist/commands/import/skill.js +1 -1
  30. package/dist/commands/info.js +1 -1
  31. package/dist/commands/init.js +12 -12
  32. package/dist/commands/list.js +1 -1
  33. package/dist/commands/new/agent.js +2 -2
  34. package/dist/commands/new/marketplace.js +2 -2
  35. package/dist/commands/new/skill.js +2 -2
  36. package/dist/commands/outdated.js +1 -1
  37. package/dist/commands/search.js +1 -1
  38. package/dist/commands/uninstall.js +1 -1
  39. package/dist/commands/update.js +2 -2
  40. package/dist/commands/validate.js +4 -2
  41. package/dist/commands/validate.js.map +1 -1
  42. package/dist/components/wizard/category-grid.test.js +2 -2
  43. package/dist/components/wizard/domain-selection.js +3 -3
  44. package/dist/components/wizard/source-grid.test.js +2 -2
  45. package/dist/components/wizard/stack-selection.js +3 -3
  46. package/dist/components/wizard/step-agents.js +3 -3
  47. package/dist/components/wizard/step-agents.test.js +3 -3
  48. package/dist/components/wizard/step-build.js +3 -3
  49. package/dist/components/wizard/step-build.test.js +3 -3
  50. package/dist/components/wizard/step-confirm.test.js +2 -2
  51. package/dist/components/wizard/step-settings.js +2 -2
  52. package/dist/components/wizard/step-settings.test.js +5 -5
  53. package/dist/components/wizard/step-sources.js +3 -3
  54. package/dist/components/wizard/step-sources.test.js +3 -3
  55. package/dist/components/wizard/step-stack.js +5 -5
  56. package/dist/components/wizard/step-stack.test.js +5 -5
  57. package/dist/components/wizard/wizard-layout.js +3 -3
  58. package/dist/components/wizard/wizard.js +11 -11
  59. package/dist/hooks/init.js +12 -12
  60. package/dist/{source-loader-2AOYLOMV.js → source-loader-VTNIFSL6.js} +2 -2
  61. package/dist/{source-manager-754LZUVK.js → source-manager-FWAJVMYS.js} +2 -2
  62. package/dist/stores/wizard-store.js +2 -2
  63. package/dist/stores/wizard-store.test.js +2 -2
  64. package/package.json +1 -1
  65. package/dist/chunk-FUWLQBKW.js.map +0 -1
  66. package/dist/chunk-YNLRLJ6P.js.map +0 -1
  67. package/dist/plugins/dummy-skill/.claude-plugin/.content-hash +0 -1
  68. package/dist/plugins/dummy-skill/.claude-plugin/plugin.json +0 -13
  69. /package/dist/{chunk-H4OIZV7U.js.map → chunk-23OJO4JS.js.map} +0 -0
  70. /package/dist/{chunk-44F6SUEX.js.map → chunk-2NWQS7N4.js.map} +0 -0
  71. /package/dist/{chunk-CC6TML4P.js.map → chunk-ALCUVCY5.js.map} +0 -0
  72. /package/dist/{chunk-PCR4DZH3.js.map → chunk-AV5KJHP2.js.map} +0 -0
  73. /package/dist/{chunk-AXZJ63V5.js.map → chunk-DUF4UVJB.js.map} +0 -0
  74. /package/dist/{chunk-3U3PDPFQ.js.map → chunk-GJLM53PH.js.map} +0 -0
  75. /package/dist/{chunk-6XHBWP2D.js.map → chunk-OLS55LVJ.js.map} +0 -0
  76. /package/dist/{chunk-ORXRSFEA.js.map → chunk-SFZQL6DJ.js.map} +0 -0
  77. /package/dist/{chunk-ZMMUR2NZ.js.map → chunk-TUILIOBW.js.map} +0 -0
  78. /package/dist/{chunk-6H6T3SZI.js.map → chunk-UVNIFNIN.js.map} +0 -0
  79. /package/dist/{chunk-JDUYWY6S.js.map → chunk-XYXDEODG.js.map} +0 -0
  80. /package/dist/{chunk-I7VZ6HVE.js.map → chunk-ZNXK2J6R.js.map} +0 -0
  81. /package/dist/{chunk-UTJ45YM6.js.map → chunk-ZWYCZ7BN.js.map} +0 -0
  82. /package/dist/{source-loader-2AOYLOMV.js.map → source-loader-VTNIFSL6.js.map} +0 -0
  83. /package/dist/{source-manager-754LZUVK.js.map → source-manager-FWAJVMYS.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/lib/loading/source-loader.ts","../src/cli/lib/metadata-keys.ts","../src/cli/lib/configuration/index.ts","../src/cli/lib/configuration/config.ts","../src/cli/lib/configuration/config-loader.ts","../src/cli/lib/configuration/config-generator.ts","../src/cli/lib/configuration/config-merger.ts","../src/cli/lib/configuration/project-config.ts","../src/cli/lib/stacks/stacks-loader.ts","../src/cli/lib/configuration/config-saver.ts","../src/cli/lib/configuration/config-writer.ts","../src/cli/lib/configuration/config-types-writer.ts","../src/cli/lib/configuration/source-manager.ts","../src/cli/lib/loading/source-fetcher.ts","../src/cli/lib/skills/local-skill-loader.ts","../src/cli/lib/loading/index.ts","../src/cli/lib/loading/multi-source-loader.ts","../src/cli/lib/matrix/index.ts","../src/cli/lib/matrix/matrix-loader.ts","../src/cli/lib/matrix/skill-resolution.ts","../src/cli/lib/matrix/matrix-resolver.ts","../src/cli/lib/matrix/matrix-health-check.ts","../src/cli/lib/plugins/index.ts","../src/cli/lib/plugins/plugin-manifest.ts","../src/cli/lib/plugins/plugin-finder.ts","../src/cli/lib/plugins/plugin-info.ts","../src/cli/lib/installation/index.ts","../src/cli/lib/installation/installation.ts","../src/cli/lib/installation/local-installer.ts","../src/cli/lib/skills/index.ts","../src/cli/lib/skills/skill-metadata.ts","../src/cli/lib/versioning.ts","../src/cli/lib/skills/skill-copier.ts","../src/cli/lib/skills/skill-plugin-compiler.ts","../src/cli/lib/skills/source-switcher.ts","../src/cli/lib/stacks/index.ts","../src/cli/lib/stacks/stack-plugin-compiler.ts","../src/cli/lib/compiler.ts","../src/cli/lib/resolver.ts","../src/cli/utils/frontmatter.ts","../src/cli/utils/exec.ts","../src/cli/lib/installation/mode-migrator.ts","../src/cli/lib/plugins/plugin-discovery.ts","../src/cli/lib/plugins/plugin-settings.ts","../src/cli/lib/plugins/plugin-validator.ts","../src/cli/lib/schema-validator.ts"],"sourcesContent":["import os from \"os\";\nimport path from \"path\";\nimport {\n PROJECT_ROOT,\n SKILL_CATEGORIES_PATH,\n SKILL_RULES_PATH,\n SKILLS_DIR_PATH,\n} from \"../../consts\";\nimport { defaultCategories } from \"../configuration/default-categories\";\nimport { defaultRules } from \"../configuration/default-rules\";\nimport { defaultStacks } from \"../configuration/default-stacks\";\nimport { LOCAL_DEFAULTS } from \"../metadata-keys\";\nimport type {\n AgentDefinition,\n AgentName,\n CategoryMap,\n Domain,\n MergedSkillsMatrix,\n RelationshipDefinitions,\n ResolvedSkill,\n ResolvedStack,\n SkillAssignment,\n SkillId,\n Stack,\n Category,\n} from \"../../types\";\nimport { fileExists } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport { typedEntries, typedKeys } from \"../../utils/typed-object\";\nimport {\n DEFAULT_SOURCE,\n isLocalSource,\n loadProjectSourceConfig,\n resolveSource,\n type ResolvedConfig,\n} from \"../configuration\";\nimport { discoverLocalSkills, type LocalSkillDiscoveryResult } from \"../skills\";\nimport {\n checkMatrixHealth,\n extractAllSkills,\n loadSkillCategories,\n loadSkillRules,\n mergeMatrixWithSkills,\n} from \"../matrix\";\nimport { loadAllAgents } from \"./loader\";\nimport { fetchFromSource, fetchMarketplace } from \"./source-fetcher\";\nimport { loadSkillsFromAllSources } from \"./multi-source-loader\";\nimport { loadStacks, resolveAgentConfigToSkills } from \"../stacks\";\nimport { initializeMatrix, matrix as currentMatrix } from \"../matrix/matrix-provider\";\nimport { BUILT_IN_MATRIX } from \"../../types/generated/matrix\";\n\nexport type SourceLoadOptions = {\n sourceFlag?: string;\n projectDir?: string;\n forceRefresh?: boolean;\n devMode?: boolean;\n /** Skip loading skills from extra sources (multi-source). Only needed for wizard UI tagging. */\n skipExtraSources?: boolean;\n};\n\nexport type SourceLoadResult = {\n matrix: MergedSkillsMatrix;\n sourceConfig: ResolvedConfig;\n sourcePath: string;\n isLocal: boolean;\n marketplace?: string;\n};\n\nexport async function loadSkillsMatrixFromSource(\n options: SourceLoadOptions = {},\n): Promise<SourceLoadResult> {\n const { sourceFlag, projectDir, forceRefresh = false, devMode = false } = options;\n\n const sourceConfig = await resolveSource(sourceFlag, projectDir);\n const { source } = sourceConfig;\n\n verbose(`Loading skills from source: ${source}`);\n\n let result: SourceLoadResult;\n\n if (source === DEFAULT_SOURCE && !devMode) {\n // Default source: use pre-computed BUILT_IN_MATRIX instead of loading from disk\n result = {\n matrix: {\n ...BUILT_IN_MATRIX,\n skills: { ...BUILT_IN_MATRIX.skills },\n categories: { ...BUILT_IN_MATRIX.categories },\n suggestedStacks: [...BUILT_IN_MATRIX.suggestedStacks],\n },\n sourceConfig,\n sourcePath: \"\",\n isLocal: false,\n marketplace: sourceConfig.marketplace,\n };\n } else {\n const isLocal = isLocalSource(source) || devMode === true;\n\n if (isLocal) {\n result = await loadFromLocal(source, sourceConfig);\n } else {\n result = await loadFromRemote(source, sourceConfig, forceRefresh);\n }\n }\n\n const resolvedProjectDir = projectDir || process.cwd();\n\n let localSkillsResult = await discoverLocalSkills(resolvedProjectDir);\n\n // If no local skills in project, try global (home directory)\n const homeDir = os.homedir();\n if (\n (!localSkillsResult || localSkillsResult.skills.length === 0) &&\n resolvedProjectDir !== homeDir\n ) {\n localSkillsResult = await discoverLocalSkills(homeDir);\n }\n\n if (localSkillsResult && localSkillsResult.skills.length > 0) {\n verbose(\n `Found ${localSkillsResult.skills.length} local skill(s) in ${localSkillsResult.localSkillsPath}`,\n );\n result.matrix = mergeLocalSkillsIntoMatrix(result.matrix, localSkillsResult);\n }\n\n if (!options.skipExtraSources) {\n await loadSkillsFromAllSources(\n result.matrix,\n sourceConfig,\n resolvedProjectDir,\n forceRefresh,\n result.marketplace,\n );\n }\n\n checkMatrixHealth(result.matrix);\n initializeMatrix(result.matrix);\n\n return result;\n}\n\nasync function loadFromLocal(\n source: string,\n sourceConfig: ResolvedConfig,\n): Promise<SourceLoadResult> {\n let skillsPath: string;\n\n if (isLocalSource(source)) {\n skillsPath = path.isAbsolute(source) ? source : path.resolve(process.cwd(), source);\n } else {\n skillsPath = PROJECT_ROOT;\n }\n\n verbose(`Loading skills from local path: ${skillsPath}`);\n\n const mergedMatrix = await loadAndMergeFromBasePath(skillsPath);\n\n return {\n matrix: mergedMatrix,\n sourceConfig,\n sourcePath: skillsPath,\n isLocal: true,\n marketplace: sourceConfig.marketplace,\n };\n}\n\nasync function loadFromRemote(\n source: string,\n sourceConfig: ResolvedConfig,\n forceRefresh: boolean,\n): Promise<SourceLoadResult> {\n verbose(`Fetching skills from remote source: ${source}`);\n\n const fetchResult = await fetchFromSource(source, { forceRefresh });\n\n verbose(`Fetched to: ${fetchResult.path}`);\n\n const mergedMatrix = await loadAndMergeFromBasePath(fetchResult.path);\n\n // Try to read marketplace name from the source's .claude-plugin/marketplace.json.\n // This handles the case where sourceConfig.marketplace is undefined (e.g. during\n // `agentsinc init --source github:user/repo` before any project config exists).\n let marketplace = sourceConfig.marketplace;\n if (!marketplace) {\n try {\n const marketplaceResult = await fetchMarketplace(source, { forceRefresh });\n marketplace = marketplaceResult.marketplace.name;\n verbose(`Using marketplace name from marketplace.json: ${marketplace}`);\n } catch {\n // No marketplace.json — getMarketplaceLabel() handles the fallback display\n verbose(`Source does not have a marketplace.json — using source name as label`);\n }\n }\n\n return {\n matrix: mergedMatrix,\n sourceConfig,\n sourcePath: fetchResult.path,\n isLocal: false,\n marketplace,\n };\n}\n\nasync function loadAndMergeFromBasePath(basePath: string): Promise<MergedSkillsMatrix> {\n const sourceProjectConfig = await loadProjectSourceConfig(basePath);\n\n const skillsDirRelPath = sourceProjectConfig?.skillsDir ?? SKILLS_DIR_PATH;\n const stacksRelFile = sourceProjectConfig?.stacksFile;\n\n let categories: CategoryMap = defaultCategories;\n let relationships: RelationshipDefinitions = defaultRules.relationships;\n\n // Load source categories and rules (if they exist)\n const sourceCategoriesPath = path.join(basePath, SKILL_CATEGORIES_PATH);\n const sourceRulesPath = path.join(basePath, SKILL_RULES_PATH);\n const hasSourceCategories = await fileExists(sourceCategoriesPath);\n const hasSourceRules = await fileExists(sourceRulesPath);\n\n if (hasSourceCategories || hasSourceRules) {\n if (hasSourceCategories) {\n const sourceCategories = await loadSkillCategories(sourceCategoriesPath);\n categories = { ...defaultCategories, ...sourceCategories };\n verbose(\n `Loaded source categories: ${sourceCategoriesPath} (${typedKeys(sourceCategories).length} categories)`,\n );\n }\n\n if (hasSourceRules) {\n const sourceRules = await loadSkillRules(sourceRulesPath);\n\n // Merge relationships: concatenate arrays\n relationships = {\n conflicts: [\n ...defaultRules.relationships.conflicts,\n ...sourceRules.relationships.conflicts,\n ],\n discourages: [\n ...defaultRules.relationships.discourages,\n ...sourceRules.relationships.discourages,\n ],\n recommends: [\n ...defaultRules.relationships.recommends,\n ...sourceRules.relationships.recommends,\n ],\n requires: [...defaultRules.relationships.requires, ...sourceRules.relationships.requires],\n alternatives: [\n ...defaultRules.relationships.alternatives,\n ...sourceRules.relationships.alternatives,\n ],\n compatibleWith: [\n ...(defaultRules.relationships.compatibleWith ?? []),\n ...(sourceRules.relationships.compatibleWith ?? []),\n ],\n };\n\n verbose(`Loaded source rules: ${sourceRulesPath}`);\n }\n\n verbose(`Matrix merged: CLI (${typedKeys(defaultCategories).length} categories) + source`);\n } else {\n verbose(`Matrix from CLI only (source has no categories/rules files)`);\n }\n\n const skillsDir = path.join(basePath, skillsDirRelPath);\n verbose(`Skills from source: ${skillsDir}`);\n\n const skills = await extractAllSkills(skillsDir);\n const mergedMatrix = mergeMatrixWithSkills(categories, relationships, skills);\n\n // Load stacks from source first, fall back to CLI's built-in defaults\n const sourceStacks = await loadStacks(basePath, stacksRelFile);\n const stacks = sourceStacks.length > 0 ? sourceStacks : defaultStacks;\n if (stacks.length > 0) {\n mergedMatrix.suggestedStacks = stacks.map((stack) => convertStackToResolvedStack(stack));\n const stackSource = sourceStacks.length > 0 ? \"source\" : \"CLI\";\n verbose(`Loaded ${stacks.length} stacks from ${stackSource}`);\n }\n\n // Collect explicit domain definitions from agent metadata.yaml files\n const agents = await loadAllAgents(basePath);\n const agentDefinedDomains: Partial<Record<AgentName, Domain>> = {};\n for (const [agentId, agentDef] of typedEntries<AgentName, AgentDefinition>(agents)) {\n if (agentDef.domain) {\n agentDefinedDomains[agentId] = agentDef.domain;\n }\n }\n if (typedKeys(agentDefinedDomains).length > 0) {\n mergedMatrix.agentDefinedDomains = agentDefinedDomains;\n verbose(`Loaded ${typedKeys(agentDefinedDomains).length} agent domain definition(s)`);\n }\n\n return mergedMatrix;\n}\n\n// Stack values are already skill IDs — no alias resolution needed\nfunction convertStackToResolvedStack(stack: Stack): ResolvedStack {\n const allSkillIds: SkillId[] = [];\n const seenSkillIds = new Set<SkillId>();\n const skills: Partial<Record<AgentName, Partial<Record<Category, SkillId[]>>>> = {};\n\n for (const agentId of typedKeys<AgentName>(stack.agents)) {\n const agentConfig = stack.agents[agentId];\n if (!agentConfig) continue;\n\n const skillRefs = resolveAgentConfigToSkills(agentConfig);\n const agentSkills: Partial<Record<Category, SkillId[]>> = {};\n\n for (const [category, assignments] of typedEntries<Category, SkillAssignment[]>(agentConfig)) {\n if (!assignments || assignments.length === 0) continue;\n const validIds = assignments.filter((a) => a.id in currentMatrix.skills).map((a) => a.id);\n if (validIds.length > 0) {\n agentSkills[category] = validIds;\n }\n }\n\n skills[agentId] = agentSkills;\n\n for (const ref of skillRefs) {\n if (!seenSkillIds.has(ref.id)) {\n seenSkillIds.add(ref.id);\n allSkillIds.push(ref.id);\n }\n }\n }\n\n const agentCount = typedKeys<AgentName>(stack.agents).length;\n verbose(`Stack '${stack.id}' has ${allSkillIds.length} skills from ${agentCount} agents`);\n\n return {\n id: stack.id,\n name: stack.name,\n description: stack.description,\n skills,\n allSkillIds,\n philosophy: stack.philosophy || \"\",\n };\n}\n\n/**\n * Extract a human-readable name from a source URL.\n * e.g. \"github:agents-inc/skills\" -> \"agents-inc\"\n * \"github:acme-corp/claude-skills\" -> \"acme-corp\"\n */\nfunction extractSourceName(source: string): string {\n // Strip protocol prefix (github:, gh:, https://, etc.)\n const withoutProtocol = source.replace(/^(?:github|gh|gitlab|bitbucket|sourcehut):/, \"\");\n const withoutUrl = withoutProtocol.replace(/^https?:\\/\\/[^/]+\\//, \"\");\n\n // Take the first path segment (org/owner name)\n const firstSegment = withoutUrl.split(\"/\")[0];\n return firstSegment || source;\n}\n\n/**\n * Compute a display label for the marketplace indicator in the wizard.\n *\n * Returns undefined when the source is local (no marketplace to display).\n *\n * Format examples:\n * \"Acme Corp + 1 public\" — private marketplace with public also available\n * \"Acme Corp\" — private marketplace only\n * \"agents-inc (public)\" — default public marketplace\n */\nexport function getMarketplaceLabel(sourceResult: SourceLoadResult): string | undefined {\n if (sourceResult.isLocal) return undefined;\n\n const { marketplace } = sourceResult;\n\n if (!marketplace) {\n const name = extractSourceName(sourceResult.sourceConfig.source);\n return `${name} (public)`;\n }\n\n // When using a non-default source, the public marketplace is also available\n const PUBLIC_MARKETPLACE_COUNT = 1;\n const isDefaultSource = sourceResult.sourceConfig.source === DEFAULT_SOURCE;\n if (!isDefaultSource) {\n return `${marketplace} + ${PUBLIC_MARKETPLACE_COUNT} public`;\n }\n\n return marketplace;\n}\n\nfunction mergeLocalSkillsIntoMatrix(\n matrix: MergedSkillsMatrix,\n localResult: LocalSkillDiscoveryResult,\n): MergedSkillsMatrix {\n for (const metadata of localResult.skills) {\n const existingSkill = matrix.skills[metadata.id];\n\n // If overwriting an existing remote skill, inherit its category unconditionally.\n // Otherwise, use whatever the local skill declared in its metadata.yaml.\n const category = existingSkill?.category ?? metadata.category;\n const slug = existingSkill?.slug ?? metadata.slug;\n const displayName = existingSkill?.displayName ?? metadata.displayName;\n\n const resolvedSkill: ResolvedSkill = {\n id: metadata.id,\n slug,\n displayName,\n description: metadata.description,\n usageGuidance: metadata.usageGuidance,\n\n category,\n tags: metadata.tags ?? [],\n\n author: LOCAL_DEFAULTS.AUTHOR,\n\n conflictsWith: existingSkill?.conflictsWith ?? [],\n isRecommended: existingSkill?.isRecommended ?? false,\n recommendedReason: existingSkill?.recommendedReason,\n requires: existingSkill?.requires ?? [],\n alternatives: existingSkill?.alternatives ?? [],\n discourages: existingSkill?.discourages ?? [],\n compatibleWith: existingSkill?.compatibleWith ?? [],\n\n path: metadata.path,\n\n local: true,\n localPath: metadata.localPath,\n custom: metadata.custom,\n };\n\n matrix.skills[metadata.id] = resolvedSkill;\n\n // Ensure the skill's category exists in matrix.categories so that\n // config-types generation can discover its domain and category.\n // Skip \"local\" — it is a pseudo-category, not a real Category union member.\n if (category !== \"local\" && !matrix.categories[category] && metadata.domain) {\n matrix.categories[category] = {\n id: category,\n displayName: category,\n description: `Local skill category`,\n domain: metadata.domain,\n exclusive: false,\n required: false,\n order: 0,\n };\n verbose(`Added local category: ${category} (domain: ${metadata.domain})`);\n }\n\n verbose(`Added local skill: ${metadata.id} (category: ${category})`);\n }\n\n return matrix;\n}\n","import { STANDARD_FILES, STANDARD_DIRS } from \"../consts\";\nimport type { CategoryPath } from \"../types\";\n\n/**\n * YAML field names used in skill metadata.yaml files.\n * Centralized to avoid string duplication across loaders and compilers.\n */\nexport const METADATA_KEYS = {\n DISPLAY_NAME: \"displayName\",\n CLI_DESCRIPTION: \"cliDescription\",\n CATEGORY: \"category\",\n FORKED_FROM: \"forkedFrom\",\n CONTENT_HASH: \"contentHash\",\n USAGE_GUIDANCE: \"usageGuidance\",\n} as const;\n\n/**\n * Default values used when importing third-party skills (no existing metadata).\n */\nexport const IMPORT_DEFAULTS = {\n CATEGORY: \"imported\" as CategoryPath,\n AUTHOR: \"@imported\",\n DOMAIN: \"shared\" as const,\n} as const;\n\n/**\n * Default values used for local skills (created via `agentsinc new skill` or discovered locally).\n */\nexport const LOCAL_DEFAULTS = {\n CATEGORY: \"dummy-category\" as CategoryPath,\n AUTHOR: \"@dummy-author\",\n DOMAIN: \"dummy\" as const,\n} as const;\n\n/**\n * Files included when computing a skill's content hash.\n * Shared by versioning.ts (for plugin version bumps) and\n * skill-plugin-compiler.ts (for plugin compilation).\n */\nexport const SKILL_CONTENT_FILES = [STANDARD_FILES.SKILL_MD, STANDARD_FILES.REFERENCE_MD] as const;\n\n/**\n * Directories included when computing a skill's content hash.\n * Shared by versioning.ts and skill-plugin-compiler.ts.\n */\nexport const SKILL_CONTENT_DIRS = [STANDARD_DIRS.EXAMPLES, STANDARD_DIRS.SCRIPTS] as const;\n","export {\n DEFAULT_SOURCE,\n SOURCE_ENV_VAR,\n PROJECT_CONFIG_FILE,\n type BrandingConfig,\n type SourceEntry,\n type ResolvedConfig,\n type ResolvedBranding,\n type AgentsSourceOrigin,\n type ResolvedAgentsSource,\n getProjectConfigPath,\n loadProjectSourceConfig,\n loadGlobalSourceConfig,\n resolveSource,\n resolveAgentsSource,\n formatOrigin,\n resolveAuthor,\n resolveBranding,\n resolveAllSources,\n isLocalSource,\n validateSourceFormat,\n} from \"./config\";\n\nexport {\n type ProjectConfigOptions,\n generateProjectConfigFromSkills,\n buildStackProperty,\n compactStackForYaml,\n} from \"./config-generator\";\n\nexport { type MergeContext, type MergeResult, mergeWithExistingConfig } from \"./config-merger\";\n\nexport { saveSourceToProjectConfig } from \"./config-saver\";\n\nexport {\n type LoadedProjectConfig,\n loadProjectConfig,\n loadProjectConfigFromDir,\n validateProjectConfig,\n} from \"./project-config\";\n\nexport { type SourceSummary, addSource, removeSource, getSourceSummary } from \"./source-manager\";\n\nexport { defineConfig } from \"./define-config\";\nexport { defaultCategories } from \"./default-categories\";\nexport { defaultRules } from \"./default-rules\";\nexport { defaultStacks } from \"./default-stacks\";\nexport { loadConfig } from \"./config-loader\";\nexport { generateConfigSource } from \"./config-writer\";\nexport {\n generateConfigTypesSource,\n generateProjectConfigTypesSource,\n getGlobalConfigTypesPath,\n type ConfigTypesBackgroundData,\n loadConfigTypesDataInBackground,\n regenerateConfigTypes,\n} from \"./config-types-writer\";\n","import os from \"os\";\nimport path from \"path\";\nimport { fileExists } from \"../../utils/fs\";\nimport { verbose, warn } from \"../../utils/logger\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { CLAUDE_SRC_DIR, DEFAULT_BRANDING, GITHUB_SOURCE, STANDARD_FILES } from \"../../consts\";\nimport { projectSourceConfigSchema } from \"../schemas\";\nimport type { ProjectConfig, SourceEntry } from \"../../types\";\nimport { loadConfig } from \"./config-loader\";\n\nexport const DEFAULT_SOURCE = `${GITHUB_SOURCE.GITHUB_PREFIX}agents-inc/skills`;\nexport const SOURCE_ENV_VAR = \"CC_SOURCE\";\nexport const PROJECT_CONFIG_FILE = STANDARD_FILES.CONFIG_TS;\n\n// Re-export types that moved to src/cli/types/config.ts for backward compatibility\nexport type { SourceEntry, BrandingConfig } from \"../../types/config\";\n\nexport type ResolvedConfig = {\n source: string;\n sourceOrigin: \"flag\" | \"env\" | \"project\" | \"default\";\n marketplace?: string;\n};\n\nexport function getProjectConfigPath(projectDir: string): string {\n return path.join(projectDir, CLAUDE_SRC_DIR, PROJECT_CONFIG_FILE);\n}\n\nexport async function loadProjectSourceConfig(\n projectDir: string,\n): Promise<Partial<ProjectConfig> | null> {\n const configPath = path.join(projectDir, CLAUDE_SRC_DIR, STANDARD_FILES.CONFIG_TS);\n\n if (!(await fileExists(configPath))) {\n verbose(`Project config not found at ${configPath}`);\n return null;\n }\n\n let data: Partial<ProjectConfig> | null;\n try {\n data = await loadConfig<Partial<ProjectConfig>>(configPath, projectSourceConfigSchema);\n } catch (error) {\n verbose(`Failed to load project source config at ${configPath}: ${getErrorMessage(error)}`);\n return null;\n }\n if (!data) return null;\n\n verbose(`Loaded project config from ${projectDir}`);\n return data;\n}\n\n/** Load source config from the global home directory (~/.claude-src/config.ts). */\nexport async function loadGlobalSourceConfig(): Promise<Partial<ProjectConfig> | null> {\n const homeDir = os.homedir();\n const globalConfigPath = path.join(homeDir, CLAUDE_SRC_DIR, STANDARD_FILES.CONFIG_TS);\n\n if (!(await fileExists(globalConfigPath))) {\n verbose(`Global config not found at ${globalConfigPath}`);\n return null;\n }\n\n let data: Partial<ProjectConfig> | null;\n try {\n data = await loadConfig<Partial<ProjectConfig>>(globalConfigPath, projectSourceConfigSchema);\n } catch (error) {\n verbose(\n `Failed to load global source config at ${globalConfigPath}: ${getErrorMessage(error)}`,\n );\n return null;\n }\n if (!data) return null;\n\n verbose(`Loaded global config from ${homeDir}`);\n return data;\n}\n\nasync function loadEffectiveSourceConfig(\n projectDir?: string,\n): Promise<Partial<ProjectConfig> | null> {\n const projectConfig = projectDir ? await loadProjectSourceConfig(projectDir) : null;\n return projectConfig ?? (await loadGlobalSourceConfig());\n}\n\n// Precedence: flag > env > project > global > default\nexport async function resolveSource(\n flagValue?: string,\n projectDir?: string,\n): Promise<ResolvedConfig> {\n const effectiveConfig = await loadEffectiveSourceConfig(projectDir);\n const marketplace = effectiveConfig?.marketplace;\n\n if (flagValue !== undefined) {\n if (flagValue === \"\" || flagValue.trim() === \"\") {\n throw new Error(\n \"--source flag cannot be empty. Provide a valid source: a local directory path or a git repository URL (e.g., './my-skills' or 'https://github.com/user/repo')\",\n );\n }\n validateSourceFormat(flagValue.trim(), \"--source\");\n verbose(`Source from --source flag: ${flagValue}`);\n return { source: flagValue, sourceOrigin: \"flag\", marketplace };\n }\n\n const envValue = process.env[SOURCE_ENV_VAR];\n if (envValue) {\n const trimmed = envValue.trim();\n if (trimmed === \"\") {\n warn(`${SOURCE_ENV_VAR} is set but empty — ignoring and falling back to next source.`);\n } else {\n try {\n validateSourceFormat(trimmed, SOURCE_ENV_VAR);\n verbose(`Source from ${SOURCE_ENV_VAR} env var: ${trimmed}`);\n return { source: trimmed, sourceOrigin: \"env\", marketplace };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n warn(\n `${SOURCE_ENV_VAR} has an invalid value — ignoring and falling back to next source.\\n${message}`,\n );\n }\n }\n }\n\n if (effectiveConfig?.source) {\n verbose(`Source from project config: ${effectiveConfig.source}`);\n return {\n source: effectiveConfig.source,\n sourceOrigin: \"project\",\n marketplace,\n };\n }\n\n verbose(`Using default source: ${DEFAULT_SOURCE}`);\n return { source: DEFAULT_SOURCE, sourceOrigin: \"default\", marketplace };\n}\n\nexport type AgentsSourceOrigin = \"flag\" | \"project\" | \"default\";\n\nexport type ResolvedAgentsSource = {\n agentsSource?: string;\n agentsSourceOrigin: AgentsSourceOrigin;\n};\n\n// Precedence: flag > project > global > default (undefined)\nexport async function resolveAgentsSource(\n flagValue?: string,\n projectDir?: string,\n): Promise<ResolvedAgentsSource> {\n if (flagValue !== undefined) {\n if (flagValue === \"\" || flagValue.trim() === \"\") {\n throw new Error(\n \"--agent-source flag cannot be empty. Provide a valid source: a local directory path or a git repository URL (e.g., './my-agents' or 'https://github.com/user/repo')\",\n );\n }\n validateSourceFormat(flagValue.trim(), \"--agent-source\");\n verbose(`Agents source from --agent-source flag: ${flagValue}`);\n return { agentsSource: flagValue, agentsSourceOrigin: \"flag\" };\n }\n\n const effectiveConfig = await loadEffectiveSourceConfig(projectDir);\n if (effectiveConfig?.agentsSource) {\n verbose(`Agents source from project config: ${effectiveConfig.agentsSource}`);\n return {\n agentsSource: effectiveConfig.agentsSource,\n agentsSourceOrigin: \"project\",\n };\n }\n\n verbose(\"Using default agents source (local CLI)\");\n return { agentsSource: undefined, agentsSourceOrigin: \"default\" };\n}\n\nconst PROJECT_ORIGIN_LABEL = \"project config (.claude-src/config.ts)\";\n\nexport function formatOrigin(\n type: \"source\" | \"agents\",\n origin: ResolvedConfig[\"sourceOrigin\"] | AgentsSourceOrigin,\n): string {\n if (origin === \"project\") return PROJECT_ORIGIN_LABEL;\n\n if (type === \"source\") {\n switch (origin) {\n case \"flag\":\n return \"--source flag\";\n case \"env\":\n return `${SOURCE_ENV_VAR} environment variable`;\n case \"default\":\n return \"default\";\n default:\n break;\n }\n }\n\n // type === \"agents\"\n switch (origin) {\n case \"flag\":\n return \"--agent-source flag\";\n case \"default\":\n return \"default (local CLI)\";\n default:\n break;\n }\n\n return origin;\n}\n\nexport async function resolveAuthor(projectDir?: string): Promise<string | undefined> {\n const effectiveConfig = await loadEffectiveSourceConfig(projectDir);\n return effectiveConfig?.author;\n}\n\n/** Resolved branding with defaults applied for any missing fields */\nexport type ResolvedBranding = {\n name: string;\n tagline: string;\n};\n\n/** Resolves branding from project config, falling back to global then DEFAULT_BRANDING. */\nexport async function resolveBranding(projectDir?: string): Promise<ResolvedBranding> {\n const effectiveConfig = await loadEffectiveSourceConfig(projectDir);\n return {\n name: effectiveConfig?.branding?.name ?? DEFAULT_BRANDING.NAME,\n tagline: effectiveConfig?.branding?.tagline ?? DEFAULT_BRANDING.TAGLINE,\n };\n}\n\nexport async function resolveAllSources(\n projectDir?: string,\n): Promise<{ primary: SourceEntry; extras: SourceEntry[] }> {\n const effectiveConfig = await loadEffectiveSourceConfig(projectDir);\n\n const resolvedConfig = await resolveSource(undefined, projectDir);\n const primary: SourceEntry = {\n name: \"marketplace\",\n url: resolvedConfig.source,\n description: \"Primary skills marketplace\",\n };\n\n const extras: SourceEntry[] = [];\n const seenNames = new Set<string>();\n\n if (effectiveConfig?.sources) {\n for (const source of effectiveConfig.sources) {\n if (!seenNames.has(source.name)) {\n seenNames.add(source.name);\n extras.push(source);\n }\n }\n }\n\n return { primary, extras };\n}\n\nconst REMOTE_PROTOCOLS = [\n GITHUB_SOURCE.GITHUB_PREFIX, // \"github:\"\n GITHUB_SOURCE.GH_PREFIX, // \"gh:\"\n \"gitlab:\",\n \"bitbucket:\",\n \"sourcehut:\",\n \"https://\",\n \"http://\",\n] as const;\n\n// Minimum length after protocol prefix for a valid remote source (e.g., \"org/repo\" = 8 chars min)\nconst MIN_REMOTE_PATH_LENGTH = 3;\nconst MAX_SOURCE_LENGTH = 512;\n\n// Null bytes must never appear in source strings — they can bypass C-level string termination in downstream tools\nconst NULL_BYTE_PATTERN = /\\0/;\n\n// Path traversal sequences in git refs/branches/tags (e.g., \"?branch=../../etc/passwd\")\nconst PATH_TRAVERSAL_PATTERN = /\\.\\./;\n\n// UNC path prefixes (Windows network paths): \\\\server\\share or //server/share\n// These can trigger SMB authentication to attacker-controlled servers\nconst UNC_PATH_PATTERN = /^(?:\\/\\/|\\\\\\\\)/;\n\n// Private/reserved IPv4 ranges that should not appear in source URLs (SSRF prevention)\n// Matches: 127.x.x.x, 10.x.x.x, 172.16-31.x.x, 192.168.x.x, 0.0.0.0, 169.254.x.x\nconst PRIVATE_IPV4_PATTERN =\n /^(?:127\\.\\d+\\.\\d+\\.\\d+|10\\.\\d+\\.\\d+\\.\\d+|172\\.(?:1[6-9]|2\\d|3[01])\\.\\d+\\.\\d+|192\\.168\\.\\d+\\.\\d+|0\\.0\\.0\\.0|169\\.254\\.\\d+\\.\\d+)$/;\n\n// IPv6 loopback and private addresses in URL hostname brackets\nconst PRIVATE_IPV6_PATTERN =\n /^\\[(?:::1|::ffff:(?:127\\.\\d+\\.\\d+\\.\\d+|10\\.\\d+\\.\\d+\\.\\d+|192\\.168\\.\\d+\\.\\d+)|fd[0-9a-f]{2}:.*|fe80:.*)\\]$/i;\n\n/**\n * Validates a source string format before it reaches giget or filesystem operations.\n * Catches obviously invalid formats early with clear error messages.\n *\n * @param source - The trimmed, non-empty source value to validate\n * @param flagName - The flag name for error messages (\"--source\" or \"--agent-source\")\n */\nexport function validateSourceFormat(source: string, flagName: string): void {\n // Null bytes can bypass C-level string termination in downstream tools (giget, git)\n if (NULL_BYTE_PATTERN.test(source)) {\n throw new Error(\n `${flagName} contains invalid characters.\\n\\n` +\n `Source values must not contain null bytes.\\n` +\n `Examples:\\n` +\n ` ${flagName} ./my-skills\\n` +\n ` ${flagName} github:user/repo`,\n );\n }\n\n if (source.length > MAX_SOURCE_LENGTH) {\n throw new Error(\n `${flagName} value is too long (${source.length} characters, max ${MAX_SOURCE_LENGTH}).\\n\\n` +\n `Provide a shorter source path or URL.\\n` +\n `Examples:\\n` +\n ` ${flagName} ./my-skills\\n` +\n ` ${flagName} github:user/repo`,\n );\n }\n\n const matchedProtocol = REMOTE_PROTOCOLS.find((prefix) => source.startsWith(prefix));\n\n if (matchedProtocol) {\n validateRemoteSource(source, matchedProtocol, flagName);\n } else {\n validateLocalPath(source, flagName);\n }\n}\n\nfunction validateRemoteSource(source: string, protocol: string, flagName: string): void {\n const pathAfterProtocol = source.slice(protocol.length).trim();\n\n if (pathAfterProtocol.length < MIN_REMOTE_PATH_LENGTH) {\n throw new Error(\n `${flagName} has an incomplete URL: \"${source}\"\\n\\n` +\n `A repository path is required after the protocol prefix.\\n` +\n `Examples:\\n` +\n ` ${flagName} github:user/repo\\n` +\n ` ${flagName} https://github.com/user/repo`,\n );\n }\n\n // Block path traversal in any remote source (refs, branches, query params)\n if (PATH_TRAVERSAL_PATTERN.test(pathAfterProtocol)) {\n throw new Error(\n `${flagName} contains path traversal in URL: \"${source}\"\\n\\n` +\n `Remote source URLs must not contain '..' sequences.\\n` +\n `Examples:\\n` +\n ` ${flagName} github:user/repo\\n` +\n ` ${flagName} https://github.com/user/repo`,\n );\n }\n\n // For https:// and http:// URLs, validate basic URL structure\n if (protocol === \"https://\" || protocol === \"http://\") {\n validateHttpUrl(source, flagName);\n }\n\n // For git shorthand protocols (github:, gh:, gitlab:, etc.), validate org/repo pattern\n if (protocol !== \"https://\" && protocol !== \"http://\") {\n validateGitShorthand(source, pathAfterProtocol, flagName);\n }\n}\n\nfunction validateHttpUrl(source: string, flagName: string): void {\n // Basic URL structure check: must have a hostname with at least one dot or localhost\n const afterProtocol = source.replace(/^https?:\\/\\//, \"\");\n // Strip port number for hostname validation (e.g., \"localhost:8080\" -> \"localhost\")\n const hostnameWithPort = afterProtocol.split(\"/\")[0] ?? \"\";\n const hostname = hostnameWithPort.split(\":\")[0] ?? \"\";\n\n // Allow: dotted hostnames (github.com), localhost, and bracketed IPv6 ([::1])\n const isBracketedIPv6 = hostnameWithPort.startsWith(\"[\") && hostnameWithPort.includes(\"]\");\n if (!hostname || (!hostname.includes(\".\") && hostname !== \"localhost\" && !isBracketedIPv6)) {\n throw new Error(\n `${flagName} has an invalid URL: \"${source}\"\\n\\n` +\n `The URL must include a valid hostname.\\n` +\n `Examples:\\n` +\n ` ${flagName} https://github.com/user/repo\\n` +\n ` ${flagName} https://gitlab.company.com/team/skills`,\n );\n }\n\n // Block private/reserved IP addresses (SSRF prevention via giget)\n if (PRIVATE_IPV4_PATTERN.test(hostname) || PRIVATE_IPV6_PATTERN.test(hostnameWithPort)) {\n throw new Error(\n `${flagName} points to a private or reserved IP address: \"${source}\"\\n\\n` +\n `Source URLs must not target private network addresses.\\n` +\n `Use a public hostname instead.\\n` +\n `Examples:\\n` +\n ` ${flagName} https://github.com/user/repo\\n` +\n ` ${flagName} https://gitlab.company.com/team/skills`,\n );\n }\n}\n\nfunction validateGitShorthand(source: string, repoPath: string, flagName: string): void {\n // Git shorthand format: protocol:owner/repo (must have at least owner/repo)\n if (!repoPath.includes(\"/\")) {\n throw new Error(\n `${flagName} has an invalid repository reference: \"${source}\"\\n\\n` +\n `Git shorthand sources require an owner/repo format.\\n` +\n `Examples:\\n` +\n ` ${flagName} github:user/repo\\n` +\n ` ${flagName} gh:organization/skills`,\n );\n }\n}\n\nfunction validateLocalPath(source: string, flagName: string): void {\n // Check for control characters (except common whitespace)\n // eslint-disable-next-line no-control-regex\n const CONTROL_CHAR_PATTERN = /[\\x00-\\x08\\x0E-\\x1F\\x7F]/u;\n if (CONTROL_CHAR_PATTERN.test(source)) {\n throw new Error(\n `${flagName} contains invalid characters: \"${source}\"\\n\\n` +\n `Source paths must not contain control characters.\\n` +\n `Examples:\\n` +\n ` ${flagName} ./my-skills\\n` +\n ` ${flagName} /home/user/skills`,\n );\n }\n\n // Block UNC paths (Windows network paths like \\\\server\\share or //server/share)\n // These can trigger SMB authentication to attacker-controlled servers, leaking credentials\n if (UNC_PATH_PATTERN.test(source)) {\n throw new Error(\n `${flagName} contains a UNC network path: \"${source}\"\\n\\n` +\n `Network paths (\\\\\\\\server\\\\share or //server/share) are not allowed for security reasons.\\n` +\n `Use a local directory path or a remote URL instead.\\n` +\n `Examples:\\n` +\n ` ${flagName} ./my-skills\\n` +\n ` ${flagName} /home/user/skills\\n` +\n ` ${flagName} https://github.com/user/repo`,\n );\n }\n}\n\nexport function isLocalSource(source: string): boolean {\n if (source.startsWith(\"/\") || source.startsWith(\".\")) {\n return true;\n }\n\n const hasRemoteProtocol = REMOTE_PROTOCOLS.some((prefix) => source.startsWith(prefix));\n\n if (!hasRemoteProtocol) {\n if (source.includes(\"..\") || source.includes(\"~\")) {\n throw new Error(\n `Invalid source path: ${source}. Path traversal patterns like '..' and '~' are not allowed for security reasons. Use absolute paths or remote URLs instead (e.g., '/home/user/skills' or 'https://github.com/user/repo').`,\n );\n }\n }\n\n return !hasRemoteProtocol;\n}\n","import path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { createJiti } from \"jiti\";\nimport { fileExists } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport { getErrorMessage } from \"../../utils/errors\";\n\n/** Resolve @agents-inc/cli/config to the source config-exports.ts so jiti can load it in dev. */\nconst CONFIG_EXPORTS_PATH = path.resolve(\n path.dirname(fileURLToPath(import.meta.url)),\n \"../../config-exports.ts\",\n);\n\ntype ZodLikeSchema = {\n safeParse: (data: unknown) => { success: boolean; data?: unknown; error?: unknown };\n};\n\n/**\n * Loads a TypeScript config file using jiti.\n * Returns null when the file does not exist.\n * Throws on validation failure or malformed/broken files.\n *\n * @param configPath - Absolute path to the .ts config file\n * @param schema - Optional Zod schema for validation\n */\nexport async function loadConfig<T>(configPath: string, schema?: ZodLikeSchema): Promise<T | null> {\n if (!(await fileExists(configPath))) {\n verbose(`Config not found at ${configPath}`);\n return null;\n }\n\n let raw: unknown;\n try {\n const jiti = createJiti(import.meta.url, {\n moduleCache: false,\n interopDefault: true,\n alias: { \"@agents-inc/cli/config\": CONFIG_EXPORTS_PATH },\n });\n\n raw = await jiti.import(configPath, { default: true });\n } catch (error) {\n throw new Error(`Failed to load config from '${configPath}': ${getErrorMessage(error)}`);\n }\n\n if (schema) {\n const result = schema.safeParse(raw);\n if (!result.success) {\n throw new Error(\n `Config validation failed at '${configPath}': ${JSON.stringify(result.error)}`,\n );\n }\n // Post-safeParse cast: schema.safeParse widened by passthrough, narrow to actual type\n return result.data as T;\n }\n\n // Boundary cast: jiti returns unknown, caller provides expected type\n return raw as T;\n}\n","import type {\n AgentName,\n CategoryPath,\n ProjectConfig,\n SkillAssignment,\n SkillId,\n Stack,\n StackAgentConfig,\n Category,\n} from \"../../types\";\nimport type { AgentScopeConfig, SkillConfig } from \"../../types/config\";\nimport { matrix } from \"../matrix/matrix-provider\";\nimport { verbose, warn } from \"../../utils/logger\";\nimport { typedEntries, typedKeys } from \"../../utils/typed-object\";\n\nexport type SplitConfigResult = {\n global: ProjectConfig;\n project: ProjectConfig;\n};\n\nexport type ProjectConfigOptions = {\n description?: string;\n author?: string;\n};\n\nfunction extractCategoryFromPath(categoryPath: CategoryPath): Category | undefined {\n if (categoryPath === \"local\") return undefined;\n // TypeScript narrows CategoryPath to Category after excluding \"local\"\n return categoryPath;\n}\n\n/**\n * Generates a ProjectConfig from a list of selected skill IDs by building the\n * stack property (agent -> category -> SkillAssignment[]).\n *\n * Every selected skill is assigned to every selected agent. When no agents are\n * provided, the agents list is empty (the wizard always provides selectedAgents\n * via the agents step).\n *\n * @param name - Project name for the config\n * @param selectedSkillIds - Skill IDs selected by the user in the wizard\n * @param options - Optional description, author, selectedAgents, and skillConfigs fields.\n * When skillConfigs is provided, it is used directly as `skills` in the config.\n * Otherwise, SkillConfig entries are synthesized from selectedSkillIds with defaults.\n * @returns Complete ProjectConfig ready to be saved to config.ts\n */\nexport function generateProjectConfigFromSkills(\n name: string,\n selectedSkillIds: SkillId[],\n options?: ProjectConfigOptions & {\n selectedAgents?: AgentName[];\n skillConfigs?: SkillConfig[];\n agentConfigs?: AgentScopeConfig[];\n },\n): ProjectConfig {\n const agentList = options?.selectedAgents ? [...options.selectedAgents].sort() : [];\n\n verbose(\n `generateProjectConfigFromSkills: ${selectedSkillIds.length} skills, ` +\n `matrix has ${typedKeys<SkillId>(matrix.skills).length} entries, ` +\n `agents=[${agentList.join(\", \")}]`,\n );\n\n const looked = selectedSkillIds.map((skillId) => {\n const skill = matrix.skills[skillId];\n if (!skill) warn(`Skill '${skillId}' NOT FOUND in matrix`);\n return { skillId, skill };\n });\n\n const found = looked.filter(\n (entry): entry is typeof entry & { skill: NonNullable<typeof entry.skill> } =>\n entry.skill != null,\n );\n const skippedCount = looked.length - found.length;\n\n const validSkills = found\n .map(({ skillId, skill }) => ({\n skillId,\n category: extractCategoryFromPath(skill.category),\n }))\n .filter((entry): entry is typeof entry & { category: Category } => entry.category != null);\n\n verbose(\n `generateProjectConfigFromSkills: ${found.length} found, ${skippedCount} not found, ` +\n `${agentList.length} agents in stack`,\n );\n\n if (skippedCount > 0) {\n const matrixSample = typedKeys<SkillId>(matrix.skills).slice(0, 5).join(\", \");\n warn(\n `${skippedCount}/${selectedSkillIds.length} skills not found in matrix. ` +\n `Matrix keys sample: [${matrixSample}]`,\n );\n }\n\n const stackProperty =\n agentList.length > 0 && validSkills.length > 0\n ? Object.fromEntries(\n agentList.map((agentId) => [\n agentId,\n // Structural cast: Object.fromEntries returns Record<string, V>, narrowing to typed keys\n Object.fromEntries(\n validSkills.map(({ skillId, category }) => [\n category,\n [{ id: skillId, preloaded: false }],\n ]),\n ) as StackAgentConfig,\n ]),\n )\n : undefined;\n\n const skills: SkillConfig[] =\n options?.skillConfigs ??\n selectedSkillIds.map((id) => ({ id, scope: \"project\" as const, source: \"local\" }));\n\n const agentConfigs: AgentScopeConfig[] = options?.agentConfigs\n ? agentList.map((agentName) => {\n const provided = options.agentConfigs!.find((ac) => ac.name === agentName);\n return provided ?? { name: agentName, scope: \"project\" as const };\n })\n : agentList.map((agentName) => ({ name: agentName, scope: \"project\" as const }));\n\n return {\n name,\n agents: agentConfigs,\n skills,\n ...(stackProperty && { stack: stackProperty }),\n ...(options?.description && { description: options.description }),\n ...(options?.author && { author: options.author }),\n };\n}\n\n/**\n * Extracts the stack property (agent -> category -> SkillAssignment[]) from a Stack definition.\n *\n * Stack values are already normalized to SkillAssignment[] by loadStacks().\n * Preserves all assignments and preloaded flags for round-trip fidelity.\n *\n * @param stack - Loaded Stack definition with normalized agent configs\n * @returns Partial mapping of agent names to category-skill assignment mappings\n */\nexport function buildStackProperty(stack: Stack): Partial<Record<AgentName, StackAgentConfig>> {\n // Structural casts: Object.fromEntries returns Record<string, V>, narrowing to typed keys\n return Object.fromEntries(\n typedEntries<AgentName, StackAgentConfig>(stack.agents)\n .filter(([, agentConfig]) => agentConfig && typedKeys<Category>(agentConfig).length > 0)\n .map(([agentId, agentConfig]) => {\n const resolvedMappings = Object.fromEntries(\n typedEntries<Category, SkillAssignment[]>(agentConfig).filter(\n ([, assignments]) => assignments && assignments.length > 0,\n ),\n ) as StackAgentConfig;\n return [agentId, resolvedMappings] as const;\n })\n .filter(([, mappings]) => typedKeys<Category>(mappings).length > 0),\n ) as Partial<Record<AgentName, StackAgentConfig>>;\n}\n\n/**\n * Compacts a ProjectConfig.stack for YAML serialization.\n * Converts SkillAssignment[] to the most compact form:\n * - Single skill with preloaded=false -> bare string (e.g., \"web-framework-react\")\n * - Single skill with preloaded=true -> object (e.g., { id: \"...\", preloaded: true })\n * - Multiple skills -> array of objects/strings\n * This ensures round-trip fidelity: bare strings stay bare, rich format stays rich.\n */\nfunction compactAssignment(assignment: SkillAssignment): unknown {\n return assignment.preloaded ? { id: assignment.id, preloaded: true } : assignment.id;\n}\n\nexport function compactStackForYaml(\n stack: Partial<Record<AgentName, StackAgentConfig>>,\n): Record<string, Record<string, unknown>> {\n return Object.fromEntries(\n typedEntries<AgentName, StackAgentConfig>(stack)\n .map(([agentId, agentConfig]) => {\n const compacted = Object.fromEntries(\n typedEntries<Category, SkillAssignment[]>(agentConfig)\n .filter(([, assignments]) => assignments && assignments.length > 0)\n .map(([category, assignments]) => [\n category,\n assignments.length === 1\n ? compactAssignment(assignments[0])\n : assignments.map(compactAssignment),\n ]),\n );\n return [agentId, compacted] as const;\n })\n .filter(([, compacted]) => Object.keys(compacted).length > 0),\n );\n}\n\n/**\n * Splits a ProjectConfig by scope into global and project partitions.\n * Skills with `scope: \"global\"` go to the global partition, `scope: \"project\"` to the project partition.\n * Agents are split based on which skills reference them in the stack.\n * Domains are preserved in both configs as-is (the project config extends global at runtime).\n */\nexport function splitConfigByScope(config: ProjectConfig): SplitConfigResult {\n const globalSkills = config.skills.filter((s) => s.scope === \"global\");\n const projectSkills = config.skills.filter((s) => s.scope === \"project\");\n\n // Split agents by their explicit scope (mirrors skill scope pattern)\n const globalAgents = config.agents.filter((a) => a.scope === \"global\");\n const projectAgents = config.agents.filter((a) => a.scope === \"project\");\n\n // Split stack by agent partition\n const globalStack: typeof config.stack = {};\n const projectStack: typeof config.stack = {};\n\n if (config.stack) {\n for (const agent of globalAgents) {\n if (config.stack[agent.name]) {\n globalStack[agent.name] = config.stack[agent.name];\n }\n }\n for (const agent of projectAgents) {\n if (config.stack[agent.name]) {\n projectStack[agent.name] = config.stack[agent.name];\n }\n }\n }\n\n // Split selectedAgents by scope: global agents go to global config, project agents to project config\n const globalAgentNames = new Set(globalAgents.map((a) => a.name));\n const globalSelectedAgents = config.selectedAgents?.filter((a) => globalAgentNames.has(a)) ?? [];\n const projectSelectedAgents =\n config.selectedAgents?.filter((a) => !globalAgentNames.has(a)) ?? [];\n\n // Split domains: global gets all, project gets only domains not already in global\n const globalDomains = config.domains ?? [];\n const globalDomainSet = new Set(globalDomains);\n const projectOnlyDomains = (config.domains ?? []).filter((d) => !globalDomainSet.has(d));\n\n const globalConfig: ProjectConfig = {\n name: \"global\",\n agents: globalAgents,\n skills: globalSkills,\n ...(Object.keys(globalStack).length > 0 && { stack: globalStack }),\n ...(globalDomains.length > 0 && { domains: globalDomains }),\n ...(globalSelectedAgents.length > 0 && { selectedAgents: globalSelectedAgents }),\n };\n\n const projectConfig: ProjectConfig = {\n name: config.name,\n agents: projectAgents,\n skills: projectSkills,\n ...(Object.keys(projectStack).length > 0 && { stack: projectStack }),\n ...(config.description && { description: config.description }),\n ...(config.author && { author: config.author }),\n ...(config.source && { source: config.source }),\n ...(config.marketplace && { marketplace: config.marketplace }),\n ...(config.agentsSource && { agentsSource: config.agentsSource }),\n ...(projectOnlyDomains.length > 0 && { domains: projectOnlyDomains }),\n ...(projectSelectedAgents.length > 0 && { selectedAgents: projectSelectedAgents }),\n };\n\n return { global: globalConfig, project: projectConfig };\n}\n","import { indexBy } from \"remeda\";\n\nimport type { ProjectConfig } from \"../../types\";\nimport type { SkillConfig } from \"../../types/config\";\nimport { typedEntries } from \"../../utils/typed-object\";\nimport { loadProjectConfig } from \"./project-config\";\nimport { loadProjectSourceConfig } from \"./config\";\n\nexport type MergeContext = {\n projectDir: string;\n};\n\nexport type MergeResult = {\n config: ProjectConfig;\n merged: boolean;\n existingConfigPath?: string;\n};\n\n// Existing values take precedence for identity fields; arrays are unioned; stack is deep-merged\nexport async function mergeWithExistingConfig(\n newConfig: ProjectConfig,\n context: MergeContext,\n): Promise<MergeResult> {\n const localConfig = { ...newConfig };\n\n const existingFullConfig = await loadProjectConfig(context.projectDir);\n if (existingFullConfig) {\n const existingConfig = existingFullConfig.config;\n\n if (existingConfig.name) {\n localConfig.name = existingConfig.name;\n }\n\n if (existingConfig.description) {\n localConfig.description = existingConfig.description;\n }\n\n if (existingConfig.source) {\n localConfig.source = existingConfig.source;\n }\n\n if (existingConfig.agents && existingConfig.agents.length > 0) {\n const existingNames = new Set(existingConfig.agents.map((a) => a.name));\n const newAgents = localConfig.agents.filter((a) => !existingNames.has(a.name));\n localConfig.agents = [...existingConfig.agents, ...newAgents];\n }\n\n // Merge skills by ID: new skills override existing, existing skills preserved otherwise\n if (existingConfig.skills && existingConfig.skills.length > 0) {\n const newSkillsById = indexBy(localConfig.skills, (s: SkillConfig) => s.id);\n const existingIds = new Set(existingConfig.skills.map((s: SkillConfig) => s.id));\n const updatedExisting = existingConfig.skills.map(\n (existing: SkillConfig) => newSkillsById[existing.id] ?? existing,\n );\n const addedSkills = localConfig.skills.filter((s) => !existingIds.has(s.id));\n localConfig.skills = [...updatedExisting, ...addedSkills];\n }\n\n if (existingConfig.stack) {\n const mergedStack = { ...localConfig.stack };\n for (const [agentId, agentConfig] of typedEntries(existingConfig.stack)) {\n mergedStack[agentId] = { ...mergedStack[agentId], ...agentConfig };\n }\n localConfig.stack = mergedStack;\n }\n\n if (existingConfig.author) {\n localConfig.author = existingConfig.author;\n }\n\n if (existingConfig.agentsSource) {\n localConfig.agentsSource = existingConfig.agentsSource;\n }\n\n if (existingConfig.marketplace) {\n localConfig.marketplace = existingConfig.marketplace;\n }\n\n return {\n config: localConfig,\n merged: true,\n existingConfigPath: existingFullConfig.configPath,\n };\n }\n\n // No existing full config, try simple project source config for author/agentsSource\n const existingProjectConfig = await loadProjectSourceConfig(context.projectDir);\n if (existingProjectConfig?.author) {\n localConfig.author = existingProjectConfig.author;\n }\n if (existingProjectConfig?.agentsSource) {\n localConfig.agentsSource = existingProjectConfig.agentsSource;\n }\n\n return { config: localConfig, merged: false };\n}\n","import os from \"os\";\nimport path from \"path\";\nimport { fileExists } from \"../../utils/fs\";\nimport { verbose, warn } from \"../../utils/logger\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { CLAUDE_SRC_DIR, STANDARD_FILES } from \"../../consts\";\nimport type { ProjectConfig, ValidationResult } from \"../../types\";\nimport { normalizeStackRecord } from \"../stacks/stacks-loader\";\nimport { projectConfigLoaderSchema } from \"../schemas\";\nimport { loadConfig } from \"./config-loader\";\n\nexport type LoadedProjectConfig = {\n config: ProjectConfig;\n configPath: string;\n};\n\n/** Load project config from a specific directory only (no global fallback). */\nexport async function loadProjectConfigFromDir(\n projectDir: string,\n): Promise<LoadedProjectConfig | null> {\n const configPath = path.join(projectDir, `${CLAUDE_SRC_DIR}/${STANDARD_FILES.CONFIG_TS}`);\n\n if (!(await fileExists(configPath))) {\n verbose(`Project config not found at ${configPath}`);\n return null;\n }\n\n let config: ProjectConfig | null;\n try {\n // Load raw object and validate with Zod (lenient schema accepts custom values via z.string() casts)\n const raw = await loadConfig<ProjectConfig>(configPath);\n if (!raw || typeof raw !== \"object\") return null;\n\n const result = projectConfigLoaderSchema.safeParse(raw);\n if (!result.success) {\n verbose(`Config validation failed at ${configPath}: ${JSON.stringify(result.error)}`);\n return null;\n }\n config = result.data as ProjectConfig;\n } catch (error) {\n verbose(`Failed to load project config at ${configPath}: ${getErrorMessage(error)}`);\n return null;\n }\n\n // Boundary cast: Zod-parsed stack has unnormalized values (bare strings, objects, arrays)\n // that normalizeStackRecord converts to typed SkillAssignment[] values\n if (config.stack) {\n config.stack = normalizeStackRecord(\n config.stack as unknown as Record<string, Record<string, unknown>>,\n );\n }\n\n if (!config.name) {\n warn(\n `Project config at '${configPath}' is missing required 'name' field — defaulting to directory name`,\n );\n config.name = path.basename(projectDir);\n }\n if (!config.skills) {\n warn(`Project config at '${configPath}' is missing 'skills' array — defaulting to empty`);\n config.skills = [];\n }\n\n verbose(`Loaded project config from ${configPath}`);\n return {\n config,\n configPath,\n };\n}\n\n/**\n * Load project config with global fallback.\n * Checks the given projectDir first, then falls back to the home directory.\n */\nexport async function loadProjectConfig(projectDir: string): Promise<LoadedProjectConfig | null> {\n const projectResult = await loadProjectConfigFromDir(projectDir);\n if (projectResult) return projectResult;\n\n // Global fallback: try home directory\n const homeDir = os.homedir();\n if (projectDir !== homeDir) {\n return loadProjectConfigFromDir(homeDir);\n }\n\n return null;\n}\n\nexport function validateProjectConfig(config: unknown): ValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n if (!config || typeof config !== \"object\") {\n return { valid: false, errors: [\"Config must be an object\"], warnings: [] };\n }\n\n // Boundary cast: config validated as object above, narrow to record for field access\n const c = config as Record<string, unknown>;\n\n if (!c.name || typeof c.name !== \"string\") {\n errors.push(\"name is required and must be a string\");\n }\n\n if (!c.agents || !Array.isArray(c.agents)) {\n errors.push(\"agents is required and must be an array\");\n } else {\n for (const agent of c.agents) {\n if (\n typeof agent !== \"object\" ||\n agent === null ||\n typeof (agent as Record<string, unknown>).name !== \"string\"\n ) {\n errors.push(`agents must contain objects with name and scope, found: ${typeof agent}`);\n }\n }\n }\n\n if (c.version !== undefined && c.version !== \"1\") {\n errors.push('version must be \"1\" (or omitted for default)');\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n","import path from \"path\";\nimport { mapValues, pipe, flatMap, unique } from \"remeda\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { verbose, warn } from \"../../utils/logger\";\nimport type {\n AgentName,\n SkillAssignment,\n SkillId,\n SkillReference,\n Stack,\n StackAgentConfig,\n StacksConfig,\n Category,\n} from \"../../types\";\nimport { SKILL_ID_PATTERN, stacksConfigSchema } from \"../schemas\";\nimport { typedEntries, typedKeys } from \"../../utils/typed-object\";\nimport { STACKS_FILE_PATH } from \"../../consts\";\nimport { loadConfig } from \"../configuration/config-loader\";\nimport { defaultStacks } from \"../configuration/default-stacks\";\n\nconst stacksCache = new Map<string, Stack[]>();\n\n/**\n * Normalizes a raw agent config (from Zod-parsed config) to StackAgentConfig.\n * Converts bare strings to `{ id, preloaded: false }` and wraps single values in arrays.\n * Used by both loadStacks() and loadProjectConfig() to handle all 3 config formats:\n * 1. bare string: `framework: \"web-framework-react\"`\n * 2. single object: `framework: { id: \"web-framework-react\", preloaded: true }`\n * 3. array: `methodology: [{ id: ..., preloaded: true }, { id: ... }]`\n */\nexport function normalizeAgentConfig(agentConfig: Record<string, unknown>): StackAgentConfig {\n // Boundary casts: Zod-parsed config has loose types (bare strings, objects, arrays)\n // that are normalized to typed SkillAssignment[] values\n return mapValues(agentConfig, (value) => {\n const items = Array.isArray(value) ? value : [value];\n return items.map(\n (item): SkillAssignment =>\n typeof item === \"string\"\n ? { id: item as SkillId, preloaded: false }\n : (item as SkillAssignment),\n );\n }) as StackAgentConfig;\n}\n\n/**\n * Normalizes a raw stack record (agent -> raw category config) to the typed form.\n * Applies normalizeAgentConfig to each agent entry.\n */\nexport function normalizeStackRecord(\n rawStack: Record<string, Record<string, unknown>>,\n): Record<string, StackAgentConfig> {\n return mapValues(rawStack, (agentConfig) => normalizeAgentConfig(agentConfig));\n}\n\nexport async function loadStacks(configDir: string, stacksFile?: string): Promise<Stack[]> {\n const resolvedStacksFile = stacksFile ?? STACKS_FILE_PATH;\n const cacheKey = `${configDir}:${resolvedStacksFile}`;\n const cached = stacksCache.get(cacheKey);\n if (cached) return cached;\n\n const stacksPath = path.join(configDir, resolvedStacksFile);\n\n try {\n const raw = await loadConfig<StacksConfig>(stacksPath, stacksConfigSchema);\n\n if (raw == null) {\n verbose(`No stacks file found at ${stacksPath}`);\n return [];\n }\n\n // Normalize: all values to SkillAssignment[] so StackAgentConfig is always SkillAssignment[]\n // Boundary casts: Zod stacksConfigSchema outputs loose Record types;\n // narrowing to Stack[\"agents\"] after normalization guarantees SkillAssignment[] values\n const stacks: Stack[] = raw.stacks.map((stack) => ({\n ...stack,\n agents: mapValues(\n stack.agents as Partial<Record<AgentName, Record<string, unknown>>>,\n (agentConfig) => normalizeAgentConfig(agentConfig as Record<string, unknown>),\n ) as Stack[\"agents\"],\n }));\n\n stacksCache.set(cacheKey, stacks);\n verbose(`Loaded ${stacks.length} stacks from ${stacksPath}`);\n\n return stacks;\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n throw new Error(`Failed to load stacks from '${stacksPath}': ${errorMessage}`);\n }\n}\n\nexport async function loadStackById(stackId: string, configDir: string): Promise<Stack | null> {\n const stacks = await loadStacks(configDir);\n const stack = stacks.find((s) => s.id === stackId);\n\n if (stack) {\n verbose(`Found stack: ${stack.name} (${stackId})`);\n return stack;\n }\n\n // Fall back to CLI's built-in default stacks\n const defaultStack = defaultStacks.find((s) => s.id === stackId) ?? null;\n if (defaultStack) {\n verbose(`Found default stack: ${defaultStack.name} (${stackId})`);\n } else {\n verbose(`Stack '${stackId}' not found in source or defaults`);\n }\n return defaultStack;\n}\n\n// Converts a StackAgentConfig (category -> SkillAssignment[]) to an array of SkillReferences.\n// Values are already normalized to SkillAssignment[] by loadStacks().\nexport function resolveAgentConfigToSkills(agentConfig: StackAgentConfig): SkillReference[] {\n return typedEntries<Category, SkillAssignment[]>(agentConfig).flatMap(([category, assignments]) =>\n (assignments ?? [])\n .filter((assignment) => {\n if (!SKILL_ID_PATTERN.test(assignment.id)) {\n warn(\n `Invalid skill ID '${assignment.id}' for category '${category}' in stack config. Skipping.`,\n );\n return false;\n }\n return true;\n })\n .map(\n (assignment): SkillReference => ({\n id: assignment.id,\n usage: `when working with ${category}`,\n preloaded: assignment.preloaded ?? false,\n }),\n ),\n );\n}\n\n/** Extracts all unique skill IDs from a stack config (agent -> category -> SkillAssignment[]). */\nexport function getStackSkillIds(stack: Record<string, StackAgentConfig>): SkillId[] {\n return pipe(\n Object.values(stack),\n flatMap(resolveAgentConfigToSkills),\n (refs) => refs.map((r) => r.id),\n unique(),\n );\n}\n\nexport function resolveStackSkills(stack: Stack): Record<string, SkillReference[]> {\n const result = mapValues(stack.agents, (agentConfig) =>\n agentConfig ? resolveAgentConfigToSkills(agentConfig) : [],\n );\n\n verbose(\n `Resolved skills for ${typedKeys<AgentName>(result).length} agents in stack '${stack.id}'`,\n );\n\n return result;\n}\n","import path from \"path\";\nimport { writeFile, ensureDir } from \"../../utils/fs\";\nimport { CLAUDE_SRC_DIR } from \"../../consts\";\nimport type { ProjectConfig } from \"../../types\";\nimport { loadProjectSourceConfig, getProjectConfigPath } from \"./config\";\nimport { generateConfigSource } from \"./config-writer\";\n\nexport async function saveSourceToProjectConfig(\n projectDir: string,\n source: string,\n name: string,\n): Promise<void> {\n const existing = (await loadProjectSourceConfig(projectDir)) ?? {};\n\n const config: ProjectConfig = {\n ...existing,\n name: existing.name ?? name,\n skills: existing.skills ?? [],\n agents: existing.agents ?? [],\n source,\n };\n\n const configPath = getProjectConfigPath(projectDir);\n await ensureDir(path.join(projectDir, CLAUDE_SRC_DIR));\n await writeFile(configPath, generateConfigSource(config));\n}\n","import os from \"os\";\nimport path from \"path\";\nimport type { ProjectConfig } from \"../../types\";\nimport { CLAUDE_SRC_DIR, DEFAULT_PLUGIN_NAME, STANDARD_FILES } from \"../../consts\";\nimport { fileExists, ensureDir, writeFile } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport { compactStackForYaml } from \"./config-generator\";\nimport { PROJECT_CONFIG_TYPES_BEFORE, PROJECT_CONFIG_INTERFACE_AFTER } from \"./config-types-writer\";\n\nexport type ConfigSourceOptions = {\n /**\n * When true, generates a project config that imports and extends the global config.\n * The global config import path is resolved internally via `getGlobalConfigImportPath()`.\n */\n isProjectConfig?: boolean;\n};\n\n/** Fields that are extracted into typed named variables below the export default */\nconst EXTRACTED_FIELDS = new Set([\"skills\", \"agents\", \"stack\", \"domains\"]);\n\n/**\n * Generates a TypeScript config file source from a ProjectConfig object.\n * The export default sits at the top as a table of contents, with typed named\n * variables (skills, agents, stack, domains) declared below it.\n *\n * When `options.isProjectConfig` is true, the generated config imports from the global\n * config and spreads global arrays into skills, agents, and domains.\n */\nexport function generateConfigSource(config: ProjectConfig, options?: ConfigSourceOptions): string {\n const serializable = config.stack\n ? { ...config, stack: compactStackForYaml(config.stack) }\n : { ...config };\n\n // JSON.parse(JSON.stringify(x)) removes undefined values\n const cleaned: Record<string, unknown> = JSON.parse(JSON.stringify(serializable));\n\n if (options?.isProjectConfig) {\n return generateProjectConfigWithGlobalImport(cleaned, getGlobalConfigImportPath());\n }\n\n return generateStandaloneConfig(cleaned);\n}\n\n/**\n * Generates a standalone config source with typed named variables above the export default.\n * The export default at the bottom acts as a table of contents, referencing the named variables.\n */\nfunction generateStandaloneConfig(cleaned: Record<string, unknown>): string {\n // Boundary cast: cleaned comes from JSON.parse(JSON.stringify(...)) so arrays are plain JSON values\n const skillsArr = (cleaned.skills as unknown[]) ?? [];\n const agentsArr = (cleaned.agents as unknown[]) ?? [];\n const stackObj = cleaned.stack as Record<string, unknown> | undefined;\n const domainsArr = (cleaned.domains as unknown[]) ?? [];\n\n const hasSkills = skillsArr.length > 0;\n const hasAgents = agentsArr.length > 0;\n const hasStack = stackObj != null && Object.keys(stackObj).length > 0;\n const hasDomains = domainsArr.length > 0;\n\n // Build type imports based on what's used\n const typeImports = buildTypeImports({ hasSkills, hasAgents, hasStack, hasDomains });\n\n const lines: string[] = [`import type { ${typeImports} } from \"./config-types\";`];\n\n // Add named variable declarations above the export default\n if (hasSkills) {\n lines.push(``);\n const items = skillsArr.map((s) => ` ${JSON.stringify(s)},`).join(\"\\n\");\n lines.push(`const skills: SkillConfig[] = [`);\n lines.push(items);\n lines.push(`];`);\n }\n\n if (hasAgents) {\n lines.push(``);\n const items = agentsArr.map((a) => ` ${JSON.stringify(a)},`).join(\"\\n\");\n lines.push(`const agents: AgentScopeConfig[] = [`);\n lines.push(items);\n lines.push(`];`);\n }\n\n if (hasStack) {\n lines.push(``);\n const stackBody = JSON.stringify(stackObj, null, 2);\n lines.push(`const stack: Partial<Record<AgentName, StackAgentConfig>> = ${stackBody};`);\n }\n\n if (hasDomains) {\n lines.push(``);\n const items = domainsArr.map((d) => JSON.stringify(d)).join(\", \");\n lines.push(`const domains: Domain[] = [${items}];`);\n }\n\n // Build export default fields\n const exportFields: string[] = [];\n for (const [key, value] of Object.entries(cleaned)) {\n if (EXTRACTED_FIELDS.has(key)) {\n if (key === \"skills\") {\n exportFields.push(` skills${hasSkills ? \"\" : \": []\"},`);\n } else if (key === \"agents\") {\n exportFields.push(` agents${hasAgents ? \"\" : \": []\"},`);\n } else if (key === \"stack\" && hasStack) {\n exportFields.push(` stack,`);\n } else if (key === \"domains\") {\n exportFields.push(` domains${hasDomains ? \"\" : \": []\"},`);\n }\n } else {\n exportFields.push(` ${JSON.stringify(key)}: ${JSON.stringify(value)},`);\n }\n }\n\n lines.push(``);\n lines.push(`export default {`);\n lines.push(...exportFields);\n lines.push(`} satisfies ProjectConfig;`);\n\n lines.push(``);\n return lines.join(\"\\n\");\n}\n\n/**\n * Builds the type import list based on which extracted fields are present.\n * ProjectConfig is always included. Other types are included only when used.\n */\nfunction buildTypeImports(flags: {\n hasSkills: boolean;\n hasAgents: boolean;\n hasStack: boolean;\n hasDomains: boolean;\n}): string {\n const types: string[] = [];\n if (flags.hasStack) types.push(\"AgentName\");\n if (flags.hasAgents) types.push(\"AgentScopeConfig\");\n if (flags.hasDomains) types.push(\"Domain\");\n types.push(\"ProjectConfig\");\n if (flags.hasSkills) types.push(\"SkillConfig\");\n if (flags.hasStack) types.push(\"StackAgentConfig\");\n return types.join(\", \");\n}\n\n/**\n * Generates a project config source that imports from the global config and extends it.\n * Typed named variables are declared above the export default. The export default at\n * the bottom acts as a table of contents. Arrays (skills, agents, domains) are spread\n * with globalConfig first, then project items.\n */\nfunction generateProjectConfigWithGlobalImport(\n cleaned: Record<string, unknown>,\n globalImportPath: string,\n): string {\n const importPath = `${globalImportPath}/config`;\n\n // Boundary cast: cleaned comes from JSON.parse(JSON.stringify(...)) so arrays are plain JSON values\n const skillsArr = (cleaned.skills as unknown[]) ?? [];\n const agentsArr = (cleaned.agents as unknown[]) ?? [];\n const stackObj = cleaned.stack as Record<string, unknown> | undefined;\n const domainsArr = (cleaned.domains as unknown[]) ?? [];\n const selectedAgentsArr = (cleaned.selectedAgents as string[]) ?? [];\n\n const hasProjectDomains = domainsArr.length > 0;\n const hasStack = stackObj != null && Object.keys(stackObj).length > 0;\n const hasProjectSelectedAgents = selectedAgentsArr.length > 0;\n\n // Build type imports\n const typeImports = buildTypeImports({\n hasSkills: true, // Always present (spread from global)\n hasAgents: true, // Always present (spread from global)\n hasStack,\n hasDomains: hasProjectDomains,\n });\n\n const lines: string[] = [\n `import globalConfig from \"${importPath}\";`,\n `import type { ${typeImports} } from \"./config-types\";`,\n ];\n\n // Skills variable (always present with global spread)\n lines.push(``);\n const skillItems = skillsArr.map((s) => ` ${JSON.stringify(s)},`).join(\"\\n\");\n lines.push(`const skills: SkillConfig[] = [`);\n lines.push(` ...globalConfig.skills,`);\n if (skillItems) lines.push(skillItems);\n lines.push(`];`);\n\n // Agents variable (always present with global spread)\n lines.push(``);\n const agentItems = agentsArr.map((a) => ` ${JSON.stringify(a)},`).join(\"\\n\");\n lines.push(`const agents: AgentScopeConfig[] = [`);\n lines.push(` ...globalConfig.agents,`);\n if (agentItems) lines.push(agentItems);\n lines.push(`];`);\n\n // Stack variable (only if project has stack assignments)\n if (hasStack) {\n lines.push(``);\n const stackBody = JSON.stringify(stackObj, null, 2);\n lines.push(`const stack: Partial<Record<AgentName, StackAgentConfig>> = ${stackBody};`);\n }\n\n // Domains variable (only if project has domains)\n if (hasProjectDomains) {\n lines.push(``);\n const domainItems = domainsArr.map((d) => ` ${JSON.stringify(d)},`).join(\"\\n\");\n lines.push(`const domains: Domain[] = [`);\n lines.push(` ...(globalConfig.domains ?? []),`);\n if (domainItems) lines.push(domainItems);\n lines.push(`];`);\n }\n\n // Build scalar fields (everything that isn't an extracted field, name, or selectedAgents)\n const scalarFields = Object.entries(cleaned)\n .filter(([key]) => !EXTRACTED_FIELDS.has(key) && key !== \"name\" && key !== \"selectedAgents\")\n .map(([key, value]) => ` ${JSON.stringify(key)}: ${JSON.stringify(value)},`)\n .join(\"\\n\");\n\n // Build export default (table of contents at bottom)\n const exportFields: string[] = [` ...globalConfig,`];\n // Ensure project config never inherits \"global\" as its name from the globalConfig spread\n const projectName =\n cleaned.name && cleaned.name !== \"global\" ? cleaned.name : DEFAULT_PLUGIN_NAME;\n exportFields.push(` name: ${JSON.stringify(projectName)},`);\n exportFields.push(` skills,`);\n exportFields.push(` agents,`);\n if (hasStack) {\n exportFields.push(` stack,`);\n }\n if (hasProjectDomains) {\n exportFields.push(` domains,`);\n }\n // selectedAgents: spread global + project-scoped agents\n if (hasProjectSelectedAgents) {\n const projectAgentItems = selectedAgentsArr.map((a) => `${JSON.stringify(a)}`).join(\", \");\n exportFields.push(\n ` \"selectedAgents\": [...(globalConfig.selectedAgents ?? []), ${projectAgentItems}],`,\n );\n }\n if (scalarFields) {\n exportFields.push(scalarFields);\n }\n\n lines.push(``);\n lines.push(`export default {`);\n lines.push(...exportFields);\n lines.push(`} satisfies ProjectConfig;`);\n\n lines.push(``);\n return lines.join(\"\\n\");\n}\n\n/**\n * Returns the absolute path to the global .claude-src directory.\n * Used as the import path for project configs that extend global.\n */\nexport function getGlobalConfigImportPath(): string {\n return path.join(os.homedir(), CLAUDE_SRC_DIR);\n}\n\n/**\n * Generates a blank global config source (empty arrays, no import preamble).\n */\nexport function generateBlankGlobalConfigSource(): string {\n return `import type { ProjectConfig } from \"./config-types\";\n\nexport default {\n \"name\": \"global\",\n \"skills\": [],\n \"agents\": [],\n \"domains\": []\n} satisfies ProjectConfig;\\n`;\n}\n\n/**\n * Generates blank global config-types source (all types are `never`).\n */\nexport function generateBlankGlobalConfigTypesSource(): string {\n return `// AUTO-GENERATED by agentsinc — DO NOT EDIT\n\nexport type SkillId = never;\n\nexport type AgentName = never;\n\nexport type Domain = never;\n\nexport type Category = never;\n\n${PROJECT_CONFIG_TYPES_BEFORE}\nexport type StackAgentConfig = Partial<Record<Category, SkillAssignment>>;\n\n${PROJECT_CONFIG_INTERFACE_AFTER}`;\n}\n\n/**\n * Ensures a blank global config exists at ~/.claude-src/.\n * Creates config.ts (empty arrays) and config-types.ts (never types) if they don't exist.\n * Returns true if files were created, false if they already existed.\n */\nexport async function ensureBlankGlobalConfig(): Promise<boolean> {\n const globalConfigDir = path.join(os.homedir(), CLAUDE_SRC_DIR);\n const configPath = path.join(globalConfigDir, STANDARD_FILES.CONFIG_TS);\n\n if (await fileExists(configPath)) {\n verbose(\"Global config already exists, skipping blank creation\");\n return false;\n }\n\n await ensureDir(globalConfigDir);\n\n const configSource = generateBlankGlobalConfigSource();\n const typesSource = generateBlankGlobalConfigTypesSource();\n\n await writeFile(configPath, configSource);\n await writeFile(path.join(globalConfigDir, STANDARD_FILES.CONFIG_TYPES_TS), typesSource);\n\n verbose(`Created blank global config at ${globalConfigDir}`);\n return true;\n}\n","import os from \"os\";\nimport path from \"path\";\nimport { unique } from \"remeda\";\nimport type { AgentName, MergedSkillsMatrix, ProjectConfig, SkillId, Category } from \"../../types\";\nimport {\n CLAUDE_SRC_DIR,\n CLI_BIN_NAME,\n GLOBAL_INSTALL_ROOT,\n PROJECT_ROOT,\n STANDARD_FILES,\n} from \"../../consts\";\nimport { directoryExists, fileExists, writeFile } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport { typedKeys } from \"../../utils/typed-object\";\n\nconst MULTI_LINE_THRESHOLD = 6;\n\n/**\n * Returns the absolute path to the global config-types.ts if it exists, or null.\n * Used to determine whether a project config-types.ts should import from global.\n */\nexport async function getGlobalConfigTypesPath(): Promise<string | null> {\n const globalConfigTypesPath = path.join(\n GLOBAL_INSTALL_ROOT,\n CLAUDE_SRC_DIR,\n STANDARD_FILES.CONFIG_TYPES_TS,\n );\n if (await fileExists(globalConfigTypesPath)) {\n return globalConfigTypesPath;\n }\n return null;\n}\n\n/**\n * Computes a relative import path from a project's .claude-src/ to the global .claude-src/.\n * Returns a POSIX-style relative path suitable for TypeScript import statements.\n */\nfunction computeGlobalTypesImportPath(projectDir: string): string {\n const projectClaudeSrc = path.join(projectDir, CLAUDE_SRC_DIR);\n const globalClaudeSrc = path.join(GLOBAL_INSTALL_ROOT, CLAUDE_SRC_DIR);\n const relativePath = path.relative(projectClaudeSrc, globalClaudeSrc);\n // Convert to POSIX separators for TypeScript imports\n return relativePath.split(path.sep).join(\"/\");\n}\n\n/** Max skills per category before switching to multi-line format in StackAgentConfig */\nconst STACK_AGENT_CONFIG_INLINE_THRESHOLD = 3;\n\n/**\n * Types emitted before the dynamically-generated StackAgentConfig.\n * Includes InstallMode, SkillConfig, AgentScopeConfig, and the generic SkillAssignment.\n */\nexport const PROJECT_CONFIG_TYPES_BEFORE = `export type InstallMode = \"local\" | \"plugin\" | \"mixed\";\n\nexport type SkillConfig = {\n id: SkillId;\n scope: \"project\" | \"global\";\n source: string;\n};\n\nexport type AgentScopeConfig = {\n name: AgentName;\n scope: \"project\" | \"global\";\n};\n\nexport type SkillAssignment<S extends SkillId = SkillId> = S | { id: S; preloaded: boolean };\n`;\n\n/**\n * The ProjectConfig interface, emitted after StackAgentConfig.\n */\nexport const PROJECT_CONFIG_INTERFACE_AFTER = `export interface ProjectConfig {\n /** Config version @default \"1\" */\n version?: \"1\";\n\n /** Project/plugin name (kebab-case) */\n name: string;\n\n /** Project description */\n description?: string;\n\n /** Per-agent configuration with scope */\n agents: AgentScopeConfig[];\n\n /** Per-skill configuration with scope and source */\n skills: SkillConfig[];\n\n /** Author handle (e.g., \"@vince\") */\n author?: string;\n\n /** Stack configuration: agent -> category -> skill assignment */\n stack?: Partial<Record<AgentName, StackAgentConfig>>;\n\n /** Skills source path or URL */\n source?: string;\n\n /** Marketplace identifier for plugin installation */\n marketplace?: string;\n\n /** Agents source path or URL (when agents come from a different source than skills) */\n agentsSource?: string;\n\n /** Selected domains from the wizard */\n domains?: Domain[];\n\n /** Selected agents from the wizard */\n selectedAgents?: AgentName[];\n}\n`;\n\nfunction formatSkillUnion(skills: SkillId[]): string {\n const sorted = [...skills].sort();\n const quoted = sorted.map((s) => `\"${s}\"`);\n if (quoted.length <= STACK_AGENT_CONFIG_INLINE_THRESHOLD) {\n return quoted.join(\" | \");\n }\n return \"\\n\" + quoted.map((q) => ` | ${q}`).join(\"\\n\") + \"\\n \";\n}\n\n/**\n * Generates a per-category constrained StackAgentConfig type from skill-by-category groupings.\n * Falls back to the loose `Partial<Record<Category, SkillAssignment>>` when no categories have skills.\n */\nfunction generateStackAgentConfig(skillsByCategory: Map<Category, SkillId[]>): string {\n if (skillsByCategory.size === 0) {\n return \"export type StackAgentConfig = Partial<Record<Category, SkillAssignment>>;\";\n }\n\n const properties = [...skillsByCategory.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([category, skills]) => ` \"${category}\"?: SkillAssignment<${formatSkillUnion(skills)}>;`);\n\n return [\"export type StackAgentConfig = {\", ...properties, \"};\"].join(\"\\n\");\n}\n\n/**\n * Builds a Map of Category -> SkillId[] from the matrix, filtered to only include\n * categories and skills that are in the provided arrays.\n */\nfunction buildSkillsByCategory(\n skillIds: SkillId[],\n categories: Category[],\n matrix: MergedSkillsMatrix,\n): Map<Category, SkillId[]> {\n const categorySet = new Set(categories);\n const skillIdSet = new Set(skillIds);\n const result = new Map<Category, SkillId[]>();\n\n for (const id of skillIdSet) {\n const skill = matrix.skills[id];\n if (!skill?.category || skill.category === \"local\") continue;\n if (!categorySet.has(skill.category)) continue;\n const existing = result.get(skill.category) ?? [];\n existing.push(id);\n result.set(skill.category, existing);\n }\n\n return result;\n}\n\nexport type ConfigTypesBackgroundData = {\n matrix: MergedSkillsMatrix;\n agentNames: AgentName[];\n customAgentNames: AgentName[];\n};\n\n/**\n * Kicks off background loading of the matrix and agents needed for config-types.ts regeneration.\n * Returns a promise that resolves with the loaded data. Callers should NOT await this immediately;\n * instead, pass the promise to `regenerateConfigTypes` after the main operation completes.\n *\n * @param sourceFlag Optional --source flag value\n * @param projectDir The project root directory\n */\nexport function loadConfigTypesDataInBackground(\n sourceFlag: string | undefined,\n projectDir: string,\n): Promise<ConfigTypesBackgroundData> {\n // Dynamic imports to avoid circular dependency issues at module load time\n const promise = (async (): Promise<ConfigTypesBackgroundData> => {\n const claudeSrcDir = path.join(projectDir, CLAUDE_SRC_DIR);\n if (!(await directoryExists(claudeSrcDir))) {\n throw new Error(`${CLAUDE_SRC_DIR}/ not found — run '${CLI_BIN_NAME} init' first`);\n }\n\n const { loadSkillsMatrixFromSource } = await import(\"../loading/source-loader\");\n const { loadAllAgents } = await import(\"../loading/loader\");\n\n const sourceResult = await loadSkillsMatrixFromSource({\n sourceFlag,\n projectDir,\n skipExtraSources: true,\n });\n\n const cliAgents = await loadAllAgents(PROJECT_ROOT);\n const sourceAgents = await loadAllAgents(sourceResult.sourcePath);\n const allAgents = { ...cliAgents, ...sourceAgents };\n const agentNames = typedKeys<AgentName>(allAgents);\n const customAgentNames = agentNames.filter((name) => allAgents[name]?.custom === true);\n\n return { matrix: sourceResult.matrix, agentNames, customAgentNames };\n })();\n\n // Prevent unhandled rejection if the command exits before awaiting this promise\n promise.catch(() => {});\n\n return promise;\n}\n\n/**\n * Regenerates config-types.ts with the latest matrix data, merging in any extra entities\n * that were just created (e.g., a new skill or agent). Errors propagate to callers.\n *\n * @param projectDir The project root directory\n * @param backgroundData Promise from loadConfigTypesDataInBackground\n * @param extras Optional extra skill IDs or agent names to include (for just-created entities)\n */\nexport async function regenerateConfigTypes(\n projectDir: string,\n backgroundData: Promise<ConfigTypesBackgroundData>,\n extras?: {\n extraSkillIds?: string[];\n extraAgentNames?: string[];\n extraDomains?: string[];\n extraCategories?: string[];\n },\n): Promise<void> {\n const data = await backgroundData;\n\n const claudeSrcDir = path.join(projectDir, CLAUDE_SRC_DIR);\n\n // When a global installation exists and we're regenerating for a project,\n // generate a project config-types.ts that imports from the global one\n const isProjectScope = path.resolve(projectDir) !== path.resolve(os.homedir());\n const globalConfigTypes = isProjectScope ? await getGlobalConfigTypesPath() : null;\n\n let source: string;\n if (globalConfigTypes) {\n source = generateProjectConfigTypesSource({\n globalTypesImportPath: computeGlobalTypesImportPath(projectDir),\n projectSkillIds: extras?.extraSkillIds ?? [],\n projectAgentNames: extras?.extraAgentNames ?? [],\n projectDomains: extras?.extraDomains ?? [],\n projectCategories: extras?.extraCategories ?? [],\n });\n verbose(\"Using project config-types.ts that imports from global\");\n } else {\n source = generateConfigTypesSource(data.matrix, data.agentNames, data.customAgentNames, extras);\n }\n\n const configTypesPath = path.join(claudeSrcDir, STANDARD_FILES.CONFIG_TYPES_TS);\n await writeFile(configTypesPath, source);\n verbose(`Regenerated ${STANDARD_FILES.CONFIG_TYPES_TS}`);\n}\n\n/**\n * Generates a config-types.ts source from marketplace data.\n * The generated file provides type safety for config.ts via `import type` + `satisfies`.\n *\n * @param customAgentNames Agent names that are custom (from sources with `custom: true`)\n * @param extras Optional extra skill IDs or agent names to include (for just-created entities)\n * @param config Optional ProjectConfig to narrow unions to only installed items.\n * When provided, SkillId/AgentName/Category/Domain are derived from\n * the config's skills[] and agents[] rather than the full matrix.\n */\nexport function generateConfigTypesSource(\n matrix: MergedSkillsMatrix,\n agentNames: AgentName[],\n customAgentNames: AgentName[] = [],\n extras?: {\n extraSkillIds?: string[];\n extraAgentNames?: string[];\n extraDomains?: string[];\n extraCategories?: string[];\n },\n config?: ProjectConfig,\n): string {\n // Boundary cast: extra IDs from CLI args may not match strict union patterns\n const extraSkillIds = (extras?.extraSkillIds ?? []) as SkillId[];\n const extraAgentNamesArr = (extras?.extraAgentNames ?? []) as AgentName[];\n const extraDomainsArr = extras?.extraDomains ?? [];\n const extraCategoriesArr = (extras?.extraCategories ?? []) as Category[];\n\n let skillIds: SkillId[];\n let sortedAgents: AgentName[];\n let domains: string[];\n let categories: Category[];\n\n if (config) {\n // Narrow to only installed/configured items\n const configSkillIds = config.skills.map((s) => s.id);\n skillIds = unique([...configSkillIds, ...extraSkillIds]).sort();\n\n const configAgentNames = config.agents.map((a) => a.name);\n sortedAgents = unique([...configAgentNames, ...extraAgentNamesArr]).sort();\n\n // Derive categories from installed skills via matrix lookup\n const configCategories = deriveCategories(configSkillIds, matrix);\n categories = unique([...configCategories, ...extraCategoriesArr]).sort();\n\n // Derive domains from included categories via matrix lookup\n const configDomains = deriveDomains(categories, matrix);\n domains = unique([...configDomains, ...extraDomainsArr]).sort();\n } else {\n // Fall back to full matrix (e.g., blank global config)\n skillIds = unique([...typedKeys(matrix.skills), ...extraSkillIds]).sort();\n sortedAgents = unique([...agentNames, ...extraAgentNamesArr]).sort();\n domains = unique([...extractDomains(matrix), ...extraDomainsArr]).sort();\n categories = unique([...typedKeys(matrix.categories), ...extraCategoriesArr]).sort();\n }\n\n // Determine which skills are custom\n const customSkillSet = new Set<SkillId>(extraSkillIds);\n for (const id of typedKeys(matrix.skills)) {\n const skill = matrix.skills[id];\n if (skill?.custom === true) {\n customSkillSet.add(id);\n }\n }\n\n // Determine which agents are custom\n const customAgentSet = new Set<AgentName>([...customAgentNames, ...extraAgentNamesArr]);\n\n // Determine which categories are custom (referenced by custom skills or passed as extras)\n const customCategorySet = new Set<Category>(extraCategoriesArr);\n for (const id of typedKeys(matrix.skills)) {\n const skill = matrix.skills[id];\n if (skill?.custom === true && skill.category && skill.category !== \"local\") {\n customCategorySet.add(skill.category);\n }\n }\n\n // Determine which domains are custom (only appear on custom categories)\n const customDomainSet = new Set<string>();\n const marketplaceDomainSet = new Set<string>();\n for (const key of typedKeys(matrix.categories)) {\n const cat = matrix.categories[key];\n if (!cat?.domain) continue;\n if (customCategorySet.has(key)) {\n customDomainSet.add(cat.domain);\n } else {\n marketplaceDomainSet.add(cat.domain);\n }\n }\n // A domain is only custom if it NEVER appears on a non-custom category\n for (const domain of marketplaceDomainSet) {\n customDomainSet.delete(domain);\n }\n // Explicitly-passed extra domains are always treated as custom\n for (const domain of extraDomainsArr) {\n customDomainSet.add(domain);\n }\n\n const skillIdLine = formatMaybeSectionedUnion(skillIds, (id) => customSkillSet.has(id));\n const agentNameLine = formatMaybeSectionedUnion(sortedAgents, (name) => customAgentSet.has(name));\n const domainLine = formatMaybeSectionedUnion(domains, (d) => customDomainSet.has(d));\n const categoryLine = formatMaybeSectionedUnion(categories, (s) => customCategorySet.has(s));\n\n const skillsByCategory = buildSkillsByCategory(skillIds, categories, matrix);\n const stackAgentConfigType = generateStackAgentConfig(skillsByCategory);\n\n return `// AUTO-GENERATED by agentsinc — DO NOT EDIT\n\nexport type SkillId = ${skillIdLine};\n\nexport type AgentName = ${agentNameLine};\n\nexport type Domain = ${domainLine};\n\nexport type Category = ${categoryLine};\n\n${PROJECT_CONFIG_TYPES_BEFORE}\n${stackAgentConfigType}\n\n${PROJECT_CONFIG_INTERFACE_AFTER}`;\n}\n\nfunction extractDomains(matrix: MergedSkillsMatrix): string[] {\n const domainSet = new Set<string>();\n for (const key of typedKeys(matrix.categories)) {\n const category = matrix.categories[key];\n if (category?.domain) {\n domainSet.add(category.domain);\n }\n }\n return [...domainSet].sort();\n}\n\n/**\n * Derives the set of categories that the given skill IDs belong to,\n * by looking up each skill's category in the matrix.\n */\nfunction deriveCategories(skillIds: SkillId[], matrix: MergedSkillsMatrix): Category[] {\n const categorySet = new Set<Category>();\n for (const id of skillIds) {\n const skill = matrix.skills[id];\n if (skill?.category && skill.category !== \"local\") {\n // Boundary cast: CategoryPath to Category for matrix key lookup\n categorySet.add(skill.category as Category);\n }\n }\n return [...categorySet];\n}\n\n/**\n * Derives the set of domains that the given categories belong to,\n * by looking up each category's domain in the matrix.\n */\nfunction deriveDomains(categories: Category[], matrix: MergedSkillsMatrix): string[] {\n const domainSet = new Set<string>();\n for (const cat of categories) {\n const def = matrix.categories[cat];\n if (def?.domain) {\n domainSet.add(def.domain);\n }\n }\n return [...domainSet];\n}\n\n/**\n * Renders a union type with optional // Custom and // Marketplace section comments.\n * If all members are in one group, only that group's header is shown.\n * If both groups exist, renders with section comments and always uses multi-line format.\n */\nfunction formatSectionedUnion(custom: string[], marketplace: string[]): string {\n if (custom.length === 0 && marketplace.length === 0) {\n return \"string\";\n }\n\n // Only one group present: show single header\n if (marketplace.length === 0) {\n const lines = custom.map((m) => ` | \"${m}\"`);\n return \"\\n // Custom\\n\" + lines.join(\"\\n\");\n }\n if (custom.length === 0) {\n const lines = marketplace.map((m) => ` | \"${m}\"`);\n return \"\\n // Marketplace\\n\" + lines.join(\"\\n\");\n }\n\n // Both groups: custom first, then marketplace\n const customLines = custom.map((m) => ` | \"${m}\"`);\n const marketplaceLines = marketplace.map((m) => ` | \"${m}\"`);\n return (\n \"\\n // Custom\\n\" +\n customLines.join(\"\\n\") +\n \"\\n // Marketplace\\n\" +\n marketplaceLines.join(\"\\n\")\n );\n}\n\n/**\n * Formats a union, using section comments when custom members exist,\n * or plain formatUnion when there are no custom members.\n */\nfunction formatMaybeSectionedUnion<T extends string>(\n members: T[],\n isCustom: (member: T) => boolean,\n): string {\n if (members.length === 0) {\n return \"string\";\n }\n\n const custom = members.filter(isCustom);\n const marketplace = members.filter((m) => !isCustom(m));\n\n // No custom members: use standard formatting (preserves single-line for small unions)\n if (custom.length === 0) {\n return formatUnion(members);\n }\n\n return formatSectionedUnion(custom, marketplace);\n}\n\nfunction formatUnion(members: string[]): string {\n if (members.length === 0) {\n return \"string\";\n }\n\n const quoted = members.map((m) => `\"${m}\"`);\n\n if (quoted.length < MULTI_LINE_THRESHOLD) {\n return quoted.join(\" | \");\n }\n\n return \"\\n\" + quoted.map((q) => ` | ${q}`).join(\"\\n\");\n}\n\nexport type ProjectConfigTypesOptions = {\n /**\n * Absolute path to the global .claude-src directory.\n * When set, generates import statements that extend global types.\n */\n globalTypesImportPath: string;\n /** Project-only skill IDs (not including global) */\n projectSkillIds: string[];\n /** Project-only agent names (not including global) */\n projectAgentNames: string[];\n /** Project-only domains (not including global) */\n projectDomains: string[];\n /** Project-only categories (not including global) */\n projectCategories?: string[];\n};\n\n/**\n * Generates a project config-types.ts source that imports global types and extends them.\n * Each type union is `GlobalType | \"project-item-1\" | \"project-item-2\"`.\n * When projectCategories are provided, Category extends GlobalCategory instead of being `string`.\n */\nexport function generateProjectConfigTypesSource(options: ProjectConfigTypesOptions): string {\n const importPath = `${options.globalTypesImportPath}/config-types`;\n\n const skillIdUnion = formatExtendedUnion(\"GlobalSkillId\", options.projectSkillIds);\n const agentNameUnion = formatExtendedUnion(\"GlobalAgentName\", options.projectAgentNames);\n const domainUnion = formatExtendedUnion(\"GlobalDomain\", options.projectDomains);\n\n const hasProjectCategories = options.projectCategories && options.projectCategories.length > 0;\n const categoryUnion = hasProjectCategories\n ? formatExtendedUnion(\"GlobalCategory\", options.projectCategories!)\n : \"GlobalCategory\";\n\n // Import Category as GlobalCategory when we have project categories or need to re-export it\n const categoryImport = ` Category as GlobalCategory,\\n`;\n\n return `// AUTO-GENERATED by agentsinc — DO NOT EDIT\n\nimport type {\n SkillId as GlobalSkillId,\n AgentName as GlobalAgentName,\n Domain as GlobalDomain,\n${categoryImport}} from \"${importPath}\";\n\nexport type SkillId = ${skillIdUnion};\n\nexport type AgentName = ${agentNameUnion};\n\nexport type Domain = ${domainUnion};\n\nexport type Category = ${categoryUnion};\n\n${PROJECT_CONFIG_TYPES_BEFORE}\nexport type StackAgentConfig = Partial<Record<Category, SkillAssignment>>;\n\n${PROJECT_CONFIG_INTERFACE_AFTER}`;\n}\n\n/**\n * Formats a union that extends a global type alias.\n * Returns `GlobalType` when no project members exist, or `GlobalType | \"a\" | \"b\"` with members.\n */\nfunction formatExtendedUnion(globalTypeName: string, projectMembers: string[]): string {\n if (projectMembers.length === 0) {\n return globalTypeName;\n }\n\n const sorted = [...projectMembers].sort();\n const quoted = sorted.map((m) => `\"${m}\"`);\n\n if (quoted.length < MULTI_LINE_THRESHOLD) {\n return `${globalTypeName} | ${quoted.join(\" | \")}`;\n }\n\n return `\\n | ${globalTypeName}\\n` + quoted.map((q) => ` | ${q}`).join(\"\\n\");\n}\n","import path from \"path\";\nimport type { SourceEntry } from \"./config\";\nimport { loadProjectSourceConfig, getProjectConfigPath, DEFAULT_SOURCE } from \"./config\";\nimport { generateConfigSource } from \"./config-writer\";\nimport { fetchMarketplace } from \"../loading/source-fetcher\";\nimport { discoverLocalSkills } from \"../skills/local-skill-loader\";\nimport { discoverAllPluginSkills } from \"../plugins/plugin-discovery\";\nimport { writeFile, ensureDir } from \"../../utils/fs\";\nimport { CLAUDE_SRC_DIR } from \"../../consts\";\nimport type { ProjectConfig } from \"../../types\";\nimport { verbose } from \"../../utils/logger\";\n\nconst DEFAULT_SOURCE_NAME = \"public\";\n\nexport type SourceSummary = {\n sources: Array<SourceEntry & { enabled: boolean }>;\n localSkillCount: number;\n pluginSkillCount: number;\n};\n\n/**\n * Add a new source to the project configuration.\n * Validates the URL by fetching the marketplace.\n */\nexport async function addSource(\n projectDir: string,\n url: string,\n): Promise<{ name: string; skillCount: number }> {\n const result = await fetchMarketplace(url, { forceRefresh: true });\n const name = result.marketplace.name;\n const skillCount = result.marketplace.plugins.length;\n\n const config = (await loadProjectSourceConfig(projectDir)) ?? {};\n const sources = config.sources ?? [];\n\n const exists = sources.some((s) => s.name === name);\n if (exists) {\n throw new Error(`Source \"${name}\" already exists`);\n }\n\n sources.push({ name, url });\n const updated: Partial<ProjectConfig> = { ...config, sources };\n await writeConfigFromPartial(projectDir, updated);\n\n verbose(`Added source \"${name}\" with ${skillCount} skills`);\n return { name, skillCount };\n}\n\n/**\n * Remove a source by name. Cannot remove \"public\" (the default).\n */\nexport async function removeSource(projectDir: string, name: string): Promise<void> {\n if (name === DEFAULT_SOURCE_NAME) {\n throw new Error(`Cannot remove the \"${DEFAULT_SOURCE_NAME}\" source`);\n }\n\n const config = (await loadProjectSourceConfig(projectDir)) ?? {};\n const sources = config.sources ?? [];\n\n const filtered = sources.filter((s) => s.name !== name);\n if (filtered.length === sources.length) {\n throw new Error(`Source \"${name}\" not found`);\n }\n\n const updated: Partial<ProjectConfig> = { ...config, sources: filtered };\n await writeConfigFromPartial(projectDir, updated);\n\n verbose(`Removed source \"${name}\"`);\n}\n\n/**\n * Get summary of all configured sources and local/plugin counts.\n */\nexport async function getSourceSummary(projectDir: string): Promise<SourceSummary> {\n const config = (await loadProjectSourceConfig(projectDir)) ?? {};\n\n const sources: Array<SourceEntry & { enabled: boolean }> = [\n {\n name: DEFAULT_SOURCE_NAME,\n url: config.source ?? DEFAULT_SOURCE,\n enabled: true,\n },\n ];\n\n if (config.sources) {\n for (const source of config.sources) {\n sources.push({ ...source, enabled: true });\n }\n }\n\n let localSkillCount = 0;\n try {\n const localResult = await discoverLocalSkills(projectDir);\n if (localResult) {\n localSkillCount = localResult.skills.length;\n }\n } catch {\n verbose(\"Failed to discover local skills for source summary\");\n }\n\n let pluginSkillCount = 0;\n try {\n const discoveredSkills = await discoverAllPluginSkills(projectDir);\n pluginSkillCount = Object.keys(discoveredSkills).length;\n } catch {\n verbose(\"Failed to discover plugin skills for source summary\");\n }\n\n return { sources, localSkillCount, pluginSkillCount };\n}\n\n/** Write a partial config to disk. Requires `name` to be present (config must already exist). */\nasync function writeConfigFromPartial(\n projectDir: string,\n partial: Partial<ProjectConfig>,\n): Promise<void> {\n if (!partial.name) {\n throw new Error(\"Cannot write config: no project config found. Run `agentsinc init` first.\");\n }\n\n const config: ProjectConfig = {\n ...partial,\n name: partial.name,\n skills: partial.skills ?? [],\n agents: partial.agents ?? [],\n };\n\n const configPath = getProjectConfigPath(projectDir);\n await ensureDir(path.join(projectDir, CLAUDE_SRC_DIR));\n await writeFile(configPath, generateConfigSource(config));\n}\n","import { createHash } from \"crypto\";\nimport { downloadTemplate } from \"giget\";\nimport os from \"os\";\nimport path from \"path\";\n\nimport {\n CACHE_DIR,\n CACHE_HASH_LENGTH,\n CACHE_READABLE_PREFIX_LENGTH,\n MAX_MARKETPLACE_FILE_SIZE,\n MAX_JSON_NESTING_DEPTH,\n MAX_MARKETPLACE_PLUGINS,\n PLUGIN_MANIFEST_DIR,\n} from \"../../consts\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { ensureDir, directoryExists, readFileSafe, remove } from \"../../utils/fs\";\nimport { verbose, warn } from \"../../utils/logger\";\nimport { isLocalSource } from \"../configuration\";\nimport {\n formatZodErrors,\n marketplaceSchema,\n validateNestingDepth,\n warnUnknownFields,\n} from \"../schemas\";\nimport type { MarketplaceFetchResult } from \"../../types\";\n\n/** Safe name pattern: alphanumeric, hyphens, underscores, dots, spaces, @, / (no shell metacharacters) */\nconst SAFE_NAME_PATTERN = /^[a-zA-Z0-9@._/ -]+$/;\nconst MAX_NAME_LENGTH = 200;\n\n/** Matches giget's source protocol regex to extract provider name */\nconst SOURCE_PROTO_RE = /^([\\w-.]+):/;\n\n/**\n * Matches giget's input regex for git URI parsing.\n * Groups: repo (org/name), subdir (optional path), ref (optional #branch)\n */\nconst GIT_URI_RE = /^(?<repo>[\\w.-]+\\/[\\w.-]+)(?<subdir>[^#]+)?(?<ref>#[\\w./@-]+)?/;\n\nexport type FetchOptions = {\n forceRefresh?: boolean;\n subdir?: string;\n};\n\nexport type FetchResult = {\n path: string;\n fromCache: boolean;\n source: string;\n};\n\nexport function sanitizeSourceForCache(source: string): string {\n const hash = createHash(\"sha256\").update(source).digest(\"hex\").slice(0, CACHE_HASH_LENGTH);\n\n const readable = source\n .replace(/[^a-zA-Z0-9]/g, \"-\")\n .replace(/--+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .slice(0, CACHE_READABLE_PREFIX_LENGTH);\n\n return readable ? `${readable}-${hash}` : hash;\n}\n\nfunction getCacheDir(source: string): string {\n const sanitized = sanitizeSourceForCache(source) || \"unknown\";\n return path.join(CACHE_DIR, \"sources\", sanitized);\n}\n\nexport async function fetchFromSource(\n source: string,\n options: FetchOptions = {},\n): Promise<FetchResult> {\n const { forceRefresh = false, subdir } = options;\n\n if (isLocalSource(source)) {\n return fetchFromLocalSource(source, subdir);\n }\n\n return fetchFromRemoteSource(source, { forceRefresh, subdir });\n}\n\nasync function fetchFromLocalSource(source: string, subdir?: string): Promise<FetchResult> {\n const fullPath = subdir ? path.join(source, subdir) : source;\n const absolutePath = path.isAbsolute(fullPath) ? fullPath : path.resolve(process.cwd(), fullPath);\n\n if (!(await directoryExists(absolutePath))) {\n throw new Error(`Local source not found: '${absolutePath}'`);\n }\n\n verbose(`Using local source: ${absolutePath}`);\n\n return {\n path: absolutePath,\n fromCache: false,\n source,\n };\n}\n\n/**\n * Compute the giget tarball cache directory for a source.\n *\n * Replicates giget's internal cache path logic:\n * `{cacheRoot}/{providerName}/{templateName}`\n *\n * where templateName is `repo.replace(\"/\", \"-\")` sanitized to `[a-zA-Z0-9-]`.\n * Returns undefined if the source format doesn't match giget's git URI pattern.\n */\nfunction getGigetCacheDir(source: string): string | undefined {\n let providerName = \"github\";\n let rawSource = source;\n\n const protoMatch = source.match(SOURCE_PROTO_RE);\n if (protoMatch) {\n providerName = protoMatch[1];\n rawSource = source.slice(protoMatch[0].length);\n // http/https providers use the full URL, not parseable as git URI\n if (providerName === \"http\" || providerName === \"https\") {\n return undefined;\n }\n }\n\n const uriMatch = rawSource.match(GIT_URI_RE);\n if (!uriMatch?.groups?.repo) {\n return undefined;\n }\n\n // Replicate giget's template.name sanitization\n const templateName = uriMatch.groups.repo.replace(\"/\", \"-\").replace(/[^\\da-z-]/gi, \"-\");\n\n const gigetCacheRoot = process.env.XDG_CACHE_HOME\n ? path.resolve(process.env.XDG_CACHE_HOME, \"giget\")\n : path.resolve(os.homedir(), \".cache\", \"giget\");\n\n return path.join(gigetCacheRoot, providerName, templateName);\n}\n\n/**\n * Clear giget's tarball/ETag cache for a source so downloadTemplate()\n * performs a fresh fetch instead of short-circuiting with a stale ETag.\n */\nasync function clearGigetCache(source: string): Promise<void> {\n const gigetDir = getGigetCacheDir(source);\n if (!gigetDir) return;\n\n if (await directoryExists(gigetDir)) {\n verbose(`Clearing giget cache: ${gigetDir}`);\n await remove(gigetDir);\n }\n}\n\nasync function fetchFromRemoteSource(source: string, options: FetchOptions): Promise<FetchResult> {\n const { forceRefresh = false, subdir } = options;\n const cacheDir = getCacheDir(source);\n\n const fullSource = subdir ? `${source}/${subdir}` : source;\n\n verbose(`Fetching from remote: ${fullSource}`);\n verbose(`Cache directory: ${cacheDir}`);\n\n if (!forceRefresh && (await directoryExists(cacheDir))) {\n verbose(`Using cached source: ${cacheDir}`);\n return {\n path: cacheDir,\n fromCache: true,\n source: fullSource,\n };\n }\n\n if (forceRefresh) {\n await clearGigetCache(source);\n await remove(cacheDir);\n }\n\n await ensureDir(path.dirname(cacheDir));\n\n try {\n const result = await downloadTemplate(fullSource, {\n dir: cacheDir,\n force: true, // Always force when downloading to avoid \"already exists\" error\n offline: false,\n });\n\n verbose(`Downloaded to: ${result.dir}`);\n\n return {\n path: result.dir,\n fromCache: false,\n source: fullSource,\n };\n } catch (error) {\n throw createDetailedFetchError(error, source);\n }\n}\n\nfunction createDetailedFetchError(error: unknown, source: string): Error {\n const message = getErrorMessage(error);\n\n if (message.includes(\"404\") || message.includes(\"Not Found\")) {\n return new Error(\n `Repository not found: ${source}\\n\\n` +\n `This could mean:\\n` +\n ` - The repository doesn't exist\\n` +\n ` - The repository is private and you need to set authentication\\n` +\n ` - There's a typo in the URL\\n\\n` +\n `For private repositories, set the GIGET_AUTH environment variable:\\n` +\n ` export GIGET_AUTH=ghp_your_github_token`,\n );\n }\n\n if (message.includes(\"401\") || message.includes(\"Unauthorized\")) {\n return new Error(\n `Authentication required for: ${source}\\n\\n` +\n `Set the GIGET_AUTH environment variable with a GitHub token:\\n` +\n ` export GIGET_AUTH=ghp_your_github_token\\n\\n` +\n `Create a token at: https://github.com/settings/tokens\\n` +\n `Required scope: repo (for private repos) or public_repo (for public)`,\n );\n }\n\n if (message.includes(\"403\") || message.includes(\"Forbidden\")) {\n return new Error(\n `Access denied to: ${source}\\n\\n` +\n `Your token may not have sufficient permissions.\\n` +\n `Ensure your GIGET_AUTH token has the 'repo' scope for private repositories.`,\n );\n }\n\n if (\n message.includes(\"ENOTFOUND\") ||\n message.includes(\"ETIMEDOUT\") ||\n message.includes(\"network\")\n ) {\n return new Error(\n `Network error fetching: ${source}\\n\\n` +\n `Please check your internet connection.\\n` +\n `If you're behind a corporate proxy, you may need to set:\\n` +\n ` export HTTPS_PROXY=http://your-proxy:port\\n` +\n ` export FORCE_NODE_FETCH=true # Required for Node 20+`,\n );\n }\n\n return new Error(`Failed to fetch ${source}: ${message}`);\n}\n\nexport async function fetchMarketplace(\n source: string,\n options: FetchOptions = {},\n): Promise<MarketplaceFetchResult> {\n const result = await fetchFromSource(source, {\n forceRefresh: options.forceRefresh,\n subdir: \"\", // Root of repo\n });\n\n const marketplacePath = path.join(result.path, PLUGIN_MANIFEST_DIR, \"marketplace.json\");\n\n if (!(await directoryExists(path.dirname(marketplacePath)))) {\n throw new Error(\n `Marketplace not found for source: ${source}\\n\\n` +\n `The .claude-plugin/marketplace.json file is missing from this repository.\\n\\n` +\n `Possible causes:\\n` +\n \" - The source URL may be incorrect\\n\" +\n \" - The repository may not have a marketplace configured\\n\\n\" +\n \"To create a marketplace, add a .claude-plugin/marketplace.json file to your source repository.\",\n );\n }\n\n const content = await readFileSafe(marketplacePath, MAX_MARKETPLACE_FILE_SIZE);\n const parsed = JSON.parse(content);\n\n if (!validateNestingDepth(parsed, MAX_JSON_NESTING_DEPTH)) {\n throw new Error(\n `Invalid marketplace.json at: ${marketplacePath}\\n\\n` +\n `JSON structure exceeds maximum nesting depth of ${MAX_JSON_NESTING_DEPTH}.`,\n );\n }\n\n const validation = marketplaceSchema.safeParse(parsed);\n\n if (!validation.success) {\n throw new Error(\n `Invalid marketplace.json at: ${marketplacePath}\\n\\n` +\n `Validation errors: ${formatZodErrors(validation.error.issues)}`,\n );\n }\n\n const marketplace = validation.data;\n\n const EXPECTED_MARKETPLACE_KEYS = [\n \"$schema\",\n \"name\",\n \"version\",\n \"description\",\n \"owner\",\n \"metadata\",\n \"plugins\",\n ] as const;\n if (typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)) {\n warnUnknownFields(\n parsed as Record<string, unknown>,\n EXPECTED_MARKETPLACE_KEYS,\n \"marketplace.json\",\n );\n }\n\n if (marketplace.plugins.length > MAX_MARKETPLACE_PLUGINS) {\n throw new Error(\n `Invalid marketplace.json at: ${marketplacePath}\\n\\n` +\n `Too many plugins: ${marketplace.plugins.length} (limit: ${MAX_MARKETPLACE_PLUGINS}).`,\n );\n }\n\n for (const plugin of marketplace.plugins) {\n if (plugin.name.length > MAX_NAME_LENGTH) {\n warn(\n `Marketplace plugin name too long (${plugin.name.length} chars): '${plugin.name.slice(0, 50)}...'`,\n );\n }\n if (!SAFE_NAME_PATTERN.test(plugin.name)) {\n warn(`Marketplace plugin name contains unsafe characters: '${plugin.name.slice(0, 50)}'`);\n }\n }\n\n verbose(`Loaded marketplace: ${marketplace.name} v${marketplace.version}`);\n\n return {\n marketplace,\n sourcePath: result.path,\n fromCache: result.fromCache ?? false,\n };\n}\n","import { parse as parseYaml } from \"yaml\";\nimport path from \"path\";\nimport { directoryExists, listDirectories, fileExists, readFile } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport { LOCAL_SKILLS_PATH, STANDARD_FILES } from \"../../consts\";\nimport { parseFrontmatter } from \"../loading\";\nimport type { CategoryPath, Domain, ExtractedSkillMetadata, SkillSlug } from \"../../types\";\nimport { formatZodErrors, localRawMetadataSchema } from \"../schemas\";\nimport { LOCAL_DEFAULTS } from \"../metadata-keys\";\n\ntype LocalRawMetadata = {\n displayName: string;\n /** Kebab-case short key for alias resolution */\n slug: SkillSlug;\n cliDescription?: string;\n /** Skill category (e.g., \"web-framework\", \"web-styling\", \"api-api\") */\n category: CategoryPath;\n usageGuidance?: string;\n tags?: string[];\n /** Domain this skill belongs to (e.g., \"web\", \"api\", \"cli\") */\n domain: Domain;\n /** True if this skill was created outside the CLI's built-in vocabulary */\n custom?: boolean;\n};\n\nexport type LocalSkillDiscoveryResult = {\n skills: ExtractedSkillMetadata[];\n localSkillsPath: string;\n};\n\nexport async function discoverLocalSkills(\n projectDir: string,\n): Promise<LocalSkillDiscoveryResult | null> {\n const localSkillsPath = path.join(projectDir, LOCAL_SKILLS_PATH);\n\n if (!(await directoryExists(localSkillsPath))) {\n verbose(`Local skills directory not found: ${localSkillsPath}`);\n return null;\n }\n\n const skills: ExtractedSkillMetadata[] = [];\n const skillDirs = await listDirectories(localSkillsPath);\n\n for (const skillDirName of skillDirs) {\n const skill = await extractLocalSkill(localSkillsPath, skillDirName);\n if (skill) {\n skills.push(skill);\n }\n }\n\n verbose(`Discovered ${skills.length} local skills from ${localSkillsPath}`);\n\n return {\n skills,\n localSkillsPath,\n };\n}\n\nasync function extractLocalSkill(\n localSkillsPath: string,\n skillDirName: string,\n): Promise<ExtractedSkillMetadata | null> {\n const skillDir = path.join(localSkillsPath, skillDirName);\n const metadataPath = path.join(skillDir, STANDARD_FILES.METADATA_YAML);\n const skillMdPath = path.join(skillDir, STANDARD_FILES.SKILL_MD);\n\n if (!(await fileExists(metadataPath))) {\n verbose(`Skipping local skill '${skillDirName}': No metadata.yaml found`);\n return null;\n }\n\n if (!(await fileExists(skillMdPath))) {\n verbose(`Skipping local skill '${skillDirName}': No SKILL.md found`);\n return null;\n }\n\n const metadataContent = await readFile(metadataPath);\n const parsed = localRawMetadataSchema.safeParse(parseYaml(metadataContent));\n\n if (!parsed.success) {\n verbose(\n `Skipping local skill '${skillDirName}': invalid metadata.yaml — ${formatZodErrors(parsed.error.issues)}`,\n );\n return null;\n }\n\n const metadata = parsed.data as LocalRawMetadata;\n\n const skillMdContent = await readFile(skillMdPath);\n const frontmatter = parseFrontmatter(skillMdContent, skillMdPath);\n\n if (!frontmatter) {\n verbose(`Skipping local skill '${skillDirName}': invalid SKILL.md frontmatter`);\n return null;\n }\n\n const relativePath = `${LOCAL_SKILLS_PATH}/${skillDirName}/`;\n const skillId = frontmatter.name;\n\n const extracted: ExtractedSkillMetadata = {\n id: skillId,\n directoryPath: skillDirName,\n description: metadata.cliDescription || frontmatter.description,\n usageGuidance: metadata.usageGuidance,\n category: metadata.category,\n author: LOCAL_DEFAULTS.AUTHOR,\n tags: metadata.tags ?? [],\n path: relativePath,\n local: true,\n localPath: relativePath,\n domain: metadata.domain,\n custom: metadata.custom,\n slug: metadata.slug,\n displayName: metadata.displayName,\n };\n\n verbose(`Extracted local skill: ${skillId}`);\n return extracted;\n}\n","export {\n parseFrontmatter,\n loadAllAgents,\n loadProjectAgents,\n loadSkillsByIds,\n loadPluginSkills,\n} from \"./loader\";\n\nexport {\n type SourceLoadOptions,\n type SourceLoadResult,\n loadSkillsMatrixFromSource,\n getMarketplaceLabel,\n} from \"./source-loader\";\n\nexport {\n type FetchOptions,\n type FetchResult,\n sanitizeSourceForCache,\n fetchFromSource,\n fetchMarketplace,\n} from \"./source-fetcher\";\n\nexport { loadSkillsFromAllSources } from \"./multi-source-loader\";\n","import path from \"path\";\n\nimport { DEFAULT_PUBLIC_SOURCE_NAME, SKILLS_DIR_PATH } from \"../../consts\";\nimport type {\n BoundSkillCandidate,\n MergedSkillsMatrix,\n SkillAlias,\n SkillId,\n SkillSource,\n SkillSourceType,\n} from \"../../types\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { verbose, warn } from \"../../utils/logger\";\nimport { typedEntries, typedKeys } from \"../../utils/typed-object\";\nimport {\n DEFAULT_SOURCE,\n resolveAllSources,\n type ResolvedConfig,\n type SourceEntry,\n} from \"../configuration\";\nimport { extractAllSkills } from \"../matrix\";\nimport { discoverAllPluginSkills } from \"../plugins\";\nimport { fetchFromSource, fetchMarketplace } from \"./source-fetcher\";\n\n/**\n * Annotates every skill in the matrix with multi-source availability metadata.\n *\n * Runs a six-phase tagging pipeline that mutates `primaryMatrix.skills` in place:\n * 1. **Primary** -- tags all skills with the primary source (public or private marketplace)\n * 2. **Local** -- tags skills with `local: true` as installed via local source\n * 3. **Plugin** -- detects plugin-installed skills via `settings.json` and global cache\n * 4. **Public fallback** -- when primary is a private marketplace, fetches the default\n * public source and tags matching skills so users can switch between sources\n * 5. **Extra sources** -- fetches each configured extra source and tags matching skills\n * 6. **Active source** -- sets `activeSource` to the installed variant, or first available\n *\n * After this function completes, each skill in the matrix has `availableSources` (all\n * known sources) and `activeSource` (the one currently in use) populated.\n *\n * @param primaryMatrix - The merged skills matrix to annotate. Mutated in place --\n * `availableSources` and `activeSource` are set on each skill.\n * @param sourceConfig - Resolved source configuration, used to determine whether the\n * primary source is a private marketplace or the default public source\n * @param projectDir - Absolute path to the project root, used to locate plugin directories\n * and resolve extra source configurations\n * @param forceRefresh - Whether to bypass cached source data\n * @param marketplace - Optional marketplace name resolved from the source's marketplace.json.\n * Takes precedence over `sourceConfig.marketplace` when provided.\n *\n * @remarks\n * **Side effects:** Mutates `primaryMatrix` in place. May perform network requests\n * to fetch extra source repositories (via giget). Errors from individual extra sources\n * are warned and skipped -- the function never throws.\n */\nexport async function loadSkillsFromAllSources(\n primaryMatrix: MergedSkillsMatrix,\n sourceConfig: ResolvedConfig,\n projectDir: string,\n forceRefresh = false,\n marketplace?: string,\n): Promise<void> {\n const resolvedMarketplace = marketplace ?? sourceConfig.marketplace;\n const isDefaultPublicSource = sourceConfig.source === DEFAULT_SOURCE;\n\n const primarySourceName = resolvedMarketplace ?? DEFAULT_PUBLIC_SOURCE_NAME;\n const primarySourceType: SkillSourceType = isDefaultPublicSource ? \"public\" : \"private\";\n\n tagPrimarySourceSkills(primaryMatrix, primarySourceName, primarySourceType);\n tagLocalSkills(primaryMatrix);\n await tagPluginSkills(primaryMatrix, projectDir, primarySourceName, primarySourceType);\n\n if (!isDefaultPublicSource) {\n await tagPublicSourceSkills(primaryMatrix, forceRefresh);\n }\n\n await tagExtraSources(primaryMatrix, projectDir, forceRefresh);\n setActiveSources(primaryMatrix);\n}\n\nfunction tagPrimarySourceSkills(\n matrix: MergedSkillsMatrix,\n sourceName: string,\n sourceType: SkillSourceType,\n): void {\n for (const [, skill] of typedEntries(matrix.skills)) {\n if (!skill) continue;\n\n const source: SkillSource = {\n name: sourceName,\n type: sourceType,\n installed: false,\n primary: true,\n };\n\n skill.availableSources = skill.availableSources ?? [];\n skill.availableSources.push(source);\n }\n}\n\nfunction tagLocalSkills(matrix: MergedSkillsMatrix): void {\n let count = 0;\n for (const [, skill] of typedEntries(matrix.skills)) {\n if (!skill) continue;\n if (!skill.local) continue;\n\n const source: SkillSource = {\n name: \"local\",\n type: \"local\",\n installed: true,\n installMode: \"local\",\n };\n\n skill.availableSources = skill.availableSources ?? [];\n skill.availableSources.push(source);\n count++;\n }\n\n verbose(`Tagged ${count} local skills with local source`);\n}\n\nasync function tagPluginSkills(\n matrix: MergedSkillsMatrix,\n projectDir: string,\n primarySourceName: string,\n primarySourceType: SkillSourceType,\n): Promise<void> {\n const allPluginSkillIds = await collectPluginSkillIds(matrix, projectDir);\n\n if (allPluginSkillIds.length === 0) {\n return;\n }\n\n for (const skillId of allPluginSkillIds) {\n const skill = matrix.skills[skillId];\n if (!skill) continue;\n\n skill.availableSources = skill.availableSources ?? [];\n\n const existingSource = skill.availableSources.find((s) => s.name === primarySourceName);\n if (existingSource && !existingSource.installMode) {\n existingSource.installed = true;\n existingSource.installMode = \"plugin\";\n } else if (!skill.availableSources.some((s) => s.installMode === \"plugin\")) {\n skill.availableSources.push({\n name: primarySourceName,\n type: primarySourceType,\n installed: true,\n installMode: \"plugin\",\n primary: true,\n });\n }\n }\n\n verbose(`Tagged ${allPluginSkillIds.length} plugin-installed skills`);\n}\n\n/**\n * Collects skill IDs from all enabled plugins via settings.json and global cache.\n * Uses {@link discoverAllPluginSkills} to find skills from the plugin registry.\n */\nasync function collectPluginSkillIds(\n _matrix: MergedSkillsMatrix,\n projectDir: string,\n): Promise<SkillId[]> {\n const pluginSkills = await discoverAllPluginSkills(projectDir);\n const skillIds = typedKeys<SkillId>(pluginSkills);\n\n if (skillIds.length === 0) {\n verbose(\"No plugin skills discovered from settings.json\");\n }\n\n return skillIds;\n}\n\n/**\n * When the primary source is a private marketplace, fetch the default public source\n * and tag matching skills so the user can switch between private and public sources\n * in the Sources step.\n */\nasync function tagPublicSourceSkills(\n matrix: MergedSkillsMatrix,\n forceRefresh: boolean,\n): Promise<void> {\n let publicSourceName = DEFAULT_PUBLIC_SOURCE_NAME;\n\n try {\n const marketplaceResult = await fetchMarketplace(DEFAULT_SOURCE, { forceRefresh });\n publicSourceName = marketplaceResult.marketplace.name;\n verbose(`Public marketplace name from marketplace.json: ${publicSourceName}`);\n } catch {\n verbose(\"Public source has no marketplace.json -- using default label\");\n }\n\n try {\n const fetchResult = await fetchFromSource(DEFAULT_SOURCE, { forceRefresh });\n const skillsDir = path.join(fetchResult.path, SKILLS_DIR_PATH);\n const publicSkills = await extractAllSkills(skillsDir);\n\n let matchCount = 0;\n for (const publicSkill of publicSkills) {\n const matrixSkill = matrix.skills[publicSkill.id];\n if (!matrixSkill) continue;\n\n const source: SkillSource = {\n name: publicSourceName,\n type: \"public\",\n installed: false,\n };\n\n matrixSkill.availableSources = matrixSkill.availableSources ?? [];\n matrixSkill.availableSources.push(source);\n matchCount++;\n }\n\n verbose(\n `Public source: ${publicSkills.length} skills found, ${matchCount} matching primary matrix`,\n );\n } catch (error) {\n warn(`Failed to load public source for alternative tagging: ${getErrorMessage(error)}`);\n }\n}\n\nasync function tagExtraSources(\n matrix: MergedSkillsMatrix,\n projectDir: string,\n forceRefresh: boolean,\n): Promise<void> {\n let allSources;\n try {\n allSources = await resolveAllSources(projectDir);\n } catch (error) {\n verbose(`Failed to resolve extra sources: ${getErrorMessage(error)}`);\n return;\n }\n\n if (allSources.extras.length === 0) {\n verbose(\"No extra sources configured\");\n return;\n }\n\n for (const extraSource of allSources.extras) {\n verbose(`Loading extra source: ${extraSource.name} (${extraSource.url})`);\n\n try {\n const fetchResult = await fetchFromSource(extraSource.url, { forceRefresh });\n const skillsDir = path.join(fetchResult.path, SKILLS_DIR_PATH);\n const skills = await extractAllSkills(skillsDir);\n\n let matchCount = 0;\n for (const extractedSkill of skills) {\n const matrixSkill = matrix.skills[extractedSkill.id];\n if (!matrixSkill) continue;\n\n const source: SkillSource = {\n name: extraSource.name,\n type: \"private\",\n url: extraSource.url,\n installed: false,\n };\n\n matrixSkill.availableSources = matrixSkill.availableSources ?? [];\n matrixSkill.availableSources.push(source);\n matchCount++;\n }\n\n verbose(\n `Extra source '${extraSource.name}': ${skills.length} skills found, ${matchCount} matching`,\n );\n } catch (error) {\n warn(\n `Failed to load extra source '${extraSource.name}' ('${extraSource.url}'): ${getErrorMessage(error)}`,\n );\n }\n }\n}\n\n/** Prefers installed source so the wizard shows current state; falls back to first available */\nfunction setActiveSources(matrix: MergedSkillsMatrix): void {\n for (const [, skill] of typedEntries(matrix.skills)) {\n if (!skill) continue;\n if (!skill.availableSources || skill.availableSources.length === 0) continue;\n\n // Prefer installed source, then fall back to first available\n const installedSource = skill.availableSources.find((s) => s.installed);\n skill.activeSource = installedSource ?? skill.availableSources[0];\n }\n}\n\n/**\n * Searches configured extra sources for skills matching a given alias.\n *\n * For each configured source, fetches the repository (using cached data when available),\n * extracts all skill metadata, and matches by the last segment of the skill's directory\n * path against the provided alias (case-insensitive). Used by the wizard's skill search\n * modal to find foreign skills that can be bound to a category.\n *\n * @param alias - Skill alias to search for (e.g., \"react\", \"zustand\"). Matched\n * case-insensitively against the last path segment of each skill's\n * directory path in the source repository.\n * @param configuredSources - Array of extra source entries from project/global config.\n * Each entry has `name` (display name) and `url` (giget-compatible\n * source URL like \"github:org/repo\").\n * @returns Array of matching candidates with skill ID, source URL, source name, alias,\n * and description. Returns an empty array if no sources are configured or no\n * matches are found. Never throws -- errors per-source are warned and skipped.\n *\n * @remarks\n * **Side effects:** May perform network requests to fetch source repositories via giget.\n * Uses cached source data when available (controlled by `forceRefresh: false`).\n */\nexport async function searchExtraSources(\n alias: SkillAlias,\n configuredSources: SourceEntry[],\n): Promise<BoundSkillCandidate[]> {\n const candidates: BoundSkillCandidate[] = [];\n\n if (configuredSources.length === 0) {\n return candidates;\n }\n\n const lowerAlias = alias.toLowerCase();\n\n for (const source of configuredSources) {\n try {\n const fetchResult = await fetchFromSource(source.url, { forceRefresh: false });\n const skillsDir = path.join(fetchResult.path, SKILLS_DIR_PATH);\n const skills = await extractAllSkills(skillsDir);\n\n for (const skill of skills) {\n // Match by last segment of directory path (the alias/display-name convention)\n const segments = skill.directoryPath.split(\"/\");\n const lastSegment = segments[segments.length - 1]?.toLowerCase();\n\n if (lastSegment === lowerAlias) {\n candidates.push({\n id: skill.id,\n sourceUrl: source.url,\n sourceName: source.name,\n alias,\n description: skill.description,\n });\n }\n }\n } catch (error) {\n warn(\n `Failed to search extra source '${source.name}' ('${source.url}'): ${getErrorMessage(error)}`,\n );\n }\n }\n\n return candidates;\n}\n","export {\n loadSkillCategories,\n loadSkillRules,\n extractAllSkills,\n loadAndMergeSkillsMatrix,\n} from \"./matrix-loader\";\n\nexport { mergeMatrixWithSkills, synthesizeCategory } from \"./skill-resolution\";\n\nexport {\n resolveAlias,\n getDependentSkills,\n isDiscouraged,\n getDiscourageReason,\n isRecommended,\n getRecommendReason,\n validateSelection,\n getAvailableSkills,\n getSkillsByCategory,\n} from \"./matrix-resolver\";\n\nexport { type MatrixHealthIssue, checkMatrixHealth } from \"./matrix-health-check\";\n\nexport {\n matrix,\n initializeMatrix,\n getSkillById,\n getSkillBySlug,\n findStack,\n} from \"./matrix-provider\";\n","import { parse as parseYaml } from \"yaml\";\nimport path from \"path\";\nimport { z } from \"zod\";\nimport { glob, readFile, fileExists } from \"../../utils/fs\";\nimport { verbose, warn } from \"../../utils/logger\";\nimport { DIRS, STANDARD_FILES } from \"../../consts\";\nimport { loadConfig } from \"../configuration/config-loader\";\nimport { METADATA_KEYS } from \"../metadata-keys\";\nimport { parseFrontmatter } from \"../loading\";\nimport {\n skillCategoriesFileSchema,\n skillRulesFileSchema,\n formatZodErrors,\n categoryPathSchema,\n} from \"../schemas\";\nimport { mergeMatrixWithSkills } from \"./skill-resolution\";\nimport type {\n CategoryMap,\n Domain,\n ExtractedSkillMetadata,\n MergedSkillsMatrix,\n SkillRulesConfig,\n SkillSlug,\n} from \"../../types\";\n\nconst rawMetadataSchema = z.object({\n category: categoryPathSchema,\n author: z.string(),\n displayName: z.string().optional(),\n slug: z.string() as z.ZodType<SkillSlug>,\n cliDescription: z.string().optional(),\n usageGuidance: z.string().optional(),\n tags: z.array(z.string()).optional(),\n // Boundary cast: domain is a string at the YAML parse boundary; narrowed to Domain type\n domain: z.string() as z.ZodType<Domain>,\n custom: z.boolean().optional(),\n});\n\n/**\n * Loads and validates a skill-categories.ts configuration file.\n *\n * @param configPath - Absolute path to the skill-categories.ts file\n * @returns Parsed and validated categories map\n * @throws When the file cannot be read or fails Zod schema validation\n */\nexport async function loadSkillCategories(configPath: string): Promise<CategoryMap> {\n const data = await loadConfig<{ version: string; categories: CategoryMap }>(\n configPath,\n skillCategoriesFileSchema,\n );\n\n if (!data) {\n throw new Error(`Invalid skill categories at '${configPath}': failed to load or validate`);\n }\n\n verbose(`Loaded skill categories: ${configPath}`);\n return data.categories;\n}\n\n/**\n * Loads and validates a skill-rules.ts configuration file.\n *\n * @param configPath - Absolute path to the skill-rules.ts file\n * @returns Parsed and validated skill rules config\n * @throws When the file cannot be read or fails Zod schema validation\n */\nexport async function loadSkillRules(configPath: string): Promise<SkillRulesConfig> {\n const data = await loadConfig<{\n version: string;\n relationships?: SkillRulesConfig[\"relationships\"];\n }>(configPath, skillRulesFileSchema);\n\n if (!data) {\n throw new Error(`Invalid skill rules at '${configPath}': failed to load or validate`);\n }\n\n const config: SkillRulesConfig = {\n version: data.version,\n relationships: data.relationships ?? {\n conflicts: [],\n discourages: [],\n recommends: [],\n requires: [],\n alternatives: [],\n },\n };\n\n verbose(`Loaded skill rules: ${configPath}`);\n return config;\n}\n\n/**\n * Scans a skills directory and extracts metadata from all valid skills.\n *\n * Discovers skills by globbing for `metadata.yaml` files, then for each:\n * 1. Validates a corresponding SKILL.md exists (skips if missing)\n * 2. Parses and validates metadata.yaml against the raw metadata schema\n * 3. Parses SKILL.md frontmatter for the canonical skill ID\n * 4. Merges metadata fields into an ExtractedSkillMetadata object\n *\n * Skills with invalid metadata are warned and skipped. Skills missing\n * the required `displayName` field in metadata.yaml cause a hard error.\n *\n * @param skillsDir - Absolute path to the skills root directory (e.g., `{root}/src/skills`)\n * @returns Array of extracted skill metadata, one per valid skill found\n * @throws When a skill's metadata.yaml is missing the required `displayName` field\n */\nexport async function extractAllSkills(skillsDir: string): Promise<ExtractedSkillMetadata[]> {\n const skills: ExtractedSkillMetadata[] = [];\n const metadataFiles = await glob(`**/${STANDARD_FILES.METADATA_YAML}`, skillsDir);\n\n for (const metadataFile of metadataFiles) {\n const skillDir = path.dirname(metadataFile);\n const skillMdPath = path.join(skillsDir, skillDir, STANDARD_FILES.SKILL_MD);\n const metadataPath = path.join(skillsDir, metadataFile);\n\n if (!(await fileExists(skillMdPath))) {\n verbose(`Skipping ${metadataFile}: No ${STANDARD_FILES.SKILL_MD} found`);\n continue;\n }\n\n const metadataContent = await readFile(metadataPath);\n const rawMetadata = parseYaml(metadataContent);\n const metadataResult = rawMetadataSchema.safeParse(rawMetadata);\n\n if (!metadataResult.success) {\n warn(\n `Skipping '${metadataFile}': invalid metadata.yaml — ${formatZodErrors(metadataResult.error.issues)}`,\n );\n continue;\n }\n\n const metadata = metadataResult.data;\n const skillMdContent = await readFile(skillMdPath);\n const frontmatter = parseFrontmatter(skillMdContent, skillMdPath);\n\n if (!frontmatter) {\n verbose(`Skipping ${metadataFile}: Invalid SKILL.md frontmatter`);\n continue;\n }\n\n if (!metadata.displayName) {\n throw new Error(\n `Skill at ${metadataFile} is missing required '${METADATA_KEYS.DISPLAY_NAME}' field in metadata.yaml`,\n );\n }\n\n const skillId = frontmatter.name;\n\n const extracted: ExtractedSkillMetadata = {\n id: skillId,\n directoryPath: skillDir,\n description: metadata.cliDescription || frontmatter.description,\n usageGuidance: metadata.usageGuidance,\n category: metadata.category,\n author: metadata.author,\n tags: metadata.tags ?? [],\n path: `skills/${skillDir}/`,\n domain: metadata.domain,\n displayName: metadata.displayName,\n slug: metadata.slug,\n ...(metadata.custom === true ? { custom: true } : {}),\n };\n\n skills.push(extracted);\n verbose(`Extracted skill: ${skillId}`);\n }\n\n return skills;\n}\n\n/**\n * Convenience function that loads categories and rules from standalone files,\n * extracts all skills from the project's skills directory, and merges them\n * into a MergedSkillsMatrix.\n *\n * @param categoriesPath - Path to the skill-categories.ts config file\n * @param rulesPath - Path to the skill-rules.ts config file\n * @param projectRoot - Project root directory (skills are scanned from `{root}/src/skills`)\n * @returns Fully resolved and merged skills matrix\n */\nexport async function loadAndMergeSkillsMatrix(\n categoriesPath: string,\n rulesPath: string,\n projectRoot: string,\n): Promise<MergedSkillsMatrix> {\n const categories = await loadSkillCategories(categoriesPath);\n const rules = await loadSkillRules(rulesPath);\n const skillsDir = path.join(projectRoot, DIRS.skills);\n const skills = await extractAllSkills(skillsDir);\n return mergeMatrixWithSkills(categories, rules.relationships, skills);\n}\n","import { verbose, warn } from \"../../utils/logger\";\nimport type {\n AlternativeGroup,\n CategoryDefinition,\n CategoryMap,\n CompatibilityGroup,\n ConflictRule,\n DiscourageRule,\n Domain,\n ExtractedSkillMetadata,\n MergedSkillsMatrix,\n RelationshipDefinitions,\n RequireRule,\n ResolvedSkill,\n SkillAlternative,\n SkillId,\n SkillRelation,\n SkillRequirement,\n SkillSlug,\n SkillSlugMap,\n Category,\n} from \"../../types\";\n\n/** Resolves a slug to a canonical SkillId, or null if unresolvable */\ntype ResolveId = (slug: SkillSlug, context?: string) => SkillId | null;\n\nconst AUTO_SYNTH_ORDER = 999;\n\n/**\n * Synthesizes a basic CategoryDefinition for a category not defined in any\n * skill-categories.ts. This is a safety net — the preferred path is for\n * skill authors to maintain proper skill-categories.ts entries.\n */\nexport function synthesizeCategory(category: Category, domain: Domain): CategoryDefinition {\n const displayName = category\n .split(\"-\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n\n return {\n id: category,\n displayName,\n description: `Auto-generated category for ${category}`,\n domain,\n exclusive: true,\n required: false,\n order: AUTO_SYNTH_ORDER,\n };\n}\n\n/**\n * Builds a bidirectional slug <-> ID map from extracted skill metadata.\n * Warns on duplicate slugs (first one wins).\n */\nfunction buildSlugMap(skills: ExtractedSkillMetadata[]): SkillSlugMap {\n const slugToId: Partial<Record<SkillSlug, SkillId>> = {};\n const idToSlug: Partial<Record<SkillId, SkillSlug>> = {};\n\n for (const skill of skills) {\n const existingId = slugToId[skill.slug];\n if (existingId) {\n warn(\n `Duplicate slug '${skill.slug}': already mapped to '${existingId}', ignoring '${skill.id}'`,\n );\n continue;\n }\n\n slugToId[skill.slug] = skill.id;\n idToSlug[skill.id] = skill.slug;\n }\n\n return { slugToId, idToSlug };\n}\n\nfunction resolveToCanonicalId(\n slug: SkillSlug,\n slugToId: SkillSlugMap[\"slugToId\"],\n context?: string,\n): SkillId | null {\n const slugResult = slugToId[slug];\n if (slugResult) {\n return slugResult;\n }\n const location = context ? ` in ${context}` : \"\";\n verbose(`Unresolved slug '${slug}'${location} — skipping`);\n return null;\n}\n\n/**\n * Merges category definitions, relationship rules, and extracted skill metadata\n * into a fully resolved MergedSkillsMatrix.\n *\n * This is the core resolution step that combines:\n * - Category definitions from skill-categories.ts\n * - Slug-based alias maps derived from metadata\n * - Relationship rules from skill-rules.ts\n * - Extracted skill metadata (from scanning skill directories)\n *\n * Each skill's raw relationship references are resolved to canonical SkillIds.\n * The result is the complete data structure consumed by the wizard UI and validation logic.\n */\nexport function mergeMatrixWithSkills(\n categories: CategoryMap,\n relationships: RelationshipDefinitions,\n skills: ExtractedSkillMetadata[],\n): MergedSkillsMatrix {\n const slugMap = buildSlugMap(skills);\n const resolvedSkills: Partial<Record<SkillId, ResolvedSkill>> = {};\n\n for (const skill of skills) {\n const resolved = buildResolvedSkill(skill, categories, relationships, slugMap);\n resolvedSkills[skill.id] = resolved;\n }\n\n // Auto-synthesize missing categories for skills that reference undefined categories\n const synthesizedCategories = { ...categories };\n for (const skill of skills) {\n // Skip \"local\" pseudo-category — it's not a real Category union member\n if (skill.category === \"local\") continue;\n if (!synthesizedCategories[skill.category]) {\n const synthesized = synthesizeCategory(skill.category, skill.domain);\n synthesizedCategories[skill.category] = synthesized;\n verbose(`Auto-synthesized category '${skill.category}' for skill '${skill.id}'`);\n }\n }\n\n const merged: MergedSkillsMatrix = {\n version: \"1.0.0\",\n categories: synthesizedCategories,\n skills: resolvedSkills,\n suggestedStacks: [],\n slugMap,\n generatedAt: new Date().toISOString(),\n };\n\n return merged;\n}\n\n/** Resolves conflicts from centralized conflict rules */\nfunction resolveConflicts(\n skillId: SkillId,\n conflictRules: ConflictRule[],\n resolve: ResolveId,\n): SkillRelation[] {\n const conflicts: SkillRelation[] = [];\n\n for (const rule of conflictRules) {\n const resolved = rule.skills\n .map((slug) => resolve(slug, \"conflicts\"))\n .filter((id): id is SkillId => id !== null);\n if (!resolved.includes(skillId)) continue;\n for (const other of resolved) {\n if (other !== skillId && !conflicts.some((c) => c.skillId === other)) {\n conflicts.push({ skillId: other, reason: rule.reason });\n }\n }\n }\n\n return conflicts;\n}\n\n/** Resolves compatibility from CompatibilityGroup[] — collects all co-members across all groups */\nfunction resolveCompatibilityGroups(\n skillId: SkillId,\n compatibilityGroups: CompatibilityGroup[],\n resolve: ResolveId,\n): SkillId[] {\n const compatible = new Set<SkillId>();\n\n for (const group of compatibilityGroups) {\n const resolved = group.skills\n .map((slug) => resolve(slug, \"compatibleWith\"))\n .filter((id): id is SkillId => id !== null);\n if (!resolved.includes(skillId)) continue;\n for (const other of resolved) {\n if (other !== skillId) {\n compatible.add(other);\n }\n }\n }\n\n return [...compatible];\n}\n\n/** Resolves requirements from centralized require rules */\nfunction resolveRequirements(\n skillId: SkillId,\n requireRules: RequireRule[],\n resolve: ResolveId,\n): SkillRequirement[] {\n const requires: SkillRequirement[] = [];\n\n for (const rule of requireRules) {\n const ruleSkillId = resolve(rule.skill, \"requires.skill\");\n if (ruleSkillId !== skillId) continue;\n const resolvedNeeds = rule.needs\n .map((slug) => resolve(slug, \"requires.needs\"))\n .filter((id): id is SkillId => id !== null);\n if (resolvedNeeds.length === 0) continue;\n requires.push({\n skillIds: resolvedNeeds,\n needsAny: rule.needsAny ?? false,\n reason: rule.reason,\n });\n }\n\n return requires;\n}\n\n/** Resolves alternatives from matrix alternative groups */\nfunction resolveAlternatives(\n skillId: SkillId,\n alternativeGroups: AlternativeGroup[],\n resolve: ResolveId,\n): SkillAlternative[] {\n const alternatives: SkillAlternative[] = [];\n\n for (const group of alternativeGroups) {\n const resolved = group.skills\n .map((slug) => resolve(slug, \"alternatives\"))\n .filter((id): id is SkillId => id !== null);\n if (!resolved.includes(skillId)) continue;\n for (const alt of resolved) {\n if (alt !== skillId) {\n alternatives.push({ skillId: alt, purpose: group.purpose });\n }\n }\n }\n\n return alternatives;\n}\n\n/** Resolves discourages from matrix discourage rules */\nfunction resolveDiscourages(\n skillId: SkillId,\n discourageRules: DiscourageRule[] | undefined,\n resolve: ResolveId,\n): SkillRelation[] {\n if (!discourageRules) return [];\n const discourages: SkillRelation[] = [];\n\n for (const rule of discourageRules) {\n const resolved = rule.skills\n .map((slug) => resolve(slug, \"discourages\"))\n .filter((id): id is SkillId => id !== null);\n if (!resolved.includes(skillId)) continue;\n for (const other of resolved) {\n if (other !== skillId && !discourages.some((d) => d.skillId === other)) {\n discourages.push({ skillId: other, reason: rule.reason });\n }\n }\n }\n\n return discourages;\n}\n\nfunction buildResolvedSkill(\n skill: ExtractedSkillMetadata,\n _categories: CategoryMap,\n relationships: RelationshipDefinitions,\n slugMap: SkillSlugMap,\n): ResolvedSkill {\n const resolve: ResolveId = (slug, context) =>\n resolveToCanonicalId(slug, slugMap.slugToId, context ? `${skill.id} ${context}` : undefined);\n\n const slug = skill.slug;\n\n // Look up isRecommended/recommendedReason from flat recommends list (now slug-based)\n const recommendation = relationships.recommends.find((r) => r.skill === skill.slug);\n\n return {\n id: skill.id,\n slug,\n displayName: skill.displayName,\n description: skill.description,\n usageGuidance: skill.usageGuidance,\n category: skill.category,\n tags: skill.tags,\n author: skill.author,\n conflictsWith: resolveConflicts(skill.id, relationships.conflicts, resolve),\n isRecommended: recommendation != null,\n recommendedReason: recommendation?.reason,\n requires: resolveRequirements(skill.id, relationships.requires, resolve),\n alternatives: resolveAlternatives(skill.id, relationships.alternatives, resolve),\n discourages: resolveDiscourages(skill.id, relationships.discourages, resolve),\n compatibleWith: resolveCompatibilityGroups(\n skill.id,\n relationships.compatibleWith ?? [],\n resolve,\n ),\n path: skill.path,\n ...(skill.custom === true ? { custom: true } : {}),\n };\n}\n","import { groupBy } from \"remeda\";\nimport type {\n CategoryPath,\n ResolvedSkill,\n SelectionValidation,\n SkillId,\n SkillOption,\n Category,\n ValidationError,\n ValidationWarning,\n} from \"../../types\";\nimport { typedEntries } from \"../../utils/typed-object\";\nimport { matrix, getSkillById } from \"./matrix-provider\";\n\nfunction getLabel(skill: Pick<ResolvedSkill, \"displayName\">): string {\n return skill.displayName;\n}\n\n/** Resolves a skill ID to its canonical SkillId. Throws if not found in the matrix. */\nexport function resolveAlias(skillId: SkillId): SkillId {\n if (matrix.skills[skillId]) return skillId;\n throw new Error(`Unknown skill ID: '${skillId}' — not found in the matrix`);\n}\n\ntype SelectionContext = {\n resolvedSelections: SkillId[];\n selectedSet: Set<SkillId>;\n};\n\nfunction initializeSelectionContext(currentSelections: SkillId[]): SelectionContext {\n const resolvedSelections = currentSelections.map((s) => resolveAlias(s));\n const selectedSet = new Set<SkillId>(resolvedSelections);\n return { resolvedSelections, selectedSet };\n}\n\n/**\n * Finds all currently selected skills that depend on the given skill.\n *\n * A skill is considered dependent if it has a requirement that would become\n * unsatisfied by removing `skillId`. For `needsAny` requirements, the skill\n * is only dependent if `skillId` is the sole remaining option satisfying\n * that requirement.\n *\n * @param skillId - The skill to check dependents for (resolved via alias lookup)\n * @param currentSelections - Currently selected skill IDs in the wizard\n * @returns Skill IDs that would lose a required dependency if `skillId` were removed\n */\nexport function getDependentSkills(skillId: SkillId, currentSelections: SkillId[]): SkillId[] {\n const fullId = resolveAlias(skillId);\n const skill = matrix.skills[fullId];\n if (!skill) return [];\n\n const { resolvedSelections, selectedSet } = initializeSelectionContext(currentSelections);\n const dependents: SkillId[] = [];\n\n for (const selectedId of resolvedSelections) {\n if (selectedId === fullId) continue;\n\n const selectedSkill: ResolvedSkill | undefined = matrix.skills[selectedId];\n if (!selectedSkill) continue;\n\n for (const requirement of selectedSkill.requires) {\n if (requirement.needsAny) {\n const satisfiedReqs = requirement.skillIds.filter((reqId) => selectedSet.has(reqId));\n if (satisfiedReqs.length === 1 && satisfiedReqs[0] === fullId) {\n dependents.push(selectedId);\n }\n } else {\n if (requirement.skillIds.includes(fullId)) {\n dependents.push(selectedId);\n }\n }\n }\n }\n\n return dependents;\n}\n\n/**\n * Determines whether a skill should be discouraged (shown with yellow warning)\n * in the wizard given the current selection state.\n *\n * A skill is discouraged when any of these conditions are true:\n * 1. It has a `discourages` relationship with a currently selected skill (bidirectional)\n * 2. It conflicts with a currently selected skill (bidirectional `conflictsWith` check)\n * 3. It has unmet `requires` dependencies (AND mode or OR/needsAny mode)\n *\n * Discouraged skills remain selectable but show a yellow warning to inform the user.\n *\n * @param skillId - The skill to check (resolved via alias lookup)\n * @param currentSelections - Currently selected skill IDs\n * @returns true if the skill should show a discouraged warning\n */\nexport function isDiscouraged(skillId: SkillId, currentSelections: SkillId[]): boolean {\n const fullId = resolveAlias(skillId);\n const skill = matrix.skills[fullId];\n if (!skill) return false;\n\n const { resolvedSelections, selectedSet } = initializeSelectionContext(currentSelections);\n\n // Check discourages relationships (bidirectional)\n for (const selectedId of resolvedSelections) {\n const selectedSkill = matrix.skills[selectedId];\n if (selectedSkill?.discourages.some((d) => d.skillId === fullId)) {\n return true;\n }\n\n if (skill.discourages.some((d) => d.skillId === selectedId)) {\n return true;\n }\n }\n\n // Check conflictsWith relationships (bidirectional)\n for (const selectedId of resolvedSelections) {\n if (skill.conflictsWith.some((c) => c.skillId === selectedId)) {\n return true;\n }\n\n const selectedSkill = matrix.skills[selectedId];\n if (selectedSkill?.conflictsWith.some((c) => c.skillId === fullId)) {\n return true;\n }\n }\n\n // Check unmet requires dependencies\n for (const requirement of skill.requires) {\n if (requirement.needsAny) {\n const hasAny = requirement.skillIds.some((reqId) => selectedSet.has(reqId));\n if (!hasAny) {\n return true;\n }\n } else {\n const hasAll = requirement.skillIds.every((reqId) => selectedSet.has(reqId));\n if (!hasAll) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * Returns a human-readable reason why a skill is discouraged, or undefined if it is not.\n *\n * Checks discourages relationships, conflicts (bidirectional), and unmet requirements,\n * returning the first matching reason with context.\n *\n * @param skillId - The skill to get the discourage reason for\n * @param currentSelections - Currently selected skill IDs\n * @returns Formatted reason string or undefined\n */\nexport function getDiscourageReason(\n skillId: SkillId,\n currentSelections: SkillId[],\n): string | undefined {\n const fullId = resolveAlias(skillId);\n const skill = matrix.skills[fullId];\n if (!skill) return undefined;\n\n const { resolvedSelections, selectedSet } = initializeSelectionContext(currentSelections);\n\n // Check discourages relationships (bidirectional)\n for (const selectedId of resolvedSelections) {\n const selectedSkill = matrix.skills[selectedId];\n if (selectedSkill) {\n const discourage = selectedSkill.discourages.find((d) => d.skillId === fullId);\n if (discourage) {\n return discourage.reason;\n }\n }\n\n const reverseDiscourage = skill.discourages.find((d) => d.skillId === selectedId);\n if (reverseDiscourage) {\n return reverseDiscourage.reason;\n }\n }\n\n // Check conflictsWith relationships (bidirectional)\n for (const selectedId of resolvedSelections) {\n const conflict = skill.conflictsWith.find((c) => c.skillId === selectedId);\n if (conflict) {\n return `${conflict.reason} (conflicts with ${getLabel(getSkillById(selectedId))})`;\n }\n\n const selectedSkill = matrix.skills[selectedId];\n if (selectedSkill) {\n const reverseConflict = selectedSkill.conflictsWith.find((c) => c.skillId === fullId);\n if (reverseConflict) {\n return `${reverseConflict.reason} (conflicts with ${getLabel(selectedSkill)})`;\n }\n }\n }\n\n // Check unmet requires dependencies\n for (const requirement of skill.requires) {\n if (requirement.needsAny) {\n const hasAny = requirement.skillIds.some((reqId) => selectedSet.has(reqId));\n if (!hasAny) {\n const requiredNames = requirement.skillIds\n .map((id) => {\n const s = matrix.skills[id];\n return s ? getLabel(s) : id;\n })\n .join(\" or \");\n return `${requirement.reason} (requires ${requiredNames})`;\n }\n } else {\n const missingIds = requirement.skillIds.filter((reqId) => !selectedSet.has(reqId));\n if (missingIds.length > 0) {\n const missingNames = missingIds\n .map((id) => {\n const s = matrix.skills[id];\n return s ? getLabel(s) : id;\n })\n .join(\", \");\n return `${requirement.reason} (requires ${missingNames})`;\n }\n }\n }\n\n return undefined;\n}\n\n/**\n * Checks if a skill is recommended based on the flat recommends list\n * and compatibility with current selections.\n *\n * A skill is recommended when:\n * 1. It appears in the flat recommends list (isRecommended === true), AND\n * 2. It is compatible with the user's current selections (shares a compatibleWith\n * group with at least one selected skill, or has no compatibility constraints)\n */\nexport function isRecommended(skillId: SkillId, currentSelections: SkillId[]): boolean {\n const fullId = resolveAlias(skillId);\n const skill = matrix.skills[fullId];\n if (!skill) return false;\n\n if (!skill.isRecommended) {\n return false;\n }\n\n // If no selections yet, isRecommended alone is sufficient\n if (currentSelections.length === 0) {\n return true;\n }\n\n const { resolvedSelections } = initializeSelectionContext(currentSelections);\n\n // If the skill has no compatibility constraints, it's recommended unconditionally\n if (skill.compatibleWith.length === 0) {\n return true;\n }\n\n // Check if compatible with at least one selected skill\n for (const selectedId of resolvedSelections) {\n if (skill.compatibleWith.includes(selectedId)) {\n return true;\n }\n }\n\n return false;\n}\n\n/** Returns the reason from the flat recommends entry */\nexport function getRecommendReason(\n skillId: SkillId,\n _currentSelections: SkillId[],\n): string | undefined {\n const fullId = resolveAlias(skillId);\n const skill = matrix.skills[fullId];\n if (!skill) return undefined;\n\n return skill.recommendedReason;\n}\n\ntype ValidationPartial = {\n errors: ValidationError[];\n warnings: ValidationWarning[];\n};\n\nfunction validateConflicts(resolvedSelections: SkillId[]): ValidationPartial {\n const errors: ValidationError[] = [];\n\n for (let i = 0; i < resolvedSelections.length; i++) {\n const skillA = matrix.skills[resolvedSelections[i]];\n if (!skillA) continue;\n\n for (let j = i + 1; j < resolvedSelections.length; j++) {\n const skillBId = resolvedSelections[j];\n const conflict = skillA.conflictsWith.find((c) => c.skillId === skillBId);\n if (conflict) {\n errors.push({\n type: \"conflict\",\n message: `${getLabel(skillA)} conflicts with ${getLabel(getSkillById(skillBId))}: ${conflict.reason}`,\n skills: [skillA.id, skillBId],\n });\n }\n }\n }\n\n return { errors, warnings: [] };\n}\n\nfunction validateRequirements(\n resolvedSelections: SkillId[],\n selectedSet: Set<SkillId>,\n): ValidationPartial {\n const errors: ValidationError[] = [];\n\n for (const skillId of resolvedSelections) {\n const skill = matrix.skills[skillId];\n if (!skill) continue;\n\n for (const requirement of skill.requires) {\n if (requirement.needsAny) {\n const hasAny = requirement.skillIds.some((reqId) => selectedSet.has(reqId));\n if (!hasAny) {\n errors.push({\n type: \"missingRequirement\",\n message: `${getLabel(skill)} requires one of: ${requirement.skillIds.map((id) => getLabel(getSkillById(id))).join(\", \")}`,\n skills: [skillId, ...requirement.skillIds],\n });\n }\n } else {\n const missingIds = requirement.skillIds.filter((reqId) => !selectedSet.has(reqId));\n if (missingIds.length > 0) {\n errors.push({\n type: \"missingRequirement\",\n message: `${getLabel(skill)} requires: ${missingIds.map((id) => getLabel(getSkillById(id))).join(\", \")}`,\n skills: [skillId, ...missingIds],\n });\n }\n }\n }\n }\n\n return { errors, warnings: [] };\n}\n\nfunction validateExclusivity(resolvedSelections: SkillId[]): ValidationPartial {\n const errors: ValidationError[] = [];\n\n const validSkills = resolvedSelections\n .map((skillId) => ({ skillId, skill: matrix.skills[skillId] }))\n .filter((entry): entry is { skillId: SkillId; skill: ResolvedSkill } => entry.skill != null);\n const categorySelections = groupBy(validSkills, (entry) => entry.skill.category);\n\n for (const [categoryId, entries] of typedEntries(categorySelections)) {\n if (entries.length > 1) {\n const skillIds = entries.map((e) => e.skillId);\n // \"local\" is a pseudo-category without exclusivity rules\n if (categoryId === \"local\") continue;\n const category = matrix.categories[categoryId];\n if (category?.exclusive) {\n errors.push({\n type: \"categoryExclusive\",\n message: `Category \"${category.displayName}\" only allows one selection, but multiple selected: ${skillIds.map((id) => getLabel(getSkillById(id))).join(\", \")}`,\n skills: skillIds,\n });\n }\n }\n }\n\n return { errors, warnings: [] };\n}\n\n/**\n * Validates recommendations: for each recommended skill that is NOT selected\n * but IS compatible with current selections, produce a missing_recommendation warning.\n */\nfunction validateRecommendations(\n resolvedSelections: SkillId[],\n selectedSet: Set<SkillId>,\n): ValidationPartial {\n const warnings: ValidationWarning[] = [];\n\n // Iterate the flat recommends list from relationships\n for (const [, skill] of typedEntries(matrix.skills)) {\n if (!skill) continue;\n if (!skill.isRecommended) continue;\n if (selectedSet.has(skill.id)) continue;\n\n // Check if compatible with current selections\n const isCompatible =\n skill.compatibleWith.length === 0 ||\n resolvedSelections.some((selectedId) => skill.compatibleWith.includes(selectedId));\n\n if (!isCompatible) continue;\n\n // Check no conflict with current selections\n const hasConflict = skill.conflictsWith.some((c) => selectedSet.has(c.skillId));\n if (hasConflict) continue;\n\n warnings.push({\n type: \"missing_recommendation\",\n message: `${getLabel(skill)} is recommended: ${skill.recommendedReason ?? \"Recommended for this stack\"}`,\n skills: [skill.id],\n });\n }\n\n return { errors: [], warnings };\n}\n\nfunction mergeValidationResults(results: ValidationPartial[]): ValidationPartial {\n return {\n errors: results.flatMap((r) => r.errors),\n warnings: results.flatMap((r) => r.warnings),\n };\n}\n\n/**\n * Validates a complete set of skill selections against all matrix constraints.\n *\n * Runs four validation passes:\n * 1. **Conflicts** - Checks for mutually exclusive skill pairs (errors)\n * 2. **Requirements** - Checks that all required dependencies are selected (errors)\n * 3. **Exclusivity** - Checks that exclusive categories have at most one selection (errors)\n * 4. **Recommendations** - Checks for missing recommended companion skills (warnings)\n *\n * @param selections - Complete list of selected skill IDs to validate\n * @returns Validation result with `valid` flag, error list, and warning list\n */\nexport function validateSelection(selections: SkillId[]): SelectionValidation {\n const { resolvedSelections, selectedSet } = initializeSelectionContext(selections);\n\n const { errors, warnings } = mergeValidationResults([\n validateConflicts(resolvedSelections),\n validateRequirements(resolvedSelections, selectedSet),\n validateExclusivity(resolvedSelections),\n validateRecommendations(resolvedSelections, selectedSet),\n ]);\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Builds a list of skill options for a category, annotated with their current\n * state (discouraged, recommended, selected) relative to the wizard's\n * selection state.\n *\n * Each skill is checked against the current selections to determine its visual\n * and interactive state in the wizard UI. States are mutually prioritized:\n * discouraged takes precedence over recommended.\n *\n * @param categoryId - Category path to filter skills by\n * @param currentSelections - Currently selected skill IDs\n * @returns Array of skill options with state annotations and reasons\n */\nexport function getAvailableSkills(\n categoryId: CategoryPath,\n currentSelections: SkillId[],\n): SkillOption[] {\n const skillOptions: SkillOption[] = [];\n const { selectedSet } = initializeSelectionContext(currentSelections);\n\n for (const skill of Object.values(matrix.skills)) {\n if (!skill) continue;\n if (skill.category !== categoryId) {\n continue;\n }\n\n const discouraged = isDiscouraged(skill.id, currentSelections);\n const recommended = !discouraged && isRecommended(skill.id, currentSelections);\n\n skillOptions.push({\n id: skill.id,\n discouraged,\n discouragedReason: discouraged ? getDiscourageReason(skill.id, currentSelections) : undefined,\n recommended,\n recommendedReason: recommended ? getRecommendReason(skill.id, currentSelections) : undefined,\n selected: selectedSet.has(skill.id),\n alternatives: skill.alternatives.map((a) => a.skillId),\n });\n }\n\n return skillOptions;\n}\n\n/** Returns all resolved skills belonging to the given category. */\nexport function getSkillsByCategory(categoryId: CategoryPath): ResolvedSkill[] {\n const skills: ResolvedSkill[] = [];\n\n for (const skill of Object.values(matrix.skills)) {\n if (!skill) continue;\n if (skill.category === categoryId) {\n skills.push(skill);\n }\n }\n\n return skills;\n}\n","import { warn } from \"../../utils/logger\";\nimport type {\n CategoryDefinition,\n MergedSkillsMatrix,\n ResolvedSkill,\n SkillId,\n Category,\n} from \"../../types\";\nimport { typedEntries } from \"../../utils/typed-object\";\n\nexport type MatrixHealthIssue = {\n severity: \"warning\" | \"error\";\n finding: string;\n details: string;\n};\n\nexport function checkMatrixHealth(matrix: MergedSkillsMatrix): MatrixHealthIssue[] {\n const issues: MatrixHealthIssue[] = [];\n\n checkCategoryDomains(matrix, issues);\n checkSkillCategories(matrix, issues);\n checkSkillRelationRefs(matrix, issues);\n\n for (const issue of issues) {\n warn(`[matrix] ${issue.details}`);\n }\n\n return issues;\n}\n\n// Categories without a domain won't appear in any wizard domain view\nfunction checkCategoryDomains(matrix: MergedSkillsMatrix, issues: MatrixHealthIssue[]): void {\n for (const [catId, cat] of typedEntries<Category, CategoryDefinition>(matrix.categories)) {\n if (!cat) continue;\n if (!cat.domain) {\n issues.push({\n severity: \"warning\",\n finding: \"category-missing-domain\",\n details: `Category '${catId}' has no domain — it won't appear in any wizard domain view`,\n });\n }\n }\n}\n\nfunction checkSkillCategories(matrix: MergedSkillsMatrix, issues: MatrixHealthIssue[]): void {\n for (const [skillId, skill] of typedEntries<SkillId, ResolvedSkill>(matrix.skills)) {\n if (!skill) continue;\n // \"local\" is a pseudo-category that won't exist in matrix.categories — skip it\n if (skill.category === \"local\") continue;\n const category = matrix.categories[skill.category];\n if (!category) {\n issues.push({\n severity: \"warning\",\n finding: \"skill-unknown-category\",\n details: `Skill '${skillId}' references category '${skill.category}' which does not exist in the matrix`,\n });\n }\n }\n}\n\nconst RELATION_FIELDS_SKILL_ID_ARRAY = [\"compatibleWith\"] as const;\n\nfunction checkSkillRelationRefs(matrix: MergedSkillsMatrix, issues: MatrixHealthIssue[]): void {\n for (const [skillId, skill] of typedEntries<SkillId, ResolvedSkill>(matrix.skills)) {\n if (!skill) continue;\n\n for (const field of RELATION_FIELDS_SKILL_ID_ARRAY) {\n for (const ref of skill[field]) {\n if (!matrix.skills[ref]) {\n issues.push({\n severity: \"warning\",\n finding: \"skill-unresolved-relation-ref\",\n details: `Skill '${skillId}' has unresolved reference '${ref}' in '${field}'`,\n });\n }\n }\n }\n\n for (const relation of skill.conflictsWith) {\n if (!matrix.skills[relation.skillId]) {\n issues.push({\n severity: \"warning\",\n finding: \"skill-unresolved-relation-ref\",\n details: `Skill '${skillId}' has unresolved reference '${relation.skillId}' in 'conflictsWith'`,\n });\n }\n }\n\n for (const requirement of skill.requires) {\n for (const ref of requirement.skillIds) {\n if (!matrix.skills[ref]) {\n issues.push({\n severity: \"warning\",\n finding: \"skill-unresolved-relation-ref\",\n details: `Skill '${skillId}' has unresolved reference '${ref}' in 'requires'`,\n });\n }\n }\n }\n }\n}\n","export {\n type SkillManifestOptions,\n type AgentManifestOptions,\n type StackManifestOptions,\n generateSkillPluginManifest,\n generateAgentPluginManifest,\n generateStackPluginManifest,\n writePluginManifest,\n getPluginDir,\n} from \"./plugin-manifest\";\n\nexport { findPluginManifest } from \"./plugin-manifest-finder\";\n\nexport {\n getUserPluginsDir,\n getCollectivePluginDir,\n getProjectPluginsDir,\n getPluginSkillsDir,\n getPluginAgentsDir,\n getPluginManifestPath,\n readPluginManifest,\n getPluginSkillIds,\n} from \"./plugin-finder\";\n\nexport {\n type PluginInfo,\n type InstallationInfo,\n getPluginInfo,\n formatPluginDisplay,\n getInstallationInfo,\n formatInstallationDisplay,\n} from \"./plugin-info\";\n\nexport {\n validatePluginStructure,\n validatePluginManifest,\n validateSkillFrontmatter,\n validateAgentFrontmatter,\n validatePlugin,\n validateAllPlugins,\n printPluginValidationResult,\n} from \"./plugin-validator\";\n\nexport { discoverAllPluginSkills, hasIndividualPlugins, listPluginNames } from \"./plugin-discovery\";\n\nexport {\n type PluginKey,\n type ResolvedPlugin,\n getEnabledPluginKeys,\n resolvePluginInstallPaths,\n getVerifiedPluginInstallPaths,\n} from \"./plugin-settings\";\n","import path from \"path\";\n\nimport { ensureDir, writeFile } from \"../../utils/fs\";\nimport { DEFAULT_VERSION, PLUGIN_MANIFEST_DIR, STANDARD_FILES } from \"../../consts\";\nimport type { PluginAuthor, PluginManifest } from \"../../types\";\n\nconst PLUGIN_DIR_NAME = PLUGIN_MANIFEST_DIR;\nconst PLUGIN_MANIFEST_FILE = STANDARD_FILES.PLUGIN_JSON;\nconst SKILL_PLUGIN_PREFIX = \"\";\nconst AGENT_PLUGIN_PREFIX = \"agent-\";\n\nexport type SkillManifestOptions = {\n skillName: string;\n description?: string;\n author?: string;\n authorEmail?: string;\n version?: string;\n keywords?: string[];\n};\n\nexport type AgentManifestOptions = {\n agentName: string;\n description?: string;\n version?: string;\n};\n\nexport type StackManifestOptions = {\n stackName: string;\n description?: string;\n author?: string;\n authorEmail?: string;\n version?: string;\n keywords?: string[];\n hasSkills?: boolean;\n hasAgents?: boolean;\n hasHooks?: boolean;\n};\n\nfunction buildAuthor(name?: string, email?: string): PluginAuthor | undefined {\n if (!name) {\n return undefined;\n }\n const author: PluginAuthor = { name };\n if (email) {\n author.email = email;\n }\n return author;\n}\n\nexport function generateSkillPluginManifest(options: SkillManifestOptions): PluginManifest {\n const manifest: PluginManifest = {\n name: `${SKILL_PLUGIN_PREFIX}${options.skillName}`,\n version: options.version ?? DEFAULT_VERSION,\n skills: \"./skills/\",\n };\n\n if (options.description) {\n manifest.description = options.description;\n }\n\n const author = buildAuthor(options.author, options.authorEmail);\n if (author) {\n manifest.author = author;\n }\n\n if (options.keywords && options.keywords.length > 0) {\n manifest.keywords = options.keywords;\n }\n\n return manifest;\n}\n\nexport function generateAgentPluginManifest(options: AgentManifestOptions): PluginManifest {\n const manifest: PluginManifest = {\n name: `${AGENT_PLUGIN_PREFIX}${options.agentName}`,\n version: options.version ?? DEFAULT_VERSION,\n agents: \"./agents/\",\n };\n\n if (options.description) {\n manifest.description = options.description;\n }\n\n return manifest;\n}\n\nexport function generateStackPluginManifest(options: StackManifestOptions): PluginManifest {\n const manifest: PluginManifest = {\n name: options.stackName,\n version: options.version ?? DEFAULT_VERSION,\n };\n\n if (options.hasSkills) {\n manifest.skills = \"./skills/\";\n }\n\n if (options.description) {\n manifest.description = options.description;\n }\n\n const author = buildAuthor(options.author, options.authorEmail);\n if (author) {\n manifest.author = author;\n }\n\n if (options.keywords && options.keywords.length > 0) {\n manifest.keywords = options.keywords;\n }\n\n // Note: Claude Code plugins don't support agents field in manifest\n // Agents are discovered from ./agents/ directory automatically\n\n if (options.hasHooks) {\n manifest.hooks = \"./hooks/hooks.json\";\n }\n\n return manifest;\n}\n\nexport async function writePluginManifest(\n outputDir: string,\n manifest: PluginManifest,\n): Promise<string> {\n const pluginDir = path.join(outputDir, PLUGIN_DIR_NAME);\n const manifestPath = path.join(pluginDir, PLUGIN_MANIFEST_FILE);\n\n await ensureDir(pluginDir);\n\n const content = JSON.stringify(manifest, null, 2);\n await writeFile(manifestPath, content);\n\n return manifestPath;\n}\n\nexport function getPluginDir(outputDir: string): string {\n return path.join(outputDir, PLUGIN_DIR_NAME);\n}\n\nexport function getPluginManifestPath(outputDir: string): string {\n return path.join(outputDir, PLUGIN_DIR_NAME, PLUGIN_MANIFEST_FILE);\n}\n","import os from \"os\";\nimport path from \"path\";\n\nimport { zip } from \"remeda\";\n\nimport { fileExists, readFileSafe, readFile, glob } from \"../../utils/fs\";\nimport { verbose, warn } from \"../../utils/logger\";\nimport {\n CLAUDE_DIR,\n DEFAULT_PLUGIN_NAME,\n MAX_PLUGIN_FILE_SIZE,\n PLUGINS_SUBDIR,\n PLUGIN_MANIFEST_DIR,\n PLUGIN_MANIFEST_FILE,\n} from \"../../consts\";\nimport type { PluginManifest, SkillId } from \"../../types\";\nimport { matrix } from \"../matrix/matrix-provider\";\nimport { pluginManifestSchema } from \"../schemas\";\nimport { parseFrontmatter } from \"../loading/loader\";\n\nconst MAX_SKILL_NAME_LENGTH = 100;\n\nexport function getUserPluginsDir(): string {\n return path.join(os.homedir(), CLAUDE_DIR, PLUGINS_SUBDIR);\n}\n\nexport function getCollectivePluginDir(projectDir?: string): string {\n const dir = projectDir ?? process.cwd();\n return path.join(dir, CLAUDE_DIR, PLUGINS_SUBDIR, DEFAULT_PLUGIN_NAME);\n}\n\nexport function getProjectPluginsDir(projectDir?: string): string {\n const dir = projectDir ?? process.cwd();\n return path.join(dir, CLAUDE_DIR, PLUGINS_SUBDIR);\n}\n\nexport function getPluginSkillsDir(pluginDir: string): string {\n return path.join(pluginDir, \"skills\");\n}\n\nexport function getPluginAgentsDir(pluginDir: string): string {\n return path.join(pluginDir, \"agents\");\n}\n\nexport function getPluginManifestPath(pluginDir: string): string {\n return path.join(pluginDir, PLUGIN_MANIFEST_DIR, PLUGIN_MANIFEST_FILE);\n}\n\nexport async function readPluginManifest(pluginDir: string): Promise<PluginManifest | null> {\n const manifestPath = getPluginManifestPath(pluginDir);\n\n if (!(await fileExists(manifestPath))) {\n verbose(` No manifest at ${manifestPath}`);\n return null;\n }\n\n try {\n const content = await readFileSafe(manifestPath, MAX_PLUGIN_FILE_SIZE);\n const manifest = pluginManifestSchema.parse(JSON.parse(content));\n\n if (!manifest.name || typeof manifest.name !== \"string\") {\n verbose(` Invalid manifest at ${manifestPath}: missing name`);\n return null;\n }\n\n return manifest;\n } catch (error) {\n verbose(` Failed to parse manifest at ${manifestPath}: ${error}`);\n return null;\n }\n}\n\nexport async function getPluginSkillIds(pluginSkillsDir: string): Promise<SkillId[]> {\n const skillFiles = await glob(\"**/SKILL.md\", pluginSkillsDir);\n const skillIds: SkillId[] = [];\n\n const fileContents = await Promise.all(\n skillFiles.map((skillFile) => readFile(path.join(pluginSkillsDir, skillFile))),\n );\n\n for (const [skillFile, content] of zip(skillFiles, fileContents)) {\n const fullPath = path.join(pluginSkillsDir, skillFile);\n const frontmatter = parseFrontmatter(content, fullPath);\n\n if (!frontmatter?.name) {\n warn(`Skipping plugin skill '${skillFile}': missing or invalid frontmatter name`);\n continue;\n }\n\n const skillName = frontmatter.name;\n\n if (skillName.length > MAX_SKILL_NAME_LENGTH) {\n warn(\n `Skipping plugin skill '${skillFile}': name exceeds ${MAX_SKILL_NAME_LENGTH} characters`,\n );\n continue;\n }\n\n if (matrix.skills[skillName]) {\n skillIds.push(skillName);\n } else {\n warn(`Skipping plugin skill '${skillFile}': '${skillName}' not found in skills matrix`);\n }\n }\n\n return skillIds;\n}\n","import { readdir } from \"fs/promises\";\n\nimport { DEFAULT_DISPLAY_VERSION, DEFAULT_PLUGIN_NAME } from \"../../consts\";\nimport { directoryExists } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport { loadProjectConfig } from \"../configuration\";\nimport { detectInstallation, type InstallMode } from \"../installation\";\nimport { getProjectPluginsDir } from \"./plugin-finder\";\nimport { discoverAllPluginSkills, listPluginNames } from \"./plugin-discovery\";\n\nexport type PluginInfo = {\n name: string;\n version: string;\n skillCount: number;\n agentCount: number;\n path: string;\n};\n\nexport type InstallationInfo = {\n mode: InstallMode;\n name: string;\n version: string;\n skillCount: number;\n agentCount: number;\n configPath: string;\n agentsDir: string;\n skillsDir: string;\n};\n\nexport async function getPluginInfo(projectDir?: string): Promise<PluginInfo | null> {\n const dir = projectDir ?? process.cwd();\n\n try {\n const pluginNames = await listPluginNames(dir);\n if (pluginNames.length > 0) {\n return {\n name: DEFAULT_PLUGIN_NAME,\n version: DEFAULT_DISPLAY_VERSION,\n skillCount: pluginNames.length,\n agentCount: 0,\n path: getProjectPluginsDir(dir),\n };\n }\n } catch {\n verbose(\"Failed to list plugins for plugin info\");\n }\n\n return null;\n}\n\nexport function formatPluginDisplay(info: PluginInfo): string {\n return `Plugin: ${info.name} v${info.version}\n Skills: ${info.skillCount}\n Agents: ${info.agentCount}\n Path: ${info.path}`;\n}\n\nexport async function getInstallationInfo(): Promise<InstallationInfo | null> {\n const installation = await detectInstallation();\n\n if (!installation) {\n return null;\n }\n\n let skillCount = 0;\n let agentCount = 0;\n let name = DEFAULT_PLUGIN_NAME;\n let version = DEFAULT_DISPLAY_VERSION;\n\n if (installation.mode === \"plugin\") {\n // Plugin mode: discover skills via settings.json and global cache\n try {\n const pluginSkills = await discoverAllPluginSkills(installation.projectDir);\n skillCount = Object.keys(pluginSkills).length;\n } catch {\n // Ignore errors\n }\n } else if (await directoryExists(installation.skillsDir)) {\n try {\n const skills = await readdir(installation.skillsDir, {\n withFileTypes: true,\n });\n skillCount = skills.filter((s) => s.isDirectory()).length;\n } catch {\n // Ignore errors\n }\n }\n\n if (await directoryExists(installation.agentsDir)) {\n try {\n const agents = await readdir(installation.agentsDir, {\n withFileTypes: true,\n });\n agentCount = agents.filter((a) => a.isFile() && a.name.endsWith(\".md\")).length;\n } catch {\n // Ignore errors\n }\n }\n\n const loaded = await loadProjectConfig(installation.projectDir);\n if (loaded?.config) {\n name = loaded.config.name || DEFAULT_PLUGIN_NAME;\n version = installation.mode === \"local\" ? \"local\" : \"plugin\";\n }\n\n return {\n mode: installation.mode,\n name,\n version,\n skillCount,\n agentCount,\n configPath: installation.configPath,\n agentsDir: installation.agentsDir,\n skillsDir: installation.skillsDir,\n };\n}\n\nexport function formatInstallationDisplay(info: InstallationInfo): string {\n const modeLabel = info.mode === \"local\" ? \"Local\" : \"Plugin\";\n const versionDisplay = info.mode === \"local\" ? \"(local mode)\" : `v${info.version}`;\n\n return `Installation: ${info.name} ${versionDisplay}\n Mode: ${modeLabel}\n Skills: ${info.skillCount}\n Agents: ${info.agentCount}\n Config: ${info.configPath}\n Agents: ${info.agentsDir}`;\n}\n","export {\n type InstallMode,\n type Installation,\n detectGlobalInstallation,\n detectInstallation,\n detectProjectInstallation,\n getInstallationOrThrow,\n} from \"./installation\";\n\nexport {\n type LocalInstallOptions,\n type LocalInstallResult,\n type PluginConfigResult,\n installLocal,\n installPluginConfig,\n buildAndMergeConfig,\n writeConfigFile,\n writeScopedConfigs,\n setConfigMetadata,\n} from \"./local-installer\";\n\nexport {\n type SkillMigration,\n type MigrationPlan,\n type MigrationResult,\n detectMigrations,\n executeMigration,\n} from \"./mode-migrator\";\n\nexport { deriveInstallMode } from \"./installation\";\n","import os from \"os\";\nimport path from \"path\";\nimport { fileExists } from \"../../utils/fs\";\nimport { loadProjectConfigFromDir } from \"../configuration/project-config\";\nimport {\n CLAUDE_DIR,\n CLAUDE_SRC_DIR,\n CLI_BIN_NAME,\n DEFAULT_BRANDING,\n PLUGINS_SUBDIR,\n STANDARD_FILES,\n} from \"../../consts\";\nimport type { SkillConfig } from \"../../types/config\";\n\nexport type InstallMode = \"local\" | \"plugin\" | \"mixed\";\n\nexport type Installation = {\n mode: InstallMode;\n configPath: string;\n agentsDir: string;\n skillsDir: string;\n projectDir: string;\n};\n\n/** Derive install mode from skills array at runtime */\nexport function deriveInstallMode(skills: SkillConfig[]): InstallMode {\n if (skills.length === 0) return \"local\";\n const hasLocal = skills.some((s) => s.source === \"local\");\n const hasPlugin = skills.some((s) => s.source !== \"local\");\n if (hasLocal && hasPlugin) return \"mixed\";\n return hasLocal ? \"local\" : \"plugin\";\n}\n\n/** Detect installation in a specific directory only (no global fallback). */\nexport async function detectProjectInstallation(projectDir: string): Promise<Installation | null> {\n const configPath = path.join(projectDir, CLAUDE_SRC_DIR, STANDARD_FILES.CONFIG_TS);\n\n if (!(await fileExists(configPath))) {\n return null;\n }\n\n // Use loadProjectConfigFromDir to avoid circular global fallback\n const loaded = await loadProjectConfigFromDir(projectDir);\n\n const mode: InstallMode = deriveInstallMode(loaded?.config?.skills ?? []);\n\n if (mode === \"local\") {\n return {\n mode: \"local\",\n configPath,\n agentsDir: path.join(projectDir, CLAUDE_DIR, \"agents\"),\n skillsDir: path.join(projectDir, CLAUDE_DIR, \"skills\"),\n projectDir,\n };\n }\n\n // Skills live in global plugin cache; agents compiled locally\n return {\n mode: \"plugin\",\n configPath,\n agentsDir: path.join(projectDir, CLAUDE_DIR, \"agents\"),\n skillsDir: path.join(projectDir, CLAUDE_DIR, PLUGINS_SUBDIR),\n projectDir,\n };\n}\n\n/** Detect installation in the home directory (global scope). */\nexport async function detectGlobalInstallation(): Promise<Installation | null> {\n const homeDir = os.homedir();\n const configPath = path.join(homeDir, CLAUDE_SRC_DIR, STANDARD_FILES.CONFIG_TS);\n\n if (!(await fileExists(configPath))) {\n return null;\n }\n\n // Use loadProjectConfigFromDir directly to avoid recursion\n const loaded = await loadProjectConfigFromDir(homeDir);\n const mode: InstallMode = deriveInstallMode(loaded?.config?.skills ?? []);\n\n if (mode === \"local\") {\n return {\n mode: \"local\",\n configPath,\n agentsDir: path.join(homeDir, CLAUDE_DIR, \"agents\"),\n skillsDir: path.join(homeDir, CLAUDE_DIR, \"skills\"),\n projectDir: homeDir,\n };\n }\n\n return {\n mode: \"plugin\",\n configPath,\n agentsDir: path.join(homeDir, CLAUDE_DIR, \"agents\"),\n skillsDir: path.join(homeDir, CLAUDE_DIR, PLUGINS_SUBDIR),\n projectDir: homeDir,\n };\n}\n\n/**\n * Detect installation: checks project-level first, then falls back to global (home directory).\n * Project fully overrides global (no merging).\n */\nexport async function detectInstallation(\n projectDir: string = process.cwd(),\n): Promise<Installation | null> {\n // 1. Check project-level first\n const projectInstallation = await detectProjectInstallation(projectDir);\n if (projectInstallation) return projectInstallation;\n\n // 2. Fall back to global (home directory)\n return detectGlobalInstallation();\n}\n\nexport async function getInstallationOrThrow(\n projectDir: string = process.cwd(),\n): Promise<Installation> {\n const installation = await detectInstallation(projectDir);\n\n if (!installation) {\n throw new Error(\n `No ${DEFAULT_BRANDING.NAME} installation found.\\nRun '${CLI_BIN_NAME} init' to create one.`,\n );\n }\n\n return installation;\n}\n","import os from \"os\";\nimport path from \"path\";\nimport type {\n AgentConfig,\n AgentDefinition,\n AgentName,\n CompileAgentConfig,\n CompileConfig,\n MergedSkillsMatrix,\n ProjectConfig,\n SkillDefinition,\n SkillId,\n Stack,\n} from \"../../types\";\nimport type { InstallMode } from \"./installation\";\nimport { deriveInstallMode } from \"./installation\";\nimport { matrix } from \"../matrix/matrix-provider\";\nimport type { AgentScopeConfig, SkillConfig } from \"../../types/config\";\nimport type { WizardResultV2 } from \"../../components/wizard/wizard\";\nimport { type CopiedSkill, copySkillsToLocalFlattened, deleteLocalSkill } from \"../skills\";\nimport { type MergeResult, mergeWithExistingConfig } from \"../configuration\";\nimport { loadAllAgents, loadSkillsByIds, type SourceLoadResult } from \"../loading\";\nimport { loadStackById, compileAgentForPlugin, getStackSkillIds } from \"../stacks\";\nimport { resolveAgents, buildSkillRefsFromConfig } from \"../resolver\";\nimport { createLiquidEngine } from \"../compiler\";\nimport { generateProjectConfigFromSkills, buildStackProperty } from \"../configuration\";\nimport { splitConfigByScope } from \"../configuration/config-generator\";\nimport { generateConfigSource, type ConfigSourceOptions } from \"../configuration/config-writer\";\nimport {\n generateConfigTypesSource,\n generateProjectConfigTypesSource,\n} from \"../configuration/config-types-writer\";\nimport { ensureDir, writeFile } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport { typedEntries, typedKeys } from \"../../utils/typed-object\";\nimport { isCategory } from \"../../utils/type-guards\";\nimport {\n CLAUDE_DIR,\n CLAUDE_SRC_DIR,\n DEFAULT_PLUGIN_NAME,\n LOCAL_SKILLS_PATH,\n PROJECT_ROOT,\n STANDARD_FILES,\n} from \"../../consts\";\n\ntype LocalResolvedSkill = SkillDefinition & {\n content: string;\n};\n\n/**\n * Options for the local skill installation pipeline.\n *\n * Passed to {@link installLocal} to drive the full installation flow:\n * skill copying, config generation, agent compilation, and file writing.\n */\nexport type LocalInstallOptions = {\n /** Wizard output containing selected skills, stack, install mode, and source selections */\n wizardResult: WizardResultV2;\n /** Loaded source data including the skills matrix, source path, and source configuration */\n sourceResult: SourceLoadResult;\n /** Absolute path to the project root where `.claude/` artifacts will be written */\n projectDir: string;\n /** Optional `--source` flag override (e.g., \"github:org/repo\"). Takes precedence over\n * source from config when writing the `source` field in config.ts */\n sourceFlag?: string;\n};\n\n/**\n * Result of a completed local skill installation.\n *\n * Returned by {@link installLocal} with details about what was written to disk,\n * enabling the caller to display a summary to the user.\n */\nexport type LocalInstallResult = {\n /** Skills that were copied to `.claude/skills/`, with source and destination paths */\n copiedSkills: CopiedSkill[];\n /** Final project configuration (may be merged with existing config.ts) */\n config: ProjectConfig;\n /** Absolute path to the written config.ts file */\n configPath: string;\n /** Agent names that were compiled and written to `.claude/agents/` */\n compiledAgents: AgentName[];\n /** Whether the config was merged with an existing config.ts (true) or freshly created (false) */\n wasMerged: boolean;\n /** Absolute path to the pre-existing config.ts that was merged, if any */\n mergedConfigPath?: string;\n /** Absolute path to the `.claude/skills/` directory */\n skillsDir: string;\n /** Absolute path to the `.claude/agents/` directory */\n agentsDir: string;\n};\n\ntype InstallPaths = {\n skillsDir: string;\n agentsDir: string;\n configPath: string;\n};\n\nfunction resolveInstallPaths(\n projectDir: string,\n scope: \"project\" | \"global\" = \"project\",\n): InstallPaths {\n // Use os.homedir() at runtime for global scope so the path agrees with mocked\n // home directories in tests (GLOBAL_INSTALL_ROOT is evaluated at import time)\n const baseDir = scope === \"global\" ? os.homedir() : projectDir;\n return {\n skillsDir: path.join(baseDir, LOCAL_SKILLS_PATH),\n agentsDir: path.join(baseDir, CLAUDE_DIR, \"agents\"),\n configPath: path.join(baseDir, CLAUDE_SRC_DIR, STANDARD_FILES.CONFIG_TS),\n };\n}\n\nasync function prepareDirectories(paths: InstallPaths): Promise<void> {\n await ensureDir(paths.skillsDir);\n await ensureDir(paths.agentsDir);\n await ensureDir(path.dirname(paths.configPath));\n}\n\nasync function deleteAndCopySkills(\n skills: SkillConfig[],\n sourceResult: SourceLoadResult,\n projectDir: string,\n skillsDir: string,\n): Promise<CopiedSkill[]> {\n for (const skill of skills) {\n if (skill.source && skill.source !== \"local\") {\n verbose(`Using alternate source '${skill.source}' for ${skill.id}`);\n await deleteLocalSkill(projectDir, skill.id);\n }\n }\n\n const skillIds = skills.map((s) => s.id);\n return copySkillsToLocalFlattened(skillIds, skillsDir, sourceResult.matrix, sourceResult);\n}\n\nfunction buildLocalSkillsMap(\n copiedSkills: CopiedSkill[],\n): Partial<Record<SkillId, LocalResolvedSkill>> {\n // Boundary cast: Object.fromEntries returns { [k: string]: V }\n return Object.fromEntries(\n copiedSkills\n .filter((cs) => matrix.skills[cs.skillId])\n .map((cs) => [\n cs.skillId,\n {\n id: cs.skillId,\n description: matrix.skills[cs.skillId]!.description,\n path: cs.destPath,\n content: \"\", // Content not needed for skill references\n },\n ]),\n );\n}\n\nasync function loadMergedAgents(sourcePath: string): Promise<Record<AgentName, AgentDefinition>> {\n const cliAgents = await loadAllAgents(PROJECT_ROOT);\n const sourceAgents = await loadAllAgents(sourcePath);\n return { ...cliAgents, ...sourceAgents };\n}\n\nasync function buildLocalConfig(\n wizardResult: WizardResultV2,\n sourceResult: SourceLoadResult,\n): Promise<{ config: ProjectConfig; loadedStack: Stack | null }> {\n const skillIds = wizardResult.skills.map((s) => s.id);\n verbose(\n `buildLocalConfig: selectedStackId='${wizardResult.selectedStackId}', ` +\n `skills=[${skillIds.join(\", \")}], ` +\n `selectedAgents=[${wizardResult.selectedAgents.join(\", \")}]`,\n );\n\n let loadedStack: Stack | null = null;\n if (wizardResult.selectedStackId) {\n loadedStack = await loadStackById(wizardResult.selectedStackId, sourceResult.sourcePath);\n verbose(\n `buildLocalConfig: loadedStack=${loadedStack ? `found (id='${loadedStack.id}')` : \"NOT FOUND\"}`,\n );\n }\n\n let localConfig: ProjectConfig;\n\n // Pass user's agent selection and skill configs to config generator\n const agentOptions: {\n selectedAgents?: AgentName[];\n skillConfigs: SkillConfig[];\n agentConfigs?: AgentScopeConfig[];\n } = {\n skillConfigs: wizardResult.skills,\n ...(wizardResult.selectedAgents.length > 0 && {\n selectedAgents: wizardResult.selectedAgents,\n }),\n ...(wizardResult.agentConfigs.length > 0 && {\n agentConfigs: wizardResult.agentConfigs,\n }),\n };\n\n if (wizardResult.selectedStackId) {\n if (loadedStack) {\n // Use actual selections (may differ from stack defaults after user customization)\n localConfig = generateProjectConfigFromSkills(DEFAULT_PLUGIN_NAME, skillIds, agentOptions);\n\n // Overlay preloaded flags from the stack definition — generateProjectConfigFromSkills\n // defaults all skills to preloaded: false; the stack YAML may define preloaded: true\n if (localConfig.stack) {\n const stackProperty = buildStackProperty(loadedStack);\n for (const [agentId, agentConfig] of typedEntries(stackProperty)) {\n if (!agentConfig) continue;\n for (const [category, assignments] of typedEntries(agentConfig)) {\n if (!assignments) continue;\n const localAgentConfig = localConfig.stack[agentId];\n if (!localAgentConfig?.[category]) continue;\n for (const assignment of localAgentConfig[category]) {\n const stackAssignment = assignments.find((a) => a.id === assignment.id);\n if (stackAssignment?.preloaded) {\n assignment.preloaded = true;\n }\n }\n }\n }\n }\n\n localConfig.description = loadedStack.description;\n // Only add stack agents that the user selected (or all if no explicit selection)\n const stackAgentIds = typedKeys<AgentName>(loadedStack.agents);\n const existingAgentNames = new Set(localConfig.agents.map((a) => a.name));\n for (const agentId of stackAgentIds) {\n if (\n !existingAgentNames.has(agentId) &&\n (wizardResult.selectedAgents.length === 0 ||\n wizardResult.selectedAgents.includes(agentId))\n ) {\n localConfig.agents.push({ name: agentId, scope: \"project\" });\n }\n }\n localConfig.agents.sort((a, b) => a.name.localeCompare(b.name));\n } else {\n throw new Error(\n `Stack '${wizardResult.selectedStackId}' not found in config/stacks.ts. ` +\n `Available stacks are defined in the CLI's config/stacks.ts file.`,\n );\n }\n } else {\n localConfig = generateProjectConfigFromSkills(DEFAULT_PLUGIN_NAME, skillIds, agentOptions);\n }\n\n verbose(\n `buildLocalConfig result: stack=${localConfig.stack ? Object.keys(localConfig.stack).length + \" agents\" : \"UNDEFINED\"}, ` +\n `agents=[${localConfig.agents.map((a) => a.name).join(\", \")}], skills=${localConfig.skills.length}`,\n );\n\n return { config: localConfig, loadedStack };\n}\n\nexport function setConfigMetadata(\n config: ProjectConfig,\n wizardResult: WizardResultV2,\n sourceResult: SourceLoadResult,\n sourceFlag?: string,\n): void {\n // Only persist domains when non-empty (sparse output)\n if (wizardResult.selectedDomains && wizardResult.selectedDomains.length > 0) {\n config.domains = wizardResult.selectedDomains;\n }\n\n // Only persist selectedAgents when non-empty (sparse output)\n if (wizardResult.selectedAgents && wizardResult.selectedAgents.length > 0) {\n config.selectedAgents = wizardResult.selectedAgents;\n }\n\n if (sourceFlag) {\n config.source = sourceFlag;\n } else if (sourceResult.sourceConfig.source) {\n config.source = sourceResult.sourceConfig.source;\n }\n\n if (sourceResult.marketplace) {\n config.marketplace = sourceResult.marketplace;\n }\n}\n\nexport async function buildAndMergeConfig(\n wizardResult: WizardResultV2,\n sourceResult: SourceLoadResult,\n projectDir: string,\n sourceFlag?: string,\n): Promise<MergeResult> {\n const { config } = await buildLocalConfig(wizardResult, sourceResult);\n verbose(\n `buildAndMergeConfig: before merge — stack=${config.stack ? Object.keys(config.stack).length + \" agents\" : \"UNDEFINED\"}`,\n );\n setConfigMetadata(config, wizardResult, sourceResult, sourceFlag);\n const result = await mergeWithExistingConfig(config, { projectDir });\n verbose(\n `buildAndMergeConfig: after merge — stack=${result.config.stack ? Object.keys(result.config.stack).length + \" agents\" : \"UNDEFINED\"}, merged=${result.merged}`,\n );\n return result;\n}\n\nexport async function writeConfigFile(\n config: ProjectConfig,\n configPath: string,\n options?: ConfigSourceOptions,\n): Promise<void> {\n const source = generateConfigSource(config, options);\n await writeFile(configPath, source);\n}\n\nfunction buildCompileAgents(\n config: ProjectConfig,\n agents: Record<AgentName, AgentDefinition>,\n): Record<string, CompileAgentConfig> {\n // D7 cross-scope safety net: build set of global skill IDs so global agents only see global skills\n const globalSkillIds = new Set(\n config.skills.filter((s) => s.scope === \"global\").map((s) => s.id),\n );\n\n const compileAgents: Record<string, CompileAgentConfig> = {};\n for (const agentConfig of config.agents) {\n if (agents[agentConfig.name]) {\n const agentStack = config.stack?.[agentConfig.name];\n if (agentStack) {\n const refs = buildSkillRefsFromConfig(agentStack);\n // Global agents only see global skills (cross-scope safety net)\n const filteredRefs =\n agentConfig.scope === \"global\" ? refs.filter((ref) => globalSkillIds.has(ref.id)) : refs;\n compileAgents[agentConfig.name] = { skills: filteredRefs };\n } else {\n compileAgents[agentConfig.name] = {};\n }\n }\n }\n return compileAgents;\n}\n\nfunction buildAgentScopeMap(config: ProjectConfig): Map<AgentName, \"project\" | \"global\"> {\n const map = new Map<AgentName, \"project\" | \"global\">();\n for (const agent of config.agents) {\n map.set(agent.name, agent.scope);\n }\n return map;\n}\n\nasync function writeStandaloneConfigTypes(\n configPath: string,\n matrix: MergedSkillsMatrix,\n agents: Record<AgentName, AgentDefinition>,\n finalConfig?: ProjectConfig,\n): Promise<void> {\n const typesPath = path.join(path.dirname(configPath), STANDARD_FILES.CONFIG_TYPES_TS);\n const customAgentNames = typedKeys(agents).filter((name) => agents[name]?.custom === true);\n const source = generateConfigTypesSource(\n matrix,\n typedKeys(agents),\n customAgentNames,\n undefined,\n finalConfig,\n );\n await writeFile(typesPath, source);\n}\n\nasync function writeProjectConfigTypes(\n projectConfigPath: string,\n projectDir: string,\n projectConfig?: ProjectConfig,\n matrix?: MergedSkillsMatrix,\n): Promise<void> {\n const typesPath = path.join(path.dirname(projectConfigPath), STANDARD_FILES.CONFIG_TYPES_TS);\n const projectClaudeSrc = path.join(projectDir, CLAUDE_SRC_DIR);\n const globalClaudeSrc = path.join(os.homedir(), CLAUDE_SRC_DIR);\n const relativePath = path.relative(projectClaudeSrc, globalClaudeSrc);\n // Convert to POSIX separators for TypeScript imports\n const globalTypesImportPath = relativePath.split(path.sep).join(\"/\");\n\n // Derive project-specific items from the project config when available\n const projectSkillIds = projectConfig?.skills.map((s) => s.id) ?? [];\n const projectAgentNames = projectConfig?.agents.map((a) => a.name) ?? [];\n\n // Derive categories and domains from project skills via matrix lookup\n let projectCategories: string[] = [];\n let projectDomains: string[] = [];\n if (matrix && projectSkillIds.length > 0) {\n const categorySet = new Set<string>();\n for (const id of projectSkillIds) {\n const skill = matrix.skills[id];\n if (skill?.category && skill.category !== \"local\") {\n categorySet.add(skill.category);\n }\n }\n projectCategories = [...categorySet].sort();\n\n const domainSet = new Set<string>();\n for (const cat of projectCategories) {\n if (!isCategory(cat)) continue;\n const def = matrix.categories[cat];\n if (def?.domain) {\n domainSet.add(def.domain);\n }\n }\n projectDomains = [...domainSet].sort();\n }\n\n const source = generateProjectConfigTypesSource({\n globalTypesImportPath,\n projectSkillIds,\n projectAgentNames,\n projectDomains,\n projectCategories,\n });\n await writeFile(typesPath, source);\n verbose(\"Using project config-types.ts that imports from global\");\n}\n\n/**\n * Writes config.ts and config-types.ts split by scope.\n * When installing into a project directory:\n * - Global config/types go to ~/.claude-src/\n * - Project config/types go to {projectDir}/.claude-src/ (with import from global)\n * When installing from home directory, writes a single standalone config.\n */\nexport async function writeScopedConfigs(\n finalConfig: ProjectConfig,\n matrix: MergedSkillsMatrix,\n agents: Record<AgentName, AgentDefinition>,\n projectDir: string,\n projectConfigPath: string,\n): Promise<void> {\n // Use os.homedir() at runtime (not GLOBAL_INSTALL_ROOT constant) so the path\n // agrees with getGlobalConfigImportPath() which also calls os.homedir() at runtime\n const homeDir = os.homedir();\n const isProjectContext = path.resolve(projectDir) !== path.resolve(homeDir);\n\n if (!isProjectContext) {\n // Installing from ~/ — write directly to global config (no import preamble)\n await writeConfigFile(finalConfig, projectConfigPath);\n await writeStandaloneConfigTypes(projectConfigPath, matrix, agents, finalConfig);\n return;\n }\n\n // Installing from project — split by scope and write to both locations\n const { global: globalConfig, project: projectSplitConfig } = splitConfigByScope(finalConfig);\n const globalConfigPath = path.join(homeDir, CLAUDE_SRC_DIR, STANDARD_FILES.CONFIG_TS);\n\n // Write global config to ~/.claude-src/config.ts (standalone, no import preamble)\n await ensureDir(path.dirname(globalConfigPath));\n await writeConfigFile(globalConfig, globalConfigPath);\n verbose(`Updated global config at ${globalConfigPath}`);\n\n // Write global config-types.ts narrowed to global-scoped items\n await writeStandaloneConfigTypes(globalConfigPath, matrix, agents, globalConfig);\n verbose(\"Updated global config-types.ts with actual types\");\n\n // Write project config with import from global\n await ensureDir(path.dirname(projectConfigPath));\n await writeConfigFile(projectSplitConfig, projectConfigPath, { isProjectConfig: true });\n verbose(`Updated project config at ${projectConfigPath}`);\n\n // Write project config-types.ts that extends global with only project-scoped items.\n // Global items are already available via GlobalSkillId/GlobalAgentName imports.\n await writeProjectConfigTypes(projectConfigPath, projectDir, projectSplitConfig, matrix);\n}\n\nasync function compileAndWriteAgents(\n compileConfig: CompileConfig,\n agents: Record<AgentName, AgentDefinition>,\n localSkills: Partial<Record<SkillId, LocalResolvedSkill>>,\n sourceResult: SourceLoadResult,\n projectDir: string,\n agentsDir: string,\n installMode?: InstallMode,\n agentScopeMap?: Map<AgentName, \"project\" | \"global\">,\n): Promise<AgentName[]> {\n const engine = await createLiquidEngine(projectDir);\n const resolvedAgents = await resolveAgents(\n agents,\n localSkills,\n compileConfig,\n sourceResult.sourcePath,\n );\n\n const globalAgentsDir = path.join(os.homedir(), CLAUDE_DIR, \"agents\");\n\n const compiledAgentNames: AgentName[] = [];\n for (const [name, agent] of typedEntries<AgentName, AgentConfig>(resolvedAgents)) {\n const output = await compileAgentForPlugin(\n name,\n agent,\n sourceResult.sourcePath,\n engine,\n installMode,\n );\n\n // Route agent output by scope: global agents go to ~/. project agents to projectDir\n const scope = agentScopeMap?.get(name) ?? \"project\";\n const targetDir = scope === \"global\" ? globalAgentsDir : agentsDir;\n if (scope === \"global\") {\n await ensureDir(targetDir);\n }\n await writeFile(path.join(targetDir, `${name}.md`), output);\n compiledAgentNames.push(name);\n }\n\n return compiledAgentNames;\n}\n\n/** Result of plugin-mode config installation — same as LocalInstallResult without copied skills or skillsDir */\nexport type PluginConfigResult = Omit<LocalInstallResult, \"copiedSkills\" | \"skillsDir\">;\n\n/**\n * Generates config and compiles agents for plugin mode (without copying skills).\n *\n * Used when skills are installed as native plugins and should NOT be copied\n * to `.claude/skills/`. This function performs only:\n * 1. Creates `.claude/agents/` and `.claude-src/` directories\n * 2. Loads agent definitions from both the CLI and source repository\n * 3. Generates project config.ts from the wizard selections, merging with any\n * existing config\n * 4. Writes config.ts\n * 5. Compiles agent markdown files using Liquid templates and writes them to\n * `.claude/agents/`\n *\n * @param options - Installation options containing wizard result, source data,\n * project directory, and optional source flag override\n * @returns Result containing config and agent artifacts (no skills)\n * @throws {Error} If the selected stack ID is not found in config/stacks.ts\n */\nexport async function installPluginConfig(\n options: LocalInstallOptions,\n): Promise<PluginConfigResult> {\n const { wizardResult, sourceResult, projectDir, sourceFlag } = options;\n\n const projectPaths = resolveInstallPaths(projectDir, \"project\");\n\n // Only create project directories if there are project-scoped agents\n const hasProjectAgents =\n wizardResult.skills.some((s) => s.scope !== \"global\") ||\n wizardResult.agentConfigs.some((a) => a.scope !== \"global\");\n if (hasProjectAgents) {\n await ensureDir(projectPaths.agentsDir);\n }\n await ensureDir(path.dirname(projectPaths.configPath));\n\n const agents = await loadMergedAgents(sourceResult.sourcePath);\n const mergeResult = await buildAndMergeConfig(wizardResult, sourceResult, projectDir, sourceFlag);\n const finalConfig = mergeResult.config;\n\n await writeScopedConfigs(\n finalConfig,\n sourceResult.matrix,\n agents,\n projectDir,\n projectPaths.configPath,\n );\n\n const compileAgentsConfig = buildCompileAgents(finalConfig, agents);\n const compileConfig: CompileConfig = {\n name: DEFAULT_PLUGIN_NAME,\n description:\n finalConfig.description || `Plugin setup with ${wizardResult.skills.length} skills`,\n agents: compileAgentsConfig,\n };\n // Load skill metadata from source for compilation\n // (actual skill content will be loaded from plugins at runtime)\n const stackSkillIds = finalConfig.stack ? getStackSkillIds(finalConfig.stack) : [];\n // Boundary cast: loadSkillsByIds returns SkillDefinitionMap, LocalResolvedSkill extends SkillDefinition\n const skillsForCompilation = (await loadSkillsByIds(\n stackSkillIds.map((id) => ({ id })),\n sourceResult.sourcePath,\n )) as Partial<Record<SkillId, LocalResolvedSkill>>;\n\n const compiledAgentNames = await compileAndWriteAgents(\n compileConfig,\n agents,\n skillsForCompilation,\n sourceResult,\n projectDir,\n projectPaths.agentsDir,\n deriveInstallMode(finalConfig.skills),\n buildAgentScopeMap(finalConfig),\n );\n\n return {\n config: finalConfig,\n configPath: projectPaths.configPath,\n compiledAgents: compiledAgentNames,\n wasMerged: mergeResult.merged,\n mergedConfigPath: mergeResult.existingConfigPath,\n agentsDir: projectPaths.agentsDir,\n };\n}\n\n/**\n * Executes the full local skill installation pipeline.\n *\n * This is the main entry point for the \"local\" install mode (as opposed to plugin mode).\n * It performs the following steps in order:\n * 1. Creates `.claude/skills/` and `.claude/agents/` directories\n * 2. Deletes local skills switching to alternate sources, then copies selected\n * skills from the source repository into `.claude/skills/` (flattened layout)\n * 3. Loads agent definitions from both the CLI and source repository\n * 4. Generates project config.ts from the wizard selections, merging with any\n * existing config\n * 5. Writes config.ts\n * 6. Compiles agent markdown files using Liquid templates and writes them to\n * `.claude/agents/`\n *\n * @param options - Installation options containing wizard result, source data,\n * project directory, and optional source flag override\n * @returns Result containing all written artifacts (skills, config, agents) and\n * metadata about the installation (merge status, paths)\n * @throws {Error} If the selected stack ID is not found in config/stacks.ts\n *\n * @remarks\n * **Side effects:** Creates directories and writes files under `{projectDir}/.claude/`.\n */\nexport async function installLocal(options: LocalInstallOptions): Promise<LocalInstallResult> {\n const { wizardResult, sourceResult, projectDir, sourceFlag } = options;\n\n const projectPaths = resolveInstallPaths(projectDir, \"project\");\n const globalPaths = resolveInstallPaths(projectDir, \"global\");\n\n // Split skills by scope for path routing\n const projectSkills = wizardResult.skills.filter((s) => s.scope !== \"global\");\n const globalSkills = wizardResult.skills.filter((s) => s.scope === \"global\");\n\n // Only create project directories when there are project-scoped skills or agents\n const hasProjectItems =\n projectSkills.length > 0 || wizardResult.agentConfigs.some((a) => a.scope !== \"global\");\n if (hasProjectItems) {\n await prepareDirectories(projectPaths);\n } else {\n // Always ensure .claude-src/ exists for project config (it imports from global)\n await ensureDir(path.dirname(projectPaths.configPath));\n }\n if (globalSkills.length > 0) {\n await ensureDir(globalPaths.skillsDir);\n }\n\n // Copy skills to their scope-appropriate directories\n const projectCopied =\n projectSkills.length > 0\n ? await deleteAndCopySkills(projectSkills, sourceResult, projectDir, projectPaths.skillsDir)\n : [];\n const globalCopied =\n globalSkills.length > 0\n ? await deleteAndCopySkills(globalSkills, sourceResult, projectDir, globalPaths.skillsDir)\n : [];\n const copiedSkills = [...projectCopied, ...globalCopied];\n\n const localSkillsForResolution = buildLocalSkillsMap(copiedSkills);\n\n const agents = await loadMergedAgents(sourceResult.sourcePath);\n const mergeResult = await buildAndMergeConfig(wizardResult, sourceResult, projectDir, sourceFlag);\n const finalConfig = mergeResult.config;\n\n await writeScopedConfigs(\n finalConfig,\n sourceResult.matrix,\n agents,\n projectDir,\n projectPaths.configPath,\n );\n\n const compileAgentsConfig = buildCompileAgents(finalConfig, agents);\n const compileConfig: CompileConfig = {\n name: DEFAULT_PLUGIN_NAME,\n description: finalConfig.description || `Local setup with ${wizardResult.skills.length} skills`,\n agents: compileAgentsConfig,\n };\n const compiledAgentNames = await compileAndWriteAgents(\n compileConfig,\n agents,\n localSkillsForResolution,\n sourceResult,\n projectDir,\n projectPaths.agentsDir,\n deriveInstallMode(finalConfig.skills),\n buildAgentScopeMap(finalConfig),\n );\n\n return {\n copiedSkills,\n config: finalConfig,\n configPath: projectPaths.configPath,\n compiledAgents: compiledAgentNames,\n wasMerged: mergeResult.merged,\n mergedConfigPath: mergeResult.existingConfigPath,\n skillsDir: projectPaths.skillsDir,\n agentsDir: projectPaths.agentsDir,\n };\n}\n","export { type FetchSkillsOptions, fetchSkills } from \"./skill-fetcher\";\n\nexport {\n type ForkedFromMetadata,\n type LocalSkillMetadata,\n type SkillComparisonResult,\n readForkedFromMetadata,\n readLocalSkillMetadata,\n getLocalSkillsWithMetadata,\n computeSourceHash,\n compareLocalSkillsWithSource,\n injectForkedFromMetadata,\n} from \"./skill-metadata\";\n\nexport {\n type CopiedSkill,\n type CopyProgressCallback,\n copySkill,\n copySkillFromSource,\n copySkillsToPluginFromSource,\n copySkillsToLocalFlattened,\n} from \"./skill-copier\";\n\nexport {\n type SkillPluginOptions,\n type CompiledSkillPlugin,\n compileSkillPlugin,\n compileAllSkillPlugins,\n printCompilationSummary,\n} from \"./skill-plugin-compiler\";\n\nexport { type LocalSkillDiscoveryResult, discoverLocalSkills } from \"./local-skill-loader\";\n\nexport { deleteLocalSkill, migrateLocalSkillScope } from \"./source-switcher\";\n","import path from \"path\";\nimport { sortBy } from \"remeda\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\n\nimport { fileExists, readFile, writeFile, listDirectories } from \"../../utils/fs\";\nimport { computeFileHash } from \"../versioning\";\nimport { getCurrentDate } from \"../versioning\";\nimport {\n LOCAL_SKILLS_PATH,\n SCHEMA_PATHS,\n STANDARD_FILES,\n YAML_FORMATTING,\n yamlSchemaComment,\n} from \"../../consts\";\nimport type { SkillId } from \"../../types\";\nimport { formatZodErrors, localSkillMetadataSchema } from \"../schemas\";\nimport { warn } from \"../../utils/logger\";\n\n/**\n * Tracks the original marketplace source of a locally-installed skill.\n *\n * Written into each skill's metadata.yaml under the `forkedFrom` key when a skill\n * is copied from a source repository to the local `.claude/skills/` directory.\n * Used for version comparison, update detection, and provenance tracking.\n */\nexport type ForkedFromMetadata = {\n /** Canonical skill ID from the source repository (e.g., \"cc-ts-react-hook-form\") */\n skillId: SkillId;\n /** SHA-256 hash of the source SKILL.md content at the time of installation */\n contentHash: string;\n /** ISO date string (YYYY-MM-DD) when the skill was installed or last updated */\n date: string;\n /** Source URL the skill was installed from (e.g., \"github:agents-inc/skills\") */\n source?: string;\n};\n\n/**\n * Full metadata.yaml content for a locally-installed skill.\n *\n * Parsed from the `metadata.yaml` file in each skill directory under `.claude/skills/`.\n * Uses an index signature to preserve unknown fields written by other tools.\n */\nexport type LocalSkillMetadata = {\n /** Provenance metadata linking back to the original source skill, if any */\n forkedFrom?: ForkedFromMetadata;\n [key: string]: unknown;\n};\n\n/**\n * Result of comparing a local skill against its source repository version.\n *\n * Produced by {@link compareLocalSkillsWithSource} for each skill in the local\n * `.claude/skills/` directory. Used by `agentsinc outdated` to display update status.\n */\nexport type SkillComparisonResult = {\n /** Canonical skill ID (from forkedFrom metadata, or directory name if no metadata) */\n id: SkillId;\n /** SHA-256 hash of the local SKILL.md content at install time, null if no forkedFrom metadata */\n localHash: string | null;\n /** SHA-256 hash of the current source SKILL.md, null if source skill no longer exists */\n sourceHash: string | null;\n /** \"current\" if hashes match, \"outdated\" if they differ, \"local-only\" if no source link */\n status: \"current\" | \"outdated\" | \"local-only\";\n /** Directory name under `.claude/skills/` (may differ from skill ID for aliased skills) */\n dirName: string;\n /** Relative path within the source repository, present only when the source skill exists */\n sourcePath?: string;\n};\n\n/**\n * Reads forkedFrom metadata from a skill's metadata.yaml file.\n *\n * This metadata tracks the original marketplace source of a locally-installed skill,\n * enabling version comparison and update detection via content hash matching.\n *\n * @param skillDir - Absolute path to the skill directory (e.g., `/project/.claude/skills/react-hook-form`)\n * @returns The `forkedFrom` metadata if present and valid, `null` if the file doesn't exist,\n * has no `forkedFrom` field, or fails Zod validation (warns on invalid metadata)\n *\n * @example\n * ```ts\n * const metadata = await readForkedFromMetadata(\"/project/.claude/skills/react-hook-form\");\n * if (metadata) {\n * console.log(`Installed from ${metadata.skillId} on ${metadata.date}`);\n * }\n * ```\n */\nexport async function readForkedFromMetadata(skillDir: string): Promise<ForkedFromMetadata | null> {\n const metadata = await readLocalSkillMetadata(skillDir);\n return metadata?.forkedFrom ?? null;\n}\n\n/**\n * Reads the full local skill metadata from a skill's metadata.yaml file.\n *\n * Returns the parsed metadata including `forkedFrom` field.\n * Used by the uninstall command to determine whether a skill was installed by the CLI.\n *\n * @param skillDir - Absolute path to the skill directory\n * @returns The parsed metadata if valid, `null` if the file doesn't exist or is invalid\n */\nexport async function readLocalSkillMetadata(skillDir: string): Promise<LocalSkillMetadata | null> {\n const metadataPath = path.join(skillDir, STANDARD_FILES.METADATA_YAML);\n\n if (!(await fileExists(metadataPath))) {\n return null;\n }\n\n const content = await readFile(metadataPath);\n const result = localSkillMetadataSchema.safeParse(parseYaml(content));\n\n if (!result.success) {\n warn(`Invalid metadata.yaml at ${metadataPath}: ${formatZodErrors(result.error.issues)}`);\n return null;\n }\n\n return result.data as LocalSkillMetadata;\n}\n\n/**\n * Scans all local skill directories and reads their forked-from metadata.\n *\n * Enumerates every subdirectory under `{projectDir}/.claude/skills/` and reads\n * the `forkedFrom` field from each skill's metadata.yaml. The returned Map is\n * keyed by skill ID (from `forkedFrom.skillId` if available, otherwise the\n * directory name).\n *\n * @param projectDir - Absolute path to the project root containing `.claude/skills/`\n * @returns Map from skill identifier to its directory name and forked-from metadata.\n * Returns an empty Map if the skills directory doesn't exist.\n *\n * @example\n * ```ts\n * const skills = await getLocalSkillsWithMetadata(\"/project\");\n * for (const [id, { dirName, forkedFrom }] of skills) {\n * console.log(`${id} in ${dirName}, forked: ${forkedFrom !== null}`);\n * }\n * ```\n */\nexport async function getLocalSkillsWithMetadata(\n projectDir: string,\n): Promise<Map<string, { dirName: string; forkedFrom: ForkedFromMetadata | null }>> {\n const localSkillsPath = path.join(projectDir, LOCAL_SKILLS_PATH);\n const result = new Map<string, { dirName: string; forkedFrom: ForkedFromMetadata | null }>();\n\n if (!(await fileExists(localSkillsPath))) {\n return result;\n }\n\n const skillDirs = await listDirectories(localSkillsPath);\n\n for (const dirName of skillDirs) {\n const skillDir = path.join(localSkillsPath, dirName);\n const forkedFrom = await readForkedFromMetadata(skillDir);\n\n const skillId = forkedFrom?.skillId ?? dirName;\n\n result.set(skillId, { dirName, forkedFrom });\n }\n\n return result;\n}\n\n/**\n * Computes the SHA-256 content hash of a skill's SKILL.md in a source repository.\n *\n * Used to compare the current source version against the locally-installed version's\n * `contentHash` to detect whether updates are available.\n *\n * @param sourcePath - Absolute path to the source repository root\n * @param skillPath - Relative path to the skill within `src/` (e.g., \"web/react/react-hook-form\")\n * @returns SHA-256 hash string of the source SKILL.md, or `null` if the file doesn't exist\n */\nexport async function computeSourceHash(\n sourcePath: string,\n skillPath: string,\n): Promise<string | null> {\n const skillMdPath = path.join(sourcePath, \"src\", skillPath, STANDARD_FILES.SKILL_MD);\n\n if (!(await fileExists(skillMdPath))) {\n return null;\n }\n\n return computeFileHash(skillMdPath);\n}\n\n/**\n * Compares all local skills against their source repository versions.\n *\n * For each skill in `{projectDir}/.claude/skills/`, reads its `forkedFrom` metadata\n * and computes the current source hash. Skills are classified as:\n * - **\"current\"** -- local content hash matches the source (no update available)\n * - **\"outdated\"** -- hashes differ (source has been updated since installation)\n * - **\"local-only\"** -- no `forkedFrom` metadata, or the source skill no longer exists\n *\n * Results are sorted alphabetically by skill ID.\n *\n * @param projectDir - Absolute path to the project root containing `.claude/skills/`\n * @param sourcePath - Absolute path to the source repository root (used to locate SKILL.md files)\n * @param sourceSkills - Map of skill IDs to their relative paths within the source repository.\n * Typically built from the skills matrix. Keys are skill IDs, values have\n * a `path` field (e.g., `{ path: \"web/react/react-hook-form\" }`)\n * @returns Array of comparison results, one per local skill, sorted by skill ID\n *\n * @example\n * ```ts\n * const results = await compareLocalSkillsWithSource(\n * \"/project\",\n * \"/tmp/source-repo\",\n * { \"cc-ts-react-hook-form\": { path: \"web/react/react-hook-form\" } },\n * );\n * const outdated = results.filter((r) => r.status === \"outdated\");\n * ```\n */\nexport async function compareLocalSkillsWithSource(\n projectDir: string,\n sourcePath: string,\n sourceSkills: Record<string, { path: string }>,\n): Promise<SkillComparisonResult[]> {\n const results: SkillComparisonResult[] = [];\n const localSkills = await getLocalSkillsWithMetadata(projectDir);\n\n for (const [skillId, { dirName, forkedFrom }] of localSkills) {\n if (!forkedFrom) {\n // Boundary cast: skillId comes from Map<string, ...> keys (directory names or forkedFrom.skillId)\n results.push({\n id: skillId as SkillId,\n localHash: null,\n sourceHash: null,\n status: \"local-only\",\n dirName,\n });\n continue;\n }\n\n const localHash = forkedFrom.contentHash;\n const sourceSkill = sourceSkills[forkedFrom.skillId];\n\n if (!sourceSkill) {\n results.push({\n id: forkedFrom.skillId,\n localHash,\n sourceHash: null,\n status: \"local-only\",\n dirName,\n });\n continue;\n }\n\n const sourceHash = await computeSourceHash(sourcePath, sourceSkill.path);\n\n if (sourceHash === null) {\n results.push({\n id: forkedFrom.skillId,\n localHash,\n sourceHash: null,\n status: \"local-only\",\n dirName,\n });\n continue;\n }\n\n const status = localHash === sourceHash ? \"current\" : \"outdated\";\n\n results.push({\n id: forkedFrom.skillId,\n localHash,\n sourceHash,\n status,\n dirName,\n sourcePath: sourceSkill.path,\n });\n }\n\n return sortBy(results, (r) => r.id);\n}\n\n/**\n * Writes forked-from provenance metadata into a skill's metadata.yaml.\n *\n * Reads the existing metadata.yaml (preserving any extra fields), sets the\n * `forkedFrom` block with the given skill ID, content hash, and current date,\n * then writes the file back with a YAML language server schema comment.\n *\n * Called during skill installation (by the skill copier) to record where a\n * locally-installed skill originated from.\n *\n * @param destPath - Absolute path to the skill directory containing metadata.yaml.\n * The file must already exist (created during skill copy).\n * @param skillId - Canonical skill ID from the source repository (e.g., \"cc-ts-react-hook-form\")\n * @param contentHash - SHA-256 hash of the source SKILL.md content at install time\n * @param source - Source URL the skill was installed from (e.g., \"github:agents-inc/skills\")\n *\n * @remarks\n * **Side effect:** Overwrites `{destPath}/metadata.yaml` on disk. Existing fields\n * are preserved if the file parses successfully; if parsing fails, only `forkedFrom`\n * is written (with a warning logged).\n */\nexport async function injectForkedFromMetadata(\n destPath: string,\n skillId: SkillId,\n contentHash: string,\n source?: string,\n): Promise<void> {\n const metadataPath = path.join(destPath, STANDARD_FILES.METADATA_YAML);\n const rawContent = await readFile(metadataPath);\n\n const lines = rawContent.split(\"\\n\");\n let yamlContent = rawContent;\n\n if (lines[0]?.startsWith(\"# yaml-language-server:\")) {\n yamlContent = lines.slice(1).join(\"\\n\");\n }\n\n const parseResult = localSkillMetadataSchema.safeParse(parseYaml(yamlContent));\n if (!parseResult.success) {\n warn(`Malformed metadata.yaml at '${metadataPath}' — existing fields may be lost`);\n }\n const metadata: LocalSkillMetadata = parseResult.success\n ? (parseResult.data as LocalSkillMetadata)\n : { forkedFrom: undefined };\n\n metadata.forkedFrom = {\n skillId: skillId,\n contentHash: contentHash,\n date: getCurrentDate(),\n ...(source ? { source } : {}),\n };\n\n const schemaComment = `${yamlSchemaComment(SCHEMA_PATHS.metadata)}\\n`;\n const newYamlContent = stringifyYaml(metadata, { lineWidth: YAML_FORMATTING.LINE_WIDTH_NONE });\n await writeFile(metadataPath, `${schemaComment}${newYamlContent}`);\n}\n","import { createHash } from \"crypto\";\nimport path from \"path\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport { readFile, readFileSafe, writeFile, glob, fileExists } from \"../utils/fs\";\nimport { warn } from \"../utils/logger\";\nimport {\n DEFAULT_VERSION,\n MAX_PLUGIN_FILE_SIZE,\n STANDARD_FILES,\n HASH_PREFIX_LENGTH,\n} from \"../consts\";\nimport { pluginManifestSchema } from \"./schemas\";\nimport { SKILL_CONTENT_FILES, SKILL_CONTENT_DIRS } from \"./metadata-keys\";\n\nexport function getCurrentDate(): string {\n return new Date().toISOString().split(\"T\")[0];\n}\n\nexport function computeStringHash(content: string): string {\n const hash = createHash(\"sha256\");\n hash.update(content);\n return hash.digest(\"hex\").slice(0, HASH_PREFIX_LENGTH);\n}\n\nexport async function computeFileHash(filePath: string): Promise<string> {\n const content = await readFile(filePath);\n return computeStringHash(content);\n}\n\nexport async function computeSkillFolderHash(skillPath: string): Promise<string> {\n const contents: string[] = [];\n\n for (const fileName of SKILL_CONTENT_FILES) {\n const filePath = path.join(skillPath, fileName);\n if (await fileExists(filePath)) {\n const content = await readFile(filePath);\n contents.push(`${fileName}:${content}`);\n }\n }\n\n for (const dirName of SKILL_CONTENT_DIRS) {\n const dirPath = path.join(skillPath, dirName);\n if (await fileExists(dirPath)) {\n const files = await glob(\"**/*\", dirPath);\n for (const file of files.sort()) {\n const filePath = path.join(dirPath, file);\n const content = await readFile(filePath);\n contents.push(`${dirName}/${file}:${content}`);\n }\n }\n }\n\n const combined = contents.join(\"\\n---\\n\");\n return computeStringHash(combined);\n}\n\n/**\n * Plugin versioning utilities shared by skill, agent, and stack plugin compilers.\n * Reads existing plugin.json + .content-hash, bumps semver major on content change.\n */\n\nconst CONTENT_HASH_FILE = \".content-hash\";\n\nfunction parseMajorVersion(version: string): number {\n const match = version.match(/^(\\d+)\\./);\n return match ? parseInt(match[1], 10) : 1;\n}\n\nfunction bumpMajorVersion(version: string): string {\n const major = parseMajorVersion(version);\n return `${major + 1}.0.0`;\n}\n\nasync function readExistingPluginManifest(\n pluginDir: string,\n getManifestPath: (dir: string) => string,\n): Promise<{ version: string; contentHash: string | undefined } | null> {\n const manifestPath = getManifestPath(pluginDir);\n\n if (!(await fileExists(manifestPath))) {\n return null;\n }\n\n try {\n const content = await readFileSafe(manifestPath, MAX_PLUGIN_FILE_SIZE);\n const manifest = pluginManifestSchema.parse(JSON.parse(content));\n\n const hashFilePath = manifestPath.replace(STANDARD_FILES.PLUGIN_JSON, CONTENT_HASH_FILE);\n let contentHash: string | undefined;\n if (await fileExists(hashFilePath)) {\n contentHash = (await readFile(hashFilePath)).trim();\n }\n\n return {\n version: manifest.version ?? DEFAULT_VERSION,\n contentHash,\n };\n } catch (error) {\n warn(`Failed to read plugin manifest at '${manifestPath}': ${getErrorMessage(error)}`);\n return null;\n }\n}\n\nexport async function determinePluginVersion(\n newHash: string,\n pluginDir: string,\n getManifestPath: (dir: string) => string,\n): Promise<{ version: string; contentHash: string }> {\n const existing = await readExistingPluginManifest(pluginDir, getManifestPath);\n\n if (!existing) {\n return {\n version: DEFAULT_VERSION,\n contentHash: newHash,\n };\n }\n\n if (existing.contentHash !== newHash) {\n return {\n version: bumpMajorVersion(existing.version),\n contentHash: newHash,\n };\n }\n\n return {\n version: existing.version,\n contentHash: newHash,\n };\n}\n\nexport async function writeContentHash(\n pluginDir: string,\n contentHash: string,\n getManifestPath: (dir: string) => string,\n): Promise<void> {\n const hashFilePath = getManifestPath(pluginDir).replace(\n STANDARD_FILES.PLUGIN_JSON,\n CONTENT_HASH_FILE,\n );\n await writeFile(hashFilePath, contentHash);\n}\n","import path from \"path\";\n\nimport { copy, ensureDir } from \"../../utils/fs\";\nimport { computeFileHash } from \"../versioning\";\nimport { STANDARD_FILES } from \"../../consts\";\nimport type { MergedSkillsMatrix, ResolvedSkill, SkillId } from \"../../types\";\nimport type { SourceLoadResult } from \"../loading\";\nimport { getSkillById } from \"../matrix/matrix-provider\";\nimport { injectForkedFromMetadata } from \"./skill-metadata\";\n\nexport type CopiedSkill = {\n skillId: SkillId;\n contentHash: string;\n sourcePath: string;\n destPath: string;\n local?: boolean;\n};\n\nconst NULL_BYTE_PATTERN = /\\0/;\n\n/**\n * Validate that a resolved path stays within the expected parent directory.\n * Prevents path traversal attacks where skill.path contains sequences like \"../../sensitive\".\n */\nexport function validateSkillPath(\n resolvedPath: string,\n expectedParent: string,\n skillPath: string,\n): void {\n if (NULL_BYTE_PATTERN.test(skillPath)) {\n throw new Error(`Invalid skill path: '${skillPath}' contains null bytes`);\n }\n\n const normalizedResolved = path.resolve(resolvedPath);\n const normalizedParent = path.resolve(expectedParent);\n\n if (\n !normalizedResolved.startsWith(normalizedParent + path.sep) &&\n normalizedResolved !== normalizedParent\n ) {\n throw new Error(\n `Invalid skill path: '${skillPath}' escapes expected directory '${normalizedParent}'`,\n );\n }\n}\n\n/**\n * Join basePath + skillPath, validate the result stays within basePath,\n * and return the resolved path. Combines path.join + validateSkillPath\n * to eliminate repeated join-then-validate boilerplate.\n */\nfunction resolveSkillPath(basePath: string, skillPath: string): string {\n const resolved = path.join(basePath, skillPath);\n validateSkillPath(resolved, basePath, skillPath);\n return resolved;\n}\n\nfunction getSkillSourcePath(skill: ResolvedSkill, registryRoot: string): string {\n const srcDir = path.join(registryRoot, \"src\");\n return resolveSkillPath(srcDir, skill.path);\n}\n\nfunction getSkillDestPath(skill: ResolvedSkill, stackDir: string): string {\n const skillRelativePath = skill.path.replace(/^skills\\//, \"\");\n const skillsDir = path.join(stackDir, \"skills\");\n return resolveSkillPath(skillsDir, skillRelativePath);\n}\n\nasync function generateSkillHash(skillSourcePath: string): Promise<string> {\n const skillMdPath = path.join(skillSourcePath, STANDARD_FILES.SKILL_MD);\n return computeFileHash(skillMdPath);\n}\n\nexport async function copySkill(\n skill: ResolvedSkill,\n stackDir: string,\n registryRoot: string,\n source?: string,\n): Promise<CopiedSkill> {\n const sourcePath = getSkillSourcePath(skill, registryRoot);\n const destPath = getSkillDestPath(skill, stackDir);\n\n const contentHash = await generateSkillHash(sourcePath);\n\n await ensureDir(path.dirname(destPath));\n await copy(sourcePath, destPath);\n\n await injectForkedFromMetadata(destPath, skill.id, contentHash, source);\n\n return {\n skillId: skill.id,\n contentHash,\n sourcePath,\n destPath,\n };\n}\n\nfunction getSkillSourcePathFromSource(\n skill: ResolvedSkill,\n sourceResult: SourceLoadResult,\n): string {\n const srcDir = path.join(sourceResult.sourcePath, \"src\");\n return resolveSkillPath(srcDir, skill.path);\n}\n\nexport async function copySkillFromSource(\n skill: ResolvedSkill,\n stackDir: string,\n sourceResult: SourceLoadResult,\n): Promise<CopiedSkill> {\n const sourcePath = getSkillSourcePathFromSource(skill, sourceResult);\n const destPath = getSkillDestPath(skill, stackDir);\n\n const contentHash = await generateSkillHash(sourcePath);\n\n await ensureDir(path.dirname(destPath));\n await copy(sourcePath, destPath);\n\n await injectForkedFromMetadata(destPath, skill.id, contentHash, sourceResult.sourceConfig.source);\n\n return {\n skillId: skill.id,\n contentHash,\n sourcePath,\n destPath,\n };\n}\n\nexport type CopyProgressCallback = (completed: number, total: number) => void;\n\nexport async function copySkillsToPluginFromSource(\n selectedSkillIds: SkillId[],\n pluginDir: string,\n matrix: MergedSkillsMatrix,\n sourceResult: SourceLoadResult,\n sourceSelections?: Partial<Record<SkillId, string>>,\n onProgress?: CopyProgressCallback,\n): Promise<CopiedSkill[]> {\n const total = selectedSkillIds.length;\n let completed = 0;\n const results = await Promise.all(\n selectedSkillIds.map(async (skillId): Promise<CopiedSkill> => {\n const skill = getSkillById(skillId);\n\n const selectedSource = sourceSelections?.[skillId];\n const userSelectedRemote = selectedSource && selectedSource !== \"local\";\n\n let result: CopiedSkill;\n if (skill.local && skill.localPath && !userSelectedRemote) {\n const localSkillPath = path.join(process.cwd(), skill.localPath);\n const contentHash = await generateSkillHash(localSkillPath);\n\n result = {\n skillId: skill.id,\n sourcePath: skill.localPath,\n destPath: skill.localPath,\n contentHash,\n local: true,\n };\n } else {\n result = await copySkillFromSource(skill, pluginDir, sourceResult);\n }\n\n completed++;\n onProgress?.(completed, total);\n return result;\n }),\n );\n\n return results;\n}\n\nfunction getFlattenedSkillDestPath(skill: ResolvedSkill, localSkillsDir: string): string {\n return resolveSkillPath(localSkillsDir, skill.id);\n}\n\nasync function copySkillToLocalFlattened(\n skill: ResolvedSkill,\n localSkillsDir: string,\n sourceResult: SourceLoadResult,\n): Promise<CopiedSkill> {\n const sourcePath = getSkillSourcePathFromSource(skill, sourceResult);\n const destPath = getFlattenedSkillDestPath(skill, localSkillsDir);\n\n const contentHash = await generateSkillHash(sourcePath);\n\n await ensureDir(path.dirname(destPath));\n await copy(sourcePath, destPath);\n\n await injectForkedFromMetadata(destPath, skill.id, contentHash, sourceResult.sourceConfig.source);\n\n return {\n skillId: skill.id,\n contentHash,\n sourcePath,\n destPath,\n };\n}\n\nexport async function copySkillsToLocalFlattened(\n selectedSkillIds: SkillId[],\n localSkillsDir: string,\n matrix: MergedSkillsMatrix,\n sourceResult: SourceLoadResult,\n sourceSelections?: Partial<Record<SkillId, string>>,\n): Promise<CopiedSkill[]> {\n const results = await Promise.all(\n selectedSkillIds.map(async (skillId): Promise<CopiedSkill> => {\n const skill = getSkillById(skillId);\n\n const selectedSource = sourceSelections?.[skillId];\n const userSelectedRemote = selectedSource && selectedSource !== \"local\";\n\n if (skill.local && skill.localPath && !userSelectedRemote) {\n const localSkillPath = path.join(process.cwd(), skill.localPath);\n const contentHash = await generateSkillHash(localSkillPath);\n\n return {\n skillId: skill.id,\n sourcePath: skill.localPath,\n destPath: skill.localPath,\n contentHash,\n local: true,\n };\n }\n\n return copySkillToLocalFlattened(skill, localSkillsDir, sourceResult);\n }),\n );\n\n return results;\n}\n","import path from \"path\";\nimport { parse as parseYaml } from \"yaml\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { readFile, writeFile, ensureDir, glob, fileExists, copy } from \"../../utils/fs\";\nimport { log, verbose, warn } from \"../../utils/logger\";\nimport {\n generateSkillPluginManifest,\n writePluginManifest,\n getPluginManifestPath,\n} from \"../plugins\";\nimport { parseFrontmatter } from \"../loading\";\nimport { computeSkillFolderHash, determinePluginVersion, writeContentHash } from \"../versioning\";\nimport type { PluginManifest, SkillFrontmatter } from \"../../types\";\nimport { formatZodErrors, skillMetadataLoaderSchema } from \"../schemas\";\nimport type { z } from \"zod\";\n\ntype SkillMetadata = z.infer<typeof skillMetadataLoaderSchema>;\nimport { DEFAULT_BRANDING, STANDARD_FILES } from \"../../consts\";\nimport { SKILL_CONTENT_FILES, SKILL_CONTENT_DIRS } from \"../metadata-keys\";\n\nexport type SkillPluginOptions = {\n skillPath: string;\n outputDir: string;\n skillName?: string;\n};\n\nexport type CompiledSkillPlugin = {\n pluginPath: string;\n manifest: PluginManifest;\n skillName: string;\n};\n\nfunction sanitizeSkillName(name: string): string {\n return name.replace(/\\+/g, \"-\");\n}\n\nasync function readSkillMetadata(skillPath: string): Promise<SkillMetadata | null> {\n const metadataPath = path.join(skillPath, STANDARD_FILES.METADATA_YAML);\n\n if (!(await fileExists(metadataPath))) {\n return null;\n }\n\n try {\n const content = await readFile(metadataPath);\n const lines = content.split(\"\\n\");\n const yamlContent = lines[0]?.startsWith(\"# yaml-language-server:\")\n ? lines.slice(1).join(\"\\n\")\n : content;\n\n const result = skillMetadataLoaderSchema.safeParse(parseYaml(yamlContent));\n if (!result.success) {\n warn(`Invalid metadata.yaml at '${skillPath}': ${formatZodErrors(result.error.issues)}`);\n return null;\n }\n return result.data;\n } catch (error) {\n warn(`Failed to read metadata.yaml at '${skillPath}': ${error}`);\n return null;\n }\n}\n\nfunction generateReadme(\n skillName: string,\n frontmatter: SkillFrontmatter,\n metadata: SkillMetadata | null,\n): string {\n const lines: string[] = [];\n\n lines.push(`# ${skillName}`);\n lines.push(\"\");\n lines.push(frontmatter.description);\n lines.push(\"\");\n\n if (metadata?.tags && metadata.tags.length > 0) {\n lines.push(\"## Tags\");\n lines.push(\"\");\n lines.push(metadata.tags.map((t) => `\\`${t}\\``).join(\" \"));\n lines.push(\"\");\n }\n\n lines.push(\"## Installation\");\n lines.push(\"\");\n lines.push(\"Add this plugin to your Claude Code configuration:\");\n lines.push(\"\");\n lines.push(\"```json\");\n lines.push(\"{\");\n lines.push(` \"plugins\": [\"${skillName}\"]`);\n lines.push(\"}\");\n lines.push(\"```\");\n lines.push(\"\");\n\n lines.push(\"## Usage\");\n lines.push(\"\");\n lines.push(\"This skill is automatically available when installed.\");\n lines.push(\"\");\n\n lines.push(\"---\");\n lines.push(\"\");\n lines.push(`*Generated by ${DEFAULT_BRANDING.NAME} skill-plugin-compiler*`);\n lines.push(\"\");\n\n return lines.join(\"\\n\");\n}\n\nexport async function compileSkillPlugin(\n options: SkillPluginOptions,\n): Promise<CompiledSkillPlugin> {\n const { skillPath, outputDir, skillName: overrideName } = options;\n\n const dirBasename = path.basename(skillPath);\n\n const skillMdPath = path.join(skillPath, STANDARD_FILES.SKILL_MD);\n if (!(await fileExists(skillMdPath))) {\n throw new Error(\n `Skill '${dirBasename}' is missing required ${STANDARD_FILES.SKILL_MD} file. Expected at: ${skillMdPath}`,\n );\n }\n\n const skillMdContent = await readFile(skillMdPath);\n const frontmatter = parseFrontmatter(skillMdContent, skillMdPath);\n\n if (!frontmatter) {\n throw new Error(\n `Skill '${dirBasename}' has invalid or missing YAML frontmatter in ${STANDARD_FILES.SKILL_MD}. ` +\n `Required fields: 'name' and 'description'. File: ${skillMdPath}`,\n );\n }\n\n const skillName = overrideName ?? sanitizeSkillName(frontmatter.name);\n\n verbose(`Compiling skill plugin: ${skillName} from ${skillPath}`);\n\n const metadata = await readSkillMetadata(skillPath);\n\n const pluginDir = path.join(outputDir, skillName);\n const skillsDir = path.join(pluginDir, \"skills\", skillName);\n\n await ensureDir(pluginDir);\n await ensureDir(skillsDir);\n\n const newHash = await computeSkillFolderHash(skillPath);\n\n const { version, contentHash } = await determinePluginVersion(\n newHash,\n pluginDir,\n getPluginManifestPath,\n );\n\n const manifest = generateSkillPluginManifest({\n skillName,\n description: frontmatter.description,\n author: metadata?.author,\n version,\n keywords: metadata?.tags,\n });\n\n await writePluginManifest(pluginDir, manifest);\n\n await writeContentHash(pluginDir, contentHash, getPluginManifestPath);\n\n verbose(` Wrote plugin.json for ${skillName} (v${version})`);\n\n await writeFile(path.join(skillsDir, STANDARD_FILES.SKILL_MD), skillMdContent);\n verbose(` Copied ${STANDARD_FILES.SKILL_MD}`);\n\n for (const fileName of SKILL_CONTENT_FILES) {\n if (fileName === STANDARD_FILES.SKILL_MD) continue;\n\n const sourcePath = path.join(skillPath, fileName);\n if (await fileExists(sourcePath)) {\n const content = await readFile(sourcePath);\n await writeFile(path.join(skillsDir, fileName), content);\n verbose(` Copied ${fileName}`);\n }\n }\n\n for (const dirName of SKILL_CONTENT_DIRS) {\n const sourceDir = path.join(skillPath, dirName);\n if (await fileExists(sourceDir)) {\n await copy(sourceDir, path.join(skillsDir, dirName));\n verbose(` Copied ${dirName}/`);\n }\n }\n\n const readme = generateReadme(skillName, frontmatter, metadata);\n await writeFile(path.join(pluginDir, \"README.md\"), readme);\n verbose(\" Generated README.md\");\n\n return {\n pluginPath: pluginDir,\n manifest,\n skillName,\n };\n}\n\nexport async function compileAllSkillPlugins(\n skillsDir: string,\n outputDir: string,\n): Promise<CompiledSkillPlugin[]> {\n const results: CompiledSkillPlugin[] = [];\n\n const skillMdFiles = await glob(`**/${STANDARD_FILES.SKILL_MD}`, skillsDir);\n\n for (const skillMdFile of skillMdFiles) {\n const skillPath = path.join(skillsDir, path.dirname(skillMdFile));\n\n try {\n const result = await compileSkillPlugin({\n skillPath,\n outputDir,\n });\n results.push(result);\n log(` [OK] ${result.skillName}`);\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n const dirBasename = path.basename(skillPath);\n warn(`Failed to compile skill from '${dirBasename}': ${errorMessage}`);\n }\n }\n\n return results;\n}\n\nexport function printCompilationSummary(results: CompiledSkillPlugin[]): void {\n log(`\\nCompiled ${results.length} skill plugins:`);\n for (const result of results) {\n log(` - ${result.skillName} (v${result.manifest.version})`);\n }\n}\n","import path from \"path\";\n\nimport { copy, ensureDir, remove } from \"../../utils/fs\";\nimport { verbose, warn } from \"../../utils/logger\";\nimport { GLOBAL_INSTALL_ROOT, LOCAL_SKILLS_PATH } from \"../../consts\";\nimport { SKILL_ID_PATTERN } from \"../schemas\";\nimport type { SkillId } from \"../../types\";\n\n/**\n * Validates a skill ID is safe for use in filesystem paths.\n * Checks format, traversal sequences, and null bytes at runtime\n * since TypeScript template literal types don't prevent malformed data from YAML/JSON.\n */\nfunction validateSkillId(skillId: SkillId): boolean {\n if (!SKILL_ID_PATTERN.test(skillId)) {\n return false;\n }\n // Block null bytes and path traversal sequences\n return !(\n skillId.includes(\"\\0\") ||\n skillId.includes(\"..\") ||\n skillId.includes(\"/\") ||\n skillId.includes(\"\\\\\")\n );\n}\n\n/**\n * Validates a resolved path stays within the expected parent directory.\n * Prevents path traversal attacks where crafted input escapes the skills directory.\n */\nfunction validatePathBoundary(resolvedPath: string, expectedParent: string): boolean {\n const normalizedPath = path.resolve(resolvedPath);\n const normalizedParent = path.resolve(expectedParent);\n return normalizedPath.startsWith(normalizedParent + path.sep);\n}\n\n/**\n * Delete a local skill directory at .claude/skills/{skill-id}/\n */\nexport async function deleteLocalSkill(projectDir: string, skillId: SkillId): Promise<void> {\n if (!validateSkillId(skillId)) {\n warn(`Invalid skill ID for deletion: '${skillId}'`);\n return;\n }\n\n const skillPath = path.resolve(path.join(projectDir, LOCAL_SKILLS_PATH, skillId));\n const skillsDir = path.resolve(path.join(projectDir, LOCAL_SKILLS_PATH));\n\n if (!validatePathBoundary(skillPath, skillsDir)) {\n warn(`Skill ID '${skillId}' resolves outside the skills directory.`);\n return;\n }\n\n try {\n await remove(skillPath);\n } catch {\n // Skill may not exist — silently ignore\n }\n\n verbose(`Deleted local skill '${skillId}'`);\n}\n\n/**\n * Migrate a local skill's files between project and global directories.\n * Used when a skill's scope changes during edit (e.g., [P] → [G] or [G] → [P]).\n *\n * Copies the skill directory to the new location, then removes the old one.\n * No-op if the source directory doesn't exist (skill may be plugin-mode).\n */\nexport async function migrateLocalSkillScope(\n skillId: SkillId,\n fromScope: \"project\" | \"global\",\n projectDir: string,\n): Promise<void> {\n if (!validateSkillId(skillId)) {\n warn(`Invalid skill ID for scope migration: '${skillId}'`);\n return;\n }\n\n const fromBaseDir = fromScope === \"global\" ? GLOBAL_INSTALL_ROOT : projectDir;\n const toBaseDir = fromScope === \"global\" ? projectDir : GLOBAL_INSTALL_ROOT;\n\n const fromPath = path.resolve(path.join(fromBaseDir, LOCAL_SKILLS_PATH, skillId));\n const toPath = path.resolve(path.join(toBaseDir, LOCAL_SKILLS_PATH, skillId));\n\n const fromSkillsDir = path.resolve(path.join(fromBaseDir, LOCAL_SKILLS_PATH));\n const toSkillsDir = path.resolve(path.join(toBaseDir, LOCAL_SKILLS_PATH));\n\n if (!validatePathBoundary(fromPath, fromSkillsDir)) {\n warn(`Skill ID '${skillId}' resolves outside the source skills directory.`);\n return;\n }\n if (!validatePathBoundary(toPath, toSkillsDir)) {\n warn(`Skill ID '${skillId}' resolves outside the destination skills directory.`);\n return;\n }\n\n try {\n await ensureDir(toSkillsDir);\n await copy(fromPath, toPath);\n await remove(fromPath);\n verbose(\n `Migrated skill '${skillId}' from ${fromScope} to ${fromScope === \"global\" ? \"project\" : \"global\"}`,\n );\n } catch {\n warn(`Could not migrate skill '${skillId}' — source directory may not exist`);\n }\n}\n","export {\n loadStacks,\n loadStackById,\n resolveAgentConfigToSkills,\n getStackSkillIds,\n resolveStackSkills,\n} from \"./stacks-loader\";\n\nexport {\n type StackInstallOptions,\n type StackInstallResult,\n compileStackToTemp,\n installStackAsPlugin,\n} from \"./stack-installer\";\n\nexport {\n type StackPluginOptions,\n type CompiledStackPlugin,\n compileAgentForPlugin,\n compileStackPlugin,\n printStackCompilationSummary,\n} from \"./stack-plugin-compiler\";\n","import path from \"path\";\nimport { Liquid } from \"liquidjs\";\nimport {\n readFile,\n readFileOptional,\n writeFile,\n ensureDir,\n copy,\n fileExists,\n directoryExists,\n} from \"../../utils/fs\";\nimport { log, verbose } from \"../../utils/logger\";\nimport { DEFAULT_BRANDING, DIRS, PROJECT_ROOT, STANDARD_FILES } from \"../../consts\";\nimport { createLiquidEngine, sanitizeCompiledAgentData } from \"../compiler\";\nimport {\n generateStackPluginManifest,\n writePluginManifest,\n getPluginManifestPath,\n} from \"../plugins\";\nimport { loadSkillsByIds, loadAllAgents } from \"../loading\";\nimport { loadStackById, resolveAgentConfigToSkills, getStackSkillIds } from \"./stacks-loader\";\nimport { resolveAgents, convertStackToCompileConfig } from \"../resolver\";\nimport { buildStackProperty } from \"../configuration\";\nimport type {\n AgentConfig,\n AgentDefinition,\n AgentName,\n CompileConfig,\n CompiledAgentData,\n PluginManifest,\n ProjectConfig,\n SkillId,\n Stack,\n} from \"../../types\";\nimport type { InstallMode } from \"../installation/installation\";\nimport { computeStringHash, determinePluginVersion, writeContentHash } from \"../versioning\";\nimport { unique } from \"remeda\";\nimport { typedEntries, typedKeys } from \"../../utils/typed-object\";\n\nfunction hashStackConfig(stack: ProjectConfig): string {\n const stackSkillIds = stack.stack ? getStackSkillIds(stack.stack).sort() : [];\n const parts: string[] = [\n `name:${stack.name}`,\n `description:${stack.description ?? \"\"}`,\n `skills:${stackSkillIds.join(\",\")}`,\n `agents:${stack.agents\n .map((a) => a.name)\n .sort()\n .join(\",\")}`,\n ];\n return computeStringHash(parts.join(\"\\n\"));\n}\n\nexport type StackPluginOptions = {\n stackId: string;\n outputDir: string;\n projectRoot: string;\n agentSourcePath?: string;\n /** Optional stack configuration - if provided, bypasses loading from config/stacks.ts */\n stack?: Stack;\n};\n\nexport type CompiledStackPlugin = {\n pluginPath: string;\n manifest: PluginManifest;\n stackName: string;\n agents: AgentName[];\n skillPlugins: SkillId[];\n hasHooks: boolean;\n};\n\nexport async function compileAgentForPlugin(\n name: AgentName,\n agent: AgentConfig,\n fallbackRoot: string,\n engine: Liquid,\n installMode?: InstallMode,\n): Promise<string> {\n verbose(`Compiling agent: ${name}`);\n\n // Use agent's sourceRoot if available (for multi-source loading), otherwise fallback\n const agentSourceRoot = agent.sourceRoot || fallbackRoot;\n // Use agent's agentBaseDir if available (for project agents in .claude-src/agents/)\n const agentBaseDir = agent.agentBaseDir || DIRS.agents;\n const agentDir = path.join(agentSourceRoot, agentBaseDir, agent.path || name);\n\n const intro = await readFile(path.join(agentDir, STANDARD_FILES.INTRO_MD));\n const workflow = await readFile(path.join(agentDir, STANDARD_FILES.WORKFLOW_MD));\n const examples = await readFileOptional(\n path.join(agentDir, STANDARD_FILES.EXAMPLES_MD),\n \"## Examples\\n\\n_No examples defined._\",\n );\n const criticalRequirementsTop = await readFileOptional(\n path.join(agentDir, STANDARD_FILES.CRITICAL_REQUIREMENTS_MD),\n \"\",\n );\n const criticalReminders = await readFileOptional(\n path.join(agentDir, STANDARD_FILES.CRITICAL_REMINDERS_MD),\n \"\",\n );\n\n const agentPath = agent.path || name;\n const category = agentPath.split(\"/\")[0];\n const categoryDir = path.join(agentSourceRoot, agentBaseDir, category);\n\n let outputFormat = await readFileOptional(\n path.join(agentDir, STANDARD_FILES.OUTPUT_FORMAT_MD),\n \"\",\n );\n if (!outputFormat) {\n outputFormat = await readFileOptional(\n path.join(categoryDir, STANDARD_FILES.OUTPUT_FORMAT_MD),\n \"\",\n );\n }\n\n // In plugin mode, skills are installed as individual plugins — use pluginRef format.\n // Create new skill objects to avoid mutating the caller's data.\n const skills =\n installMode === \"plugin\"\n ? agent.skills.map((s) => ({ ...s, pluginRef: `${s.id}:${s.id}` as const }))\n : agent.skills;\n\n const preloadedSkills = skills.filter((s) => s.preloaded);\n const dynamicSkills = skills.filter((s) => !s.preloaded);\n const preloadedSkillIds = preloadedSkills.map((s) => s.pluginRef ?? s.id);\n\n verbose(\n `Skills for ${name}: ${preloadedSkills.length} preloaded, ${dynamicSkills.length} dynamic`,\n );\n\n const data: CompiledAgentData = {\n agent,\n intro,\n workflow,\n examples,\n criticalRequirementsTop,\n criticalReminders,\n outputFormat,\n skills,\n preloadedSkills,\n dynamicSkills,\n preloadedSkillIds,\n };\n\n return engine.renderFile(\"agent\", sanitizeCompiledAgentData(data));\n}\n\nfunction generateStackReadme(\n stackId: string,\n stack: ProjectConfig,\n agents: AgentName[],\n skillPlugins: SkillId[],\n): string {\n const lines: string[] = [];\n\n lines.push(`# ${stack.name}`);\n lines.push(\"\");\n lines.push(stack.description || \"A Claude Code stack plugin.\");\n lines.push(\"\");\n\n lines.push(\"## Installation\");\n lines.push(\"\");\n lines.push(\"Add this plugin to your Claude Code configuration:\");\n lines.push(\"\");\n lines.push(\"```json\");\n lines.push(\"{\");\n lines.push(` \"plugins\": [\"${stackId}\"]`);\n lines.push(\"}\");\n lines.push(\"```\");\n lines.push(\"\");\n\n lines.push(\"## Agents\");\n lines.push(\"\");\n lines.push(\"This stack includes the following agents:\");\n lines.push(\"\");\n for (const agent of agents) {\n lines.push(`- \\`${agent}\\``);\n }\n lines.push(\"\");\n\n if (skillPlugins.length > 0) {\n lines.push(\"## Included Skills\");\n lines.push(\"\");\n lines.push(\"This stack includes the following skills:\");\n lines.push(\"\");\n const uniqueSkills = unique(skillPlugins).sort();\n for (const skill of uniqueSkills) {\n lines.push(`- \\`${skill}\\``);\n }\n lines.push(\"\");\n }\n\n lines.push(\"---\");\n lines.push(\"\");\n lines.push(`*Generated by ${DEFAULT_BRANDING.NAME} stack-plugin-compiler*`);\n lines.push(\"\");\n\n return lines.join(\"\\n\");\n}\n\nexport async function compileStackPlugin(\n options: StackPluginOptions,\n): Promise<CompiledStackPlugin> {\n const { stackId, outputDir, projectRoot, agentSourcePath } = options;\n const localAgentRoot = agentSourcePath || projectRoot;\n\n verbose(`Compiling stack plugin: ${stackId}`);\n verbose(` Stack/skills source: ${projectRoot}`);\n verbose(` Local agent source: ${localAgentRoot}`);\n verbose(` CLI agent source: ${PROJECT_ROOT}`);\n\n const cliAgents = await loadAllAgents(PROJECT_ROOT);\n const localAgents = await loadAllAgents(localAgentRoot);\n const agents: Record<AgentName, AgentDefinition> = { ...cliAgents, ...localAgents };\n\n verbose(\n ` Loaded ${Object.keys(localAgents).length} local agents, ${Object.keys(cliAgents).length} CLI agents`,\n );\n\n const newStack = options.stack || (await loadStackById(stackId, projectRoot));\n\n let stack: ProjectConfig;\n if (newStack) {\n verbose(` Found stack: ${newStack.name}`);\n\n const agentSkillIds = new Set<SkillId>();\n for (const agentName of typedKeys<AgentName>(newStack.agents)) {\n const agentConfig = newStack.agents[agentName];\n if (!agentConfig) continue;\n const skillRefs = resolveAgentConfigToSkills(agentConfig);\n for (const ref of skillRefs) {\n agentSkillIds.add(ref.id);\n }\n }\n\n stack = {\n name: newStack.name,\n description: newStack.description,\n agents: typedKeys<AgentName>(newStack.agents).map((name) => ({\n name,\n scope: \"project\" as const,\n })),\n skills: [...agentSkillIds].map((id) => ({ id, scope: \"project\" as const, source: \"local\" })),\n // Structural cast: Partial<Record<AgentName, V>> to Record<string, V> (no undefined values in practice)\n stack: buildStackProperty(newStack) as ProjectConfig[\"stack\"],\n };\n } else {\n throw new Error(`Stack '${stackId}' not found in config/stacks.ts`);\n }\n\n const stackSkillIds = stack.stack ? getStackSkillIds(stack.stack) : [];\n const skills = await loadSkillsByIds(\n stackSkillIds.map((id) => ({ id })),\n projectRoot,\n );\n\n const compileConfig: CompileConfig = convertStackToCompileConfig(stackId, stack);\n\n const resolvedAgents = await resolveAgents(agents, skills, compileConfig, projectRoot, newStack);\n\n const pluginDir = path.join(outputDir, stackId);\n const agentsDir = path.join(pluginDir, \"agents\");\n\n await ensureDir(pluginDir);\n await ensureDir(agentsDir);\n\n const pluginSkillsDir = path.join(pluginDir, \"skills\");\n await ensureDir(pluginSkillsDir);\n\n const copiedSourcePaths = new Set<string>();\n\n for (const resolvedSkill of Object.values(skills)) {\n const sourceSkillDir = path.join(projectRoot, resolvedSkill.path);\n\n if (copiedSourcePaths.has(resolvedSkill.path)) {\n continue;\n }\n\n const destSkillDir = path.join(pluginSkillsDir, resolvedSkill.id);\n\n if (await directoryExists(sourceSkillDir)) {\n await copy(sourceSkillDir, destSkillDir);\n copiedSourcePaths.add(resolvedSkill.path);\n verbose(` Copied skill: ${resolvedSkill.id}`);\n } else {\n verbose(` Warning: Skill directory not found: ${sourceSkillDir}`);\n }\n }\n\n const engine = await createLiquidEngine();\n\n const compiledAgentNames: AgentName[] = [];\n const allSkillPlugins: SkillId[] = [];\n\n for (const [name, agent] of typedEntries<AgentName, AgentConfig>(resolvedAgents)) {\n const output = await compileAgentForPlugin(name, agent, PROJECT_ROOT, engine);\n await writeFile(path.join(agentsDir, `${name}.md`), output);\n compiledAgentNames.push(name);\n\n for (const skill of agent.skills) {\n allSkillPlugins.push(skill.id);\n }\n\n verbose(` Compiled agent: ${name}`);\n }\n\n const stackDir = path.join(projectRoot, DIRS.stacks, stackId);\n const claudeMdPath = path.join(stackDir, STANDARD_FILES.CLAUDE_MD);\n if (await fileExists(claudeMdPath)) {\n const claudeContent = await readFile(claudeMdPath);\n await writeFile(path.join(pluginDir, STANDARD_FILES.CLAUDE_MD), claudeContent);\n verbose(` Copied ${STANDARD_FILES.CLAUDE_MD}`);\n }\n\n const newHash = hashStackConfig(stack);\n const { version, contentHash } = await determinePluginVersion(\n newHash,\n pluginDir,\n getPluginManifestPath,\n );\n\n const uniqueSkillPlugins = unique(allSkillPlugins);\n const manifest = generateStackPluginManifest({\n stackName: stackId,\n description: stack.description,\n author: stack.author,\n version,\n keywords: undefined,\n hasAgents: true,\n hasHooks: false,\n hasSkills: true,\n });\n\n await writePluginManifest(pluginDir, manifest);\n\n await writeContentHash(pluginDir, contentHash, getPluginManifestPath);\n\n verbose(` Wrote plugin.json (v${version})`);\n\n const readme = generateStackReadme(stackId, stack, compiledAgentNames, uniqueSkillPlugins);\n await writeFile(path.join(pluginDir, \"README.md\"), readme);\n verbose(\" Generated README.md\");\n\n return {\n pluginPath: pluginDir,\n manifest,\n stackName: stack.name,\n agents: compiledAgentNames,\n skillPlugins: uniqueSkillPlugins,\n hasHooks: false,\n };\n}\n\nexport function printStackCompilationSummary(result: CompiledStackPlugin): void {\n log(`\\nStack plugin compiled: ${result.stackName}`);\n log(` Path: ${result.pluginPath}`);\n log(` Agents: ${result.agents.length}`);\n for (const agent of result.agents) {\n log(` - ${agent}`);\n }\n if (result.skillPlugins.length > 0) {\n log(` Skills included: ${result.skillPlugins.length}`);\n for (const skill of result.skillPlugins) {\n log(` - ${skill}`);\n }\n }\n if (result.hasHooks) {\n log(\" Hooks: enabled\");\n }\n}\n","import { Liquid } from \"liquidjs\";\nimport path from \"path\";\nimport { pipe, flatMap, filter, uniqueBy } from \"remeda\";\nimport {\n readFile,\n readFileOptional,\n writeFile,\n ensureDir,\n remove,\n copy,\n glob,\n fileExists,\n directoryExists,\n} from \"../utils/fs\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport { log, verbose, warn } from \"../utils/logger\";\nimport {\n CLAUDE_DIR,\n CLAUDE_SRC_DIR,\n DIRS,\n PROJECT_ROOT,\n STANDARD_FILES,\n STANDARD_DIRS,\n} from \"../consts\";\nimport { resolveClaudeMd } from \"./resolver\";\nimport { validateCompiledAgent, printOutputValidationResult } from \"./output-validator\";\nimport type { AgentConfig, AgentName, CompiledAgentData, CompileContext, Skill } from \"../types\";\nimport { typedEntries } from \"../utils/typed-object\";\n\n/** Pattern matching Liquid template delimiters that could enable template injection */\nconst LIQUID_SYNTAX_PATTERN = /\\{\\{|\\}\\}|\\{%|%\\}/g;\n\n/**\n * Strips Liquid template syntax (`{{`, `}}`, `{%`, `%}`) from a string value.\n * Prevents template injection when user-controlled data is passed to the Liquid engine.\n *\n * @param value - Input string that may contain Liquid syntax\n * @param fieldName - Name of the field (for warning messages)\n * @returns Sanitized string with Liquid delimiters removed\n */\nexport function sanitizeLiquidSyntax<T extends string>(value: T, fieldName: string): T {\n if (!LIQUID_SYNTAX_PATTERN.test(value)) return value;\n LIQUID_SYNTAX_PATTERN.lastIndex = 0;\n const sanitized = value.replace(LIQUID_SYNTAX_PATTERN, \"\");\n warn(`Stripped Liquid template syntax from '${fieldName}' — possible template injection attempt`);\n return sanitized as T;\n}\n\nfunction sanitizeString<T extends string>(value: T | undefined, fieldName: string): T | undefined {\n if (value === undefined) return undefined;\n return sanitizeLiquidSyntax(value, fieldName);\n}\n\nfunction sanitizeStringArray(\n values: string[] | undefined,\n fieldName: string,\n): string[] | undefined {\n if (!values) return values;\n return values.map((v) => sanitizeLiquidSyntax(v, fieldName));\n}\n\nfunction sanitizeSkills(skills: Skill[]): Skill[] {\n return skills.map((s) => ({\n ...s,\n id: sanitizeLiquidSyntax(s.id, \"skill.id\"),\n description: sanitizeLiquidSyntax(s.description, \"skill.description\"),\n usage: sanitizeLiquidSyntax(s.usage, \"skill.usage\"),\n pluginRef: sanitizeString(s.pluginRef, \"skill.pluginRef\"),\n }));\n}\n\n/**\n * Sanitizes all user-controlled fields in compiled agent data to prevent\n * Liquid template injection. Strips `{{`, `}}`, `{%`, `%}` from agent\n * metadata, skill metadata, and file content before template rendering.\n */\nexport function sanitizeCompiledAgentData(data: CompiledAgentData): CompiledAgentData {\n const sanitizedAgent: AgentConfig = {\n ...data.agent,\n name: sanitizeLiquidSyntax(data.agent.name, \"agent.name\"),\n title: sanitizeLiquidSyntax(data.agent.title, \"agent.title\"),\n description: sanitizeLiquidSyntax(data.agent.description, \"agent.description\"),\n tools: sanitizeStringArray(data.agent.tools, \"agent.tools\") ?? data.agent.tools,\n disallowedTools: sanitizeStringArray(data.agent.disallowedTools, \"agent.disallowedTools\"),\n model: sanitizeString(data.agent.model, \"agent.model\"),\n permissionMode: sanitizeString(data.agent.permissionMode, \"agent.permissionMode\"),\n };\n\n const sanitizedSkills = sanitizeSkills(data.skills);\n const sanitizedPreloaded = sanitizeSkills(data.preloadedSkills);\n const sanitizedDynamic = sanitizeSkills(data.dynamicSkills);\n const sanitizedPreloadedIds = data.preloadedSkillIds.map((id) =>\n sanitizeLiquidSyntax(id, \"preloadedSkillId\"),\n );\n\n return {\n agent: sanitizedAgent,\n intro: sanitizeLiquidSyntax(data.intro, \"intro\"),\n workflow: sanitizeLiquidSyntax(data.workflow, \"workflow\"),\n examples: sanitizeLiquidSyntax(data.examples, \"examples\"),\n criticalRequirementsTop: sanitizeLiquidSyntax(\n data.criticalRequirementsTop,\n \"criticalRequirementsTop\",\n ),\n criticalReminders: sanitizeLiquidSyntax(data.criticalReminders, \"criticalReminders\"),\n outputFormat: sanitizeLiquidSyntax(data.outputFormat, \"outputFormat\"),\n skills: sanitizedSkills,\n preloadedSkills: sanitizedPreloaded,\n dynamicSkills: sanitizedDynamic,\n preloadedSkillIds: sanitizedPreloadedIds,\n };\n}\n\ntype AgentFiles = Pick<\n CompiledAgentData,\n | \"intro\"\n | \"workflow\"\n | \"examples\"\n | \"criticalRequirementsTop\"\n | \"criticalReminders\"\n | \"outputFormat\"\n>;\n\nasync function readAgentFiles(\n name: AgentName,\n agent: AgentConfig,\n projectRoot: string,\n): Promise<AgentFiles> {\n const agentSourceRoot = agent.sourceRoot || projectRoot;\n const agentBaseDir = agent.agentBaseDir || DIRS.agents;\n const agentDir = path.join(agentSourceRoot, agentBaseDir, agent.path || name);\n\n const intro = await readFile(path.join(agentDir, STANDARD_FILES.INTRO_MD));\n const workflow = await readFile(path.join(agentDir, STANDARD_FILES.WORKFLOW_MD));\n const examples = await readFileOptional(\n path.join(agentDir, STANDARD_FILES.EXAMPLES_MD),\n \"## Examples\\n\\n_No examples defined._\",\n );\n const criticalRequirementsTop = await readFileOptional(\n path.join(agentDir, STANDARD_FILES.CRITICAL_REQUIREMENTS_MD),\n \"\",\n );\n const criticalReminders = await readFileOptional(\n path.join(agentDir, STANDARD_FILES.CRITICAL_REMINDERS_MD),\n \"\",\n );\n\n const agentPath = agent.path || name;\n const parts = agentPath.split(\"/\");\n const category = parts[0] || name;\n const categoryDir = path.join(agentSourceRoot, agentBaseDir, category);\n\n let outputFormat = await readFileOptional(\n path.join(agentDir, STANDARD_FILES.OUTPUT_FORMAT_MD),\n \"\",\n );\n if (!outputFormat) {\n outputFormat = await readFileOptional(\n path.join(categoryDir, STANDARD_FILES.OUTPUT_FORMAT_MD),\n \"\",\n );\n }\n\n return { intro, workflow, examples, criticalRequirementsTop, criticalReminders, outputFormat };\n}\n\nfunction buildAgentTemplateContext(\n name: AgentName,\n agent: AgentConfig,\n files: AgentFiles,\n): CompiledAgentData {\n const preloadedSkills = agent.skills.filter((s) => s.preloaded);\n const dynamicSkills = agent.skills.filter((s) => !s.preloaded);\n const preloadedSkillIds = preloadedSkills.map((s) => s.id);\n\n verbose(\n `Skills for ${name}: ${preloadedSkills.length} preloaded, ${dynamicSkills.length} dynamic`,\n );\n\n return {\n agent,\n ...files,\n skills: agent.skills,\n preloadedSkills,\n dynamicSkills,\n preloadedSkillIds,\n };\n}\n\n/**\n * Compiles a single agent into a rendered Markdown prompt by reading its\n * constituent files (intro, workflow, examples, critical requirements/reminders,\n * output format) and rendering them through a Liquid template.\n *\n * Skills are split into preloaded (content embedded in the compiled agent) and\n * dynamic (loaded via Skill tool at runtime). Output format resolution falls back\n * from the agent-specific directory to the parent category directory.\n *\n * @param name - Agent identifier used for logging and as a directory name fallback\n * @param agent - Fully resolved agent config including skills, paths, and optional sourceRoot\n * @param projectRoot - Root directory of the project (used as base for agent file resolution)\n * @param engine - Pre-configured Liquid template engine with template roots\n * @returns Rendered Markdown string ready to be written to the output directory\n * @throws When required agent files (intro.md, workflow.md) are missing from disk\n */\nasync function compileAgent(\n name: AgentName,\n agent: AgentConfig,\n projectRoot: string,\n engine: Liquid,\n): Promise<string> {\n verbose(`Reading agent files for ${name}...`);\n const files = await readAgentFiles(name, agent, projectRoot);\n const data = buildAgentTemplateContext(name, agent, files);\n\n verbose(`Rendering template for ${name}...`);\n return engine.renderFile(\"agent\", sanitizeCompiledAgentData(data));\n}\n\n/**\n * Compiles all resolved agents into Markdown files and writes them to the output directory.\n *\n * Each agent is compiled via `compileAgent()`, validated for structural issues\n * (missing sections, placeholder text), and written to `{outputDir}/agents/{name}.md`.\n * Validation warnings are printed but do not prevent compilation.\n *\n * @param resolvedAgents - Map of agent names to fully resolved agent configs with skills\n * @param ctx - Compilation context providing projectRoot and outputDir paths\n * @param engine - Pre-configured Liquid template engine\n * @throws When any agent fails to compile (missing files, template errors)\n */\nexport async function compileAllAgents(\n resolvedAgents: Record<AgentName, AgentConfig>,\n ctx: CompileContext,\n engine: Liquid,\n): Promise<void> {\n const outDir = path.join(ctx.outputDir, \"agents\");\n await ensureDir(outDir);\n\n let hasValidationIssues = false;\n\n for (const [name, agent] of typedEntries<AgentName, AgentConfig>(resolvedAgents)) {\n try {\n const output = await compileAgent(name, agent, ctx.projectRoot, engine);\n await writeFile(path.join(outDir, `${name}.md`), output);\n log(` ✓ ${name}.md`);\n\n const validationResult = validateCompiledAgent(output);\n if (!validationResult.valid || validationResult.warnings.length > 0) {\n hasValidationIssues = true;\n printOutputValidationResult(name, validationResult);\n }\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n warn(`Failed to compile '${name}': ${errorMessage}`);\n throw new Error(\n `Failed to compile agent '${name}': ${errorMessage}. Check that all required files exist in src/agents/${agent.path || name}/`,\n );\n }\n }\n\n if (hasValidationIssues) {\n log(\"\");\n }\n}\n\n/**\n * Copies all skill files referenced by resolved agents into the output directory.\n *\n * Deduplicates skills across agents (by skill ID) and copies each skill's\n * content to `{outputDir}/skills/{id}/`. For folder-based skills, copies\n * SKILL.md, optional reference.md, examples/, and scripts/ subdirectories.\n * For single-file skills, copies the file as SKILL.md.\n *\n * @param resolvedAgents - Map of agent names to configs (skills extracted from all agents)\n * @param ctx - Compilation context providing projectRoot and outputDir paths\n * @throws When a skill file or directory is missing from the expected source path\n */\nexport async function compileAllSkills(\n resolvedAgents: Record<AgentName, AgentConfig>,\n ctx: CompileContext,\n): Promise<void> {\n const allSkills = pipe(\n Object.values(resolvedAgents),\n flatMap((a) => a.skills),\n filter((s) => Boolean(s.path)),\n );\n\n const uniqueSkills = uniqueBy(allSkills, (s) => s.id);\n\n for (const skill of uniqueSkills) {\n const id = skill.id;\n const outDir = path.join(ctx.outputDir, \"skills\", id);\n await ensureDir(outDir);\n\n const sourcePath = path.join(ctx.projectRoot, skill.path);\n const isFolder = skill.path.endsWith(\"/\");\n\n try {\n if (isFolder) {\n const mainContent = await readFile(path.join(sourcePath, STANDARD_FILES.SKILL_MD));\n await writeFile(path.join(outDir, STANDARD_FILES.SKILL_MD), mainContent);\n log(` ✓ skills/${id}/${STANDARD_FILES.SKILL_MD}`);\n\n const referenceContent = await readFileOptional(\n path.join(sourcePath, STANDARD_FILES.REFERENCE_MD),\n );\n if (referenceContent) {\n await writeFile(path.join(outDir, STANDARD_FILES.REFERENCE_MD), referenceContent);\n log(` ✓ skills/${id}/${STANDARD_FILES.REFERENCE_MD}`);\n }\n\n const examplesDir = path.join(sourcePath, STANDARD_DIRS.EXAMPLES);\n if (await fileExists(examplesDir)) {\n await copy(examplesDir, path.join(outDir, STANDARD_DIRS.EXAMPLES));\n log(` ✓ skills/${id}/${STANDARD_DIRS.EXAMPLES}/`);\n }\n\n const scriptsDir = path.join(sourcePath, STANDARD_DIRS.SCRIPTS);\n if (await fileExists(scriptsDir)) {\n await copy(scriptsDir, path.join(outDir, STANDARD_DIRS.SCRIPTS));\n log(` ✓ skills/${id}/${STANDARD_DIRS.SCRIPTS}/`);\n }\n } else {\n const content = await readFile(sourcePath);\n await writeFile(path.join(outDir, STANDARD_FILES.SKILL_MD), content);\n log(` ✓ skills/${id}/${STANDARD_FILES.SKILL_MD}`);\n }\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n warn(`Failed to compile skill '${id}': ${errorMessage}`);\n throw new Error(\n `Failed to compile skill '${skill.id}': ${errorMessage}. Expected skill at: ${sourcePath}`,\n );\n }\n }\n}\n\n/**\n * Copies the stack-specific CLAUDE.md file to the compilation output directory.\n *\n * Resolves the CLAUDE.md path from the stack directory, reads its content, and\n * writes it to the parent of the output directory (alongside the agents/ folder).\n *\n * @param ctx - Compilation context with stackId, projectRoot, and outputDir\n * @throws When the stack's CLAUDE.md file is missing\n */\nexport async function copyClaudeMdToOutput(ctx: CompileContext): Promise<void> {\n const claudePath = await resolveClaudeMd(ctx.projectRoot, ctx.stackId);\n\n const content = await readFile(claudePath);\n const outputPath = path.join(ctx.outputDir, \"..\", STANDARD_FILES.CLAUDE_MD);\n await writeFile(outputPath, content);\n log(` ✓ ${STANDARD_FILES.CLAUDE_MD} (from stack)`);\n}\n\n/**\n * Copies all custom command Markdown files from the commands source directory\n * to the compilation output directory.\n *\n * Skips gracefully if no commands directory exists or contains no .md files.\n *\n * @param ctx - Compilation context with projectRoot and outputDir\n * @throws When a command file exists but cannot be read or written\n */\nexport async function compileAllCommands(ctx: CompileContext): Promise<void> {\n const commandsDir = path.join(ctx.projectRoot, DIRS.commands);\n const outDir = path.join(ctx.outputDir, \"commands\");\n\n if (!(await fileExists(commandsDir))) {\n log(\" - No commands directory found, skipping...\");\n return;\n }\n\n const files = await glob(\"*.md\", commandsDir);\n\n if (files.length === 0) {\n log(\" - No commands found, skipping...\");\n return;\n }\n\n await ensureDir(outDir);\n\n for (const file of files) {\n try {\n const content = await readFile(path.join(commandsDir, file));\n await writeFile(path.join(outDir, file), content);\n log(` ✓ ${file}`);\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n warn(`Failed to compile command '${file}': ${errorMessage}`);\n throw new Error(\n `Failed to compile command '${file}': ${errorMessage}. Expected at: ${path.join(commandsDir, file)}`,\n );\n }\n }\n}\n\n/**\n * Creates a Liquid template engine with a layered template root hierarchy.\n *\n * Template resolution order (first match wins):\n * 1. Project-local templates: `{projectDir}/.claude-src/agents/_templates/`\n * 2. Legacy templates: `{projectDir}/.claude/templates/`\n * 3. Built-in templates: `{PROJECT_ROOT}/templates/`\n *\n * @param projectDir - Optional project directory for local template overrides\n * @returns Configured Liquid engine with `.liquid` extension and strict filters\n */\nexport async function createLiquidEngine(projectDir?: string): Promise<Liquid> {\n const roots: string[] = [];\n\n if (projectDir) {\n const srcTemplatesDir = path.join(projectDir, CLAUDE_SRC_DIR, \"agents\", \"_templates\");\n if (await directoryExists(srcTemplatesDir)) {\n roots.push(srcTemplatesDir);\n verbose(`Using local templates from: ${srcTemplatesDir}`);\n }\n\n const legacyTemplatesDir = path.join(projectDir, CLAUDE_DIR, \"templates\");\n if (await directoryExists(legacyTemplatesDir)) {\n roots.push(legacyTemplatesDir);\n verbose(`Using legacy templates from: ${legacyTemplatesDir}`);\n }\n }\n\n roots.push(path.join(PROJECT_ROOT, DIRS.templates));\n\n return new Liquid({\n root: roots,\n extname: \".liquid\",\n strictVariables: false,\n strictFilters: true,\n });\n}\n\n/** Removes the agents/, skills/, and commands/ subdirectories from the output directory. */\nexport async function removeCompiledOutputDirs(outputDir: string): Promise<void> {\n await remove(path.join(outputDir, \"agents\"));\n await remove(path.join(outputDir, \"skills\"));\n await remove(path.join(outputDir, \"commands\"));\n}\n","import path from \"path\";\nimport { fileExists } from \"../utils/fs\";\nimport { DIRS, STANDARD_FILES } from \"../consts\";\nimport { verbose } from \"../utils/logger\";\nimport type {\n AgentConfig,\n AgentDefinition,\n AgentName,\n CompileAgentConfig,\n CompileConfig,\n ProjectConfig,\n Skill,\n SkillDefinitionMap,\n SkillReference,\n Stack,\n StackAgentConfig,\n Category,\n} from \"../types\";\nimport { typedKeys } from \"../utils/typed-object\";\nimport { resolveAgentConfigToSkills } from \"./stacks/stacks-loader\";\n\nexport async function resolveClaudeMd(projectRoot: string, stackId: string): Promise<string> {\n const stackClaude = path.join(projectRoot, DIRS.stacks, stackId, STANDARD_FILES.CLAUDE_MD);\n if (await fileExists(stackClaude)) return stackClaude;\n\n throw new Error(\n `Stack '${stackId}' is missing required ${STANDARD_FILES.CLAUDE_MD} file. Expected at: ${stackClaude}`,\n );\n}\n\nexport function resolveSkillReference(\n ref: SkillReference,\n skills: SkillDefinitionMap,\n): Skill | null {\n const definition = skills[ref.id];\n if (!definition) {\n verbose(`Skill '${ref.id}' not found in available skills, skipping`);\n return null;\n }\n return {\n ...definition,\n usage: ref.usage,\n preloaded: ref.preloaded ?? false,\n };\n}\n\nexport function resolveSkillReferences(\n skillRefs: SkillReference[],\n skills: SkillDefinitionMap,\n): Skill[] {\n return skillRefs\n .map((ref) => resolveSkillReference(ref, skills))\n .filter((skill): skill is Skill => skill !== null);\n}\n\n/**\n * Builds skill references from a ProjectConfig stack mapping (agent -> category -> SkillAssignment[]).\n *\n * Values are normalized to SkillAssignment[] at load time (by normalizeStackRecord in project-config.ts).\n * Preserves preloaded flags from skill assignments.\n *\n * @param agentStack - Category-to-SkillAssignment[] mapping from ProjectConfig.stack for one agent\n * @returns Skill references with usage hints derived from category names\n */\nexport function buildSkillRefsFromConfig(agentStack: StackAgentConfig): SkillReference[] {\n return resolveAgentConfigToSkills(agentStack);\n}\n\n/**\n * Resolves skill references for an agent from a Stack definition.\n *\n * Stack values are already SkillAssignment[] normalized by loadStacks().\n * Returns an empty array if the agent is not present in the stack or has\n * no technology-specific skills configured.\n *\n * @param agentName - Agent to resolve skills for\n * @param stack - Loaded stack definition with normalized skill assignments\n * @returns Skill references with usage and preloaded flags from the stack\n */\nexport function resolveAgentSkillsFromStack(agentName: AgentName, stack: Stack): SkillReference[] {\n const agentConfig = stack.agents[agentName];\n\n if (!agentConfig) {\n verbose(`Agent '${agentName}' not found in stack '${stack.id}'`);\n return [];\n }\n\n // Empty config {} means agent has no technology-specific skills\n if (typedKeys<Category>(agentConfig).length === 0) {\n verbose(`Agent '${agentName}' has no technology config in stack '${stack.id}'`);\n return [];\n }\n\n const skillRefs = resolveAgentConfigToSkills(agentConfig);\n\n verbose(`Resolved ${skillRefs.length} skills for agent '${agentName}' from stack '${stack.id}'`);\n\n return skillRefs;\n}\n\n/**\n * Resolves skill references for an agent using a priority hierarchy.\n *\n * Priority order:\n * 1. Explicit skills defined in the agent's compile config\n * 2. Skills derived from the stack definition\n *\n * @param agentName - Agent to resolve skills for\n * @param agentConfig - Compile-time agent config (may contain explicit skills)\n * @param stack - Optional stack definition for fallback skill resolution\n * @returns Skill references from the highest-priority source, or empty array\n */\nexport async function resolveAgentSkillRefs(\n agentName: AgentName,\n agentConfig: CompileAgentConfig,\n stack?: Stack,\n): Promise<SkillReference[]> {\n // Priority 1: Explicit skills in compile config\n if (agentConfig.skills && agentConfig.skills.length > 0) {\n return agentConfig.skills;\n }\n\n // Priority 2: Stack-based skills — values are already skill IDs\n if (stack) {\n const stackSkills = resolveAgentSkillsFromStack(agentName, stack);\n if (stackSkills.length > 0) {\n verbose(`Resolved ${stackSkills.length} skills from stack for ${agentName}`);\n return stackSkills;\n }\n }\n\n return [];\n}\n\n/**\n * Resolves all agents referenced in a compile config into fully populated AgentConfigs\n * with their skill lists materialized from definitions.\n *\n * For each agent in `compileConfig.agents`, this function:\n * 1. Validates the agent exists in the scanned agent definitions\n * 2. Resolves skill references (from explicit config or stack fallback)\n * 3. Materializes skill references into full Skill objects using the skill definitions map\n * 4. Merges the agent definition with its resolved skills into an AgentConfig\n *\n * @param agents - Available agent definitions keyed by name (from scanning agent directories)\n * @param skills - Available skill definitions keyed by ID (from scanning skill directories)\n * @param compileConfig - Compilation config specifying which agents to compile and their overrides\n * @param _projectRoot - Project root directory (currently unused, reserved for future use)\n * @param stack - Optional stack definition for stack-based skill resolution\n * @returns Map of agent names to fully resolved AgentConfig objects ready for compilation\n * @throws When an agent referenced in compileConfig is not found in scanned agents\n */\nexport async function resolveAgents(\n agents: Record<AgentName, AgentDefinition>,\n skills: SkillDefinitionMap,\n compileConfig: CompileConfig,\n _projectRoot: string,\n stack?: Stack,\n): Promise<Record<AgentName, AgentConfig>> {\n const agentNames = typedKeys<AgentName>(compileConfig.agents);\n\n const entries = await Promise.all(\n agentNames.map(async (agentName) => {\n const definition = agents[agentName];\n if (!definition) {\n const availableAgents = typedKeys<AgentName>(agents);\n const agentList =\n availableAgents.length > 0\n ? `Available agents: ${availableAgents.slice(0, 5).join(\", \")}${availableAgents.length > 5 ? ` (and ${availableAgents.length - 5} more)` : \"\"}`\n : \"No agents found in scanned directories\";\n throw new Error(\n `Agent '${agentName}' referenced in compile config but not found in scanned agents. ${agentList}. Check that src/agents/${agentName}/metadata.yaml exists.`,\n );\n }\n\n const agentConfig = compileConfig.agents[agentName];\n const skillRefs = await resolveAgentSkillRefs(agentName, agentConfig, stack);\n const resolvedSkills = resolveSkillReferences(skillRefs, skills);\n\n return [\n agentName,\n {\n name: agentName,\n title: definition.title,\n description: definition.description,\n model: definition.model,\n tools: definition.tools,\n skills: resolvedSkills,\n path: definition.path,\n sourceRoot: definition.sourceRoot,\n agentBaseDir: definition.agentBaseDir,\n },\n ] as const;\n }),\n );\n\n // Structural cast: Object.fromEntries returns Record<string, V>, narrowing to typed keys\n return Object.fromEntries(entries) as Record<AgentName, AgentConfig>;\n}\n\nexport function convertStackToCompileConfig(stackId: string, stack: ProjectConfig): CompileConfig {\n return {\n name: stack.name,\n description: stack.description || \"\",\n stack: stackId,\n // Structural cast: Object.fromEntries returns Record<string, V>, narrowing to typed keys\n agents: Object.fromEntries(stack.agents.map((a) => [a.name, {}])) as Record<\n AgentName,\n CompileAgentConfig\n >,\n };\n}\n","import { parse as parseYaml } from \"yaml\";\n\nexport function extractFrontmatter(content: string): unknown | null {\n const frontmatterRegex = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/;\n const match = content.match(frontmatterRegex);\n\n if (!match || !match[1]) {\n return null;\n }\n\n try {\n return parseYaml(match[1]);\n } catch {\n return null;\n }\n}\n","import { spawn } from \"child_process\";\nimport os from \"os\";\nimport { getErrorMessage } from \"./errors\";\nimport { warn } from \"./logger\";\n\n// Argument length limits to prevent oversized CLI arguments\nconst MAX_PLUGIN_PATH_LENGTH = 1024;\nconst MAX_PLUGIN_NAME_LENGTH = 256;\nconst MAX_MARKETPLACE_SOURCE_LENGTH = 1024;\n\n// Marketplace/plugin names: alphanumeric, dashes, underscores, dots, @\nconst SAFE_NAME_PATTERN = /^[a-zA-Z0-9._@/-]+$/;\n\n// Plugin path/ref: alphanumeric, dashes, underscores, dots, slashes, @, colons (for marketplace refs like skill@marketplace)\nconst SAFE_PLUGIN_PATH_PATTERN = /^[a-zA-Z0-9._@/:~-]+$/;\n\n// eslint-disable-next-line no-control-regex\nconst CONTROL_CHAR_PATTERN = /[\\x00-\\x08\\x0E-\\x1F\\x7F]/u;\n\nfunction validatePluginPath(pluginPath: string): void {\n if (!pluginPath || pluginPath.trim().length === 0) {\n throw new Error(\"Plugin path must not be empty.\");\n }\n\n if (pluginPath.length > MAX_PLUGIN_PATH_LENGTH) {\n throw new Error(\n `Plugin path is too long (${pluginPath.length} characters, max ${MAX_PLUGIN_PATH_LENGTH}).`,\n );\n }\n\n if (CONTROL_CHAR_PATTERN.test(pluginPath)) {\n throw new Error(\"Plugin path contains invalid control characters.\");\n }\n\n if (!SAFE_PLUGIN_PATH_PATTERN.test(pluginPath)) {\n throw new Error(\n `Plugin path contains invalid characters: \"${pluginPath}\"\\n` +\n \"Plugin paths may only contain alphanumeric characters, dashes, underscores, dots, slashes, @, and colons.\",\n );\n }\n}\n\nfunction validateMarketplaceSource(source: string): void {\n if (!source || source.trim().length === 0) {\n throw new Error(\"Marketplace source must not be empty.\");\n }\n\n if (source.length > MAX_MARKETPLACE_SOURCE_LENGTH) {\n throw new Error(\n `Marketplace source is too long (${source.length} characters, max ${MAX_MARKETPLACE_SOURCE_LENGTH}).`,\n );\n }\n\n if (CONTROL_CHAR_PATTERN.test(source)) {\n throw new Error(\"Marketplace source contains invalid control characters.\");\n }\n\n if (!SAFE_PLUGIN_PATH_PATTERN.test(source)) {\n throw new Error(\n `Marketplace source contains invalid characters: \"${source}\"\\n` +\n \"Source may only contain alphanumeric characters, dashes, underscores, dots, slashes, @, and colons.\",\n );\n }\n}\n\nfunction validatePluginName(pluginName: string): void {\n if (!pluginName || pluginName.trim().length === 0) {\n throw new Error(\"Plugin name must not be empty.\");\n }\n\n if (pluginName.length > MAX_PLUGIN_NAME_LENGTH) {\n throw new Error(\n `Plugin name is too long (${pluginName.length} characters, max ${MAX_PLUGIN_NAME_LENGTH}).`,\n );\n }\n\n if (CONTROL_CHAR_PATTERN.test(pluginName)) {\n throw new Error(\"Plugin name contains invalid control characters.\");\n }\n\n if (!SAFE_NAME_PATTERN.test(pluginName)) {\n throw new Error(\n `Plugin name contains invalid characters: \"${pluginName}\"\\n` +\n \"Names may only contain alphanumeric characters, dashes, underscores, dots, @, and slashes.\",\n );\n }\n}\n\nexport type ExecResult = {\n stdout: string;\n stderr: string;\n exitCode: number;\n};\n\nexport async function execCommand(\n command: string,\n args: string[],\n options?: { cwd?: string; env?: NodeJS.ProcessEnv },\n): Promise<ExecResult> {\n return new Promise((resolve, reject) => {\n const proc = spawn(command, args, {\n cwd: options?.cwd,\n env: { ...process.env, ...options?.env },\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n proc.stdout.on(\"data\", (data) => {\n stdout += data.toString();\n });\n\n proc.stderr.on(\"data\", (data) => {\n stderr += data.toString();\n });\n\n proc.on(\"close\", (code) => {\n resolve({\n stdout,\n stderr,\n exitCode: code ?? 1,\n });\n });\n\n proc.on(\"error\", (err) => {\n reject(err);\n });\n });\n}\n\n/** User-scoped plugins run from home dir so Claude CLI only writes to ~/.claude/settings.json */\nfunction resolvePluginCwd(scope: \"project\" | \"user\", projectDir: string): string {\n return scope === \"user\" ? os.homedir() : projectDir;\n}\n\nexport async function claudePluginInstall(\n pluginPath: string,\n scope: \"project\" | \"user\",\n projectDir: string,\n): Promise<void> {\n validatePluginPath(pluginPath);\n\n const cwd = resolvePluginCwd(scope, projectDir);\n const args = [\"plugin\", \"install\", pluginPath, \"--scope\", scope];\n const result = await execCommand(\"claude\", args, { cwd });\n\n if (result.exitCode !== 0) {\n const errorMessage = result.stderr || result.stdout || \"Unknown error\";\n throw new Error(`Plugin installation failed: ${errorMessage.trim()}`);\n }\n}\n\nexport async function isClaudeCLIAvailable(): Promise<boolean> {\n try {\n const result = await execCommand(\"claude\", [\"--version\"], {});\n return result.exitCode === 0;\n } catch {\n return false;\n }\n}\n\nexport type MarketplaceInfo = {\n name: string;\n source: string;\n repo?: string;\n path?: string;\n};\n\nexport async function claudePluginMarketplaceList(): Promise<MarketplaceInfo[]> {\n try {\n const result = await execCommand(\"claude\", [\"plugin\", \"marketplace\", \"list\", \"--json\"], {});\n\n if (result.exitCode !== 0) {\n return [];\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(result.stdout);\n } catch {\n warn(\"Failed to parse marketplace list output as JSON\");\n return [];\n }\n\n if (!Array.isArray(parsed)) {\n warn(\"Unexpected marketplace list format — expected an array\");\n return [];\n }\n\n return parsed as MarketplaceInfo[];\n } catch {\n return [];\n }\n}\n\nexport async function claudePluginMarketplaceExists(name: string): Promise<boolean> {\n const marketplaces = await claudePluginMarketplaceList();\n return marketplaces.some((m) => m.name === name);\n}\n\nexport async function claudePluginMarketplaceAdd(source: string): Promise<void> {\n validateMarketplaceSource(source);\n\n const args = [\"plugin\", \"marketplace\", \"add\", source];\n let result;\n try {\n result = await execCommand(\"claude\", args, {});\n } catch (err) {\n throw new Error(`Failed to add marketplace: ${getErrorMessage(err)}`);\n }\n\n if (result.exitCode !== 0) {\n const errorMessage = result.stderr || result.stdout || \"Unknown error\";\n if (errorMessage.includes(\"already installed\")) {\n return;\n }\n throw new Error(`Failed to add marketplace: ${errorMessage.trim()}`);\n }\n}\n\nexport async function claudePluginUninstall(\n pluginName: string,\n scope: \"project\" | \"user\",\n projectDir: string,\n): Promise<void> {\n validatePluginName(pluginName);\n\n const cwd = resolvePluginCwd(scope, projectDir);\n const args = [\"plugin\", \"uninstall\", pluginName, \"--scope\", scope];\n const result = await execCommand(\"claude\", args, { cwd });\n\n if (result.exitCode !== 0) {\n const errorMessage = result.stderr || result.stdout || \"Unknown error\";\n // Ignore \"not installed\" errors - plugin may already be removed\n if (errorMessage.includes(\"not installed\") || errorMessage.includes(\"not found\")) {\n return;\n }\n throw new Error(`Plugin uninstall failed: ${errorMessage.trim()}`);\n }\n}\n","import path from \"path\";\nimport type { SkillId } from \"../../types\";\nimport type { SkillConfig } from \"../../types/config\";\nimport type { SourceLoadResult } from \"../loading\";\nimport { deleteLocalSkill, copySkillsToLocalFlattened } from \"../skills\";\nimport { claudePluginInstall, claudePluginUninstall } from \"../../utils/exec\";\nimport { verbose, warn } from \"../../utils/logger\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { LOCAL_SKILLS_PATH } from \"../../consts\";\n\nexport type SkillMigration = {\n id: SkillId;\n oldSource: string;\n newSource: string;\n oldScope: \"project\" | \"global\";\n newScope: \"project\" | \"global\";\n};\n\nexport type MigrationPlan = {\n toLocal: SkillMigration[];\n toPlugin: SkillMigration[];\n scopeChanges: SkillMigration[];\n};\n\nexport type MigrationResult = {\n localizedSkills: SkillId[];\n pluginizedSkills: SkillId[];\n warnings: string[];\n};\n\n/**\n * Detect which skills changed source or scope between old and new configs\n * by comparing SkillConfig[] entries by ID.\n */\nexport function detectMigrations(\n oldSkills: SkillConfig[],\n newSkills: SkillConfig[],\n): MigrationPlan {\n const toLocal: SkillMigration[] = [];\n const toPlugin: SkillMigration[] = [];\n const scopeChanges: SkillMigration[] = [];\n\n const oldById = new Map(oldSkills.map((s) => [s.id, s]));\n\n for (const newSkill of newSkills) {\n const oldSkill = oldById.get(newSkill.id);\n if (!oldSkill) continue;\n\n const migration: SkillMigration = {\n id: newSkill.id,\n oldSource: oldSkill.source,\n newSource: newSkill.source,\n oldScope: oldSkill.scope,\n newScope: newSkill.scope,\n };\n\n const wasLocal = oldSkill.source === \"local\";\n const isLocal = newSkill.source === \"local\";\n\n if (wasLocal && !isLocal) {\n toPlugin.push(migration);\n } else if (!wasLocal && isLocal) {\n toLocal.push(migration);\n }\n\n // Detect scope changes (independent of source changes)\n if (oldSkill.scope !== newSkill.scope && wasLocal === isLocal) {\n scopeChanges.push(migration);\n }\n }\n\n return { toLocal, toPlugin, scopeChanges };\n}\n\n/**\n * Execute per-skill migration: delete locals that switch to plugin,\n * copy to local for skills that switch from plugin.\n * Uses per-skill scope from the migration plan.\n */\nexport async function executeMigration(\n plan: MigrationPlan,\n projectDir: string,\n sourceResult: SourceLoadResult,\n): Promise<MigrationResult> {\n const warnings: string[] = [];\n const localizedSkills: SkillId[] = [];\n const pluginizedSkills: SkillId[] = [];\n\n // Migrate skills from plugin to local\n if (plan.toLocal.length > 0) {\n try {\n const localSkillsDir = path.join(projectDir, LOCAL_SKILLS_PATH);\n const skillIds = plan.toLocal.map((m) => m.id);\n const copied = await copySkillsToLocalFlattened(\n skillIds,\n localSkillsDir,\n sourceResult.matrix,\n sourceResult,\n );\n for (const skill of copied) {\n localizedSkills.push(skill.skillId);\n }\n\n // Uninstall plugin references using per-skill scope\n for (const migration of plan.toLocal) {\n try {\n const pluginScope = migration.oldScope === \"global\" ? \"user\" : \"project\";\n await claudePluginUninstall(migration.id, pluginScope, projectDir);\n verbose(`Uninstalled plugin for ${migration.id}`);\n } catch (error) {\n warnings.push(\n `Could not uninstall plugin for ${migration.id}: ${getErrorMessage(error)}`,\n );\n }\n }\n } catch (error) {\n warnings.push(`Could not copy skills to local: ${getErrorMessage(error)}`);\n }\n }\n\n // Migrate skills from local to plugin\n if (plan.toPlugin.length > 0) {\n // Delete local copies\n for (const migration of plan.toPlugin) {\n await deleteLocalSkill(projectDir, migration.id);\n }\n\n // Install as plugins using per-skill scope\n if (sourceResult.marketplace) {\n for (const migration of plan.toPlugin) {\n try {\n const pluginScope = migration.newScope === \"global\" ? \"user\" : \"project\";\n const pluginRef = `${migration.id}@${sourceResult.marketplace}`;\n await claudePluginInstall(pluginRef, pluginScope, projectDir);\n pluginizedSkills.push(migration.id);\n verbose(`Installed plugin for ${migration.id}`);\n } catch (error) {\n warnings.push(`Could not install plugin for ${migration.id}: ${getErrorMessage(error)}`);\n }\n }\n } else {\n warnings.push(\n \"No marketplace configured — cannot install skills as plugins. Skills deleted but not plugin-installed.\",\n );\n }\n }\n\n return { localizedSkills, pluginizedSkills, warnings };\n}\n","import type { SkillDefinition, SkillDefinitionMap, SkillId } from \"../../types\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { verbose } from \"../../utils/logger\";\nimport { typedEntries } from \"../../utils/typed-object\";\nimport { loadPluginSkills } from \"../loading\";\nimport { getVerifiedPluginInstallPaths } from \"./plugin-settings\";\n\n/**\n * Discovers all plugin-installed skills from enabled plugins.\n *\n * Reads `.claude/settings.json` to find enabled plugins, then looks up their\n * install paths in the global plugin registry (`~/.claude/plugins/installed_plugins.json`).\n * Loads skills from the plugin cache directories.\n *\n * @param projectDir - Absolute path to the project root\n * @returns Merged map of all discovered plugin skills (later plugins override earlier)\n */\nexport async function discoverAllPluginSkills(projectDir: string): Promise<SkillDefinitionMap> {\n const allSkills: SkillDefinitionMap = {};\n\n try {\n const pluginPaths = await getVerifiedPluginInstallPaths(projectDir);\n\n if (pluginPaths.length === 0) {\n verbose(`No enabled plugins found in settings.json`);\n return allSkills;\n }\n\n for (const { pluginKey, installPath } of pluginPaths) {\n verbose(`Discovering skills from plugin: '${pluginKey}'`);\n try {\n const pluginSkills = await loadPluginSkills(installPath);\n // Boundary cast: loadPluginSkills returns Record<string, ...> — keys are skill IDs from parsed frontmatter\n for (const [id, skill] of typedEntries<SkillId, SkillDefinition>(pluginSkills)) {\n if (skill) {\n allSkills[id] = skill;\n }\n }\n } catch (error) {\n verbose(`Failed to load skills from '${pluginKey}': ${getErrorMessage(error)}`);\n }\n }\n } catch (error) {\n verbose(`Plugin discovery failed: ${getErrorMessage(error)}`);\n }\n\n return allSkills;\n}\n\n/**\n * Checks whether any plugins are enabled in settings.json.\n *\n * @param projectDir - Absolute path to the project root\n * @returns true if at least one plugin is enabled in settings.json\n */\nexport async function hasIndividualPlugins(projectDir: string): Promise<boolean> {\n try {\n const pluginPaths = await getVerifiedPluginInstallPaths(projectDir);\n return pluginPaths.length > 0;\n } catch (error) {\n verbose(`Failed to check for individual plugins: ${getErrorMessage(error)}`);\n return false;\n }\n}\n\n/**\n * Lists the keys of all enabled plugins.\n *\n * @param projectDir - Absolute path to the project root\n * @returns Array of plugin keys (e.g., [\"web-framework-react@acme-marketplace\"])\n */\nexport async function listPluginNames(projectDir: string): Promise<string[]> {\n try {\n const pluginPaths = await getVerifiedPluginInstallPaths(projectDir);\n return pluginPaths.map(({ pluginKey }) => pluginKey);\n } catch (error) {\n verbose(`Failed to list plugin names: ${getErrorMessage(error)}`);\n return [];\n }\n}\n","import path from \"path\";\nimport os from \"os\";\nimport { z } from \"zod\";\nimport { fileExists, readFileSafe } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { typedEntries } from \"../../utils/typed-object\";\nimport {\n CLAUDE_DIR,\n PLUGINS_SUBDIR,\n MAX_CONFIG_FILE_SIZE,\n PLUGIN_MANIFEST_DIR,\n PLUGIN_MANIFEST_FILE,\n} from \"../../consts\";\n\n/**\n * Plugin key format: \"plugin-name@marketplace\"\n * e.g., \"web-framework-react@acme-marketplace\"\n *\n * Kept as string — user-extensible identifiers (plugin names and marketplace names).\n */\nexport type PluginKey = string;\n\n/**\n * Resolved plugin with its install path\n */\nexport type ResolvedPlugin = {\n pluginKey: PluginKey;\n installPath: string;\n};\n\n// Zod schemas for JSON parse boundaries\n\nconst pluginSettingsSchema = z\n .object({\n enabledPlugins: z.record(z.string(), z.unknown()).optional(),\n })\n .passthrough();\n\nconst pluginInstallationSchema = z.object({\n scope: z.enum([\"user\", \"project\", \"local\"]),\n projectPath: z.string().optional(),\n installPath: z.string(),\n version: z.string(),\n installedAt: z.string(),\n lastUpdated: z.string().optional(),\n gitCommitSha: z.string().optional(),\n});\n\nconst installedPluginsSchema = z\n .object({\n version: z.number(),\n plugins: z.record(z.string(), z.array(pluginInstallationSchema)),\n })\n .passthrough();\n\nconst SETTINGS_FILE = \"settings.json\";\nconst INSTALLED_PLUGINS_FILE = \"installed_plugins.json\";\n\n/**\n * Read enabled plugin keys from project's .claude/settings.json\n */\nexport async function getEnabledPluginKeys(projectDir: string): Promise<PluginKey[]> {\n const settingsPath = path.join(projectDir, CLAUDE_DIR, SETTINGS_FILE);\n\n if (!(await fileExists(settingsPath))) {\n verbose(`No settings.json found at '${settingsPath}'`);\n return [];\n }\n\n try {\n const content = await readFileSafe(settingsPath, MAX_CONFIG_FILE_SIZE);\n const raw: unknown = JSON.parse(content);\n const result = pluginSettingsSchema.safeParse(raw);\n\n if (!result.success) {\n verbose(`Invalid settings.json structure: ${getErrorMessage(result.error)}`);\n return [];\n }\n\n const settings = result.data;\n\n if (!settings.enabledPlugins) {\n verbose(`No enabledPlugins found in '${settingsPath}'`);\n return [];\n }\n\n const enabledKeys = typedEntries(settings.enabledPlugins)\n .filter(([, enabled]) => enabled === true)\n .map(([key]) => key);\n\n verbose(`Found ${enabledKeys.length} enabled plugins in settings.json`);\n return enabledKeys;\n } catch (error) {\n verbose(`Failed to read settings.json: ${getErrorMessage(error)}`);\n return [];\n }\n}\n\n/**\n * Resolve install paths for the given plugin keys from global registry\n */\nexport async function resolvePluginInstallPaths(\n pluginKeys: PluginKey[],\n projectDir: string,\n): Promise<ResolvedPlugin[]> {\n if (pluginKeys.length === 0) {\n return [];\n }\n\n const registryPath = path.join(os.homedir(), CLAUDE_DIR, PLUGINS_SUBDIR, INSTALLED_PLUGINS_FILE);\n\n if (!(await fileExists(registryPath))) {\n verbose(`Plugin registry not found at '${registryPath}'`);\n return [];\n }\n\n try {\n const content = await readFileSafe(registryPath, MAX_CONFIG_FILE_SIZE);\n const raw: unknown = JSON.parse(content);\n const result = installedPluginsSchema.safeParse(raw);\n\n if (!result.success) {\n verbose(`Invalid plugin registry structure: ${getErrorMessage(result.error)}`);\n return [];\n }\n\n const registry = result.data;\n const resolvedPaths: ResolvedPlugin[] = [];\n\n for (const pluginKey of pluginKeys) {\n const installations = registry.plugins[pluginKey];\n\n if (!installations || installations.length === 0) {\n verbose(`Plugin '${pluginKey}' not found in registry`);\n continue;\n }\n\n // Find project-scoped installation matching this project\n const projectInstall = installations.find(\n (install) => install.scope === \"project\" && install.projectPath === projectDir,\n );\n\n if (projectInstall) {\n resolvedPaths.push({\n pluginKey,\n installPath: projectInstall.installPath,\n });\n verbose(`Resolved '${pluginKey}' to '${projectInstall.installPath}'`);\n continue;\n }\n\n // Fallback to user-scoped installation\n const userInstall = installations.find((install) => install.scope === \"user\");\n\n if (userInstall) {\n resolvedPaths.push({\n pluginKey,\n installPath: userInstall.installPath,\n });\n verbose(`Resolved '${pluginKey}' to '${userInstall.installPath}' (user scope)`);\n continue;\n }\n\n verbose(`No matching installation found for '${pluginKey}'`);\n }\n\n return resolvedPaths;\n } catch (error) {\n verbose(`Failed to read plugin registry: ${getErrorMessage(error)}`);\n return [];\n }\n}\n\n/**\n * Get verified plugin install paths for the project\n * Combines settings.json reading, registry lookup, and path verification\n */\nexport async function getVerifiedPluginInstallPaths(projectDir: string): Promise<ResolvedPlugin[]> {\n const enabledKeys = await getEnabledPluginKeys(projectDir);\n const resolvedPaths = await resolvePluginInstallPaths(enabledKeys, projectDir);\n\n // Filter out paths that don't exist on disk\n const verified: ResolvedPlugin[] = [];\n\n for (const { pluginKey, installPath } of resolvedPaths) {\n const pluginJsonPath = path.join(installPath, PLUGIN_MANIFEST_DIR, PLUGIN_MANIFEST_FILE);\n\n if (await fileExists(pluginJsonPath)) {\n verified.push({ pluginKey, installPath });\n } else {\n verbose(`Plugin '${pluginKey}' manifest does not exist at: '${pluginJsonPath}'`);\n }\n }\n\n verbose(`Verified ${verified.length} plugin install paths`);\n return verified;\n}\n","import { z } from \"zod\";\nimport path from \"path\";\nimport fg from \"fast-glob\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport {\n fileExists,\n readFile,\n readFileSafe,\n directoryExists,\n listDirectories,\n} from \"../../utils/fs\";\nimport type { ValidationResult } from \"../../types\";\nimport { countBy } from \"remeda\";\nimport { extractFrontmatter } from \"../../utils/frontmatter\";\nimport { log } from \"../../utils/logger\";\nimport { formatZodErrors } from \"../schema-validator\";\nimport {\n pluginAuthorSchema,\n hooksRecordSchema,\n skillFrontmatterValidationSchema,\n agentFrontmatterValidationSchema,\n} from \"../schemas\";\nimport { MAX_PLUGIN_FILE_SIZE, PLUGIN_MANIFEST_DIR, STANDARD_FILES } from \"../../consts\";\n\nconst PLUGIN_DIR = PLUGIN_MANIFEST_DIR;\nconst PLUGIN_MANIFEST = STANDARD_FILES.PLUGIN_JSON;\nconst KEBAB_CASE_REGEX = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;\nconst SEMVER_REGEX =\n /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/;\n\n// Strict schema that rejects unrecognized keys (loader schema in schemas.ts uses .passthrough())\nconst pluginManifestValidationSchema = z\n .object({\n name: z.string(),\n version: z.string().optional(),\n description: z.string().optional(),\n author: pluginAuthorSchema.optional(),\n keywords: z.array(z.string()).optional(),\n commands: z.union([z.string(), z.array(z.string())]).optional(),\n agents: z.union([z.string(), z.array(z.string())]).optional(),\n skills: z.union([z.string(), z.array(z.string())]).optional(),\n hooks: z.union([z.string(), hooksRecordSchema]).optional(),\n })\n .strict();\n\nfunction isKebabCase(str: string): boolean {\n return KEBAB_CASE_REGEX.test(str);\n}\n\nfunction isValidSemver(str: string): boolean {\n return SEMVER_REGEX.test(str);\n}\n\n/**\n * Validates the directory structure of a plugin.\n *\n * Checks for the required `.claude-plugin/` directory and `plugin.json` manifest file.\n * Warns if README.md is missing (recommended but not required).\n *\n * @param pluginPath - Absolute path to the plugin root directory\n * @returns Validation result with errors for missing required structure\n */\nexport async function validatePluginStructure(pluginPath: string): Promise<ValidationResult> {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n if (!(await directoryExists(pluginPath))) {\n return {\n valid: false,\n errors: [`Plugin directory does not exist: ${pluginPath}`],\n warnings: [],\n };\n }\n\n const pluginDir = path.join(pluginPath, PLUGIN_DIR);\n if (!(await directoryExists(pluginDir))) {\n errors.push(`Missing ${PLUGIN_DIR}/ directory`);\n }\n\n const manifestPath = path.join(pluginDir, PLUGIN_MANIFEST);\n if (!(await fileExists(manifestPath))) {\n errors.push(`Missing ${PLUGIN_DIR}/${PLUGIN_MANIFEST}`);\n }\n\n const readmePath = path.join(pluginPath, \"README.md\");\n if (!(await fileExists(readmePath))) {\n warnings.push(\"Missing README.md (recommended for documentation)\");\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Validates a plugin manifest file (plugin.json) for correctness and completeness.\n *\n * Performs the following validation checks:\n * 1. File existence and readability\n * 2. Valid JSON syntax (with file size limit via readFileSafe)\n * 3. Zod schema validation (strict mode rejects unrecognized keys)\n * 4. Plugin name is kebab-case\n * 5. Version string is valid semver\n * 6. Description field is present (warning if missing)\n * 7. Skills directory path exists on disk (if specified as string)\n * 8. Agents directory path exists on disk (if specified as string)\n *\n * @param manifestPath - Absolute path to the plugin.json file\n * @returns Validation result with errors for invalid/missing data and warnings for recommendations\n */\nexport async function validatePluginManifest(manifestPath: string): Promise<ValidationResult> {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n if (!(await fileExists(manifestPath))) {\n return {\n valid: false,\n errors: [`Manifest file not found: ${manifestPath}`],\n warnings: [],\n };\n }\n\n let manifest: Record<string, unknown>;\n try {\n const content = await readFileSafe(manifestPath, MAX_PLUGIN_FILE_SIZE);\n manifest = JSON.parse(content);\n } catch (err) {\n return {\n valid: false,\n errors: [`Invalid JSON in ${PLUGIN_MANIFEST}: ${getErrorMessage(err)}`],\n warnings: [],\n };\n }\n\n const result = pluginManifestValidationSchema.safeParse(manifest);\n\n if (!result.success) {\n errors.push(...formatZodErrors(result.error));\n }\n\n if (manifest.name && typeof manifest.name === \"string\") {\n if (!isKebabCase(manifest.name)) {\n errors.push(`name must be kebab-case: \"${manifest.name}\"`);\n }\n }\n\n if (manifest.version && typeof manifest.version === \"string\") {\n if (!isValidSemver(manifest.version)) {\n errors.push(\n `version \"${manifest.version}\" is not valid semver (expected: major.minor.patch)`,\n );\n }\n }\n\n if (!manifest.description) {\n warnings.push(\"Missing description field (recommended for discoverability)\");\n }\n\n const pluginDir = path.dirname(path.dirname(manifestPath));\n\n if (manifest.skills && typeof manifest.skills === \"string\") {\n const skillsPath = path.join(pluginDir, manifest.skills);\n if (!(await directoryExists(skillsPath))) {\n errors.push(`Skills path does not exist: ${manifest.skills}`);\n }\n }\n\n if (manifest.agents && typeof manifest.agents === \"string\") {\n const agentsPath = path.join(pluginDir, manifest.agents);\n if (!(await directoryExists(agentsPath))) {\n errors.push(`Agents path does not exist: ${manifest.agents}`);\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\nexport async function validateSkillFrontmatter(skillPath: string): Promise<ValidationResult> {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n if (!(await fileExists(skillPath))) {\n return {\n valid: false,\n errors: [`Skill file not found: ${skillPath}`],\n warnings: [],\n };\n }\n\n const content = await readFile(skillPath);\n const frontmatter = extractFrontmatter(content);\n\n if (frontmatter === null) {\n return {\n valid: false,\n errors: [\"Missing or invalid YAML frontmatter\"],\n warnings: [],\n };\n }\n\n const result = skillFrontmatterValidationSchema.safeParse(frontmatter);\n\n if (!result.success) {\n errors.push(...formatZodErrors(result.error));\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\nexport async function validateAgentFrontmatter(agentPath: string): Promise<ValidationResult> {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n if (!(await fileExists(agentPath))) {\n return {\n valid: false,\n errors: [`Agent file not found: ${agentPath}`],\n warnings: [],\n };\n }\n\n const content = await readFile(agentPath);\n const frontmatter = extractFrontmatter(content);\n\n if (frontmatter === null) {\n return {\n valid: false,\n errors: [\"Missing or invalid YAML frontmatter\"],\n warnings: [],\n };\n }\n\n const result = agentFrontmatterValidationSchema.safeParse(frontmatter);\n\n if (!result.success) {\n errors.push(...formatZodErrors(result.error));\n }\n\n // Boundary cast: YAML frontmatter parsed as unknown, narrow to record for field access\n const fm = frontmatter as Record<string, unknown>;\n\n if (fm.name && typeof fm.name === \"string\") {\n if (!isKebabCase(fm.name)) {\n errors.push(`name must be kebab-case: \"${fm.name}\"`);\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\nfunction mergeResults(results: ValidationResult[]): ValidationResult {\n const errors = results.flatMap((r) => r.errors);\n const warnings = results.flatMap((r) => r.warnings);\n return { valid: errors.length === 0, errors, warnings };\n}\n\nconst EMPTY_RESULT: ValidationResult = { valid: true, errors: [], warnings: [] };\n\nfunction prefixResult(result: ValidationResult, prefix: string): ValidationResult {\n return {\n valid: result.valid,\n errors: result.valid ? [] : result.errors.map((e) => `${prefix}: ${e}`),\n warnings: result.warnings.map((w) => `${prefix}: ${w}`),\n };\n}\n\nasync function validatePluginSkillFiles(\n pluginPath: string,\n skillsRelPath: string,\n): Promise<ValidationResult> {\n const skillsDir = path.join(pluginPath, skillsRelPath);\n if (!(await directoryExists(skillsDir))) return EMPTY_RESULT;\n\n const files = await fg(\"**/SKILL.md\", { cwd: skillsDir, absolute: true });\n if (files.length === 0) {\n return {\n valid: true,\n errors: [],\n warnings: [`Skills directory exists but contains no SKILL.md files: ${skillsRelPath}`],\n };\n }\n\n const results = await Promise.all(\n files.map(async (f) =>\n prefixResult(await validateSkillFrontmatter(f), path.relative(pluginPath, f)),\n ),\n );\n return mergeResults(results);\n}\n\nasync function validatePluginAgentFiles(\n pluginPath: string,\n agentsRelPath: string,\n): Promise<ValidationResult> {\n const agentsDir = path.join(pluginPath, agentsRelPath);\n if (!(await directoryExists(agentsDir))) return EMPTY_RESULT;\n\n const files = await fg(\"*.md\", { cwd: agentsDir, absolute: true });\n if (files.length === 0) {\n return {\n valid: true,\n errors: [],\n warnings: [`Agents directory exists but contains no .md files: ${agentsRelPath}`],\n };\n }\n\n const results = await Promise.all(\n files.map(async (f) =>\n prefixResult(await validateAgentFrontmatter(f), path.relative(pluginPath, f)),\n ),\n );\n return mergeResults(results);\n}\n\nasync function loadManifestForValidation(\n manifestPath: string,\n): Promise<Record<string, unknown> | null> {\n try {\n const content = await readFileSafe(manifestPath, MAX_PLUGIN_FILE_SIZE);\n return JSON.parse(content) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\n/**\n * Runs comprehensive validation on a plugin: structure, manifest, skill files, and agent files.\n *\n * Short-circuits on structure validation failure (no point checking manifest if\n * the directory structure is wrong). For valid structures, validates the manifest\n * and then checks all SKILL.md and agent .md files for valid frontmatter.\n *\n * @param pluginPath - Absolute path to the plugin root directory\n * @returns Merged validation result from all validation passes\n */\nexport async function validatePlugin(pluginPath: string): Promise<ValidationResult> {\n const structureResult = await validatePluginStructure(pluginPath);\n if (!structureResult.valid) return structureResult;\n\n const manifestPath = path.join(pluginPath, PLUGIN_DIR, PLUGIN_MANIFEST);\n const manifestResult = await validatePluginManifest(manifestPath);\n const manifest = await loadManifestForValidation(manifestPath);\n\n const skillsResult =\n manifest?.skills && typeof manifest.skills === \"string\"\n ? await validatePluginSkillFiles(pluginPath, manifest.skills)\n : EMPTY_RESULT;\n\n const agentsResult =\n manifest?.agents && typeof manifest.agents === \"string\"\n ? await validatePluginAgentFiles(pluginPath, manifest.agents)\n : EMPTY_RESULT;\n\n return mergeResults([structureResult, manifestResult, skillsResult, agentsResult]);\n}\n\n/**\n * Validates all plugins found in a directory, returning individual results and an aggregate summary.\n *\n * Scans subdirectories for `.claude-plugin/` markers to identify plugins, then validates\n * each one. Returns early with an error if the directory doesn't exist or contains no plugins.\n *\n * @param pluginsDir - Absolute path to the directory containing plugin subdirectories\n * @returns Object with overall validity, per-plugin results, and counts summary\n */\nexport async function validateAllPlugins(pluginsDir: string): Promise<{\n valid: boolean;\n results: Array<{ name: string; result: ValidationResult }>;\n summary: {\n total: number;\n valid: number;\n invalid: number;\n withWarnings: number;\n };\n}> {\n const results: Array<{ name: string; result: ValidationResult }> = [];\n\n if (!(await directoryExists(pluginsDir))) {\n return {\n valid: false,\n results: [\n {\n name: pluginsDir,\n result: {\n valid: false,\n errors: [`Directory does not exist: ${pluginsDir}`],\n warnings: [],\n },\n },\n ],\n summary: { total: 0, valid: 0, invalid: 1, withWarnings: 0 },\n };\n }\n\n const allDirs = await listDirectories(pluginsDir);\n const pluginDirs: string[] = [];\n\n for (const dirName of allDirs) {\n const potentialPluginDir = path.join(pluginsDir, dirName, PLUGIN_DIR);\n if (await directoryExists(potentialPluginDir)) {\n pluginDirs.push(dirName);\n }\n }\n\n if (pluginDirs.length === 0) {\n return {\n valid: false,\n results: [\n {\n name: pluginsDir,\n result: {\n valid: false,\n errors: [\n `No plugins found in directory: ${pluginsDir}. Plugins must contain a ${PLUGIN_DIR}/ directory.`,\n ],\n warnings: [],\n },\n },\n ],\n summary: { total: 0, valid: 0, invalid: 1, withWarnings: 0 },\n };\n }\n\n for (const pluginName of pluginDirs) {\n const pluginPath = path.join(pluginsDir, pluginName);\n const result = await validatePlugin(pluginPath);\n results.push({ name: pluginName, result });\n }\n\n const summary = {\n total: results.length,\n valid: countBy(results, (r) => String(r.result.valid))[\"true\"] ?? 0,\n invalid: countBy(results, (r) => String(r.result.valid))[\"false\"] ?? 0,\n withWarnings: countBy(results, (r) => String(r.result.warnings.length > 0))[\"true\"] ?? 0,\n };\n\n return {\n valid: summary.invalid === 0,\n results,\n summary,\n };\n}\n\nexport function printPluginValidationResult(\n name: string,\n result: ValidationResult,\n verbose = false,\n): void {\n const status = result.valid ? \"\\u2713\" : \"\\u2717\";\n\n if (result.valid && result.warnings.length === 0 && !verbose) {\n return;\n }\n\n log(`\\n ${status} ${name}`);\n\n if (result.errors.length > 0) {\n log(\" Errors:\");\n result.errors.forEach((e) => log(` - ${e}`));\n }\n\n if (result.warnings.length > 0) {\n log(\" Warnings:\");\n result.warnings.forEach((w) => log(` - ${w}`));\n }\n}\n","import { sumBy } from \"remeda\";\nimport { z } from \"zod\";\nimport path from \"path\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport { readFile, fileExists } from \"../utils/fs\";\nimport { parse as parseYaml } from \"yaml\";\nimport fg from \"fast-glob\";\nimport { extractFrontmatter } from \"../utils/frontmatter\";\nimport { log } from \"../utils/logger\";\nimport {\n skillCategoriesFileSchema,\n skillRulesFileSchema,\n metadataValidationSchema,\n stackConfigValidationSchema,\n skillFrontmatterValidationSchema,\n agentFrontmatterValidationSchema,\n agentYamlGenerationSchema,\n stacksConfigSchema,\n projectSourceConfigSchema,\n pluginManifestSchema,\n} from \"./schemas\";\nimport { CLAUDE_DIR, CLAUDE_SRC_DIR, STANDARD_FILES } from \"../consts\";\nimport { loadConfig } from \"./configuration/config-loader\";\n\ntype FileValidationError = {\n file: string;\n errors: string[];\n};\n\ntype SchemaValidationResult = {\n schemaName: string;\n valid: boolean;\n totalFiles: number;\n validFiles: number;\n invalidFiles: FileValidationError[];\n};\n\nexport type FullValidationResult = {\n valid: boolean;\n results: SchemaValidationResult[];\n summary: {\n totalSchemas: number;\n totalFiles: number;\n validFiles: number;\n invalidFiles: number;\n };\n};\n\ntype ContentExtractor = (content: string) => unknown | null;\n\ntype ValidationTarget = {\n name: string;\n schema: z.ZodType<unknown>;\n pattern: string;\n baseDir: string;\n extractor?: ContentExtractor;\n /** When true, load via loadConfig instead of YAML parsing */\n isConfigFile?: boolean;\n};\n\nconst VALIDATION_TARGETS: ValidationTarget[] = [\n {\n name: \"Skill Categories\",\n schema: skillCategoriesFileSchema,\n pattern: STANDARD_FILES.SKILL_CATEGORIES_TS,\n baseDir: \"config\",\n isConfigFile: true,\n },\n {\n name: \"Skill Rules\",\n schema: skillRulesFileSchema,\n pattern: STANDARD_FILES.SKILL_RULES_TS,\n baseDir: \"config\",\n isConfigFile: true,\n },\n {\n name: \"Skill Metadata\",\n schema: metadataValidationSchema,\n pattern: `**/${STANDARD_FILES.METADATA_YAML}`,\n baseDir: \"src/skills\",\n },\n {\n name: \"Stack Skill Metadata\",\n schema: metadataValidationSchema,\n pattern: `**/skills/**/${STANDARD_FILES.METADATA_YAML}`,\n baseDir: \"src/stacks\",\n },\n {\n name: \"Stack Config\",\n schema: stackConfigValidationSchema,\n pattern: `*/${STANDARD_FILES.CONFIG_YAML}`,\n baseDir: \"src/stacks\",\n },\n {\n name: \"Agent Definition\",\n schema: agentYamlGenerationSchema,\n pattern: `**/${STANDARD_FILES.AGENT_METADATA_YAML}`,\n baseDir: \"src/agents\",\n },\n {\n name: \"Skill Frontmatter\",\n schema: skillFrontmatterValidationSchema,\n pattern: `**/${STANDARD_FILES.SKILL_MD}`,\n baseDir: \"src/skills\",\n extractor: extractFrontmatter,\n },\n {\n name: \"Stack Skill Frontmatter\",\n schema: skillFrontmatterValidationSchema,\n pattern: `**/skills/**/${STANDARD_FILES.SKILL_MD}`,\n baseDir: \"src/stacks\",\n extractor: extractFrontmatter,\n },\n {\n name: \"Stacks Config\",\n schema: stacksConfigSchema,\n pattern: \"stacks.ts\",\n baseDir: \"config\",\n isConfigFile: true,\n },\n {\n name: \"Project Source Config\",\n schema: projectSourceConfigSchema,\n pattern: STANDARD_FILES.CONFIG_YAML,\n baseDir: CLAUDE_SRC_DIR,\n },\n {\n name: \"Project Skill Metadata\",\n schema: metadataValidationSchema,\n pattern: `*/${STANDARD_FILES.METADATA_YAML}`,\n baseDir: `${CLAUDE_DIR}/skills`,\n },\n {\n name: \"Project Skill Frontmatter\",\n schema: skillFrontmatterValidationSchema,\n pattern: `*/${STANDARD_FILES.SKILL_MD}`,\n baseDir: `${CLAUDE_DIR}/skills`,\n extractor: extractFrontmatter,\n },\n {\n name: \"Project Agent Frontmatter\",\n schema: agentFrontmatterValidationSchema,\n pattern: \"*.md\",\n baseDir: `${CLAUDE_DIR}/agents`,\n extractor: extractFrontmatter,\n },\n {\n name: \"Plugin Manifest\",\n schema: pluginManifestSchema,\n pattern: `*/${STANDARD_FILES.PLUGIN_JSON}`,\n baseDir: `${CLAUDE_DIR}/plugins`,\n extractor: (content: string) => JSON.parse(content) as unknown,\n },\n];\n\nexport function formatZodErrors(error: z.ZodError): string[] {\n return error.issues.map((issue) => {\n const path = issue.path.join(\".\");\n if (issue.code === \"unrecognized_keys\") {\n return `Unrecognized key: \"${issue.keys.join('\", \"')}\"`;\n }\n return path ? `${path}: ${issue.message}` : issue.message;\n });\n}\n\nasync function validateFile(\n filePath: string,\n schema: z.ZodType<unknown>,\n extractor?: ContentExtractor,\n isConfigFile?: boolean,\n): Promise<{ valid: boolean; errors: string[] }> {\n try {\n if (!(await fileExists(filePath))) {\n return { valid: false, errors: [`File not found: ${filePath}`] };\n }\n\n if (isConfigFile) {\n const data = await loadConfig(filePath, schema);\n if (data === null) {\n return { valid: false, errors: [\"Failed to load or validate config\"] };\n }\n return { valid: true, errors: [] };\n }\n\n const content = await readFile(filePath);\n\n let parsed: unknown;\n if (extractor) {\n parsed = extractor(content);\n if (parsed === null) {\n return {\n valid: false,\n errors: [\"Failed to extract content (no valid frontmatter found)\"],\n };\n }\n } else {\n parsed = parseYaml(content);\n }\n\n const result = schema.safeParse(parsed);\n\n if (result.success) {\n return { valid: true, errors: [] };\n }\n\n return { valid: false, errors: formatZodErrors(result.error) };\n } catch (error) {\n const message = getErrorMessage(error);\n return { valid: false, errors: [`Failed to parse content: ${message}`] };\n }\n}\n\nasync function validateTarget(\n target: ValidationTarget,\n rootDir: string = process.cwd(),\n): Promise<SchemaValidationResult> {\n const baseDir = path.join(rootDir, target.baseDir);\n const pattern = path.join(baseDir, target.pattern);\n const files = await fg(pattern, { absolute: true });\n\n const result: SchemaValidationResult = {\n schemaName: target.name,\n valid: true,\n totalFiles: files.length,\n validFiles: 0,\n invalidFiles: [],\n };\n\n if (files.length === 0) {\n return result;\n }\n\n for (const file of files) {\n const validation = await validateFile(\n file,\n target.schema,\n target.extractor,\n target.isConfigFile,\n );\n const relativePath = path.relative(rootDir, file);\n\n if (validation.valid) {\n result.validFiles++;\n } else {\n result.valid = false;\n result.invalidFiles.push({\n file: relativePath,\n errors: validation.errors,\n });\n }\n }\n\n return result;\n}\n\nexport async function validateAllSchemas(\n rootDir: string = process.cwd(),\n): Promise<FullValidationResult> {\n const results: SchemaValidationResult[] = [];\n\n for (const target of VALIDATION_TARGETS) {\n const result = await validateTarget(target, rootDir);\n results.push(result);\n }\n\n const summary = {\n totalSchemas: results.length,\n totalFiles: sumBy(results, (r) => r.totalFiles),\n validFiles: sumBy(results, (r) => r.validFiles),\n invalidFiles: sumBy(results, (r) => r.invalidFiles.length),\n };\n\n return {\n valid: results.every((r) => r.valid),\n results,\n summary,\n };\n}\n\nexport function printValidationResults(result: FullValidationResult): void {\n log(\"\\n Schema Validation Summary:\");\n log(\" ─────────────────────────\");\n log(` Total schemas checked: ${result.summary.totalSchemas}`);\n log(` Total files: ${result.summary.totalFiles}`);\n log(` Valid: ${result.summary.validFiles}`);\n log(` Invalid: ${result.summary.invalidFiles}`);\n\n for (const schemaResult of result.results) {\n if (schemaResult.totalFiles === 0) continue;\n\n const status = schemaResult.valid ? \"✓\" : \"✗\";\n log(\n `\\n ${status} ${schemaResult.schemaName}: ${schemaResult.validFiles}/${schemaResult.totalFiles} valid`,\n );\n\n if (schemaResult.invalidFiles.length > 0) {\n for (const file of schemaResult.invalidFiles) {\n log(`\\n ${file.file}:`);\n file.errors.forEach((e) => log(` - ${e}`));\n }\n }\n }\n\n if (result.valid) {\n log(\"\\n ✓ All schemas validated successfully\\n\");\n } else {\n log(\"\\n ✗ Validation failed\\n\");\n }\n}\n"],"mappings":"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","names":["os","path","path","path","CONTROL_CHAR_PATTERN","os","path","path","path","path","os","path","os","path","os","path","unique","path","matrix","loadSkillsMatrixFromSource","loadAllAgents","os","unique","path","os","path","path","os","path","path","os","parseYaml","path","path","path","slug","path","matrix","path","PLUGIN_MANIFEST_FILE","path","path","path","path","os","path","path","os","os","path","path","parseYaml","createHash","path","createHash","path","path","parseYaml","path","NULL_BYTE_PATTERN","path","path","path","path","matrix","path","parseYaml","path","parseYaml","path","path","path","path","pipe","flatMap","parseYaml","path","unique","path","unique","os","SAFE_NAME_PATTERN","os","os","path","matrix","path","path","path","os","z","z","path","os","z","path","fg","path","parseYaml","formatZodErrors","path","parseYaml","z","path","formatZodErrors","fg","verbose","matrix","path","path","parseYaml","path","os","path","matrix"]}