agents-inc 0.153.0 → 0.155.0

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 (218) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/dist/chunk-2H7UWE2G.js +246 -0
  3. package/dist/chunk-2H7UWE2G.js.map +1 -0
  4. package/dist/{chunk-ZNDLUWWD.js → chunk-4A4L3YIW.js} +5 -5
  5. package/dist/chunk-4G2YHZIM.js +132 -0
  6. package/dist/chunk-4G2YHZIM.js.map +1 -0
  7. package/dist/{chunk-WDAO3RUY.js → chunk-5F2YR5XV.js} +3 -3
  8. package/dist/{chunk-JFAUQDZM.js → chunk-5OKLCVM4.js} +3 -3
  9. package/dist/{chunk-REKOWTIB.js → chunk-5QZAK6J7.js} +44 -10
  10. package/dist/chunk-5QZAK6J7.js.map +1 -0
  11. package/dist/{chunk-VECFAKM5.js → chunk-6RLV45HN.js} +10 -10
  12. package/dist/{chunk-VECFAKM5.js.map → chunk-6RLV45HN.js.map} +1 -1
  13. package/dist/{chunk-K7PJDWER.js → chunk-CLFHC2DK.js} +15 -106
  14. package/dist/chunk-CLFHC2DK.js.map +1 -0
  15. package/dist/chunk-D2CAV7MG.js +61 -0
  16. package/dist/chunk-D2CAV7MG.js.map +1 -0
  17. package/dist/{chunk-NXGMM5YN.js → chunk-F2AMBBIA.js} +6 -6
  18. package/dist/{chunk-NXGMM5YN.js.map → chunk-F2AMBBIA.js.map} +1 -1
  19. package/dist/{chunk-HEBPKK5L.js → chunk-F5T6TV4Z.js} +213 -92
  20. package/dist/chunk-F5T6TV4Z.js.map +1 -0
  21. package/dist/{chunk-K3O3YQYG.js → chunk-G47TDUK3.js} +2 -2
  22. package/dist/{chunk-U2DNAHFE.js → chunk-GS2NZ3GD.js} +8 -8
  23. package/dist/chunk-GS2NZ3GD.js.map +1 -0
  24. package/dist/{chunk-ORJ5Y222.js → chunk-H6UTKTLK.js} +176 -256
  25. package/dist/chunk-H6UTKTLK.js.map +1 -0
  26. package/dist/{chunk-M5HSTNYU.js → chunk-HG4JPXJT.js} +11 -29
  27. package/dist/chunk-HG4JPXJT.js.map +1 -0
  28. package/dist/{chunk-VGEBYCQZ.js → chunk-HTYH7CKN.js} +4 -15
  29. package/dist/chunk-HTYH7CKN.js.map +1 -0
  30. package/dist/{chunk-JC7DBPRD.js → chunk-HXKOIWLU.js} +2 -2
  31. package/dist/chunk-HXKOIWLU.js.map +1 -0
  32. package/dist/{chunk-NSJ2S7R5.js → chunk-ILUVL7WM.js} +2 -2
  33. package/dist/{chunk-R54KIGN2.js → chunk-IO5YBKHV.js} +13 -2
  34. package/dist/chunk-IO5YBKHV.js.map +1 -0
  35. package/dist/chunk-IXRZAHZF.js +53 -0
  36. package/dist/chunk-IXRZAHZF.js.map +1 -0
  37. package/dist/chunk-JCPANDNR.js +35 -0
  38. package/dist/chunk-JCPANDNR.js.map +1 -0
  39. package/dist/{chunk-R4SEU3DF.js → chunk-LJCNUP6M.js} +2 -2
  40. package/dist/{chunk-FRWKCE6R.js → chunk-MHRC3KRX.js} +5 -5
  41. package/dist/chunk-MHRC3KRX.js.map +1 -0
  42. package/dist/chunk-MO5FGLVS.js +142 -0
  43. package/dist/chunk-MO5FGLVS.js.map +1 -0
  44. package/dist/{chunk-Q5FLW4JG.js → chunk-OKH64JZE.js} +2 -2
  45. package/dist/{chunk-WG6V6VJV.js → chunk-PCC4LBKB.js} +2 -2
  46. package/dist/chunk-PMUABBPG.js +258 -0
  47. package/dist/chunk-PMUABBPG.js.map +1 -0
  48. package/dist/{chunk-EFU6P3B7.js → chunk-PNMM5HNX.js} +5 -5
  49. package/dist/{chunk-4VYALFQZ.js → chunk-QWVXOCXO.js} +6 -6
  50. package/dist/{chunk-35VOK7XE.js → chunk-RWOYPOMR.js} +4365 -4355
  51. package/dist/chunk-RWOYPOMR.js.map +1 -0
  52. package/dist/{chunk-IO4VEW5U.js → chunk-SY4X2LND.js} +4 -4
  53. package/dist/{chunk-XGMOXMS4.js → chunk-TBOVYLQJ.js} +2 -2
  54. package/dist/{chunk-BMGBA6HJ.js → chunk-TNGMF4UX.js} +20 -20
  55. package/dist/{chunk-BMGBA6HJ.js.map → chunk-TNGMF4UX.js.map} +1 -1
  56. package/dist/{chunk-TY6CAOL7.js → chunk-UMH2YZKG.js} +14 -5
  57. package/dist/chunk-UMH2YZKG.js.map +1 -0
  58. package/dist/{chunk-6CNRMCFM.js → chunk-VPASBA7P.js} +2 -2
  59. package/dist/{chunk-NXQAY5U7.js → chunk-WCAUUBHO.js} +5860 -5126
  60. package/dist/chunk-WCAUUBHO.js.map +1 -0
  61. package/dist/{chunk-V3ENMW7G.js → chunk-WFRTHH3A.js} +3 -3
  62. package/dist/{chunk-2HC2SNRP.js → chunk-WTJ3AY33.js} +1 -5
  63. package/dist/chunk-WTJ3AY33.js.map +1 -0
  64. package/dist/{chunk-F7Z5I6GU.js → chunk-WUQ3MTPF.js} +11 -5
  65. package/dist/{chunk-F7Z5I6GU.js.map → chunk-WUQ3MTPF.js.map} +1 -1
  66. package/dist/{chunk-U2YSGBHA.js → chunk-XAXJWXI4.js} +93 -43
  67. package/dist/chunk-XAXJWXI4.js.map +1 -0
  68. package/dist/{chunk-ACKC577F.js → chunk-Y5Y7XHVU.js} +4 -4
  69. package/dist/{chunk-X5XJ6WKO.js → chunk-YO2LTXB4.js} +107 -16
  70. package/dist/chunk-YO2LTXB4.js.map +1 -0
  71. package/dist/{chunk-FIHTAFST.js → chunk-ZUAZHDKP.js} +64 -65
  72. package/dist/chunk-ZUAZHDKP.js.map +1 -0
  73. package/dist/commands/build/marketplace.js +98 -120
  74. package/dist/commands/build/marketplace.js.map +1 -1
  75. package/dist/commands/build/plugins.js +8 -8
  76. package/dist/commands/compile.js +57 -24
  77. package/dist/commands/compile.js.map +1 -1
  78. package/dist/commands/doctor.js +220 -79
  79. package/dist/commands/doctor.js.map +1 -1
  80. package/dist/commands/edit.js +608 -100
  81. package/dist/commands/edit.js.map +1 -1
  82. package/dist/commands/eject.js +26 -21
  83. package/dist/commands/eject.js.map +1 -1
  84. package/dist/commands/init.js +41 -39
  85. package/dist/commands/list.js +11 -11
  86. package/dist/commands/list.js.map +1 -1
  87. package/dist/commands/new/marketplace.js +243 -0
  88. package/dist/commands/new/marketplace.js.map +1 -0
  89. package/dist/commands/search.js +34 -24
  90. package/dist/commands/search.js.map +1 -1
  91. package/dist/commands/share.js +67 -0
  92. package/dist/commands/share.js.map +1 -0
  93. package/dist/commands/uninstall.js +234 -196
  94. package/dist/commands/uninstall.js.map +1 -1
  95. package/dist/commands/update.js +9 -9
  96. package/dist/commands/update.js.map +1 -1
  97. package/dist/components/common/prompt-confirm.js +1 -1
  98. package/dist/components/common/removal-plan-confirm.js +10 -0
  99. package/dist/components/common/select-list.js +2 -2
  100. package/dist/components/wizard/category-grid.js +5 -5
  101. package/dist/components/wizard/checkbox-grid.js +5 -5
  102. package/dist/components/wizard/domain-selection.js +11 -11
  103. package/dist/components/wizard/run-wizard-session.js +29 -28
  104. package/dist/components/wizard/scroll-affordance.js +2 -2
  105. package/dist/components/wizard/skill-agent-summary.js +6 -6
  106. package/dist/components/wizard/source-grid.js +6 -6
  107. package/dist/components/wizard/stack-selection.js +8 -8
  108. package/dist/components/wizard/step-agents.js +10 -11
  109. package/dist/components/wizard/step-build.js +9 -9
  110. package/dist/components/wizard/step-confirm.js +10 -10
  111. package/dist/components/wizard/step-sources.js +10 -10
  112. package/dist/components/wizard/step-stack.js +9 -9
  113. package/dist/components/wizard/summary-panel.js +9 -9
  114. package/dist/components/wizard/toast.js +2 -2
  115. package/dist/components/wizard/wizard-layout.js +14 -14
  116. package/dist/components/wizard/wizard-tabs.js +2 -2
  117. package/dist/components/wizard/wizard.js +27 -27
  118. package/dist/copy-local-skills-NSUTBVLJ.js +14 -0
  119. package/dist/hooks/init.js +42 -62
  120. package/dist/hooks/init.js.map +1 -1
  121. package/dist/load-agent-defs-X4E57I2U.js +15 -0
  122. package/dist/{loader-4U7UCE2Y.js → loader-G6BFG2VA.js} +3 -3
  123. package/dist/recompile-project-agents-JE4MM72I.js +20 -0
  124. package/dist/{source-loader-ZNSYJJCI.js → source-loader-3DL3NYUX.js} +7 -5
  125. package/dist/source-loader-3DL3NYUX.js.map +1 -0
  126. package/dist/src/agents/developer/ai-developer/critical-reminders.md +1 -1
  127. package/dist/src/agents/developer/ai-developer/critical-requirements.md +1 -1
  128. package/dist/src/agents/developer/ai-developer/identity.md +1 -1
  129. package/dist/src/agents/developer/ai-developer/playbook.md +1 -1
  130. package/dist/src/agents/developer/api-developer/identity.md +1 -1
  131. package/dist/src/agents/developer/cli-developer/identity.md +1 -1
  132. package/dist/src/agents/developer/web-developer/identity.md +1 -1
  133. package/dist/src/agents/meta/codex-keeper/identity.md +1 -1
  134. package/dist/src/agents/meta/convention-keeper/identity.md +1 -1
  135. package/dist/src/agents/meta/skill-summoner/identity.md +1 -1
  136. package/dist/src/agents/researcher/ai-researcher/identity.md +1 -1
  137. package/dist/src/agents/researcher/api-researcher/identity.md +1 -1
  138. package/dist/src/agents/researcher/cli-researcher/identity.md +1 -1
  139. package/dist/src/agents/researcher/web-researcher/identity.md +1 -1
  140. package/dist/src/agents/reviewer/reviewer/playbook.md +1 -1
  141. package/dist/src/agents/tester/ai-tester/identity.md +1 -1
  142. package/dist/src/agents/tester/api-tester/critical-reminders.md +1 -1
  143. package/dist/src/agents/tester/api-tester/critical-requirements.md +1 -1
  144. package/dist/src/agents/tester/api-tester/identity.md +2 -2
  145. package/dist/src/agents/tester/cli-tester/identity.md +1 -1
  146. package/dist/src/agents/tester/web-tester/identity.md +3 -3
  147. package/dist/stores/wizard-store.js +7 -5
  148. package/package.json +10 -7
  149. package/src/agents/developer/ai-developer/critical-reminders.md +1 -1
  150. package/src/agents/developer/ai-developer/critical-requirements.md +1 -1
  151. package/src/agents/developer/ai-developer/identity.md +1 -1
  152. package/src/agents/developer/ai-developer/playbook.md +1 -1
  153. package/src/agents/developer/api-developer/identity.md +1 -1
  154. package/src/agents/developer/cli-developer/identity.md +1 -1
  155. package/src/agents/developer/web-developer/identity.md +1 -1
  156. package/src/agents/meta/codex-keeper/identity.md +1 -1
  157. package/src/agents/meta/convention-keeper/identity.md +1 -1
  158. package/src/agents/meta/skill-summoner/identity.md +1 -1
  159. package/src/agents/researcher/ai-researcher/identity.md +1 -1
  160. package/src/agents/researcher/api-researcher/identity.md +1 -1
  161. package/src/agents/researcher/cli-researcher/identity.md +1 -1
  162. package/src/agents/researcher/web-researcher/identity.md +1 -1
  163. package/src/agents/reviewer/reviewer/playbook.md +1 -1
  164. package/src/agents/tester/ai-tester/identity.md +1 -1
  165. package/src/agents/tester/api-tester/critical-reminders.md +1 -1
  166. package/src/agents/tester/api-tester/critical-requirements.md +1 -1
  167. package/src/agents/tester/api-tester/identity.md +2 -2
  168. package/src/agents/tester/cli-tester/identity.md +1 -1
  169. package/src/agents/tester/web-tester/identity.md +3 -3
  170. package/src/schemas/custom-metadata.schema.json +3 -0
  171. package/src/schemas/metadata.schema.json +3 -0
  172. package/src/schemas/plugin.schema.json +3 -0
  173. package/src/schemas/project-config.schema.json +4 -8
  174. package/src/schemas/project-source-config.schema.json +2 -2
  175. package/dist/chunk-2HC2SNRP.js.map +0 -1
  176. package/dist/chunk-35VOK7XE.js.map +0 -1
  177. package/dist/chunk-FIHTAFST.js.map +0 -1
  178. package/dist/chunk-FRWKCE6R.js.map +0 -1
  179. package/dist/chunk-HEBPKK5L.js.map +0 -1
  180. package/dist/chunk-JC7DBPRD.js.map +0 -1
  181. package/dist/chunk-K7PJDWER.js.map +0 -1
  182. package/dist/chunk-KET3EVGX.js +0 -41
  183. package/dist/chunk-KET3EVGX.js.map +0 -1
  184. package/dist/chunk-M5HSTNYU.js.map +0 -1
  185. package/dist/chunk-NXQAY5U7.js.map +0 -1
  186. package/dist/chunk-OJJLYHM3.js +0 -34
  187. package/dist/chunk-OJJLYHM3.js.map +0 -1
  188. package/dist/chunk-ORJ5Y222.js.map +0 -1
  189. package/dist/chunk-R54KIGN2.js.map +0 -1
  190. package/dist/chunk-REKOWTIB.js.map +0 -1
  191. package/dist/chunk-TY6CAOL7.js.map +0 -1
  192. package/dist/chunk-U2DNAHFE.js.map +0 -1
  193. package/dist/chunk-U2YSGBHA.js.map +0 -1
  194. package/dist/chunk-VGEBYCQZ.js.map +0 -1
  195. package/dist/chunk-X5XJ6WKO.js.map +0 -1
  196. package/dist/copy-local-skills-KF2RAVD3.js +0 -14
  197. package/dist/load-agent-defs-DGXGBU3Q.js +0 -15
  198. package/dist/recompile-project-agents-CJVBAWDJ.js +0 -20
  199. /package/dist/{chunk-ZNDLUWWD.js.map → chunk-4A4L3YIW.js.map} +0 -0
  200. /package/dist/{chunk-WDAO3RUY.js.map → chunk-5F2YR5XV.js.map} +0 -0
  201. /package/dist/{chunk-JFAUQDZM.js.map → chunk-5OKLCVM4.js.map} +0 -0
  202. /package/dist/{chunk-K3O3YQYG.js.map → chunk-G47TDUK3.js.map} +0 -0
  203. /package/dist/{chunk-NSJ2S7R5.js.map → chunk-ILUVL7WM.js.map} +0 -0
  204. /package/dist/{chunk-R4SEU3DF.js.map → chunk-LJCNUP6M.js.map} +0 -0
  205. /package/dist/{chunk-Q5FLW4JG.js.map → chunk-OKH64JZE.js.map} +0 -0
  206. /package/dist/{chunk-WG6V6VJV.js.map → chunk-PCC4LBKB.js.map} +0 -0
  207. /package/dist/{chunk-EFU6P3B7.js.map → chunk-PNMM5HNX.js.map} +0 -0
  208. /package/dist/{chunk-4VYALFQZ.js.map → chunk-QWVXOCXO.js.map} +0 -0
  209. /package/dist/{chunk-IO4VEW5U.js.map → chunk-SY4X2LND.js.map} +0 -0
  210. /package/dist/{chunk-XGMOXMS4.js.map → chunk-TBOVYLQJ.js.map} +0 -0
  211. /package/dist/{chunk-6CNRMCFM.js.map → chunk-VPASBA7P.js.map} +0 -0
  212. /package/dist/{chunk-V3ENMW7G.js.map → chunk-WFRTHH3A.js.map} +0 -0
  213. /package/dist/{chunk-ACKC577F.js.map → chunk-Y5Y7XHVU.js.map} +0 -0
  214. /package/dist/{copy-local-skills-KF2RAVD3.js.map → components/common/removal-plan-confirm.js.map} +0 -0
  215. /package/dist/{load-agent-defs-DGXGBU3Q.js.map → copy-local-skills-NSUTBVLJ.js.map} +0 -0
  216. /package/dist/{loader-4U7UCE2Y.js.map → load-agent-defs-X4E57I2U.js.map} +0 -0
  217. /package/dist/{recompile-project-agents-CJVBAWDJ.js.map → loader-G6BFG2VA.js.map} +0 -0
  218. /package/dist/{source-loader-ZNSYJJCI.js.map → recompile-project-agents-JE4MM72I.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/lib/loading/source-loader.ts","../src/cli/lib/installation/is-home-directory.ts","../src/cli/lib/metadata-keys.ts","../src/cli/lib/configuration/config.ts","../src/cli/lib/configuration/config-loader.ts","../src/cli/lib/installation/install-base-dir.ts","../src/cli/lib/configuration/config-generator.ts","../../matrix/src/vendor/generated/source-types.ts","../../matrix/src/read-model/collections.ts","../../matrix/src/vendor/generated/matrix.ts","../../matrix/src/built-in-matrix.ts","../../matrix/src/read-model/source.ts","../../matrix/src/read-model/domains.ts","../../matrix/src/read-model/catalog.ts","../../matrix/src/generated/agents.ts","../../matrix/src/built-in-agents.ts","../../matrix/src/vendor/matrix.ts","../../matrix/src/read-model/preload-defaults.ts","../../matrix/src/read-model/sub-agents.ts","../../matrix/src/read-model/assignment-defaults.ts","../../matrix/src/read-model/stacks.ts","../../matrix/src/read-model/selection-defaults.ts","../../matrix/src/read-model/selection-semantics.ts","../../matrix/src/contract/selection-scenarios.ts","../../matrix/src/seed.ts","../../matrix/src/matrix-schema.ts","../../matrix/src/skill-index.ts","../src/cli/lib/configuration/scope-predicates.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-types-writer.ts","../src/cli/utils/string.ts","../src/cli/lib/skills/skill-metadata.ts","../src/cli/lib/versioning.ts","../src/cli/utils/yaml-schema.ts","../src/cli/lib/skills/skill-copier.ts","../src/cli/lib/skills/skill-plugin-compiler.ts","../src/cli/lib/plugins/plugin-manifest.ts","../src/cli/lib/plugins/plugin-finder.ts","../src/cli/lib/plugins/plugin-ref.ts","../src/cli/lib/plugins/plugin-info.ts","../src/cli/lib/installation/installation.ts","../src/cli/lib/installation/local-installer.ts","../src/cli/lib/loading/source-fetcher.ts","../src/cli/lib/validate-kebab-name.ts","../src/cli/utils/messages.ts","../src/cli/lib/loading/multi-source-loader.ts","../src/cli/lib/resolver.ts","../src/cli/lib/compiler.ts","../src/cli/lib/agents/agent-provenance.ts","../src/cli/lib/validation-result.ts","../src/cli/lib/agents/write-compiled-agents.ts","../src/cli/lib/config-gate/index.ts","../src/cli/lib/configuration/config-writer.ts","../src/cli/lib/config-gate/classify.ts","../src/cli/lib/config-gate/deps.ts","../src/cli/lib/config-gate/pair-writer.ts","../src/cli/lib/config-gate/propagate.ts","../src/cli/lib/config-gate/recompile.ts","../src/cli/utils/exec.ts","../src/cli/lib/installation/mode-migrator.ts","../src/cli/lib/plugins/plugin-settings.ts","../src/cli/lib/plugins/plugin-discovery.ts","../src/cli/lib/plugins/plugin-validator.ts","../src/cli/lib/skills/local-skill-loader.ts","../src/cli/lib/skills/unresolved-skill-entries.ts","../src/cli/lib/skills/local-skill-mover.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/configuration/skill-audit.ts","../src/cli/lib/matrix/matrix-health-check.ts"],"sourcesContent":["import os from \"os\";\nimport { unique } from \"remeda\";\nimport path from \"path\";\nimport {\n MARKETPLACE_JSON,\n PROJECT_ROOT,\n SKILL_CATEGORIES_PATH,\n SKILL_RULES_PATH,\n SKILLS_DIR_PATH,\n LOCAL_PSEUDO_CATEGORY,\n STANDARD_FILES,\n} from \"../../consts\";\nimport { defaultCategories } from \"../configuration/default-categories\";\nimport { defaultStacks } from \"../configuration/default-stacks\";\nimport { isHomeDirectory } from \"../installation/is-home-directory\";\nimport { LOCAL_DEFAULTS, METADATA_KEYS } from \"../metadata-keys\";\nimport type {\n AgentDefinition,\n AgentName,\n CategoryMap,\n CategoryPath,\n ExtractedSkillMetadata,\n MergedSkillsMatrix,\n ResolvedSkill,\n ResolvedStack,\n SkillAssignment,\n SkillId,\n SkillScope,\n Stack,\n Category,\n} from \"../../types\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { fileExists } from \"../../utils/fs\";\nimport { verbose, warn } from \"../../utils/logger\";\nimport { typedEntries, typedFromEntries, typedKeys } from \"../../utils/typed-object\";\nimport {\n isDefaultSource,\n isLocalSource,\n isPublicCatalogueCheckout,\n loadProjectSourceConfig,\n offersBuiltInStacks,\n resolveSource,\n type ResolvedConfig,\n type SourceCaller,\n} from \"../configuration\";\nimport { discoverLocalSkills, type LocalSkillDiscoveryResult } from \"../skills\";\nimport {\n checkMatrixHealth,\n claimSlug,\n extractAllSkills,\n loadSkillCategories,\n loadSkillRules,\n mergeMatrixWithSkills,\n relationshipsForSource,\n} from \"../matrix\";\nimport { loadAllAgents } from \"./loader\";\nimport {\n fetchFromSource,\n fetchMarketplace,\n MarketplaceManifestAbsentError,\n} 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 /**\n * Whether this load may reach the init-time source rungs — see {@link SourceCaller}.\n * Defaults to `\"stored\"`: the ambient environment can only be reached by a caller that\n * names itself `init`, so no path arrives there by omission.\n */\n caller?: SourceCaller;\n sourceFlag?: string;\n projectDir?: string;\n devMode?: boolean;\n /** Skip loading skills from extra sources (multi-source). Only needed for wizard UI tagging. */\n skipExtraSources?: boolean;\n /**\n * The caller only needs the matrix, not skill files on disk. For the default\n * source this skips the `fetchFromSource` clone (the matrix is the pre-computed\n * BUILT_IN_MATRIX anyway) so the load stays offline; `sourcePath` comes back\n * empty. Sources that must be read from disk to build the matrix (local paths,\n * custom remotes) are unaffected.\n */\n matrixOnly?: 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 {\n caller = \"stored\",\n sourceFlag,\n projectDir,\n devMode = false,\n matrixOnly = false,\n } = options;\n\n const sourceConfig = await resolveSource({ caller, flag: sourceFlag, projectDir });\n const { source } = sourceConfig;\n\n verbose(`Loading skills from source: ${source}`);\n\n const result = await resolveBaseResult(source, sourceConfig, devMode, matrixOnly);\n\n const resolvedProjectDir = projectDir || process.cwd();\n\n // Everything the marketplace itself carries, read before any local skill is merged on\n // top: past this point a skill's provenance is no longer legible from the matrix, and\n // an id the merge INTRODUCES is one nothing but the copy on disk backs.\n const marketplaceSkillIds = new Set(typedKeys<SkillId>(result.matrix.skills));\n\n // Load global local skills first, then project local skills — project wins on conflict\n const homeDir = os.homedir();\n if (!isHomeDirectory(resolvedProjectDir)) {\n result.matrix = await mergeDiscoveredLocalSkills(result.matrix, homeDir, \"global\");\n }\n result.matrix = await mergeDiscoveredLocalSkills(result.matrix, resolvedProjectDir, \"project\");\n\n if (!options.skipExtraSources) {\n await loadSkillsFromAllSources(\n result.matrix,\n sourceConfig,\n resolvedProjectDir,\n result.marketplace,\n idsOutsideMarketplace(result.matrix, marketplaceSkillIds),\n );\n }\n\n checkMatrixHealth(result.matrix);\n initializeMatrix(result.matrix);\n\n return result;\n}\n\n/**\n * Skills the merged matrix holds that the marketplace never offered — the local merge's\n * own additions. Eject is the only install any of them can have, so they are the ids the\n * tagging pass must leave a marketplace entry off.\n */\nfunction idsOutsideMarketplace(\n matrix: MergedSkillsMatrix,\n marketplaceSkillIds: ReadonlySet<SkillId>,\n): ReadonlySet<SkillId> {\n return new Set(typedKeys<SkillId>(matrix.skills).filter((id) => !marketplaceSkillIds.has(id)));\n}\n\n/**\n * The shipped catalogue, in a copy this load may write into. Every collection the\n * local-skill merge writes to is copied: `BUILT_IN_MATRIX` is a module constant,\n * so a shared reference would leave one project's local skill in the catalogue\n * every later load reads.\n */\nfunction copyOfBuiltInMatrix(): MergedSkillsMatrix {\n return {\n ...BUILT_IN_MATRIX,\n skills: { ...BUILT_IN_MATRIX.skills },\n categories: { ...BUILT_IN_MATRIX.categories },\n suggestedStacks: [...BUILT_IN_MATRIX.suggestedStacks],\n slugMap: {\n slugToId: { ...BUILT_IN_MATRIX.slugMap.slugToId },\n idToSlug: { ...BUILT_IN_MATRIX.slugMap.idToSlug },\n },\n };\n}\n\n/**\n * Resolves the base matrix for the configured source: the pre-computed\n * BUILT_IN_MATRIX for the default source, otherwise a local or remote load.\n */\nasync function resolveBaseResult(\n source: string,\n sourceConfig: SourceLoadResult[\"sourceConfig\"],\n devMode: boolean,\n matrixOnly: boolean,\n): Promise<SourceLoadResult> {\n if (isDefaultSource(source) && !devMode) {\n // Default source: use pre-computed BUILT_IN_MATRIX instead of loading from disk.\n // Still resolve sourcePath via fetchFromSource so skill files can be read\n // (e.g. for eject-mode copy) — unless the caller declared matrixOnly, in\n // which case the fetch (a network clone on a cold cache) is skipped entirely.\n // The fetch is cached, so no network call if the clone already exists.\n const sourcePath = matrixOnly ? \"\" : (await fetchFromSource(source)).path;\n return {\n matrix: copyOfBuiltInMatrix(),\n sourceConfig,\n sourcePath,\n isLocal: false,\n ...(sourceConfig.marketplace !== undefined && { marketplace: sourceConfig.marketplace }),\n };\n }\n\n const isLocal = isLocalSource(source) || devMode === true;\n return isLocal ? loadFromLocal(source, sourceConfig) : loadFromRemote(source, sourceConfig);\n}\n\ntype MarketplaceLabels = Pick<SourceLoadResult, \"marketplace\">;\n\n/**\n * Which state a marketplace's manifest is in, as far as naming the marketplace goes.\n *\n * Three states rather than two because the two failures are not the same event: a\n * marketplace with no manifest is an ordinary local directory, while one whose manifest\n * is there and refused is a broken publication, and the author is the only person who\n * can repair it. Collapsing them reported every schema violation in that file as an\n * absent file, and a reader who checked found it exactly where the message said it was\n * not. `doctor`'s `ConfigState` splits its own three the same way and for the same reason.\n */\ntype ManifestState =\n { kind: \"absent\" } | { kind: \"unreadable\"; reason: string } | { kind: \"named\"; name: string };\n\n/**\n * {@link ManifestState} for one marketplace. Absence is read off the throw's TYPE rather\n * than its text: `fetchMarketplace` is the only thing that can tell a file it never found\n * from one it found and refused, so it says which, and nothing here matches on a sentence.\n */\nasync function readManifestState(source: string): Promise<ManifestState> {\n try {\n const { marketplace } = await fetchMarketplace(source);\n return { kind: \"named\", name: marketplace.name };\n } catch (error) {\n if (error instanceof MarketplaceManifestAbsentError) return { kind: \"absent\" };\n return { kind: \"unreadable\", reason: getErrorMessage(error) };\n }\n}\n\n/** The label a config already recorded, which outlives a manifest this load could not name. */\nfunction configuredLabel(sourceConfig: ResolvedConfig): MarketplaceLabels {\n return sourceConfig.marketplace === undefined ? {} : { marketplace: sourceConfig.marketplace };\n}\n\n/**\n * Resolves the marketplace name from the source's\n * `.claude-plugin/marketplace.json`. A `marketplace` already recorded in the\n * project config wins; sources this load cannot name keep whatever the config had\n * (possibly nothing) and are labelled by their source name.\n */\nasync function resolveMarketplaceLabels(\n source: string,\n sourceConfig: ResolvedConfig,\n): Promise<MarketplaceLabels> {\n const state = await readManifestState(source);\n\n switch (state.kind) {\n case \"named\": {\n const marketplace = sourceConfig.marketplace ?? state.name;\n verbose(`Using marketplace name from ${MARKETPLACE_JSON}: ${marketplace}`);\n return { marketplace };\n }\n case \"absent\":\n verbose(`Marketplace has no ${MARKETPLACE_JSON} — using its ref as the label`);\n return configuredLabel(sourceConfig);\n case \"unreadable\":\n warn(\n `Marketplace has a ${MARKETPLACE_JSON} this CLI cannot read, so its ref is the label instead:\\n${state.reason}`,\n );\n return configuredLabel(sourceConfig);\n default: {\n const exhaustive: never = state;\n return exhaustive;\n }\n }\n}\n\n/** Merges any discovered local skills for `dir` into the matrix, logging the find. */\nasync function mergeDiscoveredLocalSkills(\n matrix: MergedSkillsMatrix,\n dir: string,\n label: SkillScope,\n): Promise<MergedSkillsMatrix> {\n const discovered = await discoverLocalSkills(dir);\n if (!discovered || discovered.skills.length === 0) return matrix;\n verbose(\n `Found ${discovered.skills.length} ${label} local skill(s) in ${discovered.localSkillsPath}`,\n );\n return mergeLocalSkillsIntoMatrix(matrix, discovered);\n}\n\nasync function loadFromLocal(\n source: string,\n sourceConfig: ResolvedConfig,\n): Promise<SourceLoadResult> {\n // Resolved through `fetchFromSource` — the same call `loadFromRemote` makes — rather\n // than joined here, so a path the user named and the CLI cannot read is REFUSED with\n // the loader's own message. Reading it directly returned an empty matrix instead, and\n // `init`/`edit` went on to mount a wizard over nothing the user asked for.\n const skillsPath = isLocalSource(source) ? (await fetchFromSource(source)).path : PROJECT_ROOT;\n\n verbose(`Loading skills from local path: ${skillsPath}`);\n\n const mergedMatrix = await loadAndMergeFromBasePath(skillsPath, source);\n const labels = await resolveMarketplaceLabels(skillsPath, sourceConfig);\n\n return {\n matrix: mergedMatrix,\n sourceConfig,\n sourcePath: skillsPath,\n isLocal: true,\n ...labels,\n };\n}\n\nasync function loadFromRemote(\n source: string,\n sourceConfig: ResolvedConfig,\n): Promise<SourceLoadResult> {\n verbose(`Fetching skills from remote source: ${source}`);\n\n const fetchResult = await fetchFromSource(source);\n\n verbose(`Fetched to: ${fetchResult.path}`);\n\n const mergedMatrix = await loadAndMergeFromBasePath(fetchResult.path, source);\n const labels = await resolveMarketplaceLabels(source, sourceConfig);\n\n return {\n matrix: mergedMatrix,\n sourceConfig,\n sourcePath: fetchResult.path,\n isLocal: false,\n ...labels,\n };\n}\n\n/**\n * The matrix a marketplace on disk describes — its own skills, its own\n * categories and stacks, and the built-in relationship rules narrowed to the\n * slugs it actually ships.\n *\n * This is the load an AUTHOR's command makes, and it is deliberately not\n * {@link loadSkillsMatrixFromSource}: that one merges the invoking machine's\n * `~/.claude/skills` and the project's own into the result, which is right for\n * an install and wrong for anything published — a catalogue carrying the\n * author's private skills offers consumers skills that exist on one machine.\n * The local merge lives one layer up, in the install path alone.\n *\n * A marketplace's base path is also the only word anything has for WHICH\n * marketplace it is, so it stands as the source string too.\n */\nexport async function loadMarketplaceMatrix(marketplaceDir: string): Promise<MergedSkillsMatrix> {\n return loadAndMergeFromBasePath(marketplaceDir, marketplaceDir);\n}\n\n/**\n * Builds the matrix for a source read from disk, from the files under\n * `basePath`. `source` is the source string that base path stands for — the\n * loader's only word for WHICH marketplace it is reading, and one of the two\n * things {@link resolveOfferedStacks} decides the built-in catalogue's fate on.\n */\nasync function loadAndMergeFromBasePath(\n basePath: string,\n source: string,\n): Promise<MergedSkillsMatrix> {\n const sourceProjectConfig = await loadProjectSourceConfig(basePath);\n\n const skillsDirRelPath = sourceProjectConfig?.skillsDir ?? SKILLS_DIR_PATH;\n const stacksRelFile = sourceProjectConfig?.stacksFile;\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 const sourceCategories = hasSourceCategories\n ? await loadSkillCategories(sourceCategoriesPath)\n : undefined;\n if (sourceCategories) {\n verbose(\n `Loaded source categories: ${sourceCategoriesPath} (${typedKeys(sourceCategories).length} categories)`,\n );\n }\n const categories: CategoryMap = sourceCategories\n ? { ...defaultCategories, ...sourceCategories }\n : defaultCategories;\n\n const sourceRules = hasSourceRules ? await loadSkillRules(sourceRulesPath) : undefined;\n if (sourceRules) {\n verbose(`Loaded source rules: ${sourceRulesPath}`);\n }\n\n if (hasSourceCategories || hasSourceRules) {\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 await refuseCatalogueCollisions(basePath, source, skills);\n\n const relationships = relationshipsForSource(skills, sourceRules);\n const mergedMatrix = mergeMatrixWithSkills(categories, relationships, skills);\n initializeMatrix(mergedMatrix);\n\n // Assigned unconditionally: a source offering no stacks is a matrix carrying\n // none, which is the whole of what the wizard needs to skip the stack step.\n const stacks = await resolveOfferedStacks(basePath, stacksRelFile, source);\n mergedMatrix.suggestedStacks = stacks.map((stack) => convertStackToResolvedStack(stack));\n\n // Collect explicit domain definitions from agent metadata.yaml files\n const agents = await loadAllAgents(basePath);\n const agentDefinedDomains = typedFromEntries(\n typedEntries<AgentName, AgentDefinition>(agents).flatMap(([agentId, agentDef]) =>\n agentDef.domain ? [[agentId, agentDef.domain] as const] : [],\n ),\n );\n const domainCount = typedKeys(agentDefinedDomains).length;\n if (domainCount > 0) {\n mergedMatrix.agentDefinedDomains = agentDefinedDomains;\n verbose(`Loaded ${domainCount} agent domain definition(s)`);\n }\n\n return mergedMatrix;\n}\n\n/** Every skill id the shipped catalogue owns — the ids no other marketplace may take. */\nconst CATALOGUE_SKILL_IDS: ReadonlySet<SkillId> = new Set(typedKeys(BUILT_IN_MATRIX.skills));\n\n/** How many colliding ids a refusal lists before summarising the rest. */\nconst MAX_REPORTED_COLLISIONS = 10;\n\n/**\n * Refuses a marketplace shipping skill ids the public catalogue already owns.\n *\n * A skill id is the directory the skill installs into, and Claude reads\n * `~/.claude` and `./.claude` together, so two marketplaces naming one id means\n * one silently shadows the other. `build marketplace` refuses those ids at author\n * time; this is what catches a marketplace that skipped that build, was\n * hand-edited, or is lying — nothing a source ships is unforgeable, so the\n * consumer's own load has to ask the question again.\n *\n * The SOURCE is refused, not the colliding skills: dropping them would hand the\n * user a marketplace quietly missing the skills they chose it for, leave the\n * catalogue's own copies standing in under those ids, and tell the author\n * nothing. One loud refusal naming the fix beats a partial load that hides it.\n */\nasync function refuseCatalogueCollisions(\n basePath: string,\n source: string,\n skills: ExtractedSkillMetadata[],\n): Promise<void> {\n const collidingIds = skills.map((skill) => skill.id).filter((id) => CATALOGUE_SKILL_IDS.has(id));\n if (collidingIds.length === 0) return;\n if (await isPublicCatalogueCheckout(basePath)) return;\n\n throw new Error(catalogueCollisionError(collidingIds, source));\n}\n\nfunction catalogueCollisionError(collidingIds: SkillId[], source: string): string {\n const listed = collidingIds.slice(0, MAX_REPORTED_COLLISIONS).map((id) => ` ${id}`);\n const unlisted = collidingIds.length - listed.length;\n\n return [\n `Marketplace '${source}' ships ${collidingIds.length} skill id(s) the public catalogue ` +\n `already owns:`,\n ...listed,\n ...(unlisted > 0 ? [` ... and ${unlisted} more`] : []),\n `A skill id is the directory the skill installs into, so these would shadow the public ` +\n `catalogue's own skills. Every id must carry its marketplace's name as a namespace — ` +\n `'<marketplace>-<id>'. Rename each skill and the 'name' in its SKILL.md, then re-run ` +\n `'build marketplace', which refuses the same ids before they are published.`,\n ].join(\"\\n\");\n}\n\n/**\n * The stacks a source offers the wizard: the ones it ships, or — for the public\n * catalogue alone — the CLI's built-in catalogue standing in when it ships none.\n *\n * A custom marketplace gets no such stand-in. Handing it one meant offering a\n * catalogue of stacks written against a different catalogue of skills, under a\n * name the user never asked for, with most of each stack silently dropped for\n * naming ids the chosen source does not carry. A marketplace ships its own\n * stacks or offers none, and none means a wizard with no stack step rather than\n * one showing somebody else's list.\n */\nasync function resolveOfferedStacks(\n basePath: string,\n stacksFile: string | undefined,\n source: string,\n): Promise<Stack[]> {\n const sourceStacks = await loadStacks(basePath, stacksFile);\n if (sourceStacks.length > 0) {\n verbose(`Offering the ${sourceStacks.length} stacks the source ships`);\n return sourceStacks;\n }\n\n if (await offersBuiltInStacks(basePath, source)) {\n verbose(\n `The public catalogue ships no stacks — offering the ${defaultStacks.length} built-in stacks`,\n );\n return defaultStacks;\n }\n\n verbose(`Marketplace '${source}' ships no stacks, and gets no built-in stand-in — offering none`);\n return [];\n}\n\n// Stack values are already skill IDs — no alias resolution needed\nexport function convertStackToResolvedStack(stack: Stack): ResolvedStack {\n const agentConfigs = typedKeys<AgentName>(stack.agents).flatMap((agentId) => {\n const agentConfig = stack.agents[agentId];\n return agentConfig ? [{ agentId, agentConfig }] : [];\n });\n\n const skills = typedFromEntries(\n agentConfigs.map(\n ({ agentId, agentConfig }) => [agentId, resolveStackAgentSkills(agentConfig)] as const,\n ),\n );\n\n // First-seen order across agents, matching the historical seen-Set accumulation\n const allSkillIds = unique(\n agentConfigs.flatMap(({ agentConfig }) =>\n resolveAgentConfigToSkills(agentConfig).map((ref) => ref.id),\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/** Per-category skill ids for one stack agent, keeping only ids present in the current matrix. */\nfunction resolveStackAgentSkills(\n agentConfig: Partial<Record<Category, SkillAssignment[]>>,\n): Partial<Record<Category, SkillId[]>> {\n const byCategory = typedEntries<Category, SkillAssignment[]>(agentConfig)\n .map(([category, assignments]) => ({\n category,\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n validIds: (assignments ?? []).filter((a) => a.id in currentMatrix.skills).map((a) => a.id),\n }))\n .filter(({ validIds }) => validIds.length > 0);\n return typedFromEntries(\n byCategory.map(({ category, validIds }) => [category, validIds] as const),\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 */\nexport function 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 * Whether this matrix carries a definition for the category. `local` never is\n * one — it is the trapdoor a skill wears when it belongs to no category at all.\n */\nfunction declaresCategory(matrix: MergedSkillsMatrix, category: CategoryPath): boolean {\n return category !== LOCAL_PSEUDO_CATEGORY && matrix.categories[category] !== undefined;\n}\n\n/**\n * Why a custom skill was dropped, and which file places it.\n *\n * The categories on offer are deliberately not listed: they are the whole\n * catalogue's, and a refusal that prints a hundred names is one nobody reads.\n * Whatever the user picked the category in renders them already.\n */\nfunction undeclaredCategoryRefusal(\n metadata: ExtractedSkillMetadata,\n category: CategoryPath,\n): string {\n const metadataPath = path.join(metadata.path, STANDARD_FILES.METADATA_YAML);\n return (\n `Skipping local skill '${metadata.id}': ${METADATA_KEYS.CATEGORY} '${category}' is not one this ` +\n `installation declares, so the skill belongs in no grid tab and can be given to no sub-agent. ` +\n `Set ${METADATA_KEYS.CATEGORY} in ${metadataPath} to a category that already exists — a skill ` +\n `is placed in the taxonomy, it does not extend it.`\n );\n}\n\nexport function 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 // A custom skill is PLACED in the taxonomy — its category is picked from the\n // ones that exist, never invented — so one naming a category nothing declares\n // means no pick happened. Synthesizing a definition for it is what let a\n // fabricated category read as a real placement while the skill sat in a tab\n // nothing draws. Local skills that claim no `custom` flag keep the old\n // behaviour below; narrowing that is matrix hygiene, not this rule.\n if (metadata.custom === true && !declaresCategory(matrix, category)) {\n warn(undeclaredCategoryRefusal(metadata, category));\n continue;\n }\n\n const resolvedSkill: ResolvedSkill = {\n id: metadata.id,\n slug,\n displayName,\n description: metadata.description,\n ...(metadata.usageGuidance !== undefined && { usageGuidance: metadata.usageGuidance }),\n\n category,\n\n author: LOCAL_DEFAULTS.AUTHOR,\n\n conflictsWith: existingSkill?.conflictsWith ?? [],\n requires: existingSkill?.requires ?? [],\n alternatives: existingSkill?.alternatives ?? [],\n discourages: existingSkill?.discourages ?? [],\n\n path: metadata.path,\n\n local: true,\n ...(metadata.localPath !== undefined && { localPath: metadata.localPath }),\n ...(metadata.custom !== undefined && { custom: metadata.custom }),\n };\n\n matrix.skills[metadata.id] = resolvedSkill;\n\n // Completes the map over the matrix this merge is building: the skill went\n // into `matrix.skills` and the slug map stayed as the source left it, so\n // `getSkillBySlug` — the asserting lookup the matrix barrel exports — threw\n // for every skill a user had written themselves.\n claimSlug(matrix.slugMap, slug, metadata.id);\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_PSEUDO_CATEGORY && !matrix.categories[category]) {\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 fs from \"fs\";\nimport os from \"os\";\n\n/**\n * True when `dir` is the user's home directory — the global installation root.\n *\n * Symlink-safe: compares via `fs.realpathSync` so a symlinked $HOME (common on\n * macOS) still matches. Falls back to a plain string compare when either path\n * cannot be resolved (e.g. does not exist yet). Calls `os.homedir()` at runtime\n * (not the module-load-time `GLOBAL_INSTALL_ROOT` constant) so it agrees with\n * other runtime `os.homedir()` callers and with test home-dir mocks.\n */\nexport function isHomeDirectory(dir: string): boolean {\n try {\n return fs.realpathSync(dir) === fs.realpathSync(os.homedir());\n } catch {\n return dir === os.homedir();\n }\n}\n","import { STANDARD_FILES, STANDARD_DIRS } from \"../consts\";\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 * What a skill discovered on disk is attributed to.\n *\n * Forced rather than defaulted: the merge writes it over whatever the file says,\n * because a local skill answers to the machine it sits on and not to a handle.\n *\n * It used to have a `CATEGORY` and a `DOMAIN` beside it — `dummy-category` and\n * `dummy`, a taxonomy in no union, placing a skill in a tab nothing draws and a\n * stack no sub-agent reads. They were scaffold placeholders for `new skill` and\n * `import skill`, and both commands were deleted; nothing has read either since.\n */\nexport const LOCAL_DEFAULTS = {\n AUTHOR: \"@dummy-author\",\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","import os from \"os\";\nimport path from \"path\";\nimport { z } from \"zod\";\nimport { fileExists, readFileOptional } from \"../../utils/fs\";\nimport { verbose, warn } from \"../../utils/logger\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport {\n DEFAULT_BRANDING,\n GITHUB_SOURCE,\n PUBLIC_CATALOGUE_PACKAGE,\n STANDARD_FILES,\n} from \"../../consts\";\nimport { projectSourceConfigSchema } from \"../schemas\";\nimport type { ProjectConfig, SourceEntry } from \"../../types\";\nimport { ConfigDefaultExportError, ConfigSchemaError, loadConfig } from \"./config-loader\";\nimport { getProjectConfigPath } from \"../installation/install-base-dir\";\nimport { isHomeDirectory } from \"../installation/is-home-directory\";\n\nexport const DEFAULT_SOURCE = `${GITHUB_SOURCE.GITHUB_PREFIX}agents-inc/skills`;\nexport const SOURCE_ENV_VAR = \"CC_MARKETPLACE\";\n\n// Re-export types that moved to src/cli/types/config.ts for backward compatibility\nexport type { SourceEntry, BrandingConfig } from \"../../types/config\";\n\n// getProjectConfigPath lives in install-base-dir.ts (a neutral leaf) to avoid an\n// import cycle; re-exported here for existing importers of this module.\nexport { getProjectConfigPath };\n\nexport type ResolvedConfig = {\n source: string;\n sourceOrigin: \"flag\" | \"env\" | \"project\" | \"global\" | \"default\";\n marketplace?: string;\n};\n\n/**\n * Who is asking for a marketplace, and therefore whether this run may CHOOSE one.\n *\n * Choosing is an install-time decision (owner ruling 2026-08-09): `--marketplace` is\n * `init`'s flag and nobody else's, and {@link SOURCE_ENV_VAR} is the same choice made\n * without typing it — so the environment rung is read for `init` and for nothing else.\n * Every later command asks as `\"stored\"` and gets what the install recorded: the\n * project config, then the global one, then {@link DEFAULT_SOURCE}.\n *\n * A `\"stored\"` caller may still NAME a marketplace it is reading for its own sake —\n * `doctor` validating a marketplace repository points the loader at a path — which is why\n * the flag is not tied to the caller. What `init` alone gets is the ambient environment.\n */\nexport type SourceCaller = \"init\" | \"stored\";\n\nexport type ResolveSourceRequest = {\n caller: SourceCaller;\n /** The marketplace this run named, where it named one. */\n flag?: string | undefined;\n /** The project whose `config.ts` is the first stored rung. */\n projectDir?: string | undefined;\n};\n\nasync function loadSourceConfig(\n dir: string,\n scope: \"project\" | \"global\",\n): Promise<Partial<ProjectConfig> | null> {\n const scopeLabel = scope === \"project\" ? \"Project\" : \"Global\";\n const configPath = getProjectConfigPath(dir);\n\n if (!(await fileExists(configPath))) {\n verbose(`${scopeLabel} config not found at ${configPath}`);\n return null;\n }\n\n let data: Partial<ProjectConfig> | null;\n try {\n data = await loadConfig(configPath, projectSourceConfigSchema);\n } catch (error) {\n // A shape the schema refused is raised, never reported as absence. `resolveSource` reads the\n // return value alone, so a swallowed refusal is indistinguishable from a config that is not\n // there — it walks past this rung to DEFAULT_SOURCE and installs from a marketplace nobody\n // named. A file that could not be evaluated at all stays the \"no config\" this loader has\n // always reported it as. A file whose exports are all named is on the loud side of that same\n // line: it evaluated, and everything it says is a statement about this install.\n if (error instanceof ConfigSchemaError || error instanceof ConfigDefaultExportError)\n throw error;\n verbose(`Failed to load ${scope} config at ${configPath}: ${getErrorMessage(error)}`);\n return null;\n }\n if (!data) return null;\n\n verbose(`Loaded ${scope} config from ${dir}`);\n return data;\n}\n\n/**\n * Load source config from a directory's own `.claude-src/config.ts`.\n *\n * The scope it announces is derived, not assumed: at the home root the file this reads\n * IS the global config, and a caller asking a project question there — `doctor` deciding\n * whether the cwd is a source repository — must not be told a project config was found\n * where none exists.\n */\nexport async function loadProjectSourceConfig(\n projectDir: string,\n): Promise<Partial<ProjectConfig> | null> {\n return loadSourceConfig(projectDir, isHomeDirectory(projectDir) ? \"global\" : \"project\");\n}\n\n/** Load source config from the global home directory (~/.claude-src/config.ts). */\nexport async function loadGlobalSourceConfig(): Promise<Partial<ProjectConfig> | null> {\n return loadSourceConfig(os.homedir(), \"global\");\n}\n\n/** The effective source config plus which scope it was actually loaded from. */\ntype EffectiveSourceConfig = {\n config: Partial<ProjectConfig>;\n origin: \"project\" | \"global\";\n};\n\nasync function loadEffectiveSourceConfig(\n projectDir?: string,\n): Promise<EffectiveSourceConfig | null> {\n const projectConfig = await loadOwnProjectSourceConfig(projectDir);\n if (projectConfig) return { config: projectConfig, origin: \"project\" };\n\n const globalConfig = await loadGlobalSourceConfig();\n if (globalConfig) return { config: globalConfig, origin: \"global\" };\n\n return null;\n}\n\n/**\n * A project's OWN source config, and nothing at the home root.\n *\n * `~/.claude-src/config.ts` is the global config, so reading it as a project's would label\n * one file both things at once: `compile` naming `Marketplace: project` beside\n * `Compiling global agents...`, `edit` announcing `(project)` while refusing scope toggles\n * as a global context. The axis is which FILE the settings were read from — never what\n * scope the skill and agent entries inside it carry.\n */\nasync function loadOwnProjectSourceConfig(\n projectDir: string | undefined,\n): Promise<Partial<ProjectConfig> | null> {\n if (projectDir === undefined || isHomeDirectory(projectDir)) return null;\n return loadProjectSourceConfig(projectDir);\n}\n\n/**\n * Precedence: flag > env > project > global > default, with the first two rungs\n * reachable by `init` alone — see {@link SourceCaller}.\n */\nexport async function resolveSource(request: ResolveSourceRequest): Promise<ResolvedConfig> {\n const { caller, flag, projectDir } = request;\n const effective = await loadEffectiveSourceConfig(projectDir);\n // The stored NAME becomes this result's `marketplace` — the ref it was read beside becomes the\n // `source`. Every return below carries the same name, present only when the config named one.\n const marketplaceName = effective?.config.marketplaceName;\n const marketplaceLabel = marketplaceName !== undefined && { marketplace: marketplaceName };\n\n if (flag !== undefined) {\n assertNamedSourceUsable(flag);\n verbose(`Marketplace named by this run: ${flag}`);\n return { source: flag, sourceOrigin: \"flag\", ...marketplaceLabel };\n }\n\n const envSource = caller === \"init\" ? readEnvSource() : undefined;\n if (envSource !== undefined) {\n return { source: envSource, sourceOrigin: \"env\", ...marketplaceLabel };\n }\n\n if (effective?.config.marketplace) {\n verbose(`Marketplace from ${effective.origin} config: ${effective.config.marketplace}`);\n return {\n source: effective.config.marketplace,\n sourceOrigin: effective.origin,\n ...marketplaceLabel,\n };\n }\n\n verbose(`Using default marketplace: ${DEFAULT_SOURCE}`);\n return { source: DEFAULT_SOURCE, sourceOrigin: \"default\", ...marketplaceLabel };\n}\n\n/**\n * How a marketplace this run NAMED is referred to back to whoever named it.\n *\n * Origin-neutral on purpose: `--marketplace` is `init`'s flag and nobody else's, while a\n * `\"stored\"` caller may still name a marketplace it is reading for its own sake — `doctor`\n * points the loader at a marketplace repository. Naming the flag in a sentence that caller\n * reads blames an option it never passed.\n */\nconst NAMED_SOURCE_LABEL = \"The marketplace\";\n\n/**\n * Refuses a named marketplace that cannot be one. Raised rather than warned: somebody named\n * this, so falling through to another would install from a place they did not name.\n */\nfunction assertNamedSourceUsable(flag: string): void {\n if (flag.trim() === \"\") {\n throw new Error(\n `${NAMED_SOURCE_LABEL} cannot be empty. Provide a valid marketplace: a local directory path or a git repository URL (e.g., './my-skills' or 'https://github.com/user/repo')`,\n );\n }\n validateSourceFormat(flag.trim(), NAMED_SOURCE_LABEL);\n}\n\n/**\n * The marketplace {@link SOURCE_ENV_VAR} names, or undefined when it names none this run.\n *\n * Unset, empty and unusable all fall through to the next rung with a warning rather than\n * a refusal — the environment is ambient, so an exported value nobody meant for this run\n * must not be able to fail it. That is the opposite of {@link assertNamedSourceUsable},\n * and deliberately so: one was typed at this command, the other was already there.\n */\nfunction readEnvSource(): string | undefined {\n const envValue = process.env[SOURCE_ENV_VAR];\n if (!envValue) return undefined;\n\n const trimmed = envValue.trim();\n if (trimmed === \"\") {\n warn(`${SOURCE_ENV_VAR} is set but empty — ignoring and falling back to the next rung.`);\n return undefined;\n }\n\n try {\n validateSourceFormat(trimmed, SOURCE_ENV_VAR);\n } catch (error) {\n warn(\n `${SOURCE_ENV_VAR} has an invalid value — ignoring and falling back to the next rung.\\n${getErrorMessage(error)}`,\n );\n return undefined;\n }\n\n verbose(`Marketplace from ${SOURCE_ENV_VAR} env var: ${trimmed}`);\n return trimmed;\n}\n\nexport async function resolveAuthor(projectDir?: string): Promise<string | undefined> {\n const effective = await loadEffectiveSourceConfig(projectDir);\n return effective?.config.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 effective = await loadEffectiveSourceConfig(projectDir);\n return {\n name: effective?.config.branding?.name ?? DEFAULT_BRANDING.NAME,\n tagline: effective?.config.branding?.tagline ?? DEFAULT_BRANDING.TAGLINE,\n };\n}\n\n/**\n * The one marketplace this installation reads skills from, as a {@link SourceEntry}.\n *\n * Distinct from {@link resolveSource}, which answers the same question as a\n * {@link ResolvedConfig} (source string plus where it came from). This is the shape the\n * surfaces that LIST sources want — `search` and `doctor` — and there is exactly one of\n * them: the registered-extras array this used to return alongside it was withdrawn with\n * the marketplace axis (CLI-450).\n */\nexport async function resolvePrimarySourceEntry(projectDir?: string): Promise<SourceEntry> {\n const resolvedConfig = await resolveSource({ caller: \"stored\", projectDir });\n return {\n name: \"marketplace\",\n url: resolvedConfig.source,\n description: \"Primary skills marketplace\",\n };\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 marketplace 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 marketplace value to validate\n * @param flagName - What carried this value, as the error messages name it back: `init`'s\n * `--marketplace`, {@link SOURCE_ENV_VAR}, or {@link NAMED_SOURCE_LABEL} when no flag did\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 `Marketplace 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 marketplace 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 marketplace (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 marketplace 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 `Marketplace 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 marketplaces 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 `Marketplace 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\n/**\n * Whether a resolved marketplace IS the default public one, asked of the source\n * STRING.\n *\n * The one place that question is answered, because more than one surface asks it\n * and they must agree: the install-mode tagger decides whether the marketplace it\n * labels skills with is public or private, and both stack lookups ask it as half\n * of {@link offersBuiltInStacks}. A marketplace named explicitly — by flag, env\n * or config — is the default one when it spells {@link DEFAULT_SOURCE}.\n *\n * A path is not this question's subject. Nothing in a source STRING that happens\n * to be a path says which repository it holds; {@link isPublicCatalogueCheckout}\n * asks the directory instead, and it is the one to use where a directory is in hand.\n */\nexport function isDefaultSource(source: string): boolean {\n return source === DEFAULT_SOURCE;\n}\n\n/** The only field of a repository's package.json this module reads. */\nconst packageIdentitySchema = z.object({ name: z.string() });\n\n/**\n * Whether the DIRECTORY at `basePath` is a checkout of the public catalogue's own\n * repository, read off package identity.\n *\n * Never off the name in `marketplace.json`: that name is a claim the author\n * writes, so a guard keyed on it would exempt exactly the source it exists to\n * catch. {@link PUBLIC_CATALOGUE_PACKAGE} carries what the signal is and is not\n * worth.\n *\n * The build side asks a different question of the same identity and is spelled\n * apart from this one on purpose: `isCatalogueOwnReservedName` in\n * `marketplace-generator.ts` asks whether a marketplace NAME about to be\n * published is the catalogue's own, and takes the package name it already holds\n * rather than a directory to read one from.\n */\nexport async function isPublicCatalogueCheckout(basePath: string): Promise<boolean> {\n const raw = await readFileOptional(path.join(basePath, STANDARD_FILES.PACKAGE_JSON));\n return declaredPackageName(raw) === PUBLIC_CATALOGUE_PACKAGE;\n}\n\n/** The `name` a package.json declares, or null when there is none to read. */\nfunction declaredPackageName(raw: string): string | null {\n let json: unknown;\n try {\n json = JSON.parse(raw);\n } catch {\n return null;\n }\n\n const parsed = packageIdentitySchema.safeParse(json);\n return parsed.success ? parsed.data.name : null;\n}\n\n/**\n * Whether the CLI's built-in stack catalogue stands in for a marketplace that\n * ships no stacks of its own.\n *\n * Two spellings of one marketplace, and BOTH stack lookups must read this rather\n * than either half. `resolveOfferedStacks` decides the list the wizard offers and\n * `loadStackById` resolves the id the user then picked; a rule they answer\n * differently offers a stack and refuses to install it.\n *\n * The built-in stacks ARE the public catalogue's stacks — that repository ships\n * no `config/stacks.ts` at all — so a checkout of it read off a path has to reach\n * them too, and the source string cannot say that a path is that repository.\n */\nexport async function offersBuiltInStacks(basePath: string, source: string): Promise<boolean> {\n return isDefaultSource(source) || (await isPublicCatalogueCheckout(basePath));\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 marketplace 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\";\nimport { isRecord } from \"../../utils/type-guards\";\nimport { formatZodIssues } from \"../schemas\";\nimport type { z } from \"zod\";\n\n/** Resolve agents-inc/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\n/**\n * Thrown when a config file evaluated cleanly but the schema refused its SHAPE.\n *\n * Named apart from the generic load failure because the two mean different things to a caller:\n * a file that cannot be evaluated says only that something is broken, while a refused shape has\n * said exactly what is wrong with a file the user still owns. A loader may reasonably report the\n * first as \"no config\"; reporting the second that way is how a config carrying a stale key ends\n * up silently repointing an install at the default marketplace.\n */\nexport class ConfigSchemaError extends Error {\n constructor(\n readonly configPath: string,\n readonly issues: string,\n ) {\n super(`Config validation failed at '${configPath}': ${issues}`);\n this.name = \"ConfigSchemaError\";\n }\n}\n\n/**\n * Thrown when a config file evaluated cleanly and exported bindings, none of which is the default\n * one every config in this project is read out of.\n *\n * Distinct from {@link ConfigSchemaError} because the two fault different lines of the file. A\n * refused shape names a field the author can go and correct; a module that exports\n * `export const skillRules = {...}` has nothing wrong with its contents at all, and validating\n * the module NAMESPACE against the schema is what told such an author their `version` was missing\n * from a file they can see it in.\n */\nexport class ConfigDefaultExportError extends Error {\n constructor(readonly configPath: string) {\n super(`Config at '${configPath}' has no default export`);\n this.name = \"ConfigDefaultExportError\";\n }\n}\n\n/**\n * The marker every ES module jiti transpiles carries, and a CommonJS one does not. It is the only\n * thing separating `export const x = {}` — a namespace whose keys are named exports — from\n * `module.exports = { x: {} }`, whose keys ARE the default export: both arrive here as a plain\n * object with no `default` key.\n */\nconst ES_MODULE_MARKER = \"__esModule\";\n\n/**\n * The default export, or the namespace when there is none — jiti documents `import(id, { default:\n * true })` as exactly this, and the namespace is imported whole here because the option throws the\n * distinction away and {@link ConfigDefaultExportError} is made of it.\n */\nfunction unwrapDefaultExport(namespace: unknown): unknown {\n if (isRecord(namespace) && namespace.default !== undefined) return namespace.default;\n return namespace;\n}\n\n/** An ES module that exports bindings, none of them the default one. */\nfunction declaresNoDefaultExport(namespace: unknown): boolean {\n return isRecord(namespace) && ES_MODULE_MARKER in namespace && !(\"default\" in namespace);\n}\n\n/** Nothing was exported: an empty file, `export {}`, or a default export with no keys. */\nfunction exportsNothing(value: unknown): boolean {\n return value == null || (typeof value === \"object\" && Object.keys(value).length === 0);\n}\n\n/**\n * Loads a TypeScript config file using jiti.\n * Returns null when the file does not exist, and when it exists but exports nothing.\n * Throws {@link ConfigDefaultExportError} for a module whose exports are all named,\n * {@link ConfigSchemaError} on validation failure, and a plain Error for a malformed/broken file.\n *\n * @param configPath - Absolute path to the .ts config file\n * @param schema - Optional Zod schema; when provided, T is inferred from it\n */\nexport async function loadConfig<T>(configPath: string, schema?: z.ZodType<T>): Promise<T | null> {\n if (!(await fileExists(configPath))) {\n verbose(`Config not found at ${configPath}`);\n return null;\n }\n\n let namespace: unknown;\n try {\n const jiti = createJiti(import.meta.url, {\n moduleCache: false,\n interopDefault: true,\n // Both spellings on purpose. `@agents-inc/cli/config` is the package name the CLI published\n // under until 0.150.0, and a config hand-written against the documentation of the day imports\n // it — but nothing answers to that name in node_modules now that the CLI ships as\n // `agents-inc`, so dropping the key would stop such a config loading on upgrade. Removing it\n // once nobody is on the old package: REPO-24 in todo/repo.md.\n alias: {\n \"agents-inc/config\": CONFIG_EXPORTS_PATH,\n \"@agents-inc/cli/config\": CONFIG_EXPORTS_PATH,\n },\n });\n\n namespace = await jiti.import(configPath);\n } catch (error) {\n throw new Error(`Failed to load config from '${configPath}': ${getErrorMessage(error)}`, {\n cause: error,\n });\n }\n\n const raw = unwrapDefaultExport(namespace);\n\n // Empty or whitespace-only files produce an empty module object. Treat this the same as a\n // missing file rather than returning a confusing empty object — and ask it BEFORE the export\n // question, because such a file declares no exports of any kind to have opinions about.\n if (exportsNothing(raw)) {\n verbose(`Config at ${configPath} exports nothing`);\n return null;\n }\n\n if (declaresNoDefaultExport(namespace)) {\n throw new ConfigDefaultExportError(configPath);\n }\n\n if (schema) {\n const result = schema.safeParse(raw);\n if (!result.success) {\n throw new ConfigSchemaError(configPath, formatZodIssues(result.error.issues));\n }\n return result.data;\n }\n\n // Boundary cast: jiti returns unknown, caller provides expected type\n return raw as T;\n}\n","import os from \"os\";\nimport path from \"path\";\nimport type { SkillScope } from \"../../types/config.js\";\nimport {\n CLAUDE_DIR,\n CLAUDE_SRC_DIR,\n LOCAL_SKILLS_PATH,\n STANDARD_DIRS,\n STANDARD_FILES,\n} from \"../../consts.js\";\n\n/**\n * Base directory for a scope's installed artifacts: the home directory for\n * `\"global\"` scope, the project directory otherwise (absent scope defaults to\n * project). Calls `os.homedir()` at runtime so test home-dir mocks apply.\n */\nexport function installBaseDir(projectDir: string, scope: SkillScope | undefined): string {\n return scope === \"global\" ? os.homedir() : projectDir;\n}\n\n/** Path to the unified project config (`<dir>/.claude-src/config.ts`). */\nexport function getProjectConfigPath(dir: string): string {\n return path.join(dir, CLAUDE_SRC_DIR, STANDARD_FILES.CONFIG_TS);\n}\n\nexport type InstallPaths = {\n skillsDir: string;\n agentsDir: string;\n configPath: string;\n};\n\nexport function resolveInstallPaths(\n projectDir: string,\n scope: SkillScope = \"project\",\n): InstallPaths {\n const baseDir = installBaseDir(projectDir, scope);\n return {\n skillsDir: path.join(baseDir, LOCAL_SKILLS_PATH),\n agentsDir: path.join(baseDir, CLAUDE_DIR, STANDARD_DIRS.AGENTS),\n configPath: getProjectConfigPath(baseDir),\n };\n}\n","import type {\n AgentName,\n CategoryPath,\n ProjectConfig,\n SkillAssignment,\n SkillId,\n Stack,\n StackAgentConfig,\n Category,\n} from \"../../types\";\nimport { groupBy, indexBy, partition } from \"remeda\";\nimport {\n resolveAssignment,\n resolveLoadState,\n type LoadState,\n type SkillTaxonomy,\n} from \"@workspace/matrix\";\n\nimport type { AgentScopeConfig, SkillConfig, SkillScope } from \"../../types/config\";\nimport { byCategoryDeclarationOrder, getCategoryDomain, matrix } from \"../matrix/matrix-provider\";\nimport {\n CLI_INVOKE_COMMAND,\n EJECT_SOURCE,\n GLOBAL_CONFIG_NAME,\n LOCAL_PSEUDO_CATEGORY,\n} from \"../../consts\";\nimport { isActiveAt, activeAgentScopeMap, effectivelyExcludedSkillIds } from \"./scope-predicates\";\nimport { verbose, warn } from \"../../utils/logger\";\nimport { isAgentName, isSkillId } from \"../../utils/type-guards\";\nimport { typedEntries, typedFromEntries, 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\n/** How many matrix ids the verbose diagnostic names when a lookup misses. */\nconst MATRIX_SAMPLE_SIZE = 5;\n\nfunction extractCategoryFromPath(categoryPath: CategoryPath): Category | undefined {\n if (categoryPath === LOCAL_PSEUDO_CATEGORY) return undefined;\n // TypeScript narrows CategoryPath to Category after excluding \"local\"\n return categoryPath;\n}\n\ntype StackBuildInputs = {\n agentList: AgentName[];\n activeSkillsByCategory: Map<Category, SkillId[]>;\n skillScope: Map<SkillId, SkillScope>;\n agentScope: Map<AgentName, SkillScope>;\n existingStack: Partial<Record<AgentName, StackAgentConfig>>;\n /**\n * Skills that are new to this session's top-level selection (not in the prior\n * `existing.config.skills`). When `undefined`, the D-220 per-agent curation\n * preservation rule is disabled and every scope-compatible, resolver-relevant\n * skill lands on every existing agent (legacy behavior). When defined\n * (possibly empty), the preservation rule applies: skills NOT in an agent's\n * prior stack entry and NOT in this set are omitted from that agent's stack —\n * respecting the user's curation.\n */\n newlyAddedSkillIds?: ReadonlySet<SkillId>;\n /**\n * Keys of `(agent, skillId)` pairs whose scope-compatibility was GAINED this\n * session — either the skill's scope was flipped so it now reaches this\n * agent, or the agent's scope was flipped so previously-filtered skills now\n * reach it. Parallel to `newlyAddedSkillIds`: when the caller opts into\n * D-220 preservation semantics, this set admits triples that the skill-id\n * diff would miss. Keys are produced by `scopeEligibilityKey()`.\n */\n scopeEligibilityGained?: ReadonlySet<string>;\n};\n\n/**\n * Encodes an `(agent, skillId)` pair as a single string for set-membership\n * lookups. Both arguments are typed string unions so a `|` delimiter produces\n * a unique, stable key.\n */\nexport function scopeEligibilityKey(agent: AgentName, skillId: SkillId): string {\n return `${agent}|${skillId}`;\n}\n\n/**\n * What the prior save said about this triple, or `undefined` when it carried\n * no entry for it at all. An entry with no flag is not silence: the generator\n * only ever writes `preloaded` where it is true, so a bare `{ id }` read back\n * off disk is the user's curated lazy and outranks any default.\n */\nfunction priorLoadState(\n existingStack: Partial<Record<AgentName, StackAgentConfig>>,\n agent: AgentName,\n category: Category,\n skillId: SkillId,\n): LoadState | undefined {\n const prior = existingStack[agent]?.[category]?.find((a) => a.id === skillId);\n if (prior === undefined) return undefined;\n\n return prior.preloaded === true ? \"preloaded\" : \"lazy\";\n}\n\n/**\n * The shared mapping's word for a triple nobody has decided on yet — the same\n * table the editor's default assignments read, so a skill picked in either\n * place arrives loaded the same way.\n *\n * Only catalog skills on roster agents are put to it. The mapping is keyed by\n * generated skill id and agent role, so a local skill, a marketplace one or a\n * hand-written agent has no entry it could ever match — those are lazy by\n * rule, not by rescue. `resolveLoadState` throws on ids it does not know, and\n * catching that throw is what would make this a silent fallback.\n */\nfunction mappedLoadState(skillId: SkillId, agent: AgentName): LoadState {\n if (!isSkillId(skillId) || !isAgentName(agent)) return \"lazy\";\n\n return resolveLoadState({ skillId, agentId: agent });\n}\n\n/**\n * How the shared resolver is told about a skill. Targeting reads a domain and a\n * category, never catalog membership, so what goes is the taxonomy the LOADED\n * matrix carries: a marketplace's skill wears its marketplace's namespace in its\n * id, belongs to no catalog-keyed table, and is still placed by its domain like\n * any other.\n *\n * A category the matrix gives no domain leaves no taxonomy to state, so the id\n * goes alone and the resolver answers for it — nobody, unless the catalog knows\n * it. `checkMatrixHealth` reports such a category in its own right.\n */\nfunction taxonomyOrIdOf(skillId: SkillId, category: Category): SkillId | SkillTaxonomy {\n const domainId = getCategoryDomain(category);\n if (domainId === undefined) return skillId;\n\n return { id: skillId, domainId, categoryId: category };\n}\n\n/**\n * The shared resolver's word on whether this sub-agent would reasonably use\n * this skill — the same targeting the editor's default assignments read, so a\n * pick lands on the same agents from either surface.\n */\nfunction isRelevantPair(skillId: SkillId, category: Category, agent: AgentName): boolean {\n return resolveAssignment(taxonomyOrIdOf(skillId, category)).some(\n (target) => target.agentId === agent,\n );\n}\n\n/**\n * The relevance rule as it applies inside a stack build: a triple the prior\n * save carries is the user's curation — D-220 — and rides through wherever it\n * sits, cross-domain included; a triple arriving this session lands only where\n * the shared resolver targets it.\n */\nfunction isPreservedOrRelevant(\n agent: AgentName,\n category: Category,\n skillId: SkillId,\n inputs: StackBuildInputs,\n): boolean {\n const hasPriorEntry =\n priorLoadState(inputs.existingStack, agent, category, skillId) !== undefined;\n return hasPriorEntry || isRelevantPair(skillId, category, agent);\n}\n\nfunction getScopeOrThrow<K>(map: Map<K, SkillScope>, key: K, kind: \"skill\" | \"agent\"): SkillScope {\n const scope = map.get(key);\n if (scope === undefined) {\n throw new Error(\n `generateProjectConfigFromSkills: ${kind} '${String(key)}' missing from ` +\n `${kind === \"skill\" ? \"skillConfigs\" : \"agentConfigs\"}. ` +\n `Caller must pass a ${kind === \"skill\" ? \"SkillConfig\" : \"AgentScopeConfig\"} ` +\n `for every selected ${kind}.`,\n );\n }\n return scope;\n}\n\n/** Project skills never reach global agents; global skills reach any agent. */\nexport function isScopePairCompatible(skillScope: SkillScope, agentScope: SkillScope): boolean {\n return !(skillScope === \"project\" && agentScope === \"global\");\n}\n\nfunction isScopeCompatible(\n skillId: SkillId,\n agent: AgentName,\n skillScope: Map<SkillId, SkillScope>,\n agentScope: Map<AgentName, SkillScope>,\n): boolean {\n const sScope = getScopeOrThrow(skillScope, skillId, \"skill\");\n const aScope = getScopeOrThrow(agentScope, agent, \"agent\");\n return isScopePairCompatible(sScope, aScope);\n}\n\n/**\n * Decides whether a given `(agent, category, skillId)` triple lands in the\n * agent's stack for this save. The scope filter has already run in the caller\n * — this function only enforces D-220's per-agent curation rule.\n *\n * Branches:\n * - `agent ∉ existingStack` → seed branch (new agent); every scope-compatible\n * skill the shared resolver targets at this agent lands, and with no prior\n * entry to inherit a `preloaded` flag from, each one takes the shared\n * mapping's default (see `toStackAssignment`).\n * - `agent ∈ existingStack` → preservation branch:\n * * skillId was in `existingStack[agent][category]` → KEEP (idempotent).\n * * skillId ∈ `newlyAddedSkillIds` OR `(agent, skillId)` ∈\n * `scopeEligibilityGained` → APPEND (user's session-level addition or\n * scope-compat flip).\n * * otherwise → OMIT (respect user's prior per-agent curation removal).\n *\n * Legacy path: when `newlyAddedSkillIds` is not provided, the D-220 check is\n * disabled — every scope-compatible skill passes this gate (the relevance\n * filter in `buildAgentStack` still applies). This preserves the contract of\n * callers that pre-date D-220.\n */\nfunction shouldIncludeTriple(\n agent: AgentName,\n category: Category,\n skillId: SkillId,\n inputs: StackBuildInputs,\n): boolean {\n // Legacy path: callers that don't opt in keep the pre-D-220 behavior.\n if (inputs.newlyAddedSkillIds === undefined) return true;\n\n const agentExistingStack = inputs.existingStack[agent];\n if (agentExistingStack === undefined) {\n // Seeding branch: agent is new this session → full ownership-derived stack.\n return true;\n }\n\n const priorCategory = agentExistingStack[category];\n if (priorCategory && priorCategory.some((a) => a.id === skillId)) return true;\n\n if (inputs.newlyAddedSkillIds.has(skillId)) return true;\n const scopeEligibility = inputs.scopeEligibilityGained;\n if (scopeEligibility && scopeEligibility.has(scopeEligibilityKey(agent, skillId))) {\n return true;\n }\n return false;\n}\n\n/** The prior stack's word for this triple, or the mapping's when it is new. */\nfunction toStackAssignment(\n id: SkillId,\n agent: AgentName,\n category: Category,\n inputs: StackBuildInputs,\n): SkillAssignment {\n const prior = priorLoadState(inputs.existingStack, agent, category, id);\n const load = prior ?? mappedLoadState(id, agent);\n\n return load === \"preloaded\" ? { id, preloaded: true } : { id };\n}\n\n/**\n * The selection's categories in the matrix's own declaration order, so a newly\n * built stack's key order is a property of the roster rather than of the order\n * the skills happened to be picked in — two sessions that select the same\n * skills emit the same bytes, and an agent whose skill set did not change is\n * not rewritten. The writer holds the same rule for a stack it did not build.\n */\nfunction inCanonicalCategoryOrder(\n activeSkillsByCategory: Map<Category, SkillId[]>,\n): [Category, SkillId[]][] {\n const byDeclaration = byCategoryDeclarationOrder();\n return [...activeSkillsByCategory].sort(([a], [b]) => byDeclaration(a, b));\n}\n\nfunction buildAgentStack(agent: AgentName, inputs: StackBuildInputs): StackAgentConfig | undefined {\n const agentStack: StackAgentConfig = {};\n for (const [category, skillIds] of inCanonicalCategoryOrder(inputs.activeSkillsByCategory)) {\n const assignments = skillIds\n .filter((id) => isScopeCompatible(id, agent, inputs.skillScope, inputs.agentScope))\n .filter((id) => shouldIncludeTriple(agent, category, id, inputs))\n .filter((id) => isPreservedOrRelevant(agent, category, id, inputs))\n .map((id) => toStackAssignment(id, agent, category, inputs));\n if (assignments.length > 0) {\n agentStack[category] = assignments;\n }\n }\n return typedKeys<Category>(agentStack).length > 0 ? agentStack : undefined;\n}\n\nfunction buildStackForSelection(\n inputs: StackBuildInputs,\n): Partial<Record<AgentName, StackAgentConfig>> | undefined {\n // No agents in play → this caller is not managing the stack. Return\n // `undefined` (key omitted) so the merger preserves any existing stack.\n if (inputs.agentList.length === 0) {\n verbose(`buildStackForSelection: no agents — returning undefined (stack untouched)`);\n return undefined;\n }\n\n // Agents are in play → the generator authoritatively rebuilt the stack from\n // the current selection. An empty result is a real \"nothing preloads\" outcome\n // (e.g. the last categorized skill was removed), so return `{}` — NOT\n // `undefined`. The merger trusts `{}` and drops the stale existing stack,\n // whereas `undefined` would resurrect it (the removed-last-skill bug).\n const result: Partial<Record<AgentName, StackAgentConfig>> = {};\n for (const agent of inputs.agentList) {\n const built = buildAgentStack(agent, inputs);\n if (built) result[agent] = built;\n }\n return result;\n}\n\n/**\n * Generates a ProjectConfig from a list of selected skill IDs, rebuilding the\n * stack property (agent -> category -> SkillAssignment[]) from the current\n * wizard selection plus any previously-saved stack entries.\n *\n * Ownership rules (what lands in each agent's stack):\n * - agent is selected AND skill is non-excluded AND agent is non-excluded\n * - scope filter: a project-scoped skill never lands on a global-scoped agent\n * - relevance filter: a NEW triple lands only where the shared resolver targets\n * the (skill, agent) pair — a sub-agent carries only skills it would\n * reasonably use. Prior entries are preserved verbatim (D-220), wherever\n * they sit.\n *\n * Load state per (agent, category, skill) triple: a triple `options.existingStack`\n * already carries keeps exactly what it carried — flag or no flag, that entry is\n * the author's stack YAML or the user's own curation. A triple that is new to\n * this save has nobody's word to inherit and takes the shared mapping's default,\n * which is what the editor resolves against too.\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, skillConfigs,\n * agentConfigs, and existingStack fields. When skillConfigs is\n * provided, it is used directly as `skills` in the config;\n * otherwise SkillConfig entries are synthesized with defaults.\n * @returns Complete ProjectConfig ready to be saved to config.ts\n */\ntype ResolvedSkillEntry = { skillId: SkillId; category: Category };\n\n/**\n * Resolves selected ids against the matrix: reports and drops the ids this marketplace does\n * not carry, extracts each skill's category, and drops ids whose every config entry is\n * excluded. A skill with an excluded global entry AND an active project entry is KEPT —\n * the active entry still needs to reach the stack builder.\n */\nfunction resolveValidSkills(\n selectedSkillIds: SkillId[],\n skillConfigs: SkillConfig[],\n): { validSkills: ResolvedSkillEntry[]; foundCount: number; skippedCount: number } {\n const looked = selectedSkillIds.map((skillId) => ({ skillId, skill: matrix.skills[skillId] }));\n const found = looked.filter(\n (entry): entry is typeof entry & { skill: NonNullable<typeof entry.skill> } =>\n entry.skill != null,\n );\n const absentSkillIds = looked\n .filter((entry) => entry.skill == null)\n .map((entry) => entry.skillId);\n\n reportAbsentSkills(absentSkillIds);\n\n const excludedSkillIds = effectivelyExcludedSkillIds(skillConfigs);\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 .filter((entry) => !excludedSkillIds.has(entry.skillId));\n\n return { validSkills, foundCount: found.length, skippedCount: absentSkillIds.length };\n}\n\n/**\n * Two audiences, one fact: what the user is told about an id this marketplace does not carry,\n * and what the run's verbose diagnostics keep for whoever is debugging the loader.\n *\n * A sample of matrix keys belongs to the second audience entirely — five arbitrary ids explain\n * nothing to anyone not comparing them against a catalogue — so it goes where this project's\n * logging convention puts a diagnostic, and the warning carries only what a user can act on.\n */\nfunction reportAbsentSkills(absentSkillIds: SkillId[]): void {\n if (absentSkillIds.length === 0) return;\n\n for (const skillId of absentSkillIds) {\n warn(absentSkillWarning(skillId), { suppressInTest: true });\n }\n\n const matrixSample = typedKeys<SkillId>(matrix.skills).slice(0, MATRIX_SAMPLE_SIZE).join(\", \");\n verbose(\n `${absentSkillIds.length} skills absent from the matrix. Matrix keys sample: [${matrixSample}]`,\n );\n}\n\n/**\n * What an unplaceable id means and what changes it.\n *\n * The outcome first, because it is the part the user cannot see: the entry stays in `config.ts`\n * — nothing here removes it — and the skill reaches no sub-agent, which is what a stack built\n * without it amounts to. Both ways out are named because the fact has two readings: a catalogue\n * that has moved on since this configuration was written, and an id this one never carried.\n */\nfunction absentSkillWarning(skillId: SkillId): string {\n return (\n `Skill '${skillId}' is not in this marketplace — it stays in the configuration and no ` +\n `sub-agent is given it. Run '${CLI_INVOKE_COMMAND} update' to refresh the marketplace, or ` +\n `remove it with '${CLI_INVOKE_COMMAND} edit'.`\n );\n}\n\n/**\n * Per-skill scope, active-entry-authoritative: when a skill has both an excluded\n * and an active entry (excluded global + active project), excluded entries spread\n * first so active entries overwrite them.\n */\nfunction buildSkillScopeMap(skillConfigs: SkillConfig[]): Map<SkillId, SkillScope> {\n const [excludedConfigs, activeConfigs] = partition(skillConfigs, (s) => Boolean(s.excluded));\n return new Map([...excludedConfigs, ...activeConfigs].map((s) => [s.id, s.scope]));\n}\n\n/**\n * One active AgentScopeConfig per selected agent. When the caller provided\n * agentConfigs, every selected agent MUST have a non-excluded entry (invariant\n * throw); otherwise agents default to project scope.\n */\nfunction resolveActiveAgentConfigs(\n agentList: AgentName[],\n providedConfigs: AgentScopeConfig[] | undefined,\n): AgentScopeConfig[] {\n const providedByName = providedConfigs\n ? indexBy(\n providedConfigs.filter((a) => !a.excluded),\n (a) => a.name,\n )\n : {};\n return agentList.map((agentName) => {\n if (providedConfigs) {\n const provided = providedByName[agentName];\n if (!provided) {\n throw new Error(\n `generateProjectConfigFromSkills: selected agent '${agentName}' has no ` +\n `non-excluded AgentScopeConfig in agentConfigs.`,\n );\n }\n return provided;\n }\n return { name: agentName, scope: \"project\" as const };\n });\n}\n\nexport function generateProjectConfigFromSkills(\n name: string,\n selectedSkillIds: SkillId[],\n options?: ProjectConfigOptions & {\n selectedAgents?: AgentName[];\n skillConfigs?: SkillConfig[];\n agentConfigs?: AgentScopeConfig[];\n existingStack?: Partial<Record<AgentName, StackAgentConfig>>;\n /**\n * Skills new to this session (not present in the prior on-disk config).\n * Passing this field (even as an empty array) opts into D-220's per-agent\n * curation preservation: existing agents' stack entries are treated as\n * authoritative, and skills absent from a given agent's prior stack are\n * only appended when they appear in this set (or in `scopeEligibilityGained`).\n * When undefined, behavior falls back to pre-D-220 semantics.\n */\n newlyAddedSkillIds?: readonly SkillId[];\n /**\n * `(agent, skillId)` keys whose scope-compat transitioned from incompatible\n * to compatible this session. Admits scope-flip cases that `newlyAddedSkillIds`\n * (keyed by skill id only) cannot express. Keys are built with\n * {@link scopeEligibilityKey}.\n */\n scopeEligibilityGained?: ReadonlySet<string>;\n },\n): ProjectConfig {\n const agentList = options?.selectedAgents ? [...options.selectedAgents].sort() : [];\n\n // Invariant: when selectedAgents is provided, callers must also supply the\n // authoritative SkillConfig and AgentScopeConfig entries so scope lookups\n // never silently default. Enforced here to prevent Bug 1-class regressions\n // where a missing config silently resolves every scope to \"project\".\n if (agentList.length > 0) {\n if (!options?.skillConfigs) {\n throw new Error(\n `generateProjectConfigFromSkills: selectedAgents was passed without skillConfigs. ` +\n `Callers must pass a SkillConfig for every selected skill.`,\n );\n }\n if (!options.agentConfigs) {\n throw new Error(\n `generateProjectConfigFromSkills: selectedAgents was passed without agentConfigs. ` +\n `Callers must pass an AgentScopeConfig for every selected agent.`,\n );\n }\n }\n\n // Safe after invariant: when agentList is non-empty these are guaranteed present.\n // When agentList is empty, no scope/ownership work runs so `[]` is a valid no-op.\n const skillConfigs = options?.skillConfigs ?? [];\n const agentConfigs = options?.agentConfigs ?? [];\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 { validSkills, foundCount, skippedCount } = resolveValidSkills(\n selectedSkillIds,\n skillConfigs,\n );\n\n verbose(\n `generateProjectConfigFromSkills: ${foundCount} found, ${skippedCount} not found, ` +\n `${agentList.length} agents in stack`,\n );\n\n const activeSkillsByCategory = new Map(\n typedEntries(groupBy(validSkills, (entry) => entry.category)).map(([category, entries]) => [\n category,\n entries.map((entry) => entry.skillId),\n ]),\n );\n\n const skillScope = buildSkillScopeMap(skillConfigs);\n const agentScope = activeAgentScopeMap(agentConfigs);\n\n // Opt-in D-220 preservation: only when the caller provides the delta set.\n // `newlyAddedSkillIds === undefined` triggers legacy seed-everything behavior\n // (preserves pre-D-220 callers and existing unit tests that set up\n // `existingStack` without the new field).\n const newlyAddedSkillIdsSet: ReadonlySet<SkillId> | undefined =\n options?.newlyAddedSkillIds === undefined ? undefined : new Set(options.newlyAddedSkillIds);\n\n const stackProperty = buildStackForSelection({\n agentList,\n activeSkillsByCategory,\n skillScope,\n agentScope,\n existingStack: options?.existingStack ?? {},\n ...(newlyAddedSkillIdsSet !== undefined && { newlyAddedSkillIds: newlyAddedSkillIdsSet }),\n ...(options?.scopeEligibilityGained !== undefined && {\n scopeEligibilityGained: options.scopeEligibilityGained,\n }),\n });\n\n const skills: SkillConfig[] =\n options?.skillConfigs ??\n selectedSkillIds.map((id) => ({ id, scope: \"project\" as const, origin: EJECT_SOURCE }));\n\n const activeAgentConfigs = resolveActiveAgentConfigs(agentList, options?.agentConfigs);\n // Excluded agents aren't in selectedAgents but must be preserved in config\n const excludedAgentConfigs = agentConfigs.filter((ac) => ac.excluded);\n const finalAgentConfigs: AgentScopeConfig[] = [...activeAgentConfigs, ...excludedAgentConfigs];\n\n return {\n name,\n agents: finalAgentConfigs,\n skills,\n ...(stackProperty && { stack: stackProperty }),\n ...(options?.description && { description: options.description }),\n ...(options?.author && { author: options.author }),\n };\n}\n\n/**\n * One stack entry's load. A flag the author wrote is somebody's word and rides\n * through untouched — a third-party source's stacks file is the explicit tier,\n * and `loadStacks` gives even its bare strings an explicit `preloaded: false`.\n * An entry with no flag at all is a stack stating only WHICH skill an agent\n * gets, so HOW it loads is the shared mapping's answer, exactly as it is for a\n * skill picked by hand. The built-in stacks carry no flags, by design.\n */\nfunction toStackPropertyAssignment(assignment: SkillAssignment, agent: AgentName): SkillAssignment {\n if (assignment.preloaded !== undefined) return assignment;\n if (mappedLoadState(assignment.id, agent) === \"lazy\") return assignment;\n\n return { ...assignment, preloaded: true };\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 every assignment, and every load its author stated; an assignment\n * that states none takes the shared mapping's, per `(skill, agent)` pair.\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 return typedFromEntries(\n typedEntries<AgentName, StackAgentConfig>(stack.agents)\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n .filter(([, agentConfig]) => agentConfig && typedKeys<Category>(agentConfig).length > 0)\n .map(([agentId, agentConfig]) => {\n const resolvedMappings: StackAgentConfig = typedFromEntries(\n typedEntries<Category, SkillAssignment[]>(agentConfig)\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n .filter(([, assignments]) => assignments && assignments.length > 0)\n .map(([category, assignments]) => [\n category,\n assignments.map((assignment) => toStackPropertyAssignment(assignment, agentId)),\n ]),\n );\n return [agentId, resolvedMappings] as const;\n })\n .filter(([, mappings]) => typedKeys<Category>(mappings).length > 0),\n );\n}\n\n/** Splits one agent's stack per category: global skills → global config, project skills → project config. */\nfunction splitAgentStack(\n agentStack: StackAgentConfig,\n globalSkillIds: ReadonlySet<SkillId>,\n): { global: StackAgentConfig; project: StackAgentConfig } {\n const perCategory = typedEntries<Category, SkillAssignment[]>(agentStack)\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n .filter(([, assignments]) => assignments !== undefined)\n .map(([category, assignments]) => {\n const [globalOnly, projectOnly] = partition(assignments, (a) => globalSkillIds.has(a.id));\n return { category, globalOnly, projectOnly };\n });\n return {\n global: Object.fromEntries(\n perCategory.filter((c) => c.globalOnly.length > 0).map((c) => [c.category, c.globalOnly]),\n ),\n project: Object.fromEntries(\n perCategory.filter((c) => c.projectOnly.length > 0).map((c) => [c.category, c.projectOnly]),\n ),\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 * Selected domains go to the global partition only — the project config inherits them from\n * global at runtime, so its own key is cleared rather than duplicated.\n */\nexport function splitConfigByScope(config: ProjectConfig): SplitConfigResult {\n // Every entry is either active-global or project-owned (project-scoped, or an\n // excluded-global tombstone routed to the project partition as an override).\n const [globalSkills, projectSkills] = partition(config.skills, (s) => isActiveAt(s, \"global\"));\n const [globalAgents, projectAgents] = partition(config.agents, (a) => isActiveAt(a, \"global\"));\n\n // Split stack by agent partition, filtering global agents' stacks to only reference global skills.\n // Project agents keep ALL skill references (both project and global) since global skills are available everywhere.\n const globalSkillIds = new Set(globalSkills.map((s) => s.id));\n const globalStack: typeof config.stack = {};\n const projectStack: typeof config.stack = {};\n\n if (config.stack) {\n for (const agent of globalAgents) {\n const agentStack = config.stack[agent.name];\n if (!agentStack) continue;\n const split = splitAgentStack(agentStack, globalSkillIds);\n if (typedKeys<Category>(split.global).length > 0) {\n globalStack[agent.name] = split.global;\n }\n if (typedKeys<Category>(split.project).length > 0) {\n projectStack[agent.name] = split.project;\n }\n }\n for (const agent of projectAgents) {\n const agentStack = config.stack[agent.name];\n if (agentStack) {\n projectStack[agent.name] = agentStack;\n }\n }\n }\n\n // Domains are a UI/preference concept — all selected domains go in global config.\n // Project config inherits domains from global at runtime, so it gets none.\n //\n // `stack` is written on BOTH partitions unconditionally, and that is the whole of what\n // keeps each one to its own rows: the spread above carries the undivided stack, so an\n // override that declines to fire hands a partition every row the other partition earned.\n // A derivation that yielded nothing is a partition with no stack, and `{}` is how that is\n // said — the same word `buildStackForSelection` uses and for the same reason, since the\n // merger reads an absent stack as no statement and keeps the stale one. `generateConfigSource`\n // omits an empty stack from the file it writes, so nothing emits `stack: {}` on this account.\n const globalConfig: ProjectConfig = {\n ...config,\n name: GLOBAL_CONFIG_NAME,\n agents: globalAgents,\n skills: globalSkills,\n stack: globalStack,\n ...(config.selectedDomains !== undefined && { selectedDomains: config.selectedDomains }),\n };\n\n const projectConfig: ProjectConfig = {\n ...config,\n name: config.name,\n agents: projectAgents,\n skills: projectSkills,\n stack: projectStack,\n };\n\n return { global: globalConfig, project: projectConfig };\n}\n","// AUTO-GENERATED from skills source and agent metadata — do not edit manually\n// Run: bun run generate:types\n\n// ── Skill Map (slug → ID) ─────────────────────────────────────\n\nexport const SKILL_MAP = {\n \"ai-planning\": \"meta-planning-ai-planning\",\n \"ai-reviewing\": \"meta-reviewing-ai-reviewing\",\n \"angular-standalone\": \"web-framework-angular-standalone\",\n \"ant-design\": \"web-ui-ant-design\",\n \"anthropic-sdk\": \"ai-provider-anthropic-sdk\",\n \"api-performance\": \"api-performance-api-performance\",\n \"api-planning\": \"meta-planning-api-planning\",\n \"api-reviewing\": \"meta-reviewing-api-reviewing\",\n \"apollo-server\": \"api-graphql-apollo-server\",\n \"app-links\": \"mobile-deep-linking-app-links\",\n appwrite: \"api-baas-appwrite\",\n astro: \"web-meta-framework-astro\",\n \"auth-security\": \"shared-security-auth-security\",\n \"aws-sdk\": \"infra-platform-aws-sdk\",\n \"axiom-pino-sentry\": \"api-observability-axiom-pino-sentry\",\n \"base-ui\": \"web-ui-base-ui\",\n \"better-auth-drizzle-hono\": \"api-auth-better-auth-drizzle-hono\",\n biome: \"shared-tooling-biome\",\n \"ble-nfc\": \"mobile-hardware-ble-nfc\",\n bullmq: \"api-queue-bullmq\",\n \"chakra-ui\": \"web-ui-chakra-ui\",\n changesets: \"shared-tooling-changesets\",\n chroma: \"api-vector-db-chroma\",\n clack: \"cli-prompts-clack\",\n \"claude-vision\": \"ai-provider-claude-vision\",\n clerk: \"api-auth-clerk\",\n \"cli-commander\": \"cli-framework-cli-commander\",\n \"cli-planning\": \"meta-planning-cli-planning\",\n \"cli-reviewing\": \"meta-reviewing-cli-reviewing\",\n \"cloudflare-workers\": \"infra-platform-cloudflare-workers\",\n cockroachdb: \"api-database-cockroachdb\",\n \"cohere-sdk\": \"ai-provider-cohere-sdk\",\n \"component-library\": \"web-tooling-component-library\",\n \"composable-components\": \"meta-design-composable-components\",\n \"css-animations\": \"web-animation-css-animations\",\n cva: \"web-styling-cva\",\n \"cypress-e2e\": \"web-testing-cypress-e2e\",\n d3: \"web-dataviz-d3\",\n \"date-fns\": \"web-utilities-date-fns\",\n \"design-tokens\": \"web-styling-design-tokens\",\n detox: \"mobile-testing-detox\",\n \"dnd-kit\": \"web-dnd-dnd-kit\",\n docker: \"infra-ci-cd-docker\",\n docusaurus: \"web-meta-framework-docusaurus\",\n drizzle: \"api-database-drizzle\",\n eas: \"mobile-deployment-eas\",\n edgedb: \"api-database-edgedb\",\n elasticsearch: \"api-search-elasticsearch\",\n electron: \"desktop-framework-electron\",\n \"electron-forge\": \"desktop-packaging-electron-forge\",\n \"electron-ipc\": \"desktop-ipc-electron\",\n \"electron-multiwindow\": \"desktop-multiwindow-electron\",\n \"electron-security\": \"desktop-security-electron\",\n \"electron-storage\": \"desktop-storage-electron\",\n \"electron-testing\": \"desktop-testing-electron\",\n \"electron-ui\": \"desktop-ui-electron\",\n \"electron-updater\": \"desktop-updates-electron-updater\",\n elevenlabs: \"ai-provider-elevenlabs\",\n elysia: \"api-framework-elysia\",\n \"error-boundaries\": \"web-error-handling-error-boundaries\",\n \"eslint-prettier\": \"shared-tooling-eslint-prettier\",\n expo: \"mobile-framework-expo\",\n \"expo-router\": \"mobile-navigation-expo-router\",\n express: \"api-framework-express\",\n \"expressive-typescript\": \"meta-design-expressive-typescript\",\n fastify: \"api-framework-fastify\",\n \"file-upload-patterns\": \"web-files-file-upload-patterns\",\n firebase: \"api-baas-firebase\",\n \"framer-motion\": \"web-animation-framer-motion\",\n \"gesture-handler\": \"mobile-animation-gesture-handler\",\n \"git-hooks\": \"shared-tooling-git-hooks\",\n \"github-actions\": \"infra-ci-cd-github-actions\",\n \"google-gemini-sdk\": \"ai-provider-google-gemini-sdk\",\n \"graphql-apollo\": \"web-data-fetching-graphql-apollo\",\n \"graphql-urql\": \"web-data-fetching-graphql-urql\",\n \"headless-ui\": \"web-ui-headless-ui\",\n hono: \"api-framework-hono\",\n \"huggingface-inference\": \"ai-infrastructure-huggingface-inference\",\n \"image-handling\": \"web-files-image-handling\",\n \"infra-reviewing\": \"meta-reviewing-infra-reviewing\",\n jotai: \"web-state-jotai\",\n knex: \"api-database-knex\",\n kubernetes: \"infra-containers-kubernetes\",\n langchain: \"ai-orchestration-langchain\",\n langfuse: \"ai-observability-langfuse\",\n leaflet: \"web-maps-leaflet\",\n lexical: \"web-editor-lexical\",\n litellm: \"ai-infrastructure-litellm\",\n llamaindex: \"ai-orchestration-llamaindex\",\n maestro: \"mobile-testing-maestro\",\n mantine: \"web-ui-mantine\",\n mapbox: \"web-maps-mapbox\",\n meilisearch: \"api-search-meilisearch\",\n mercurius: \"api-graphql-mercurius\",\n \"mistral-sdk\": \"ai-provider-mistral-sdk\",\n mmkv: \"mobile-storage-mmkv\",\n mobx: \"web-state-mobx\",\n modal: \"ai-infrastructure-modal\",\n mongodb: \"api-database-mongodb\",\n mongoose: \"api-database-mongoose\",\n msw: \"web-mocks-msw\",\n mui: \"web-ui-mui\",\n mysql: \"api-database-mysql\",\n \"native-js\": \"web-utilities-native-js\",\n nativewind: \"mobile-styling-nativewind\",\n neon: \"api-baas-neon\",\n nestjs: \"api-framework-nestjs\",\n netlify: \"infra-platform-netlify\",\n \"next-intl\": \"web-i18n-next-intl\",\n nextauth: \"api-auth-nextauth\",\n nextjs: \"web-meta-framework-nextjs\",\n \"ngrx-signalstore\": \"web-state-ngrx-signalstore\",\n nuxt: \"web-meta-framework-nuxt\",\n nx: \"shared-monorepo-nx\",\n \"oclif-ink\": \"cli-framework-oclif-ink\",\n \"offline-first\": \"web-pwa-offline-first\",\n ollama: \"ai-infrastructure-ollama\",\n \"openai-sdk\": \"ai-provider-openai-sdk\",\n \"openai-whisper\": \"ai-provider-openai-whisper\",\n openapi: \"api-specs-openapi\",\n payload: \"api-cms-payload\",\n pinecone: \"api-vector-db-pinecone\",\n pinia: \"web-state-pinia\",\n planetscale: \"api-baas-planetscale\",\n \"playwright-e2e\": \"web-testing-playwright-e2e\",\n \"pnpm-workspaces\": \"shared-monorepo-pnpm-workspaces\",\n postgresql: \"api-database-postgresql\",\n \"posthog-analytics\": \"api-analytics-posthog-analytics\",\n \"posthog-flags\": \"api-flags-posthog-flags\",\n prisma: \"api-database-prisma\",\n promptfoo: \"ai-observability-promptfoo\",\n pulumi: \"infra-iac-pulumi\",\n push: \"mobile-notifications-push\",\n qdrant: \"api-vector-db-qdrant\",\n qwik: \"web-meta-framework-qwik\",\n \"radix-ui\": \"web-ui-radix-ui\",\n react: \"web-framework-react\",\n \"react-hook-form\": \"web-forms-react-hook-form\",\n \"react-intl\": \"web-i18n-react-intl\",\n \"react-native\": \"mobile-framework-react-native\",\n \"react-native-paper\": \"mobile-ui-components-react-native-paper\",\n \"react-native-performance\": \"mobile-performance-react-native\",\n \"react-native-security\": \"mobile-security-react-native\",\n \"react-navigation\": \"mobile-navigation-react-navigation\",\n \"react-query\": \"web-server-state-react-query\",\n \"react-router\": \"web-routing-react-router\",\n \"react-testing-library\": \"web-testing-react-testing-library\",\n \"react-three-fiber\": \"web-3d-react-three-fiber\",\n reanimated: \"mobile-animation-reanimated\",\n recharts: \"web-dataviz-recharts\",\n redis: \"api-database-redis\",\n \"redux-toolkit\": \"web-state-redux-toolkit\",\n remix: \"web-meta-framework-remix\",\n replicate: \"ai-infrastructure-replicate\",\n \"research-methodology\": \"meta-methodology-research-methodology\",\n \"resend-react-email\": \"api-email-resend-react-email\",\n \"result-types\": \"web-error-handling-result-types\",\n reviewing: \"meta-reviewing-reviewing\",\n rxjs: \"web-utilities-rxjs\",\n sanity: \"api-cms-sanity\",\n \"scss-modules\": \"web-styling-scss-modules\",\n sequelize: \"api-database-sequelize\",\n \"service-workers\": \"web-pwa-service-workers\",\n \"setup-axiom-pino-sentry\": \"api-observability-setup-axiom-pino-sentry\",\n \"setup-env\": \"infra-config-setup-env\",\n \"setup-posthog\": \"api-analytics-setup-posthog\",\n \"setup-resend\": \"api-email-setup-resend\",\n \"shadcn-ui\": \"web-ui-shadcn-ui\",\n skia: \"mobile-animation-skia\",\n \"socket-io\": \"web-realtime-socket-io\",\n solidjs: \"web-framework-solidjs\",\n \"sqlite-powersync\": \"mobile-storage-sqlite-powersync\",\n sse: \"web-realtime-sse\",\n sst: \"infra-iac-sst\",\n \"stack-detect\": \"meta-config-stack-detect\",\n storybook: \"web-tooling-storybook\",\n strapi: \"api-cms-strapi\",\n strategies: \"api-caching-strategies\",\n stripe: \"api-commerce-stripe\",\n supabase: \"api-baas-supabase\",\n surrealdb: \"api-database-surrealdb\",\n svelte: \"web-framework-svelte\",\n sveltekit: \"web-meta-framework-sveltekit\",\n swr: \"web-data-fetching-swr\",\n tailwind: \"web-styling-tailwind\",\n tamagui: \"mobile-ui-components-tamagui\",\n \"tanstack-form\": \"web-forms-tanstack-form\",\n \"tanstack-router\": \"web-routing-tanstack-router\",\n \"tanstack-table\": \"web-ui-tanstack-table\",\n tasks: \"mobile-background-tasks\",\n tauri: \"desktop-framework-tauri\",\n \"tauri-backend\": \"desktop-backend-tauri\",\n \"tauri-bundling\": \"desktop-packaging-tauri\",\n \"tauri-mobile\": \"desktop-mobile-tauri\",\n \"tauri-multiwindow\": \"desktop-multiwindow-tauri\",\n \"tauri-plugins\": \"desktop-plugins-tauri\",\n \"tauri-security\": \"desktop-security-tauri\",\n terraform: \"infra-iac-terraform\",\n theming: \"web-styling-theming\",\n tiptap: \"web-editor-tiptap\",\n \"together-ai\": \"ai-infrastructure-together-ai\",\n \"tool-use-patterns\": \"ai-patterns-tool-use-patterns\",\n trpc: \"web-data-fetching-trpc\",\n turborepo: \"shared-monorepo-turborepo\",\n \"turborepo-ci\": \"infra-ci-cd-turborepo-ci\",\n turso: \"api-baas-turso\",\n typeorm: \"api-database-typeorm\",\n \"typescript-config\": \"shared-tooling-typescript-config\",\n unistyles: \"mobile-styling-unistyles\",\n upstash: \"api-database-upstash\",\n \"vee-validate\": \"web-forms-vee-validate\",\n vercel: \"infra-platform-vercel\",\n \"vercel-ai-sdk\": \"ai-orchestration-vercel-ai-sdk\",\n \"vercel-kv\": \"api-database-vercel-kv\",\n \"vercel-postgres\": \"api-database-vercel-postgres\",\n \"view-transitions\": \"web-animation-view-transitions\",\n \"vision-camera\": \"mobile-camera-vision-camera\",\n \"visual-regression\": \"web-testing-visual-regression\",\n vite: \"web-tooling-vite\",\n vitepress: \"web-meta-framework-vitepress\",\n vitest: \"web-testing-vitest\",\n \"vue-composition-api\": \"web-framework-vue-composition-api\",\n \"vue-i18n\": \"web-i18n-vue-i18n\",\n \"vue-test-utils\": \"web-testing-vue-test-utils\",\n vuetify: \"web-ui-vuetify\",\n vueuse: \"web-utilities-vueuse\",\n watermelondb: \"mobile-storage-watermelondb\",\n weaviate: \"api-vector-db-weaviate\",\n \"web-accessibility\": \"web-accessibility-web-accessibility\",\n \"web-performance\": \"web-performance-web-performance\",\n \"web-planning\": \"meta-planning-web-planning\",\n \"web-reviewing\": \"meta-reviewing-web-reviewing\",\n webhooks: \"api-messaging-webhooks\",\n websockets: \"web-realtime-websockets\",\n xquik: \"api-search-xquik\",\n yoga: \"api-graphql-yoga\",\n \"zod-validation\": \"web-forms-zod-validation\",\n zustand: \"web-state-zustand\",\n} as const;\n\nexport type SkillSlug = keyof typeof SKILL_MAP;\nexport type SkillId = (typeof SKILL_MAP)[SkillSlug];\n\n// Derived arrays for Zod enum compatibility\n// (z.enum() requires a readonly tuple, not Object.keys/values)\nexport const SKILL_SLUGS = [\n \"ai-planning\",\n \"ai-reviewing\",\n \"angular-standalone\",\n \"ant-design\",\n \"anthropic-sdk\",\n \"api-performance\",\n \"api-planning\",\n \"api-reviewing\",\n \"apollo-server\",\n \"app-links\",\n \"appwrite\",\n \"astro\",\n \"auth-security\",\n \"aws-sdk\",\n \"axiom-pino-sentry\",\n \"base-ui\",\n \"better-auth-drizzle-hono\",\n \"biome\",\n \"ble-nfc\",\n \"bullmq\",\n \"chakra-ui\",\n \"changesets\",\n \"chroma\",\n \"clack\",\n \"claude-vision\",\n \"clerk\",\n \"cli-commander\",\n \"cli-planning\",\n \"cli-reviewing\",\n \"cloudflare-workers\",\n \"cockroachdb\",\n \"cohere-sdk\",\n \"component-library\",\n \"composable-components\",\n \"css-animations\",\n \"cva\",\n \"cypress-e2e\",\n \"d3\",\n \"date-fns\",\n \"design-tokens\",\n \"detox\",\n \"dnd-kit\",\n \"docker\",\n \"docusaurus\",\n \"drizzle\",\n \"eas\",\n \"edgedb\",\n \"elasticsearch\",\n \"electron\",\n \"electron-forge\",\n \"electron-ipc\",\n \"electron-multiwindow\",\n \"electron-security\",\n \"electron-storage\",\n \"electron-testing\",\n \"electron-ui\",\n \"electron-updater\",\n \"elevenlabs\",\n \"elysia\",\n \"error-boundaries\",\n \"eslint-prettier\",\n \"expo\",\n \"expo-router\",\n \"express\",\n \"expressive-typescript\",\n \"fastify\",\n \"file-upload-patterns\",\n \"firebase\",\n \"framer-motion\",\n \"gesture-handler\",\n \"git-hooks\",\n \"github-actions\",\n \"google-gemini-sdk\",\n \"graphql-apollo\",\n \"graphql-urql\",\n \"headless-ui\",\n \"hono\",\n \"huggingface-inference\",\n \"image-handling\",\n \"infra-reviewing\",\n \"jotai\",\n \"knex\",\n \"kubernetes\",\n \"langchain\",\n \"langfuse\",\n \"leaflet\",\n \"lexical\",\n \"litellm\",\n \"llamaindex\",\n \"maestro\",\n \"mantine\",\n \"mapbox\",\n \"meilisearch\",\n \"mercurius\",\n \"mistral-sdk\",\n \"mmkv\",\n \"mobx\",\n \"modal\",\n \"mongodb\",\n \"mongoose\",\n \"msw\",\n \"mui\",\n \"mysql\",\n \"native-js\",\n \"nativewind\",\n \"neon\",\n \"nestjs\",\n \"netlify\",\n \"next-intl\",\n \"nextauth\",\n \"nextjs\",\n \"ngrx-signalstore\",\n \"nuxt\",\n \"nx\",\n \"oclif-ink\",\n \"offline-first\",\n \"ollama\",\n \"openai-sdk\",\n \"openai-whisper\",\n \"openapi\",\n \"payload\",\n \"pinecone\",\n \"pinia\",\n \"planetscale\",\n \"playwright-e2e\",\n \"pnpm-workspaces\",\n \"postgresql\",\n \"posthog-analytics\",\n \"posthog-flags\",\n \"prisma\",\n \"promptfoo\",\n \"pulumi\",\n \"push\",\n \"qdrant\",\n \"qwik\",\n \"radix-ui\",\n \"react\",\n \"react-hook-form\",\n \"react-intl\",\n \"react-native\",\n \"react-native-paper\",\n \"react-native-performance\",\n \"react-native-security\",\n \"react-navigation\",\n \"react-query\",\n \"react-router\",\n \"react-testing-library\",\n \"react-three-fiber\",\n \"reanimated\",\n \"recharts\",\n \"redis\",\n \"redux-toolkit\",\n \"remix\",\n \"replicate\",\n \"research-methodology\",\n \"resend-react-email\",\n \"result-types\",\n \"reviewing\",\n \"rxjs\",\n \"sanity\",\n \"scss-modules\",\n \"sequelize\",\n \"service-workers\",\n \"setup-axiom-pino-sentry\",\n \"setup-env\",\n \"setup-posthog\",\n \"setup-resend\",\n \"shadcn-ui\",\n \"skia\",\n \"socket-io\",\n \"solidjs\",\n \"sqlite-powersync\",\n \"sse\",\n \"sst\",\n \"stack-detect\",\n \"storybook\",\n \"strapi\",\n \"strategies\",\n \"stripe\",\n \"supabase\",\n \"surrealdb\",\n \"svelte\",\n \"sveltekit\",\n \"swr\",\n \"tailwind\",\n \"tamagui\",\n \"tanstack-form\",\n \"tanstack-router\",\n \"tanstack-table\",\n \"tasks\",\n \"tauri\",\n \"tauri-backend\",\n \"tauri-bundling\",\n \"tauri-mobile\",\n \"tauri-multiwindow\",\n \"tauri-plugins\",\n \"tauri-security\",\n \"terraform\",\n \"theming\",\n \"tiptap\",\n \"together-ai\",\n \"tool-use-patterns\",\n \"trpc\",\n \"turborepo\",\n \"turborepo-ci\",\n \"turso\",\n \"typeorm\",\n \"typescript-config\",\n \"unistyles\",\n \"upstash\",\n \"vee-validate\",\n \"vercel\",\n \"vercel-ai-sdk\",\n \"vercel-kv\",\n \"vercel-postgres\",\n \"view-transitions\",\n \"vision-camera\",\n \"visual-regression\",\n \"vite\",\n \"vitepress\",\n \"vitest\",\n \"vue-composition-api\",\n \"vue-i18n\",\n \"vue-test-utils\",\n \"vuetify\",\n \"vueuse\",\n \"watermelondb\",\n \"weaviate\",\n \"web-accessibility\",\n \"web-performance\",\n \"web-planning\",\n \"web-reviewing\",\n \"webhooks\",\n \"websockets\",\n \"xquik\",\n \"yoga\",\n \"zod-validation\",\n \"zustand\",\n] as const satisfies readonly SkillSlug[];\n\nexport const SKILL_IDS = [\n \"ai-infrastructure-huggingface-inference\",\n \"ai-infrastructure-litellm\",\n \"ai-infrastructure-modal\",\n \"ai-infrastructure-ollama\",\n \"ai-infrastructure-replicate\",\n \"ai-infrastructure-together-ai\",\n \"ai-observability-langfuse\",\n \"ai-observability-promptfoo\",\n \"ai-orchestration-langchain\",\n \"ai-orchestration-llamaindex\",\n \"ai-orchestration-vercel-ai-sdk\",\n \"ai-patterns-tool-use-patterns\",\n \"ai-provider-anthropic-sdk\",\n \"ai-provider-claude-vision\",\n \"ai-provider-cohere-sdk\",\n \"ai-provider-elevenlabs\",\n \"ai-provider-google-gemini-sdk\",\n \"ai-provider-mistral-sdk\",\n \"ai-provider-openai-sdk\",\n \"ai-provider-openai-whisper\",\n \"api-analytics-posthog-analytics\",\n \"api-analytics-setup-posthog\",\n \"api-auth-better-auth-drizzle-hono\",\n \"api-auth-clerk\",\n \"api-auth-nextauth\",\n \"api-baas-appwrite\",\n \"api-baas-firebase\",\n \"api-baas-neon\",\n \"api-baas-planetscale\",\n \"api-baas-supabase\",\n \"api-baas-turso\",\n \"api-caching-strategies\",\n \"api-cms-payload\",\n \"api-cms-sanity\",\n \"api-cms-strapi\",\n \"api-commerce-stripe\",\n \"api-database-cockroachdb\",\n \"api-database-drizzle\",\n \"api-database-edgedb\",\n \"api-database-knex\",\n \"api-database-mongodb\",\n \"api-database-mongoose\",\n \"api-database-mysql\",\n \"api-database-postgresql\",\n \"api-database-prisma\",\n \"api-database-redis\",\n \"api-database-sequelize\",\n \"api-database-surrealdb\",\n \"api-database-typeorm\",\n \"api-database-upstash\",\n \"api-database-vercel-kv\",\n \"api-database-vercel-postgres\",\n \"api-email-resend-react-email\",\n \"api-email-setup-resend\",\n \"api-flags-posthog-flags\",\n \"api-framework-elysia\",\n \"api-framework-express\",\n \"api-framework-fastify\",\n \"api-framework-hono\",\n \"api-framework-nestjs\",\n \"api-graphql-apollo-server\",\n \"api-graphql-mercurius\",\n \"api-graphql-yoga\",\n \"api-messaging-webhooks\",\n \"api-observability-axiom-pino-sentry\",\n \"api-observability-setup-axiom-pino-sentry\",\n \"api-performance-api-performance\",\n \"api-queue-bullmq\",\n \"api-search-elasticsearch\",\n \"api-search-meilisearch\",\n \"api-search-xquik\",\n \"api-specs-openapi\",\n \"api-vector-db-chroma\",\n \"api-vector-db-pinecone\",\n \"api-vector-db-qdrant\",\n \"api-vector-db-weaviate\",\n \"cli-framework-cli-commander\",\n \"cli-framework-oclif-ink\",\n \"cli-prompts-clack\",\n \"desktop-backend-tauri\",\n \"desktop-framework-electron\",\n \"desktop-framework-tauri\",\n \"desktop-ipc-electron\",\n \"desktop-mobile-tauri\",\n \"desktop-multiwindow-electron\",\n \"desktop-multiwindow-tauri\",\n \"desktop-packaging-electron-forge\",\n \"desktop-packaging-tauri\",\n \"desktop-plugins-tauri\",\n \"desktop-security-electron\",\n \"desktop-security-tauri\",\n \"desktop-storage-electron\",\n \"desktop-testing-electron\",\n \"desktop-ui-electron\",\n \"desktop-updates-electron-updater\",\n \"infra-ci-cd-docker\",\n \"infra-ci-cd-github-actions\",\n \"infra-ci-cd-turborepo-ci\",\n \"infra-config-setup-env\",\n \"infra-containers-kubernetes\",\n \"infra-iac-pulumi\",\n \"infra-iac-sst\",\n \"infra-iac-terraform\",\n \"infra-platform-aws-sdk\",\n \"infra-platform-cloudflare-workers\",\n \"infra-platform-netlify\",\n \"infra-platform-vercel\",\n \"meta-config-stack-detect\",\n \"meta-design-composable-components\",\n \"meta-design-expressive-typescript\",\n \"meta-methodology-research-methodology\",\n \"meta-planning-ai-planning\",\n \"meta-planning-api-planning\",\n \"meta-planning-cli-planning\",\n \"meta-planning-web-planning\",\n \"meta-reviewing-ai-reviewing\",\n \"meta-reviewing-api-reviewing\",\n \"meta-reviewing-cli-reviewing\",\n \"meta-reviewing-infra-reviewing\",\n \"meta-reviewing-reviewing\",\n \"meta-reviewing-web-reviewing\",\n \"mobile-animation-gesture-handler\",\n \"mobile-animation-reanimated\",\n \"mobile-animation-skia\",\n \"mobile-background-tasks\",\n \"mobile-camera-vision-camera\",\n \"mobile-deep-linking-app-links\",\n \"mobile-deployment-eas\",\n \"mobile-framework-expo\",\n \"mobile-framework-react-native\",\n \"mobile-hardware-ble-nfc\",\n \"mobile-navigation-expo-router\",\n \"mobile-navigation-react-navigation\",\n \"mobile-notifications-push\",\n \"mobile-performance-react-native\",\n \"mobile-security-react-native\",\n \"mobile-storage-mmkv\",\n \"mobile-storage-sqlite-powersync\",\n \"mobile-storage-watermelondb\",\n \"mobile-styling-nativewind\",\n \"mobile-styling-unistyles\",\n \"mobile-testing-detox\",\n \"mobile-testing-maestro\",\n \"mobile-ui-components-react-native-paper\",\n \"mobile-ui-components-tamagui\",\n \"shared-monorepo-nx\",\n \"shared-monorepo-pnpm-workspaces\",\n \"shared-monorepo-turborepo\",\n \"shared-security-auth-security\",\n \"shared-tooling-biome\",\n \"shared-tooling-changesets\",\n \"shared-tooling-eslint-prettier\",\n \"shared-tooling-git-hooks\",\n \"shared-tooling-typescript-config\",\n \"web-3d-react-three-fiber\",\n \"web-accessibility-web-accessibility\",\n \"web-animation-css-animations\",\n \"web-animation-framer-motion\",\n \"web-animation-view-transitions\",\n \"web-data-fetching-graphql-apollo\",\n \"web-data-fetching-graphql-urql\",\n \"web-data-fetching-swr\",\n \"web-data-fetching-trpc\",\n \"web-dataviz-d3\",\n \"web-dataviz-recharts\",\n \"web-dnd-dnd-kit\",\n \"web-editor-lexical\",\n \"web-editor-tiptap\",\n \"web-error-handling-error-boundaries\",\n \"web-error-handling-result-types\",\n \"web-files-file-upload-patterns\",\n \"web-files-image-handling\",\n \"web-forms-react-hook-form\",\n \"web-forms-tanstack-form\",\n \"web-forms-vee-validate\",\n \"web-forms-zod-validation\",\n \"web-framework-angular-standalone\",\n \"web-framework-react\",\n \"web-framework-solidjs\",\n \"web-framework-svelte\",\n \"web-framework-vue-composition-api\",\n \"web-i18n-next-intl\",\n \"web-i18n-react-intl\",\n \"web-i18n-vue-i18n\",\n \"web-maps-leaflet\",\n \"web-maps-mapbox\",\n \"web-meta-framework-astro\",\n \"web-meta-framework-docusaurus\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-nuxt\",\n \"web-meta-framework-qwik\",\n \"web-meta-framework-remix\",\n \"web-meta-framework-sveltekit\",\n \"web-meta-framework-vitepress\",\n \"web-mocks-msw\",\n \"web-performance-web-performance\",\n \"web-pwa-offline-first\",\n \"web-pwa-service-workers\",\n \"web-realtime-socket-io\",\n \"web-realtime-sse\",\n \"web-realtime-websockets\",\n \"web-routing-react-router\",\n \"web-routing-tanstack-router\",\n \"web-server-state-react-query\",\n \"web-state-jotai\",\n \"web-state-mobx\",\n \"web-state-ngrx-signalstore\",\n \"web-state-pinia\",\n \"web-state-redux-toolkit\",\n \"web-state-zustand\",\n \"web-styling-cva\",\n \"web-styling-design-tokens\",\n \"web-styling-scss-modules\",\n \"web-styling-tailwind\",\n \"web-styling-theming\",\n \"web-testing-cypress-e2e\",\n \"web-testing-playwright-e2e\",\n \"web-testing-react-testing-library\",\n \"web-testing-visual-regression\",\n \"web-testing-vitest\",\n \"web-testing-vue-test-utils\",\n \"web-tooling-component-library\",\n \"web-tooling-storybook\",\n \"web-tooling-vite\",\n \"web-ui-ant-design\",\n \"web-ui-base-ui\",\n \"web-ui-chakra-ui\",\n \"web-ui-headless-ui\",\n \"web-ui-mantine\",\n \"web-ui-mui\",\n \"web-ui-radix-ui\",\n \"web-ui-shadcn-ui\",\n \"web-ui-tanstack-table\",\n \"web-ui-vuetify\",\n \"web-utilities-date-fns\",\n \"web-utilities-native-js\",\n \"web-utilities-rxjs\",\n \"web-utilities-vueuse\",\n] as const satisfies readonly SkillId[];\n\n// ── Categories ─────────────────────────────────────────────────\n\nexport const CATEGORIES = [\n \"ai-infrastructure\",\n \"ai-observability\",\n \"ai-orchestration\",\n \"ai-patterns\",\n \"ai-provider\",\n \"api-analytics\",\n \"api-api\",\n \"api-auth\",\n \"api-baas\",\n \"api-caching\",\n \"api-cms\",\n \"api-commerce\",\n \"api-db-host\",\n \"api-document\",\n \"api-email\",\n \"api-graphql\",\n \"api-kv\",\n \"api-messaging\",\n \"api-observability\",\n \"api-orm\",\n \"api-performance\",\n \"api-queue\",\n \"api-search\",\n \"api-specs\",\n \"api-sql-engine\",\n \"api-vector-db\",\n \"cli-framework\",\n \"cli-prompts\",\n \"desktop-backend\",\n \"desktop-framework\",\n \"desktop-ipc\",\n \"desktop-mobile\",\n \"desktop-multiwindow\",\n \"desktop-packaging\",\n \"desktop-plugins\",\n \"desktop-security\",\n \"desktop-storage\",\n \"desktop-testing\",\n \"desktop-ui\",\n \"desktop-updates\",\n \"infra-ci-cd\",\n \"infra-config\",\n \"infra-containers\",\n \"infra-iac\",\n \"infra-platform\",\n \"meta-design\",\n \"meta-methodology\",\n \"meta-planning\",\n \"meta-reviewing\",\n \"mobile-animation\",\n \"mobile-background\",\n \"mobile-camera\",\n \"mobile-deep-linking\",\n \"mobile-deployment\",\n \"mobile-framework\",\n \"mobile-hardware\",\n \"mobile-navigation\",\n \"mobile-notifications\",\n \"mobile-performance\",\n \"mobile-security\",\n \"mobile-storage\",\n \"mobile-styling\",\n \"mobile-testing\",\n \"mobile-ui-components\",\n \"shared-lint\",\n \"shared-monorepo\",\n \"shared-security\",\n \"shared-task-runner\",\n \"shared-tooling\",\n \"web-3d\",\n \"web-accessibility\",\n \"web-animation\",\n \"web-client-state\",\n \"web-dataviz\",\n \"web-dnd\",\n \"web-docs\",\n \"web-e2e\",\n \"web-editor\",\n \"web-error-handling\",\n \"web-file-upload\",\n \"web-files\",\n \"web-form-library\",\n \"web-forms\",\n \"web-framework\",\n \"web-graphql-client\",\n \"web-i18n\",\n \"web-maps\",\n \"web-meta-framework\",\n \"web-mocking\",\n \"web-performance\",\n \"web-pwa\",\n \"web-realtime\",\n \"web-routing\",\n \"web-rpc\",\n \"web-server-state\",\n \"web-streaming\",\n \"web-styling\",\n \"web-testing\",\n \"web-tooling\",\n \"web-ui-components\",\n \"web-ui-kit\",\n \"web-utilities\",\n] as const;\n\nexport type Category = (typeof CATEGORIES)[number];\n\n// ── Domains ────────────────────────────────────────────────────\n\nexport const DOMAINS = [\n \"ai\",\n \"api\",\n \"cli\",\n \"desktop\",\n \"infra\",\n \"meta\",\n \"mobile\",\n \"shared\",\n \"web\",\n] as const;\n\nexport type Domain = (typeof DOMAINS)[number];\n\n// ── Agent Names ────────────────────────────────────────────────\n\nexport const AGENT_NAMES = [\n \"agent-summoner\",\n \"ai-developer\",\n \"ai-researcher\",\n \"ai-tester\",\n \"api-developer\",\n \"api-researcher\",\n \"api-tester\",\n \"cli-developer\",\n \"cli-researcher\",\n \"cli-tester\",\n \"codex-keeper\",\n \"convention-keeper\",\n \"pm\",\n \"reviewer\",\n \"skill-summoner\",\n \"web-developer\",\n \"web-researcher\",\n \"web-tester\",\n] as const;\n\nexport type AgentName = (typeof AGENT_NAMES)[number];\n","// The two collection shapes every read model builds: ordered groups and a\n// by-id lookup. Local to read-model/ on purpose — nothing outside it groups\n// or indexes anything.\n\nexport const groupBy = <T, K>(\n items: T[],\n keyOf: (item: T) => K\n): Map<K, T[]> => {\n const groups = new Map<K, T[]>()\n for (const item of items) {\n const key = keyOf(item)\n const bucket = groups.get(key)\n if (bucket) bucket.push(item)\n else groups.set(key, [item])\n }\n return groups\n}\n\n// Keyed by whatever the items call themselves, and partial because that is what\n// an index built from a list is: it holds the ids it was given and nothing else,\n// so a lookup answers `undefined` rather than pretending the union is total.\nexport const indexById = <T extends { id: string }>(\n items: T[]\n): Partial<Record<T[\"id\"], T>> =>\n // Boundary cast: `Object.fromEntries` types every key as `string`; each of\n // these is the item's own id, which is the key type being claimed.\n Object.fromEntries(items.map((item) => [item.id, item])) as Partial<\n Record<T[\"id\"], T>\n >\n\n// `Object.entries` widens every key to `string`, which is what forces a cast\n// back to the union at each call site. One cast here, in the one place that\n// knows the keys came from a record typed by that union.\nexport const typedEntries = <K extends string, V>(\n record: Partial<Record<K, V>>\n): [K, V][] => Object.entries(record) as [K, V][]\n","// AUTO-GENERATED from skills source — do not edit manually\n// Run: bun run generate:types\n\nimport type {\n CategoryMap,\n MergedSkillsMatrix,\n ResolvedSkill,\n ResolvedStack,\n SkillSlugMap,\n} from \"../matrix\";\nimport type { AgentName } from \"../agents\";\nimport type { SkillId, SkillSlug } from \"../skills\";\nimport type { Category, Domain } from \"./source-types\";\n\n// ── Built-in Matrix ───────────────────────────────────────────\n\nexport const BUILT_IN_MATRIX: MergedSkillsMatrix = {\n version: \"1.0.0\",\n categories: {\n \"web-framework\": {\n id: \"web-framework\",\n displayName: \"Framework\",\n description: \"UI framework (React, Vue, Angular, SolidJS)\",\n domain: \"web\",\n exclusive: true,\n required: true,\n order: 1,\n },\n \"web-meta-framework\": {\n id: \"web-meta-framework\",\n displayName: \"Meta-Framework\",\n description: \"Full-stack meta-framework (Next.js, Remix, Nuxt, SvelteKit)\",\n domain: \"web\",\n exclusive: true,\n required: false,\n order: 2,\n },\n \"web-routing\": {\n id: \"web-routing\",\n displayName: \"Routing\",\n description: \"Client-side routing (TanStack Router)\",\n domain: \"web\",\n exclusive: true,\n required: false,\n order: 3,\n },\n \"web-styling\": {\n id: \"web-styling\",\n displayName: \"Styling\",\n description: \"CSS approach (SCSS Modules, Tailwind, CVA)\",\n domain: \"web\",\n exclusive: false,\n required: true,\n order: 4,\n },\n \"web-client-state\": {\n id: \"web-client-state\",\n displayName: \"Client State Management\",\n description: \"UI state, forms, local data (Zustand, Redux, MobX)\",\n domain: \"web\",\n exclusive: true,\n required: false,\n order: 5,\n },\n \"web-server-state\": {\n id: \"web-server-state\",\n displayName: \"Server State / Data Fetching\",\n description: \"API data caching (React Query, SWR)\",\n domain: \"web\",\n exclusive: true,\n required: false,\n order: 6,\n },\n \"web-graphql-client\": {\n id: \"web-graphql-client\",\n displayName: \"GraphQL Client\",\n description: \"GraphQL client library (Apollo Client, urql)\",\n domain: \"web\",\n exclusive: true,\n required: false,\n order: 7,\n },\n \"web-rpc\": {\n id: \"web-rpc\",\n displayName: \"Type-Safe RPC\",\n description: \"End-to-end type-safe RPC (tRPC)\",\n domain: \"web\",\n exclusive: false,\n required: false,\n order: 8,\n },\n \"web-forms\": {\n id: \"web-forms\",\n displayName: \"Validation\",\n description: \"Schema validation (Zod)\",\n domain: \"web\",\n exclusive: false,\n required: false,\n order: 9,\n },\n \"web-form-library\": {\n id: \"web-form-library\",\n displayName: \"Form Library\",\n description: \"Form state and submission (React Hook Form, TanStack Form, VeeValidate)\",\n domain: \"web\",\n exclusive: true,\n required: false,\n order: 10,\n },\n \"web-testing\": {\n id: \"web-testing\",\n displayName: \"Testing\",\n description: \"Unit, component, and visual testing\",\n domain: \"web\",\n exclusive: false,\n required: false,\n order: 11,\n },\n \"web-e2e\": {\n id: \"web-e2e\",\n displayName: \"E2E Testing\",\n description: \"End-to-end browser testing (Playwright, Cypress)\",\n domain: \"web\",\n exclusive: true,\n required: false,\n order: 12,\n },\n \"web-ui-kit\": {\n id: \"web-ui-kit\",\n displayName: \"Design System Kit\",\n description: \"Pre-styled component kit (shadcn/ui, MUI, Mantine, Vuetify)\",\n domain: \"web\",\n exclusive: true,\n required: false,\n order: 13,\n },\n \"web-ui-components\": {\n id: \"web-ui-components\",\n displayName: \"Headless Components\",\n description: \"Headless primitives (Radix UI, Base UI, Headless UI, TanStack Table)\",\n domain: \"web\",\n exclusive: false,\n required: false,\n order: 14,\n },\n \"web-tooling\": {\n id: \"web-tooling\",\n displayName: \"Build Tools\",\n description: \"Frontend build tools and bundlers (Vite, Webpack)\",\n domain: \"web\",\n exclusive: false,\n required: false,\n order: 15,\n },\n \"web-docs\": {\n id: \"web-docs\",\n displayName: \"Documentation Framework\",\n description: \"Documentation site generator (Docusaurus, VitePress)\",\n domain: \"web\",\n exclusive: true,\n required: false,\n order: 16,\n },\n \"web-mocking\": {\n id: \"web-mocking\",\n displayName: \"API Mocking\",\n description: \"Mock Service Worker for development and testing\",\n domain: \"web\",\n exclusive: false,\n required: false,\n order: 17,\n },\n \"web-error-handling\": {\n id: \"web-error-handling\",\n displayName: \"Error Handling\",\n description: \"Error boundaries, result types, and error patterns\",\n domain: \"web\",\n exclusive: false,\n required: false,\n order: 18,\n },\n \"web-i18n\": {\n id: \"web-i18n\",\n displayName: \"Internationalization\",\n description: \"i18n libraries (next-intl, react-intl, vue-i18n)\",\n domain: \"web\",\n exclusive: true,\n required: false,\n order: 19,\n },\n \"web-file-upload\": {\n id: \"web-file-upload\",\n displayName: \"File Upload\",\n description: \"File upload patterns and handling\",\n domain: \"web\",\n exclusive: false,\n required: false,\n order: 20,\n },\n \"web-files\": {\n id: \"web-files\",\n displayName: \"Files & Images\",\n description: \"Image handling and file processing\",\n domain: \"web\",\n exclusive: false,\n required: false,\n order: 21,\n },\n \"web-utilities\": {\n id: \"web-utilities\",\n displayName: \"Utilities\",\n description: \"Utility libraries (date-fns, native JS patterns)\",\n domain: \"web\",\n exclusive: false,\n required: false,\n order: 22,\n },\n \"web-realtime\": {\n id: \"web-realtime\",\n displayName: \"Realtime\",\n description: \"Bidirectional realtime (WebSockets, Socket.IO)\",\n domain: \"web\",\n exclusive: true,\n required: false,\n order: 23,\n },\n \"web-streaming\": {\n id: \"web-streaming\",\n displayName: \"Server Streaming\",\n description: \"Server-sent events and HTTP streaming\",\n domain: \"web\",\n exclusive: false,\n required: false,\n order: 24,\n },\n \"web-animation\": {\n id: \"web-animation\",\n displayName: \"Animation\",\n description: \"Animation libraries and CSS animations\",\n domain: \"web\",\n exclusive: false,\n required: false,\n order: 25,\n },\n \"web-pwa\": {\n id: \"web-pwa\",\n displayName: \"Progressive Web App\",\n description: \"Service workers, offline-first patterns, and PWA features\",\n domain: \"web\",\n exclusive: false,\n required: false,\n order: 26,\n },\n \"web-accessibility\": {\n id: \"web-accessibility\",\n displayName: \"Accessibility\",\n description: \"WCAG compliance, ARIA, and keyboard navigation\",\n domain: \"web\",\n exclusive: false,\n required: false,\n order: 27,\n },\n \"web-performance\": {\n id: \"web-performance\",\n displayName: \"Web Performance\",\n description: \"Bundle optimization, render performance, and code splitting\",\n domain: \"web\",\n exclusive: false,\n required: false,\n order: 28,\n },\n \"web-3d\": {\n id: \"web-3d\",\n displayName: \"3D Graphics\",\n description: \"3D rendering (React Three Fiber)\",\n domain: \"web\",\n exclusive: false,\n required: false,\n order: 29,\n },\n \"web-dataviz\": {\n id: \"web-dataviz\",\n displayName: \"Data Visualization\",\n description: \"Charts and data visualization (D3, Recharts)\",\n domain: \"web\",\n exclusive: false,\n required: false,\n order: 30,\n },\n \"web-dnd\": {\n id: \"web-dnd\",\n displayName: \"Drag & Drop\",\n description: \"Drag-and-drop interactions (dnd-kit)\",\n domain: \"web\",\n exclusive: false,\n required: false,\n order: 31,\n },\n \"web-editor\": {\n id: \"web-editor\",\n displayName: \"Rich Text Editor\",\n description: \"Rich text editing (Lexical, Tiptap)\",\n domain: \"web\",\n exclusive: true,\n required: false,\n order: 32,\n },\n \"web-maps\": {\n id: \"web-maps\",\n displayName: \"Maps\",\n description: \"Interactive maps (Leaflet, Mapbox)\",\n domain: \"web\",\n exclusive: true,\n required: false,\n order: 33,\n },\n \"api-api\": {\n id: \"api-api\",\n displayName: \"API Framework\",\n description: \"Backend framework (Hono, Express, Fastify)\",\n domain: \"api\",\n exclusive: true,\n required: true,\n order: 1,\n },\n \"api-sql-engine\": {\n id: \"api-sql-engine\",\n displayName: \"SQL Engine\",\n description: \"Primary SQL engine (PostgreSQL, MySQL, CockroachDB)\",\n domain: \"api\",\n exclusive: true,\n required: false,\n order: 2,\n },\n \"api-orm\": {\n id: \"api-orm\",\n displayName: \"ORM / Query Builder\",\n description: \"Database access layer (Drizzle, Prisma, TypeORM)\",\n domain: \"api\",\n exclusive: true,\n required: false,\n order: 3,\n },\n \"api-document\": {\n id: \"api-document\",\n displayName: \"Document / Multi-Model Database\",\n description: \"Primary non-SQL store (MongoDB, Mongoose, Gel, SurrealDB)\",\n domain: \"api\",\n exclusive: true,\n required: false,\n order: 4,\n },\n \"api-kv\": {\n id: \"api-kv\",\n displayName: \"Cache / KV Store\",\n description: \"Redis-class key-value provider (Redis, Upstash)\",\n domain: \"api\",\n exclusive: true,\n required: false,\n order: 5,\n },\n \"api-db-host\": {\n id: \"api-db-host\",\n displayName: \"Managed Database\",\n description: \"Managed database host (Neon, PlanetScale, Turso)\",\n domain: \"api\",\n exclusive: true,\n required: false,\n order: 6,\n },\n \"api-auth\": {\n id: \"api-auth\",\n displayName: \"Authentication\",\n description: \"Auth solution (Better Auth, Auth.js)\",\n domain: \"api\",\n exclusive: true,\n required: false,\n order: 8,\n },\n \"api-observability\": {\n id: \"api-observability\",\n displayName: \"Observability\",\n description: \"Logging, monitoring, error tracking\",\n domain: \"api\",\n exclusive: false,\n required: false,\n order: 9,\n },\n \"api-analytics\": {\n id: \"api-analytics\",\n displayName: \"Analytics\",\n description: \"Product analytics and tracking\",\n domain: \"api\",\n exclusive: false,\n required: false,\n order: 10,\n },\n \"api-email\": {\n id: \"api-email\",\n displayName: \"Email\",\n description: \"Transactional email (Resend, Sendgrid)\",\n domain: \"api\",\n exclusive: false,\n required: false,\n order: 11,\n },\n \"ai-provider\": {\n id: \"ai-provider\",\n displayName: \"AI Provider\",\n description: \"AI model provider SDKs (Anthropic, OpenAI, Google, etc.)\",\n domain: \"ai\",\n exclusive: false,\n required: false,\n order: 1,\n },\n \"ai-orchestration\": {\n id: \"ai-orchestration\",\n displayName: \"AI Orchestration\",\n description: \"Multi-model AI workflow frameworks (LangChain, LlamaIndex, Vercel AI)\",\n domain: \"ai\",\n exclusive: false,\n required: false,\n order: 2,\n },\n \"ai-observability\": {\n id: \"ai-observability\",\n displayName: \"AI Observability\",\n description: \"LLM monitoring, evaluation, and tracing (Langfuse, Promptfoo)\",\n domain: \"ai\",\n exclusive: false,\n required: false,\n order: 3,\n },\n \"ai-infrastructure\": {\n id: \"ai-infrastructure\",\n displayName: \"AI Infrastructure\",\n description: \"Model hosting, serving, and inference gateways\",\n domain: \"ai\",\n exclusive: false,\n required: false,\n order: 4,\n },\n \"ai-patterns\": {\n id: \"ai-patterns\",\n displayName: \"AI Patterns\",\n description: \"Cross-cutting AI usage patterns (tool use, prompting)\",\n domain: \"ai\",\n exclusive: false,\n required: false,\n order: 5,\n },\n \"api-baas\": {\n id: \"api-baas\",\n displayName: \"Backend as a Service\",\n description:\n \"Full backend platform — auth, database, storage, functions (Supabase, Firebase)\",\n domain: \"api\",\n exclusive: true,\n required: false,\n order: 7,\n },\n \"api-performance\": {\n id: \"api-performance\",\n displayName: \"Performance\",\n description: \"API performance patterns and optimization\",\n domain: \"api\",\n exclusive: false,\n required: false,\n order: 12,\n },\n \"api-cms\": {\n id: \"api-cms\",\n displayName: \"CMS\",\n description: \"CMS platforms (Payload, Sanity, Strapi)\",\n domain: \"api\",\n exclusive: true,\n required: false,\n order: 13,\n },\n \"api-commerce\": {\n id: \"api-commerce\",\n displayName: \"Commerce\",\n description: \"Commerce platforms (Stripe)\",\n domain: \"api\",\n exclusive: false,\n required: false,\n order: 14,\n },\n \"api-search\": {\n id: \"api-search\",\n displayName: \"Search\",\n description: \"Search engines (Elasticsearch, Meilisearch)\",\n domain: \"api\",\n exclusive: true,\n required: false,\n order: 15,\n },\n \"api-vector-db\": {\n id: \"api-vector-db\",\n displayName: \"Vector Database\",\n description: \"Vector databases (Pinecone, Qdrant, Chroma, Weaviate)\",\n domain: \"api\",\n exclusive: true,\n required: false,\n order: 16,\n },\n \"api-caching\": {\n id: \"api-caching\",\n displayName: \"Caching\",\n description: \"API caching strategies and patterns\",\n domain: \"api\",\n exclusive: false,\n required: false,\n order: 17,\n },\n \"api-graphql\": {\n id: \"api-graphql\",\n displayName: \"GraphQL Server\",\n description: \"GraphQL servers (Apollo Server, Mercurius, Yoga)\",\n domain: \"api\",\n exclusive: true,\n required: false,\n order: 18,\n },\n \"api-messaging\": {\n id: \"api-messaging\",\n displayName: \"Messaging\",\n description: \"Webhooks and event-driven messaging\",\n domain: \"api\",\n exclusive: false,\n required: false,\n order: 19,\n },\n \"api-queue\": {\n id: \"api-queue\",\n displayName: \"Queues\",\n description: \"Background job queues (BullMQ)\",\n domain: \"api\",\n exclusive: false,\n required: false,\n order: 20,\n },\n \"api-specs\": {\n id: \"api-specs\",\n displayName: \"API Specifications\",\n description: \"API specification formats (OpenAPI)\",\n domain: \"api\",\n exclusive: false,\n required: false,\n order: 21,\n },\n \"mobile-framework\": {\n id: \"mobile-framework\",\n displayName: \"Mobile Framework\",\n description: \"Native mobile framework (React Native, Expo)\",\n domain: \"mobile\",\n exclusive: false,\n required: true,\n order: 1,\n },\n \"mobile-animation\": {\n id: \"mobile-animation\",\n displayName: \"Mobile Animation\",\n description: \"Native animation and gestures (Reanimated, Gesture Handler, Skia)\",\n domain: \"mobile\",\n exclusive: false,\n required: false,\n order: 6,\n },\n \"mobile-background\": {\n id: \"mobile-background\",\n displayName: \"Background Tasks\",\n description: \"Background task scheduling and execution\",\n domain: \"mobile\",\n exclusive: false,\n required: false,\n order: 12,\n },\n \"mobile-camera\": {\n id: \"mobile-camera\",\n displayName: \"Camera\",\n description: \"Camera integration (Vision Camera)\",\n domain: \"mobile\",\n exclusive: false,\n required: false,\n order: 10,\n },\n \"mobile-deep-linking\": {\n id: \"mobile-deep-linking\",\n displayName: \"Deep Linking\",\n description: \"Deep links and universal/app links\",\n domain: \"mobile\",\n exclusive: false,\n required: false,\n order: 9,\n },\n \"mobile-deployment\": {\n id: \"mobile-deployment\",\n displayName: \"Deployment\",\n description: \"App builds and store releases (EAS)\",\n domain: \"mobile\",\n exclusive: false,\n required: false,\n order: 15,\n },\n \"mobile-hardware\": {\n id: \"mobile-hardware\",\n displayName: \"Hardware\",\n description: \"Device hardware access (BLE, NFC)\",\n domain: \"mobile\",\n exclusive: false,\n required: false,\n order: 11,\n },\n \"mobile-navigation\": {\n id: \"mobile-navigation\",\n displayName: \"Navigation\",\n description: \"Screen navigation (Expo Router, React Navigation)\",\n domain: \"mobile\",\n exclusive: true,\n required: false,\n order: 2,\n },\n \"mobile-notifications\": {\n id: \"mobile-notifications\",\n displayName: \"Notifications\",\n description: \"Push and local notifications\",\n domain: \"mobile\",\n exclusive: false,\n required: false,\n order: 8,\n },\n \"mobile-performance\": {\n id: \"mobile-performance\",\n displayName: \"Mobile Performance\",\n description: \"React Native performance optimization\",\n domain: \"mobile\",\n exclusive: false,\n required: false,\n order: 13,\n },\n \"mobile-security\": {\n id: \"mobile-security\",\n displayName: \"Mobile Security\",\n description: \"Mobile app security patterns (React Native)\",\n domain: \"mobile\",\n exclusive: false,\n required: false,\n order: 14,\n },\n \"mobile-storage\": {\n id: \"mobile-storage\",\n displayName: \"Mobile Storage\",\n description: \"On-device storage and offline databases (MMKV, SQLite, WatermelonDB)\",\n domain: \"mobile\",\n exclusive: false,\n required: false,\n order: 4,\n },\n \"mobile-styling\": {\n id: \"mobile-styling\",\n displayName: \"Mobile Styling\",\n description: \"Native styling (NativeWind, Unistyles)\",\n domain: \"mobile\",\n exclusive: true,\n required: false,\n order: 3,\n },\n \"mobile-testing\": {\n id: \"mobile-testing\",\n displayName: \"Mobile Testing\",\n description: \"Mobile E2E testing (Detox, Maestro)\",\n domain: \"mobile\",\n exclusive: false,\n required: false,\n order: 7,\n },\n \"mobile-ui-components\": {\n id: \"mobile-ui-components\",\n displayName: \"Mobile UI Components\",\n description: \"Native UI component libraries (React Native Paper, Tamagui)\",\n domain: \"mobile\",\n exclusive: true,\n required: false,\n order: 5,\n },\n \"shared-monorepo\": {\n id: \"shared-monorepo\",\n displayName: \"Monorepo\",\n description: \"Workspace management (pnpm workspaces)\",\n domain: \"shared\",\n exclusive: false,\n required: false,\n order: 1,\n },\n \"shared-task-runner\": {\n id: \"shared-task-runner\",\n displayName: \"Task Runner\",\n description: \"Monorepo task orchestration (Turborepo, Nx)\",\n domain: \"shared\",\n exclusive: true,\n required: false,\n order: 2,\n },\n \"shared-lint\": {\n id: \"shared-lint\",\n displayName: \"Lint & Format\",\n description: \"Linting and formatting (Biome, ESLint & Prettier)\",\n domain: \"shared\",\n exclusive: true,\n required: false,\n order: 3,\n },\n \"shared-tooling\": {\n id: \"shared-tooling\",\n displayName: \"Build Tooling\",\n description: \"TypeScript config, git hooks, changesets, stack detection\",\n domain: \"shared\",\n exclusive: false,\n required: false,\n order: 4,\n },\n \"shared-security\": {\n id: \"shared-security\",\n displayName: \"Security\",\n description: \"Authentication security patterns and best practices\",\n domain: \"shared\",\n exclusive: false,\n required: false,\n order: 5,\n },\n \"meta-reviewing\": {\n id: \"meta-reviewing\",\n displayName: \"Code Review\",\n description: \"Code review patterns and methodology\",\n domain: \"meta\",\n exclusive: false,\n required: false,\n order: 1,\n },\n \"meta-methodology\": {\n id: \"meta-methodology\",\n displayName: \"Methodology\",\n description: \"Research and investigation methodology\",\n domain: \"meta\",\n exclusive: false,\n required: false,\n order: 2,\n },\n \"meta-design\": {\n id: \"meta-design\",\n displayName: \"Software Design\",\n description: \"Software design patterns and paradigms\",\n domain: \"meta\",\n exclusive: false,\n required: false,\n order: 3,\n },\n \"meta-planning\": {\n id: \"meta-planning\",\n displayName: \"Planning\",\n description: \"Specification planning frameworks per domain\",\n domain: \"meta\",\n exclusive: false,\n required: false,\n order: 4,\n },\n \"infra-ci-cd\": {\n id: \"infra-ci-cd\",\n displayName: \"CI/CD\",\n description: \"Continuous integration and deployment pipelines\",\n domain: \"infra\",\n exclusive: false,\n required: false,\n order: 1,\n },\n \"infra-platform\": {\n id: \"infra-platform\",\n displayName: \"Platform\",\n description: \"Edge compute and deployment platforms\",\n domain: \"infra\",\n exclusive: false,\n required: false,\n order: 2,\n },\n \"infra-config\": {\n id: \"infra-config\",\n displayName: \"Configuration\",\n description: \"Environment and infrastructure configuration\",\n domain: \"infra\",\n exclusive: false,\n required: false,\n order: 3,\n },\n \"infra-containers\": {\n id: \"infra-containers\",\n displayName: \"Containers\",\n description: \"Containers (Docker, Kubernetes)\",\n domain: \"infra\",\n exclusive: false,\n required: false,\n order: 5,\n },\n \"infra-iac\": {\n id: \"infra-iac\",\n displayName: \"Infrastructure as Code\",\n description: \"Infrastructure as code (Pulumi, SST, Terraform)\",\n domain: \"infra\",\n exclusive: true,\n required: false,\n order: 4,\n },\n \"cli-framework\": {\n id: \"cli-framework\",\n displayName: \"CLI Framework\",\n description: \"CLI application framework (Commander, oclif)\",\n domain: \"cli\",\n exclusive: true,\n required: true,\n order: 1,\n },\n \"cli-prompts\": {\n id: \"cli-prompts\",\n displayName: \"CLI Prompts\",\n description: \"Interactive CLI prompts (Clack)\",\n domain: \"cli\",\n exclusive: false,\n required: false,\n order: 2,\n },\n \"desktop-framework\": {\n id: \"desktop-framework\",\n displayName: \"Desktop Framework\",\n description: \"Desktop application framework (Tauri, Electron)\",\n domain: \"desktop\",\n exclusive: true,\n required: true,\n order: 1,\n },\n \"desktop-backend\": {\n id: \"desktop-backend\",\n displayName: \"Desktop Backend\",\n description: \"Desktop backend integration (Tauri)\",\n domain: \"desktop\",\n exclusive: false,\n required: false,\n order: 3,\n },\n \"desktop-ipc\": {\n id: \"desktop-ipc\",\n displayName: \"IPC\",\n description: \"Inter-process communication (Electron)\",\n domain: \"desktop\",\n exclusive: false,\n required: false,\n order: 2,\n },\n \"desktop-mobile\": {\n id: \"desktop-mobile\",\n displayName: \"Mobile Support\",\n description: \"Desktop-to-mobile platform support (Tauri)\",\n domain: \"desktop\",\n exclusive: false,\n required: false,\n order: 12,\n },\n \"desktop-multiwindow\": {\n id: \"desktop-multiwindow\",\n displayName: \"Multi-Window\",\n description: \"Multi-window management (Electron, Tauri)\",\n domain: \"desktop\",\n exclusive: false,\n required: false,\n order: 5,\n },\n \"desktop-packaging\": {\n id: \"desktop-packaging\",\n displayName: \"Packaging\",\n description: \"App packaging and distribution (Electron Forge, Tauri)\",\n domain: \"desktop\",\n exclusive: true,\n required: false,\n order: 9,\n },\n \"desktop-plugins\": {\n id: \"desktop-plugins\",\n displayName: \"Plugins\",\n description: \"Desktop plugin systems (Tauri)\",\n domain: \"desktop\",\n exclusive: false,\n required: false,\n order: 11,\n },\n \"desktop-security\": {\n id: \"desktop-security\",\n displayName: \"Desktop Security\",\n description: \"Desktop app security hardening (Electron, Tauri)\",\n domain: \"desktop\",\n exclusive: false,\n required: false,\n order: 7,\n },\n \"desktop-storage\": {\n id: \"desktop-storage\",\n displayName: \"Desktop Storage\",\n description: \"Desktop data persistence (Electron)\",\n domain: \"desktop\",\n exclusive: false,\n required: false,\n order: 6,\n },\n \"desktop-testing\": {\n id: \"desktop-testing\",\n displayName: \"Desktop Testing\",\n description: \"Desktop app testing (Electron)\",\n domain: \"desktop\",\n exclusive: false,\n required: false,\n order: 8,\n },\n \"desktop-ui\": {\n id: \"desktop-ui\",\n displayName: \"Desktop UI\",\n description: \"Desktop UI patterns (Electron)\",\n domain: \"desktop\",\n exclusive: false,\n required: false,\n order: 4,\n },\n \"desktop-updates\": {\n id: \"desktop-updates\",\n displayName: \"Auto-Updates\",\n description: \"Application auto-updates (electron-updater)\",\n domain: \"desktop\",\n exclusive: false,\n required: false,\n order: 10,\n },\n },\n skills: {\n \"ai-infrastructure-huggingface-inference\": {\n id: \"ai-infrastructure-huggingface-inference\",\n slug: \"huggingface-inference\",\n displayName: \"Hugging Face Inference\",\n description: \"Access 200k+ models via Inference API and Endpoints\",\n usageGuidance:\n \"Use when accessing ML models via Hugging Face — text generation, chat completion, embeddings, image generation, audio transcription, translation, summarization, and custom Inference Endpoints for dedicated deployments.\",\n category: \"ai-infrastructure\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"ai-provider-anthropic-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-openai-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-google-gemini-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-mistral-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-cohere-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-together-ai\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-replicate\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-ollama\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-litellm\",\n purpose: \"AI Provider SDK\",\n },\n ],\n path: \"skills/ai-infrastructure-huggingface-inference\",\n },\n \"ai-infrastructure-litellm\": {\n id: \"ai-infrastructure-litellm\",\n slug: \"litellm\",\n displayName: \"LiteLLM\",\n description: \"Unified LLM proxy — 100+ providers, OpenAI-compatible API\",\n usageGuidance:\n \"Use when routing LLM requests through LiteLLM proxy — unified OpenAI-compatible API across providers, model fallbacks, load balancing, spend tracking, and rate limiting. Covers proxy server config.yaml setup, TypeScript client via OpenAI SDK, virtual keys, and production deployment.\",\n category: \"ai-infrastructure\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"ai-provider-anthropic-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-openai-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-google-gemini-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-mistral-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-cohere-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-together-ai\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-replicate\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-huggingface-inference\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-ollama\",\n purpose: \"AI Provider SDK\",\n },\n ],\n path: \"skills/ai-infrastructure-litellm\",\n },\n \"ai-infrastructure-modal\": {\n id: \"ai-infrastructure-modal\",\n slug: \"modal\",\n displayName: \"Modal\",\n description: \"Serverless GPU compute for model deployment and inference\",\n usageGuidance:\n \"Use when deploying ML models or GPU workloads on Modal — web endpoints for API access from TypeScript, serverless GPU functions, model serving, scheduled jobs, and container-based deployments.\",\n category: \"ai-infrastructure\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/ai-infrastructure-modal\",\n },\n \"ai-infrastructure-ollama\": {\n id: \"ai-infrastructure-ollama\",\n slug: \"ollama\",\n displayName: \"Ollama\",\n description: \"Local LLM inference with the Ollama JavaScript client\",\n usageGuidance:\n \"Use when running LLMs locally with Ollama — chat completions, streaming, tool calling, vision, embeddings, model management, structured output with JSON schemas, and the OpenAI-compatible endpoint.\",\n category: \"ai-infrastructure\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"ai-provider-anthropic-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-openai-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-google-gemini-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-mistral-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-cohere-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-together-ai\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-replicate\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-huggingface-inference\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-litellm\",\n purpose: \"AI Provider SDK\",\n },\n ],\n path: \"skills/ai-infrastructure-ollama\",\n },\n \"ai-infrastructure-replicate\": {\n id: \"ai-infrastructure-replicate\",\n slug: \"replicate\",\n displayName: \"Replicate\",\n description: \"Run open-source ML models with serverless GPU inference\",\n usageGuidance:\n \"Use when running open-source models on Replicate — model predictions, streaming, webhooks, file handling, model versioning, and serverless GPU deployment.\",\n category: \"ai-infrastructure\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"ai-provider-anthropic-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-openai-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-google-gemini-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-mistral-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-cohere-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-together-ai\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-huggingface-inference\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-ollama\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-litellm\",\n purpose: \"AI Provider SDK\",\n },\n ],\n path: \"skills/ai-infrastructure-replicate\",\n },\n \"ai-infrastructure-together-ai\": {\n id: \"ai-infrastructure-together-ai\",\n slug: \"together-ai\",\n displayName: \"Together AI\",\n description: \"Multi-model inference API for open-source LLMs\",\n usageGuidance:\n \"Use when running open-source LLMs on Together AI — chat completions, streaming, embeddings, image generation, function calling, JSON mode, structured output, fine-tuning, and OpenAI-compatible endpoints.\",\n category: \"ai-infrastructure\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"ai-provider-anthropic-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-openai-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-google-gemini-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-mistral-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-cohere-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-replicate\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-huggingface-inference\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-ollama\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-litellm\",\n purpose: \"AI Provider SDK\",\n },\n ],\n path: \"skills/ai-infrastructure-together-ai\",\n },\n \"ai-observability-langfuse\": {\n id: \"ai-observability-langfuse\",\n slug: \"langfuse\",\n displayName: \"Langfuse\",\n description: \"LLM observability — tracing, evaluations, prompt management\",\n usageGuidance:\n \"Use when adding observability to LLM applications — tracing LLM calls, tracking costs, evaluations, prompt management, session tracking, user feedback, and datasets for testing with Langfuse.\",\n category: \"ai-observability\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"ai-observability-promptfoo\",\n purpose: \"AI Evaluation / Observability\",\n },\n ],\n path: \"skills/ai-observability-langfuse\",\n },\n \"ai-observability-promptfoo\": {\n id: \"ai-observability-promptfoo\",\n slug: \"promptfoo\",\n displayName: \"Promptfoo\",\n description: \"Testing and evaluation framework for LLM prompts and apps\",\n usageGuidance:\n \"Use when testing LLM prompts and applications — promptfooconfig.yaml for test definitions, assertion types, model-graded evals, red teaming, CI integration, and comparative evaluation across providers.\",\n category: \"ai-observability\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"ai-observability-langfuse\",\n purpose: \"AI Evaluation / Observability\",\n },\n ],\n path: \"skills/ai-observability-promptfoo\",\n },\n \"ai-orchestration-langchain\": {\n id: \"ai-orchestration-langchain\",\n slug: \"langchain\",\n displayName: \"LangChain\",\n description: \"LLM app framework with chains, agents, RAG, and memory\",\n usageGuidance:\n \"Use when building LLM-powered applications with LangChain.js — chat models, prompt templates, output parsers, chains (LCEL), agents with tools, RAG pipelines, vector stores, and memory.\",\n category: \"ai-orchestration\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"ai-orchestration-vercel-ai-sdk\",\n purpose: \"AI SDK\",\n },\n {\n skillId: \"ai-orchestration-llamaindex\",\n purpose: \"AI SDK\",\n },\n ],\n path: \"skills/ai-orchestration-langchain\",\n },\n \"ai-orchestration-llamaindex\": {\n id: \"ai-orchestration-llamaindex\",\n slug: \"llamaindex\",\n displayName: \"LlamaIndex\",\n description: \"LLM data framework — indexing, retrieval, query engines\",\n usageGuidance:\n \"Use when building RAG and data-aware LLM applications — document loading, text chunking, vector indexing, query engines, chat engines, and agentic RAG with LlamaIndex.TS.\",\n category: \"ai-orchestration\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"ai-orchestration-vercel-ai-sdk\",\n purpose: \"AI SDK\",\n },\n {\n skillId: \"ai-orchestration-langchain\",\n purpose: \"AI SDK\",\n },\n ],\n path: \"skills/ai-orchestration-llamaindex\",\n },\n \"ai-orchestration-vercel-ai-sdk\": {\n id: \"ai-orchestration-vercel-ai-sdk\",\n slug: \"vercel-ai-sdk\",\n displayName: \"Vercel AI SDK\",\n description: \"Vercel AI SDK for streaming AI applications\",\n usageGuidance:\n \"Use when building AI-powered features with streaming, chat UIs, or multi-provider AI integrations. Covers generateText, streamText, structured output with Zod, tool calling, useChat/useCompletion hooks, embeddings, and RAG patterns.\",\n category: \"ai-orchestration\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"ai-orchestration-langchain\",\n purpose: \"AI SDK\",\n },\n {\n skillId: \"ai-orchestration-llamaindex\",\n purpose: \"AI SDK\",\n },\n ],\n path: \"skills/ai-orchestration-vercel-ai-sdk\",\n },\n \"ai-patterns-tool-use-patterns\": {\n id: \"ai-patterns-tool-use-patterns\",\n slug: \"tool-use-patterns\",\n displayName: \"Tool Use Patterns\",\n description: \"Provider-agnostic patterns for LLM function calling\",\n usageGuidance:\n \"Use when implementing LLM tool use -- tool definition schemas, the tool call loop pattern, parallel tool calls, error reporting back to the model, multi-step agent workflows, human-in-the-loop patterns, and tool choice control. Provider-agnostic -- shows generic TypeScript patterns, not provider-specific SDK code.\",\n category: \"ai-patterns\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/ai-patterns-tool-use-patterns\",\n },\n \"ai-provider-anthropic-sdk\": {\n id: \"ai-provider-anthropic-sdk\",\n slug: \"anthropic-sdk\",\n displayName: \"Anthropic SDK\",\n description: \"Claude API — messages, streaming, tool use, and vision\",\n usageGuidance:\n \"Use when integrating Claude via the Anthropic API — messages API, streaming responses, tool use (function calling), vision (image input), extended thinking, batch API, and prompt caching.\",\n category: \"ai-provider\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"ai-provider-openai-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-google-gemini-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-mistral-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-cohere-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-together-ai\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-replicate\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-huggingface-inference\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-ollama\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-litellm\",\n purpose: \"AI Provider SDK\",\n },\n ],\n path: \"skills/ai-provider-anthropic-sdk\",\n },\n \"ai-provider-claude-vision\": {\n id: \"ai-provider-claude-vision\",\n slug: \"claude-vision\",\n displayName: \"Claude Vision\",\n description: \"Image understanding and document analysis with Claude\",\n usageGuidance:\n \"Use when processing images and documents with Claude — image analysis, document extraction, chart interpretation, multi-image comparison, and PDF processing with the Anthropic API.\",\n category: \"ai-provider\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"ai-provider-anthropic-sdk\"],\n needsAny: false,\n reason: \"Claude Vision uses the Anthropic SDK\",\n },\n ],\n alternatives: [],\n path: \"skills/ai-provider-claude-vision\",\n },\n \"ai-provider-cohere-sdk\": {\n id: \"ai-provider-cohere-sdk\",\n slug: \"cohere-sdk\",\n displayName: \"Cohere SDK\",\n description: \"Cohere API — chat, embeddings, rerank, and RAG\",\n usageGuidance:\n \"Use when integrating Cohere AI -- chat completions with Command models, embeddings for semantic search, rerank for relevance scoring, RAG with inline documents and citations, tool use / function calling, and streaming.\",\n category: \"ai-provider\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"ai-provider-anthropic-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-openai-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-google-gemini-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-mistral-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-together-ai\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-replicate\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-huggingface-inference\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-ollama\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-litellm\",\n purpose: \"AI Provider SDK\",\n },\n ],\n path: \"skills/ai-provider-cohere-sdk\",\n },\n \"ai-provider-elevenlabs\": {\n id: \"ai-provider-elevenlabs\",\n slug: \"elevenlabs\",\n displayName: \"ElevenLabs\",\n description: \"Text-to-speech, voice cloning, and real-time streaming\",\n usageGuidance:\n \"Use when generating speech with ElevenLabs — text-to-speech, streaming audio, voice cloning, voice selection, pronunciation control (SSML), and real-time conversational AI.\",\n category: \"ai-provider\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/ai-provider-elevenlabs\",\n },\n \"ai-provider-google-gemini-sdk\": {\n id: \"ai-provider-google-gemini-sdk\",\n slug: \"google-gemini-sdk\",\n displayName: \"Google Gemini SDK\",\n description: \"Gemini API — multimodal input, tools, structured output\",\n usageGuidance:\n \"Use when integrating Google Gemini — text generation, multimodal input (images, video, audio, PDF), function calling, structured JSON output, streaming, embeddings, and context caching.\",\n category: \"ai-provider\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"ai-provider-anthropic-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-openai-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-mistral-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-cohere-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-together-ai\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-replicate\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-huggingface-inference\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-ollama\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-litellm\",\n purpose: \"AI Provider SDK\",\n },\n ],\n path: \"skills/ai-provider-google-gemini-sdk\",\n },\n \"ai-provider-mistral-sdk\": {\n id: \"ai-provider-mistral-sdk\",\n slug: \"mistral-sdk\",\n displayName: \"Mistral SDK\",\n description: \"Mistral API — chat, embeddings, tools, code generation\",\n usageGuidance:\n \"Use when integrating Mistral AI models — chat completions, streaming, function calling, embeddings, JSON mode, structured outputs with Zod, vision with supported models, and Codestral for code generation / FIM.\",\n category: \"ai-provider\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"ai-provider-anthropic-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-openai-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-google-gemini-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-cohere-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-together-ai\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-replicate\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-huggingface-inference\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-ollama\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-litellm\",\n purpose: \"AI Provider SDK\",\n },\n ],\n path: \"skills/ai-provider-mistral-sdk\",\n },\n \"ai-provider-openai-sdk\": {\n id: \"ai-provider-openai-sdk\",\n slug: \"openai-sdk\",\n displayName: \"OpenAI SDK\",\n description: \"Official OpenAI SDK for TypeScript/Node.js\",\n usageGuidance:\n \"Use when building applications with OpenAI's API — GPT models, chat completions, Responses API, embeddings, function calling, structured outputs, vision, audio, streaming, and batch processing.\",\n category: \"ai-provider\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"ai-provider-anthropic-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-google-gemini-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-mistral-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-provider-cohere-sdk\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-together-ai\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-replicate\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-huggingface-inference\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-ollama\",\n purpose: \"AI Provider SDK\",\n },\n {\n skillId: \"ai-infrastructure-litellm\",\n purpose: \"AI Provider SDK\",\n },\n ],\n path: \"skills/ai-provider-openai-sdk\",\n },\n \"ai-provider-openai-whisper\": {\n id: \"ai-provider-openai-whisper\",\n slug: \"openai-whisper\",\n displayName: \"OpenAI Whisper\",\n description: \"Speech-to-text and translation via the OpenAI Audio API\",\n usageGuidance:\n \"Use when transcribing or translating audio with OpenAI Whisper -- file transcription, streaming transcription, translation to English, timestamp generation, and custom vocabulary prompting.\",\n category: \"ai-provider\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"ai-provider-openai-sdk\"],\n needsAny: false,\n reason: \"Whisper API uses the OpenAI SDK\",\n },\n ],\n alternatives: [],\n path: \"skills/ai-provider-openai-whisper\",\n },\n \"api-analytics-posthog-analytics\": {\n id: \"api-analytics-posthog-analytics\",\n slug: \"posthog-analytics\",\n displayName: \"PostHog Analytics\",\n description: \"Product analytics tracking\",\n usageGuidance:\n \"Use when tracking user events, setting up funnels, or implementing GDPR-compliant analytics.\",\n category: \"api-analytics\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/api-analytics-posthog-analytics\",\n },\n \"api-analytics-setup-posthog\": {\n id: \"api-analytics-setup-posthog\",\n slug: \"setup-posthog\",\n displayName: \"PostHog Setup\",\n description: \"PostHog initial setup\",\n usageGuidance: \"Use when setting up PostHog analytics or feature flags for the first time.\",\n category: \"api-analytics\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/api-analytics-setup-posthog\",\n },\n \"api-auth-better-auth-drizzle-hono\": {\n id: \"api-auth-better-auth-drizzle-hono\",\n slug: \"better-auth-drizzle-hono\",\n displayName: \"Better Auth\",\n description: \"Authentication and sessions\",\n usageGuidance: \"Use when implementing authentication, sessions, OAuth, or user management.\",\n category: \"api-auth\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"api-auth-nextauth\",\n reason: \"Authentication solutions are mutually exclusive\",\n },\n {\n skillId: \"api-auth-clerk\",\n reason: \"Authentication solutions are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [\n {\n skillIds: [\"api-database-drizzle\", \"api-framework-hono\"],\n needsAny: false,\n reason:\n \"Skill teaches Better Auth with the Drizzle adapter, mounted via Hono routes and typed Hono middleware\",\n },\n ],\n alternatives: [\n {\n skillId: \"api-auth-nextauth\",\n purpose: \"Auth\",\n },\n {\n skillId: \"api-auth-clerk\",\n purpose: \"Auth\",\n },\n ],\n path: \"skills/api-auth-better-auth-drizzle-hono\",\n },\n \"api-auth-clerk\": {\n id: \"api-auth-clerk\",\n slug: \"clerk\",\n displayName: \"Clerk\",\n description: \"Clerk managed authentication and user management\",\n usageGuidance:\n \"Use when building with Clerk for auth, user management, organizations, or pre-built UI components.\",\n category: \"api-auth\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"api-auth-better-auth-drizzle-hono\",\n reason: \"Authentication solutions are mutually exclusive\",\n },\n {\n skillId: \"api-auth-nextauth\",\n reason: \"Authentication solutions are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [\n {\n skillIds: [\"web-meta-framework-nextjs\"],\n needsAny: false,\n reason: \"Skill teaches @clerk/nextjs patterns\",\n },\n ],\n alternatives: [\n {\n skillId: \"api-auth-better-auth-drizzle-hono\",\n purpose: \"Auth\",\n },\n {\n skillId: \"api-auth-nextauth\",\n purpose: \"Auth\",\n },\n ],\n path: \"skills/api-auth-clerk\",\n },\n \"api-auth-nextauth\": {\n id: \"api-auth-nextauth\",\n slug: \"nextauth\",\n displayName: \"Auth.js\",\n description: \"Auth.js (NextAuth v5) authentication\",\n usageGuidance:\n \"Use when implementing authentication with Auth.js/NextAuth for Next.js, SvelteKit, or other frameworks.\",\n category: \"api-auth\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"api-auth-better-auth-drizzle-hono\",\n reason: \"Authentication solutions are mutually exclusive\",\n },\n {\n skillId: \"api-auth-clerk\",\n reason: \"Authentication solutions are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [\n {\n skillIds: [\"web-meta-framework-nextjs\"],\n needsAny: false,\n reason:\n \"Skill teaches the next-auth (Next.js) package — auth.ts, handlers, middleware, Server Components\",\n },\n ],\n alternatives: [\n {\n skillId: \"api-auth-better-auth-drizzle-hono\",\n purpose: \"Auth\",\n },\n {\n skillId: \"api-auth-clerk\",\n purpose: \"Auth\",\n },\n ],\n path: \"skills/api-auth-nextauth\",\n },\n \"api-baas-appwrite\": {\n id: \"api-baas-appwrite\",\n slug: \"appwrite\",\n displayName: \"Appwrite\",\n description: \"Open-source BaaS — auth, databases, storage, and functions\",\n usageGuidance:\n \"Use when building with Appwrite — client/server SDKs for authentication, TablesDB (tables, rows, columns), file storage with buckets, serverless functions, and realtime subscriptions.\",\n category: \"api-baas\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-baas-supabase\",\n purpose: \"Backend as a Service\",\n },\n {\n skillId: \"api-baas-firebase\",\n purpose: \"Backend as a Service\",\n },\n ],\n path: \"skills/api-baas-appwrite\",\n },\n \"api-baas-firebase\": {\n id: \"api-baas-firebase\",\n slug: \"firebase\",\n displayName: \"Firebase\",\n description: \"Google Firebase platform for web and mobile\",\n usageGuidance:\n \"Use when building with Firebase — Firestore, Authentication, Cloud Functions, Storage, Hosting, Realtime Database, and Firebase Admin SDK.\",\n category: \"api-baas\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-baas-supabase\",\n purpose: \"Backend as a Service\",\n },\n {\n skillId: \"api-baas-appwrite\",\n purpose: \"Backend as a Service\",\n },\n ],\n path: \"skills/api-baas-firebase\",\n },\n \"api-baas-neon\": {\n id: \"api-baas-neon\",\n slug: \"neon\",\n displayName: \"Neon\",\n description: \"Serverless PostgreSQL — branching, autoscaling, edge driver\",\n usageGuidance:\n \"Use when deploying PostgreSQL on Neon — serverless driver for edge/serverless functions, database branching for dev/preview, autoscaling, connection pooling, and the Neon API for programmatic management.\",\n category: \"api-db-host\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-baas-planetscale\",\n purpose: \"Managed Database\",\n },\n {\n skillId: \"api-baas-turso\",\n purpose: \"Managed Database\",\n },\n {\n skillId: \"api-database-vercel-postgres\",\n purpose: \"Managed Database\",\n },\n {\n skillId: \"api-database-cockroachdb\",\n purpose: \"Managed Database\",\n },\n ],\n path: \"skills/api-baas-neon\",\n },\n \"api-baas-planetscale\": {\n id: \"api-baas-planetscale\",\n slug: \"planetscale\",\n displayName: \"PlanetScale\",\n description: \"Serverless MySQL — branching, deploy requests, edge driver\",\n usageGuidance:\n \"Use when deploying MySQL on PlanetScale — serverless driver for edge/serverless, database branching, deploy requests for schema changes, connection pooling, and Vitess-powered horizontal scaling.\",\n category: \"api-db-host\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-baas-neon\",\n purpose: \"Managed Database\",\n },\n {\n skillId: \"api-baas-turso\",\n purpose: \"Managed Database\",\n },\n {\n skillId: \"api-database-vercel-postgres\",\n purpose: \"Managed Database\",\n },\n {\n skillId: \"api-database-cockroachdb\",\n purpose: \"Managed Database\",\n },\n ],\n path: \"skills/api-baas-planetscale\",\n },\n \"api-baas-supabase\": {\n id: \"api-baas-supabase\",\n slug: \"supabase\",\n displayName: \"Supabase\",\n description: \"Supabase backend-as-a-service platform\",\n usageGuidance:\n \"Use when building with Supabase Auth, Database, Realtime, Storage, or Edge Functions. Covers client setup, typed queries, RLS policies, realtime subscriptions, file storage, and Deno edge functions.\",\n category: \"api-baas\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-baas-firebase\",\n purpose: \"Backend as a Service\",\n },\n {\n skillId: \"api-baas-appwrite\",\n purpose: \"Backend as a Service\",\n },\n ],\n path: \"skills/api-baas-supabase\",\n },\n \"api-baas-turso\": {\n id: \"api-baas-turso\",\n slug: \"turso\",\n displayName: \"Turso\",\n description: \"Edge-hosted SQLite with libSQL driver and embedded replicas\",\n usageGuidance:\n \"Use when deploying SQLite on Turso — libSQL client for edge/serverless, embedded replicas for zero-latency reads, database groups for multi-region, and schema migrations with branching.\",\n category: \"api-db-host\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-baas-neon\",\n purpose: \"Managed Database\",\n },\n {\n skillId: \"api-baas-planetscale\",\n purpose: \"Managed Database\",\n },\n {\n skillId: \"api-database-vercel-postgres\",\n purpose: \"Managed Database\",\n },\n {\n skillId: \"api-database-cockroachdb\",\n purpose: \"Managed Database\",\n },\n ],\n path: \"skills/api-baas-turso\",\n },\n \"api-caching-strategies\": {\n id: \"api-caching-strategies\",\n slug: \"strategies\",\n displayName: \"Caching\",\n description: \"Application-level caching and cache invalidation patterns\",\n usageGuidance:\n \"Use when implementing caching in backend applications — cache-aside, write-through, write-behind, TTL strategies, cache invalidation, CDN caching headers, HTTP caching, in-memory caching, and distributed cache patterns.\",\n category: \"api-caching\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/api-caching-strategies\",\n },\n \"api-cms-payload\": {\n id: \"api-cms-payload\",\n slug: \"payload\",\n displayName: \"Payload CMS\",\n description: \"TypeScript headless CMS — code-first schema, admin panel\",\n usageGuidance:\n \"Use when building content-managed applications with Payload — collection configs, field types, hooks, access control, REST/GraphQL/Local API, admin panel customization, and database adapter pattern.\",\n category: \"api-cms\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-cms-sanity\",\n purpose: \"CMS\",\n },\n {\n skillId: \"api-cms-strapi\",\n purpose: \"CMS\",\n },\n ],\n path: \"skills/api-cms-payload\",\n },\n \"api-cms-sanity\": {\n id: \"api-cms-sanity\",\n slug: \"sanity\",\n displayName: \"Sanity\",\n description: \"Structured content with GROQ queries and live collaboration\",\n usageGuidance:\n \"Use when building content-managed applications with Sanity — schema definitions, GROQ queries, @sanity/client for data fetching, image handling with @sanity/image-url, Portable Text for rich text, and Sanity Studio customization.\",\n category: \"api-cms\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-cms-payload\",\n purpose: \"CMS\",\n },\n {\n skillId: \"api-cms-strapi\",\n purpose: \"CMS\",\n },\n ],\n path: \"skills/api-cms-sanity\",\n },\n \"api-cms-strapi\": {\n id: \"api-cms-strapi\",\n slug: \"strapi\",\n displayName: \"Strapi\",\n description: \"Open-source headless CMS — content types, REST/GraphQL API\",\n usageGuidance:\n \"Use when building content-managed applications with Strapi — content type schemas, REST API (filters, populate, pagination), Document Service API (find, create, update, delete, publish), custom controllers, services, policies, middlewares, lifecycle hooks, authentication (register, login, JWT), roles and permissions, media upload, and TypeScript support.\",\n category: \"api-cms\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-cms-payload\",\n purpose: \"CMS\",\n },\n {\n skillId: \"api-cms-sanity\",\n purpose: \"CMS\",\n },\n ],\n path: \"skills/api-cms-strapi\",\n },\n \"api-commerce-stripe\": {\n id: \"api-commerce-stripe\",\n slug: \"stripe\",\n displayName: \"Stripe\",\n description: \"Payments — subscriptions, checkout, webhooks, and Connect\",\n usageGuidance:\n \"Use when integrating payments with Stripe — Checkout Sessions, Payment Intents, subscriptions, webhooks, customer management, Connect for platforms, and Stripe Elements.\",\n category: \"api-commerce\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/api-commerce-stripe\",\n },\n \"api-database-cockroachdb\": {\n id: \"api-database-cockroachdb\",\n slug: \"cockroachdb\",\n displayName: \"CockroachDB\",\n description: \"Distributed SQL with PostgreSQL wire protocol\",\n usageGuidance:\n \"Use when working with CockroachDB -- PostgreSQL-compatible wire protocol, distributed transactions with serializable isolation, automatic sharding, multi-region locality, and transaction retry logic.\",\n category: \"api-sql-engine\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-baas-neon\",\n purpose: \"Managed Database\",\n },\n {\n skillId: \"api-baas-planetscale\",\n purpose: \"Managed Database\",\n },\n {\n skillId: \"api-baas-turso\",\n purpose: \"Managed Database\",\n },\n {\n skillId: \"api-database-vercel-postgres\",\n purpose: \"Managed Database\",\n },\n ],\n path: \"skills/api-database-cockroachdb\",\n },\n \"api-database-drizzle\": {\n id: \"api-database-drizzle\",\n slug: \"drizzle\",\n displayName: \"Drizzle\",\n description: \"Drizzle ORM patterns\",\n usageGuidance: \"Use when writing database queries, migrations, or working with Drizzle ORM.\",\n category: \"api-orm\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-database-prisma\",\n purpose: \"SQL ORM / Query Builder\",\n },\n {\n skillId: \"api-database-sequelize\",\n purpose: \"SQL ORM / Query Builder\",\n },\n {\n skillId: \"api-database-typeorm\",\n purpose: \"SQL ORM / Query Builder\",\n },\n {\n skillId: \"api-database-knex\",\n purpose: \"SQL ORM / Query Builder\",\n },\n ],\n path: \"skills/api-database-drizzle\",\n },\n \"api-database-edgedb\": {\n id: \"api-database-edgedb\",\n slug: \"edgedb\",\n displayName: \"Gel (EdgeDB)\",\n description: \"Graph-relational database with EdgeQL and code-first schema\",\n usageGuidance:\n \"Use when working with Gel (formerly EdgeDB) — EdgeQL for type-safe queries, code-first schema with migrations, link-based relations, computed properties, and the query builder for fully typed TypeScript queries.\",\n category: \"api-document\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/api-database-edgedb\",\n },\n \"api-database-knex\": {\n id: \"api-database-knex\",\n slug: \"knex\",\n displayName: \"Knex.js\",\n description: \"SQL query builder for PostgreSQL, MySQL, SQLite, and MSSQL\",\n usageGuidance:\n \"Use when building SQL queries programmatically -- fluent query builder, schema builder, migrations, seeds, transactions, and raw queries with parameter binding.\",\n category: \"api-orm\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-database-drizzle\",\n purpose: \"SQL ORM / Query Builder\",\n },\n {\n skillId: \"api-database-prisma\",\n purpose: \"SQL ORM / Query Builder\",\n },\n {\n skillId: \"api-database-sequelize\",\n purpose: \"SQL ORM / Query Builder\",\n },\n {\n skillId: \"api-database-typeorm\",\n purpose: \"SQL ORM / Query Builder\",\n },\n ],\n path: \"skills/api-database-knex\",\n },\n \"api-database-mongodb\": {\n id: \"api-database-mongodb\",\n slug: \"mongodb\",\n displayName: \"MongoDB\",\n description: \"Native MongoDB driver — the mongodb npm package, no ODM\",\n usageGuidance:\n \"Use when talking to MongoDB through the official `mongodb` driver directly, with no schema layer in between — MongoClient and pool lifecycle, typed collections, CRUD result shapes, cursors and streaming reads, aggregation pipelines, index design and verification with explain, and multi document transactions with sessions.\",\n category: \"api-document\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-database-mongoose\",\n purpose: \"MongoDB\",\n },\n ],\n path: \"skills/api-database-mongodb\",\n },\n \"api-database-mongoose\": {\n id: \"api-database-mongoose\",\n slug: \"mongoose\",\n displayName: \"Mongoose\",\n description: \"MongoDB ODM — schemas, validation, middleware, TypeScript\",\n usageGuidance:\n \"Use when working with MongoDB via Mongoose — schema definitions, model creation, queries, population, middleware hooks, virtuals, and TypeScript integration.\",\n category: \"api-document\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-database-mongodb\",\n purpose: \"MongoDB\",\n },\n ],\n path: \"skills/api-database-mongoose\",\n },\n \"api-database-mysql\": {\n id: \"api-database-mysql\",\n slug: \"mysql\",\n displayName: \"MySQL\",\n description: \"Direct MySQL database access with mysql2 driver\",\n usageGuidance:\n \"Use when interacting directly with MySQL -- connection pools, prepared statements, transactions, streaming, and promise-based API with mysql2.\",\n category: \"api-sql-engine\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-database-postgresql\",\n purpose: \"SQL Database\",\n },\n ],\n path: \"skills/api-database-mysql\",\n },\n \"api-database-postgresql\": {\n id: \"api-database-postgresql\",\n slug: \"postgresql\",\n displayName: \"PostgreSQL\",\n description: \"Direct PostgreSQL database access with node-postgres (pg)\",\n usageGuidance:\n \"Use when interacting directly with PostgreSQL -- connection pools, parameterized queries, transactions, migrations, and type-safe query results with pg.\",\n category: \"api-sql-engine\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-database-mysql\",\n purpose: \"SQL Database\",\n },\n ],\n path: \"skills/api-database-postgresql\",\n },\n \"api-database-prisma\": {\n id: \"api-database-prisma\",\n slug: \"prisma\",\n displayName: \"Prisma\",\n description: \"Prisma ORM patterns\",\n usageGuidance: \"Use when writing database queries, migrations, or working with Prisma ORM.\",\n category: \"api-orm\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-database-drizzle\",\n purpose: \"SQL ORM / Query Builder\",\n },\n {\n skillId: \"api-database-sequelize\",\n purpose: \"SQL ORM / Query Builder\",\n },\n {\n skillId: \"api-database-typeorm\",\n purpose: \"SQL ORM / Query Builder\",\n },\n {\n skillId: \"api-database-knex\",\n purpose: \"SQL ORM / Query Builder\",\n },\n ],\n path: \"skills/api-database-prisma\",\n },\n \"api-database-redis\": {\n id: \"api-database-redis\",\n slug: \"redis\",\n displayName: \"Redis\",\n description: \"Redis in-memory data store with ioredis\",\n usageGuidance:\n \"Use when implementing caching, session storage, rate limiting, pub/sub messaging, queues, or real-time leaderboards with Redis.\",\n category: \"api-kv\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-database-upstash\",\n purpose: \"Cache / KV Store\",\n },\n {\n skillId: \"api-database-vercel-kv\",\n purpose: \"Cache / KV Store\",\n },\n ],\n path: \"skills/api-database-redis\",\n },\n \"api-database-sequelize\": {\n id: \"api-database-sequelize\",\n slug: \"sequelize\",\n displayName: \"Sequelize\",\n description: \"Promise-based SQL ORM with model definitions and migrations\",\n usageGuidance:\n \"Use when working with SQL databases via Sequelize — model definitions, associations, queries, transactions, migrations, hooks, and scopes.\",\n category: \"api-orm\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-database-drizzle\",\n purpose: \"SQL ORM / Query Builder\",\n },\n {\n skillId: \"api-database-prisma\",\n purpose: \"SQL ORM / Query Builder\",\n },\n {\n skillId: \"api-database-typeorm\",\n purpose: \"SQL ORM / Query Builder\",\n },\n {\n skillId: \"api-database-knex\",\n purpose: \"SQL ORM / Query Builder\",\n },\n ],\n path: \"skills/api-database-sequelize\",\n },\n \"api-database-surrealdb\": {\n id: \"api-database-surrealdb\",\n slug: \"surrealdb\",\n displayName: \"SurrealDB\",\n description: \"Multi-model database with graph relations and live queries\",\n usageGuidance:\n \"Use when working with SurrealDB — SurrealQL queries, record links for graph relations, live queries for real-time, schema-full and schema-less modes, and multi-tenancy with namespaces and databases.\",\n category: \"api-document\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/api-database-surrealdb\",\n },\n \"api-database-typeorm\": {\n id: \"api-database-typeorm\",\n slug: \"typeorm\",\n displayName: \"TypeORM\",\n description: \"Decorator-based TypeScript ORM with Data Mapper patterns\",\n usageGuidance:\n \"Use when building TypeScript applications with relational databases — entity decorators, repository pattern, migrations, relations, query builder, and transaction management.\",\n category: \"api-orm\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-database-drizzle\",\n purpose: \"SQL ORM / Query Builder\",\n },\n {\n skillId: \"api-database-prisma\",\n purpose: \"SQL ORM / Query Builder\",\n },\n {\n skillId: \"api-database-sequelize\",\n purpose: \"SQL ORM / Query Builder\",\n },\n {\n skillId: \"api-database-knex\",\n purpose: \"SQL ORM / Query Builder\",\n },\n ],\n path: \"skills/api-database-typeorm\",\n },\n \"api-database-upstash\": {\n id: \"api-database-upstash\",\n slug: \"upstash\",\n displayName: \"Upstash\",\n description: \"Serverless Redis via REST for edge and serverless runtimes\",\n usageGuidance:\n \"Use when deploying Redis on Upstash -- REST-based Redis for edge/serverless compatibility, automatic JSON serialization, pipeline support, rate limiting with @upstash/ratelimit, and global replication.\",\n category: \"api-kv\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-database-redis\",\n purpose: \"Cache / KV Store\",\n },\n {\n skillId: \"api-database-vercel-kv\",\n purpose: \"Cache / KV Store\",\n },\n ],\n path: \"skills/api-database-upstash\",\n },\n \"api-database-vercel-kv\": {\n id: \"api-database-vercel-kv\",\n slug: \"vercel-kv\",\n displayName: \"Vercel KV\",\n description: \"Serverless Redis-compatible key-value store on Vercel\",\n usageGuidance:\n \"Use when deploying Redis-compatible KV storage on Vercel -- automatic connection via UPSTASH_REDIS_REST_URL env vars, edge-compatible REST API, Redis command compatibility, and TTL-based caching.\",\n category: \"api-kv\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-database-redis\",\n purpose: \"Cache / KV Store\",\n },\n {\n skillId: \"api-database-upstash\",\n purpose: \"Cache / KV Store\",\n },\n ],\n path: \"skills/api-database-vercel-kv\",\n },\n \"api-database-vercel-postgres\": {\n id: \"api-database-vercel-postgres\",\n slug: \"vercel-postgres\",\n displayName: \"Vercel Postgres\",\n description: \"Serverless PostgreSQL on Vercel with edge-compatible SDK\",\n usageGuidance:\n \"Use when deploying PostgreSQL on Vercel -- sql tagged template for edge functions, createPool/createClient for Node.js, automatic connection management via POSTGRES_URL env vars. NOTE: @vercel/postgres is deprecated (Dec 2024). For new projects, use @neondatabase/serverless instead.\",\n category: \"api-db-host\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-baas-neon\",\n purpose: \"Managed Database\",\n },\n {\n skillId: \"api-baas-planetscale\",\n purpose: \"Managed Database\",\n },\n {\n skillId: \"api-baas-turso\",\n purpose: \"Managed Database\",\n },\n {\n skillId: \"api-database-cockroachdb\",\n purpose: \"Managed Database\",\n },\n ],\n path: \"skills/api-database-vercel-postgres\",\n },\n \"api-email-resend-react-email\": {\n id: \"api-email-resend-react-email\",\n slug: \"resend-react-email\",\n displayName: \"Resend\",\n description: \"Transactional email templates\",\n usageGuidance: \"Use when sending transactional emails or building React Email templates.\",\n category: \"api-email\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason: \"React Email uses React for email templates\",\n },\n ],\n alternatives: [],\n path: \"skills/api-email-resend-react-email\",\n },\n \"api-email-setup-resend\": {\n id: \"api-email-setup-resend\",\n slug: \"setup-resend\",\n displayName: \"Email Setup\",\n description: \"Email service setup\",\n usageGuidance: \"Use when configuring Resend email service or domain verification.\",\n category: \"api-email\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason:\n \"Resend Email & React Email Setup — .tsx templates and the react: send prop are React Email surface\",\n },\n ],\n alternatives: [],\n path: \"skills/api-email-setup-resend\",\n },\n \"api-flags-posthog-flags\": {\n id: \"api-flags-posthog-flags\",\n slug: \"posthog-flags\",\n displayName: \"PostHog Flags\",\n description: \"Feature flags and A/B testing\",\n usageGuidance:\n \"Use when implementing feature flags, gradual rollouts, A/B tests, or remote configuration.\",\n category: \"api-analytics\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/api-flags-posthog-flags\",\n },\n \"api-framework-elysia\": {\n id: \"api-framework-elysia\",\n slug: \"elysia\",\n displayName: \"Elysia\",\n description: \"Bun-native HTTP framework with end-to-end type safety\",\n usageGuidance:\n \"Use when building APIs on Bun runtime — end-to-end type safety via Eden Treaty, plugin-based architecture, schema validation with TypeBox, lifecycle hooks, and high-performance routing.\",\n category: \"api-api\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"api-framework-hono\",\n reason: \"API frameworks are mutually exclusive within a single service\",\n },\n {\n skillId: \"api-framework-express\",\n reason: \"API frameworks are mutually exclusive within a single service\",\n },\n {\n skillId: \"api-framework-fastify\",\n reason: \"API frameworks are mutually exclusive within a single service\",\n },\n {\n skillId: \"api-framework-nestjs\",\n reason: \"API frameworks are mutually exclusive within a single service\",\n },\n ],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-framework-hono\",\n purpose: \"API Framework\",\n },\n {\n skillId: \"api-framework-express\",\n purpose: \"API Framework\",\n },\n {\n skillId: \"api-framework-fastify\",\n purpose: \"API Framework\",\n },\n {\n skillId: \"api-framework-nestjs\",\n purpose: \"API Framework\",\n },\n ],\n path: \"skills/api-framework-elysia\",\n },\n \"api-framework-express\": {\n id: \"api-framework-express\",\n slug: \"express\",\n displayName: \"Express\",\n description: \"Express API framework\",\n usageGuidance: \"Use when building Express.js APIs, middleware chains, or error handling.\",\n category: \"api-api\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"api-framework-hono\",\n reason: \"API frameworks are mutually exclusive within a single service\",\n },\n {\n skillId: \"api-framework-fastify\",\n reason: \"API frameworks are mutually exclusive within a single service\",\n },\n {\n skillId: \"api-framework-elysia\",\n reason: \"API frameworks are mutually exclusive within a single service\",\n },\n {\n skillId: \"api-framework-nestjs\",\n reason: \"API frameworks are mutually exclusive within a single service\",\n },\n ],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-framework-hono\",\n purpose: \"API Framework\",\n },\n {\n skillId: \"api-framework-fastify\",\n purpose: \"API Framework\",\n },\n {\n skillId: \"api-framework-elysia\",\n purpose: \"API Framework\",\n },\n {\n skillId: \"api-framework-nestjs\",\n purpose: \"API Framework\",\n },\n ],\n path: \"skills/api-framework-express\",\n },\n \"api-framework-fastify\": {\n id: \"api-framework-fastify\",\n slug: \"fastify\",\n displayName: \"Fastify\",\n description: \"Fastify API framework\",\n usageGuidance:\n \"Use when building Fastify APIs, using JSON Schema validation, or plugin architecture.\",\n category: \"api-api\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"api-framework-hono\",\n reason: \"API frameworks are mutually exclusive within a single service\",\n },\n {\n skillId: \"api-framework-express\",\n reason: \"API frameworks are mutually exclusive within a single service\",\n },\n {\n skillId: \"api-framework-elysia\",\n reason: \"API frameworks are mutually exclusive within a single service\",\n },\n {\n skillId: \"api-framework-nestjs\",\n reason: \"API frameworks are mutually exclusive within a single service\",\n },\n ],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-framework-hono\",\n purpose: \"API Framework\",\n },\n {\n skillId: \"api-framework-express\",\n purpose: \"API Framework\",\n },\n {\n skillId: \"api-framework-elysia\",\n purpose: \"API Framework\",\n },\n {\n skillId: \"api-framework-nestjs\",\n purpose: \"API Framework\",\n },\n ],\n path: \"skills/api-framework-fastify\",\n },\n \"api-framework-hono\": {\n id: \"api-framework-hono\",\n slug: \"hono\",\n displayName: \"Hono\",\n description: \"Hono API framework\",\n usageGuidance:\n \"Use when building API routes with Hono, implementing OpenAPI specs, or Zod validation.\",\n category: \"api-api\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"api-framework-express\",\n reason: \"API frameworks are mutually exclusive within a single service\",\n },\n {\n skillId: \"api-framework-fastify\",\n reason: \"API frameworks are mutually exclusive within a single service\",\n },\n {\n skillId: \"api-framework-elysia\",\n reason: \"API frameworks are mutually exclusive within a single service\",\n },\n {\n skillId: \"api-framework-nestjs\",\n reason: \"API frameworks are mutually exclusive within a single service\",\n },\n ],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-framework-express\",\n purpose: \"API Framework\",\n },\n {\n skillId: \"api-framework-fastify\",\n purpose: \"API Framework\",\n },\n {\n skillId: \"api-framework-elysia\",\n purpose: \"API Framework\",\n },\n {\n skillId: \"api-framework-nestjs\",\n purpose: \"API Framework\",\n },\n ],\n path: \"skills/api-framework-hono\",\n },\n \"api-framework-nestjs\": {\n id: \"api-framework-nestjs\",\n slug: \"nestjs\",\n displayName: \"NestJS\",\n description: \"NestJS structured backend framework\",\n usageGuidance:\n \"Use when building NestJS apps with modules, controllers, services, or decorators.\",\n category: \"api-api\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"api-framework-hono\",\n reason: \"API frameworks are mutually exclusive within a single service\",\n },\n {\n skillId: \"api-framework-express\",\n reason: \"API frameworks are mutually exclusive within a single service\",\n },\n {\n skillId: \"api-framework-fastify\",\n reason: \"API frameworks are mutually exclusive within a single service\",\n },\n {\n skillId: \"api-framework-elysia\",\n reason: \"API frameworks are mutually exclusive within a single service\",\n },\n ],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-framework-hono\",\n purpose: \"API Framework\",\n },\n {\n skillId: \"api-framework-express\",\n purpose: \"API Framework\",\n },\n {\n skillId: \"api-framework-fastify\",\n purpose: \"API Framework\",\n },\n {\n skillId: \"api-framework-elysia\",\n purpose: \"API Framework\",\n },\n ],\n path: \"skills/api-framework-nestjs\",\n },\n \"api-graphql-apollo-server\": {\n id: \"api-graphql-apollo-server\",\n slug: \"apollo-server\",\n displayName: \"Apollo Server\",\n description: \"GraphQL API server with Apollo Server\",\n usageGuidance:\n \"Use when building GraphQL APIs with Apollo Server — schema definition, resolvers, context, data sources, error handling, subscriptions, caching, and federation patterns.\",\n category: \"api-graphql\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/api-graphql-apollo-server\",\n },\n \"api-graphql-mercurius\": {\n id: \"api-graphql-mercurius\",\n slug: \"mercurius\",\n displayName: \"Mercurius\",\n description: \"GraphQL server for Fastify with Mercurius\",\n usageGuidance:\n \"Use when building GraphQL APIs on Fastify with Mercurius — schema definition, resolvers, loaders (DataLoader-like batching), subscriptions, federation, gateway, and Fastify plugin integration.\",\n category: \"api-graphql\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"api-framework-fastify\"],\n needsAny: false,\n reason:\n \"Mercurius is a Fastify plugin — registered via app.register on a Fastify instance\",\n },\n ],\n alternatives: [],\n path: \"skills/api-graphql-mercurius\",\n },\n \"api-graphql-yoga\": {\n id: \"api-graphql-yoga\",\n slug: \"yoga\",\n displayName: \"GraphQL Yoga\",\n description: \"GraphQL server with Yoga v5 and the Envelop plugin system\",\n usageGuidance:\n \"Use when building GraphQL APIs with GraphQL Yoga — schema definition, resolvers, Envelop plugins, subscriptions (SSE/WebSocket), file uploads, error handling, and server framework integration.\",\n category: \"api-graphql\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/api-graphql-yoga\",\n },\n \"api-messaging-webhooks\": {\n id: \"api-messaging-webhooks\",\n slug: \"webhooks\",\n displayName: \"Webhooks\",\n description: \"Receiving, sending, signature verification, and retry logic\",\n usageGuidance:\n \"Use when implementing webhook endpoints or sending webhooks — signature verification (HMAC), idempotency, retry logic with exponential backoff, payload validation, event routing, and dead letter queues.\",\n category: \"api-messaging\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/api-messaging-webhooks\",\n },\n \"api-observability-axiom-pino-sentry\": {\n id: \"api-observability-axiom-pino-sentry\",\n slug: \"axiom-pino-sentry\",\n displayName: \"Observability\",\n description: \"Logging and error tracking\",\n usageGuidance:\n \"Use when implementing structured logging, error tracking, or performance monitoring.\",\n category: \"api-observability\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/api-observability-axiom-pino-sentry\",\n },\n \"api-observability-setup-axiom-pino-sentry\": {\n id: \"api-observability-setup-axiom-pino-sentry\",\n slug: \"setup-axiom-pino-sentry\",\n displayName: \"Observability Setup\",\n description: \"Logging and monitoring setup\",\n usageGuidance: \"Use when setting up Pino logging, Axiom, or Sentry for the first time.\",\n category: \"api-observability\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"web-meta-framework-nextjs\"],\n needsAny: false,\n reason:\n \"Every pattern is the Next.js wiring — next-axiom, @sentry/nextjs, next.config.ts wrapping, instrumentation.ts; strip the Next slice and nothing followable remains\",\n },\n ],\n alternatives: [],\n path: \"skills/api-observability-setup-axiom-pino-sentry\",\n },\n \"api-performance-api-performance\": {\n id: \"api-performance-api-performance\",\n slug: \"api-performance\",\n displayName: \"Backend Performance\",\n description: \"Query and caching optimization\",\n usageGuidance:\n \"Use when optimizing database queries, implementing caching, or improving API response times.\",\n category: \"api-performance\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/api-performance-api-performance\",\n },\n \"api-queue-bullmq\": {\n id: \"api-queue-bullmq\",\n slug: \"bullmq\",\n displayName: \"BullMQ\",\n description: \"Job queues and background processing with BullMQ\",\n usageGuidance:\n \"Use when implementing job queues, background processing, or task scheduling with BullMQ -- queue creation, workers, job scheduling, rate limiting, concurrency, flows, events, and Redis connection patterns.\",\n category: \"api-queue\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"api-database-redis\", \"api-database-upstash\"],\n needsAny: true,\n reason:\n \"BullMQ drives a Redis-compatible server over ioredis/TCP (blocking commands, Lua scripts, streams); Upstash documents BullMQ over its TCP endpoint — its REST client cannot drive BullMQ, and the skill carries its own ioredis connection factory\",\n },\n ],\n alternatives: [],\n path: \"skills/api-queue-bullmq\",\n },\n \"api-search-elasticsearch\": {\n id: \"api-search-elasticsearch\",\n slug: \"elasticsearch\",\n displayName: \"Elasticsearch\",\n description: \"Distributed search — full-text, aggregations, vector search\",\n usageGuidance:\n \"Use when building search with Elasticsearch -- full-text search, structured queries, aggregations, vector/semantic search, index management, and bulk operations.\",\n category: \"api-search\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-search-meilisearch\",\n purpose: \"Search Engine\",\n },\n ],\n path: \"skills/api-search-elasticsearch\",\n },\n \"api-search-meilisearch\": {\n id: \"api-search-meilisearch\",\n slug: \"meilisearch\",\n displayName: \"Meilisearch\",\n description: \"Fast, typo-tolerant search with instant results and facets\",\n usageGuidance:\n \"Use when adding search to applications with Meilisearch -- instant typo-tolerant search, faceted filtering, geo search, multi-index search, and real-time document indexing.\",\n category: \"api-search\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-search-elasticsearch\",\n purpose: \"Search Engine\",\n },\n ],\n path: \"skills/api-search-meilisearch\",\n },\n \"api-search-xquik\": {\n id: \"api-search-xquik\",\n slug: \"xquik\",\n displayName: \"Xquik\",\n description: \"X data and automation API\",\n usageGuidance:\n \"Use when integrating Xquik REST endpoints for X post search, user lookup, timelines, media download, monitors, signed webhooks, or approval-gated X actions.\",\n category: \"api-search\",\n author: \"@kriptoburak\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/api-search-xquik\",\n },\n \"api-specs-openapi\": {\n id: \"api-specs-openapi\",\n slug: \"openapi\",\n displayName: \"OpenAPI\",\n description: \"OpenAPI schema design and client/server code generation\",\n usageGuidance:\n \"Use when designing API contracts with OpenAPI (Swagger) — spec authoring (YAML/JSON), schema definitions, path operations, request/response types, code generation (client/server), validation, and documentation generation.\",\n category: \"api-specs\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/api-specs-openapi\",\n },\n \"api-vector-db-chroma\": {\n id: \"api-vector-db-chroma\",\n slug: \"chroma\",\n displayName: \"Chroma\",\n description: \"Lightweight embedding database with automatic vectorization\",\n usageGuidance:\n \"Use when building semantic search or RAG with Chroma -- collection management, automatic embedding generation, metadata filtering, document storage, and multi-modal embeddings.\",\n category: \"api-vector-db\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-vector-db-pinecone\",\n purpose: \"Vector Database\",\n },\n {\n skillId: \"api-vector-db-qdrant\",\n purpose: \"Vector Database\",\n },\n {\n skillId: \"api-vector-db-weaviate\",\n purpose: \"Vector Database\",\n },\n ],\n path: \"skills/api-vector-db-chroma\",\n },\n \"api-vector-db-pinecone\": {\n id: \"api-vector-db-pinecone\",\n slug: \"pinecone\",\n displayName: \"Pinecone\",\n description: \"Serverless vector database for similarity search and RAG\",\n usageGuidance:\n \"Use when building semantic search or RAG with Pinecone -- index management, vector upsert/query, metadata filtering, namespaces, sparse-dense hybrid search, and serverless scaling.\",\n category: \"api-vector-db\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-vector-db-qdrant\",\n purpose: \"Vector Database\",\n },\n {\n skillId: \"api-vector-db-chroma\",\n purpose: \"Vector Database\",\n },\n {\n skillId: \"api-vector-db-weaviate\",\n purpose: \"Vector Database\",\n },\n ],\n path: \"skills/api-vector-db-pinecone\",\n },\n \"api-vector-db-qdrant\": {\n id: \"api-vector-db-qdrant\",\n slug: \"qdrant\",\n displayName: \"Qdrant\",\n description: \"Fast vector DB — filtering, payload indexing, quantization\",\n usageGuidance:\n \"Use when building semantic search or RAG with Qdrant -- collection management, vector upsert/search, payload filtering, named vectors, quantization, and recommendation API.\",\n category: \"api-vector-db\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-vector-db-pinecone\",\n purpose: \"Vector Database\",\n },\n {\n skillId: \"api-vector-db-chroma\",\n purpose: \"Vector Database\",\n },\n {\n skillId: \"api-vector-db-weaviate\",\n purpose: \"Vector Database\",\n },\n ],\n path: \"skills/api-vector-db-qdrant\",\n },\n \"api-vector-db-weaviate\": {\n id: \"api-vector-db-weaviate\",\n slug: \"weaviate\",\n displayName: \"Weaviate\",\n description: \"Vector database — built-in vectorization and hybrid search\",\n usageGuidance:\n \"Use when building semantic search or RAG with Weaviate — collection management, built-in vectorization modules, hybrid search (vector + keyword), filtering, multi-tenancy, and generative search.\",\n category: \"api-vector-db\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"api-vector-db-pinecone\",\n purpose: \"Vector Database\",\n },\n {\n skillId: \"api-vector-db-qdrant\",\n purpose: \"Vector Database\",\n },\n {\n skillId: \"api-vector-db-chroma\",\n purpose: \"Vector Database\",\n },\n ],\n path: \"skills/api-vector-db-weaviate\",\n },\n \"cli-framework-cli-commander\": {\n id: \"cli-framework-cli-commander\",\n slug: \"cli-commander\",\n displayName: \"CLI Commander\",\n description: \"CLI dev with Commander.js, clack, picocolors\",\n usageGuidance:\n \"Use when building CLI applications, interactive prompts, wizard flows, or command-line tools with Node.js.\",\n category: \"cli-framework\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"cli-framework-oclif-ink\",\n reason: \"CLI frameworks are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"cli-framework-oclif-ink\",\n purpose: \"CLI Framework\",\n },\n ],\n path: \"skills/cli-framework-cli-commander\",\n },\n \"cli-framework-oclif-ink\": {\n id: \"cli-framework-oclif-ink\",\n slug: \"oclif-ink\",\n displayName: \"oclif + Ink\",\n description: \"CLI dev with oclif framework and Ink React\",\n usageGuidance:\n \"Use when building command-line interfaces with oclif framework, React-based terminal UIs with Ink, or integrating both for interactive CLI applications. Triggers: oclif, Ink, @oclif/core, @inkjs/ui, terminal React, CLI commands, useInput, useApp, render(), Command class, Flags, Args.\",\n category: \"cli-framework\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"cli-framework-cli-commander\",\n reason: \"CLI frameworks are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"cli-framework-cli-commander\",\n purpose: \"CLI Framework\",\n },\n ],\n path: \"skills/cli-framework-oclif-ink\",\n },\n \"cli-prompts-clack\": {\n id: \"cli-prompts-clack\",\n slug: \"clack\",\n displayName: \"Clack\",\n description: \"Beautiful interactive CLI prompts with @clack/prompts\",\n usageGuidance:\n \"Use when building interactive CLI experiences with @clack/prompts — text input, select, multiselect, confirm, spinner, group prompts, cancellation handling, and themed output. Triggers: @clack/prompts, @clack/core, clack, isCancel, intro, outro, spinner, group, text prompt, select prompt, confirm prompt, multiselect, note, log, tasks, progress bar, taskLog.\",\n category: \"cli-prompts\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/cli-prompts-clack\",\n },\n \"desktop-backend-tauri\": {\n id: \"desktop-backend-tauri\",\n slug: \"tauri-backend\",\n displayName: \"Tauri Rust Backend\",\n description: \"Rust command patterns, state, error handling\",\n usageGuidance:\n \"Use when writing Tauri Rust backend code: defining #[tauri::command] handlers (sync and async), managing state with app.manage() and State<T>, implementing error types with thiserror + serde::Serialize, emitting events from Rust, streaming data via Channel<T>, or testing Rust commands with the mock runtime.\",\n category: \"desktop-backend\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"desktop-framework-tauri\"],\n needsAny: false,\n reason: \"tauri::command and State are the tauri crate\",\n },\n ],\n alternatives: [],\n path: \"skills/desktop-backend-tauri\",\n },\n \"desktop-framework-electron\": {\n id: \"desktop-framework-electron\",\n slug: \"electron\",\n displayName: \"Electron\",\n description: \"Cross-platform desktop apps with web technologies\",\n usageGuidance:\n \"Use when building desktop applications with Electron, configuring main/renderer process architecture, IPC communication, preload scripts, security hardening, native API integration, or packaging for distribution.\",\n category: \"desktop-framework\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"desktop-framework-tauri\",\n reason: \"Desktop frameworks are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"desktop-framework-tauri\",\n purpose: \"Desktop Framework\",\n },\n ],\n path: \"skills/desktop-framework-electron\",\n },\n \"desktop-framework-tauri\": {\n id: \"desktop-framework-tauri\",\n slug: \"tauri\",\n displayName: \"Tauri\",\n description: \"Desktop and mobile apps with system webview and Rust backend\",\n usageGuidance:\n \"Use when building desktop or mobile applications with Tauri 2.x, defining Rust commands and IPC bridge, configuring the permission/capability system, using official plugins, system tray, window management, or packaging for distribution.\",\n category: \"desktop-framework\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"desktop-framework-electron\",\n reason: \"Desktop frameworks are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"desktop-framework-electron\",\n purpose: \"Desktop Framework\",\n },\n ],\n path: \"skills/desktop-framework-tauri\",\n },\n \"desktop-ipc-electron\": {\n id: \"desktop-ipc-electron\",\n slug: \"electron-ipc\",\n displayName: \"Electron Type-Safe IPC\",\n description: \"Type-safe Electron IPC patterns\",\n usageGuidance:\n \"Use when implementing type-safe IPC between Electron main and renderer processes, setting up electron-trpc for end-to-end type safety, creating typed channel maps with shared payload types, building typed preload APIs with contextBridge, using MessagePort for high-throughput communication, or implementing utility process IPC.\",\n category: \"desktop-ipc\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"desktop-framework-electron\"],\n needsAny: false,\n reason: \"contextBridge/ipcMain are Electron core APIs\",\n },\n ],\n alternatives: [],\n path: \"skills/desktop-ipc-electron\",\n },\n \"desktop-mobile-tauri\": {\n id: \"desktop-mobile-tauri\",\n slug: \"tauri-mobile\",\n displayName: \"Tauri Mobile\",\n description: \"Mobile app development with Tauri 2.x\",\n usageGuidance:\n \"Use when building iOS or Android mobile apps with Tauri 2.x, initializing mobile targets, using mobile-specific plugins (biometric, barcode-scanner, NFC, haptics, geolocation), writing platform-specific Swift/Kotlin plugin code, configuring mobile permissions (AndroidManifest.xml, Info.plist), or debugging on mobile devices and emulators.\",\n category: \"desktop-mobile\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"desktop-framework-tauri\"],\n needsAny: false,\n reason: \"Tauri mobile targets are the same Tauri project\",\n },\n ],\n alternatives: [],\n path: \"skills/desktop-mobile-tauri\",\n },\n \"desktop-multiwindow-electron\": {\n id: \"desktop-multiwindow-electron\",\n slug: \"electron-multiwindow\",\n displayName: \"Electron Multi-Window\",\n description: \"Multi-window, WebContentsView, window lifecycle\",\n usageGuidance:\n \"Use when managing multiple windows or embedded views in Electron: BaseWindow with WebContentsView for tabs/panels/split views, parent/child and modal windows, window registries, inter-window communication via MessagePort, window state persistence, or multi-monitor placement with the screen API.\",\n category: \"desktop-multiwindow\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"desktop-framework-electron\"],\n needsAny: false,\n reason: \"BaseWindow and WebContentsView are Electron core APIs\",\n },\n ],\n alternatives: [],\n path: \"skills/desktop-multiwindow-electron\",\n },\n \"desktop-multiwindow-tauri\": {\n id: \"desktop-multiwindow-tauri\",\n slug: \"tauri-multiwindow\",\n displayName: \"Tauri Multi-Window & Events\",\n description: \"Multi-window management and event system\",\n usageGuidance:\n \"Use when creating or managing multiple windows in a Tauri 2.x app, communicating between windows via events (emit, emitTo, emit_filter), handling close confirmation, persisting window state, or setting up parent/child and modal window relationships.\",\n category: \"desktop-multiwindow\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"desktop-framework-tauri\"],\n needsAny: false,\n reason: \"Tauri 2 event system and WebviewWindow APIs\",\n },\n ],\n alternatives: [],\n path: \"skills/desktop-multiwindow-tauri\",\n },\n \"desktop-packaging-electron-forge\": {\n id: \"desktop-packaging-electron-forge\",\n slug: \"electron-forge\",\n displayName: \"Electron Forge\",\n description: \"Electron build toolchain, makers, publishers, signing\",\n usageGuidance:\n \"Use when configuring Electron Forge (forge.config.ts), setting up makers for platform-specific installers, configuring publishers for release distribution, code signing and notarization, Electron Fuses, build hooks, or choosing between Forge and electron-builder.\",\n category: \"desktop-packaging\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"desktop-framework-electron\"],\n needsAny: false,\n reason: \"Electron Forge packages Electron apps\",\n },\n ],\n alternatives: [],\n path: \"skills/desktop-packaging-electron-forge\",\n },\n \"desktop-packaging-tauri\": {\n id: \"desktop-packaging-tauri\",\n slug: \"tauri-bundling\",\n displayName: \"Tauri Bundling & Distribution\",\n description: \"Bundle config, signing, updater, CI/CD\",\n usageGuidance:\n \"Use when configuring tauri.conf.json bundle settings, building platform-specific installers (NSIS/MSI, DMG, deb/rpm/AppImage), setting up code signing or notarization, configuring the auto-updater with signature verification, optimizing app size, adding sidecar binaries, or creating CI/CD pipelines for cross-platform Tauri builds.\",\n category: \"desktop-packaging\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"desktop-framework-tauri\"],\n needsAny: false,\n reason: \"Tauri bundler, signer, and updater configuration\",\n },\n ],\n alternatives: [],\n path: \"skills/desktop-packaging-tauri\",\n },\n \"desktop-plugins-tauri\": {\n id: \"desktop-plugins-tauri\",\n slug: \"tauri-plugins\",\n displayName: \"Tauri Plugins\",\n description: \"Official plugin ecosystem and custom plugin development\",\n usageGuidance:\n \"Use when installing, configuring, or using official Tauri 2.x plugins (fs, http, store, dialog, notification, shell, updater, log, sql, stronghold, deep-link, global-shortcut, autostart, clipboard, window-state, barcode-scanner, biometric, single-instance, os, process), or when developing custom plugins with the Rust Builder pattern and optional mobile (Swift/Kotlin) support.\",\n category: \"desktop-plugins\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"desktop-framework-tauri\"],\n needsAny: false,\n reason: \"tauri-plugin-* crates and the Tauri 2 ACL model\",\n },\n ],\n alternatives: [],\n path: \"skills/desktop-plugins-tauri\",\n },\n \"desktop-security-electron\": {\n id: \"desktop-security-electron\",\n slug: \"electron-security\",\n displayName: \"Electron Security & Fuses\",\n description: \"Electron fuses, ASAR integrity, sandbox hardening\",\n usageGuidance:\n \"Use when hardening an Electron app's security posture: flipping fuses with @electron/fuses, configuring ASAR integrity validation, enforcing sandbox and contextIsolation defaults, setting Content Security Policy, restricting permissions, or validating deep link URLs.\",\n category: \"desktop-security\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"desktop-framework-electron\"],\n needsAny: false,\n reason: \"Fuses, ASAR integrity, and sandbox are Electron mechanisms\",\n },\n ],\n alternatives: [],\n path: \"skills/desktop-security-electron\",\n },\n \"desktop-security-tauri\": {\n id: \"desktop-security-tauri\",\n slug: \"tauri-security\",\n displayName: \"Tauri Capabilities & ACL\",\n description: \"Deny-by-default security, capabilities, permissions, scopes\",\n usageGuidance:\n \"Use when configuring Tauri 2.x capabilities, permissions, or scopes. Covers capability file structure, window-specific permissions, allow/deny scopes, custom permission definitions, permission sets, remote domain access, debugging permission errors, and migrating from the Tauri 1.x allowlist. Not for Tauri commands, IPC, plugins, or window management (use desktop-framework-tauri).\",\n category: \"desktop-security\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"desktop-framework-tauri\"],\n needsAny: false,\n reason: \"Capabilities and permissions are the Tauri 2 security model\",\n },\n ],\n alternatives: [],\n path: \"skills/desktop-security-tauri\",\n },\n \"desktop-storage-electron\": {\n id: \"desktop-storage-electron\",\n slug: \"electron-storage\",\n displayName: \"Electron Storage & Credentials\",\n description: \"Persistent storage and credential management\",\n usageGuidance:\n \"Use when persisting user preferences with electron-store, storing structured data with better-sqlite3, encrypting secrets with safeStorage, choosing between storage solutions, or working with app.getPath() storage directories.\",\n category: \"desktop-storage\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"desktop-framework-electron\"],\n needsAny: false,\n reason: \"electron-store and safeStorage are Electron-scoped\",\n },\n ],\n alternatives: [],\n path: \"skills/desktop-storage-electron\",\n },\n \"desktop-testing-electron\": {\n id: \"desktop-testing-electron\",\n slug: \"electron-testing\",\n displayName: \"Electron Testing\",\n description: \"E2E, unit, and IPC testing for Electron\",\n usageGuidance:\n \"Use when writing E2E tests with Playwright for Electron apps (_electron.launch), unit testing main process code, testing IPC handlers, mocking Electron modules (dialog, BrowserWindow, ipcMain/ipcRenderer), testing preload scripts, running Electron tests in CI (xvfb), or migrating from Spectron.\",\n category: \"desktop-testing\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"desktop-framework-electron\"],\n needsAny: false,\n reason: \"Playwright's _electron driver automates Electron apps\",\n },\n ],\n alternatives: [],\n path: \"skills/desktop-testing-electron\",\n },\n \"desktop-ui-electron\": {\n id: \"desktop-ui-electron\",\n slug: \"electron-ui\",\n displayName: \"Electron Desktop UI\",\n description: \"Frameless windows, custom title bars, tray, menus\",\n usageGuidance:\n \"Use when customizing Electron window appearance (frameless, transparent, vibrancy), building custom title bars with drag regions, positioning macOS traffic lights, creating system tray icons, application/context menus, dock badges, splash screens, kiosk mode, or persisting window state.\",\n category: \"desktop-ui\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"desktop-framework-electron\"],\n needsAny: false,\n reason: \"Tray, Menu, and frameless windows are Electron core APIs\",\n },\n ],\n alternatives: [],\n path: \"skills/desktop-ui-electron\",\n },\n \"desktop-updates-electron-updater\": {\n id: \"desktop-updates-electron-updater\",\n slug: \"electron-updater\",\n displayName: \"Electron Auto-Updates\",\n description: \"Cross-platform auto-update with electron-updater\",\n usageGuidance:\n \"Use when implementing auto-updates in Electron apps using electron-updater from the electron-builder ecosystem. Covers update providers (GitHub, S3, generic server), update channels (stable/beta/alpha), staged rollouts, differential downloads, manual update control, error handling, and local testing.\",\n category: \"desktop-updates\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"desktop-framework-electron\"],\n needsAny: false,\n reason: \"electron-updater updates packaged Electron apps\",\n },\n ],\n alternatives: [],\n path: \"skills/desktop-updates-electron-updater\",\n },\n \"infra-ci-cd-docker\": {\n id: \"infra-ci-cd-docker\",\n slug: \"docker\",\n displayName: \"Docker\",\n description: \"Docker containerization for development and deployment\",\n usageGuidance:\n \"Use when creating Dockerfiles, docker-compose configs, multi-stage builds, or containerized development environments for Node.js/TypeScript applications.\",\n category: \"infra-containers\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/infra-ci-cd-docker\",\n },\n \"infra-ci-cd-github-actions\": {\n id: \"infra-ci-cd-github-actions\",\n slug: \"github-actions\",\n displayName: \"GitHub Actions\",\n description: \"CI/CD pipelines\",\n usageGuidance:\n \"Use when configuring CI/CD pipelines, GitHub workflows, or deployment automation.\",\n category: \"infra-ci-cd\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/infra-ci-cd-github-actions\",\n },\n \"infra-ci-cd-turborepo-ci\": {\n id: \"infra-ci-cd-turborepo-ci\",\n slug: \"turborepo-ci\",\n displayName: \"Turborepo CI\",\n description: \"CI pipelines with remote caching and affected detection\",\n usageGuidance:\n \"Use when configuring CI/CD for Turborepo monorepos — remote caching, affected detection, task pipelines, parallel execution, and CI provider integration.\",\n category: \"infra-ci-cd\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"shared-monorepo-turborepo\"],\n needsAny: false,\n reason:\n \"Turborepo CI patterns configure turbo.json and the turbo CLI — requires the Turborepo task runner (shared-task-runner)\",\n },\n ],\n alternatives: [],\n path: \"skills/infra-ci-cd-turborepo-ci\",\n },\n \"infra-config-setup-env\": {\n id: \"infra-config-setup-env\",\n slug: \"setup-env\",\n displayName: \"Environment\",\n description: \"Environment variable management\",\n usageGuidance:\n \"Use when setting up environment variables, .env files, or Zod validation for config.\",\n category: \"infra-config\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/infra-config-setup-env\",\n },\n \"infra-containers-kubernetes\": {\n id: \"infra-containers-kubernetes\",\n slug: \"kubernetes\",\n displayName: \"Kubernetes\",\n description: \"Kubernetes manifests, Helm charts, and resource patterns\",\n usageGuidance:\n \"Use when writing Kubernetes manifests, Helm charts, or Kustomize overlays — deployments, services, ingress, configmaps, secrets, RBAC, health checks, resource limits, and scaling patterns.\",\n category: \"infra-containers\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/infra-containers-kubernetes\",\n },\n \"infra-iac-pulumi\": {\n id: \"infra-iac-pulumi\",\n slug: \"pulumi\",\n displayName: \"Pulumi\",\n description: \"TypeScript-native Infrastructure as Code with Pulumi\",\n usageGuidance:\n \"Use when writing Pulumi programs in TypeScript — resource definitions, component resources, stack references, config/secrets, providers, automation API, and deployment workflows.\",\n category: \"infra-iac\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/infra-iac-pulumi\",\n },\n \"infra-iac-sst\": {\n id: \"infra-iac-sst\",\n slug: \"sst\",\n displayName: \"SST\",\n description: \"Serverless Stack (SST) for full-stack TypeScript on AWS\",\n usageGuidance:\n \"Use when building with SST (Ion) — constructs for Lambda, API Gateway, S3, DynamoDB, Aurora, queues, cron jobs, Next.js/Remix/Astro deployments, and live Lambda dev mode.\",\n category: \"infra-iac\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/infra-iac-sst\",\n },\n \"infra-iac-terraform\": {\n id: \"infra-iac-terraform\",\n slug: \"terraform\",\n displayName: \"Terraform\",\n description: \"Infrastructure as Code with HashiCorp Terraform\",\n usageGuidance:\n \"Use when writing Terraform/OpenTofu configurations — HCL syntax, resource definitions, modules, state management, providers, workspaces, and plan/apply workflows.\",\n category: \"infra-iac\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/infra-iac-terraform\",\n },\n \"infra-platform-aws-sdk\": {\n id: \"infra-platform-aws-sdk\",\n slug: \"aws-sdk\",\n displayName: \"AWS SDK\",\n description: \"AWS SDK v3 for TypeScript — S3, DynamoDB, SQS, Lambda\",\n usageGuidance:\n \"Use when integrating AWS services via the AWS SDK v3 for JavaScript/TypeScript — S3 operations, DynamoDB queries, SQS messaging, Lambda invocations, SNS notifications, Secrets Manager, and IAM patterns.\",\n category: \"infra-platform\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/infra-platform-aws-sdk\",\n },\n \"infra-platform-cloudflare-workers\": {\n id: \"infra-platform-cloudflare-workers\",\n slug: \"cloudflare-workers\",\n displayName: \"Cloudflare Workers\",\n description: \"Cloudflare Workers edge compute platform\",\n usageGuidance:\n \"Use when deploying to Cloudflare Workers — Wrangler CLI, KV storage, D1 databases, R2 object storage, Durable Objects, Queues, and edge-first TypeScript patterns.\",\n category: \"infra-platform\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/infra-platform-cloudflare-workers\",\n },\n \"infra-platform-netlify\": {\n id: \"infra-platform-netlify\",\n slug: \"netlify\",\n displayName: \"Netlify\",\n description: \"Deployment platform with serverless and edge functions\",\n usageGuidance:\n \"Use when deploying to Netlify — site configuration, serverless functions, edge functions, redirects/rewrites, forms, environment variables, build plugins, and deployment workflows.\",\n category: \"infra-platform\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/infra-platform-netlify\",\n },\n \"infra-platform-vercel\": {\n id: \"infra-platform-vercel\",\n slug: \"vercel\",\n displayName: \"Vercel\",\n description: \"Vercel deployment platform, edge functions, and middleware\",\n usageGuidance:\n \"Use when deploying to Vercel — project configuration (vercel.json/vercel.ts), serverless and edge functions, Routing Middleware, cron jobs, environment variables, monorepo setup, regions, headers, redirects, rewrites, and deployment workflows.\",\n category: \"infra-platform\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/infra-platform-vercel\",\n },\n \"meta-config-stack-detect\": {\n id: \"meta-config-stack-detect\",\n slug: \"stack-detect\",\n displayName: \"Stack Detection\",\n description: \"Detect a project's stack and propose a config\",\n usageGuidance:\n \"Use when proposing an agents-inc configuration from what is actually in front of you — a codebase to traverse, a stack the user describes in conversation, or nothing but a description of what they want to build. Maps detected libraries to catalog skill ids, offers candidate built-in stacks for the user to pick between when intent is all there is, marks how each assignment loads per the product's preload mapping, surfaces conflicts, and emits a SeedPayload plus a human-readable proposal report for the user to confirm.\",\n category: \"shared-tooling\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/meta-config-stack-detect\",\n },\n \"meta-design-composable-components\": {\n id: \"meta-design-composable-components\",\n slug: \"composable-components\",\n displayName: \"Composable Components\",\n description: \"Composable component APIs — parts, state, polymorphism\",\n usageGuidance:\n \"Use when designing a new React component API or aligning an existing one. Apply when a component is accumulating configuration props, booleans, or renderX props, and when adding controlled/uncontrolled duality, polymorphic rendering, data-attribute state, context scoping, or prop and ref forwarding.\",\n category: \"meta-design\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"web-framework-react\"],\n needsAny: false,\n reason:\n \"Composition patterns are React surface — base-ui useRender/mergeProps, forwardRef, JSX parts\",\n },\n ],\n alternatives: [],\n path: \"skills/meta-design-composable-components\",\n },\n \"meta-design-expressive-typescript\": {\n id: \"meta-design-expressive-typescript\",\n slug: \"expressive-typescript\",\n displayName: \"Expressive TypeScript\",\n description: \"Readable functional patterns and named abstractions\",\n usageGuidance:\n \"Use when writing or refactoring TypeScript functions, data transformations, store actions, or any code that mixes logic levels. Apply the orchestrator pattern and extract until the code reads like prose.\",\n category: \"meta-design\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/meta-design-expressive-typescript\",\n },\n \"meta-methodology-research-methodology\": {\n id: \"meta-methodology-research-methodology\",\n slug: \"research-methodology\",\n displayName: \"Research\",\n description: \"Codebase investigation\",\n usageGuidance:\n \"Use when investigating codebase patterns, researching implementations, or discovering how things work.\",\n category: \"meta-methodology\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/meta-methodology-research-methodology\",\n },\n \"meta-planning-ai-planning\": {\n id: \"meta-planning-ai-planning\",\n slug: \"ai-planning\",\n displayName: \"AI Planning\",\n description: \"Prompt contracts, model selection, budgets, eval planning\",\n usageGuidance:\n \"Use when a spec touches model calls, prompts, retrieval, tool calling, agentic loops, or evals. Carries the approach-selection, output-contract, budget, failure-mode, and eval frameworks for AI specifications.\",\n category: \"meta-planning\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/meta-planning-ai-planning\",\n },\n \"meta-planning-api-planning\": {\n id: \"meta-planning-api-planning\",\n slug: \"api-planning\",\n displayName: \"API Planning\",\n description: \"Endpoint contracts, schema design, auth and error catalogs\",\n usageGuidance:\n \"Use when a spec touches API endpoints, database schema, middleware, or auth. Carries the endpoint-contract, schema, middleware-pipeline, and error-catalog frameworks for backend specifications.\",\n category: \"meta-planning\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/meta-planning-api-planning\",\n },\n \"meta-planning-cli-planning\": {\n id: \"meta-planning-cli-planning\",\n slug: \"cli-planning\",\n displayName: \"CLI Planning\",\n description: \"Command-surface, flag, exit-code and output-mode planning\",\n usageGuidance:\n \"Use when a spec touches a command surface, an interactive flow, config precedence, exit codes, or output modes. Carries the contract frameworks and per-artifact spec tables for CLI specifications.\",\n category: \"meta-planning\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/meta-planning-cli-planning\",\n },\n \"meta-planning-web-planning\": {\n id: \"meta-planning-web-planning\",\n slug: \"web-planning\",\n displayName: \"Web Planning\",\n description: \"UI-state completeness, component boundaries, spec criteria\",\n usageGuidance:\n \"Use when a spec touches UI components, forms, client state, or user-facing flows. Carries the UI-state completeness, component-boundary, and measurable-criteria frameworks for frontend specifications.\",\n category: \"meta-planning\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/meta-planning-web-planning\",\n },\n \"meta-reviewing-ai-reviewing\": {\n id: \"meta-reviewing-ai-reviewing\",\n slug: \"ai-reviewing\",\n displayName: \"AI Reviewing\",\n description: \"Prompt injection, output validation, and cost control\",\n usageGuidance:\n \"Use when reviewing diffs that touch model API calls, prompt construction, LLM output handling, RAG pipelines, or tool-calling code. Covers injection call-chain tracing, output validation, token budgets, retry/timeout handling, streaming, and key/PII exposure.\",\n category: \"meta-reviewing\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/meta-reviewing-ai-reviewing\",\n },\n \"meta-reviewing-api-reviewing\": {\n id: \"meta-reviewing-api-reviewing\",\n slug: \"api-reviewing\",\n displayName: \"API Reviewing\",\n description: \"Injection, boundary validation, authorization, data exposure\",\n usageGuidance:\n \"Use when reviewing diffs that touch API routes, database queries, auth middleware, or server utilities. Covers injection, input validation at boundaries, authn/authz coverage, secret and PII exposure, error leakage, and query patterns.\",\n category: \"meta-reviewing\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/meta-reviewing-api-reviewing\",\n },\n \"meta-reviewing-cli-reviewing\": {\n id: \"meta-reviewing-cli-reviewing\",\n slug: \"cli-reviewing\",\n displayName: \"CLI Reviewing\",\n description: \"CLI code review patterns for Commander.js and @clack/prompts\",\n usageGuidance:\n \"Use when reviewing CLI applications built with Commander.js, @clack/prompts, or similar tools. Covers exit codes, signal handling, cancellation, error messages, spinners, and testing adequacy.\",\n category: \"meta-reviewing\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/meta-reviewing-cli-reviewing\",\n },\n \"meta-reviewing-infra-reviewing\": {\n id: \"meta-reviewing-infra-reviewing\",\n slug: \"infra-reviewing\",\n displayName: \"Infra Reviewing\",\n description: \"Supply-chain pinning, secret exposure, container hygiene\",\n usageGuidance:\n \"Use when reviewing diffs that touch CI/CD workflows, Dockerfiles, deployment configs, or IaC. Covers action and base-image pinning, secret handling, non-root containers, layer caching, least-privilege permissions, and deployment safety.\",\n category: \"meta-reviewing\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/meta-reviewing-infra-reviewing\",\n },\n \"meta-reviewing-reviewing\": {\n id: \"meta-reviewing-reviewing\",\n slug: \"reviewing\",\n displayName: \"Code Review\",\n description: \"Code review guidance\",\n usageGuidance: \"Use when reviewing code, PRs, or making approval/rejection decisions.\",\n category: \"meta-reviewing\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/meta-reviewing-reviewing\",\n },\n \"meta-reviewing-web-reviewing\": {\n id: \"meta-reviewing-web-reviewing\",\n slug: \"web-reviewing\",\n displayName: \"Web Reviewing\",\n description: \"React hooks, accessibility, and render performance\",\n usageGuidance:\n \"Use when reviewing diffs that touch UI components - React/JSX files, hooks, props and state, styling, or accessibility. Covers rules of hooks, effect cleanup, render performance, list keys, and ARIA/keyboard patterns.\",\n category: \"meta-reviewing\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"web-framework-react\"],\n needsAny: false,\n reason:\n \"Checklist self-scopes to React diffs — rules of hooks, dependency arrays, React.memo\",\n },\n ],\n alternatives: [],\n path: \"skills/meta-reviewing-web-reviewing\",\n },\n \"mobile-animation-gesture-handler\": {\n id: \"mobile-animation-gesture-handler\",\n slug: \"gesture-handler\",\n displayName: \"Gesture Handler\",\n description: \"Native gesture system for React Native\",\n usageGuidance:\n \"Use when implementing touch gestures (pan, pinch, tap, rotation, long press, fling, hover), composing multiple gestures on the same view, building swipeable list rows, or replacing React Native's built-in Gesture Responder System.\",\n category: \"mobile-animation\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-react-native\", \"mobile-framework-expo\"],\n needsAny: true,\n reason: \"Gesture Handler replaces React Native's gesture system\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-animation-gesture-handler\",\n },\n \"mobile-animation-reanimated\": {\n id: \"mobile-animation-reanimated\",\n slug: \"reanimated\",\n displayName: \"Reanimated\",\n description: \"React Native animations and gestures\",\n usageGuidance:\n \"Use when implementing animations in React Native with Reanimated 4 - shared values, animated styles, spring/timing/decay animations, layout animations, gesture-driven animations, scroll-driven animations, interpolation, or worklet functions.\",\n category: \"mobile-animation\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-react-native\", \"mobile-framework-expo\"],\n needsAny: true,\n reason: \"Reanimated animates React Native via worklets\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-animation-reanimated\",\n },\n \"mobile-animation-skia\": {\n id: \"mobile-animation-skia\",\n slug: \"skia\",\n displayName: \"Skia\",\n description: \"GPU-accelerated 2D graphics with Skia\",\n usageGuidance:\n \"Use when implementing custom 2D graphics, shaders, blur effects, path animations, text layout with Paragraph API, sprite batch rendering with Atlas, or GPU-accelerated drawing in React Native using @shopify/react-native-skia.\",\n category: \"mobile-animation\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-react-native\", \"mobile-framework-expo\"],\n needsAny: true,\n reason: \"@shopify/react-native-skia is a React Native renderer\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-animation-skia\",\n },\n \"mobile-background-tasks\": {\n id: \"mobile-background-tasks\",\n slug: \"tasks\",\n displayName: \"Background Tasks\",\n description: \"Background fetch, processing, location\",\n usageGuidance:\n \"Use when implementing background fetch, periodic sync, background location tracking, headless JS tasks, or any work that must execute while the app is backgrounded or terminated.\",\n category: \"mobile-background\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-react-native\", \"mobile-framework-expo\"],\n needsAny: true,\n reason: \"Dual-path: Expo background tasks or react-native-background-fetch\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-background-tasks\",\n },\n \"mobile-camera-vision-camera\": {\n id: \"mobile-camera-vision-camera\",\n slug: \"vision-camera\",\n displayName: \"VisionCamera\",\n description: \"Camera capture, scanning, frame processing\",\n usageGuidance:\n \"Use when implementing camera features with react-native-vision-camera: photo/video capture, QR/barcode scanning, real-time frame processing, zoom/focus/exposure controls, or HDR. Not for image picking from gallery.\",\n category: \"mobile-camera\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-react-native\", \"mobile-framework-expo\"],\n needsAny: true,\n reason: \"react-native-vision-camera depends on React Native's JSI\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-camera-vision-camera\",\n },\n \"mobile-deep-linking-app-links\": {\n id: \"mobile-deep-linking-app-links\",\n slug: \"app-links\",\n displayName: \"Deep Linking & App Links\",\n description: \"Universal Links, App Links, URI schemes\",\n usageGuidance:\n \"Use when implementing deep linking, Universal Links (iOS), App Links (Android), custom URI schemes, or configuring navigation to handle incoming URLs in React Native.\",\n category: \"mobile-deep-linking\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-react-native\", \"mobile-framework-expo\"],\n needsAny: true,\n reason: \"Deep linking via expo-linking or React Navigation linking config\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-deep-linking-app-links\",\n },\n \"mobile-deployment-eas\": {\n id: \"mobile-deployment-eas\",\n slug: \"eas\",\n displayName: \"EAS\",\n description: \"EAS Build, Update, Submit patterns\",\n usageGuidance:\n \"Use when configuring EAS Build profiles, publishing OTA updates with EAS Update, submitting to app stores with EAS Submit, managing credentials, setting up CI/CD with EAS Workflows, or configuring eas.json for any Expo project.\",\n category: \"mobile-deployment\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-expo\"],\n needsAny: false,\n reason: \"EAS Build/Update workflows assume the Expo SDK\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-deployment-eas\",\n },\n \"mobile-framework-expo\": {\n id: \"mobile-framework-expo\",\n slug: \"expo\",\n displayName: \"Expo\",\n description: \"Expo managed workflow\",\n usageGuidance:\n \"Use when building React Native apps with Expo, configuring EAS builds, or using Expo Router.\",\n category: \"mobile-framework\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-react-native\"],\n needsAny: false,\n reason: \"Expo is a React Native framework\",\n },\n ],\n alternatives: [\n {\n skillId: \"mobile-framework-react-native\",\n purpose: \"Mobile\",\n },\n ],\n path: \"skills/mobile-framework-expo\",\n },\n \"mobile-framework-react-native\": {\n id: \"mobile-framework-react-native\",\n slug: \"react-native\",\n displayName: \"React Native\",\n description: \"React Native mobile apps\",\n usageGuidance:\n \"Use when building cross-platform mobile apps, working with native modules, or React Navigation.\",\n category: \"mobile-framework\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"web-framework-react\"],\n needsAny: false,\n reason: \"React Native is built on React\",\n },\n ],\n alternatives: [\n {\n skillId: \"mobile-framework-expo\",\n purpose: \"Mobile\",\n },\n ],\n path: \"skills/mobile-framework-react-native\",\n },\n \"mobile-hardware-ble-nfc\": {\n id: \"mobile-hardware-ble-nfc\",\n slug: \"ble-nfc\",\n displayName: \"BLE & NFC\",\n description: \"Bluetooth LE and NFC hardware access\",\n usageGuidance:\n \"Use when implementing BLE scanning, connecting, reading/writing characteristics, or NFC tag reading/writing with react-native-ble-plx and react-native-nfc-manager. Not for classic Bluetooth, peripheral mode, or Wi-Fi Direct.\",\n category: \"mobile-hardware\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-react-native\", \"mobile-framework-expo\"],\n needsAny: true,\n reason: \"Both taught libraries are React Native packages\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-hardware-ble-nfc\",\n },\n \"mobile-navigation-expo-router\": {\n id: \"mobile-navigation-expo-router\",\n slug: \"expo-router\",\n displayName: \"Expo Router\",\n description: \"File-based routing for React Native\",\n usageGuidance:\n \"Use when implementing navigation with Expo Router: file-based routing, layout routes, dynamic/catch-all routes, tab/stack navigation, modal routes, authentication flows with Stack.Protected, API routes, typed routes, deep linking, or static rendering for web.\",\n category: \"mobile-navigation\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-expo\"],\n needsAny: false,\n reason: \"Expo Router is built on the Expo SDK\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-navigation-expo-router\",\n },\n \"mobile-navigation-react-navigation\": {\n id: \"mobile-navigation-react-navigation\",\n slug: \"react-navigation\",\n displayName: \"React Navigation\",\n description: \"Type-safe mobile navigation patterns\",\n usageGuidance:\n \"Use when implementing navigation in React Native apps: stack/tab/drawer navigators, deep linking, type-safe navigation with TypeScript, authentication flows, screen preloading, or header customization. Covers both static and dynamic APIs.\",\n category: \"mobile-navigation\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-react-native\", \"mobile-framework-expo\"],\n needsAny: true,\n reason: \"React Navigation targets React Native apps, bare or Expo\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-navigation-react-navigation\",\n },\n \"mobile-notifications-push\": {\n id: \"mobile-notifications-push\",\n slug: \"push\",\n displayName: \"Push Notifications\",\n description: \"Push notification patterns for React Native\",\n usageGuidance:\n \"Use when implementing push notifications (remote or local), requesting notification permissions, handling push tokens, listening for foreground/background/tap events, scheduling local notifications, managing Android channels, or configuring notification categories and actions in React Native.\",\n category: \"mobile-notifications\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-react-native\", \"mobile-framework-expo\"],\n needsAny: true,\n reason: \"Dual-path: expo-notifications or React Native Firebase messaging\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-notifications-push\",\n },\n \"mobile-performance-react-native\": {\n id: \"mobile-performance-react-native\",\n slug: \"react-native-performance\",\n displayName: \"React Native Performance\",\n description: \"RN profiling, optimization, memory\",\n usageGuidance:\n \"Use when profiling React Native performance, optimizing re-renders, improving list scrolling, reducing bundle size, fixing memory leaks, or analyzing JS thread vs UI thread bottlenecks. Not for general React Native component architecture (use mobile-framework-react-native).\",\n category: \"mobile-performance\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-react-native\", \"mobile-framework-expo\"],\n needsAny: true,\n reason: \"React Native performance patterns: Hermes, threads, FlashList\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-performance-react-native\",\n },\n \"mobile-security-react-native\": {\n id: \"mobile-security-react-native\",\n slug: \"react-native-security\",\n displayName: \"React Native Security\",\n description: \"Mobile app security hardening\",\n usageGuidance:\n \"Use when implementing secure storage, certificate pinning, biometric authentication, jailbreak/root detection, code obfuscation, screenshot prevention, or network security in React Native apps.\",\n category: \"mobile-security\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-react-native\", \"mobile-framework-expo\"],\n needsAny: true,\n reason: \"Dual-path secure storage: expo-secure-store or react-native-keychain\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-security-react-native\",\n },\n \"mobile-storage-mmkv\": {\n id: \"mobile-storage-mmkv\",\n slug: \"mmkv\",\n displayName: \"MMKV\",\n description: \"High-performance key-value storage\",\n usageGuidance:\n \"Use when persisting key-value data in React Native with react-native-mmkv - synchronous reads/writes, encryption, multiple instances, hooks, or migrating from AsyncStorage.\",\n category: \"mobile-storage\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-react-native\", \"mobile-framework-expo\"],\n needsAny: true,\n reason: \"react-native-mmkv is a React Native storage package\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-storage-mmkv\",\n },\n \"mobile-storage-sqlite-powersync\": {\n id: \"mobile-storage-sqlite-powersync\",\n slug: \"sqlite-powersync\",\n displayName: \"SQLite + PowerSync\",\n description: \"Offline-first SQLite sync engine\",\n usageGuidance:\n \"Use when building offline-first React Native apps with @powersync/react-native - local SQLite database with cloud sync, schema definition, watched queries, CRUD operations, backend connectors, conflict resolution, or attachment handling.\",\n category: \"mobile-storage\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-react-native\", \"mobile-framework-expo\"],\n needsAny: true,\n reason: \"The skill teaches PowerSync's React Native SDK\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-storage-sqlite-powersync\",\n },\n \"mobile-storage-watermelondb\": {\n id: \"mobile-storage-watermelondb\",\n slug: \"watermelondb\",\n displayName: \"WatermelonDB\",\n description: \"Reactive local database for React Native\",\n usageGuidance:\n \"Use when building offline-first React Native apps with WatermelonDB - schema and model definitions, reactive queries with observe/withObservables, relations, writer/reader actions, batch operations, migrations, or sync with pullChanges/pushChanges.\",\n category: \"mobile-storage\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-react-native\", \"mobile-framework-expo\"],\n needsAny: true,\n reason: \"WatermelonDB as taught targets offline-first React Native apps\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-storage-watermelondb\",\n },\n \"mobile-styling-nativewind\": {\n id: \"mobile-styling-nativewind\",\n slug: \"nativewind\",\n displayName: \"NativeWind\",\n description: \"Tailwind CSS styling for React Native\",\n usageGuidance:\n \"Use when styling React Native components with Tailwind CSS utility classes via NativeWind, implementing dark mode, theming with CSS variables, platform-specific styles, or integrating className support with third-party components.\",\n category: \"mobile-styling\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-react-native\", \"mobile-framework-expo\"],\n needsAny: true,\n reason: \"NativeWind compiles Tailwind classes for React Native components\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-styling-nativewind\",\n },\n \"mobile-styling-unistyles\": {\n id: \"mobile-styling-unistyles\",\n slug: \"unistyles\",\n displayName: \"Unistyles\",\n description: \"C++ powered React Native styling\",\n usageGuidance:\n \"Use when styling React Native components with Unistyles 3.0: theming with StyleSheet.configure, breakpoints and media queries, variants and compound variants, dynamic functions, runtime values (insets, screen, fontScale), scoped themes, or migrating from Unistyles 2.x.\",\n category: \"mobile-styling\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-react-native\", \"mobile-framework-expo\"],\n needsAny: true,\n reason: \"Unistyles styles React Native via Nitro Modules\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-styling-unistyles\",\n },\n \"mobile-testing-detox\": {\n id: \"mobile-testing-detox\",\n slug: \"detox\",\n displayName: \"Detox\",\n description: \"React Native E2E gray-box testing\",\n usageGuidance:\n \"Use when writing end-to-end tests for React Native apps with Detox, configuring .detoxrc.js, using element matchers/actions/expectations, waitFor polling, device API, mocking with Metro, or setting up CI artifacts.\",\n category: \"mobile-testing\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-react-native\", \"mobile-framework-expo\"],\n needsAny: true,\n reason: \"Detox is gray-box E2E testing for React Native\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-testing-detox\",\n },\n \"mobile-testing-maestro\": {\n id: \"mobile-testing-maestro\",\n slug: \"maestro\",\n displayName: \"Maestro\",\n description: \"YAML-based mobile UI testing\",\n usageGuidance:\n \"Use when writing or debugging Maestro YAML flows for mobile E2E testing, working with selectors, flow control, environment variables, Maestro Studio, Maestro Cloud CI, JavaScript expressions, or device interaction commands.\",\n category: \"mobile-testing\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"mobile-framework-react-native\",\n \"mobile-framework-expo\",\n \"desktop-mobile-tauri\",\n ],\n needsAny: true,\n reason: \"Maestro drives a mobile app; these are the catalog's mobile-app producers\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-testing-maestro\",\n },\n \"mobile-ui-components-react-native-paper\": {\n id: \"mobile-ui-components-react-native-paper\",\n slug: \"react-native-paper\",\n displayName: \"React Native Paper\",\n description: \"Material Design 3 components for React Native\",\n usageGuidance:\n \"Use when building Material Design UIs with React Native Paper v5+, configuring PaperProvider theming (MD3 light/dark, custom themes, dynamic color), or using Paper components (Button, Card, TextInput, FAB, Appbar, Dialog, Snackbar, SegmentedButtons, BottomNavigation). Not for general React Native patterns.\",\n category: \"mobile-ui-components\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"mobile-framework-react-native\", \"mobile-framework-expo\"],\n needsAny: true,\n reason: \"React Native Paper is Material Design 3 for React Native\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-ui-components-react-native-paper\",\n },\n \"mobile-ui-components-tamagui\": {\n id: \"mobile-ui-components-tamagui\",\n slug: \"tamagui\",\n displayName: \"Tamagui\",\n description: \"Universal UI for React Native and web\",\n usageGuidance:\n \"Use when building universal React Native + web UIs with Tamagui styled components, token system, themes, optimizing compiler, responsive media queries, animations, or Tamagui UI kit components (Sheet, Dialog, Button, Input).\",\n category: \"mobile-ui-components\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"mobile-framework-react-native\",\n \"mobile-framework-expo\",\n \"web-framework-react\",\n ],\n needsAny: true,\n reason: \"Tamagui is universal React: native via RN or Expo, web via React alone\",\n },\n ],\n alternatives: [],\n path: \"skills/mobile-ui-components-tamagui\",\n },\n \"shared-monorepo-nx\": {\n id: \"shared-monorepo-nx\",\n slug: \"nx\",\n displayName: \"Nx\",\n description: \"Nx monorepo build system and task orchestration\",\n usageGuidance:\n \"Use when setting up or working with Nx monorepos — workspace configuration, project graph, task pipelines, caching, generators, and plugins.\",\n category: \"shared-task-runner\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"shared-monorepo-turborepo\",\n reason: \"Monorepo build orchestrators are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"shared-monorepo-turborepo\",\n purpose: \"Monorepo Orchestrator\",\n },\n ],\n path: \"skills/shared-monorepo-nx\",\n },\n \"shared-monorepo-pnpm-workspaces\": {\n id: \"shared-monorepo-pnpm-workspaces\",\n slug: \"pnpm-workspaces\",\n displayName: \"pnpm Workspaces\",\n description: \"pnpm workspace protocol for monorepo management\",\n usageGuidance:\n \"Use when managing monorepos with pnpm — workspace protocol, filtering, shared dependencies, publishConfig, and catalog for version synchronization.\",\n category: \"shared-monorepo\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/shared-monorepo-pnpm-workspaces\",\n },\n \"shared-monorepo-turborepo\": {\n id: \"shared-monorepo-turborepo\",\n slug: \"turborepo\",\n displayName: \"Turborepo\",\n description: \"Monorepo orchestration\",\n usageGuidance:\n \"Use when configuring monorepo pipelines, workspaces, or package architecture.\",\n category: \"shared-task-runner\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"shared-monorepo-nx\",\n reason: \"Monorepo build orchestrators are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"shared-monorepo-nx\",\n purpose: \"Monorepo Orchestrator\",\n },\n ],\n path: \"skills/shared-monorepo-turborepo\",\n },\n \"shared-security-auth-security\": {\n id: \"shared-security-auth-security\",\n slug: \"auth-security\",\n displayName: \"Security\",\n description: \"Application security patterns\",\n usageGuidance:\n \"Use when implementing authentication, authorization, XSS prevention, CSRF protection, CSP headers, or managing secrets.\",\n category: \"shared-security\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/shared-security-auth-security\",\n },\n \"shared-tooling-biome\": {\n id: \"shared-tooling-biome\",\n slug: \"biome\",\n displayName: \"Biome\",\n description: \"Biome unified linter and formatter\",\n usageGuidance:\n \"Use when configuring Biome as an all-in-one linter, formatter, and import organizer — replacing ESLint and Prettier with a single fast tool.\",\n category: \"shared-lint\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"shared-tooling-eslint-prettier\",\n reason: \"Linting and formatting tools are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"shared-tooling-eslint-prettier\",\n purpose: \"Linting / Formatting\",\n },\n ],\n path: \"skills/shared-tooling-biome\",\n },\n \"shared-tooling-changesets\": {\n id: \"shared-tooling-changesets\",\n slug: \"changesets\",\n displayName: \"Changesets\",\n description: \"Versioning and changelog management with Changesets\",\n usageGuidance:\n \"Use when managing package versioning and changelogs with @changesets/cli — adding changesets, version bumping, changelog generation, monorepo publishing, pre-release modes, and CI automation.\",\n category: \"shared-tooling\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/shared-tooling-changesets\",\n },\n \"shared-tooling-eslint-prettier\": {\n id: \"shared-tooling-eslint-prettier\",\n slug: \"eslint-prettier\",\n displayName: \"ESLint & Prettier\",\n description: \"ESLint 9/10 flat config and Prettier formatting\",\n usageGuidance:\n \"Use when configuring ESLint 9 flat config, Prettier formatting, shared linting configs, or migrating from legacy .eslintrc to flat config.\",\n category: \"shared-lint\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"shared-tooling-biome\",\n reason: \"Linting and formatting tools are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"shared-tooling-biome\",\n purpose: \"Linting / Formatting\",\n },\n ],\n path: \"skills/shared-tooling-eslint-prettier\",\n },\n \"shared-tooling-git-hooks\": {\n id: \"shared-tooling-git-hooks\",\n slug: \"git-hooks\",\n displayName: \"Git Hooks\",\n description: \"Husky, lint-staged, commitlint\",\n usageGuidance:\n \"Use when setting up pre-commit hooks with Husky, configuring lint-staged for staged file linting, or adding commitlint for conventional commits.\",\n category: \"shared-tooling\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/shared-tooling-git-hooks\",\n },\n \"shared-tooling-typescript-config\": {\n id: \"shared-tooling-typescript-config\",\n slug: \"typescript-config\",\n displayName: \"TypeScript Config\",\n description: \"Shared TypeScript strict configs\",\n usageGuidance:\n \"Use when configuring TypeScript strict mode, shared tsconfig patterns, path aliases, or TS 5.x module settings.\",\n category: \"shared-tooling\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/shared-tooling-typescript-config\",\n },\n \"web-3d-react-three-fiber\": {\n id: \"web-3d-react-three-fiber\",\n slug: \"react-three-fiber\",\n displayName: \"React Three Fiber\",\n description: \"3D rendering with React Three Fiber and Three.js\",\n usageGuidance:\n \"Use when building 3D experiences with React Three Fiber (R3F) — scene setup, meshes, materials, lights, cameras, animations, physics (rapier), post-processing, performance optimization, and interaction/events.\",\n category: \"web-3d\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason: \"React Three Fiber is a React renderer for Three.js\",\n },\n ],\n alternatives: [],\n path: \"skills/web-3d-react-three-fiber\",\n },\n \"web-accessibility-web-accessibility\": {\n id: \"web-accessibility-web-accessibility\",\n slug: \"web-accessibility\",\n displayName: \"Accessibility\",\n description: \"WCAG accessibility patterns\",\n usageGuidance:\n \"Use when implementing WCAG compliance, ARIA attributes, or keyboard navigation.\",\n category: \"web-accessibility\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/web-accessibility-web-accessibility\",\n },\n \"web-animation-css-animations\": {\n id: \"web-animation-css-animations\",\n slug: \"css-animations\",\n displayName: \"CSS Animations\",\n description: \"Native CSS animations\",\n usageGuidance:\n \"Use when implementing CSS transitions, keyframes, or scroll-driven animations.\",\n category: \"web-animation\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"web-animation-framer-motion\",\n purpose: \"Animation\",\n },\n {\n skillId: \"web-animation-view-transitions\",\n purpose: \"Animation\",\n },\n ],\n path: \"skills/web-animation-css-animations\",\n },\n \"web-animation-framer-motion\": {\n id: \"web-animation-framer-motion\",\n slug: \"framer-motion\",\n displayName: \"Motion\",\n description: \"Motion animation library\",\n usageGuidance: \"Use when animating React components with Motion (Framer Motion).\",\n category: \"web-animation\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason: \"Motion (Framer Motion) is a React animation library\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-animation-css-animations\",\n purpose: \"Animation\",\n },\n {\n skillId: \"web-animation-view-transitions\",\n purpose: \"Animation\",\n },\n ],\n path: \"skills/web-animation-framer-motion\",\n },\n \"web-animation-view-transitions\": {\n id: \"web-animation-view-transitions\",\n slug: \"view-transitions\",\n displayName: \"View Transitions\",\n description: \"Page transition animations\",\n usageGuidance: \"Use when implementing page transitions with View Transitions API.\",\n category: \"web-animation\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"web-animation-framer-motion\",\n purpose: \"Animation\",\n },\n {\n skillId: \"web-animation-css-animations\",\n purpose: \"Animation\",\n },\n ],\n path: \"skills/web-animation-view-transitions\",\n },\n \"web-data-fetching-graphql-apollo\": {\n id: \"web-data-fetching-graphql-apollo\",\n slug: \"graphql-apollo\",\n displayName: \"Apollo Client\",\n description: \"Apollo GraphQL client\",\n usageGuidance: \"Use when working with Apollo Client for GraphQL queries and mutations.\",\n category: \"web-graphql-client\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason: \"Skill teaches React Apollo Client patterns\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-data-fetching-graphql-urql\",\n purpose: \"GraphQL Client\",\n },\n ],\n path: \"skills/web-data-fetching-graphql-apollo\",\n },\n \"web-data-fetching-graphql-urql\": {\n id: \"web-data-fetching-graphql-urql\",\n slug: \"graphql-urql\",\n displayName: \"URQL\",\n description: \"URQL GraphQL client\",\n usageGuidance: \"Use when working with URQL client for GraphQL.\",\n category: \"web-graphql-client\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-framework-vue-composition-api\",\n \"web-framework-solidjs\",\n \"web-framework-svelte\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n \"web-meta-framework-nuxt\",\n \"web-meta-framework-sveltekit\",\n ],\n needsAny: true,\n reason: \"URQL supports React, Vue, Solid, and Svelte\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-data-fetching-graphql-apollo\",\n purpose: \"GraphQL Client\",\n },\n ],\n path: \"skills/web-data-fetching-graphql-urql\",\n },\n \"web-data-fetching-swr\": {\n id: \"web-data-fetching-swr\",\n slug: \"swr\",\n displayName: \"SWR\",\n description: \"Server state and caching\",\n usageGuidance: \"Use when implementing stale-while-revalidate data fetching patterns.\",\n category: \"web-server-state\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-server-state-react-query\",\n reason: \"Both solve server state caching\",\n },\n ],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n \"mobile-framework-react-native\",\n ],\n needsAny: true,\n reason: \"SWR is a React Hooks library\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-server-state-react-query\",\n purpose: \"Server State / Data Fetching\",\n },\n {\n skillId: \"web-data-fetching-trpc\",\n purpose: \"Server State / Data Fetching\",\n },\n ],\n path: \"skills/web-data-fetching-swr\",\n },\n \"web-data-fetching-trpc\": {\n id: \"web-data-fetching-trpc\",\n slug: \"trpc\",\n displayName: \"tRPC\",\n description: \"Type-safe API layer\",\n usageGuidance: \"Use when building type-safe APIs with tRPC procedures and React Query.\",\n category: \"web-rpc\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason: \"Skill teaches React Query integration patterns\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-server-state-react-query\",\n purpose: \"Server State / Data Fetching\",\n },\n {\n skillId: \"web-data-fetching-swr\",\n purpose: \"Server State / Data Fetching\",\n },\n ],\n path: \"skills/web-data-fetching-trpc\",\n },\n \"web-dataviz-d3\": {\n id: \"web-dataviz-d3\",\n slug: \"d3\",\n displayName: \"D3.js\",\n description: \"Data-driven visualizations with D3.js\",\n usageGuidance:\n \"Use when building custom data visualizations with D3.js — selections, data joins, scales, axes, shapes, transitions, force layouts, geographic projections, and integrating D3 with component frameworks.\",\n category: \"web-dataviz\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/web-dataviz-d3\",\n },\n \"web-dataviz-recharts\": {\n id: \"web-dataviz-recharts\",\n slug: \"recharts\",\n displayName: \"Recharts\",\n description: \"Composable chart components with Recharts\",\n usageGuidance:\n \"Use when building charts and data visualizations with Recharts — line charts, bar charts, area charts, pie charts, scatter plots, composed charts, responsive containers, custom tooltips, animations, and real-time data updates.\",\n category: \"web-dataviz\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason: \"Recharts wraps D3 in composable React components\",\n },\n ],\n alternatives: [],\n path: \"skills/web-dataviz-recharts\",\n },\n \"web-dnd-dnd-kit\": {\n id: \"web-dnd-dnd-kit\",\n slug: \"dnd-kit\",\n displayName: \"dnd-kit\",\n description: \"Drag and drop toolkit with @dnd-kit\",\n usageGuidance:\n \"Use when implementing drag and drop with @dnd-kit — sortable lists, Kanban boards, droppable containers, drag overlays, collision detection, keyboard/screen reader accessibility, and multi-container sorting.\",\n category: \"web-dnd\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason:\n \"The skill teaches DndContext/useDraggable/useDroppable/useSortable — @dnd-kit React packages throughout\",\n },\n ],\n alternatives: [],\n path: \"skills/web-dnd-dnd-kit\",\n },\n \"web-editor-lexical\": {\n id: \"web-editor-lexical\",\n slug: \"lexical\",\n displayName: \"Lexical\",\n description: \"Extensible text editor framework by Meta with Lexical\",\n usageGuidance:\n \"Use when building rich text editors with Lexical — editor setup, nodes, plugins, commands, decorators, collaboration, serialization, and custom toolbar/menu creation.\",\n category: \"web-editor\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason:\n \"The skill's only editor setup and plugin registration path is @lexical/react — LexicalComposer plus useEffect registration\",\n },\n ],\n alternatives: [],\n path: \"skills/web-editor-lexical\",\n },\n \"web-editor-tiptap\": {\n id: \"web-editor-tiptap\",\n slug: \"tiptap\",\n displayName: \"TipTap\",\n description: \"Rich text editor framework with TipTap and ProseMirror\",\n usageGuidance:\n \"Use when building rich text editors with TipTap — editor setup, extensions, custom nodes/marks, menus (bubble/floating), collaborative editing, content serialization, keyboard shortcuts, and schema customization.\",\n category: \"web-editor\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/web-editor-tiptap\",\n },\n \"web-error-handling-error-boundaries\": {\n id: \"web-error-handling-error-boundaries\",\n slug: \"error-boundaries\",\n displayName: \"Error Boundaries\",\n description: \"Error UI handling\",\n usageGuidance: \"Use when implementing React error boundaries, fallback UIs, or retry logic.\",\n category: \"web-error-handling\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason: \"Error boundaries are a React concept\",\n },\n ],\n alternatives: [],\n path: \"skills/web-error-handling-error-boundaries\",\n },\n \"web-error-handling-result-types\": {\n id: \"web-error-handling-result-types\",\n slug: \"result-types\",\n displayName: \"Result Types\",\n description: \"Type-safe error handling\",\n usageGuidance: \"Use when implementing Result/Either types for type-safe error handling.\",\n category: \"web-error-handling\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/web-error-handling-result-types\",\n },\n \"web-files-file-upload-patterns\": {\n id: \"web-files-file-upload-patterns\",\n slug: \"file-upload-patterns\",\n displayName: \"File Upload\",\n description: \"File upload handling\",\n usageGuidance: \"Use when implementing file uploads, drag-drop, or chunked uploads.\",\n category: \"web-file-upload\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason: \"Skill teaches React-based file upload patterns\",\n },\n ],\n alternatives: [],\n path: \"skills/web-files-file-upload-patterns\",\n },\n \"web-files-image-handling\": {\n id: \"web-files-image-handling\",\n slug: \"image-handling\",\n displayName: \"Image Handling\",\n description: \"Client-side image processing\",\n usageGuidance: \"Use when processing images client-side, resizing, or format conversion.\",\n category: \"web-files\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason: \"Skill teaches React-based image handling hooks\",\n },\n ],\n alternatives: [],\n path: \"skills/web-files-image-handling\",\n },\n \"web-forms-react-hook-form\": {\n id: \"web-forms-react-hook-form\",\n slug: \"react-hook-form\",\n displayName: \"React Hook Form\",\n description: \"React form handling\",\n usageGuidance:\n \"Use when building forms in React with validation, field arrays, or Controller.\",\n category: \"web-form-library\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n \"mobile-framework-react-native\",\n ],\n needsAny: true,\n reason: \"React Hook Form is React only\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-forms-tanstack-form\",\n purpose: \"Forms (React)\",\n },\n ],\n path: \"skills/web-forms-react-hook-form\",\n },\n \"web-forms-tanstack-form\": {\n id: \"web-forms-tanstack-form\",\n slug: \"tanstack-form\",\n displayName: \"TanStack Form\",\n description: \"Type-safe, headless form management\",\n usageGuidance:\n \"Use when building forms with TanStack Form — type-safe, framework-agnostic form state, validation, and submission.\",\n category: \"web-form-library\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-framework-vue-composition-api\",\n \"web-framework-angular-standalone\",\n \"web-framework-solidjs\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n \"web-meta-framework-nuxt\",\n ],\n needsAny: true,\n reason: \"TanStack Form requires a UI framework\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-forms-react-hook-form\",\n purpose: \"Forms (React)\",\n },\n {\n skillId: \"web-forms-vee-validate\",\n purpose: \"Forms (Vue)\",\n },\n ],\n path: \"skills/web-forms-tanstack-form\",\n },\n \"web-forms-vee-validate\": {\n id: \"web-forms-vee-validate\",\n slug: \"vee-validate\",\n displayName: \"VeeValidate\",\n description: \"Vue form validation\",\n usageGuidance: \"Use when building forms in Vue with useForm, useField, or schema validation.\",\n category: \"web-form-library\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"web-framework-vue-composition-api\", \"web-meta-framework-nuxt\"],\n needsAny: true,\n reason: \"VeeValidate is Vue only\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-forms-tanstack-form\",\n purpose: \"Forms (Vue)\",\n },\n ],\n path: \"skills/web-forms-vee-validate\",\n },\n \"web-forms-zod-validation\": {\n id: \"web-forms-zod-validation\",\n slug: \"zod-validation\",\n displayName: \"Zod\",\n description: \"Schema validation\",\n usageGuidance: \"Use when defining validation schemas, type inference, or data transforms.\",\n category: \"web-forms\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/web-forms-zod-validation\",\n },\n \"web-framework-angular-standalone\": {\n id: \"web-framework-angular-standalone\",\n slug: \"angular-standalone\",\n displayName: \"Angular\",\n description: \"Angular standalone components\",\n usageGuidance:\n \"Use when building Angular 17+ apps with standalone components, signals, or DI.\",\n category: \"web-framework\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-framework-react\",\n reason: \"Base frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-framework-vue-composition-api\",\n reason: \"Base frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-framework-solidjs\",\n reason: \"Base frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-framework-svelte\",\n reason: \"Base frameworks are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"web-framework-react\",\n purpose: \"Base Framework\",\n },\n {\n skillId: \"web-framework-vue-composition-api\",\n purpose: \"Base Framework\",\n },\n {\n skillId: \"web-framework-solidjs\",\n purpose: \"Base Framework\",\n },\n {\n skillId: \"web-framework-svelte\",\n purpose: \"Base Framework\",\n },\n ],\n path: \"skills/web-framework-angular-standalone\",\n },\n \"web-framework-react\": {\n id: \"web-framework-react\",\n slug: \"react\",\n displayName: \"React\",\n description: \"React component patterns\",\n usageGuidance: \"Use when building React components, hooks, or following React 19 patterns.\",\n category: \"web-framework\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-framework-vue-composition-api\",\n reason: \"Base frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-framework-angular-standalone\",\n reason: \"Base frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-framework-solidjs\",\n reason: \"Base frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-framework-svelte\",\n reason: \"Base frameworks are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"web-framework-vue-composition-api\",\n purpose: \"Base Framework\",\n },\n {\n skillId: \"web-framework-angular-standalone\",\n purpose: \"Base Framework\",\n },\n {\n skillId: \"web-framework-solidjs\",\n purpose: \"Base Framework\",\n },\n {\n skillId: \"web-framework-svelte\",\n purpose: \"Base Framework\",\n },\n ],\n path: \"skills/web-framework-react\",\n },\n \"web-framework-solidjs\": {\n id: \"web-framework-solidjs\",\n slug: \"solidjs\",\n displayName: \"SolidJS\",\n description: \"SolidJS reactive patterns\",\n usageGuidance: \"Use when building SolidJS apps with signals, effects, or SolidStart.\",\n category: \"web-framework\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-framework-react\",\n reason: \"Base frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-framework-vue-composition-api\",\n reason: \"Base frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-framework-angular-standalone\",\n reason: \"Base frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-framework-svelte\",\n reason: \"Base frameworks are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"web-framework-react\",\n purpose: \"Base Framework\",\n },\n {\n skillId: \"web-framework-vue-composition-api\",\n purpose: \"Base Framework\",\n },\n {\n skillId: \"web-framework-angular-standalone\",\n purpose: \"Base Framework\",\n },\n {\n skillId: \"web-framework-svelte\",\n purpose: \"Base Framework\",\n },\n ],\n path: \"skills/web-framework-solidjs\",\n },\n \"web-framework-svelte\": {\n id: \"web-framework-svelte\",\n slug: \"svelte\",\n displayName: \"Svelte\",\n description: \"Svelte 5 with Runes reactivity\",\n usageGuidance:\n \"Use when building Svelte 5 apps with Runes ($state, $derived, $effect), components, or snippets.\",\n category: \"web-framework\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-framework-react\",\n reason: \"Base frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-framework-vue-composition-api\",\n reason: \"Base frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-framework-angular-standalone\",\n reason: \"Base frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-framework-solidjs\",\n reason: \"Base frameworks are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"web-framework-react\",\n purpose: \"Base Framework\",\n },\n {\n skillId: \"web-framework-vue-composition-api\",\n purpose: \"Base Framework\",\n },\n {\n skillId: \"web-framework-angular-standalone\",\n purpose: \"Base Framework\",\n },\n {\n skillId: \"web-framework-solidjs\",\n purpose: \"Base Framework\",\n },\n ],\n path: \"skills/web-framework-svelte\",\n },\n \"web-framework-vue-composition-api\": {\n id: \"web-framework-vue-composition-api\",\n slug: \"vue-composition-api\",\n displayName: \"Vue\",\n description: \"Vue 3 Composition API\",\n usageGuidance:\n \"Use when building Vue 3 apps with Composition API, composables, or reactivity.\",\n category: \"web-framework\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-framework-react\",\n reason: \"Base frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-framework-angular-standalone\",\n reason: \"Base frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-framework-solidjs\",\n reason: \"Base frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-framework-svelte\",\n reason: \"Base frameworks are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"web-framework-react\",\n purpose: \"Base Framework\",\n },\n {\n skillId: \"web-framework-angular-standalone\",\n purpose: \"Base Framework\",\n },\n {\n skillId: \"web-framework-solidjs\",\n purpose: \"Base Framework\",\n },\n {\n skillId: \"web-framework-svelte\",\n purpose: \"Base Framework\",\n },\n ],\n path: \"skills/web-framework-vue-composition-api\",\n },\n \"web-i18n-next-intl\": {\n id: \"web-i18n-next-intl\",\n slug: \"next-intl\",\n displayName: \"next-intl\",\n description: \"Next.js internationalization\",\n usageGuidance: \"Use when implementing i18n in Next.js with next-intl.\",\n category: \"web-i18n\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-i18n-react-intl\",\n reason: \"React internationalization libraries are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [\n {\n skillIds: [\"web-meta-framework-nextjs\"],\n needsAny: false,\n reason:\n \"Skill teaches next-intl's Next.js App Router surface — middleware, routing.ts, setRequestLocale, NextIntlClientProvider\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-i18n-react-intl\",\n purpose: \"Internationalization (React)\",\n },\n ],\n path: \"skills/web-i18n-next-intl\",\n },\n \"web-i18n-react-intl\": {\n id: \"web-i18n-react-intl\",\n slug: \"react-intl\",\n displayName: \"React Intl\",\n description: \"React internationalization\",\n usageGuidance: \"Use when implementing i18n in React with FormatJS/react-intl.\",\n category: \"web-i18n\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-i18n-next-intl\",\n reason: \"React internationalization libraries are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason: \"React Intl (FormatJS) is React only\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-i18n-next-intl\",\n purpose: \"Internationalization (React)\",\n },\n ],\n path: \"skills/web-i18n-react-intl\",\n },\n \"web-i18n-vue-i18n\": {\n id: \"web-i18n-vue-i18n\",\n slug: \"vue-i18n\",\n displayName: \"Vue I18n\",\n description: \"Vue internationalization\",\n usageGuidance: \"Use when implementing i18n in Vue with vue-i18n.\",\n category: \"web-i18n\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"web-framework-vue-composition-api\", \"web-meta-framework-nuxt\"],\n needsAny: true,\n reason: \"vue-i18n is Vue 3 only\",\n },\n ],\n alternatives: [],\n path: \"skills/web-i18n-vue-i18n\",\n },\n \"web-maps-leaflet\": {\n id: \"web-maps-leaflet\",\n slug: \"leaflet\",\n displayName: \"Leaflet\",\n description: \"Lightweight interactive maps with Leaflet\",\n usageGuidance:\n \"Use when building interactive maps with Leaflet -- map initialization, tile layers, markers, popups, GeoJSON, custom controls, plugins, marker clustering, and event handling.\",\n category: \"web-maps\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/web-maps-leaflet\",\n },\n \"web-maps-mapbox\": {\n id: \"web-maps-mapbox\",\n slug: \"mapbox\",\n displayName: \"Mapbox GL JS\",\n description: \"Interactive maps with Mapbox GL JS\",\n usageGuidance:\n \"Use when building interactive maps with Mapbox GL JS — map initialization, markers, popups, layers, sources, expressions, geocoding, directions, clustering, 3D terrain, and style customization.\",\n category: \"web-maps\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/web-maps-mapbox\",\n },\n \"web-meta-framework-astro\": {\n id: \"web-meta-framework-astro\",\n slug: \"astro\",\n displayName: \"Astro\",\n description: \"Astro content-first framework\",\n usageGuidance:\n \"Use when building Astro sites with islands architecture, content collections, or hybrid rendering.\",\n category: \"web-meta-framework\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-meta-framework-nextjs\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-remix\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-nuxt\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-sveltekit\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-qwik\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"web-meta-framework-nextjs\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-remix\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-nuxt\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-sveltekit\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-qwik\",\n purpose: \"Meta-Framework\",\n },\n ],\n path: \"skills/web-meta-framework-astro\",\n },\n \"web-meta-framework-docusaurus\": {\n id: \"web-meta-framework-docusaurus\",\n slug: \"docusaurus\",\n displayName: \"Docusaurus\",\n description: \"Docusaurus 3.x documentation site framework\",\n usageGuidance:\n \"Use when building or maintaining documentation sites with Docusaurus 3.x — configuring docs/blog plugins, sidebars, versioning, MDX content, swizzling theme components, or deploying static builds.\",\n category: \"web-docs\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"web-meta-framework-vitepress\",\n purpose: \"Documentation Framework\",\n },\n ],\n path: \"skills/web-meta-framework-docusaurus\",\n },\n \"web-meta-framework-nextjs\": {\n id: \"web-meta-framework-nextjs\",\n slug: \"nextjs\",\n displayName: \"Next.js\",\n description: \"Next.js full-stack framework\",\n usageGuidance:\n \"Use when building Next.js apps with App Router, Server/Client Components, Server Actions, or streaming.\",\n category: \"web-meta-framework\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-meta-framework-remix\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-nuxt\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-sveltekit\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-astro\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-qwik\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [\n {\n skillIds: [\"web-framework-react\"],\n needsAny: false,\n reason: \"Next.js is built on React\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-meta-framework-remix\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-nuxt\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-sveltekit\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-astro\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-qwik\",\n purpose: \"Meta-Framework\",\n },\n ],\n path: \"skills/web-meta-framework-nextjs\",\n },\n \"web-meta-framework-nuxt\": {\n id: \"web-meta-framework-nuxt\",\n slug: \"nuxt\",\n displayName: \"Nuxt\",\n description: \"Nuxt full-stack framework\",\n usageGuidance: \"Use when building Nuxt apps with useFetch, useState, or server routes.\",\n category: \"web-meta-framework\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-meta-framework-nextjs\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-remix\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-sveltekit\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-astro\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-qwik\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [\n {\n skillIds: [\"web-framework-vue-composition-api\"],\n needsAny: false,\n reason: \"Nuxt is built on Vue\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-meta-framework-nextjs\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-remix\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-sveltekit\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-astro\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-qwik\",\n purpose: \"Meta-Framework\",\n },\n ],\n path: \"skills/web-meta-framework-nuxt\",\n },\n \"web-meta-framework-qwik\": {\n id: \"web-meta-framework-qwik\",\n slug: \"qwik\",\n displayName: \"Qwik\",\n description: \"Resumable framework with zero hydration and lazy loading\",\n usageGuidance:\n \"Use when building web apps that need instant interactivity — resumability eliminates hydration, $ suffixed functions mark lazy boundaries, and Qwik City provides file-based routing with server loaders and actions.\",\n category: \"web-meta-framework\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-meta-framework-nextjs\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-remix\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-nuxt\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-sveltekit\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-astro\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"web-meta-framework-nextjs\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-remix\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-nuxt\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-sveltekit\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-astro\",\n purpose: \"Meta-Framework\",\n },\n ],\n path: \"skills/web-meta-framework-qwik\",\n },\n \"web-meta-framework-remix\": {\n id: \"web-meta-framework-remix\",\n slug: \"remix\",\n displayName: \"Remix\",\n description: \"Remix full-stack framework\",\n usageGuidance: \"Use when building Remix apps with loaders, actions, or useFetcher.\",\n category: \"web-meta-framework\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-meta-framework-nextjs\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-nuxt\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-sveltekit\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-astro\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-qwik\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [\n {\n skillIds: [\"web-framework-react\"],\n needsAny: false,\n reason: \"Remix is built on React\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-meta-framework-nextjs\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-nuxt\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-sveltekit\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-astro\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-qwik\",\n purpose: \"Meta-Framework\",\n },\n ],\n path: \"skills/web-meta-framework-remix\",\n },\n \"web-meta-framework-sveltekit\": {\n id: \"web-meta-framework-sveltekit\",\n slug: \"sveltekit\",\n displayName: \"SvelteKit\",\n description: \"SvelteKit full-stack framework\",\n usageGuidance:\n \"Use when building SvelteKit apps with load functions, form actions, or server hooks.\",\n category: \"web-meta-framework\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-meta-framework-nextjs\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-remix\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-nuxt\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-astro\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n {\n skillId: \"web-meta-framework-qwik\",\n reason: \"Meta-frameworks are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [\n {\n skillIds: [\"web-framework-svelte\"],\n needsAny: false,\n reason: \"SvelteKit is built on Svelte\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-meta-framework-nextjs\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-remix\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-nuxt\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-astro\",\n purpose: \"Meta-Framework\",\n },\n {\n skillId: \"web-meta-framework-qwik\",\n purpose: \"Meta-Framework\",\n },\n ],\n path: \"skills/web-meta-framework-sveltekit\",\n },\n \"web-meta-framework-vitepress\": {\n id: \"web-meta-framework-vitepress\",\n slug: \"vitepress\",\n displayName: \"VitePress\",\n description: \"VitePress documentation site generator\",\n usageGuidance:\n \"Use when building documentation sites with VitePress — configuring navigation, extending themes, writing data loaders, and customizing markdown rendering.\",\n category: \"web-docs\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"web-meta-framework-docusaurus\",\n purpose: \"Documentation Framework\",\n },\n ],\n path: \"skills/web-meta-framework-vitepress\",\n },\n \"web-mocks-msw\": {\n id: \"web-mocks-msw\",\n slug: \"msw\",\n displayName: \"MSW\",\n description: \"API mocking\",\n usageGuidance: \"Use when mocking APIs for development or testing with MSW handlers.\",\n category: \"web-mocking\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/web-mocks-msw\",\n },\n \"web-performance-web-performance\": {\n id: \"web-performance-web-performance\",\n slug: \"web-performance\",\n displayName: \"Frontend Performance\",\n description: \"Bundle and render optimization\",\n usageGuidance:\n \"Use when optimizing bundle size, render performance, or implementing memoization.\",\n category: \"web-performance\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/web-performance-web-performance\",\n },\n \"web-pwa-offline-first\": {\n id: \"web-pwa-offline-first\",\n slug: \"offline-first\",\n displayName: \"Offline First\",\n description: \"Offline-first patterns\",\n usageGuidance: \"Use when building offline-first apps with IndexedDB or sync queues.\",\n category: \"web-pwa\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/web-pwa-offline-first\",\n },\n \"web-pwa-service-workers\": {\n id: \"web-pwa-service-workers\",\n slug: \"service-workers\",\n displayName: \"Service Workers\",\n description: \"Offline caching strategies\",\n usageGuidance:\n \"Use when implementing service workers, caching strategies, or offline support.\",\n category: \"web-pwa\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/web-pwa-service-workers\",\n },\n \"web-realtime-socket-io\": {\n id: \"web-realtime-socket-io\",\n slug: \"socket-io\",\n displayName: \"Socket.IO\",\n description: \"Bidirectional real-time communication\",\n usageGuidance: \"Use when implementing Socket.IO client connections, rooms, or namespaces.\",\n category: \"web-realtime\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"web-realtime-websockets\",\n purpose: \"Realtime\",\n },\n {\n skillId: \"web-realtime-sse\",\n purpose: \"Realtime\",\n },\n ],\n path: \"skills/web-realtime-socket-io\",\n },\n \"web-realtime-sse\": {\n id: \"web-realtime-sse\",\n slug: \"sse\",\n displayName: \"Server-Sent Events\",\n description: \"Server-to-client streaming\",\n usageGuidance: \"Use when implementing Server-Sent Events for server-to-client streaming.\",\n category: \"web-streaming\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"web-realtime-websockets\",\n purpose: \"Realtime\",\n },\n {\n skillId: \"web-realtime-socket-io\",\n purpose: \"Realtime\",\n },\n ],\n path: \"skills/web-realtime-sse\",\n },\n \"web-realtime-websockets\": {\n id: \"web-realtime-websockets\",\n slug: \"websockets\",\n displayName: \"WebSockets\",\n description: \"Bidirectional real-time communication\",\n usageGuidance:\n \"Use when implementing WebSocket connections, reconnection, or message handling.\",\n category: \"web-realtime\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"web-realtime-socket-io\",\n purpose: \"Realtime\",\n },\n {\n skillId: \"web-realtime-sse\",\n purpose: \"Realtime\",\n },\n ],\n path: \"skills/web-realtime-websockets\",\n },\n \"web-routing-react-router\": {\n id: \"web-routing-react-router\",\n slug: \"react-router\",\n displayName: \"React Router\",\n description: \"Client-side and server-side routing for React applications\",\n usageGuidance:\n \"Use when building React apps with client-side routing — nested routes, loaders, actions, error boundaries, lazy loading, and URL-based state.\",\n category: \"web-routing\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-routing-tanstack-router\",\n reason: \"React client-side routers are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [\n {\n skillIds: [\"web-framework-react\"],\n needsAny: false,\n reason:\n \"React Router v7 Data Mode SPA skill — createBrowserRouter/RouterProvider are framework-owned (wrong) inside a Remix framework-mode app\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-routing-tanstack-router\",\n purpose: \"Routing (React)\",\n },\n ],\n path: \"skills/web-routing-react-router\",\n },\n \"web-routing-tanstack-router\": {\n id: \"web-routing-tanstack-router\",\n slug: \"tanstack-router\",\n displayName: \"TanStack Router\",\n description: \"Type-safe client-side routing for React\",\n usageGuidance:\n \"Use when building React SPAs with type-safe routing — file-based routes, search params validation, route loaders, code splitting, and nested layouts.\",\n category: \"web-routing\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-routing-react-router\",\n reason: \"React client-side routers are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [\n {\n skillIds: [\"web-framework-react\"],\n needsAny: false,\n reason: \"TanStack Router is a React routing library\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-routing-react-router\",\n purpose: \"Routing (React)\",\n },\n ],\n path: \"skills/web-routing-tanstack-router\",\n },\n \"web-server-state-react-query\": {\n id: \"web-server-state-react-query\",\n slug: \"react-query\",\n displayName: \"React Query\",\n description: \"Server state and caching\",\n usageGuidance:\n \"Use when fetching API data with React Query, generating API clients from OpenAPI specs with hey-api, or configuring query caching and error handling.\",\n category: \"web-server-state\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-data-fetching-swr\",\n reason: \"Both solve server state caching\",\n },\n ],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n \"mobile-framework-react-native\",\n ],\n needsAny: true,\n reason: \"TanStack Query's React adapter\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-data-fetching-swr\",\n purpose: \"Server State / Data Fetching\",\n },\n {\n skillId: \"web-data-fetching-trpc\",\n purpose: \"Server State / Data Fetching\",\n },\n ],\n path: \"skills/web-server-state-react-query\",\n },\n \"web-state-jotai\": {\n id: \"web-state-jotai\",\n slug: \"jotai\",\n displayName: \"Jotai\",\n description: \"Atomic client state\",\n usageGuidance: \"Use when managing atomic state with bottom-up composition.\",\n category: \"web-client-state\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-state-zustand\",\n reason: \"React state management libraries are mutually exclusive\",\n },\n {\n skillId: \"web-state-redux-toolkit\",\n reason: \"React state management libraries are mutually exclusive\",\n },\n {\n skillId: \"web-state-mobx\",\n reason: \"React state management libraries are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n \"mobile-framework-react-native\",\n ],\n needsAny: true,\n reason: \"Jotai is a React atomic state library\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-state-zustand\",\n purpose: \"Client State (React)\",\n },\n {\n skillId: \"web-state-redux-toolkit\",\n purpose: \"Client State (React)\",\n },\n {\n skillId: \"web-state-mobx\",\n purpose: \"Client State (React)\",\n },\n ],\n path: \"skills/web-state-jotai\",\n },\n \"web-state-mobx\": {\n id: \"web-state-mobx\",\n slug: \"mobx\",\n displayName: \"MobX\",\n description: \"Observable reactive state management\",\n usageGuidance:\n \"Use when implementing client-side state with MobX observables, computed values, actions, reactions, or the observer HOC from mobx-react-lite. Not for server state or simple local UI state (use useState).\",\n category: \"web-client-state\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-state-zustand\",\n reason: \"React state management libraries are mutually exclusive\",\n },\n {\n skillId: \"web-state-redux-toolkit\",\n reason: \"React state management libraries are mutually exclusive\",\n },\n {\n skillId: \"web-state-jotai\",\n reason: \"React state management libraries are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n \"mobile-framework-react-native\",\n ],\n needsAny: true,\n reason: \"Skill teaches React/React Native patterns\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-state-zustand\",\n purpose: \"Client State (React)\",\n },\n {\n skillId: \"web-state-redux-toolkit\",\n purpose: \"Client State (React)\",\n },\n {\n skillId: \"web-state-jotai\",\n purpose: \"Client State (React)\",\n },\n ],\n path: \"skills/web-state-mobx\",\n },\n \"web-state-ngrx-signalstore\": {\n id: \"web-state-ngrx-signalstore\",\n slug: \"ngrx-signalstore\",\n displayName: \"NgRx SignalStore\",\n description: \"Angular signal-based state\",\n usageGuidance: \"Use when managing Angular state with Signals and SignalStore.\",\n category: \"web-client-state\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"web-framework-angular-standalone\"],\n needsAny: false,\n reason: \"NgRx SignalStore is Angular only\",\n },\n ],\n alternatives: [],\n path: \"skills/web-state-ngrx-signalstore\",\n },\n \"web-state-pinia\": {\n id: \"web-state-pinia\",\n slug: \"pinia\",\n displayName: \"Pinia\",\n description: \"Vue client state\",\n usageGuidance: \"Use when managing state in Vue apps with Options or Setup stores.\",\n category: \"web-client-state\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"web-framework-vue-composition-api\", \"web-meta-framework-nuxt\"],\n needsAny: true,\n reason: \"Pinia is Vue only\",\n },\n ],\n alternatives: [],\n path: \"skills/web-state-pinia\",\n },\n \"web-state-redux-toolkit\": {\n id: \"web-state-redux-toolkit\",\n slug: \"redux-toolkit\",\n displayName: \"Redux Toolkit\",\n description: \"Enterprise client state\",\n usageGuidance: \"Use when managing enterprise-scale state, needing DevTools, or RTK Query.\",\n category: \"web-client-state\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-state-zustand\",\n reason: \"React state management libraries are mutually exclusive\",\n },\n {\n skillId: \"web-state-mobx\",\n reason: \"React state management libraries are mutually exclusive\",\n },\n {\n skillId: \"web-state-jotai\",\n reason: \"React state management libraries are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n \"mobile-framework-react-native\",\n ],\n needsAny: true,\n reason: \"Skill teaches React/React Native patterns\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-state-zustand\",\n purpose: \"Client State (React)\",\n },\n {\n skillId: \"web-state-mobx\",\n purpose: \"Client State (React)\",\n },\n {\n skillId: \"web-state-jotai\",\n purpose: \"Client State (React)\",\n },\n ],\n path: \"skills/web-state-redux-toolkit\",\n },\n \"web-state-zustand\": {\n id: \"web-state-zustand\",\n slug: \"zustand\",\n displayName: \"Zustand\",\n description: \"Lightweight client state\",\n usageGuidance:\n \"Use when managing global UI state, replacing Context misuse, or handling cross-component state.\",\n category: \"web-client-state\",\n author: \"@vince\",\n conflictsWith: [\n {\n skillId: \"web-state-redux-toolkit\",\n reason: \"React state management libraries are mutually exclusive\",\n },\n {\n skillId: \"web-state-mobx\",\n reason: \"React state management libraries are mutually exclusive\",\n },\n {\n skillId: \"web-state-jotai\",\n reason: \"React state management libraries are mutually exclusive\",\n },\n ],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n \"mobile-framework-react-native\",\n ],\n needsAny: true,\n reason: \"Skill teaches React/React Native patterns\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-state-redux-toolkit\",\n purpose: \"Client State (React)\",\n },\n {\n skillId: \"web-state-mobx\",\n purpose: \"Client State (React)\",\n },\n {\n skillId: \"web-state-jotai\",\n purpose: \"Client State (React)\",\n },\n ],\n path: \"skills/web-state-zustand\",\n },\n \"web-styling-cva\": {\n id: \"web-styling-cva\",\n slug: \"cva\",\n displayName: \"CVA\",\n description: \"Component variant styling\",\n usageGuidance: \"Use when building component variants with class-variance-authority.\",\n category: \"web-styling\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/web-styling-cva\",\n },\n \"web-styling-design-tokens\": {\n id: \"web-styling-design-tokens\",\n slug: \"design-tokens\",\n displayName: \"Design Tokens\",\n description: \"Token tiers, naming, and build pipeline\",\n usageGuidance:\n \"Use when authoring or restructuring a design token system - defining primitive, semantic and component tiers, naming tokens, delivering them as CSS custom properties, or building them from DTCG source with a token pipeline.\",\n category: \"web-styling\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/web-styling-design-tokens\",\n },\n \"web-styling-scss-modules\": {\n id: \"web-styling-scss-modules\",\n slug: \"scss-modules\",\n displayName: \"SCSS Modules\",\n description: \"SCSS Modules styling\",\n usageGuidance: \"Use when styling with SCSS Modules, design tokens, or CSS cascade layers.\",\n category: \"web-styling\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"web-styling-tailwind\",\n purpose: \"Styling\",\n },\n ],\n path: \"skills/web-styling-scss-modules\",\n },\n \"web-styling-tailwind\": {\n id: \"web-styling-tailwind\",\n slug: \"tailwind\",\n displayName: \"Tailwind CSS\",\n description: \"Utility-first CSS framework v4\",\n usageGuidance:\n \"Use when styling with Tailwind CSS v4 utility classes, configuring themes with @theme directive, implementing dark mode, responsive design, custom utilities with @utility, or composing component classes with cn() and tailwind-merge.\",\n category: \"web-styling\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"web-styling-scss-modules\",\n purpose: \"Styling\",\n },\n ],\n path: \"skills/web-styling-tailwind\",\n },\n \"web-styling-theming\": {\n id: \"web-styling-theming\",\n slug: \"theming\",\n displayName: \"Runtime Theming\",\n description: \"Runtime light/dark and multi-brand theme switching\",\n usageGuidance:\n \"Use when applying a theme system to a live app - wiring prefers-color-scheme and an explicit override, eliminating theme flash on first paint, persisting a light/dark/system preference, switching semantic token values per scope, or adding multi-brand and nested theme scopes.\",\n category: \"web-styling\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/web-styling-theming\",\n },\n \"web-testing-cypress-e2e\": {\n id: \"web-testing-cypress-e2e\",\n slug: \"cypress-e2e\",\n displayName: \"Cypress\",\n description: \"E2E browser testing\",\n usageGuidance: \"Use when writing Cypress E2E tests, custom commands, or component tests.\",\n category: \"web-e2e\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"web-testing-playwright-e2e\",\n purpose: \"E2E Testing\",\n },\n ],\n path: \"skills/web-testing-cypress-e2e\",\n },\n \"web-testing-playwright-e2e\": {\n id: \"web-testing-playwright-e2e\",\n slug: \"playwright-e2e\",\n displayName: \"Playwright\",\n description: \"E2E browser testing\",\n usageGuidance: \"Use when writing E2E tests, Page Object Models, or visual regression tests.\",\n category: \"web-e2e\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [\n {\n skillId: \"web-testing-cypress-e2e\",\n purpose: \"E2E Testing\",\n },\n ],\n path: \"skills/web-testing-playwright-e2e\",\n },\n \"web-testing-react-testing-library\": {\n id: \"web-testing-react-testing-library\",\n slug: \"react-testing-library\",\n displayName: \"React Testing Library\",\n description: \"React component testing\",\n usageGuidance: \"Use when testing React components with user-centric queries.\",\n category: \"web-testing\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason: \"React Testing Library is React only\",\n },\n ],\n alternatives: [],\n path: \"skills/web-testing-react-testing-library\",\n },\n \"web-testing-visual-regression\": {\n id: \"web-testing-visual-regression\",\n slug: \"visual-regression\",\n displayName: \"Visual Regression\",\n description: \"Screenshot baselines and diff review\",\n usageGuidance:\n \"Use when catching unintended visual changes with screenshot baselines, diff review, or visual CI jobs.\",\n category: \"web-testing\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/web-testing-visual-regression\",\n },\n \"web-testing-vitest\": {\n id: \"web-testing-vitest\",\n slug: \"vitest\",\n displayName: \"Vitest\",\n description: \"Vite-native test runner\",\n usageGuidance:\n \"Use when writing unit tests, integration tests, configuring Vitest, or using vi.fn/vi.mock/vi.spyOn.\",\n category: \"web-testing\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/web-testing-vitest\",\n },\n \"web-testing-vue-test-utils\": {\n id: \"web-testing-vue-test-utils\",\n slug: \"vue-test-utils\",\n displayName: \"Vue Test Utils\",\n description: \"Vue component testing\",\n usageGuidance:\n \"Use when testing Vue components with mount, shallowMount, or testing composables.\",\n category: \"web-testing\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"web-framework-vue-composition-api\", \"web-meta-framework-nuxt\"],\n needsAny: true,\n reason: \"Vue Test Utils is Vue only\",\n },\n ],\n alternatives: [],\n path: \"skills/web-testing-vue-test-utils\",\n },\n \"web-tooling-component-library\": {\n id: \"web-tooling-component-library\",\n slug: \"component-library\",\n displayName: \"Component Library Packaging\",\n description: \"Packaging React components as a library\",\n usageGuidance:\n 'Use when shipping styled, client-interactive React components as a consumable package — choosing a style delivery contract, marking styles side-effectful, layering library CSS so consumer overrides win, preserving \"use client\" through the build, declaring peer dependency ranges, and splitting server-safe from client entries.',\n category: \"web-tooling\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason:\n \"Packaging React components — react/react-dom peerDependencies and 'use client' preservation are the skill's critical requirements\",\n },\n ],\n alternatives: [],\n path: \"skills/web-tooling-component-library\",\n },\n \"web-tooling-storybook\": {\n id: \"web-tooling-storybook\",\n slug: \"storybook\",\n displayName: \"Storybook\",\n description: \"Component documentation\",\n usageGuidance:\n \"Use when documenting components with Storybook, writing stories, or interaction tests.\",\n category: \"web-tooling\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-framework-vue-composition-api\",\n \"web-framework-angular-standalone\",\n \"web-framework-solidjs\",\n \"web-framework-svelte\",\n \"web-meta-framework-qwik\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n \"web-meta-framework-nuxt\",\n \"web-meta-framework-sveltekit\",\n ],\n needsAny: true,\n reason: \"Storybook requires a UI framework\",\n },\n ],\n alternatives: [],\n path: \"skills/web-tooling-storybook\",\n },\n \"web-tooling-vite\": {\n id: \"web-tooling-vite\",\n slug: \"vite\",\n displayName: \"Vite\",\n description: \"Vite build tool configuration\",\n usageGuidance:\n \"Use when configuring Vite build tool, path aliases, vendor chunk splitting, environment-specific builds, or migrating to Rolldown.\",\n category: \"web-tooling\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/web-tooling-vite\",\n },\n \"web-ui-ant-design\": {\n id: \"web-ui-ant-design\",\n slug: \"ant-design\",\n displayName: \"Ant Design\",\n description: \"Ant Design enterprise UI library for React\",\n usageGuidance:\n \"Use when building React UIs with Ant Design — ConfigProvider theming, Table, Form, Layout, data entry components, and enterprise design patterns.\",\n category: \"web-ui-kit\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason: \"Ant Design is a React component library\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-ui-shadcn-ui\",\n purpose: \"UI Components (React)\",\n },\n {\n skillId: \"web-ui-mui\",\n purpose: \"UI Components (React)\",\n },\n {\n skillId: \"web-ui-chakra-ui\",\n purpose: \"UI Components (React)\",\n },\n {\n skillId: \"web-ui-mantine\",\n purpose: \"UI Components (React)\",\n },\n ],\n path: \"skills/web-ui-ant-design\",\n },\n \"web-ui-base-ui\": {\n id: \"web-ui-base-ui\",\n slug: \"base-ui\",\n displayName: \"Base UI\",\n description: \"Unstyled accessible React primitives\",\n usageGuidance:\n \"Use when building accessible UI with Base UI (@base-ui/react) — part-based anatomy (Portal, Positioner, Popup), the render prop for polymorphism, useRender and mergeProps, data-attribute state styling, controlled state with eventDetails cancelation, and Field/Fieldset/Form validation.\",\n category: \"web-ui-components\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason: \"Base UI primitives are React-only (@base-ui/react)\",\n },\n ],\n alternatives: [],\n path: \"skills/web-ui-base-ui\",\n },\n \"web-ui-chakra-ui\": {\n id: \"web-ui-chakra-ui\",\n slug: \"chakra-ui\",\n displayName: \"Chakra UI\",\n description: \"Accessible React components with style props and theming\",\n usageGuidance:\n \"Use when building React UIs with Chakra UI — style props, responsive design, theming, accessible components, and composable component patterns.\",\n category: \"web-ui-kit\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason: \"Chakra UI is a React component library\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-ui-shadcn-ui\",\n purpose: \"UI Components (React)\",\n },\n {\n skillId: \"web-ui-mui\",\n purpose: \"UI Components (React)\",\n },\n {\n skillId: \"web-ui-mantine\",\n purpose: \"UI Components (React)\",\n },\n {\n skillId: \"web-ui-ant-design\",\n purpose: \"UI Components (React)\",\n },\n ],\n path: \"skills/web-ui-chakra-ui\",\n },\n \"web-ui-headless-ui\": {\n id: \"web-ui-headless-ui\",\n slug: \"headless-ui\",\n displayName: \"Headless UI\",\n description: \"Unstyled accessible UI components by Tailwind Labs\",\n usageGuidance:\n \"Use when building accessible UI with Headless UI — Dialog, Menu, Listbox, Combobox, Popover, Tabs, Disclosure, and other unstyled primitives designed for Tailwind CSS.\",\n category: \"web-ui-components\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason: \"Headless UI v2 is React only\",\n },\n ],\n alternatives: [],\n path: \"skills/web-ui-headless-ui\",\n },\n \"web-ui-mantine\": {\n id: \"web-ui-mantine\",\n slug: \"mantine\",\n displayName: \"Mantine\",\n description: \"Full-featured React components with hooks, forms, theming\",\n usageGuidance:\n \"Use when building React UIs with Mantine — 100+ components, CSS modules styling, theme customization, built-in hooks, form management with @mantine/form, and notification system.\",\n category: \"web-ui-kit\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason: \"Mantine is a React component library\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-ui-shadcn-ui\",\n purpose: \"UI Components (React)\",\n },\n {\n skillId: \"web-ui-mui\",\n purpose: \"UI Components (React)\",\n },\n {\n skillId: \"web-ui-chakra-ui\",\n purpose: \"UI Components (React)\",\n },\n {\n skillId: \"web-ui-ant-design\",\n purpose: \"UI Components (React)\",\n },\n ],\n path: \"skills/web-ui-mantine\",\n },\n \"web-ui-mui\": {\n id: \"web-ui-mui\",\n slug: \"mui\",\n displayName: \"MUI (Material UI)\",\n description: \"Material UI component library for React\",\n usageGuidance:\n \"Use when building React UIs with MUI — theming, component customization, sx prop, styled API, data grids, date pickers, and Material Design patterns.\",\n category: \"web-ui-kit\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason: \"MUI is a React component library\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-ui-shadcn-ui\",\n purpose: \"UI Components (React)\",\n },\n {\n skillId: \"web-ui-chakra-ui\",\n purpose: \"UI Components (React)\",\n },\n {\n skillId: \"web-ui-mantine\",\n purpose: \"UI Components (React)\",\n },\n {\n skillId: \"web-ui-ant-design\",\n purpose: \"UI Components (React)\",\n },\n ],\n path: \"skills/web-ui-mui\",\n },\n \"web-ui-radix-ui\": {\n id: \"web-ui-radix-ui\",\n slug: \"radix-ui\",\n displayName: \"Radix UI\",\n description: \"Accessible UI primitives\",\n usageGuidance:\n \"Use when building accessible overlay components (dialogs, popovers, dropdowns, tooltips), compound component APIs, keyboard navigation, focus management, or polymorphic components with asChild and Slot patterns.\",\n category: \"web-ui-components\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason: \"Radix UI primitives are React-specific\",\n },\n ],\n alternatives: [],\n path: \"skills/web-ui-radix-ui\",\n },\n \"web-ui-shadcn-ui\": {\n id: \"web-ui-shadcn-ui\",\n slug: \"shadcn-ui\",\n displayName: \"shadcn/ui\",\n description: \"Tailwind component library\",\n usageGuidance: \"Use when using shadcn/ui components, theming, or customization.\",\n category: \"web-ui-kit\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason: \"shadcn/ui requires a React-based framework\",\n },\n {\n skillIds: [\"web-styling-tailwind\"],\n needsAny: false,\n reason: \"shadcn/ui requires Tailwind CSS\",\n },\n ],\n alternatives: [\n {\n skillId: \"web-ui-mui\",\n purpose: \"UI Components (React)\",\n },\n {\n skillId: \"web-ui-chakra-ui\",\n purpose: \"UI Components (React)\",\n },\n {\n skillId: \"web-ui-mantine\",\n purpose: \"UI Components (React)\",\n },\n {\n skillId: \"web-ui-ant-design\",\n purpose: \"UI Components (React)\",\n },\n ],\n path: \"skills/web-ui-shadcn-ui\",\n },\n \"web-ui-tanstack-table\": {\n id: \"web-ui-tanstack-table\",\n slug: \"tanstack-table\",\n displayName: \"TanStack Table\",\n description: \"Data table component\",\n usageGuidance: \"Use when building data tables with sorting, filtering, or pagination.\",\n category: \"web-ui-components\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-remix\",\n ],\n needsAny: true,\n reason: \"Skill teaches @tanstack/react-table patterns\",\n },\n ],\n alternatives: [],\n path: \"skills/web-ui-tanstack-table\",\n },\n \"web-ui-vuetify\": {\n id: \"web-ui-vuetify\",\n slug: \"vuetify\",\n displayName: \"Vuetify\",\n description: \"Material Design component library for Vue 3\",\n usageGuidance:\n \"Use when building Vue 3 UIs with Vuetify — theming, global defaults, data tables, form validation, SASS variable customization, composables, and Material Design 3 patterns.\",\n category: \"web-ui-kit\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"web-framework-vue-composition-api\", \"web-meta-framework-nuxt\"],\n needsAny: true,\n reason: \"Vuetify is Vue only\",\n },\n ],\n alternatives: [],\n path: \"skills/web-ui-vuetify\",\n },\n \"web-utilities-date-fns\": {\n id: \"web-utilities-date-fns\",\n slug: \"date-fns\",\n displayName: \"date-fns\",\n description: \"Date utilities\",\n usageGuidance: \"Use when formatting, parsing, or manipulating dates with date-fns.\",\n category: \"web-utilities\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/web-utilities-date-fns\",\n },\n \"web-utilities-native-js\": {\n id: \"web-utilities-native-js\",\n slug: \"native-js\",\n displayName: \"Native JS\",\n description: \"Native JS utilities\",\n usageGuidance: \"Use when using modern JS methods instead of lodash utilities.\",\n category: \"web-utilities\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/web-utilities-native-js\",\n },\n \"web-utilities-rxjs\": {\n id: \"web-utilities-rxjs\",\n slug: \"rxjs\",\n displayName: \"RxJS\",\n description: \"Reactive programming — Observables, operators, streams\",\n usageGuidance:\n \"Use when handling complex async flows with RxJS — Observables, operators (map, filter, switchMap, mergeMap), Subjects, error handling, unsubscription, and reactive patterns for event streams and HTTP requests.\",\n category: \"web-utilities\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [],\n alternatives: [],\n path: \"skills/web-utilities-rxjs\",\n },\n \"web-utilities-vueuse\": {\n id: \"web-utilities-vueuse\",\n slug: \"vueuse\",\n displayName: \"Vueuse\",\n description: \"Vue Composition API utilities — 250+ composable functions\",\n usageGuidance:\n \"Use when building Vue apps with VueUse — browser APIs (useLocalStorage, useClipboard, useFetch), sensors (useMouse, useScroll), animations, state management helpers, and component utilities.\",\n category: \"web-utilities\",\n author: \"@vince\",\n conflictsWith: [],\n discourages: [],\n requires: [\n {\n skillIds: [\"web-framework-vue-composition-api\", \"web-meta-framework-nuxt\"],\n needsAny: true,\n reason: \"VueUse composables require Vue 3\",\n },\n ],\n alternatives: [],\n path: \"skills/web-utilities-vueuse\",\n },\n },\n suggestedStacks: [\n {\n id: \"nextjs-fullstack\",\n name: \"Next.js Full-Stack\",\n description: \"Hono, Drizzle, Better Auth, Zustand\",\n skills: {\n \"web-developer\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n \"web-tooling\": [\"web-tooling-vite\"],\n },\n \"api-developer\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n \"cli-developer\": {\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n reviewer: {\n \"meta-reviewing\": [\"meta-reviewing-reviewing\", \"meta-reviewing-cli-reviewing\"],\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n },\n \"web-tester\": {\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-e2e\": [\"web-testing-playwright-e2e\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n },\n pm: {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n },\n \"web-researcher\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n },\n \"api-researcher\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n },\n \"agent-summoner\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"skill-summoner\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"codex-keeper\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"cli-tester\": {},\n },\n allSkillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-styling-scss-modules\",\n \"web-state-zustand\",\n \"web-server-state-react-query\",\n \"web-testing-vitest\",\n \"web-mocks-msw\",\n \"web-accessibility-web-accessibility\",\n \"shared-tooling-typescript-config\",\n \"shared-tooling-git-hooks\",\n \"shared-tooling-eslint-prettier\",\n \"web-tooling-vite\",\n \"api-framework-hono\",\n \"api-database-drizzle\",\n \"api-auth-better-auth-drizzle-hono\",\n \"api-observability-axiom-pino-sentry\",\n \"api-analytics-posthog-analytics\",\n \"api-email-resend-react-email\",\n \"infra-ci-cd-github-actions\",\n \"cli-framework-oclif-ink\",\n \"meta-reviewing-reviewing\",\n \"meta-reviewing-cli-reviewing\",\n \"web-testing-playwright-e2e\",\n ],\n philosophy: \"Ship fast, iterate faster\",\n },\n {\n id: \"nextjs-t3-stack\",\n name: \"Next.js T3 Stack\",\n description: \"tRPC, Prisma, NextAuth, Tailwind\",\n skills: {\n \"web-developer\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-rpc\": [\"web-data-fetching-trpc\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n \"web-tooling\": [\"web-tooling-vite\"],\n },\n \"api-developer\": {\n \"api-orm\": [\"api-database-prisma\"],\n \"api-auth\": [\"api-auth-nextauth\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n reviewer: {\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-rpc\": [\"web-data-fetching-trpc\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-orm\": [\"api-database-prisma\"],\n \"api-auth\": [\"api-auth-nextauth\"],\n },\n pm: {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-rpc\": [\"web-data-fetching-trpc\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-orm\": [\"api-database-prisma\"],\n \"api-auth\": [\"api-auth-nextauth\"],\n },\n \"web-researcher\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-rpc\": [\"web-data-fetching-trpc\"],\n \"web-testing\": [\"web-testing-vitest\"],\n },\n \"api-researcher\": {\n \"api-orm\": [\"api-database-prisma\"],\n \"api-auth\": [\"api-auth-nextauth\"],\n },\n \"agent-summoner\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-rpc\": [\"web-data-fetching-trpc\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-orm\": [\"api-database-prisma\"],\n \"api-auth\": [\"api-auth-nextauth\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"skill-summoner\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-rpc\": [\"web-data-fetching-trpc\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-orm\": [\"api-database-prisma\"],\n \"api-auth\": [\"api-auth-nextauth\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"codex-keeper\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-rpc\": [\"web-data-fetching-trpc\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-orm\": [\"api-database-prisma\"],\n \"api-auth\": [\"api-auth-nextauth\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"web-tester\": {\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-e2e\": [\"web-testing-playwright-e2e\"],\n },\n },\n allSkillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-styling-tailwind\",\n \"web-data-fetching-trpc\",\n \"web-testing-vitest\",\n \"shared-tooling-typescript-config\",\n \"shared-tooling-git-hooks\",\n \"shared-tooling-eslint-prettier\",\n \"web-tooling-vite\",\n \"api-database-prisma\",\n \"api-auth-nextauth\",\n \"meta-reviewing-reviewing\",\n \"web-testing-playwright-e2e\",\n ],\n philosophy: \"End-to-end type safety with great DX\",\n },\n {\n id: \"nextjs-supabase-fullstack\",\n name: \"Next.js Supabase Full-Stack\",\n description: \"Supabase, Drizzle, Better Auth\",\n skills: {\n \"web-developer\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n \"web-tooling\": [\"web-tooling-vite\"],\n },\n \"api-developer\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-baas\": [\"api-baas-supabase\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n \"cli-developer\": {\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n reviewer: {\n \"meta-reviewing\": [\"meta-reviewing-reviewing\", \"meta-reviewing-cli-reviewing\"],\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-baas\": [\"api-baas-supabase\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n },\n \"web-tester\": {\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-e2e\": [\"web-testing-playwright-e2e\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n },\n pm: {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-baas\": [\"api-baas-supabase\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n },\n \"web-researcher\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n },\n \"api-researcher\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-baas\": [\"api-baas-supabase\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n },\n \"agent-summoner\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-baas\": [\"api-baas-supabase\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"skill-summoner\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-baas\": [\"api-baas-supabase\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"codex-keeper\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-baas\": [\"api-baas-supabase\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"cli-tester\": {},\n },\n allSkillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-styling-scss-modules\",\n \"web-state-zustand\",\n \"web-server-state-react-query\",\n \"web-testing-vitest\",\n \"web-mocks-msw\",\n \"web-accessibility-web-accessibility\",\n \"shared-tooling-typescript-config\",\n \"shared-tooling-git-hooks\",\n \"shared-tooling-eslint-prettier\",\n \"web-tooling-vite\",\n \"api-framework-hono\",\n \"api-database-drizzle\",\n \"api-auth-better-auth-drizzle-hono\",\n \"api-baas-supabase\",\n \"api-observability-axiom-pino-sentry\",\n \"api-analytics-posthog-analytics\",\n \"api-email-resend-react-email\",\n \"infra-ci-cd-github-actions\",\n \"cli-framework-oclif-ink\",\n \"meta-reviewing-reviewing\",\n \"meta-reviewing-cli-reviewing\",\n \"web-testing-playwright-e2e\",\n ],\n philosophy: \"Full-stack with Supabase backend-as-a-service\",\n },\n {\n id: \"nextjs-turborepo-fullstack\",\n name: \"Next.js Turborepo Full-Stack\",\n description: \"Turborepo, pnpm Workspaces, Hono, Drizzle\",\n skills: {\n \"web-developer\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n \"web-tooling\": [\"web-tooling-vite\"],\n \"shared-monorepo\": [\"shared-monorepo-pnpm-workspaces\"],\n \"shared-task-runner\": [\"shared-monorepo-turborepo\"],\n },\n \"api-developer\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n \"shared-monorepo\": [\"shared-monorepo-pnpm-workspaces\"],\n \"shared-task-runner\": [\"shared-monorepo-turborepo\"],\n },\n \"cli-developer\": {\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n \"shared-monorepo\": [\"shared-monorepo-pnpm-workspaces\"],\n \"shared-task-runner\": [\"shared-monorepo-turborepo\"],\n },\n reviewer: {\n \"meta-reviewing\": [\"meta-reviewing-reviewing\", \"meta-reviewing-cli-reviewing\"],\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"shared-monorepo\": [\"shared-monorepo-pnpm-workspaces\"],\n \"shared-task-runner\": [\"shared-monorepo-turborepo\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n },\n \"web-tester\": {\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-e2e\": [\"web-testing-playwright-e2e\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"shared-monorepo\": [\"shared-monorepo-pnpm-workspaces\"],\n \"shared-task-runner\": [\"shared-monorepo-turborepo\"],\n },\n pm: {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"shared-monorepo\": [\"shared-monorepo-pnpm-workspaces\"],\n \"shared-task-runner\": [\"shared-monorepo-turborepo\"],\n },\n \"web-researcher\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"shared-monorepo\": [\"shared-monorepo-pnpm-workspaces\"],\n \"shared-task-runner\": [\"shared-monorepo-turborepo\"],\n },\n \"api-researcher\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"shared-monorepo\": [\"shared-monorepo-pnpm-workspaces\"],\n \"shared-task-runner\": [\"shared-monorepo-turborepo\"],\n },\n \"agent-summoner\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"shared-monorepo\": [\"shared-monorepo-pnpm-workspaces\"],\n \"shared-task-runner\": [\"shared-monorepo-turborepo\"],\n },\n \"skill-summoner\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"shared-monorepo\": [\"shared-monorepo-pnpm-workspaces\"],\n \"shared-task-runner\": [\"shared-monorepo-turborepo\"],\n },\n \"codex-keeper\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"shared-monorepo\": [\"shared-monorepo-pnpm-workspaces\"],\n \"shared-task-runner\": [\"shared-monorepo-turborepo\"],\n },\n \"cli-tester\": {},\n },\n allSkillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-styling-scss-modules\",\n \"web-state-zustand\",\n \"web-server-state-react-query\",\n \"web-testing-vitest\",\n \"web-mocks-msw\",\n \"web-accessibility-web-accessibility\",\n \"shared-tooling-typescript-config\",\n \"shared-tooling-git-hooks\",\n \"shared-tooling-eslint-prettier\",\n \"web-tooling-vite\",\n \"shared-monorepo-pnpm-workspaces\",\n \"shared-monorepo-turborepo\",\n \"api-framework-hono\",\n \"api-database-drizzle\",\n \"api-auth-better-auth-drizzle-hono\",\n \"api-observability-axiom-pino-sentry\",\n \"api-analytics-posthog-analytics\",\n \"api-email-resend-react-email\",\n \"infra-ci-cd-github-actions\",\n \"cli-framework-oclif-ink\",\n \"meta-reviewing-reviewing\",\n \"meta-reviewing-cli-reviewing\",\n \"web-testing-playwright-e2e\",\n ],\n philosophy: \"Monorepo architecture with Turborepo and pnpm\",\n },\n {\n id: \"react-old-school\",\n name: \"React Old School\",\n description: \"Redux Toolkit, SCSS Modules, Vite, Vitest\",\n skills: {\n \"web-developer\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-client-state\": [\"web-state-redux-toolkit\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-routing\": [\"web-routing-react-router\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n \"web-tooling\": [\"web-tooling-vite\"],\n },\n reviewer: {\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"web-framework\": [\"web-framework-react\"],\n \"web-client-state\": [\"web-state-redux-toolkit\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-routing\": [\"web-routing-react-router\"],\n \"web-testing\": [\"web-testing-vitest\"],\n },\n pm: {\n \"web-framework\": [\"web-framework-react\"],\n \"web-client-state\": [\"web-state-redux-toolkit\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-routing\": [\"web-routing-react-router\"],\n \"web-testing\": [\"web-testing-vitest\"],\n },\n \"web-researcher\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-client-state\": [\"web-state-redux-toolkit\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-routing\": [\"web-routing-react-router\"],\n \"web-testing\": [\"web-testing-vitest\"],\n },\n \"agent-summoner\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-client-state\": [\"web-state-redux-toolkit\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-routing\": [\"web-routing-react-router\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"skill-summoner\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-client-state\": [\"web-state-redux-toolkit\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-routing\": [\"web-routing-react-router\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"codex-keeper\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-client-state\": [\"web-state-redux-toolkit\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-routing\": [\"web-routing-react-router\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"web-tester\": {\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-e2e\": [\"web-testing-playwright-e2e\"],\n },\n },\n allSkillIds: [\n \"web-framework-react\",\n \"web-state-redux-toolkit\",\n \"web-styling-scss-modules\",\n \"web-routing-react-router\",\n \"web-testing-vitest\",\n \"shared-tooling-typescript-config\",\n \"shared-tooling-git-hooks\",\n \"shared-tooling-eslint-prettier\",\n \"web-tooling-vite\",\n \"meta-reviewing-reviewing\",\n \"web-testing-playwright-e2e\",\n ],\n philosophy: \"Classic React with proven patterns\",\n },\n {\n id: \"react-hono-fullstack\",\n name: \"React Hono Full-Stack\",\n description: \"Vite, Hono, Drizzle, Better Auth\",\n skills: {\n \"web-developer\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n \"web-tooling\": [\"web-tooling-vite\"],\n },\n \"api-developer\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n \"cli-developer\": {\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n reviewer: {\n \"meta-reviewing\": [\"meta-reviewing-reviewing\", \"meta-reviewing-cli-reviewing\"],\n \"web-framework\": [\"web-framework-react\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n },\n \"web-tester\": {\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-e2e\": [\"web-testing-playwright-e2e\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n },\n pm: {\n \"web-framework\": [\"web-framework-react\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n },\n \"web-researcher\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n },\n \"api-researcher\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n },\n \"agent-summoner\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"skill-summoner\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"codex-keeper\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-styling\": [\"web-styling-scss-modules\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"cli-tester\": {},\n },\n allSkillIds: [\n \"web-framework-react\",\n \"web-styling-scss-modules\",\n \"web-state-zustand\",\n \"web-server-state-react-query\",\n \"web-testing-vitest\",\n \"web-mocks-msw\",\n \"web-accessibility-web-accessibility\",\n \"shared-tooling-typescript-config\",\n \"shared-tooling-git-hooks\",\n \"shared-tooling-eslint-prettier\",\n \"web-tooling-vite\",\n \"api-framework-hono\",\n \"api-database-drizzle\",\n \"api-auth-better-auth-drizzle-hono\",\n \"api-observability-axiom-pino-sentry\",\n \"api-analytics-posthog-analytics\",\n \"api-email-resend-react-email\",\n \"infra-ci-cd-github-actions\",\n \"cli-framework-oclif-ink\",\n \"meta-reviewing-reviewing\",\n \"meta-reviewing-cli-reviewing\",\n \"web-testing-playwright-e2e\",\n ],\n philosophy: \"React SPA with Hono backend\",\n },\n {\n id: \"remix-fullstack\",\n name: \"Remix Full-Stack\",\n description: \"Hono, Drizzle, Better Auth\",\n skills: {\n \"web-developer\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-remix\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n \"web-tooling\": [\"web-tooling-vite\"],\n },\n \"api-developer\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n reviewer: {\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-remix\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n },\n pm: {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-remix\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n },\n \"web-researcher\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-remix\"],\n \"web-testing\": [\"web-testing-vitest\"],\n },\n \"api-researcher\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n },\n \"agent-summoner\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-remix\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"skill-summoner\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-remix\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"codex-keeper\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-remix\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"web-tester\": {\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-e2e\": [\"web-testing-playwright-e2e\"],\n },\n },\n allSkillIds: [\n \"web-framework-react\",\n \"web-meta-framework-remix\",\n \"web-testing-vitest\",\n \"shared-tooling-typescript-config\",\n \"shared-tooling-git-hooks\",\n \"shared-tooling-eslint-prettier\",\n \"web-tooling-vite\",\n \"api-framework-hono\",\n \"api-database-drizzle\",\n \"api-auth-better-auth-drizzle-hono\",\n \"api-observability-axiom-pino-sentry\",\n \"meta-reviewing-reviewing\",\n \"web-testing-playwright-e2e\",\n ],\n philosophy: \"Web standards and excellent forms handling\",\n },\n {\n id: \"sveltekit-fullstack\",\n name: \"SvelteKit Full-Stack\",\n description: \"Hono, Drizzle, Better Auth\",\n skills: {\n \"web-developer\": {\n \"web-framework\": [\"web-framework-svelte\"],\n \"web-meta-framework\": [\"web-meta-framework-sveltekit\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n \"web-tooling\": [\"web-tooling-vite\"],\n },\n \"api-developer\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n reviewer: {\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"web-framework\": [\"web-framework-svelte\"],\n \"web-meta-framework\": [\"web-meta-framework-sveltekit\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n },\n pm: {\n \"web-framework\": [\"web-framework-svelte\"],\n \"web-meta-framework\": [\"web-meta-framework-sveltekit\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n },\n \"web-researcher\": {\n \"web-framework\": [\"web-framework-svelte\"],\n \"web-meta-framework\": [\"web-meta-framework-sveltekit\"],\n \"web-testing\": [\"web-testing-vitest\"],\n },\n \"api-researcher\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n },\n \"agent-summoner\": {\n \"web-framework\": [\"web-framework-svelte\"],\n \"web-meta-framework\": [\"web-meta-framework-sveltekit\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"skill-summoner\": {\n \"web-framework\": [\"web-framework-svelte\"],\n \"web-meta-framework\": [\"web-meta-framework-sveltekit\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"codex-keeper\": {\n \"web-framework\": [\"web-framework-svelte\"],\n \"web-meta-framework\": [\"web-meta-framework-sveltekit\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"web-tester\": {\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-e2e\": [\"web-testing-playwright-e2e\"],\n },\n },\n allSkillIds: [\n \"web-framework-svelte\",\n \"web-meta-framework-sveltekit\",\n \"web-testing-vitest\",\n \"shared-tooling-typescript-config\",\n \"shared-tooling-git-hooks\",\n \"shared-tooling-eslint-prettier\",\n \"web-tooling-vite\",\n \"api-framework-hono\",\n \"api-database-drizzle\",\n \"api-auth-better-auth-drizzle-hono\",\n \"api-observability-axiom-pino-sentry\",\n \"meta-reviewing-reviewing\",\n \"web-testing-playwright-e2e\",\n ],\n philosophy: \"Write less, do more with compiler magic\",\n },\n {\n id: \"solidjs-fullstack\",\n name: \"SolidJS Full-Stack\",\n description: \"Hono, Drizzle, Better Auth, Vitest\",\n skills: {\n \"web-developer\": {\n \"web-framework\": [\"web-framework-solidjs\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n \"web-tooling\": [\"web-tooling-vite\"],\n },\n \"api-developer\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n reviewer: {\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"web-framework\": [\"web-framework-solidjs\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n },\n pm: {\n \"web-framework\": [\"web-framework-solidjs\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n },\n \"web-researcher\": {\n \"web-framework\": [\"web-framework-solidjs\"],\n \"web-testing\": [\"web-testing-vitest\"],\n },\n \"api-researcher\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n },\n \"agent-summoner\": {\n \"web-framework\": [\"web-framework-solidjs\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"skill-summoner\": {\n \"web-framework\": [\"web-framework-solidjs\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"codex-keeper\": {\n \"web-framework\": [\"web-framework-solidjs\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"web-tester\": {\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-e2e\": [\"web-testing-playwright-e2e\"],\n },\n },\n allSkillIds: [\n \"web-framework-solidjs\",\n \"web-testing-vitest\",\n \"shared-tooling-typescript-config\",\n \"shared-tooling-git-hooks\",\n \"shared-tooling-eslint-prettier\",\n \"web-tooling-vite\",\n \"api-framework-hono\",\n \"api-database-drizzle\",\n \"api-auth-better-auth-drizzle-hono\",\n \"api-observability-axiom-pino-sentry\",\n \"meta-reviewing-reviewing\",\n \"web-testing-playwright-e2e\",\n ],\n philosophy: \"Maximum performance with minimal overhead\",\n },\n {\n id: \"astro-content-fullstack\",\n name: \"Astro Content Full-Stack\",\n description: \"Hono, Drizzle\",\n skills: {\n \"web-developer\": {\n \"web-meta-framework\": [\"web-meta-framework-astro\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n \"web-tooling\": [\"web-tooling-vite\"],\n },\n \"api-developer\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-cms\": [\"api-cms-sanity\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n reviewer: {\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"web-meta-framework\": [\"web-meta-framework-astro\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-cms\": [\"api-cms-sanity\"],\n },\n pm: {\n \"web-meta-framework\": [\"web-meta-framework-astro\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-cms\": [\"api-cms-sanity\"],\n },\n \"web-researcher\": {\n \"web-meta-framework\": [\"web-meta-framework-astro\"],\n \"web-testing\": [\"web-testing-vitest\"],\n },\n \"api-researcher\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-cms\": [\"api-cms-sanity\"],\n },\n \"agent-summoner\": {\n \"web-meta-framework\": [\"web-meta-framework-astro\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-cms\": [\"api-cms-sanity\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"skill-summoner\": {\n \"web-meta-framework\": [\"web-meta-framework-astro\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-cms\": [\"api-cms-sanity\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"codex-keeper\": {\n \"web-meta-framework\": [\"web-meta-framework-astro\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-cms\": [\"api-cms-sanity\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"web-tester\": {\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-e2e\": [\"web-testing-playwright-e2e\"],\n },\n },\n allSkillIds: [\n \"web-meta-framework-astro\",\n \"web-testing-vitest\",\n \"shared-tooling-typescript-config\",\n \"shared-tooling-git-hooks\",\n \"shared-tooling-eslint-prettier\",\n \"web-tooling-vite\",\n \"api-framework-hono\",\n \"api-database-drizzle\",\n \"api-observability-axiom-pino-sentry\",\n \"api-cms-sanity\",\n \"meta-reviewing-reviewing\",\n \"web-testing-playwright-e2e\",\n ],\n philosophy: \"Ship less JavaScript, faster by default\",\n },\n {\n id: \"vue-modern-fullstack\",\n name: \"Vue Modern Full-Stack\",\n description: \"Pinia, Hono, Drizzle, Better Auth\",\n skills: {\n \"web-developer\": {\n \"web-framework\": [\"web-framework-vue-composition-api\"],\n \"web-client-state\": [\"web-state-pinia\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n \"web-tooling\": [\"web-tooling-vite\"],\n },\n \"api-developer\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n reviewer: {\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"web-framework\": [\"web-framework-vue-composition-api\"],\n \"web-client-state\": [\"web-state-pinia\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n },\n pm: {\n \"web-framework\": [\"web-framework-vue-composition-api\"],\n \"web-client-state\": [\"web-state-pinia\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n },\n \"web-researcher\": {\n \"web-framework\": [\"web-framework-vue-composition-api\"],\n \"web-client-state\": [\"web-state-pinia\"],\n \"web-testing\": [\"web-testing-vitest\"],\n },\n \"api-researcher\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n },\n \"agent-summoner\": {\n \"web-framework\": [\"web-framework-vue-composition-api\"],\n \"web-client-state\": [\"web-state-pinia\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"skill-summoner\": {\n \"web-framework\": [\"web-framework-vue-composition-api\"],\n \"web-client-state\": [\"web-state-pinia\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"codex-keeper\": {\n \"web-framework\": [\"web-framework-vue-composition-api\"],\n \"web-client-state\": [\"web-state-pinia\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"web-tester\": {\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-e2e\": [\"web-testing-playwright-e2e\"],\n },\n },\n allSkillIds: [\n \"web-framework-vue-composition-api\",\n \"web-state-pinia\",\n \"web-testing-vitest\",\n \"shared-tooling-typescript-config\",\n \"shared-tooling-git-hooks\",\n \"shared-tooling-eslint-prettier\",\n \"web-tooling-vite\",\n \"api-framework-hono\",\n \"api-database-drizzle\",\n \"api-auth-better-auth-drizzle-hono\",\n \"api-observability-axiom-pino-sentry\",\n \"meta-reviewing-reviewing\",\n \"web-testing-playwright-e2e\",\n ],\n philosophy: \"Progressive and approachable\",\n },\n {\n id: \"nuxt-fullstack\",\n name: \"Nuxt Full-Stack\",\n description: \"Hono, Drizzle, Better Auth\",\n skills: {\n \"web-developer\": {\n \"web-framework\": [\"web-framework-vue-composition-api\"],\n \"web-meta-framework\": [\"web-meta-framework-nuxt\"],\n \"web-client-state\": [\"web-state-pinia\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n \"web-tooling\": [\"web-tooling-vite\"],\n },\n \"api-developer\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n reviewer: {\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"web-framework\": [\"web-framework-vue-composition-api\"],\n \"web-meta-framework\": [\"web-meta-framework-nuxt\"],\n \"web-client-state\": [\"web-state-pinia\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n },\n pm: {\n \"web-framework\": [\"web-framework-vue-composition-api\"],\n \"web-meta-framework\": [\"web-meta-framework-nuxt\"],\n \"web-client-state\": [\"web-state-pinia\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n },\n \"web-researcher\": {\n \"web-framework\": [\"web-framework-vue-composition-api\"],\n \"web-meta-framework\": [\"web-meta-framework-nuxt\"],\n \"web-client-state\": [\"web-state-pinia\"],\n \"web-testing\": [\"web-testing-vitest\"],\n },\n \"api-researcher\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n },\n \"agent-summoner\": {\n \"web-framework\": [\"web-framework-vue-composition-api\"],\n \"web-meta-framework\": [\"web-meta-framework-nuxt\"],\n \"web-client-state\": [\"web-state-pinia\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"skill-summoner\": {\n \"web-framework\": [\"web-framework-vue-composition-api\"],\n \"web-meta-framework\": [\"web-meta-framework-nuxt\"],\n \"web-client-state\": [\"web-state-pinia\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"codex-keeper\": {\n \"web-framework\": [\"web-framework-vue-composition-api\"],\n \"web-meta-framework\": [\"web-meta-framework-nuxt\"],\n \"web-client-state\": [\"web-state-pinia\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"web-tester\": {\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-e2e\": [\"web-testing-playwright-e2e\"],\n },\n },\n allSkillIds: [\n \"web-framework-vue-composition-api\",\n \"web-meta-framework-nuxt\",\n \"web-state-pinia\",\n \"web-testing-vitest\",\n \"shared-tooling-typescript-config\",\n \"shared-tooling-git-hooks\",\n \"shared-tooling-eslint-prettier\",\n \"web-tooling-vite\",\n \"api-framework-hono\",\n \"api-database-drizzle\",\n \"api-auth-better-auth-drizzle-hono\",\n \"api-observability-axiom-pino-sentry\",\n \"meta-reviewing-reviewing\",\n \"web-testing-playwright-e2e\",\n ],\n philosophy: \"Progressive Vue with Nuxt power\",\n },\n {\n id: \"angular-modern-fullstack\",\n name: \"Angular Modern Full-Stack\",\n description: \"NgRx, Hono, Drizzle, Better Auth\",\n skills: {\n \"web-developer\": {\n \"web-framework\": [\"web-framework-angular-standalone\"],\n \"web-client-state\": [\"web-state-ngrx-signalstore\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n \"web-tooling\": [\"web-tooling-vite\"],\n },\n \"api-developer\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n reviewer: {\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"web-framework\": [\"web-framework-angular-standalone\"],\n \"web-client-state\": [\"web-state-ngrx-signalstore\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n },\n pm: {\n \"web-framework\": [\"web-framework-angular-standalone\"],\n \"web-client-state\": [\"web-state-ngrx-signalstore\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n },\n \"web-researcher\": {\n \"web-framework\": [\"web-framework-angular-standalone\"],\n \"web-client-state\": [\"web-state-ngrx-signalstore\"],\n \"web-testing\": [\"web-testing-vitest\"],\n },\n \"api-researcher\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n },\n \"agent-summoner\": {\n \"web-framework\": [\"web-framework-angular-standalone\"],\n \"web-client-state\": [\"web-state-ngrx-signalstore\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"skill-summoner\": {\n \"web-framework\": [\"web-framework-angular-standalone\"],\n \"web-client-state\": [\"web-state-ngrx-signalstore\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"codex-keeper\": {\n \"web-framework\": [\"web-framework-angular-standalone\"],\n \"web-client-state\": [\"web-state-ngrx-signalstore\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"web-tester\": {\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-e2e\": [\"web-testing-playwright-e2e\"],\n },\n },\n allSkillIds: [\n \"web-framework-angular-standalone\",\n \"web-state-ngrx-signalstore\",\n \"web-testing-vitest\",\n \"shared-tooling-typescript-config\",\n \"shared-tooling-git-hooks\",\n \"shared-tooling-eslint-prettier\",\n \"web-tooling-vite\",\n \"api-framework-hono\",\n \"api-database-drizzle\",\n \"api-auth-better-auth-drizzle-hono\",\n \"api-observability-axiom-pino-sentry\",\n \"meta-reviewing-reviewing\",\n \"web-testing-playwright-e2e\",\n ],\n philosophy: \"Enterprise-grade and type-safe\",\n },\n {\n id: \"nextjs-ai-saas\",\n name: \"Next.js AI SaaS\",\n description: \"Vercel AI, Anthropic, Drizzle, Pinecone\",\n skills: {\n \"web-developer\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n \"web-tooling\": [\"web-tooling-vite\"],\n },\n \"api-developer\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"ai-orchestration\": [\"ai-orchestration-vercel-ai-sdk\"],\n \"ai-provider\": [\"ai-provider-anthropic-sdk\"],\n \"ai-patterns\": [\"ai-patterns-tool-use-patterns\"],\n \"api-vector-db\": [\"api-vector-db-pinecone\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n \"cli-developer\": {\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n reviewer: {\n \"meta-reviewing\": [\"meta-reviewing-reviewing\", \"meta-reviewing-cli-reviewing\"],\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"ai-orchestration\": [\"ai-orchestration-vercel-ai-sdk\"],\n \"ai-provider\": [\"ai-provider-anthropic-sdk\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n },\n \"web-tester\": {\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-e2e\": [\"web-testing-playwright-e2e\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n },\n pm: {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"ai-orchestration\": [\"ai-orchestration-vercel-ai-sdk\"],\n \"ai-provider\": [\"ai-provider-anthropic-sdk\"],\n \"ai-patterns\": [\"ai-patterns-tool-use-patterns\"],\n \"api-vector-db\": [\"api-vector-db-pinecone\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n },\n \"web-researcher\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n },\n \"api-researcher\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"ai-orchestration\": [\"ai-orchestration-vercel-ai-sdk\"],\n \"ai-provider\": [\"ai-provider-anthropic-sdk\"],\n \"ai-patterns\": [\"ai-patterns-tool-use-patterns\"],\n \"api-vector-db\": [\"api-vector-db-pinecone\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n },\n \"agent-summoner\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"ai-orchestration\": [\"ai-orchestration-vercel-ai-sdk\"],\n \"ai-provider\": [\"ai-provider-anthropic-sdk\"],\n \"ai-patterns\": [\"ai-patterns-tool-use-patterns\"],\n \"api-vector-db\": [\"api-vector-db-pinecone\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"skill-summoner\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"ai-orchestration\": [\"ai-orchestration-vercel-ai-sdk\"],\n \"ai-provider\": [\"ai-provider-anthropic-sdk\"],\n \"ai-patterns\": [\"ai-patterns-tool-use-patterns\"],\n \"api-vector-db\": [\"api-vector-db-pinecone\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"codex-keeper\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"ai-orchestration\": [\"ai-orchestration-vercel-ai-sdk\"],\n \"ai-provider\": [\"ai-provider-anthropic-sdk\"],\n \"ai-patterns\": [\"ai-patterns-tool-use-patterns\"],\n \"api-vector-db\": [\"api-vector-db-pinecone\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"cli-tester\": {},\n },\n allSkillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-styling-tailwind\",\n \"web-state-zustand\",\n \"web-server-state-react-query\",\n \"web-testing-vitest\",\n \"web-mocks-msw\",\n \"web-accessibility-web-accessibility\",\n \"shared-tooling-typescript-config\",\n \"shared-tooling-git-hooks\",\n \"shared-tooling-eslint-prettier\",\n \"web-tooling-vite\",\n \"api-framework-hono\",\n \"api-database-drizzle\",\n \"api-auth-better-auth-drizzle-hono\",\n \"ai-orchestration-vercel-ai-sdk\",\n \"ai-provider-anthropic-sdk\",\n \"ai-patterns-tool-use-patterns\",\n \"api-vector-db-pinecone\",\n \"api-observability-axiom-pino-sentry\",\n \"api-email-resend-react-email\",\n \"infra-ci-cd-github-actions\",\n \"cli-framework-oclif-ink\",\n \"meta-reviewing-reviewing\",\n \"meta-reviewing-cli-reviewing\",\n \"web-testing-playwright-e2e\",\n ],\n philosophy: \"AI-first full-stack with streaming and tool use\",\n },\n {\n id: \"nextjs-saas-starter\",\n name: \"Next.js SaaS Starter\",\n description: \"Better Auth, Stripe, Drizzle, Resend, PostHog\",\n skills: {\n \"web-developer\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n \"web-tooling\": [\"web-tooling-vite\"],\n },\n \"api-developer\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-commerce\": [\"api-commerce-stripe\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\", \"api-flags-posthog-flags\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n \"cli-developer\": {\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n reviewer: {\n \"meta-reviewing\": [\"meta-reviewing-reviewing\", \"meta-reviewing-cli-reviewing\"],\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-commerce\": [\"api-commerce-stripe\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n },\n \"web-tester\": {\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-e2e\": [\"web-testing-playwright-e2e\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n },\n pm: {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-commerce\": [\"api-commerce-stripe\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n },\n \"web-researcher\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n },\n \"api-researcher\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-commerce\": [\"api-commerce-stripe\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n },\n \"agent-summoner\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-commerce\": [\"api-commerce-stripe\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"skill-summoner\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-commerce\": [\"api-commerce-stripe\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"codex-keeper\": {\n \"web-framework\": [\"web-framework-react\"],\n \"web-meta-framework\": [\"web-meta-framework-nextjs\"],\n \"web-styling\": [\"web-styling-tailwind\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-commerce\": [\"api-commerce-stripe\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-analytics\": [\"api-analytics-posthog-analytics\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"cli-tester\": {},\n },\n allSkillIds: [\n \"web-framework-react\",\n \"web-meta-framework-nextjs\",\n \"web-styling-tailwind\",\n \"web-state-zustand\",\n \"web-server-state-react-query\",\n \"web-testing-vitest\",\n \"web-mocks-msw\",\n \"web-accessibility-web-accessibility\",\n \"shared-tooling-typescript-config\",\n \"shared-tooling-git-hooks\",\n \"shared-tooling-eslint-prettier\",\n \"web-tooling-vite\",\n \"api-framework-hono\",\n \"api-database-drizzle\",\n \"api-auth-better-auth-drizzle-hono\",\n \"api-commerce-stripe\",\n \"api-observability-axiom-pino-sentry\",\n \"api-analytics-posthog-analytics\",\n \"api-flags-posthog-flags\",\n \"api-email-resend-react-email\",\n \"infra-ci-cd-github-actions\",\n \"cli-framework-oclif-ink\",\n \"meta-reviewing-reviewing\",\n \"meta-reviewing-cli-reviewing\",\n \"web-testing-playwright-e2e\",\n ],\n philosophy: \"Ship your SaaS fast with auth, payments, and analytics\",\n },\n {\n id: \"expo-mobile-fullstack\",\n name: \"Expo Mobile Full-Stack\",\n description: \"Zustand, React Query, Hono, Drizzle\",\n skills: {\n \"web-developer\": {\n \"web-framework\": [\"web-framework-react\"],\n \"mobile-framework\": [\"mobile-framework-expo\", \"mobile-framework-react-native\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n \"api-developer\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n \"cli-developer\": {\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n reviewer: {\n \"meta-reviewing\": [\"meta-reviewing-reviewing\", \"meta-reviewing-cli-reviewing\"],\n \"web-framework\": [\"web-framework-react\"],\n \"mobile-framework\": [\"mobile-framework-expo\", \"mobile-framework-react-native\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n },\n \"web-tester\": {\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n },\n pm: {\n \"web-framework\": [\"web-framework-react\"],\n \"mobile-framework\": [\"mobile-framework-expo\", \"mobile-framework-react-native\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n },\n \"web-researcher\": {\n \"web-framework\": [\"web-framework-react\"],\n \"mobile-framework\": [\"mobile-framework-expo\", \"mobile-framework-react-native\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n },\n \"api-researcher\": {\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n },\n \"agent-summoner\": {\n \"web-framework\": [\"web-framework-react\"],\n \"mobile-framework\": [\"mobile-framework-expo\", \"mobile-framework-react-native\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"skill-summoner\": {\n \"web-framework\": [\"web-framework-react\"],\n \"mobile-framework\": [\"mobile-framework-expo\", \"mobile-framework-react-native\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"codex-keeper\": {\n \"web-framework\": [\"web-framework-react\"],\n \"mobile-framework\": [\"mobile-framework-expo\", \"mobile-framework-react-native\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-server-state\": [\"web-server-state-react-query\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"api-api\": [\"api-framework-hono\"],\n \"api-orm\": [\"api-database-drizzle\"],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\"],\n \"api-observability\": [\"api-observability-axiom-pino-sentry\"],\n \"api-email\": [\"api-email-resend-react-email\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n },\n \"cli-tester\": {},\n },\n allSkillIds: [\n \"web-framework-react\",\n \"mobile-framework-expo\",\n \"mobile-framework-react-native\",\n \"web-state-zustand\",\n \"web-server-state-react-query\",\n \"web-testing-vitest\",\n \"web-mocks-msw\",\n \"shared-tooling-typescript-config\",\n \"shared-tooling-git-hooks\",\n \"shared-tooling-eslint-prettier\",\n \"api-framework-hono\",\n \"api-database-drizzle\",\n \"api-auth-better-auth-drizzle-hono\",\n \"api-observability-axiom-pino-sentry\",\n \"api-email-resend-react-email\",\n \"infra-ci-cd-github-actions\",\n \"cli-framework-oclif-ink\",\n \"meta-reviewing-reviewing\",\n \"meta-reviewing-cli-reviewing\",\n ],\n philosophy: \"Cross-platform mobile with shared React patterns\",\n },\n {\n id: \"cli-ink-oclif\",\n name: \"CLI Tool\",\n description: \"oclif, Ink, Zustand, Vitest\",\n skills: {\n \"cli-developer\": {\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"web-framework\": [\"web-framework-react\"],\n \"web-forms\": [\"web-forms-zod-validation\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"meta-design\": [\"meta-design-expressive-typescript\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n reviewer: {\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"web-framework\": [\"web-framework-react\"],\n \"web-forms\": [\"web-forms-zod-validation\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"meta-design\": [\"meta-design-expressive-typescript\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n \"cli-tester\": {\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"web-framework\": [\"web-framework-react\"],\n \"web-forms\": [\"web-forms-zod-validation\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"meta-design\": [\"meta-design-expressive-typescript\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n \"cli-researcher\": {\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"web-framework\": [\"web-framework-react\"],\n \"web-forms\": [\"web-forms-zod-validation\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"meta-design\": [\"meta-design-expressive-typescript\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n pm: {\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"web-framework\": [\"web-framework-react\"],\n \"web-forms\": [\"web-forms-zod-validation\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"meta-design\": [\"meta-design-expressive-typescript\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n \"web-researcher\": {\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"web-framework\": [\"web-framework-react\"],\n \"web-forms\": [\"web-forms-zod-validation\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"meta-design\": [\"meta-design-expressive-typescript\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n \"agent-summoner\": {\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"web-framework\": [\"web-framework-react\"],\n \"web-forms\": [\"web-forms-zod-validation\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"meta-design\": [\"meta-design-expressive-typescript\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n \"skill-summoner\": {\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"web-framework\": [\"web-framework-react\"],\n \"web-forms\": [\"web-forms-zod-validation\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"meta-design\": [\"meta-design-expressive-typescript\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n \"codex-keeper\": {\n \"cli-framework\": [\"cli-framework-oclif-ink\"],\n \"web-framework\": [\"web-framework-react\"],\n \"web-forms\": [\"web-forms-zod-validation\"],\n \"web-client-state\": [\"web-state-zustand\"],\n \"web-testing\": [\"web-testing-vitest\"],\n \"meta-design\": [\"meta-design-expressive-typescript\"],\n \"meta-reviewing\": [\"meta-reviewing-reviewing\"],\n \"shared-tooling\": [\"shared-tooling-typescript-config\", \"shared-tooling-git-hooks\"],\n \"shared-lint\": [\"shared-tooling-eslint-prettier\"],\n },\n },\n allSkillIds: [\n \"cli-framework-oclif-ink\",\n \"web-framework-react\",\n \"web-forms-zod-validation\",\n \"web-state-zustand\",\n \"web-testing-vitest\",\n \"meta-design-expressive-typescript\",\n \"meta-reviewing-reviewing\",\n \"shared-tooling-typescript-config\",\n \"shared-tooling-git-hooks\",\n \"shared-tooling-eslint-prettier\",\n ],\n philosophy: \"Terminal-native CLI with interactive React-based wizard UI\",\n },\n ],\n slugMap: {\n slugToId: {\n \"huggingface-inference\": \"ai-infrastructure-huggingface-inference\",\n litellm: \"ai-infrastructure-litellm\",\n modal: \"ai-infrastructure-modal\",\n ollama: \"ai-infrastructure-ollama\",\n replicate: \"ai-infrastructure-replicate\",\n \"together-ai\": \"ai-infrastructure-together-ai\",\n langfuse: \"ai-observability-langfuse\",\n promptfoo: \"ai-observability-promptfoo\",\n langchain: \"ai-orchestration-langchain\",\n llamaindex: \"ai-orchestration-llamaindex\",\n \"vercel-ai-sdk\": \"ai-orchestration-vercel-ai-sdk\",\n \"tool-use-patterns\": \"ai-patterns-tool-use-patterns\",\n \"anthropic-sdk\": \"ai-provider-anthropic-sdk\",\n \"claude-vision\": \"ai-provider-claude-vision\",\n \"cohere-sdk\": \"ai-provider-cohere-sdk\",\n elevenlabs: \"ai-provider-elevenlabs\",\n \"google-gemini-sdk\": \"ai-provider-google-gemini-sdk\",\n \"mistral-sdk\": \"ai-provider-mistral-sdk\",\n \"openai-sdk\": \"ai-provider-openai-sdk\",\n \"openai-whisper\": \"ai-provider-openai-whisper\",\n \"posthog-analytics\": \"api-analytics-posthog-analytics\",\n \"setup-posthog\": \"api-analytics-setup-posthog\",\n \"better-auth-drizzle-hono\": \"api-auth-better-auth-drizzle-hono\",\n clerk: \"api-auth-clerk\",\n nextauth: \"api-auth-nextauth\",\n appwrite: \"api-baas-appwrite\",\n firebase: \"api-baas-firebase\",\n neon: \"api-baas-neon\",\n planetscale: \"api-baas-planetscale\",\n supabase: \"api-baas-supabase\",\n turso: \"api-baas-turso\",\n strategies: \"api-caching-strategies\",\n payload: \"api-cms-payload\",\n sanity: \"api-cms-sanity\",\n strapi: \"api-cms-strapi\",\n stripe: \"api-commerce-stripe\",\n cockroachdb: \"api-database-cockroachdb\",\n drizzle: \"api-database-drizzle\",\n edgedb: \"api-database-edgedb\",\n knex: \"api-database-knex\",\n mongodb: \"api-database-mongodb\",\n mongoose: \"api-database-mongoose\",\n mysql: \"api-database-mysql\",\n postgresql: \"api-database-postgresql\",\n prisma: \"api-database-prisma\",\n redis: \"api-database-redis\",\n sequelize: \"api-database-sequelize\",\n surrealdb: \"api-database-surrealdb\",\n typeorm: \"api-database-typeorm\",\n upstash: \"api-database-upstash\",\n \"vercel-kv\": \"api-database-vercel-kv\",\n \"vercel-postgres\": \"api-database-vercel-postgres\",\n \"resend-react-email\": \"api-email-resend-react-email\",\n \"setup-resend\": \"api-email-setup-resend\",\n \"posthog-flags\": \"api-flags-posthog-flags\",\n elysia: \"api-framework-elysia\",\n express: \"api-framework-express\",\n fastify: \"api-framework-fastify\",\n hono: \"api-framework-hono\",\n nestjs: \"api-framework-nestjs\",\n \"apollo-server\": \"api-graphql-apollo-server\",\n mercurius: \"api-graphql-mercurius\",\n yoga: \"api-graphql-yoga\",\n webhooks: \"api-messaging-webhooks\",\n \"axiom-pino-sentry\": \"api-observability-axiom-pino-sentry\",\n \"setup-axiom-pino-sentry\": \"api-observability-setup-axiom-pino-sentry\",\n \"api-performance\": \"api-performance-api-performance\",\n bullmq: \"api-queue-bullmq\",\n elasticsearch: \"api-search-elasticsearch\",\n meilisearch: \"api-search-meilisearch\",\n xquik: \"api-search-xquik\",\n openapi: \"api-specs-openapi\",\n chroma: \"api-vector-db-chroma\",\n pinecone: \"api-vector-db-pinecone\",\n qdrant: \"api-vector-db-qdrant\",\n weaviate: \"api-vector-db-weaviate\",\n \"cli-commander\": \"cli-framework-cli-commander\",\n \"oclif-ink\": \"cli-framework-oclif-ink\",\n clack: \"cli-prompts-clack\",\n \"tauri-backend\": \"desktop-backend-tauri\",\n electron: \"desktop-framework-electron\",\n tauri: \"desktop-framework-tauri\",\n \"electron-ipc\": \"desktop-ipc-electron\",\n \"tauri-mobile\": \"desktop-mobile-tauri\",\n \"electron-multiwindow\": \"desktop-multiwindow-electron\",\n \"tauri-multiwindow\": \"desktop-multiwindow-tauri\",\n \"electron-forge\": \"desktop-packaging-electron-forge\",\n \"tauri-bundling\": \"desktop-packaging-tauri\",\n \"tauri-plugins\": \"desktop-plugins-tauri\",\n \"electron-security\": \"desktop-security-electron\",\n \"tauri-security\": \"desktop-security-tauri\",\n \"electron-storage\": \"desktop-storage-electron\",\n \"electron-testing\": \"desktop-testing-electron\",\n \"electron-ui\": \"desktop-ui-electron\",\n \"electron-updater\": \"desktop-updates-electron-updater\",\n docker: \"infra-ci-cd-docker\",\n \"github-actions\": \"infra-ci-cd-github-actions\",\n \"turborepo-ci\": \"infra-ci-cd-turborepo-ci\",\n \"setup-env\": \"infra-config-setup-env\",\n kubernetes: \"infra-containers-kubernetes\",\n pulumi: \"infra-iac-pulumi\",\n sst: \"infra-iac-sst\",\n terraform: \"infra-iac-terraform\",\n \"aws-sdk\": \"infra-platform-aws-sdk\",\n \"cloudflare-workers\": \"infra-platform-cloudflare-workers\",\n netlify: \"infra-platform-netlify\",\n vercel: \"infra-platform-vercel\",\n \"stack-detect\": \"meta-config-stack-detect\",\n \"composable-components\": \"meta-design-composable-components\",\n \"expressive-typescript\": \"meta-design-expressive-typescript\",\n \"research-methodology\": \"meta-methodology-research-methodology\",\n \"ai-planning\": \"meta-planning-ai-planning\",\n \"api-planning\": \"meta-planning-api-planning\",\n \"cli-planning\": \"meta-planning-cli-planning\",\n \"web-planning\": \"meta-planning-web-planning\",\n \"ai-reviewing\": \"meta-reviewing-ai-reviewing\",\n \"api-reviewing\": \"meta-reviewing-api-reviewing\",\n \"cli-reviewing\": \"meta-reviewing-cli-reviewing\",\n \"infra-reviewing\": \"meta-reviewing-infra-reviewing\",\n reviewing: \"meta-reviewing-reviewing\",\n \"web-reviewing\": \"meta-reviewing-web-reviewing\",\n \"gesture-handler\": \"mobile-animation-gesture-handler\",\n reanimated: \"mobile-animation-reanimated\",\n skia: \"mobile-animation-skia\",\n tasks: \"mobile-background-tasks\",\n \"vision-camera\": \"mobile-camera-vision-camera\",\n \"app-links\": \"mobile-deep-linking-app-links\",\n eas: \"mobile-deployment-eas\",\n expo: \"mobile-framework-expo\",\n \"react-native\": \"mobile-framework-react-native\",\n \"ble-nfc\": \"mobile-hardware-ble-nfc\",\n \"expo-router\": \"mobile-navigation-expo-router\",\n \"react-navigation\": \"mobile-navigation-react-navigation\",\n push: \"mobile-notifications-push\",\n \"react-native-performance\": \"mobile-performance-react-native\",\n \"react-native-security\": \"mobile-security-react-native\",\n mmkv: \"mobile-storage-mmkv\",\n \"sqlite-powersync\": \"mobile-storage-sqlite-powersync\",\n watermelondb: \"mobile-storage-watermelondb\",\n nativewind: \"mobile-styling-nativewind\",\n unistyles: \"mobile-styling-unistyles\",\n detox: \"mobile-testing-detox\",\n maestro: \"mobile-testing-maestro\",\n \"react-native-paper\": \"mobile-ui-components-react-native-paper\",\n tamagui: \"mobile-ui-components-tamagui\",\n nx: \"shared-monorepo-nx\",\n \"pnpm-workspaces\": \"shared-monorepo-pnpm-workspaces\",\n turborepo: \"shared-monorepo-turborepo\",\n \"auth-security\": \"shared-security-auth-security\",\n biome: \"shared-tooling-biome\",\n changesets: \"shared-tooling-changesets\",\n \"eslint-prettier\": \"shared-tooling-eslint-prettier\",\n \"git-hooks\": \"shared-tooling-git-hooks\",\n \"typescript-config\": \"shared-tooling-typescript-config\",\n \"react-three-fiber\": \"web-3d-react-three-fiber\",\n \"web-accessibility\": \"web-accessibility-web-accessibility\",\n \"css-animations\": \"web-animation-css-animations\",\n \"framer-motion\": \"web-animation-framer-motion\",\n \"view-transitions\": \"web-animation-view-transitions\",\n \"graphql-apollo\": \"web-data-fetching-graphql-apollo\",\n \"graphql-urql\": \"web-data-fetching-graphql-urql\",\n swr: \"web-data-fetching-swr\",\n trpc: \"web-data-fetching-trpc\",\n d3: \"web-dataviz-d3\",\n recharts: \"web-dataviz-recharts\",\n \"dnd-kit\": \"web-dnd-dnd-kit\",\n lexical: \"web-editor-lexical\",\n tiptap: \"web-editor-tiptap\",\n \"error-boundaries\": \"web-error-handling-error-boundaries\",\n \"result-types\": \"web-error-handling-result-types\",\n \"file-upload-patterns\": \"web-files-file-upload-patterns\",\n \"image-handling\": \"web-files-image-handling\",\n \"react-hook-form\": \"web-forms-react-hook-form\",\n \"tanstack-form\": \"web-forms-tanstack-form\",\n \"vee-validate\": \"web-forms-vee-validate\",\n \"zod-validation\": \"web-forms-zod-validation\",\n \"angular-standalone\": \"web-framework-angular-standalone\",\n react: \"web-framework-react\",\n solidjs: \"web-framework-solidjs\",\n svelte: \"web-framework-svelte\",\n \"vue-composition-api\": \"web-framework-vue-composition-api\",\n \"next-intl\": \"web-i18n-next-intl\",\n \"react-intl\": \"web-i18n-react-intl\",\n \"vue-i18n\": \"web-i18n-vue-i18n\",\n leaflet: \"web-maps-leaflet\",\n mapbox: \"web-maps-mapbox\",\n astro: \"web-meta-framework-astro\",\n docusaurus: \"web-meta-framework-docusaurus\",\n nextjs: \"web-meta-framework-nextjs\",\n nuxt: \"web-meta-framework-nuxt\",\n qwik: \"web-meta-framework-qwik\",\n remix: \"web-meta-framework-remix\",\n sveltekit: \"web-meta-framework-sveltekit\",\n vitepress: \"web-meta-framework-vitepress\",\n msw: \"web-mocks-msw\",\n \"web-performance\": \"web-performance-web-performance\",\n \"offline-first\": \"web-pwa-offline-first\",\n \"service-workers\": \"web-pwa-service-workers\",\n \"socket-io\": \"web-realtime-socket-io\",\n sse: \"web-realtime-sse\",\n websockets: \"web-realtime-websockets\",\n \"react-router\": \"web-routing-react-router\",\n \"tanstack-router\": \"web-routing-tanstack-router\",\n \"react-query\": \"web-server-state-react-query\",\n jotai: \"web-state-jotai\",\n mobx: \"web-state-mobx\",\n \"ngrx-signalstore\": \"web-state-ngrx-signalstore\",\n pinia: \"web-state-pinia\",\n \"redux-toolkit\": \"web-state-redux-toolkit\",\n zustand: \"web-state-zustand\",\n cva: \"web-styling-cva\",\n \"design-tokens\": \"web-styling-design-tokens\",\n \"scss-modules\": \"web-styling-scss-modules\",\n tailwind: \"web-styling-tailwind\",\n theming: \"web-styling-theming\",\n \"cypress-e2e\": \"web-testing-cypress-e2e\",\n \"playwright-e2e\": \"web-testing-playwright-e2e\",\n \"react-testing-library\": \"web-testing-react-testing-library\",\n \"visual-regression\": \"web-testing-visual-regression\",\n vitest: \"web-testing-vitest\",\n \"vue-test-utils\": \"web-testing-vue-test-utils\",\n \"component-library\": \"web-tooling-component-library\",\n storybook: \"web-tooling-storybook\",\n vite: \"web-tooling-vite\",\n \"ant-design\": \"web-ui-ant-design\",\n \"base-ui\": \"web-ui-base-ui\",\n \"chakra-ui\": \"web-ui-chakra-ui\",\n \"headless-ui\": \"web-ui-headless-ui\",\n mantine: \"web-ui-mantine\",\n mui: \"web-ui-mui\",\n \"radix-ui\": \"web-ui-radix-ui\",\n \"shadcn-ui\": \"web-ui-shadcn-ui\",\n \"tanstack-table\": \"web-ui-tanstack-table\",\n vuetify: \"web-ui-vuetify\",\n \"date-fns\": \"web-utilities-date-fns\",\n \"native-js\": \"web-utilities-native-js\",\n rxjs: \"web-utilities-rxjs\",\n vueuse: \"web-utilities-vueuse\",\n },\n idToSlug: {\n \"ai-infrastructure-huggingface-inference\": \"huggingface-inference\",\n \"ai-infrastructure-litellm\": \"litellm\",\n \"ai-infrastructure-modal\": \"modal\",\n \"ai-infrastructure-ollama\": \"ollama\",\n \"ai-infrastructure-replicate\": \"replicate\",\n \"ai-infrastructure-together-ai\": \"together-ai\",\n \"ai-observability-langfuse\": \"langfuse\",\n \"ai-observability-promptfoo\": \"promptfoo\",\n \"ai-orchestration-langchain\": \"langchain\",\n \"ai-orchestration-llamaindex\": \"llamaindex\",\n \"ai-orchestration-vercel-ai-sdk\": \"vercel-ai-sdk\",\n \"ai-patterns-tool-use-patterns\": \"tool-use-patterns\",\n \"ai-provider-anthropic-sdk\": \"anthropic-sdk\",\n \"ai-provider-claude-vision\": \"claude-vision\",\n \"ai-provider-cohere-sdk\": \"cohere-sdk\",\n \"ai-provider-elevenlabs\": \"elevenlabs\",\n \"ai-provider-google-gemini-sdk\": \"google-gemini-sdk\",\n \"ai-provider-mistral-sdk\": \"mistral-sdk\",\n \"ai-provider-openai-sdk\": \"openai-sdk\",\n \"ai-provider-openai-whisper\": \"openai-whisper\",\n \"api-analytics-posthog-analytics\": \"posthog-analytics\",\n \"api-analytics-setup-posthog\": \"setup-posthog\",\n \"api-auth-better-auth-drizzle-hono\": \"better-auth-drizzle-hono\",\n \"api-auth-clerk\": \"clerk\",\n \"api-auth-nextauth\": \"nextauth\",\n \"api-baas-appwrite\": \"appwrite\",\n \"api-baas-firebase\": \"firebase\",\n \"api-baas-neon\": \"neon\",\n \"api-baas-planetscale\": \"planetscale\",\n \"api-baas-supabase\": \"supabase\",\n \"api-baas-turso\": \"turso\",\n \"api-caching-strategies\": \"strategies\",\n \"api-cms-payload\": \"payload\",\n \"api-cms-sanity\": \"sanity\",\n \"api-cms-strapi\": \"strapi\",\n \"api-commerce-stripe\": \"stripe\",\n \"api-database-cockroachdb\": \"cockroachdb\",\n \"api-database-drizzle\": \"drizzle\",\n \"api-database-edgedb\": \"edgedb\",\n \"api-database-knex\": \"knex\",\n \"api-database-mongodb\": \"mongodb\",\n \"api-database-mongoose\": \"mongoose\",\n \"api-database-mysql\": \"mysql\",\n \"api-database-postgresql\": \"postgresql\",\n \"api-database-prisma\": \"prisma\",\n \"api-database-redis\": \"redis\",\n \"api-database-sequelize\": \"sequelize\",\n \"api-database-surrealdb\": \"surrealdb\",\n \"api-database-typeorm\": \"typeorm\",\n \"api-database-upstash\": \"upstash\",\n \"api-database-vercel-kv\": \"vercel-kv\",\n \"api-database-vercel-postgres\": \"vercel-postgres\",\n \"api-email-resend-react-email\": \"resend-react-email\",\n \"api-email-setup-resend\": \"setup-resend\",\n \"api-flags-posthog-flags\": \"posthog-flags\",\n \"api-framework-elysia\": \"elysia\",\n \"api-framework-express\": \"express\",\n \"api-framework-fastify\": \"fastify\",\n \"api-framework-hono\": \"hono\",\n \"api-framework-nestjs\": \"nestjs\",\n \"api-graphql-apollo-server\": \"apollo-server\",\n \"api-graphql-mercurius\": \"mercurius\",\n \"api-graphql-yoga\": \"yoga\",\n \"api-messaging-webhooks\": \"webhooks\",\n \"api-observability-axiom-pino-sentry\": \"axiom-pino-sentry\",\n \"api-observability-setup-axiom-pino-sentry\": \"setup-axiom-pino-sentry\",\n \"api-performance-api-performance\": \"api-performance\",\n \"api-queue-bullmq\": \"bullmq\",\n \"api-search-elasticsearch\": \"elasticsearch\",\n \"api-search-meilisearch\": \"meilisearch\",\n \"api-search-xquik\": \"xquik\",\n \"api-specs-openapi\": \"openapi\",\n \"api-vector-db-chroma\": \"chroma\",\n \"api-vector-db-pinecone\": \"pinecone\",\n \"api-vector-db-qdrant\": \"qdrant\",\n \"api-vector-db-weaviate\": \"weaviate\",\n \"cli-framework-cli-commander\": \"cli-commander\",\n \"cli-framework-oclif-ink\": \"oclif-ink\",\n \"cli-prompts-clack\": \"clack\",\n \"desktop-backend-tauri\": \"tauri-backend\",\n \"desktop-framework-electron\": \"electron\",\n \"desktop-framework-tauri\": \"tauri\",\n \"desktop-ipc-electron\": \"electron-ipc\",\n \"desktop-mobile-tauri\": \"tauri-mobile\",\n \"desktop-multiwindow-electron\": \"electron-multiwindow\",\n \"desktop-multiwindow-tauri\": \"tauri-multiwindow\",\n \"desktop-packaging-electron-forge\": \"electron-forge\",\n \"desktop-packaging-tauri\": \"tauri-bundling\",\n \"desktop-plugins-tauri\": \"tauri-plugins\",\n \"desktop-security-electron\": \"electron-security\",\n \"desktop-security-tauri\": \"tauri-security\",\n \"desktop-storage-electron\": \"electron-storage\",\n \"desktop-testing-electron\": \"electron-testing\",\n \"desktop-ui-electron\": \"electron-ui\",\n \"desktop-updates-electron-updater\": \"electron-updater\",\n \"infra-ci-cd-docker\": \"docker\",\n \"infra-ci-cd-github-actions\": \"github-actions\",\n \"infra-ci-cd-turborepo-ci\": \"turborepo-ci\",\n \"infra-config-setup-env\": \"setup-env\",\n \"infra-containers-kubernetes\": \"kubernetes\",\n \"infra-iac-pulumi\": \"pulumi\",\n \"infra-iac-sst\": \"sst\",\n \"infra-iac-terraform\": \"terraform\",\n \"infra-platform-aws-sdk\": \"aws-sdk\",\n \"infra-platform-cloudflare-workers\": \"cloudflare-workers\",\n \"infra-platform-netlify\": \"netlify\",\n \"infra-platform-vercel\": \"vercel\",\n \"meta-config-stack-detect\": \"stack-detect\",\n \"meta-design-composable-components\": \"composable-components\",\n \"meta-design-expressive-typescript\": \"expressive-typescript\",\n \"meta-methodology-research-methodology\": \"research-methodology\",\n \"meta-planning-ai-planning\": \"ai-planning\",\n \"meta-planning-api-planning\": \"api-planning\",\n \"meta-planning-cli-planning\": \"cli-planning\",\n \"meta-planning-web-planning\": \"web-planning\",\n \"meta-reviewing-ai-reviewing\": \"ai-reviewing\",\n \"meta-reviewing-api-reviewing\": \"api-reviewing\",\n \"meta-reviewing-cli-reviewing\": \"cli-reviewing\",\n \"meta-reviewing-infra-reviewing\": \"infra-reviewing\",\n \"meta-reviewing-reviewing\": \"reviewing\",\n \"meta-reviewing-web-reviewing\": \"web-reviewing\",\n \"mobile-animation-gesture-handler\": \"gesture-handler\",\n \"mobile-animation-reanimated\": \"reanimated\",\n \"mobile-animation-skia\": \"skia\",\n \"mobile-background-tasks\": \"tasks\",\n \"mobile-camera-vision-camera\": \"vision-camera\",\n \"mobile-deep-linking-app-links\": \"app-links\",\n \"mobile-deployment-eas\": \"eas\",\n \"mobile-framework-expo\": \"expo\",\n \"mobile-framework-react-native\": \"react-native\",\n \"mobile-hardware-ble-nfc\": \"ble-nfc\",\n \"mobile-navigation-expo-router\": \"expo-router\",\n \"mobile-navigation-react-navigation\": \"react-navigation\",\n \"mobile-notifications-push\": \"push\",\n \"mobile-performance-react-native\": \"react-native-performance\",\n \"mobile-security-react-native\": \"react-native-security\",\n \"mobile-storage-mmkv\": \"mmkv\",\n \"mobile-storage-sqlite-powersync\": \"sqlite-powersync\",\n \"mobile-storage-watermelondb\": \"watermelondb\",\n \"mobile-styling-nativewind\": \"nativewind\",\n \"mobile-styling-unistyles\": \"unistyles\",\n \"mobile-testing-detox\": \"detox\",\n \"mobile-testing-maestro\": \"maestro\",\n \"mobile-ui-components-react-native-paper\": \"react-native-paper\",\n \"mobile-ui-components-tamagui\": \"tamagui\",\n \"shared-monorepo-nx\": \"nx\",\n \"shared-monorepo-pnpm-workspaces\": \"pnpm-workspaces\",\n \"shared-monorepo-turborepo\": \"turborepo\",\n \"shared-security-auth-security\": \"auth-security\",\n \"shared-tooling-biome\": \"biome\",\n \"shared-tooling-changesets\": \"changesets\",\n \"shared-tooling-eslint-prettier\": \"eslint-prettier\",\n \"shared-tooling-git-hooks\": \"git-hooks\",\n \"shared-tooling-typescript-config\": \"typescript-config\",\n \"web-3d-react-three-fiber\": \"react-three-fiber\",\n \"web-accessibility-web-accessibility\": \"web-accessibility\",\n \"web-animation-css-animations\": \"css-animations\",\n \"web-animation-framer-motion\": \"framer-motion\",\n \"web-animation-view-transitions\": \"view-transitions\",\n \"web-data-fetching-graphql-apollo\": \"graphql-apollo\",\n \"web-data-fetching-graphql-urql\": \"graphql-urql\",\n \"web-data-fetching-swr\": \"swr\",\n \"web-data-fetching-trpc\": \"trpc\",\n \"web-dataviz-d3\": \"d3\",\n \"web-dataviz-recharts\": \"recharts\",\n \"web-dnd-dnd-kit\": \"dnd-kit\",\n \"web-editor-lexical\": \"lexical\",\n \"web-editor-tiptap\": \"tiptap\",\n \"web-error-handling-error-boundaries\": \"error-boundaries\",\n \"web-error-handling-result-types\": \"result-types\",\n \"web-files-file-upload-patterns\": \"file-upload-patterns\",\n \"web-files-image-handling\": \"image-handling\",\n \"web-forms-react-hook-form\": \"react-hook-form\",\n \"web-forms-tanstack-form\": \"tanstack-form\",\n \"web-forms-vee-validate\": \"vee-validate\",\n \"web-forms-zod-validation\": \"zod-validation\",\n \"web-framework-angular-standalone\": \"angular-standalone\",\n \"web-framework-react\": \"react\",\n \"web-framework-solidjs\": \"solidjs\",\n \"web-framework-svelte\": \"svelte\",\n \"web-framework-vue-composition-api\": \"vue-composition-api\",\n \"web-i18n-next-intl\": \"next-intl\",\n \"web-i18n-react-intl\": \"react-intl\",\n \"web-i18n-vue-i18n\": \"vue-i18n\",\n \"web-maps-leaflet\": \"leaflet\",\n \"web-maps-mapbox\": \"mapbox\",\n \"web-meta-framework-astro\": \"astro\",\n \"web-meta-framework-docusaurus\": \"docusaurus\",\n \"web-meta-framework-nextjs\": \"nextjs\",\n \"web-meta-framework-nuxt\": \"nuxt\",\n \"web-meta-framework-qwik\": \"qwik\",\n \"web-meta-framework-remix\": \"remix\",\n \"web-meta-framework-sveltekit\": \"sveltekit\",\n \"web-meta-framework-vitepress\": \"vitepress\",\n \"web-mocks-msw\": \"msw\",\n \"web-performance-web-performance\": \"web-performance\",\n \"web-pwa-offline-first\": \"offline-first\",\n \"web-pwa-service-workers\": \"service-workers\",\n \"web-realtime-socket-io\": \"socket-io\",\n \"web-realtime-sse\": \"sse\",\n \"web-realtime-websockets\": \"websockets\",\n \"web-routing-react-router\": \"react-router\",\n \"web-routing-tanstack-router\": \"tanstack-router\",\n \"web-server-state-react-query\": \"react-query\",\n \"web-state-jotai\": \"jotai\",\n \"web-state-mobx\": \"mobx\",\n \"web-state-ngrx-signalstore\": \"ngrx-signalstore\",\n \"web-state-pinia\": \"pinia\",\n \"web-state-redux-toolkit\": \"redux-toolkit\",\n \"web-state-zustand\": \"zustand\",\n \"web-styling-cva\": \"cva\",\n \"web-styling-design-tokens\": \"design-tokens\",\n \"web-styling-scss-modules\": \"scss-modules\",\n \"web-styling-tailwind\": \"tailwind\",\n \"web-styling-theming\": \"theming\",\n \"web-testing-cypress-e2e\": \"cypress-e2e\",\n \"web-testing-playwright-e2e\": \"playwright-e2e\",\n \"web-testing-react-testing-library\": \"react-testing-library\",\n \"web-testing-visual-regression\": \"visual-regression\",\n \"web-testing-vitest\": \"vitest\",\n \"web-testing-vue-test-utils\": \"vue-test-utils\",\n \"web-tooling-component-library\": \"component-library\",\n \"web-tooling-storybook\": \"storybook\",\n \"web-tooling-vite\": \"vite\",\n \"web-ui-ant-design\": \"ant-design\",\n \"web-ui-base-ui\": \"base-ui\",\n \"web-ui-chakra-ui\": \"chakra-ui\",\n \"web-ui-headless-ui\": \"headless-ui\",\n \"web-ui-mantine\": \"mantine\",\n \"web-ui-mui\": \"mui\",\n \"web-ui-radix-ui\": \"radix-ui\",\n \"web-ui-shadcn-ui\": \"shadcn-ui\",\n \"web-ui-tanstack-table\": \"tanstack-table\",\n \"web-ui-vuetify\": \"vuetify\",\n \"web-utilities-date-fns\": \"date-fns\",\n \"web-utilities-native-js\": \"native-js\",\n \"web-utilities-rxjs\": \"rxjs\",\n \"web-utilities-vueuse\": \"vueuse\",\n },\n },\n generatedAt: \"build\",\n} as MergedSkillsMatrix;\n\n// ── Derived Lookup Maps ───────────────────────────────────────\n\nexport const SKILL_IDS_BY_CATEGORY: Record<Category, readonly SkillId[]> = {\n \"ai-infrastructure\": [\n \"ai-infrastructure-huggingface-inference\",\n \"ai-infrastructure-litellm\",\n \"ai-infrastructure-modal\",\n \"ai-infrastructure-ollama\",\n \"ai-infrastructure-replicate\",\n \"ai-infrastructure-together-ai\",\n ],\n \"ai-observability\": [\"ai-observability-langfuse\", \"ai-observability-promptfoo\"],\n \"ai-orchestration\": [\n \"ai-orchestration-langchain\",\n \"ai-orchestration-llamaindex\",\n \"ai-orchestration-vercel-ai-sdk\",\n ],\n \"ai-patterns\": [\"ai-patterns-tool-use-patterns\"],\n \"ai-provider\": [\n \"ai-provider-anthropic-sdk\",\n \"ai-provider-claude-vision\",\n \"ai-provider-cohere-sdk\",\n \"ai-provider-elevenlabs\",\n \"ai-provider-google-gemini-sdk\",\n \"ai-provider-mistral-sdk\",\n \"ai-provider-openai-sdk\",\n \"ai-provider-openai-whisper\",\n ],\n \"api-analytics\": [\n \"api-analytics-posthog-analytics\",\n \"api-analytics-setup-posthog\",\n \"api-flags-posthog-flags\",\n ],\n \"api-api\": [\n \"api-framework-elysia\",\n \"api-framework-express\",\n \"api-framework-fastify\",\n \"api-framework-hono\",\n \"api-framework-nestjs\",\n ],\n \"api-auth\": [\"api-auth-better-auth-drizzle-hono\", \"api-auth-clerk\", \"api-auth-nextauth\"],\n \"api-baas\": [\"api-baas-appwrite\", \"api-baas-firebase\", \"api-baas-supabase\"],\n \"api-caching\": [\"api-caching-strategies\"],\n \"api-cms\": [\"api-cms-payload\", \"api-cms-sanity\", \"api-cms-strapi\"],\n \"api-commerce\": [\"api-commerce-stripe\"],\n \"api-db-host\": [\n \"api-baas-neon\",\n \"api-baas-planetscale\",\n \"api-baas-turso\",\n \"api-database-vercel-postgres\",\n ],\n \"api-document\": [\n \"api-database-edgedb\",\n \"api-database-mongodb\",\n \"api-database-mongoose\",\n \"api-database-surrealdb\",\n ],\n \"api-email\": [\"api-email-resend-react-email\", \"api-email-setup-resend\"],\n \"api-graphql\": [\"api-graphql-apollo-server\", \"api-graphql-mercurius\", \"api-graphql-yoga\"],\n \"api-kv\": [\"api-database-redis\", \"api-database-upstash\", \"api-database-vercel-kv\"],\n \"api-messaging\": [\"api-messaging-webhooks\"],\n \"api-observability\": [\n \"api-observability-axiom-pino-sentry\",\n \"api-observability-setup-axiom-pino-sentry\",\n ],\n \"api-orm\": [\n \"api-database-drizzle\",\n \"api-database-knex\",\n \"api-database-prisma\",\n \"api-database-sequelize\",\n \"api-database-typeorm\",\n ],\n \"api-performance\": [\"api-performance-api-performance\"],\n \"api-queue\": [\"api-queue-bullmq\"],\n \"api-search\": [\"api-search-elasticsearch\", \"api-search-meilisearch\", \"api-search-xquik\"],\n \"api-specs\": [\"api-specs-openapi\"],\n \"api-sql-engine\": [\"api-database-cockroachdb\", \"api-database-mysql\", \"api-database-postgresql\"],\n \"api-vector-db\": [\n \"api-vector-db-chroma\",\n \"api-vector-db-pinecone\",\n \"api-vector-db-qdrant\",\n \"api-vector-db-weaviate\",\n ],\n \"cli-framework\": [\"cli-framework-cli-commander\", \"cli-framework-oclif-ink\"],\n \"cli-prompts\": [\"cli-prompts-clack\"],\n \"desktop-backend\": [\"desktop-backend-tauri\"],\n \"desktop-framework\": [\"desktop-framework-electron\", \"desktop-framework-tauri\"],\n \"desktop-ipc\": [\"desktop-ipc-electron\"],\n \"desktop-mobile\": [\"desktop-mobile-tauri\"],\n \"desktop-multiwindow\": [\"desktop-multiwindow-electron\", \"desktop-multiwindow-tauri\"],\n \"desktop-packaging\": [\"desktop-packaging-electron-forge\", \"desktop-packaging-tauri\"],\n \"desktop-plugins\": [\"desktop-plugins-tauri\"],\n \"desktop-security\": [\"desktop-security-electron\", \"desktop-security-tauri\"],\n \"desktop-storage\": [\"desktop-storage-electron\"],\n \"desktop-testing\": [\"desktop-testing-electron\"],\n \"desktop-ui\": [\"desktop-ui-electron\"],\n \"desktop-updates\": [\"desktop-updates-electron-updater\"],\n \"infra-ci-cd\": [\"infra-ci-cd-github-actions\", \"infra-ci-cd-turborepo-ci\"],\n \"infra-config\": [\"infra-config-setup-env\"],\n \"infra-containers\": [\"infra-ci-cd-docker\", \"infra-containers-kubernetes\"],\n \"infra-iac\": [\"infra-iac-pulumi\", \"infra-iac-sst\", \"infra-iac-terraform\"],\n \"infra-platform\": [\n \"infra-platform-aws-sdk\",\n \"infra-platform-cloudflare-workers\",\n \"infra-platform-netlify\",\n \"infra-platform-vercel\",\n ],\n \"meta-design\": [\"meta-design-composable-components\", \"meta-design-expressive-typescript\"],\n \"meta-methodology\": [\"meta-methodology-research-methodology\"],\n \"meta-planning\": [\n \"meta-planning-ai-planning\",\n \"meta-planning-api-planning\",\n \"meta-planning-cli-planning\",\n \"meta-planning-web-planning\",\n ],\n \"meta-reviewing\": [\n \"meta-reviewing-ai-reviewing\",\n \"meta-reviewing-api-reviewing\",\n \"meta-reviewing-cli-reviewing\",\n \"meta-reviewing-infra-reviewing\",\n \"meta-reviewing-reviewing\",\n \"meta-reviewing-web-reviewing\",\n ],\n \"mobile-animation\": [\n \"mobile-animation-gesture-handler\",\n \"mobile-animation-reanimated\",\n \"mobile-animation-skia\",\n ],\n \"mobile-background\": [\"mobile-background-tasks\"],\n \"mobile-camera\": [\"mobile-camera-vision-camera\"],\n \"mobile-deep-linking\": [\"mobile-deep-linking-app-links\"],\n \"mobile-deployment\": [\"mobile-deployment-eas\"],\n \"mobile-framework\": [\"mobile-framework-expo\", \"mobile-framework-react-native\"],\n \"mobile-hardware\": [\"mobile-hardware-ble-nfc\"],\n \"mobile-navigation\": [\"mobile-navigation-expo-router\", \"mobile-navigation-react-navigation\"],\n \"mobile-notifications\": [\"mobile-notifications-push\"],\n \"mobile-performance\": [\"mobile-performance-react-native\"],\n \"mobile-security\": [\"mobile-security-react-native\"],\n \"mobile-storage\": [\n \"mobile-storage-mmkv\",\n \"mobile-storage-sqlite-powersync\",\n \"mobile-storage-watermelondb\",\n ],\n \"mobile-styling\": [\"mobile-styling-nativewind\", \"mobile-styling-unistyles\"],\n \"mobile-testing\": [\"mobile-testing-detox\", \"mobile-testing-maestro\"],\n \"mobile-ui-components\": [\n \"mobile-ui-components-react-native-paper\",\n \"mobile-ui-components-tamagui\",\n ],\n \"shared-lint\": [\"shared-tooling-biome\", \"shared-tooling-eslint-prettier\"],\n \"shared-monorepo\": [\"shared-monorepo-pnpm-workspaces\"],\n \"shared-security\": [\"shared-security-auth-security\"],\n \"shared-task-runner\": [\"shared-monorepo-nx\", \"shared-monorepo-turborepo\"],\n \"shared-tooling\": [\n \"meta-config-stack-detect\",\n \"shared-tooling-changesets\",\n \"shared-tooling-git-hooks\",\n \"shared-tooling-typescript-config\",\n ],\n \"web-3d\": [\"web-3d-react-three-fiber\"],\n \"web-accessibility\": [\"web-accessibility-web-accessibility\"],\n \"web-animation\": [\n \"web-animation-css-animations\",\n \"web-animation-framer-motion\",\n \"web-animation-view-transitions\",\n ],\n \"web-client-state\": [\n \"web-state-jotai\",\n \"web-state-mobx\",\n \"web-state-ngrx-signalstore\",\n \"web-state-pinia\",\n \"web-state-redux-toolkit\",\n \"web-state-zustand\",\n ],\n \"web-dataviz\": [\"web-dataviz-d3\", \"web-dataviz-recharts\"],\n \"web-dnd\": [\"web-dnd-dnd-kit\"],\n \"web-docs\": [\"web-meta-framework-docusaurus\", \"web-meta-framework-vitepress\"],\n \"web-e2e\": [\"web-testing-cypress-e2e\", \"web-testing-playwright-e2e\"],\n \"web-editor\": [\"web-editor-lexical\", \"web-editor-tiptap\"],\n \"web-error-handling\": [\"web-error-handling-error-boundaries\", \"web-error-handling-result-types\"],\n \"web-file-upload\": [\"web-files-file-upload-patterns\"],\n \"web-files\": [\"web-files-image-handling\"],\n \"web-form-library\": [\n \"web-forms-react-hook-form\",\n \"web-forms-tanstack-form\",\n \"web-forms-vee-validate\",\n ],\n \"web-forms\": [\"web-forms-zod-validation\"],\n \"web-framework\": [\n \"web-framework-angular-standalone\",\n \"web-framework-react\",\n \"web-framework-solidjs\",\n \"web-framework-svelte\",\n \"web-framework-vue-composition-api\",\n ],\n \"web-graphql-client\": [\"web-data-fetching-graphql-apollo\", \"web-data-fetching-graphql-urql\"],\n \"web-i18n\": [\"web-i18n-next-intl\", \"web-i18n-react-intl\", \"web-i18n-vue-i18n\"],\n \"web-maps\": [\"web-maps-leaflet\", \"web-maps-mapbox\"],\n \"web-meta-framework\": [\n \"web-meta-framework-astro\",\n \"web-meta-framework-nextjs\",\n \"web-meta-framework-nuxt\",\n \"web-meta-framework-qwik\",\n \"web-meta-framework-remix\",\n \"web-meta-framework-sveltekit\",\n ],\n \"web-mocking\": [\"web-mocks-msw\"],\n \"web-performance\": [\"web-performance-web-performance\"],\n \"web-pwa\": [\"web-pwa-offline-first\", \"web-pwa-service-workers\"],\n \"web-realtime\": [\"web-realtime-socket-io\", \"web-realtime-websockets\"],\n \"web-routing\": [\"web-routing-react-router\", \"web-routing-tanstack-router\"],\n \"web-rpc\": [\"web-data-fetching-trpc\"],\n \"web-server-state\": [\"web-data-fetching-swr\", \"web-server-state-react-query\"],\n \"web-streaming\": [\"web-realtime-sse\"],\n \"web-styling\": [\n \"web-styling-cva\",\n \"web-styling-design-tokens\",\n \"web-styling-scss-modules\",\n \"web-styling-tailwind\",\n \"web-styling-theming\",\n ],\n \"web-testing\": [\n \"web-testing-react-testing-library\",\n \"web-testing-visual-regression\",\n \"web-testing-vitest\",\n \"web-testing-vue-test-utils\",\n ],\n \"web-tooling\": [\"web-tooling-component-library\", \"web-tooling-storybook\", \"web-tooling-vite\"],\n \"web-ui-components\": [\n \"web-ui-base-ui\",\n \"web-ui-headless-ui\",\n \"web-ui-radix-ui\",\n \"web-ui-tanstack-table\",\n ],\n \"web-ui-kit\": [\n \"web-ui-ant-design\",\n \"web-ui-chakra-ui\",\n \"web-ui-mantine\",\n \"web-ui-mui\",\n \"web-ui-shadcn-ui\",\n \"web-ui-vuetify\",\n ],\n \"web-utilities\": [\n \"web-utilities-date-fns\",\n \"web-utilities-native-js\",\n \"web-utilities-rxjs\",\n \"web-utilities-vueuse\",\n ],\n} as Record<Category, readonly SkillId[]>;\n\nexport const CATEGORIES_BY_DOMAIN: Record<Domain, readonly Category[]> = {\n ai: [\"ai-infrastructure\", \"ai-observability\", \"ai-orchestration\", \"ai-patterns\", \"ai-provider\"],\n api: [\n \"api-analytics\",\n \"api-api\",\n \"api-auth\",\n \"api-baas\",\n \"api-caching\",\n \"api-cms\",\n \"api-commerce\",\n \"api-db-host\",\n \"api-document\",\n \"api-email\",\n \"api-graphql\",\n \"api-kv\",\n \"api-messaging\",\n \"api-observability\",\n \"api-orm\",\n \"api-performance\",\n \"api-queue\",\n \"api-search\",\n \"api-specs\",\n \"api-sql-engine\",\n \"api-vector-db\",\n ],\n cli: [\"cli-framework\", \"cli-prompts\"],\n desktop: [\n \"desktop-backend\",\n \"desktop-framework\",\n \"desktop-ipc\",\n \"desktop-mobile\",\n \"desktop-multiwindow\",\n \"desktop-packaging\",\n \"desktop-plugins\",\n \"desktop-security\",\n \"desktop-storage\",\n \"desktop-testing\",\n \"desktop-ui\",\n \"desktop-updates\",\n ],\n infra: [\"infra-ci-cd\", \"infra-config\", \"infra-containers\", \"infra-iac\", \"infra-platform\"],\n meta: [\"meta-design\", \"meta-methodology\", \"meta-planning\", \"meta-reviewing\"],\n mobile: [\n \"mobile-animation\",\n \"mobile-background\",\n \"mobile-camera\",\n \"mobile-deep-linking\",\n \"mobile-deployment\",\n \"mobile-framework\",\n \"mobile-hardware\",\n \"mobile-navigation\",\n \"mobile-notifications\",\n \"mobile-performance\",\n \"mobile-security\",\n \"mobile-storage\",\n \"mobile-styling\",\n \"mobile-testing\",\n \"mobile-ui-components\",\n ],\n shared: [\n \"shared-lint\",\n \"shared-monorepo\",\n \"shared-security\",\n \"shared-task-runner\",\n \"shared-tooling\",\n ],\n web: [\n \"web-3d\",\n \"web-accessibility\",\n \"web-animation\",\n \"web-client-state\",\n \"web-dataviz\",\n \"web-dnd\",\n \"web-docs\",\n \"web-e2e\",\n \"web-editor\",\n \"web-error-handling\",\n \"web-file-upload\",\n \"web-files\",\n \"web-form-library\",\n \"web-forms\",\n \"web-framework\",\n \"web-graphql-client\",\n \"web-i18n\",\n \"web-maps\",\n \"web-meta-framework\",\n \"web-mocking\",\n \"web-performance\",\n \"web-pwa\",\n \"web-realtime\",\n \"web-routing\",\n \"web-rpc\",\n \"web-server-state\",\n \"web-streaming\",\n \"web-styling\",\n \"web-testing\",\n \"web-tooling\",\n \"web-ui-components\",\n \"web-ui-kit\",\n \"web-utilities\",\n ],\n} as Record<Domain, readonly Category[]>;\n","// The validation boundary for `BUILT_IN_MATRIX` — the one catalogue this package\n// vendors — and for everything the read models build on it.\n//\n// These schemas describe only what the editor actually reads, not the full CLI types.\n// Unknown keys are stripped, so the vendored data can grow fields without touching this file.\n// What they do catch is the case that matters: a regenerated catalog that dropped or renamed\n// something we depend on. That fails here, loudly, instead of rendering a blank table.\n//\n// The narrowing is what makes it the VENDORED boundary rather than a general\n// one: every id is held against a generated vocabulary, so a catalogue whose\n// ids came from somewhere else is rejected by construction. That other case is\n// `matrixSchema` in `matrix-schema.ts`, which describes any marketplace's\n// catalogue and is the schema a fetched `catalog.json` is parsed with.\n\nimport { z } from \"zod\"\nimport {\n AGENT_NAMES,\n CATEGORIES,\n DOMAINS,\n SKILL_IDS,\n} from \"./vendor/generated/source-types\"\n\nexport const domainIdSchema = z.enum(DOMAINS)\n\n// The generated vocabularies, as the boundary's own alphabet. Ids validated\n// against them arrive downstream already narrowed, which is what spares every\n// read model from casting a `string` back into the union it came from.\nconst skillIdSchema = z.enum(SKILL_IDS)\nconst categorySchema = z.enum(CATEGORIES)\nconst agentNameSchema = z.enum(AGENT_NAMES)\n\nexport const categoryDefinitionSchema = z.object({\n id: categorySchema,\n displayName: z.string(),\n description: z.string(),\n // Optional in the CLI's type. Present on all 89 built-in categories today; a category without\n // one cannot be placed in the UI, so the read model drops it rather than failing the whole boot.\n domain: domainIdSchema.exactOptional(),\n exclusive: z.boolean(),\n required: z.boolean(),\n order: z.number(),\n})\n\nconst skillRelationSchema = z.object({\n skillId: skillIdSchema,\n reason: z.string(),\n})\n\nconst skillRequirementSchema = z.object({\n skillIds: z.array(skillIdSchema),\n needsAny: z.boolean(),\n reason: z.string(),\n})\n\nexport const resolvedSkillSchema = z.object({\n id: skillIdSchema,\n slug: z.string(),\n displayName: z.string(),\n description: z.string(),\n category: categorySchema,\n conflictsWith: z.array(skillRelationSchema),\n discourages: z.array(skillRelationSchema),\n requires: z.array(skillRequirementSchema),\n})\n\nexport const resolvedStackSchema = z.object({\n id: z.string(),\n name: z.string(),\n description: z.string(),\n // agent id → category id → skill ids. Partial because a stack names the few\n // agents it staffs, not the whole roster; the category keys are the one level\n // nothing here reads, so they stay unvalidated strings.\n skills: z.partialRecord(\n agentNameSchema,\n z.record(z.string(), z.array(skillIdSchema))\n ),\n allSkillIds: z.array(skillIdSchema),\n philosophy: z.string(),\n // Never populated by the CLI today; the stack rail groups by it when it appears.\n group: z.string().exactOptional(),\n})\n\nexport const builtInMatrixSchema = z.object({\n // Stamped into every seed payload so a consumer can explain skipped ids.\n version: z.string(),\n categories: z.record(z.string(), categoryDefinitionSchema),\n skills: z.record(z.string(), resolvedSkillSchema),\n suggestedStacks: z.array(resolvedStackSchema),\n})\n\nexport type BuiltInMatrix = z.infer<typeof builtInMatrixSchema>\nexport type ParsedSkill = z.infer<typeof resolvedSkillSchema>\nexport type ParsedCategory = z.infer<typeof categoryDefinitionSchema>\nexport type ParsedStack = z.infer<typeof resolvedStackSchema>\n","import { BUILT_IN_MATRIX } from \"../vendor/generated/matrix\"\nimport { builtInMatrixSchema } from \"../built-in-matrix\"\n\n// The vendored matrix, validated once. Parsing the whole catalog is measurably slow, so every\n// read-model module shares this rather than calling builtInMatrixSchema.parse itself.\nexport const MATRIX = builtInMatrixSchema.parse(BUILT_IN_MATRIX)\n\nexport const MATRIX_VERSION = MATRIX.version\n","import { DOMAINS, type Domain } from \"../vendor/generated/source-types\"\n\n// The canonical display order. The CLI's wizard imports it from here — the\n// byte-duplicate it used to keep in sync by hand (`BUILT_IN_DOMAIN_ORDER` in\n// src/cli/consts.ts) was folded into this one when the selection semantics\n// moved onto this shared surface.\nexport const DOMAIN_ORDER: readonly Domain[] = [\n \"web\",\n \"api\",\n \"ai\",\n \"mobile\",\n \"desktop\",\n \"cli\",\n \"infra\",\n \"meta\",\n \"shared\",\n]\n\n// Short labels, for a filter bar that has to fit nine chips on one row.\n// The CLI spells `infra` out as \"Infrastructure\"; the design's chip says \"Infra\".\nexport const DOMAIN_LABELS: Record<Domain, string> = {\n web: \"Web\",\n api: \"API\",\n ai: \"AI\",\n mobile: \"Mobile\",\n desktop: \"Desktop\",\n cli: \"CLI\",\n infra: \"Infra\",\n meta: \"Meta\",\n shared: \"Shared\",\n}\n\n// One-line descriptions: the editor's chip and group tooltips, and the CLI's\n// domain-selection grid — its own copy folded into this one alongside\n// DOMAIN_ORDER above.\nexport const DOMAIN_DESCRIPTIONS: Record<Domain, string> = {\n web: \"Frontend web applications\",\n api: \"Backend APIs and services\",\n ai: \"AI and LLM integrations\",\n mobile: \"Mobile applications\",\n desktop: \"Desktop applications\",\n cli: \"Command-line tools\",\n infra: \"CI/CD, deployment, and infrastructure\",\n meta: \"Design patterns, code review, and research methodology\",\n shared: \"Shared utilities and methodology\",\n}\n\nconst DOMAIN_IDS = new Set<string>(DOMAINS)\n\n/**\n * Whether the UI has a section for this domain.\n *\n * Exported because a fetched marketplace names its own domains as plain\n * strings, and the nine here are the only ones with a label, an order and a\n * filter chip — so this is the question `buildCatalog` asks before it decides a\n * category has somewhere to render.\n */\nexport const isDomain = (domainId: string): domainId is Domain =>\n DOMAIN_IDS.has(domainId)\n\n// Agent ids are `<domain>-<role>` for the twelve agents that belong to a domain. The other six\n// (`agent-summoner`, `codex-keeper`, `convention-keeper`, `skill-summoner`, and the two\n// consolidated role agents `pm` and `reviewer`) have no domain prefix and land in `meta`,\n// alongside the meta-domain skills.\n//\n// The CLI's `MergedSkillsMatrix.agentDefinedDomains` would be the authoritative source, but it\n// is never populated and the CLI has it queued for deletion, so the prefix is what we have.\nexport const agentDomainOf = (agentId: string): Domain => {\n const prefix = agentId.split(\"-\")[0]\n return prefix && isDomain(prefix) ? prefix : \"meta\"\n}\n\nconst DOMAIN_POSITION = new Map(\n DOMAIN_ORDER.map((domain, index) => [domain, index])\n)\n\nexport const compareDomains = (a: Domain, b: Domain) =>\n (DOMAIN_POSITION.get(a) ?? DOMAIN_ORDER.length) -\n (DOMAIN_POSITION.get(b) ?? DOMAIN_ORDER.length)\n","import {\n SKILL_IDS,\n type Domain,\n type SkillId,\n} from \"../vendor/generated/source-types\"\nimport type { Matrix, MatrixCategory, MatrixSkill } from \"../matrix-schema\"\nimport { groupBy } from \"./collections\"\nimport { MATRIX } from \"./source\"\nimport {\n DOMAIN_DESCRIPTIONS,\n DOMAIN_LABELS,\n compareDomains,\n isDomain,\n} from \"./domains\"\n\n// Ids are `string` throughout, and that is the point rather than a loosening.\n// A catalogue is no longer only the vendored one: the editor fetches a\n// marketplace's `catalog.json` and builds these same read models over it, and a\n// marketplace's ids are its own — `SkillId` would reject every one of them by\n// construction. The vendored unions still narrow what the VENDORED artefact is\n// allowed to contain, in `built-in-matrix.ts`, which is the boundary that\n// question belongs to.\n//\n// `Domain` is the exception and stays closed, because it is not the\n// catalogue's vocabulary — it is the UI's. Nine domains have labels, an order\n// and a filter chip, so a category naming a tenth has nowhere to render; it is\n// dropped exactly as one naming no domain already was.\n\n// One dependency group: `needsAny` picks between \"all of these\" and \"one of\n// these\". `reason` is authored upstream (\"SvelteKit is built on Svelte\").\nexport type SkillRequirement = {\n skillIds: string[]\n needsAny: boolean\n reason: string\n}\n\nexport type CatalogSkill = {\n id: string\n slug: string\n displayName: string\n description: string\n categoryId: string\n domainId: Domain\n // Selecting this skill hard-excludes these.\n conflictsWith: string[]\n // Soft conflict — warn, do not disable.\n discourages: string[]\n // What this skill is built on. The only place a cross-category\n // incompatibility is expressed: SvelteKit requires Svelte, so picking React\n // — which Svelte conflicts with — puts SvelteKit out of reach.\n requires: SkillRequirement[]\n}\n\nexport type CatalogCategory = {\n id: string\n displayName: string\n description: string\n domainId: Domain\n // Only one skill may be picked. Drives the `pick one` tag and auto-collapse.\n exclusive: boolean\n required: boolean\n skills: CatalogSkill[]\n}\n\nexport type CatalogDomain = {\n id: Domain\n label: string\n description: string\n categories: CatalogCategory[]\n skillCount: number\n}\n\nexport type Catalog = {\n domains: CatalogDomain[]\n // Both indexes hold the ids this catalogue ships and nothing else: a category\n // with no placeable domain never reaches them, so even a known id can miss —\n // and once the catalogue can be a marketplace's, so can an id from another\n // one. Keyed by `string` rather than by a union, which under\n // `noUncheckedIndexedAccess` is what already types every read as \"or nothing\".\n skillsById: Record<string, CatalogSkill>\n categoriesById: Record<string, CatalogCategory>\n skillCount: number\n}\n\nconst toCatalogSkill = (\n skill: MatrixSkill,\n domainId: Domain\n): CatalogSkill => ({\n id: skill.id,\n slug: skill.slug,\n displayName: skill.displayName,\n description: skill.description,\n categoryId: skill.category,\n domainId,\n conflictsWith: skill.conflictsWith.map((relation) => relation.skillId),\n discourages: skill.discourages.map((relation) => relation.skillId),\n requires: skill.requires.map((requirement) => ({\n skillIds: requirement.skillIds,\n needsAny: requirement.needsAny,\n reason: requirement.reason,\n })),\n})\n\ntype PlaceableCategory = MatrixCategory & { domain: Domain }\n\n// Categories the UI can place. A category has nowhere to render when it names\n// no domain, and equally when it names one the UI has never heard of — a\n// marketplace is free to invent a category id but not a domain, because a\n// domain is a labelled section with an order and a filter chip.\nconst placeableCategories = (categories: Record<string, MatrixCategory>) =>\n Object.values(categories).filter(\n (category): category is PlaceableCategory =>\n category.domain !== undefined && isDomain(category.domain)\n )\n\n// Domain order first, then the category order authored upstream.\nconst byDomainThenAuthoredOrder = (\n a: PlaceableCategory,\n b: PlaceableCategory\n) => compareDomains(a.domain, b.domain) || a.order - b.order\n\nconst toCatalogCategory = (\n category: PlaceableCategory,\n skills: MatrixSkill[]\n): CatalogCategory => ({\n id: category.id,\n displayName: category.displayName,\n description: category.description,\n domainId: category.domain,\n exclusive: category.exclusive,\n required: category.required,\n skills: skills\n .map((skill) => toCatalogSkill(skill, category.domain))\n .sort((a, b) => a.displayName.localeCompare(b.displayName)),\n})\n\nconst toCatalogDomain = (\n id: Domain,\n categories: CatalogCategory[]\n): CatalogDomain => ({\n id,\n label: DOMAIN_LABELS[id],\n description: DOMAIN_DESCRIPTIONS[id],\n categories,\n skillCount: categories.reduce(\n (total, category) => total + category.skills.length,\n 0\n ),\n})\n\n/**\n * The read model, over any catalogue in the wire shape.\n *\n * Exported because the vendored matrix is no longer the only one: the editor\n * fetches a marketplace's `catalog.json`, parses it with `matrixSchema`, and\n * builds exactly this — same derivation, same sorting, same placement rules, so\n * a marketplace's grid cannot render by a different set of rules than the\n * public one's.\n */\nexport const buildCatalog = (matrix: Matrix): Catalog => {\n const skillsByCategory = groupBy(\n Object.values(matrix.skills),\n (skill) => skill.category\n )\n\n const categories = placeableCategories(matrix.categories)\n .sort(byDomainThenAuthoredOrder)\n .map((category) =>\n toCatalogCategory(category, skillsByCategory.get(category.id) ?? [])\n )\n\n const domains = [...groupBy(categories, (category) => category.domainId)]\n .sort(([a], [b]) => compareDomains(a, b))\n .map(([id, domainCategories]) => toCatalogDomain(id, domainCategories))\n\n const allSkills = categories.flatMap((category) => category.skills)\n\n return {\n domains,\n skillsById: byId(allSkills),\n categoriesById: byId(categories),\n skillCount: allSkills.length,\n }\n}\n\n// `indexById`'s open-vocabulary twin. That one keys by a finite union and is\n// therefore `Partial`; these ids are `string`, so `noUncheckedIndexedAccess`\n// already says a read may miss and no cast is needed to say it again.\nconst byId = <T extends { id: string }>(items: T[]): Record<string, T> =>\n Object.fromEntries(items.map((item) => [item.id, item]))\n\n/** The vendored public catalogue — what an app nobody has pointed anywhere shows. */\nexport const CATALOG = buildCatalog(MATRIX)\n\n/**\n * The catalogue asked with an open id.\n *\n * The question reaching it is not always an id the catalogue carries: the\n * editor mints `github:owner/repo` ids for skills added mid-session, a saved\n * configuration can name one a later catalogue dropped, and a configuration\n * built against one marketplace can be asked of another. All three are answered\n * — `undefined` — rather than rejected, which is what keeps the guards at those\n * call sites doing real work.\n */\nexport const createSkillLookup =\n (catalog: Catalog) =>\n (skillId: string): CatalogSkill | undefined =>\n catalog.skillsById[skillId]\n\n/** The lookup bound to the vendored catalogue. */\nexport const skillById = createSkillLookup(CATALOG)\n\nconst SHIPPED_IDS = new Set<string>(SKILL_IDS)\n\n/**\n * Whether this id is one the VENDORED catalogue ships.\n *\n * Not \"does some catalogue carry it\" — `skillById` answers that, of whichever\n * catalogue it is bound to. This is the narrower question, and the only surface\n * that needs it is a table authored against the shipped ids: a marketplace's\n * skill cannot have a row in one by construction, so it is outside the table\n * rather than left out of it.\n */\nexport const isShippedSkillId = (skillId: string): skillId is SkillId =>\n SHIPPED_IDS.has(skillId)\n","// AUTO-GENERATED from packages/cli/src/agents/*/*/metadata.yaml in this repo.\n// Do not edit manually — run `bun run generate` in packages/matrix.\n// Fills the AGENT_DEFINITIONS gap described in the CLI's todo/D-239.\n\nimport type { AgentName } from \"../vendor/generated/source-types\"\nimport type { ModelName, PermissionMode } from \"../vendor/matrix\"\n\n/** Agent metadata as shipped by the CLI's per-agent metadata.yaml files. */\nexport type GeneratedAgentDefinition = {\n id: AgentName\n title: string\n description: string\n model?: ModelName\n tools: string[]\n disallowedTools?: string[]\n permissionMode?: PermissionMode\n outputFormat?: string\n /** Agent role, from the CLI's src/agents/<flavor>/ directory. */\n flavor: string\n /** Path relative to the CLI's src/agents/. */\n path: string\n}\n\nexport const AGENT_DEFINITIONS = {\n \"agent-summoner\": {\n \"id\": \"agent-summoner\",\n \"title\": \"Agent Summoner Agent\",\n \"description\": \"Expert in creating agents and skills - understands agent architecture deeply - invoke when you need to create, improve, or analyze agents/skills\",\n \"model\": \"opus\",\n \"tools\": [\"Read\",\"Write\",\"Edit\",\"Grep\",\"Glob\",\"Bash\"],\n \"flavor\": \"meta\",\n \"path\": \"meta/agent-summoner\",\n },\n \"ai-developer\": {\n \"id\": \"ai-developer\",\n \"title\": \"AI Developer Agent\",\n \"description\": \"Implements AI features from specs - RAG pipelines, agent loops, tool calling, prompt engineering, streaming responses, embedding workflows, multi-model orchestration - surgical execution following existing patterns\",\n \"model\": \"opus\",\n \"tools\": [\"Read\",\"Write\",\"Edit\",\"Grep\",\"Glob\",\"Bash\"],\n \"flavor\": \"developer\",\n \"path\": \"developer/ai-developer\",\n },\n \"ai-researcher\": {\n \"id\": \"ai-researcher\",\n \"title\": \"AI Researcher Agent\",\n \"description\": \"Read-only AI codebase research specialist - discovers prompt templates and prompt-assembly code, catalogs model and provider SDK usage, maps RAG and embedding pipelines and vector stores, documents tool-calling schemas and agentic loops, finds eval setups, token budgeting, streaming and caching patterns - produces structured findings for ai-developer and the pm - invoke for AI research before implementation\",\n \"model\": \"opus\",\n \"tools\": [\"Read\",\"Grep\",\"Glob\",\"Bash\"],\n \"flavor\": \"researcher\",\n \"path\": \"researcher/ai-researcher\",\n },\n \"ai-tester\": {\n \"id\": \"ai-tester\",\n \"title\": \"AI Tester Agent\",\n \"description\": \"Tests AI features - mocks LLM and provider calls at deterministic seams, unit-tests prompt assembly and context construction, validates tool-call and structured-output schemas, covers retry/fallback/rate-limit/streaming paths, asserts token and cost budgets, writes prompt regression snapshots, and builds eval harnesses with golden datasets kept out of CI - invoke BEFORE or AFTER ai-developer implements features\",\n \"model\": \"opus\",\n \"tools\": [\"Read\",\"Write\",\"Edit\",\"Grep\",\"Glob\",\"Bash\"],\n \"flavor\": \"tester\",\n \"path\": \"tester/ai-tester\",\n },\n \"api-developer\": {\n \"id\": \"api-developer\",\n \"title\": \"API Developer Agent\",\n \"description\": \"Implements backend features from detailed specs - API routes, database operations, server utilities, authentication, middleware - surgical execution following existing patterns - invoke AFTER the pm creates the spec\",\n \"model\": \"opus\",\n \"tools\": [\"Read\",\"Write\",\"Edit\",\"Grep\",\"Glob\",\"Bash\"],\n \"flavor\": \"developer\",\n \"path\": \"developer/api-developer\",\n },\n \"api-researcher\": {\n \"id\": \"api-researcher\",\n \"title\": \"API Researcher Agent\",\n \"description\": \"Read-only backend research specialist - discovers API route patterns, understands database schemas and ORM patterns, catalogs middleware and authentication flows, finds similar service implementations - produces structured findings for api-developer - invoke for backend research before implementation\",\n \"model\": \"opus\",\n \"tools\": [\"Read\",\"Grep\",\"Glob\",\"Bash\"],\n \"flavor\": \"researcher\",\n \"path\": \"researcher/api-researcher\",\n },\n \"api-tester\": {\n \"id\": \"api-tester\",\n \"title\": \"API Tester Agent\",\n \"description\": \"Tests backend features - API endpoint integration tests, database operation tests, auth flow tests, middleware chain tests, error response validation - invoke BEFORE or AFTER api-developer implements features\",\n \"model\": \"sonnet\",\n \"tools\": [\"Read\",\"Write\",\"Edit\",\"Grep\",\"Glob\",\"Bash\"],\n \"flavor\": \"tester\",\n \"path\": \"tester/api-tester\",\n },\n \"cli-developer\": {\n \"id\": \"cli-developer\",\n \"title\": \"CLI Developer Agent\",\n \"description\": \"Implements CLI features from detailed specs - CLI commands, interactive prompts, option parsing, config hierarchies, exit codes - surgical execution following existing patterns - invoke AFTER pm creates spec\",\n \"model\": \"opus\",\n \"tools\": [\"Read\",\"Write\",\"Edit\",\"Grep\",\"Glob\",\"Bash\"],\n \"flavor\": \"developer\",\n \"path\": \"developer/cli-developer\",\n },\n \"cli-researcher\": {\n \"id\": \"cli-researcher\",\n \"title\": \"CLI Researcher Agent\",\n \"description\": \"Read-only CLI research specialist - discovers command registration and structure patterns, catalogs interactive prompt and TUI component conventions, understands flag parsing and config hierarchies, maps exit-code, error-handling and output-formatting conventions, finds testing seams - produces structured findings for cli-developer and the pm - invoke for CLI research before implementation\",\n \"model\": \"opus\",\n \"tools\": [\"Read\",\"Grep\",\"Glob\",\"Bash\"],\n \"flavor\": \"researcher\",\n \"path\": \"researcher/cli-researcher\",\n },\n \"cli-tester\": {\n \"id\": \"cli-tester\",\n \"title\": \"CLI Tester Agent\",\n \"description\": \"Tests CLI applications - wizard flows, commands, keyboard interactions, file system outputs - invoke BEFORE or AFTER cli-developer implements features\",\n \"model\": \"opus\",\n \"tools\": [\"Read\",\"Write\",\"Edit\",\"Grep\",\"Glob\",\"Bash\"],\n \"flavor\": \"tester\",\n \"path\": \"tester/cli-tester\",\n },\n \"codex-keeper\": {\n \"id\": \"codex-keeper\",\n \"title\": \"Codex Keeper Agent\",\n \"description\": \"Creates AI-focused reference documentation (architecture, types, store maps, commands) that helps other agents understand where and how to implement features. Works incrementally, tracking progress over time.\",\n \"model\": \"opus\",\n \"tools\": [\"Read\",\"Write\",\"Edit\",\"Glob\",\"Grep\",\"Bash\"],\n \"flavor\": \"meta\",\n \"path\": \"meta/codex-keeper\",\n },\n \"convention-keeper\": {\n \"id\": \"convention-keeper\",\n \"title\": \"Convention Keeper Agent\",\n \"description\": \"Reviews accumulated findings from sub-agent work, cross-references against existing standards docs, and proposes targeted documentation updates to prevent recurrence of anti-patterns\",\n \"model\": \"sonnet\",\n \"tools\": [\"Read\",\"Write\",\"Edit\",\"Grep\",\"Glob\",\"Bash\"],\n \"flavor\": \"meta\",\n \"path\": \"meta/convention-keeper\",\n },\n \"pm\": {\n \"id\": \"pm\",\n \"title\": \"PM and Architect Agent\",\n \"description\": \"Creates implementation specs for any feature - frontend, backend, CLI, and AI alike - by researching the codebase's real patterns and naming the ones to follow, with fenced scope and verifiable success criteria; domain planning frameworks arrive via meta-planning skills - invoke BEFORE a developer for any new feature\",\n \"model\": \"opus\",\n \"tools\": [\"Read\",\"Write\",\"Edit\",\"Grep\",\"Glob\",\"Bash\"],\n \"flavor\": \"planning\",\n \"path\": \"planning/pm\",\n },\n \"reviewer\": {\n \"id\": \"reviewer\",\n \"title\": \"Reviewer Agent\",\n \"description\": \"Reviews any diff - web, API, CLI, AI, and infrastructure code alike - one severity-disciplined quality gate for correctness, security, and convention adherence; domain-specific checklists arrive via meta-reviewing skills\",\n \"model\": \"opus\",\n \"tools\": [\"Read\",\"Write\",\"Edit\",\"Grep\",\"Glob\",\"Bash\"],\n \"flavor\": \"reviewer\",\n \"path\": \"reviewer/reviewer\",\n },\n \"skill-summoner\": {\n \"id\": \"skill-summoner\",\n \"title\": \"Skill Summoner Agent\",\n \"description\": \"Creates technology-specific skills by researching best practices and comparing with codebase standards - use for state management, styling, API frameworks, and other technology skills\",\n \"model\": \"opus\",\n \"tools\": [\"Read\",\"Write\",\"Edit\",\"Grep\",\"Glob\",\"WebSearch\",\"WebFetch\"],\n \"flavor\": \"meta\",\n \"path\": \"meta/skill-summoner\",\n },\n \"web-developer\": {\n \"id\": \"web-developer\",\n \"title\": \"Web Developer Agent\",\n \"description\": \"Implements frontend features from detailed specs - UI components, TypeScript, styling, client state - surgical execution following existing patterns - invoke AFTER the pm creates the spec\",\n \"model\": \"opus\",\n \"tools\": [\"Read\",\"Write\",\"Edit\",\"Grep\",\"Glob\",\"Bash\"],\n \"flavor\": \"developer\",\n \"path\": \"developer/web-developer\",\n },\n \"web-researcher\": {\n \"id\": \"web-researcher\",\n \"title\": \"Web Researcher Agent\",\n \"description\": \"Read-only frontend research specialist - discovers UI component patterns, catalogs design systems, understands styling methodology and tokens, finds similar component implementations - produces structured findings for web-developer - invoke for frontend research before implementation\",\n \"model\": \"opus\",\n \"tools\": [\"Read\",\"Grep\",\"Glob\",\"Bash\"],\n \"flavor\": \"researcher\",\n \"path\": \"researcher/web-researcher\",\n },\n \"web-tester\": {\n \"id\": \"web-tester\",\n \"title\": \"Web Tester Agent\",\n \"description\": \"Writes tests BEFORE implementation - all test types (*.test.*, *.spec.*, E2E) - Tester red-green-refactor - invoke BEFORE developer implements feature\",\n \"model\": \"opus\",\n \"tools\": [\"Read\",\"Write\",\"Edit\",\"Grep\",\"Glob\",\"Bash\"],\n \"flavor\": \"tester\",\n \"path\": \"tester/web-tester\",\n },\n} as const satisfies Record<AgentName, GeneratedAgentDefinition>\n","// The validation boundary for `AGENT_DEFINITIONS` — the built-in sub-agent\n// roster, generated from the CLI's per-agent `metadata.yaml` files.\n//\n// It sits beside `built-in-matrix.ts` rather than inside it because the roster\n// is not part of the matrix: `MergedSkillsMatrix` carries categories, skills\n// and stacks, and the agents are a second generated artefact with a second\n// consumer (`read-model/sub-agents.ts`). The two boundaries narrow against the\n// same generated vocabularies and answer different questions.\n\nimport { z } from \"zod\"\nimport { AGENT_NAMES } from \"./vendor/generated/source-types\"\nimport { MODEL_NAMES } from \"./vendor/matrix\"\n\nconst agentNameSchema = z.enum(AGENT_NAMES)\nconst modelNameSchema = z.enum(MODEL_NAMES)\n\nexport const agentDefinitionSchema = z.object({\n id: agentNameSchema,\n title: z.string(),\n description: z.string(),\n model: modelNameSchema.exactOptional(),\n tools: z.array(z.string()),\n // Not narrowed here: which roles are sayable is authored in the read model's\n // preload table — so the check lives where the list does, in `flavorOf`,\n // rather than the list being imported back into the boundary.\n flavor: z.string(),\n})\n\nexport const agentDefinitionsSchema = z.record(\n z.string(),\n agentDefinitionSchema\n)\n\nexport type ParsedAgentDefinition = z.infer<typeof agentDefinitionSchema>\n","// Vendored byte-for-byte into packages/matrix/src/vendor/ by scripts/generate-matrix-package.ts.\n// ANY edit here — a comment-only one included — obliges `bun run generate:matrix` in packages/cli;\n// `generate:matrix:check` is the gate.\n\nimport type { CategoryPath, SkillSlug, SkillId } from \"./skills\";\nimport type { AgentName } from \"./agents\";\n\nexport type { Category, Domain } from \"./generated/source-types\";\nexport { CATEGORIES, DOMAINS } from \"./generated/source-types\";\n\n// Import locally for use within this file\nimport type { Category, Domain } from \"./generated/source-types\";\n\n/** Claude model selectors for agent configuration */\nexport const MODEL_NAMES = [\"sonnet\", \"opus\", \"haiku\", \"fable\", \"inherit\"] as const;\nexport type ModelName = (typeof MODEL_NAMES)[number];\n\n/** Reasoning effort levels for agent configuration */\nexport const EFFORT_NAMES = [\"low\", \"medium\", \"high\", \"xhigh\", \"max\"] as const;\nexport type EffortLevel = (typeof EFFORT_NAMES)[number];\n\n/** Agent permission modes for Claude Code tool access */\nexport const PERMISSION_MODES = [\n \"default\",\n \"acceptEdits\",\n \"dontAsk\",\n \"bypassPermissions\",\n \"plan\",\n \"delegate\",\n] as const;\nexport type PermissionMode = (typeof PERMISSION_MODES)[number];\n\n/**\n * Category definitions indexed by category ID.\n * Partial because not every Category has a category definition (e.g., a marketplace\n * may only define a subset of all possible categories).\n */\nexport type CategoryMap = Partial<Record<Category, CategoryDefinition>>;\n\n/**\n * Full domain selections used throughout the wizard pipeline (store, components, result).\n *\n * Structure: `{ domain: { category: [skillId, ...] } }`\n *\n * - Outer Partial: not all domains need selections (user may skip \"mobile\" entirely)\n * - Inner Partial: within a domain, only some categories may have selections\n * - SkillId[]: a category can have multiple skills unless `CategoryDefinition.exclusive` is true\n */\nexport type DomainSelections = Partial<Record<Domain, Partial<Record<Category, SkillId[]>>>>;\n\n/** Single category definition from skill-categories.ts */\nexport type CategoryDefinition = {\n id: Category;\n displayName: string;\n description: string;\n /** Domain for wizard domain filtering */\n domain?: Domain;\n /** If true, only one skill can be selected in this category (radio behavior). */\n exclusive: boolean;\n /** If true, the user must select at least one skill before proceeding. */\n required: boolean;\n /** Display order within domain (lower = earlier) */\n order: number;\n icon?: string;\n};\n\n/** Relationship rules between skills from skill-rules.ts */\nexport type RelationshipDefinitions = {\n /** Selecting one disables the others */\n conflicts: ConflictRule[];\n /** Selecting one shows warning for others but doesn't disable */\n discourages: DiscourageRule[];\n /** Skill A requires skill B to be selected first */\n requires: RequireRule[];\n /** Groups of interchangeable skills for the same purpose */\n alternatives: AlternativeGroup[];\n};\n\n/** Base shape for skill-group rules: a set of related slugs plus a reason */\nexport type SkillGroupRule = {\n /** Skill slugs (resolved to canonical IDs by matrix-loader) */\n skills: SkillSlug[];\n reason: string;\n};\n\n/** Mutual exclusion rule - selecting any one skill disables ALL others */\nexport type ConflictRule = SkillGroupRule;\n\n/** Soft conflict rule - selecting any one shows a warning for ALL others */\nexport type DiscourageRule = SkillGroupRule;\n\n/** Dependency rule - skill A requires skill B to be selected first */\nexport type RequireRule = {\n skill: SkillSlug;\n /** Skill slugs that must be selected before this one */\n needs: SkillSlug[];\n /**\n * If true, only ONE of the `needs` skills is required (OR logic).\n * If false/undefined, ALL are required (AND logic).\n * @default false\n */\n needsAny?: boolean;\n reason: string;\n};\n\n/** Group of interchangeable skills serving the same purpose */\nexport type AlternativeGroup = {\n purpose: string;\n skills: SkillSlug[];\n};\n\n/** Parsed configuration from skill-rules.ts */\nexport type SkillRulesConfig = {\n version: string;\n /** Aggregate relationship rules between skills */\n relationships: RelationshipDefinitions;\n};\n\n/** Bidirectional slug <-> skill ID mapping. Partial because only extracted skills are present. */\nexport type SkillSlugMap = {\n /** Forward: slug -> canonical skill ID */\n slugToId: Partial<Record<SkillSlug, SkillId>>;\n /** Reverse: canonical skill ID -> slug */\n idToSlug: Partial<Record<SkillId, SkillSlug>>;\n};\n\n/**\n * Output of mergeMatrixWithSkills() combining skill-categories.ts + skill-rules.ts with extracted metadata.\n * This is the primary read model consumed by the wizard and CLI commands.\n */\nexport type MergedSkillsMatrix = {\n version: string;\n categories: CategoryMap;\n /** Indexed by full skill ID for O(1) lookup */\n skills: Partial<Record<SkillId, ResolvedSkill>>;\n /** Stacks with all skill aliases resolved to canonical IDs */\n suggestedStacks: ResolvedStack[];\n /** Bidirectional slug <-> ID mapping */\n slugMap: SkillSlugMap;\n /**\n * Slugs the relationship rules name that no skill in this matrix carries.\n * Absent when every reference resolved. Resolution drops such a reference and\n * warns; carrying the list is what lets `checkMatrixHealth` report the typo\n * against the source that shipped it rather than only logging it.\n */\n unresolvedSlugs?: SkillSlug[];\n /** Explicit domain definitions from agent metadata files */\n agentDefinedDomains?: Partial<Record<AgentName, Domain>>;\n /** ISO timestamp of when this matrix was generated */\n generatedAt: string;\n};\n\n/**\n * Identity/description fields shared by ExtractedSkillMetadata (pre-merge) and\n * ResolvedSkill (post-merge). Both types are `SkillCore & { extras }`; extracting\n * the common shape keeps the two skill surfaces in sync. Purely structural — no\n * runtime change (the intersection is equivalent to the flattened object).\n */\nexport type SkillCore = {\n id: SkillId;\n /** Kebab-case short key for alias resolution, search, and relationship rules (e.g., \"react\") */\n slug: SkillSlug;\n /** Title-cased label for UI display (e.g., \"React\", \"Apollo Client\") */\n displayName: string;\n description: string;\n /** When an AI agent should invoke this skill (decision criteria) */\n usageGuidance?: string;\n /** Matches key in matrix.categories; determines which wizard category grid this skill appears in */\n category: CategoryPath;\n /** Author handle (e.g., \"@vince\") from metadata.yaml */\n author: string;\n /** Relative path from src/ to the skill directory */\n path: string;\n /** True if from .claude/skills/ (user-defined local skill) */\n local?: boolean;\n /** Absolute path to local skill directory */\n localPath?: string;\n /** True if this skill was created outside the CLI's built-in vocabulary */\n custom?: boolean;\n};\n\n/**\n * Single skill with all computed relationships resolved for CLI rendering.\n * Produced by mergeMatrixWithSkills() after resolving aliases, relationships, and sources.\n */\nexport type ResolvedSkill = SkillCore & {\n /** Selecting this skill disables these others (hard exclusion) */\n conflictsWith: SkillRelation[];\n /** Skills that THIS skill requires (must select first) */\n requires: SkillRequirement[];\n /** Other skills that serve the same purpose (informational, not enforced) */\n alternatives: SkillAlternative[];\n /** Selecting this skill shows a warning for these others (soft conflict) */\n discourages: SkillRelation[];\n /** All known sources that provide this skill (populated by multi-source-loader) */\n availableSources?: SkillSource[];\n /** Currently active/installed source (if any) */\n activeSource?: SkillSource;\n};\n\n/** Skill-to-skill relationship with reason */\nexport type SkillRelation = {\n skillId: SkillId;\n reason: string;\n};\n\n/** Resolved skill dependency with AND/OR logic */\nexport type SkillRequirement = {\n skillIds: SkillId[];\n /**\n * If true, only ONE of skillIds is needed (OR).\n * If false, ALL are needed (AND).\n *\n * Always present. The absence this field could have carried is resolved one step upstream:\n * `resolveRelationships` in `lib/matrix/skill-resolution.ts` writes\n * `rule.needsAny ?? false` from the optional {@link RequireRule.needsAny}, so nothing\n * downstream of resolution ever meets an unset value.\n */\n needsAny: boolean;\n reason: string;\n};\n\n/** Alternative skill that serves the same purpose */\nexport type SkillAlternative = {\n skillId: SkillId;\n purpose: string;\n};\n\n/** Stack with resolved skill IDs and agent mappings */\nexport type ResolvedStack = {\n id: string;\n name: string;\n description: string;\n /** Skill selections with resolved full skill IDs by category */\n skills: Partial<Record<AgentName, Partial<Record<Category, SkillId[]>>>>;\n /** Flat list of all skill IDs in this stack */\n allSkillIds: SkillId[];\n philosophy: string;\n /** UI grouping label for the stack selection screen (e.g., \"React\", \"CLI\") */\n group?: string;\n};\n\n/** Short alias used for category-level search (e.g., \"react\", \"zustand\") */\nexport type SkillAlias = string;\n\n/** Source type classification for skill provenance (where the skill comes from) */\nexport const SKILL_SOURCE_TYPES = [\"public\", \"private\", \"local\"] as const;\nexport type SkillSourceType = (typeof SKILL_SOURCE_TYPES)[number];\n\n/**\n * How a project's skills are installed: fully ejected, fully plugin-based, or a\n * mix of both. Derived at runtime from SkillConfig.origin (see deriveInstallMode).\n */\nexport type InstallMode = \"eject\" | \"plugin\" | \"mixed\";\n\n/** A single source from which a skill can be obtained */\nexport type SkillSource = {\n /** Source identifier: \"public\", marketplace name, \"local\" */\n name: string;\n type: SkillSourceType;\n /** Source URL for remote sources (e.g., \"github:acme-corp/claude-skills\") */\n url?: string;\n /** Whether this source's version is currently installed on disk */\n installed: boolean;\n /** How the skill was installed on disk (separate from provenance) — a single skill is never \"mixed\" */\n installMode?: Exclude<InstallMode, \"mixed\">;\n /** True for the primary marketplace source (scoped or default public). Set by multi-source-loader. */\n primary?: boolean;\n};\n\n/** Advisory visual state for a skill option in the wizard UI */\nexport type OptionState =\n | { status: \"normal\" }\n | { status: \"discouraged\"; reason: string }\n | { status: \"incompatible\"; reason: string };\n\n/**\n * Skill option as displayed in the wizard, computed based on current selections.\n * Recomputed by matrix-resolver on every selection change.\n */\nexport type SkillOption = {\n id: SkillId;\n /** Advisory state computed from matrix relationships (incompatible > discouraged > normal) */\n advisoryState: OptionState;\n /** True if this skill is currently selected by the user */\n selected: boolean;\n /** True when this skill is selected but has unmet dependency requirements */\n hasUnmetRequirements: boolean;\n /** Explains which requirements are unmet (only set when hasUnmetRequirements is true) */\n unmetRequirementsReason?: string;\n /** Other skills that serve the same purpose (for \"or try X\" hints) */\n alternatives: SkillId[];\n};\n\n/** Result of validating the current skill selections */\nexport type SelectionValidation = {\n valid: boolean;\n errors: ValidationError[];\n};\n\n/** Advisory validation error (non-blocking) */\nexport type ValidationError = {\n type: \"conflict\" | \"missingRequirement\" | \"categoryExclusive\";\n message: string;\n skills: SkillId[];\n};\n\n/**\n * Skill metadata extracted from SKILL.md frontmatter + metadata.yaml before matrix merge.\n *\n * Relationship fields (conflictsWith, requires, etc.) are resolved from\n * centralized group-based declarations in skill-rules.ts — not from individual skill metadata.\n */\nexport type ExtractedSkillMetadata = SkillCore & {\n /** Directory path for filesystem access, e.g. \"web/framework/react\" */\n directoryPath: string;\n /** Domain this skill belongs to (e.g., \"web\", \"api\", \"cli\") */\n domain: Domain;\n};\n","import { AGENT_DEFINITIONS } from \"../generated/agents\"\nimport {\n SKILL_IDS,\n type AgentName,\n type Domain,\n type SkillId,\n} from \"../vendor/generated/source-types\"\nimport { CATALOG } from \"./catalog\"\nimport { agentDomainOf } from \"./domains\"\n\n// The one place that answers \"does this skill arrive preloaded on this agent?\".\n// Both surfaces resolve against it — the editor's default assignments and the\n// CLI's config generator — so the same pick lands the same way on either side.\n//\n// A table hit is necessary but not sufficient: the owner's domain-affinity\n// ruling gates the default, so a role row only preloads on the skill's own\n// domain's agents. Shared skills have no home domain to gate to, and meta\n// skills' rows pass as authored — those two read the row alone.\n//\n// Hand-written and browser-safe: no filesystem, no I/O, nothing Node-only, at\n// import time or ever. The editor bundles this module.\n\n/** What a compiled agent does with a skill it carries. */\nexport type LoadState = \"lazy\" | \"preloaded\"\n\n/**\n * Every role the roster carries, in the order the table lists them. Naming one\n * in an entry preloads that skill on all of that role's agents — `developer`\n * covers web, api, ai and cli alike. `satisfies` binds each one to a role the\n * roster actually has; `flavorOf` below covers the other direction, a roster\n * role this list does not name.\n */\nexport const ROLE_FLAVORS = [\n \"developer\",\n \"planning\",\n \"researcher\",\n \"reviewer\",\n \"tester\",\n \"meta\",\n] as const satisfies readonly (typeof AGENT_DEFINITIONS)[AgentName][\"flavor\"][]\n\n// The listable roles, and nothing else. Anchored to the list above rather than\n// to the roster, so what an entry may say is authored here and the generated\n// agent data is checked against it — not the other way round.\nexport type RoleFlavor = (typeof ROLE_FLAVORS)[number]\n\n/**\n * A list of what IS preloaded: skill → the roles that carry it eagerly. Sparse\n * on purpose, so absence is lazy — the same thing a missing flag means in an\n * emitted config. There is deliberately no way to write \"lazy\" here; a second\n * spelling of the default is a second thing to disagree with it.\n */\nexport type PreloadDefaults = Readonly<\n Partial<Record<SkillId, readonly RoleFlavor[]>>\n>\n\nexport type ResolveLoadStateInput = {\n skillId: SkillId\n agentId: AgentName\n /** The author's word — a curated stack flag, or the user's saved config. */\n explicit?: LoadState\n}\n\n/**\n * The shipped table, authored per skill: the role flavors that carry it\n * eagerly. Grouped by domain, and read as \"what this role reaches for in most\n * of its sessions\" — a skill that matters occasionally is worth loading when\n * it does, not in every prompt. Setup skills are absent by rule: setting a\n * project up is one session, never most of them.\n *\n * The `reviewer` flavor is narrower still, by the owner's ruling: the\n * framework a diff is written in and the review process itself, and nothing\n * else. What to look for in ONE diff — a database's pitfalls, a security list\n * — reaches the reviewer lazily and arrives per diff through the\n * `meta-reviewing-*` checklists, which is why none of them carries a row.\n *\n * The `planning` flavor is narrowed the same way, one kind wider: the PM needs\n * to know WHAT the project is built with in most of its spec sessions, so the\n * framework and the state kind — where the app keeps its state — stay. The\n * depth beneath them is a different question: which database, which UI\n * library, how to make any of them fast or accessible. That arrives when the\n * spec touches it, so those rows name the builders and the researcher and\n * stop there. Consolidated, the planner is domainless like the reviewer, so\n * these rows land on it whatever domain they belong to — a full-stack spec is\n * one agent's work.\n *\n * The AI domain expresses that same breadth under other names, by the owner's\n * 2026-08-07 ruling: the catalog gives it no framework category at all, and an\n * AI project is built on the provider SDK it calls plus the orchestration\n * framework it calls it through — so those two kinds carry the planner the way\n * a framework does. The capability skills sharing the provider category —\n * speech, vision, transcription — are what a feature reaches for rather than\n * what the project runs on, and stay absent like any other occasional body.\n *\n * One skill per line, which is why the formatter is held off below: at 80\n * columns Prettier gives each five-role entry seven lines, turning a 144-row\n * table into 600 and a one-role change into a seven-line diff.\n */\n// prettier-ignore\nexport const PRELOAD_DEFAULTS: PreloadDefaults = {\n // Web — frameworks, the concerns built on them, and the tests\n \"web-framework-angular-standalone\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"web-framework-react\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"web-framework-solidjs\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"web-framework-svelte\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"web-framework-vue-composition-api\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"web-meta-framework-astro\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"web-meta-framework-docusaurus\": [\"developer\", \"planning\", \"researcher\", \"reviewer\"],\n \"web-meta-framework-nextjs\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"web-meta-framework-nuxt\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"web-meta-framework-qwik\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"web-meta-framework-remix\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"web-meta-framework-sveltekit\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"web-meta-framework-vitepress\": [\"developer\", \"planning\", \"researcher\", \"reviewer\"],\n \"web-state-jotai\": [\"developer\", \"planning\", \"researcher\"],\n \"web-state-mobx\": [\"developer\", \"planning\", \"researcher\"],\n \"web-state-ngrx-signalstore\": [\"developer\", \"planning\", \"researcher\"],\n \"web-state-pinia\": [\"developer\", \"planning\", \"researcher\"],\n \"web-state-redux-toolkit\": [\"developer\", \"planning\", \"researcher\"],\n \"web-state-zustand\": [\"developer\", \"planning\", \"researcher\"],\n \"web-data-fetching-graphql-apollo\": [\"developer\", \"planning\", \"researcher\"],\n \"web-data-fetching-graphql-urql\": [\"developer\", \"planning\", \"researcher\"],\n \"web-data-fetching-swr\": [\"developer\", \"planning\", \"researcher\"],\n \"web-data-fetching-trpc\": [\"developer\", \"planning\", \"researcher\"],\n \"web-server-state-react-query\": [\"developer\", \"planning\", \"researcher\"],\n \"web-forms-react-hook-form\": [\"developer\"],\n \"web-forms-tanstack-form\": [\"developer\"],\n \"web-forms-vee-validate\": [\"developer\"],\n \"web-forms-zod-validation\": [\"developer\", \"researcher\"],\n \"web-styling-cva\": [\"developer\", \"researcher\"],\n \"web-styling-design-tokens\": [\"developer\", \"researcher\"],\n \"web-styling-scss-modules\": [\"developer\", \"researcher\"],\n \"web-styling-tailwind\": [\"developer\", \"researcher\"],\n \"web-ui-ant-design\": [\"developer\", \"researcher\"],\n \"web-ui-base-ui\": [\"developer\", \"researcher\"],\n \"web-ui-chakra-ui\": [\"developer\", \"researcher\"],\n \"web-ui-headless-ui\": [\"developer\", \"researcher\"],\n \"web-ui-mantine\": [\"developer\", \"researcher\"],\n \"web-ui-mui\": [\"developer\", \"researcher\"],\n \"web-ui-radix-ui\": [\"developer\", \"researcher\"],\n \"web-ui-shadcn-ui\": [\"developer\", \"researcher\"],\n \"web-ui-vuetify\": [\"developer\", \"researcher\"],\n \"web-performance-web-performance\": [\"developer\", \"researcher\"],\n \"web-accessibility-web-accessibility\": [\"developer\", \"researcher\"],\n \"web-routing-react-router\": [\"developer\"],\n \"web-routing-tanstack-router\": [\"developer\"],\n \"web-error-handling-result-types\": [\"developer\"],\n \"web-i18n-next-intl\": [\"developer\"],\n \"web-i18n-react-intl\": [\"developer\"],\n \"web-i18n-vue-i18n\": [\"developer\"],\n \"web-pwa-offline-first\": [\"developer\", \"researcher\"],\n \"web-mocks-msw\": [\"tester\"],\n \"web-testing-cypress-e2e\": [\"tester\"],\n \"web-testing-playwright-e2e\": [\"tester\"],\n \"web-testing-react-testing-library\": [\"tester\"],\n \"web-testing-visual-regression\": [\"tester\"],\n \"web-testing-vitest\": [\"tester\"],\n \"web-testing-vue-test-utils\": [\"tester\"],\n \"web-utilities-native-js\": [\"developer\"],\n \"web-utilities-vueuse\": [\"developer\"],\n\n // API — frameworks, data, auth, and the safety around them\n \"api-framework-express\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"api-framework-fastify\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"api-framework-hono\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"api-framework-nestjs\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"api-framework-elysia\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"api-auth-better-auth-drizzle-hono\": [\"developer\", \"researcher\"],\n \"api-auth-clerk\": [\"developer\"],\n \"api-auth-nextauth\": [\"developer\"],\n \"api-baas-appwrite\": [\"developer\", \"researcher\"],\n \"api-baas-firebase\": [\"developer\", \"researcher\"],\n \"api-baas-neon\": [\"developer\", \"researcher\"],\n \"api-baas-planetscale\": [\"developer\", \"researcher\"],\n \"api-baas-supabase\": [\"developer\", \"researcher\"],\n \"api-baas-turso\": [\"developer\", \"researcher\"],\n \"api-database-cockroachdb\": [\"developer\", \"researcher\"],\n \"api-database-drizzle\": [\"developer\", \"researcher\"],\n \"api-database-edgedb\": [\"developer\", \"researcher\"],\n \"api-database-knex\": [\"developer\", \"researcher\"],\n \"api-database-mongodb\": [\"developer\", \"researcher\"],\n \"api-database-mongoose\": [\"developer\", \"researcher\"],\n \"api-database-mysql\": [\"developer\", \"researcher\"],\n \"api-database-postgresql\": [\"developer\", \"researcher\"],\n \"api-database-prisma\": [\"developer\", \"researcher\"],\n \"api-database-redis\": [\"developer\", \"researcher\"],\n \"api-database-sequelize\": [\"developer\", \"researcher\"],\n \"api-database-surrealdb\": [\"developer\", \"researcher\"],\n \"api-database-typeorm\": [\"developer\", \"researcher\"],\n \"api-database-upstash\": [\"developer\", \"researcher\"],\n \"api-database-vercel-kv\": [\"developer\", \"researcher\"],\n \"api-database-vercel-postgres\": [\"developer\", \"researcher\"],\n \"api-graphql-apollo-server\": [\"developer\", \"researcher\", \"tester\"],\n \"api-graphql-mercurius\": [\"developer\", \"researcher\", \"tester\"],\n \"api-graphql-yoga\": [\"developer\", \"researcher\", \"tester\"],\n \"api-performance-api-performance\": [\"developer\", \"researcher\"],\n \"api-specs-openapi\": [\"developer\"],\n \"api-observability-axiom-pino-sentry\": [\"developer\"],\n\n // Mobile\n \"mobile-framework-react-native\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"mobile-framework-expo\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"mobile-navigation-expo-router\": [\"developer\"],\n \"mobile-navigation-react-navigation\": [\"developer\"],\n \"mobile-styling-nativewind\": [\"developer\", \"researcher\"],\n \"mobile-styling-unistyles\": [\"developer\", \"researcher\"],\n \"mobile-ui-components-react-native-paper\": [\"developer\", \"researcher\"],\n \"mobile-ui-components-tamagui\": [\"developer\", \"researcher\"],\n \"mobile-storage-sqlite-powersync\": [\"developer\", \"researcher\"],\n \"mobile-storage-watermelondb\": [\"developer\", \"researcher\"],\n \"mobile-performance-react-native\": [\"developer\", \"researcher\"],\n \"mobile-testing-detox\": [\"tester\"],\n \"mobile-testing-maestro\": [\"tester\"],\n\n // Desktop\n \"desktop-framework-electron\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"desktop-framework-tauri\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"desktop-backend-tauri\": [\"developer\", \"researcher\"],\n \"desktop-ipc-electron\": [\"developer\", \"researcher\"],\n \"desktop-security-tauri\": [\"developer\", \"researcher\"],\n \"desktop-plugins-tauri\": [\"developer\"],\n \"desktop-testing-electron\": [\"tester\"],\n \"desktop-storage-electron\": [\"developer\", \"researcher\"],\n\n // AI — the provider and the orchestration around it are what the project is\n // built on, so they carry the planner too; evals and tracing test\n \"ai-infrastructure-huggingface-inference\": [\"developer\", \"researcher\"],\n \"ai-infrastructure-ollama\": [\"developer\", \"researcher\"],\n \"ai-infrastructure-replicate\": [\"developer\", \"researcher\"],\n \"ai-infrastructure-together-ai\": [\"developer\", \"researcher\"],\n \"ai-observability-langfuse\": [\"tester\"],\n \"ai-observability-promptfoo\": [\"tester\"],\n \"ai-orchestration-langchain\": [\"developer\", \"planning\", \"researcher\"],\n \"ai-orchestration-llamaindex\": [\"developer\", \"planning\", \"researcher\"],\n \"ai-orchestration-vercel-ai-sdk\": [\"developer\", \"planning\", \"researcher\"],\n \"ai-patterns-tool-use-patterns\": [\"developer\", \"researcher\"],\n \"ai-provider-anthropic-sdk\": [\"developer\", \"planning\", \"researcher\"],\n \"ai-provider-cohere-sdk\": [\"developer\", \"planning\", \"researcher\"],\n \"ai-provider-google-gemini-sdk\": [\"developer\", \"planning\", \"researcher\"],\n \"ai-provider-mistral-sdk\": [\"developer\", \"planning\", \"researcher\"],\n \"ai-provider-openai-sdk\": [\"developer\", \"planning\", \"researcher\"],\n\n // CLI — the framework and its prompts are the whole surface\n \"cli-framework-cli-commander\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"cli-framework-oclif-ink\": [\"developer\", \"planning\", \"researcher\", \"reviewer\", \"tester\"],\n \"cli-prompts-clack\": [\"developer\", \"researcher\", \"tester\"],\n\n // Infra — deployment is occasional, so almost nothing preloads\n \"infra-platform-cloudflare-workers\": [\"developer\"],\n\n // Meta — the review PROCESS is every review session's material; the domain\n // checklists are one diff's, so they carry no row and arrive per diff\n \"meta-design-composable-components\": [\"developer\"],\n \"meta-design-expressive-typescript\": [\"developer\"],\n \"meta-methodology-research-methodology\": [\"researcher\"],\n \"meta-reviewing-reviewing\": [\"reviewer\"],\n\n // Shared — carried across every implementation domain\n \"shared-security-auth-security\": [\"developer\", \"researcher\"],\n}\n\nconst KNOWN_SKILL_IDS = new Set<string>(SKILL_IDS)\nconst KNOWN_AGENT_IDS = new Set<string>(Object.keys(AGENT_DEFINITIONS))\nconst LISTABLE_FLAVORS = new Set<string>(ROLE_FLAVORS)\n\nconst assertKnownSkill = (skillId: SkillId) => {\n if (!KNOWN_SKILL_IDS.has(skillId))\n throw new Error(`Skill not found: ${skillId}`)\n}\n\nconst assertKnownAgent = (agentId: AgentName) => {\n if (!KNOWN_AGENT_IDS.has(agentId))\n throw new Error(`Agent not found: ${agentId}`)\n}\n\nconst isRoleFlavor = (flavor: string): flavor is RoleFlavor =>\n LISTABLE_FLAVORS.has(flavor)\n\n// A role the roster carries and `ROLE_FLAVORS` does not name is a role no\n// entry can be written for. Resolving it to lazy would read like a table that\n// left it out on purpose, so it is an error like any other unknown id.\n//\n// Exported because the read model's `SubAgent` carries a `RoleFlavor` too, and\n// two spellings of \"is this role sayable?\" is one more than the answer needs.\nexport const flavorOf = (agentId: AgentName): RoleFlavor => {\n const flavor = AGENT_DEFINITIONS[agentId].flavor\n // `String` because the guard narrows this branch to `never`: today's generated\n // roster names no flavor `ROLE_FLAVORS` lacks, so the two unions coincide and\n // the failure is unreachable *as typed*. Regenerating the roster with a new\n // flavor is what makes it reachable, which is the case worth naming — so the\n // message keeps the value rather than the branch being deleted for saying\n // something the current data makes true.\n if (!isRoleFlavor(flavor))\n throw new Error(\n `Role flavor not found: ${String(flavor)} (agent: ${agentId})`\n )\n\n return flavor\n}\n\n// Sparse both ways: a skill with no entry names no role, and an entry names\n// only the roles that carry it eagerly.\nconst listsFlavor = (\n listedFlavors: readonly RoleFlavor[] | undefined,\n flavor: RoleFlavor\n) => listedFlavors !== undefined && listedFlavors.includes(flavor)\n\n// The union knows the id, so a catalog with no domain for it is generated data\n// out of step with itself — an error like an unlistable flavor, not a lazy.\nconst domainOfSkill = (skillId: SkillId): Domain => {\n const skill = CATALOG.skillsById[skillId]\n if (!skill) throw new Error(`Skill domain not found: ${skillId}`)\n\n return skill.domainId\n}\n\n// A role agent with no domain prefix — the consolidated `reviewer` and `pm`.\n// Their ids trapdoor into the meta GROUP for display, but their roles serve\n// every implementation domain, which is exactly why they carry no prefix.\nconst isDomainlessRoleAgent = (agentId: AgentName): boolean =>\n agentDomainOf(agentId) === \"meta\" &&\n AGENT_DEFINITIONS[agentId].flavor !== \"meta\"\n\n// The domain-affinity gate on the default tier: a role row speaks for the\n// skill's own domain's agents. `shared` belongs to every implementation\n// domain, and a meta row names its flavors deliberately — both pass; a\n// cross-domain pair fails even on a role match, because an api developer is\n// not a web developer. A domainless role agent has no domain to fail the\n// match on, so its preloads are exactly the rows as authored.\nconst hasDomainAffinity = (skillDomain: Domain, agentId: AgentName): boolean =>\n skillDomain === \"shared\" ||\n skillDomain === \"meta\" ||\n skillDomain === agentDomainOf(agentId) ||\n isDomainlessRoleAgent(agentId)\n\n/**\n * Binds a resolver to a table. An explicit flag wins, then the gated table,\n * then lazy — but an id that does not exist is an error either way, since\n * taking the flag first is exactly how a typo in a saved config would go\n * unread.\n */\nexport const createLoadStateResolver =\n (defaults: PreloadDefaults) =>\n ({ skillId, agentId, explicit }: ResolveLoadStateInput): LoadState => {\n assertKnownSkill(skillId)\n assertKnownAgent(agentId)\n\n if (explicit !== undefined) return explicit\n\n return listsFlavor(defaults[skillId], flavorOf(agentId)) &&\n hasDomainAffinity(domainOfSkill(skillId), agentId)\n ? \"preloaded\"\n : \"lazy\"\n }\n\n/** The resolver both surfaces read: `PRELOAD_DEFAULTS`, bound. */\nexport const resolveLoadState = createLoadStateResolver(PRELOAD_DEFAULTS)\n","import { AGENT_DEFINITIONS } from \"../generated/agents\"\nimport {\n AGENT_NAMES,\n type AgentName,\n type Domain,\n} from \"../vendor/generated/source-types\"\nimport type { ModelName } from \"../vendor/matrix\"\nimport {\n agentDefinitionsSchema,\n type ParsedAgentDefinition,\n} from \"../built-in-agents\"\nimport { groupBy, indexById } from \"./collections\"\nimport { DOMAIN_LABELS, agentDomainOf, compareDomains } from \"./domains\"\nimport { flavorOf, type RoleFlavor } from \"./preload-defaults\"\n\nexport type SubAgent = {\n id: AgentName\n // Label inside its domain group — \"Developer\" for `web-developer`.\n label: string\n title: string\n description: string\n model?: ModelName\n domainId: Domain\n flavor: RoleFlavor\n}\n\nexport type SubAgentGroup = {\n domainId: Domain\n label: string\n agents: SubAgent[]\n}\n\n// Role fragments that are initialisms, so `pm` reads \"PM\" and not \"Pm\".\nconst ACRONYMS = new Set([\"pm\", \"ai\", \"api\", \"cli\", \"ui\", \"ux\", \"qa\"])\n\nconst titleCase = (words: string) =>\n words\n .split(\"-\")\n .map((word) =>\n ACRONYMS.has(word)\n ? word.toUpperCase()\n : word.charAt(0).toUpperCase() + word.slice(1)\n )\n .join(\" \")\n\n// `web-researcher` → \"Researcher\"; `codex-keeper` → \"Codex Keeper\".\nconst labelOf = (agentId: string, domainId: Domain) =>\n agentId.startsWith(`${domainId}-`)\n ? titleCase(agentId.slice(domainId.length + 1))\n : titleCase(agentId)\n\nconst toSubAgent = (definition: ParsedAgentDefinition): SubAgent => {\n const domainId = agentDomainOf(definition.id)\n return {\n id: definition.id,\n label: labelOf(definition.id, domainId),\n title: definition.title,\n description: definition.description,\n ...(definition.model !== undefined && { model: definition.model }),\n domainId,\n // The same string the definition carries, read back through the preload\n // table's list of sayable roles — a role no entry could name is an error\n // there, so it is one here rather than a flavor nothing routes on.\n flavor: flavorOf(definition.id),\n }\n}\n\nconst toSubAgentGroup = (\n domainId: Domain,\n agents: SubAgent[]\n): SubAgentGroup => ({\n domainId,\n label: DOMAIN_LABELS[domainId],\n agents: agents.sort((a, b) => a.label.localeCompare(b.label)),\n})\n\nconst buildSubAgentGroups = (): SubAgentGroup[] => {\n const agents = Object.values(\n agentDefinitionsSchema.parse(AGENT_DEFINITIONS)\n ).map(toSubAgent)\n\n return [...groupBy(agents, (agent) => agent.domainId)]\n .sort(([a], [b]) => compareDomains(a, b))\n .map(([domainId, domainAgents]) => toSubAgentGroup(domainId, domainAgents))\n}\n\nexport const SUB_AGENT_GROUPS = buildSubAgentGroups()\n\nexport const SUB_AGENTS_BY_ID: Partial<Record<AgentName, SubAgent>> = indexById(\n SUB_AGENT_GROUPS.flatMap((group) => group.agents)\n)\n\nconst ROSTER_IDS = new Set<string>(AGENT_NAMES)\n\nconst isAgentName = (agentId: string): agentId is AgentName =>\n ROSTER_IDS.has(agentId)\n\n/**\n * The roster asked with an open id — the counterpart to `skillById`. The roster\n * itself is closed, but the surfaces reading it hold ids as plain strings (a\n * saved configuration, a persisted assignment), and one the CLI has since\n * retired is an answer rather than a crash.\n */\nexport const subAgentById = (agentId: string): SubAgent | undefined =>\n isAgentName(agentId) ? SUB_AGENTS_BY_ID[agentId] : undefined\n","import type { AgentName, SkillId } from \"../vendor/generated/source-types\"\nimport { isShippedSkillId, skillById, type CatalogSkill } from \"./catalog\"\nimport {\n PRELOAD_DEFAULTS,\n createLoadStateResolver,\n type LoadState,\n type PreloadDefaults,\n type RoleFlavor,\n} from \"./preload-defaults\"\nimport { SUB_AGENT_GROUPS, type SubAgent } from \"./sub-agents\"\n\n// The one place that answers \"which sub-agents does a freshly picked skill\n// reach, and how does each of them load it?\". Both surfaces resolve against it\n// — the editor's default assignments and the CLI's config generator — so the\n// owner's relevance ruling (\"only add skills to subagents that will reasonably\n// use it\") has exactly one spelling. No broadcast, not even lazy: a sub-agent\n// carries only skills it would reasonably use.\n//\n// Hand-written and browser-safe: no filesystem, no I/O, nothing Node-only, at\n// import time or ever. The editor bundles this module.\n\n/** One sub-agent a skill reaches, and how it arrives there. */\nexport type AssignmentTarget = {\n agentId: AgentName\n load: LoadState\n}\n\n/**\n * What targeting reads of a skill, and the whole of it: the domain it belongs\n * to, the category it sits in, and the id the shipped tables are keyed by.\n * `CatalogSkill` satisfies it, so an id alone still resolves through the\n * catalog — but a skill from another marketplace, whose id carries that\n * marketplace's namespace and is therefore in no catalog-keyed table, states\n * the taxonomy its own metadata carries and is placed on that.\n */\nexport type SkillTaxonomy = {\n id: string\n domainId: CatalogSkill[\"domainId\"]\n categoryId: CatalogSkill[\"categoryId\"]\n}\n\n// The roster in display order — domain groups first, agents by label within\n// each — so both surfaces list a skill's reach the same way.\nconst ROSTER: readonly SubAgent[] = SUB_AGENT_GROUPS.flatMap(\n (group) => group.agents\n)\n\n// A role agent with no domain prefix — the consolidated `reviewer` and `pm`.\n// Their ids trapdoor into the meta GROUP for display, but their roles are\n// cross-domain by nature: any implementation domain's diff is the reviewer's\n// material, and any domain's feature is the planner's.\nconst isCrossDomainRoleAgent = (agent: SubAgent) =>\n agent.domainId === \"meta\" && agent.flavor !== \"meta\"\n\n// Every implementation-ROLE agent. Cross-domain use is a shared skill's\n// nature; the meta-flavor agents are the one standing exclusion — a review\n// role and a planning role are not meta ones, so both belong here.\nconst NON_META_ROSTER: readonly SubAgent[] = ROSTER.filter(\n (agent) => agent.flavor !== \"meta\"\n)\n\n// An implementation-domain skill reaches its own domain's agents plus the\n// cross-domain role agents — the reviewer reviews web and api diffs alike and\n// the PM specs both, so web and api skills alike must be able to reach them.\nconst implementationDomainReach = (domainId: CatalogSkill[\"domainId\"]) =>\n ROSTER.filter(\n (agent) => agent.domainId === domainId || isCrossDomainRoleAgent(agent)\n )\n\n// A role's craft: the categories its agents reach with or without a row, keyed\n// by the flavor whose craft it is. One map rather than a rule per role, so a\n// second flavor earning a craft is an entry here and nothing else.\n//\n// The reviewer's own reviewing craft is one: the process skill preloads by\n// row, the domain checklists carry no row at all — lazy by absence, per the\n// owner's loading design — yet must still reach the reviewer, because being\n// listed in its activation protocol and loaded per-diff is what they are for.\n// The design craft is the other, by the owner's 2026-08-06 ruling: how code is\n// meant to read is what a diff is judged against.\n//\n// The planner's crafts are the same two shapes one role over. The methodology\n// craft is the 2026-08-07 ruling's: how research is run is what a spec's\n// evidence is gathered by. The planning playbooks are the reviewing\n// checklists': row-less per-spec material, listed in the activation protocol\n// and loaded when the spec touches their artifact classes. Each names a domain\n// in its slug, but the planner it reaches is domainless — one PM specs web and\n// api features alike — so the category is the whole rule, as it is for the\n// reviewer's checklists.\n//\n// A craft reach is targeting alone. Eagerness stays the row's answer, so a\n// craft the rows never name for that flavor arrives lazily — which is how the\n// reviewer receives the design skills its developers preload, and how the PM\n// receives the methodology skill its researchers preload.\nconst CRAFT_CATEGORIES_BY_FLAVOR: Partial<\n Record<RoleFlavor, readonly CatalogSkill[\"categoryId\"][]>\n> = {\n planning: [\"meta-methodology\", \"meta-planning\"],\n reviewer: [\"meta-reviewing\", \"meta-design\"],\n}\n\nconst isRoleCraftFor = (skill: SkillTaxonomy, agent: SubAgent): boolean => {\n const craft = CRAFT_CATEGORIES_BY_FLAVOR[agent.flavor]\n\n return craft !== undefined && craft.includes(skill.categoryId)\n}\n\n// A meta skill reaches exactly the flavors its authored row names — across\n// implementation domains, and the meta agents themselves only when a row says\n// \"meta\". No row, no agents — except the crafts: a role reaches its own craft\n// categories with or without a row. Relevance is otherwise the author's to\n// claim.\nconst metaSkillReach = (\n skill: SkillTaxonomy,\n rowFlavors: readonly RoleFlavor[]\n): readonly SubAgent[] => {\n const listedFlavors = new Set<string>(rowFlavors)\n\n return ROSTER.filter(\n (agent) => listedFlavors.has(agent.flavor) || isRoleCraftFor(skill, agent)\n )\n}\n\nconst targetsOf = (\n skill: SkillTaxonomy,\n rowFlavors: readonly RoleFlavor[]\n): readonly SubAgent[] => {\n if (skill.domainId === \"meta\") return metaSkillReach(skill, rowFlavors)\n if (skill.domainId === \"shared\") return NON_META_ROSTER\n\n return implementationDomainReach(skill.domainId)\n}\n\n// The caller's word when it has one, the catalog's when it does not: the •••\n// panel and a curated stack hold nothing but an id, while a loaded marketplace\n// hands its skills' own metadata straight through.\nconst taxonomyOf = (\n skill: string | SkillTaxonomy\n): SkillTaxonomy | undefined =>\n typeof skill === \"string\" ? skillById(skill) : skill\n\n// The shipped rows are keyed by the shipped catalog's own ids, so only a\n// shipped skill can carry one: another marketplace's id is outside the table by\n// construction rather than left out of it. `undefined` is therefore both\n// answers at once — no such skill, and a skill from somewhere else — because\n// the table treats them identically.\nconst shippedIdOf = (\n catalogued: CatalogSkill | undefined\n): SkillId | undefined =>\n catalogued !== undefined && isShippedSkillId(catalogued.id)\n ? catalogued.id\n : undefined\n\nconst rowFlavorsOf = (\n defaults: PreloadDefaults,\n shippedId: SkillId | undefined\n): readonly RoleFlavor[] =>\n shippedId === undefined ? [] : (defaults[shippedId] ?? [])\n\n/**\n * Binds a resolver to a table: targeting from the skill's domain and category,\n * load per pair from the same table's gated load resolver. A caller holding a\n * skill's taxonomy states it and is answered on it, whichever marketplace the\n * id belongs to; a caller holding only an id is answered from the catalog. An\n * id the catalog does not carry and nobody named a taxonomy for — added from\n * GitHub this session, or stale — reaches nobody: relevance unknown, so callers\n * hand it to manual assignment instead of any default.\n *\n * Eagerness stays the catalog's answer, because the rows are its ids': a\n * marketplace's own skill matches none and arrives lazily, exactly as a catalog\n * skill the table leaves out does.\n */\nexport const createAssignmentResolver = (defaults: PreloadDefaults) => {\n const resolveLoad = createLoadStateResolver(defaults)\n\n return (skill: string | SkillTaxonomy): readonly AssignmentTarget[] => {\n const taxonomy = taxonomyOf(skill)\n if (!taxonomy) return []\n\n // Both the row and the gated load resolver are the shipped catalog's, so a\n // skill it does not carry has neither: no row to be eager by, and no id the\n // load resolver would accept. Lazy, the way absence always reads.\n const shippedId = shippedIdOf(skillById(taxonomy.id))\n const loadOn = (agentId: AgentName): LoadState =>\n shippedId === undefined\n ? \"lazy\"\n : resolveLoad({ skillId: shippedId, agentId })\n\n return targetsOf(taxonomy, rowFlavorsOf(defaults, shippedId)).map(\n (agent) => ({ agentId: agent.id, load: loadOn(agent.id) })\n )\n }\n}\n\n/** The resolver both surfaces read: `PRELOAD_DEFAULTS`, bound. */\nexport const resolveAssignment = createAssignmentResolver(PRELOAD_DEFAULTS)\n","import type { AgentName } from \"../vendor/generated/source-types\"\nimport type { Matrix, MatrixStack } from \"../matrix-schema\"\nimport { resolveAssignment, type AssignmentTarget } from \"./assignment-defaults\"\nimport type { LoadState } from \"./preload-defaults\"\nimport { MATRIX } from \"./source\"\nimport { subAgentById } from \"./sub-agents\"\n\nexport type CatalogStack = {\n id: string\n name: string\n description: string\n philosophy: string\n // Never set by the CLI today. The stack rail renders flat until it is.\n group?: string\n skillCount: number\n}\n\n// What applying a stack means, in terms the config store can consume directly.\n// Deliberately not the store's own shape — this package knows nothing about the app.\nexport type StackExpansion = {\n skillIds: string[]\n // Which sub-agents each skill is assigned to, and how each of them loads it.\n assignmentsBySkill: Record<string, AssignmentTarget[]>\n}\n\nconst toCatalogStack = (stack: MatrixStack): CatalogStack => ({\n id: stack.id,\n name: stack.name,\n description: stack.description,\n philosophy: stack.philosophy,\n ...(stack.group !== undefined && { group: stack.group }),\n skillCount: stack.allSkillIds.length,\n})\n\n/**\n * The stack rail's cells, over any catalogue in the wire shape — the\n * counterpart to `buildCatalog`, and exported for the same reason: a\n * marketplace ships its own stacks and they must render by the same rules.\n */\nexport const buildStacks = (matrix: Matrix): CatalogStack[] =>\n matrix.suggestedStacks.map(toCatalogStack)\n\n/** The vendored public catalogue's stacks. */\nexport const STACKS: CatalogStack[] = buildStacks(MATRIX)\n\n// A stack's skill ids are its marketplace's own, but its AGENT ids are not:\n// marketplaces do not ship sub-agents, so the roster is the vendored one and a\n// stack can only staff an agent that exists. One naming an agent this build has\n// never heard of staffs nobody with it, rather than writing an assignment\n// nothing downstream could render.\nconst rosteredAgents = (stack: MatrixStack) =>\n Object.keys(stack.skills)\n .map((agentId) => subAgentById(agentId))\n .filter((agent) => agent !== undefined)\n .map((agent) => agent.id)\n\n// Inverts the stack's agent → category → skills nesting into skill → agents.\nconst toAgentsBySkill = (stack: MatrixStack): Record<string, AgentName[]> => {\n const agentsBySkill: Record<string, AgentName[]> = {}\n for (const agentId of rosteredAgents(stack)) {\n for (const skillId of Object.values(stack.skills[agentId] ?? {}).flat()) {\n const agents = (agentsBySkill[skillId] ??= [])\n if (!agents.includes(agentId)) agents.push(agentId)\n }\n }\n return agentsBySkill\n}\n\n// The stack names which sub-agents carry a skill; the shared resolver answers\n// how each of them loads it — the same table the CLI writes into config.ts and\n// the same one a hand-picked skill resolves against. Per pair, so a framework\n// preloads on its own domain's agents and arrives lazily on the summoners that\n// also carry it. A pair the resolver does not target has no eagerness to claim.\nconst toLoadByAgent = (skillId: string): Map<string, LoadState> =>\n new Map(\n resolveAssignment(skillId).map(({ agentId, load }) => [agentId, load])\n )\n\nconst toAssignmentsBySkill = (\n stack: MatrixStack\n): Record<string, AssignmentTarget[]> =>\n Object.fromEntries(\n Object.entries(toAgentsBySkill(stack)).map(([skillId, agentIds]) => {\n const loadByAgent = toLoadByAgent(skillId)\n\n return [\n skillId,\n agentIds.map((agentId) => ({\n agentId,\n load: loadByAgent.get(agentId) ?? \"lazy\",\n })),\n ]\n })\n )\n\n/**\n * Binds the expander to a catalogue. A marketplace's stacks name that\n * marketplace's skills, so a stack can only be expanded against the catalogue\n * it came from — asking the public one would strand every id.\n */\nexport const createStackExpander =\n (matrix: Matrix) =>\n (stackId: string): StackExpansion | undefined => {\n const stack = matrix.suggestedStacks.find(\n (candidate) => candidate.id === stackId\n )\n if (!stack) return undefined\n\n return {\n skillIds: stack.allSkillIds,\n assignmentsBySkill: toAssignmentsBySkill(stack),\n }\n }\n\n/** The expander bound to the vendored catalogue. */\nexport const expandStack = createStackExpander(MATRIX)\n","import type { SeedSkill } from \"../seed\"\n\n// How a fresh pick installs before anyone touches it: as a plugin, into the\n// user's own ~/.claude. Spelled once and read by every surface — the editor's\n// fresh skill entry and resting agent scope, and the CLI's seed decode — so\n// \"what does an untouched pick do?\" has exactly one answer instead of the\n// three that used to disagree.\n//\n// Typed against the seed vocabulary because the wire is where the surfaces\n// meet: a default this object could name that a payload could not carry would\n// be a default that cannot travel.\nexport const DEFAULT_SELECTION_OPTIONS = {\n install: \"plugin\",\n scope: \"global\",\n} as const satisfies Pick<SeedSkill, \"install\" | \"scope\">\n","// The selection semantics, implemented once. Both surfaces delegate here —\n// the editor's `derive.ts` and the CLI's `matrix-resolver.ts` /\n// `build-step-logic.ts` — so a verdict is the same verdict wherever it is\n// rendered; `contract/selection-scenarios.ts` is the specification this module\n// answers to, and each side's runner holds its own view layer to the same\n// scenarios.\n//\n// Verdicts are structured rather than worded: this module decides *that* a\n// skill is out of reach and *why*, and each surface renders the why in its own\n// words (\"Needs Svelte\" in the editor, \"requires Svelte which conflicts with\n// current selection\" in the wizard).\n//\n// Parameterized over the catalogue like `createLoadStateResolver`, never\n// closed over one: the CLI judges a merged matrix that carries local skills\n// the shipped catalogue has never heard of, which is also why the ids here are\n// `string` rather than `SkillId`.\n//\n// Hand-written and browser-safe: no filesystem, no I/O, nothing Node-only, at\n// import time or ever. The editor bundles this module.\n\nimport type { Matrix } from \"../matrix-schema\"\nimport { MATRIX } from \"./source\"\n\nexport type SkillRequirementFacts = {\n skillIds: readonly string[]\n /** One of these is enough; otherwise every one is needed. */\n needsAny: boolean\n}\n\n/** What the semantics read about one skill — relationships, not presentation. */\nexport type SelectionSkillFacts = {\n id: string\n categoryId: string\n /** Selecting either side hard-excludes the other; declared on one is enough. */\n conflictsWith: readonly string[]\n /** Soft conflict — warn, never disable. The reason is authored upstream. */\n discourages: readonly { skillId: string; reason: string }[]\n /** What this skill is built on: the closure and the fixpoint both walk it. */\n requires: readonly SkillRequirementFacts[]\n}\n\nexport type SelectionCatalogFacts = {\n skills: readonly SelectionSkillFacts[]\n /** Pick-one categories: a click swaps the sibling out rather than joining it. */\n exclusiveCategoryIds: ReadonlySet<string>\n}\n\n// A verdict is about possibility, never presence: a skill is ruled out only\n// once the selection has made it impossible, never merely because the host it\n// prefers has not been clicked. The `compatibleWith` whitelist stated the\n// second reading and was deleted on the owner's 2026-08-07 ruling (CLI-389\n// phase C) — see `.ai-docs/reference/features/skills-and-matrix.md`.\nexport type IncompatibilityCause =\n // Something the selection reaches conflicts with it outright.\n | { kind: \"conflict\"; skillId: string }\n // A requirement whose named candidates the selection has ruled out —\n // `lostIds` are the ones actually gone, the whole group for a lost choice.\n | {\n kind: \"unreachableRequirement\"\n requirement: SkillRequirementFacts\n lostIds: readonly string[]\n }\n\nexport type SelectionVerdict =\n | { status: \"normal\" }\n | { status: \"discouraged\"; reason: string }\n | { status: \"incompatible\"; cause: IncompatibilityCause }\n\n/** One selection, judged: the sets it settles and the verdicts it implies. */\nexport type SelectionJudgement = {\n /** Selected, plus everything the selection necessarily also chooses. */\n reached: ReadonlySet<string>\n /** Ruled out by that, dependents included, to a fixpoint. */\n outOfReach: ReadonlySet<string>\n /** The closure minus the selection — what was chosen without being clicked. */\n implied: readonly string[]\n /**\n * The verdict a cell renders. Inside a pick-one category an incompatibility\n * is re-judged against the selection a click would produce — the swap drops\n * every same-category member, selected or implied — so a conflict the swap\n * resolves is forgiven and an impossibility it leaves standing keeps its\n * reason.\n */\n verdictOf: (skillId: string) => SelectionVerdict\n /** The verdict before the swap rule — what the selection as it stands says. */\n incompatibilityOf: (skillId: string) => IncompatibilityCause | undefined\n /** The soft warning alone, whatever else the skill's verdict says. */\n discourageReasonOf: (skillId: string) => string | undefined\n}\n\nexport type SelectionSemantics = (\n selection: readonly string[]\n) => SelectionJudgement\n\n// A group offering a choice commits the user to none of the options: \"Pinia\n// needs Vue *or* Nuxt\" cannot say which, so it implies neither.\nconst isAmbiguous = (requirement: SkillRequirementFacts) =>\n requirement.needsAny && requirement.skillIds.length > 1\n\n// The judging material for one verdict pass. The base pass judges the\n// selection as it stands; the swap pass judges the selection a pick-one click\n// would produce.\ntype JudgingSets = {\n reached: ReadonlySet<string>\n outOfReach: ReadonlySet<string>\n}\n\nexport const createSelectionSemantics = (\n catalog: SelectionCatalogFacts\n): SelectionSemantics => {\n const skillsById = new Map(catalog.skills.map((skill) => [skill.id, skill]))\n\n // Conflicts are declared on either side, so the symmetric view is built once\n // and every lookup is one direction.\n const conflictIdsBySkill = new Map<string, Set<string>>()\n const noteConflict = (skillId: string, otherId: string) => {\n const held = conflictIdsBySkill.get(skillId)\n if (held) held.add(otherId)\n else conflictIdsBySkill.set(skillId, new Set([otherId]))\n }\n for (const skill of catalog.skills) {\n for (const otherId of skill.conflictsWith) {\n noteConflict(skill.id, otherId)\n noteConflict(otherId, skill.id)\n }\n }\n\n const mustHold = (skillId: string): SelectionSkillFacts => {\n const skill = skillsById.get(skillId)\n if (!skill) throw new Error(`Skill not found: ${skillId}`)\n return skill\n }\n\n // What choosing this skill necessarily also chooses.\n const directlyImpliedBy = (skillId: string) =>\n (skillsById.get(skillId)?.requires ?? [])\n .filter((requirement) => !isAmbiguous(requirement))\n .flatMap((requirement) => requirement.skillIds)\n\n // What the selection drags in behind it: choosing Next.js is choosing React\n // whether or not React was ever clicked.\n const closureOf = (selection: readonly string[]) => {\n const reached = new Set(selection)\n const frontier = [...reached]\n\n for (let skillId = frontier.pop(); skillId; skillId = frontier.pop()) {\n for (const required of directlyImpliedBy(skillId)) {\n if (reached.has(required)) continue\n reached.add(required)\n frontier.push(required)\n }\n }\n\n return reached\n }\n\n // The first reached skill this one cannot coexist with, if any — reached in\n // selection order, so the verdict names what the user actually picked first.\n const reachedConflictOf = (skillId: string, reached: ReadonlySet<string>) => {\n const conflictIds = conflictIdsBySkill.get(skillId)\n if (!conflictIds) return undefined\n for (const reachedId of reached) {\n if (reachedId !== skillId && conflictIds.has(reachedId)) return reachedId\n }\n return undefined\n }\n\n const lostIdsOf = (\n requirement: SkillRequirementFacts,\n reached: ReadonlySet<string>,\n outOfReach: ReadonlySet<string>\n ) =>\n requirement.skillIds.filter(\n (skillId) => !reached.has(skillId) && outOfReach.has(skillId)\n )\n\n // A group is met while any candidate is still reachable — for `needsAny`,\n // one survivor is enough; otherwise every candidate has to survive.\n const isUnreachable = (\n requirement: SkillRequirementFacts,\n lostIds: readonly string[]\n ) =>\n requirement.needsAny\n ? lostIds.length === requirement.skillIds.length\n : lostIds.length > 0\n\n // First everything conflicting with the reached set, then everything built\n // on what was lost, and so on — Vue goes, then Nuxt, then Pinia. Each round\n // either strands at least one more skill or stops, so this terminates.\n const strandedBeyond = (reached: ReadonlySet<string>) => {\n const outOfReach = new Set<string>()\n for (const skill of catalog.skills) {\n if (!reached.has(skill.id) && reachedConflictOf(skill.id, reached)) {\n outOfReach.add(skill.id)\n }\n }\n\n const hasLostRequirement = (skill: SelectionSkillFacts) =>\n skill.requires.some((requirement) =>\n isUnreachable(requirement, lostIdsOf(requirement, reached, outOfReach))\n )\n\n for (let settled = false; !settled;) {\n settled = true\n\n for (const skill of catalog.skills) {\n if (reached.has(skill.id) || outOfReach.has(skill.id)) continue\n if (hasLostRequirement(skill)) {\n outOfReach.add(skill.id)\n settled = false\n }\n }\n }\n\n return outOfReach\n }\n\n const incompatibilityAgainst = (\n skill: SelectionSkillFacts,\n sets: JudgingSets\n ): IncompatibilityCause | undefined => {\n const conflictId = reachedConflictOf(skill.id, sets.reached)\n if (conflictId) return { kind: \"conflict\", skillId: conflictId }\n\n for (const requirement of skill.requires) {\n const lostIds = lostIdsOf(requirement, sets.reached, sets.outOfReach)\n if (isUnreachable(requirement, lostIds)) {\n return { kind: \"unreachableRequirement\", requirement, lostIds }\n }\n }\n\n return undefined\n }\n\n const discourageAgainst = (\n skill: SelectionSkillFacts,\n sets: JudgingSets\n ): string | undefined => {\n for (const reachedId of sets.reached) {\n if (reachedId === skill.id) continue\n\n const declared = skillsById\n .get(reachedId)\n ?.discourages.find((relation) => relation.skillId === skill.id)\n if (declared) return declared.reason\n\n const declaredBack = skill.discourages.find(\n (relation) => relation.skillId === reachedId\n )\n if (declaredBack) return declaredBack.reason\n }\n return undefined\n }\n\n const verdictAgainst = (\n skill: SelectionSkillFacts,\n sets: JudgingSets\n ): SelectionVerdict => {\n const cause = incompatibilityAgainst(skill, sets)\n if (cause) return { status: \"incompatible\", cause }\n\n const reason = discourageAgainst(skill, sets)\n return reason ? { status: \"discouraged\", reason } : { status: \"normal\" }\n }\n\n return (selection) => {\n const reached = closureOf(selection)\n const base: JudgingSets = {\n reached,\n outOfReach: strandedBeyond(reached),\n }\n\n // The selection a pick-one click would produce: every same-category\n // member drops out of the judging material — selected or implied — and\n // the strandings are recomputed from what survives. Cached per category,\n // since every cell in it swaps against the same remainder.\n const swapSetsByCategory = new Map<string, JudgingSets>()\n const swapSetsFor = (categoryId: string): JudgingSets => {\n const held = swapSetsByCategory.get(categoryId)\n if (held) return held\n\n const outside = (skillId: string) =>\n skillsById.get(skillId)?.categoryId !== categoryId\n const survivingReached = new Set([...reached].filter(outside))\n const sets: JudgingSets = {\n reached: survivingReached,\n outOfReach: strandedBeyond(survivingReached),\n }\n swapSetsByCategory.set(categoryId, sets)\n return sets\n }\n\n return {\n reached,\n outOfReach: base.outOfReach,\n implied: [...reached].filter((skillId) => !selection.includes(skillId)),\n verdictOf: (skillId) => {\n const skill = mustHold(skillId)\n const verdict = verdictAgainst(skill, base)\n\n const swaps =\n verdict.status === \"incompatible\" &&\n catalog.exclusiveCategoryIds.has(skill.categoryId)\n return swaps\n ? verdictAgainst(skill, swapSetsFor(skill.categoryId))\n : verdict\n },\n incompatibilityOf: (skillId) =>\n incompatibilityAgainst(mustHold(skillId), base),\n discourageReasonOf: (skillId) =>\n discourageAgainst(mustHold(skillId), base),\n }\n }\n}\n\n/**\n * The relationships a selection is judged by, read off a catalogue.\n *\n * Exported because a marketplace's conflicts are its own: judging its skills by\n * the public catalogue's facts would find no relationship at all, since it\n * knows neither id. The CLI builds these facts from its own merged matrix\n * instead, which is why the semantics take them rather than reading a module.\n */\nexport const catalogFactsOf = (matrix: Matrix): SelectionCatalogFacts => ({\n skills: Object.values(matrix.skills).map((skill) => ({\n id: skill.id,\n categoryId: skill.category,\n conflictsWith: skill.conflictsWith.map((relation) => relation.skillId),\n discourages: skill.discourages.map((relation) => ({\n skillId: relation.skillId,\n reason: relation.reason,\n })),\n requires: skill.requires.map((requirement) => ({\n skillIds: requirement.skillIds,\n needsAny: requirement.needsAny,\n })),\n })),\n exclusiveCategoryIds: new Set(\n Object.values(matrix.categories)\n .filter((category) => category.exclusive)\n .map((category) => category.id)\n ),\n})\n\n/** The semantics both surfaces read: the shipped catalogue, bound. */\nexport const judgeSelection = createSelectionSemantics(catalogFactsOf(MATRIX))\n","// The selection semantics, written down once, as data.\n//\n// These scenarios were pinned while two implementations answered the same\n// questions — the CLI's `matrix-resolver.ts` plus `build-step-logic.ts`, and\n// the editor's `derive.ts` — and did not always agree. The expectations are\n// the CLI's, which the owner ruled authoritative. Both sides now delegate to\n// `read-model/selection-semantics.ts`, and the scenarios hold that module and\n// each side's rendering of it to one contract instead of to each other.\n//\n// Nothing here imports either implementation, and nothing here is\n// editor-shaped or CLI-shaped: a scenario is a selection against the real\n// catalogue and the outcomes that selection must produce. Each side writes\n// its own runner that maps its API onto these fields.\n//\n// `outOfReach` and `inReach` are *samples*, not the whole catalogue. Listing\n// every skill would pin hundreds of incidental answers that nobody decided and\n// that a regenerated catalogue would churn; each id listed here is one somebody\n// chose, and the `why` says what it is standing for.\n\nimport { CATALOG } from \"../read-model/catalog\"\nimport type { SkillId } from \"../vendor/generated/source-types\"\n\n// The divergences the owner ruled bugs on 2026-08-06, each fixed when the\n// editor moved onto the shared semantics — the label survives as the record of\n// what its scenario was pinned to guard. A further one, found while writing\n// these down, was the CLI forgiving every incompatibility inside a pick-one\n// category; that one was narrowed rather than pinned, and the scenario holding\n// it is an agreement now.\n//\n// A third, `framework-constraint`, is gone rather than fixed: it named the\n// CLI's `compatibleWith` whitelist ruling out a framework-bound skill beside a\n// framework that merely does not host it. The owner ruled on 2026-08-07 that\n// those verdicts are an accepted loss and deleted the field (CLI-389 phase C),\n// which makes both sides answer the one question that survives — *could this\n// still become valid* — and leaves nothing for the label to name. The three\n// scenarios that carried it are agreements below, each recording the ruling.\nexport type SelectionDivergence =\n // The editor never read `discourages`, so a soft warning never appeared.\n | \"discourages\"\n // Inside an exclusive category the editor forgave a conflict only with a\n // *selected* sibling; the CLI forgives any verdict the swap would resolve,\n // whether the sibling was selected or merely implied.\n | \"exclusive-forgiveness\"\n\nexport type SelectionScenario = {\n id: string\n // Phrased as the behaviour a test name would describe.\n title: string\n // What the user has clicked, and only that.\n selection: readonly SkillId[]\n // Everything the selection necessarily also chooses, itself excluded. A\n // group offering a choice commits the user to none of its options.\n implied: readonly SkillId[]\n // Must be surfaced as unavailable against this selection.\n outOfReach: readonly SkillId[]\n // Must stay offerable against this selection.\n inReach: readonly SkillId[]\n // Must be surfaced as a soft warning — never disabled.\n discouraged: readonly SkillId[]\n // `null` on the agreement surface: both implementations already answer this.\n divergence: SelectionDivergence | null\n why: string\n}\n\nconst REACT = \"web-framework-react\"\nconst VUE = \"web-framework-vue-composition-api\"\nconst SVELTE = \"web-framework-svelte\"\nconst ANGULAR = \"web-framework-angular-standalone\"\nconst SOLID = \"web-framework-solidjs\"\nconst NEXTJS = \"web-meta-framework-nextjs\"\nconst REMIX = \"web-meta-framework-remix\"\nconst NUXT = \"web-meta-framework-nuxt\"\nconst SVELTEKIT = \"web-meta-framework-sveltekit\"\nconst ASTRO = \"web-meta-framework-astro\"\nconst REACT_NATIVE = \"mobile-framework-react-native\"\nconst EXPO = \"mobile-framework-expo\"\nconst TAILWIND = \"web-styling-tailwind\"\nconst VITE = \"web-tooling-vite\"\nconst SHADCN = \"web-ui-shadcn-ui\"\nconst RADIX = \"web-ui-radix-ui\"\nconst HEADLESS_UI = \"web-ui-headless-ui\"\nconst MUI = \"web-ui-mui\"\nconst VUETIFY = \"web-ui-vuetify\"\nconst RHF = \"web-forms-react-hook-form\"\nconst VEE_VALIDATE = \"web-forms-vee-validate\"\nconst TANSTACK_FORM = \"web-forms-tanstack-form\"\nconst RTL = \"web-testing-react-testing-library\"\nconst VUE_TEST_UTILS = \"web-testing-vue-test-utils\"\nconst VUEUSE = \"web-utilities-vueuse\"\nconst NEXT_INTL = \"web-i18n-next-intl\"\nconst PINIA = \"web-state-pinia\"\nconst NGRX = \"web-state-ngrx-signalstore\"\nconst PRISMA = \"api-database-prisma\"\nconst DRIZZLE = \"api-database-drizzle\"\nconst SEQUELIZE = \"api-database-sequelize\"\n\nexport const SELECTION_SCENARIOS: readonly SelectionScenario[] = [\n {\n id: \"empty-selection-rules-out-nothing\",\n title: \"offers the whole catalogue while nothing is selected\",\n selection: [],\n implied: [],\n outOfReach: [],\n inReach: [REACT, SVELTE, PINIA, SHADCN, TAILWIND],\n discouraged: [],\n divergence: null,\n why: \"Two skills that cannot coexist are both offerable until one is picked.\",\n },\n {\n id: \"closure-follows-one-requirement\",\n title: \"counts what a selection is built on as chosen\",\n selection: [NEXTJS],\n implied: [REACT],\n outOfReach: [],\n inReach: [RADIX, RHF, HEADLESS_UI, RTL],\n discouraged: [],\n divergence: null,\n why: \"Next.js is built on React, so the React-bound companions are open without React ever being clicked.\",\n },\n {\n id: \"closure-follows-a-chain-of-requirements\",\n title: \"carries the closure through more than one hop\",\n selection: [EXPO],\n implied: [REACT_NATIVE, REACT],\n outOfReach: [VEE_VALIDATE],\n inReach: [REACT_NATIVE],\n discouraged: [],\n divergence: null,\n why: \"Expo needs React Native, which needs React — and Vue's forms go with it.\",\n },\n {\n id: \"closure-takes-only-the-unambiguous-requirement\",\n title: \"implies every member of an all-of group and none of a choice\",\n selection: [SHADCN],\n implied: [TAILWIND],\n outOfReach: [],\n inReach: [TAILWIND, REACT],\n discouraged: [],\n divergence: null,\n why: \"shadcn/ui needs Tailwind outright plus one of the React frameworks; only the first can be named.\",\n },\n {\n id: \"a-choice-commits-to-none-of-its-options\",\n title: \"implies nothing from a requirement offering a choice\",\n selection: [PINIA],\n implied: [],\n outOfReach: [],\n inReach: [VUE, NUXT],\n discouraged: [],\n divergence: null,\n why: \"Pinia needs Vue or Nuxt and cannot say which, so neither is chosen and neither rules the other out. What Pinia does *not* do to the frameworks it cannot run on is the scenario below.\",\n },\n {\n id: \"a-choice-survives-on-one-candidate\",\n title: \"keeps a choice open while any one candidate survives\",\n selection: [ANGULAR],\n implied: [],\n outOfReach: [RADIX],\n inReach: [NGRX, TANSTACK_FORM],\n discouraged: [],\n divergence: null,\n why: \"TanStack Form lists Angular among its options and survives; Radix lists only the React family and does not.\",\n },\n {\n id: \"the-wrong-framework-rules-out-what-is-bound-to-another\",\n title: \"rules out the skills bound to a framework the selection excludes\",\n selection: [SVELTE],\n implied: [],\n outOfReach: [RADIX, SHADCN, RHF, RTL, REACT_NATIVE],\n inReach: [TAILWIND, VITE],\n discouraged: [],\n divergence: null,\n why: \"Svelte conflicts with React, so everything that needs React goes; the unbound skills stay.\",\n },\n {\n id: \"losing-a-skill-loses-what-was-built-on-it\",\n title: \"keeps stranding dependents until nothing more is stranded\",\n selection: [REACT],\n implied: [],\n outOfReach: [VEE_VALIDATE, VUE_TEST_UTILS, VUETIFY, VUEUSE],\n inReach: [TAILWIND],\n discouraged: [],\n divergence: null,\n why: \"React conflicts with Vue, Nuxt is built on Vue, and the Vue companions accept only those two — the mirror of the Svelte case.\",\n },\n {\n id: \"a-pick-one-category-swaps-rather-than-disables\",\n title: \"leaves the siblings of a selected skill swappable\",\n selection: [REACT],\n implied: [],\n outOfReach: [],\n inReach: [SVELTE, VUE, ANGULAR, SOLID],\n discouraged: [],\n divergence: null,\n why: \"Clicking a sibling replaces React rather than joining it, so disabling the rest would strand the first choice.\",\n },\n {\n id: \"the-swap-rule-is-not-about-frameworks\",\n title: \"leaves the siblings swappable in every pick-one category\",\n selection: [PRISMA],\n implied: [],\n outOfReach: [],\n inReach: [DRIZZLE, SEQUELIZE],\n discouraged: [],\n divergence: null,\n why: \"The same swap holds for database ORMs, so the rule cannot be reading the web framework category by name.\",\n },\n {\n id: \"the-implier-keeps-its-own-siblings-swappable\",\n title: \"leaves a sibling of the skill that implied the closure swappable\",\n selection: [NEXTJS],\n implied: [REACT],\n outOfReach: [],\n inReach: [REACT, REMIX],\n discouraged: [],\n divergence: null,\n why: \"Remix is built on the same React and swaps with Next.js; React itself was never clicked and stays a live choice.\",\n },\n {\n id: \"two-selections-satisfy-a-split-requirement\",\n title: \"opens a skill once every one of its requirements is met\",\n selection: [REACT, TAILWIND],\n implied: [],\n outOfReach: [],\n inReach: [SHADCN, RADIX, MUI],\n discouraged: [],\n divergence: null,\n why: \"shadcn/ui needs both halves; MUI stands for the design-system kits, which are a pick-one category and so stay swappable while none is selected. A scenario pinning the opposite — kits disabling each other through a conflict group inside an open category — was dropped when that group died with the `web-ui-kit` radio, and no catalogued pair states that shape any more.\",\n },\n {\n id: \"a-meta-framework-rules-out-the-other-family\",\n title: \"rules out the other family through the framework it implies\",\n selection: [NUXT],\n implied: [VUE],\n outOfReach: [RADIX],\n inReach: [VUE, VUETIFY],\n discouraged: [],\n divergence: null,\n why: \"Nuxt implies Vue, Vue conflicts with React, and Radix accepts only the React family.\",\n },\n {\n id: \"selecting-the-base-alongside-changes-nothing\",\n title: \"answers the same whether the base was clicked or implied\",\n selection: [VUE, NUXT],\n implied: [],\n outOfReach: [RADIX, RHF],\n inReach: [VUETIFY],\n discouraged: [],\n divergence: null,\n why: \"Selecting Vue explicitly beside Nuxt must not change a single verdict from implying it.\",\n },\n {\n id: \"a-svelte-meta-framework-rules-out-the-react-family\",\n title: \"rules out the React family through a Svelte meta-framework\",\n selection: [SVELTEKIT],\n implied: [SVELTE],\n outOfReach: [RADIX, RHF],\n inReach: [SVELTE, TAILWIND],\n discouraged: [],\n divergence: null,\n why: \"The mirror of the Nuxt case, so the answer cannot be coming from anything React-specific.\",\n },\n {\n id: \"a-framework-bound-skill-beside-a-framework-that-cannot-host-it\",\n title:\n \"rules out only what a framework excludes, not what it fails to host\",\n selection: [ASTRO],\n implied: [],\n outOfReach: [NEXT_INTL],\n inReach: [RADIX, VUETIFY, RHF, VUE_TEST_UTILS, TAILWIND],\n discouraged: [],\n divergence: null,\n why: \"Astro hosts neither React nor Vue, but it excludes neither: it conflicts only with its sibling meta-frameworks, so next-intl loses the Next.js it is built on while both component families stay satisfiable and therefore offerable. Until 2026-08-07 this scenario asserted the mirror image — all four families' companions ruled out — and carried `divergence: \\\"framework-constraint\\\"`, the CLI's `compatibleWith` whitelist answering 'is a declared host selected'. The owner ruled those verdicts an accepted loss and CLI-389 phase C deleted the field, so both sides now answer 'could this still become valid' and this is an agreement.\",\n },\n {\n id: \"a-companion-whose-base-is-merely-still-available\",\n title:\n \"keeps a companion offerable while the base it needs is still selectable\",\n selection: [REACT],\n implied: [],\n outOfReach: [],\n inReach: [EXPO, REACT_NATIVE],\n discouraged: [],\n divergence: null,\n why: \"Expo is for React Native, and React alone is not React Native — but React rules React Native out of nothing, so Expo's requirement is unmet rather than unreachable and the cell stays live. Until 2026-08-07 this asserted Expo ruled out, on the CLI's `compatibleWith` whitelist; the owner ruled that verdict an accepted loss when CLI-389 phase C deleted the field. Nudging the user toward the base it still needs is another surface's job — `getUnmetRequiredBy` in the wizard, not a verdict.\",\n },\n {\n id: \"a-framework-beside-a-companion-bound-to-another\",\n title:\n \"leaves every framework offerable beside a companion that has committed to none\",\n selection: [PINIA],\n implied: [],\n outOfReach: [],\n inReach: [REACT, SVELTE],\n discouraged: [],\n divergence: null,\n why: \"Pinia needs Vue or Nuxt and cannot say which, so it drags neither in — and a framework it cannot run on is therefore excluded by nothing. Until 2026-08-07 React and Svelte were ruled out here through the CLI's `compatibleWith` whitelist, which read the companion's declared hosts back onto the frameworks; the owner ruled that an accepted loss and CLI-389 phase C deleted the field. The sibling scenario `a-choice-commits-to-none-of-its-options` pins what Pinia implies; this one pins what it does not rule out.\",\n },\n {\n id: \"a-sibling-conflicting-with-a-merely-implied-skill\",\n title: \"leaves a sibling conflicting with an implied skill swappable\",\n selection: [NEXTJS],\n implied: [REACT],\n outOfReach: [],\n inReach: [ANGULAR, SVELTE],\n discouraged: [],\n divergence: \"exclusive-forgiveness\",\n why: \"The CLI forgives the conflict because the category is pick-one. The editor forgives it only for a *selected* sibling, and React here is implied, so it disables Angular and Svelte instead.\",\n },\n {\n id: \"an-unmet-requirement-inside-a-pick-one-category\",\n title:\n \"rules out a pick-one skill whose requirement the selection has ruled out\",\n selection: [NEXTJS, REACT],\n implied: [],\n outOfReach: [NUXT],\n inReach: [REMIX],\n discouraged: [],\n divergence: null,\n why: \"Both clash with the selected Next.js in a pick-one category, so the click swaps it out — which rescues Remix, built on the React that is also selected, and does nothing for Nuxt, which needs the Vue that same React rules out. Forgiveness reaches exactly as far as the swap does. React is named beside Next.js rather than left implied because the CLI computes no requires-closure yet, the same reason `selecting-the-base-alongside-changes-nothing` spells its base out. The exemplar was VitePress until the docs frameworks stopped requiring a base framework — a docs site is its own deployable — which left Nuxt carrying the fence this scenario is about.\",\n },\n]\n\n// The pairs the `discourages` golden runs over. Derived rather than written\n// down because the point of that golden is what the catalogue actually\n// declares: as of 2026-08-06 it declares none, so the golden is red on its\n// data before it is ever red on an implementation.\n//\n// `string` rather than `SkillId` because that is what the read model holds now\n// that a catalogue can be a marketplace's. These pairs are still the SHIPPED\n// catalogue's — `CATALOG` is the vendored one — and both runners feed them\n// straight into semantics that take open ids, so nothing downstream wanted the\n// narrower type.\nexport const DISCOURAGED_PAIRS: readonly (readonly [string, string])[] =\n Object.values(CATALOG.skillsById).flatMap((skill) =>\n skill.discourages.map((other) => [skill.id, other] as const)\n )\n","import { z } from \"zod\"\n\n// The wire contract for shared configs: the web app POSTs this payload to the\n// config store (Cloudflare Worker + KV) and gets a short id back; `agents-inc\n// init --from <id>` fetches and validates it with this same schema. This file is\n// the source of truth, and every consumer IMPORTS it — the CLI through\n// `@workspace/matrix/seed`, which tsup inlines at build time, plus the editor,\n// the worker and the API mocks. There is no vendored copy of this schema: the\n// `generate:matrix` script that vendors into `packages/matrix/src/vendor/` runs\n// the other way, copying the CLI's own types here, and does not emit this file.\n\n// Bump when the payload shape changes. Pre-release policy is discard-don't-\n// migrate, so the schema accepts exactly one version: an id minted before a\n// bump fails to decode loudly rather than being guessed at.\n//\n// v2 moved model and effort off the skill and onto the sub-agent, which is\n// where they were always a property of — a skill is a plugin from someone\n// else's repo and has no business naming a model.\n//\n// v3 gave the sub-agent its scope. The CLI has carried one on every agent all\n// along; the web had no surface for it, so `--from` wrote `project` for\n// everyone. The field is additive-optional, which a version could not normally\n// be needed for — but a consumer parsing with an older build of this schema\n// strips what it does not know, so the version is what says the field is\n// really there.\n//\n// v4 gave the payload the marketplace its skills are fetched from. An id\n// already says whose skill it is — a marketplace's name is the author-time\n// prefix on every id it ships — but no id can say WHERE that marketplace\n// lives, and a payload silent about it has the receiver install its own\n// `acme-web-frontend` rather than acme's. One ref at the top covers it,\n// because an install reads one marketplace. Absent still means the default\n// public catalogue, which is every payload the web app mints.\n//\n// v5 made the payload carry CONTENT. Every id above it is resolved by the\n// receiver against a catalogue it already has; a skill added from outside\n// answers to no catalogue, so its whole directory travels inline (owner ruling,\n// 2026-08-16). That is what makes a shared id self-contained: `--from` reaches\n// into no third-party repository at install time, and two people installing one\n// id get identical bytes.\n//\n// The bump is what stops that being a silent change. `external` is additive-\n// optional, so a consumer built against v4 would STRIP it and install a\n// configuration quietly missing the skills the sharer picked — the same defect\n// the field exists to fix, moved one step later. The literal below refuses\n// instead. Pre-release policy is discard-don't-migrate, so ids minted under v4\n// stop decoding; that is deliberate, and the message a consumer prints for it\n// is what has to name the fix.\nexport const SEED_VERSION = 5\n\n// The model and effort a sub-agent runs on. Both scales are the CLI's, since\n// the CLI is what writes them into the agent's frontmatter.\nexport const seedModelSchema = z.enum([\"opus\", \"fable\", \"sonnet\", \"haiku\"])\n// Claude Code's subagent and skill frontmatter accept exactly these. `ultra` was\n// carried here by mistake: \"ultracode\" exists but is a session-only Claude Code\n// setting that sends `xhigh`, not a model effort level, so a config naming it\n// would have been invalid wherever it landed.\nexport const seedEffortSchema = z.enum([\n \"low\",\n \"medium\",\n \"high\",\n \"xhigh\",\n \"max\",\n])\n\nexport const seedLoadStateSchema = z.enum([\"lazy\", \"preloaded\"])\n\n// A skill says where it installs and which agents carry it, and nothing about\n// how they think.\nexport const seedSkillSchema = z.object({\n install: z.enum([\"plugin\", \"eject\"]),\n scope: z.enum([\"project\", \"global\"]),\n // Sub-agent id → load state; presence is assignment. Per (agent, skill),\n // matching the granularity of the CLI's stack config.\n assignments: z.record(z.string(), seedLoadStateSchema),\n})\n\n// Everything one sub-agent has to say, all of it optional so the map can be as\n// sparse as the skill map is. `on: true` is what lets a bare base agent travel\n// at all: v1 could only infer agents from assignments, so an agent holding no\n// skills was unshareable. An entry naming only a model does *not* switch the\n// agent on — absent means \"the assignments decide\".\nexport const seedAgentSchema = z.object({\n on: z.boolean().exactOptional(),\n model: seedModelSchema.exactOptional(),\n effort: seedEffortSchema.exactOptional(),\n // Where this agent's front-matter is written: the project, or the user's own\n // ~/.claude. Absent means the shared selection default — `global`, spelled\n // once in `DEFAULT_SELECTION_OPTIONS` — so the resting choice never travels,\n // exactly as a resting model does not.\n scope: z.enum([\"project\", \"global\"]).exactOptional(),\n})\n\n// ── External skills ──────────────────────────────────────────────────────\n\n/**\n * The most one external skill's directory may weigh, in UTF-8 bytes.\n *\n * Measured rather than guessed. The largest real documentation skill on the\n * allowlisted repositories is `obra/superpowers/skills/brainstorming` at 78 KB\n * across 8 files; our own run 60-75 KB across 3-7. Three of them in one payload\n * is 161 KB raw and 48 KB gzipped, against 1.9 KB for the same selection before\n * content travelled — so a cap several times the largest real skill still holds\n * a realistic configuration many times over.\n *\n * What it refuses is the other shape entirely: `anthropics/skills/skills/docx`\n * is 1.1 MB across 61 files, almost all of it XML schemas for a Python library\n * that happens to sit under a SKILL.md. Inlining one of those into a link\n * somebody pastes into a terminal is what this number exists to prevent.\n */\nexport const MAX_EXTERNAL_SKILL_BYTES = 262_144\n\n/** The file Claude Code reads to learn a skill exists at all. */\nconst SKILL_MANIFEST = \"SKILL.md\"\n\n// UTF-8, because that is what lands in KV and on disk. A tree of multi-byte\n// characters weighs more than its length says, and the cap is about weight.\nconst treeBytes = (files: Record<string, string>) => {\n const encoder = new TextEncoder()\n return Object.values(files).reduce(\n (total, text) => total + encoder.encode(text).length,\n 0\n )\n}\n\n/**\n * A skill's whole directory, keyed by path relative to it.\n *\n * The whole directory and not SKILL.md alone (owner, 2026-08-16): a skill is\n * `SKILL.md`, the `metadata.yaml` beside it, and every `reference/` or\n * `examples-*.md` file under it. Carrying the manifest alone would install\n * something that loads and then cannot do what it says.\n *\n * A record rather than a list, so a path cannot appear twice by construction.\n * Nesting lives in the key — `reference/api.md` — which keeps the shape flat\n * while the tree it describes is not.\n */\nexport const seedSkillTreeSchema = z\n .record(z.string().min(1), z.string())\n .refine((files) => SKILL_MANIFEST in files, {\n message: `a skill directory must hold ${SKILL_MANIFEST}`,\n })\n .refine((files) => treeBytes(files) <= MAX_EXTERNAL_SKILL_BYTES, {\n message: `a skill directory may not exceed ${String(MAX_EXTERNAL_SKILL_BYTES)} bytes`,\n })\n\n/**\n * One skill added from outside whichever catalogue the payload names.\n *\n * It is a real catalogue entry on the sending side and has to become one on the\n * receiving side, so everything a catalogue entry needs travels: the name, the\n * description, and the category the user CONFIRMED at add time (CLI-412 — the\n * category is a decision, never derived from the repository). `repo` and `path`\n * are provenance rather than a resolution step: the bytes are already here, and\n * these are what let a reader go and look at where they came from.\n */\nexport const seedExternalSkillSchema = z.object({\n displayName: z.string().min(1),\n description: z.string(),\n // A category of the catalogue this payload names — the placement the user\n // confirmed. Without it the skill has nowhere to render and no sub-agent\n // reach, which is the whole difference between a catalogue entry and an\n // orphan section.\n categoryId: z.string().min(1),\n // GitHub's own `owner/name`.\n repo: z.string().min(1),\n // The skill's DIRECTORY within it — `skills/docx`, never the SKILL.md.\n path: z.string().min(1),\n files: seedSkillTreeSchema,\n})\n\n// Ids are full catalog slugs, never positional indices, so a payload survives\n// catalog churn: consumers warn and skip unknown ids rather than failing.\nexport const seedPayloadSchema = z.object({\n v: z.literal(SEED_VERSION),\n // Diagnostics only. A mismatch with the consumer's matrix must not fail the\n // decode — it explains why some ids were skipped.\n matrixVersion: z.string(),\n stackId: z.string().nullable(),\n // Where the skills below are fetched from, in the form `--marketplace` takes\n // one: `github:acme/skills`, a URL, a local path. The ref alone — the name\n // its manifest gives it is read from the fetched marketplace.json, so\n // carrying that too would let a payload disagree with the repository it\n // names. Absent is the default public catalogue, which is why a payload that\n // installs from it looks exactly as it did before this field existed.\n marketplace: z.string().exactOptional(),\n // Sparse — presence is selection, exactly like the web store. `remembered`\n // is deliberately absent: deselected setup never leaves the browser.\n skills: z.record(z.string(), seedSkillSchema),\n // Skill id → its whole directory, for the ids above that no catalogue can\n // resolve. Keyed by the same id `skills` uses, so a selection reads one map\n // whichever kind of skill it names. Absent is the ordinary case — a payload\n // built from the catalogue alone — which is why one looks exactly as it did\n // before content travelled. Content is the expensive part of a payload, so an\n // added skill nobody selected has no entry here either.\n external: z.record(z.string(), seedExternalSkillSchema).exactOptional(),\n // Sparse for the same reason: an agent resting on its own catalogue model\n // with no pin has nothing to say, so it has no entry. Presence is a\n // statement, not an install: what installs is decided by assignments and\n // `on: true` alone, so a derived-off agent can still travel its overrides.\n // Only an agent pinned *off* is omitted outright — with the assignment rows\n // naming it, since the sharer's own counts exclude them.\n agents: z.record(z.string(), seedAgentSchema),\n})\n\nexport type SeedModel = z.infer<typeof seedModelSchema>\nexport type SeedEffort = z.infer<typeof seedEffortSchema>\nexport type SeedLoadState = z.infer<typeof seedLoadStateSchema>\nexport type SeedSkill = z.infer<typeof seedSkillSchema>\nexport type SeedAgent = z.infer<typeof seedAgentSchema>\nexport type SeedSkillTree = z.infer<typeof seedSkillTreeSchema>\nexport type SeedExternalSkill = z.infer<typeof seedExternalSkillSchema>\nexport type SeedPayload = z.infer<typeof seedPayloadSchema>\n","import { z } from \"zod\"\n\n// The wire contract for a catalogue: the CLI's `MergedSkillsMatrix`, described\n// without reference to any particular vocabulary of ids.\n//\n// It has two callers and they want the same thing for different reasons. A\n// marketplace's `build marketplace` emits `catalog.json` in this shape, and the\n// editor fetches that file and `safeParse`s it — one fetch, one parse, no\n// transform layer, whichever marketplace it came from. And `generate:matrix`\n// asks it whether the artefact it is about to vendor is still a matrix at all,\n// which byte-comparison against the CLI's own copy cannot answer.\n//\n// NOT to be confused with `builtInMatrixSchema` in `built-in-matrix.ts`. That\n// one narrows every id to the vendored vocabulary — `SKILL_IDS`, `CATEGORIES`,\n// `AGENT_NAMES` — so it catches a regenerated catalogue that renamed something\n// the read models index by. It is the right boundary for the catalogue this\n// package ships and the wrong one for every other: a marketplace's ids are its\n// own, and parsing a fetched `catalog.json` with it would reject all of them by\n// construction.\n//\n// Ids are therefore `z.string().min(1)` here, and unknown keys are stripped, so\n// a matrix may grow fields without this file moving. What it does hold is the\n// fields a consumer reads — the same surface `built-in-matrix.ts` models, for\n// the same reason: a catalogue that dropped one fails here, loudly, rather than\n// rendering a blank grid.\n\nconst idSchema = z.string().min(1)\n\nconst matrixCategorySchema = z.object({\n id: idSchema,\n displayName: z.string(),\n description: z.string(),\n // Optional in the CLI's type. A category without one cannot be placed in the\n // UI, so a consumer drops it rather than failing the whole catalogue.\n domain: z.string().exactOptional(),\n exclusive: z.boolean(),\n required: z.boolean(),\n order: z.number(),\n})\n\nconst skillRelationSchema = z.object({\n skillId: idSchema,\n reason: z.string(),\n})\n\nconst skillRequirementSchema = z.object({\n skillIds: z.array(idSchema),\n needsAny: z.boolean(),\n reason: z.string(),\n})\n\nconst matrixSkillSchema = z.object({\n id: idSchema,\n slug: z.string(),\n displayName: z.string(),\n description: z.string(),\n category: idSchema,\n conflictsWith: z.array(skillRelationSchema),\n discourages: z.array(skillRelationSchema),\n requires: z.array(skillRequirementSchema),\n})\n\nconst matrixStackSchema = z.object({\n id: idSchema,\n name: z.string(),\n description: z.string(),\n // agent id → category id → skill ids. A stack names the few agents it staffs\n // rather than the whole roster, and the agent roster is as marketplace-owned\n // as the skills are, so neither level is narrowed.\n skills: z.record(z.string(), z.record(z.string(), z.array(idSchema))),\n allSkillIds: z.array(idSchema),\n philosophy: z.string(),\n // Never populated by the CLI today; a stack rail groups by it when it appears.\n group: z.string().exactOptional(),\n})\n\nexport const matrixSchema = z.object({\n version: z.string(),\n categories: z.record(z.string(), matrixCategorySchema),\n skills: z.record(z.string(), matrixSkillSchema),\n suggestedStacks: z.array(matrixStackSchema),\n})\n\nexport type Matrix = z.infer<typeof matrixSchema>\nexport type MatrixSkill = z.infer<typeof matrixSkillSchema>\nexport type MatrixCategory = z.infer<typeof matrixCategorySchema>\nexport type MatrixStack = z.infer<typeof matrixStackSchema>\n","import { z } from \"zod\"\n\n// The wire contract for the federated skill index. A daily GitHub Action crawls\n// a small allowlist of EXTERNAL skills repositories, proves each skill\n// installable by reading its SKILL.md, and publishes the result to the worker's\n// KV; `apps/server` serves it under `GET /skills` and the editor's add-skills\n// dialog filters that list client-side.\n//\n// It lives here for the same reason `seed.ts` does: the worker and the editor\n// both have to agree about the shape, and neither may import the other — the\n// worker's source names `Env` from `wrangler types`, which redefines DOM\n// globals in anything that pulls it in. The Action's crawl reads it too, which\n// is the third party this shape now has to hold still for.\n//\n// There is no version field, unlike the seed payload. A seed payload is stored\n// forever under an id someone may have written down; an index is rebuilt from\n// scratch every day, so a shape change is handled by bumping the KV key — which\n// the worker owns and nothing else can hold a link to.\n\n// One skill, as the dialog needs it: enough to show a result, and enough to\n// fetch it afterwards. `repo` + `path` together are the install coordinates.\nexport const skillIndexEntrySchema = z.object({\n // The skill's own name — its frontmatter `name` where there is one, its\n // directory name where there is not. Never empty: a skill with neither is\n // not addressable and does not make it into the index.\n name: z.string().min(1),\n // Frontmatter `description`, or the SKILL.md's first heading. Empty when the\n // file offers neither, which is a thin result rather than an invalid one.\n description: z.string(),\n // GitHub's own `owner/name`, so a result can be attributed and fetched\n // without a second lookup.\n repo: z.string().min(1),\n // The skill DIRECTORY within that repo — `skills/docx`, not\n // `skills/docx/SKILL.md`. A skill is a directory in every consumer of this\n // index, and the file is only how the directory proves itself.\n path: z.string().min(1),\n // The repository's star count when the index was built. A property of the\n // repo rather than the skill, repeated per entry because the dialog ranks\n // and badges individual results.\n stars: z.number().int().nonnegative(),\n // How much the skill's whole DIRECTORY weighs — the sum over its blobs of the\n // sizes GitHub reported for them in the tree listing the crawl already made,\n // never a download. Repeated per entry because the cap it is read against is\n // per skill: `MAX_EXTERNAL_SKILL_BYTES` decides whether one directory can\n // ride a shared link, and without this number that decision cannot be made\n // until the consumer has listed the repository itself. Zero is a real answer,\n // for a directory GitHub reported no sizes for at all.\n bytes: z.number().int().nonnegative(),\n})\n\nexport const skillIndexSchema = z.object({\n // When this index was assembled, as an ISO 8601 instant. The worker's own\n // freshness check reads it, and it is served so a caller can say how old the\n // list is rather than having to guess.\n builtAt: z.iso.datetime(),\n skills: z.array(skillIndexEntrySchema),\n})\n\n// Whether what was served is the current whole picture. `stale` covers both an\n// upstream the worker could not refresh and a cold index still filling in —\n// from a caller's side those are the same statement: this list is not\n// everything, ask again later.\nexport const skillIndexFreshnessSchema = z.enum([\"fresh\", \"stale\"])\n\n// The response header carrying it. Named here rather than spelled out in the\n// worker, its mocks and the editor, because a header three packages have to\n// agree about is a contract like any other.\nexport const SKILL_INDEX_FRESHNESS_HEADER = \"x-skill-index\"\n\nexport type SkillIndexEntry = z.infer<typeof skillIndexEntrySchema>\nexport type SkillIndex = z.infer<typeof skillIndexSchema>\nexport type SkillIndexFreshness = z.infer<typeof skillIndexFreshnessSchema>\n","import type { AgentName, SkillId } from \"../../types/index.js\";\nimport type { AgentScopeConfig, SkillConfig, SkillScope } from \"../../types/config.js\";\n\n/** Shared shape of scoped config entries (skills and agents). */\nexport type ScopedEntry = { scope?: SkillScope; excluded?: boolean };\n\n/** Active (non-excluded) entry at the given scope. */\nexport function isActiveAt(entry: ScopedEntry, scope: SkillScope): boolean {\n return entry.scope === scope && !entry.excluded;\n}\n\n/** Tombstone masking a global install (`scope === \"global\"` + excluded). */\nexport function isGlobalTombstone(entry: ScopedEntry): boolean {\n return entry.scope === \"global\" && !!entry.excluded;\n}\n\n/**\n * Entry the project owns: a project-scoped entry, or the project's own global\n * tombstone. Inherited global-active entries belong to the global config.\n */\nexport function isProjectOwned(entry: ScopedEntry): boolean {\n return entry.scope === \"project\" || isGlobalTombstone(entry);\n}\n\n/** Names of active project-scoped agents. */\nexport function activeProjectAgentNames(agents: readonly AgentScopeConfig[]): AgentName[] {\n return agents.filter((a) => isActiveAt(a, \"project\")).map((a) => a.name);\n}\n\n/**\n * Names of every active (non-excluded) agent, at either scope — the config's own\n * record of who is selected, now that no flat `selectedAgents` list is persisted.\n * Exported ahead of a second caller by the key-builder exception: the emitted\n * `SelectedAgentName` union and the wizard's agent hydration must derive the same\n * set from the same rows, and two surfaces each writing their own filter is the\n * drift this replaces.\n */\nexport function activeAgentNames(agents: readonly AgentScopeConfig[]): AgentName[] {\n return agents.filter((a) => !a.excluded).map((a) => a.name);\n}\n\n/** Scope of each active (non-excluded) skill, keyed by id. */\nexport function activeSkillScopeMap(\n skills: readonly SkillConfig[] | undefined,\n): Map<SkillId, SkillScope> {\n return new Map((skills ?? []).filter((s) => !s.excluded).map((s) => [s.id, s.scope]));\n}\n\n/** Scope of each active (non-excluded) agent, keyed by name. */\nexport function activeAgentScopeMap(\n agents: readonly AgentScopeConfig[] | undefined,\n): Map<AgentName, SkillScope> {\n return new Map((agents ?? []).filter((a) => !a.excluded).map((a) => [a.name, a.scope]));\n}\n\n/**\n * Ids of skills that are effectively excluded: they have an excluded entry and no\n * active (non-excluded) entry with the same id rescues them. A skill with an\n * excluded global entry AND an active project entry is NOT effectively excluded.\n */\nexport function effectivelyExcludedSkillIds(skills: readonly SkillConfig[]): Set<SkillId> {\n const activeIds = new Set(skills.filter((s) => !s.excluded).map((s) => s.id));\n return new Set(skills.filter((s) => s.excluded && !activeIds.has(s.id)).map((s) => s.id));\n}\n","import { indexBy, uniqueBy } from \"remeda\";\n\nimport type { ProjectConfig } from \"../../types\";\nimport type { AgentScopeConfig, SkillConfig } from \"../../types/config\";\nimport { getProjectConfigPath } from \"../installation/install-base-dir\";\nimport { loadProjectConfig, type LoadedProjectConfig } from \"./project-config\";\nimport { loadProjectSourceConfig } from \"./config\";\nimport { isGlobalTombstone, isProjectOwned, type ScopedEntry } from \"./scope-predicates\";\n\n/**\n * How authoritative `newConfig` is over entries absent from it (D-233 Scenario C):\n * - `\"all\"` — global-context EDIT at ~/: the wizard loaded the ENTIRE global config, so any\n * absent agent/skill was removed. Every existing entry is in scope.\n * - `\"owned\"` — project-context EDIT: the wizard loaded the full project roster and owns only\n * PROJECT-OWNED entries (project-scoped + the project's own global tombstones).\n * Inherited global-active entries are read-only and are always preserved.\n * - `undefined` — init / non-edit merges: additive union-preserve (never drop absent entries).\n */\nexport type AuthoritativeScope = \"all\" | \"owned\";\n\nexport type MergeContext = {\n projectDir: string;\n authoritativeScope?: AuthoritativeScope;\n};\n\nexport type MergeResult = {\n config: ProjectConfig;\n merged: boolean;\n existingConfigPath?: string;\n};\n\n/**\n * Compound identity key for an agent entry. Includes scope and the excluded\n * discriminator so that `{name, scope:\"project\"}` and `{name, scope:\"global\"}`\n * (and their tombstone variants) are treated as distinct entries rather than\n * collapsed onto `name` alone (D-221).\n */\nconst agentKey = (a: AgentScopeConfig): string =>\n `${a.name}:${a.scope}${a.excluded ? \":excluded\" : \"\"}`;\n\n/**\n * Compound identity key for a skill entry. Same shape as {@link agentKey}:\n * `id:scope` for actives, `id:scope:excluded` for tombstones. Prevents the\n * D-221 class of bugs where two distinct-scope entries collide onto `id`.\n */\nconst skillKey = (s: SkillConfig): string => `${s.id}:${s.scope}${s.excluded ? \":excluded\" : \"\"}`;\n\n/** Names of agents carrying a global tombstone — i.e. dual-scope entries the project owns. */\nfunction agentTombstoneNames(agents: AgentScopeConfig[]): Set<string> {\n return new Set(agents.filter(isGlobalTombstone).map((a) => a.name));\n}\n\n/** Ids of skills carrying a global tombstone — i.e. dual-scope entries the project owns. */\nfunction skillTombstoneIds(skills: SkillConfig[]): Set<string> {\n return new Set(skills.filter(isGlobalTombstone).map((s) => s.id));\n}\n\n/**\n * True when an existing entry is within the current edit session's authority, so its absence\n * from `newConfig` means a deliberate removal (drop) rather than an untouched entry (preserve).\n *\n * `\"all\"` (global edit): every entry is owned. `\"owned\"` (project edit): only project-scoped\n * entries and the project's own global tombstones — inherited global-active entries belong to\n * the global config and must never be dropped from a project edit.\n */\nfunction isWithinSessionAuthority(entry: ScopedEntry, scope: AuthoritativeScope): boolean {\n if (scope === \"all\") return true;\n return isProjectOwned(entry);\n}\n\n/**\n * Pure merge logic: existing values take precedence for identity fields;\n * agents and skills are merged so that `newConfig` is authoritative for every\n * `name`/`id` it references. Existing entries survive in-place when their\n * compound key matches a new entry (same name, scope, excluded). Existing\n * entries whose NAME/ID appears in new but whose compound key does NOT match\n * a new entry are dropped — this is how scope migrations (P→G, G→P) remove\n * stale rows and how P→G tombstone removal is honored. Existing entries whose\n * name/ID is absent from new are preserved unchanged — EXCEPT names/ids the\n * project owned as dual-scope this session (they carry a global tombstone in the\n * existing config): when new carries nothing for such a name, the user fully\n * deselected the dual-scope row, so both the lingering active project entry and\n * the stale tombstone are dropped together (D-233 Scenario B full-deselect).\n *\n * A final compound-key dedup (keeping first occurrence, which in our concat\n * order is the existing-derived or first-new entry) collapses any pre-existing\n * on-disk corruption rather than carrying multiplied duplicates forward.\n *\n * Dual-scope semantics (active at one scope + excluded tombstone at another)\n * are preserved because `newConfig.agents`/`newConfig.skills` carry BOTH\n * entries for the same name/id when that dual state is legitimate (wizard\n * output from `generateProjectConfigFromSkills` + `toggleAgentScope`).\n *\n * D-221 root cause (fixed here): the prior name-only key collapsed\n * distinct-scope entries, and the positional `.map()` over existing rewrote\n * every collision slot — multiplying pre-existing duplicates and failing to\n * drop stale rows on scope migration.\n *\n * `authoritativeScope` (D-233 Scenario C): a full `cc edit` pass presents the complete roster\n * the wizard could edit, so an entry within that authority which is absent from `newConfig` was\n * deliberately removed and must be dropped (even a plain active entry with no tombstone), rather\n * than union-preserved. `\"all\"` (global edit) covers every entry; `\"owned\"` (project edit) covers\n * only project-scoped entries and the project's own global tombstones — inherited global-active\n * entries are always preserved. `undefined` (init) keeps additive union-preserve.\n *\n * A skill the wizard could not resolve from the loaded source this session is NOT exempt from that\n * drop: it is removed like any other absent entry, and `edit` names it and says why in its Changes\n * block. Exempting it used to keep an entry in `config.ts` that the same run's summary announced as\n * gone and the compiled agent no longer carried — three surfaces, three answers about one skill.\n */\ntype MergeOptions = Pick<MergeContext, \"authoritativeScope\">;\n\nexport function mergeConfigs(\n newConfig: ProjectConfig,\n existingConfig: ProjectConfig,\n options?: MergeOptions,\n): ProjectConfig {\n const merged = { ...newConfig };\n\n if (existingConfig.name) {\n merged.name = existingConfig.name;\n }\n\n if (existingConfig.description) {\n merged.description = existingConfig.description;\n }\n\n if (existingConfig.marketplace && !newConfig.marketplace) {\n merged.marketplace = existingConfig.marketplace;\n }\n\n if (existingConfig.agents.length > 0) {\n const newAgentsByKey = indexBy(merged.agents, agentKey);\n const newAgentNames = new Set(merged.agents.map((a) => a.name));\n const existingKeys = new Set(existingConfig.agents.map(agentKey));\n // Names the project managed as dual-scope this session: a global tombstone in the\n // existing config marks an agent whose global install the project actively overrode.\n // When newConfig carries NO entry for such a name, the user fully deselected the\n // dual-scope row — both the lingering active project entry and the stale tombstone\n // must drop together, not be preserved (D-233 Scenario B full-deselect).\n const dualScopeAgentNames = agentTombstoneNames(existingConfig.agents);\n const updatedExisting = existingConfig.agents.flatMap((existing) => {\n const matching = newAgentsByKey[agentKey(existing)];\n if (matching) return [matching];\n // Name is actively managed by newConfig but this exact (scope, excluded)\n // slot is NOT in new → the wizard intentionally dropped this row\n // (scope migration or tombstone cleanup). Drop it.\n if (newAgentNames.has(existing.name)) return [];\n if (dualScopeAgentNames.has(existing.name)) return [];\n // Authoritative edit: an in-authority agent absent from newConfig (even a plain active\n // one with no tombstone) was deselected and must be dropped (D-233 Scenario C).\n if (\n options?.authoritativeScope &&\n isWithinSessionAuthority(existing, options.authoritativeScope)\n )\n return [];\n return [existing];\n });\n const addedAgents = merged.agents.filter((a) => !existingKeys.has(agentKey(a)));\n merged.agents = uniqueBy([...updatedExisting, ...addedAgents], agentKey);\n } else {\n merged.agents = uniqueBy(merged.agents, agentKey);\n }\n\n if (existingConfig.skills.length > 0) {\n const newSkillsByKey = indexBy(merged.skills, skillKey);\n const newSkillIds = new Set(merged.skills.map((s) => s.id));\n const existingKeys = new Set(existingConfig.skills.map(skillKey));\n // Skill-side twin of dualScopeAgentNames — see the agent branch above (D-233).\n const dualScopeSkillIds = skillTombstoneIds(existingConfig.skills);\n const updatedExisting = existingConfig.skills.flatMap((existing) => {\n const matching = newSkillsByKey[skillKey(existing)];\n if (matching) return [matching];\n if (newSkillIds.has(existing.id)) return [];\n if (dualScopeSkillIds.has(existing.id)) return [];\n // Skill-side twin — see the agent branch above (D-233 Scenario C).\n if (\n options?.authoritativeScope &&\n isWithinSessionAuthority(existing, options.authoritativeScope)\n )\n return [];\n return [existing];\n });\n const addedSkills = merged.skills.filter((s) => !existingKeys.has(skillKey(s)));\n merged.skills = uniqueBy([...updatedExisting, ...addedSkills], skillKey);\n } else {\n merged.skills = uniqueBy(merged.skills, skillKey);\n }\n\n // Stack is the pure output of the mutator — trust newConfig.stack whenever it\n // is defined. Only fall back to existingConfig.stack when the new config has\n // none (preserves existing during non-stack-touching operations).\n if (newConfig.stack === undefined && existingConfig.stack) {\n merged.stack = existingConfig.stack;\n }\n\n if (existingConfig.author) {\n merged.author = existingConfig.author;\n }\n\n if (existingConfig.agentsSource) {\n merged.agentsSource = existingConfig.agentsSource;\n }\n\n if (existingConfig.marketplaceName) {\n merged.marketplaceName = existingConfig.marketplaceName;\n }\n\n // Preserve the registered project paths from the existing (global) config — the wizard\n // result never carries them, and losing them silently disables propagation of global\n // changes to registered projects (D-233 Scenario C: the tombstone reconcile never runs).\n if (existingConfig.projects && !newConfig.projects) {\n merged.projects = existingConfig.projects;\n }\n\n return merged;\n}\n\n/**\n * The config the merge reconciles against, wearing an identity this directory can own.\n *\n * `loadProjectConfig` falls back to `os.homedir()` for a project that carries no config of\n * its own, so a first save into a project sitting under an existing global install\n * reconciles against the GLOBAL config — whose `name` identifies that installation and no\n * directory here. `mergeConfigs`' identity-field carry-forward would then stamp it onto the\n * project's own file.\n *\n * The carry-forward itself is intentional and stays: a project's OWN prior config is how a\n * hand-renamed `config.ts` keeps its name across saves. What decides between the two is the\n * provenance of the load, which is known here and nowhere inside the pure merge — so a\n * config that came from the home fallback lends this save every field except its name.\n */\nfunction existingConfigForMerge(\n loaded: LoadedProjectConfig,\n projectDir: string,\n ownName: string,\n): ProjectConfig {\n const isProjectsOwnFile = loaded.configPath === getProjectConfigPath(projectDir);\n return isProjectsOwnFile ? loaded.config : { ...loaded.config, name: ownName };\n}\n\nexport async function mergeWithExistingConfig(\n newConfig: ProjectConfig,\n context: MergeContext,\n): Promise<MergeResult> {\n const existingFullConfig = await loadProjectConfig(context.projectDir);\n if (existingFullConfig) {\n // A full `cc edit` pass loads the complete roster, so newConfig is authoritative over the\n // entries it owns — every entry for a global edit (`\"all\"`), or project-owned entries for a\n // project edit (`\"owned\"`). Absent owned entries were deselected and are dropped rather than\n // union-preserved (D-233 Scenario C). Init leaves the scope undefined (additive union).\n const existingConfig = existingConfigForMerge(\n existingFullConfig,\n context.projectDir,\n newConfig.name,\n );\n const config = mergeConfigs(newConfig, existingConfig, {\n ...(context.authoritativeScope !== undefined && {\n authoritativeScope: context.authoritativeScope,\n }),\n });\n\n return {\n config,\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 localConfig = { ...newConfig };\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 type { ProjectConfig, ValidationResult } from \"../../types\";\nimport { normalizeStackRecord } from \"../stacks/stacks-loader\";\nimport { projectConfigLoaderSchema } from \"../schemas\";\nimport { formatZodErrors } from \"../schema-validator\";\nimport { getProjectConfigPath } from \"../installation/install-base-dir\";\nimport { isHomeDirectory } from \"../installation/is-home-directory\";\nimport { loadConfig } from \"./config-loader\";\n\nexport type LoadedProjectConfig = {\n config: ProjectConfig;\n configPath: string;\n};\n\n/**\n * Thrown when a project config file exists on disk but cannot be loaded into a\n * usable config — a syntax/evaluation error, no default export, or a shape the\n * loader schema rejects. This is deliberately distinct from a MISSING file\n * (which is a legitimate `null`): a corrupt config is an error that callers must\n * surface, never swallow into `null`. Collapsing both into `null` let a broken\n * install pass as absent (e.g. `compile` treating it as config-less and\n * resurrecting every built-in agent).\n */\nexport class ConfigLoadError extends Error {\n constructor(\n readonly configPath: string,\n readonly reason: string,\n ) {\n super(`Config at '${configPath}' could not be loaded: ${reason}`);\n this.name = \"ConfigLoadError\";\n }\n}\n\n/**\n * Load project config from a specific directory only (no global fallback).\n *\n * Returns `null` only when the config file does not exist. When the file exists\n * but cannot be parsed into a usable config, throws {@link ConfigLoadError} —\n * the caller decides how to report it.\n *\n * The two lines it announces name the scope of the file it read, the way\n * `loadSourceConfig`'s already do: the config at the home root is the GLOBAL one,\n * and a run there that calls it a project config names a file that is not there.\n */\nexport async function loadProjectConfigFromDir(\n projectDir: string,\n): Promise<LoadedProjectConfig | null> {\n const configPath = getProjectConfigPath(projectDir);\n const scope = isHomeDirectory(projectDir) ? \"global\" : \"project\";\n const scopeLabel = scope === \"project\" ? \"Project\" : \"Global\";\n\n if (!(await fileExists(configPath))) {\n verbose(`${scopeLabel} config not found at ${configPath}`);\n return null;\n }\n\n // The file exists. From here, any failure to produce a usable config means the\n // file is corrupt — surface it as ConfigLoadError rather than returning `null`,\n // which is indistinguishable from \"missing\".\n let raw: unknown;\n try {\n // Load raw object and validate with Zod (lenient schema accepts custom values via z.string() casts)\n raw = await loadConfig<ProjectConfig>(configPath);\n } catch (error) {\n throw new ConfigLoadError(configPath, getErrorMessage(error));\n }\n\n if (!raw || typeof raw !== \"object\") {\n throw new ConfigLoadError(configPath, \"the file has no valid default export\");\n }\n\n const result = projectConfigLoaderSchema.safeParse(raw);\n if (!result.success) {\n throw new ConfigLoadError(configPath, formatZodErrors(result.error).join(\"; \"));\n }\n\n // Normalize the loose stack values (bare strings, objects, arrays) BEFORE claiming\n // ProjectConfig, so the boundary cast below is the only one on this path.\n const parsed = result.data;\n const normalizedStack = parsed.stack ? normalizeStackRecord(parsed.stack) : undefined;\n if (parsed.name === undefined) {\n warn(\n `Project config at '${configPath}' is missing required 'name' field — defaulting to directory name`,\n );\n }\n if (parsed.skills === undefined) {\n warn(`Project config at '${configPath}' is missing 'skills' array — defaulting to empty`);\n }\n\n // The defaults are applied here rather than mutated in afterwards, so the cast is the\n // last thing that happens and ProjectConfig's required fields are genuinely present.\n // `agents` is defaulted for the same reason `skills` is: the loader schema admits its\n // absence, ProjectConfig declares it required, and every caller was paying for the gap\n // with a `?? []` the type said was dead.\n //\n // Boundary cast: the loader schema is lenient about the string unions (category, slug,\n // domain), so the literal still does not satisfy ProjectConfig even with the defaults in\n // place; validateProjectConfig enforces the strict shape after load.\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- see above\n const config = {\n ...parsed,\n name: parsed.name ?? path.basename(projectDir),\n skills: parsed.skills ?? [],\n agents: parsed.agents ?? [],\n ...(normalizedStack && { stack: normalizedStack }),\n } as ProjectConfig;\n\n verbose(`Loaded ${scope} config from ${configPath}`);\n return {\n config,\n configPath,\n };\n}\n\n/**\n * The directories whose config a run reads: the project's own, plus the global one it\n * inlines. At the home root the two collapse into one.\n */\nexport function configDirsInPlay(projectDir: string): string[] {\n return isHomeDirectory(projectDir) ? [projectDir] : [projectDir, os.homedir()];\n}\n\n/**\n * Every config a run would read that exists and cannot be loaded, in the order the run reads\n * them. A directory whose config is absent (legitimate) or loads contributes nothing; any other\n * failure is a real fault and propagates.\n *\n * Exported rather than kept private to its first caller because two surfaces have to agree on\n * exactly which configs are in play: `BaseCommand.ensureConfigReadable`, which refuses to run over\n * one it cannot read, and `doctor`, which reports the same fault. Two answers to that question is\n * how the CLI ended up refusing a file in one command and calling it missing in another.\n */\nexport async function findConfigLoadFailures(projectDir: string): Promise<ConfigLoadError[]> {\n const outcomes = await Promise.all(configDirsInPlay(projectDir).map(configLoadFailure));\n return outcomes.filter((failure): failure is ConfigLoadError => failure !== undefined);\n}\n\nasync function configLoadFailure(dir: string): Promise<ConfigLoadError | undefined> {\n try {\n await loadProjectConfigFromDir(dir);\n return undefined;\n } catch (error) {\n if (error instanceof ConfigLoadError) return error;\n throw error;\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 (!isHomeDirectory(projectDir)) {\n return loadProjectConfigFromDir(homeDir);\n }\n\n return null;\n}\n\n/**\n * Validates a loaded config value. Shape validity is defined by\n * `projectConfigLoaderSchema` (the single definition); on top of the schema's\n * lenient shape, a usable project config additionally requires `name` and\n * `agents` to be present.\n */\nexport function validateProjectConfig(config: unknown): ValidationResult {\n const result = projectConfigLoaderSchema.safeParse(config);\n if (!result.success) {\n return { valid: false, errors: formatZodErrors(result.error), warnings: [] };\n }\n\n const errors = [\n ...(result.data.name ? [] : [\"name is required and must be a string\"]),\n ...(result.data.agents ? [] : [\"agents is required and must be an array\"]),\n ];\n return { valid: errors.length === 0, errors, warnings: [] };\n}\n","import path from \"path\";\nimport { flatMap, groupBy, mapValues, partition, pipe, unique, uniqueBy } from \"remeda\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { verbose, warn } from \"../../utils/logger\";\nimport { hasSkill, matrix } from \"../matrix/matrix-provider\";\nimport type {\n AgentName,\n SkillAssignment,\n SkillId,\n SkillReference,\n Stack,\n StackAgentConfig,\n Category,\n} from \"../../types\";\nimport { stacksConfigSchema } from \"../schemas\";\nimport { typedEntries } from \"../../utils/typed-object\";\nimport { isSkillAssignment } from \"../../utils/type-guards\";\nimport { LOCAL_PSEUDO_CATEGORY, STACKS_FILE_PATH } from \"../../consts\";\nimport { loadConfig } from \"../configuration/config-loader\";\nimport { offersBuiltInStacks } from \"../configuration/config\";\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((item): SkillAssignment => {\n if (typeof item === \"string\") return { id: item as SkillId, preloaded: false };\n if (isSkillAssignment(item)) return item;\n warn(`Malformed skill assignment in stack data: ${JSON.stringify(item)}`);\n return item as SkillAssignment;\n });\n });\n}\n\n/**\n * Where the live catalog says a skill's entry belongs, or `undefined` when it\n * has nothing to say: an id the matrix does not carry (local, marketplace, or\n * withdrawn) and a skill in the `local` pseudo-category both leave the key the\n * config already spells as the only word available.\n */\nfunction liveCategoryOf(skillId: SkillId): Category | undefined {\n const category = matrix.skills[skillId]?.category;\n if (category === undefined || category === LOCAL_PSEUDO_CATEGORY) return undefined;\n // TypeScript narrows CategoryPath to Category after excluding \"local\"\n return category;\n}\n\ntype PlacedAssignment = {\n storedCategory: Category;\n liveCategory: Category;\n assignment: SkillAssignment;\n};\n\nfunction placeAssignments(agentConfig: StackAgentConfig): PlacedAssignment[] {\n return typedEntries<Category, SkillAssignment[]>(agentConfig).flatMap(\n ([storedCategory, assignments]) =>\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n (assignments ?? []).map((assignment) => ({\n storedCategory,\n liveCategory: liveCategoryOf(assignment.id) ?? storedCategory,\n assignment,\n })),\n );\n}\n\n/**\n * One agent's saved stack re-keyed under each skill's live category.\n *\n * A persisted `stack` block names the category each skill sat in when it was\n * written, and every consumer downstream — the generator's preservation\n * lookup, the load-state lookup, the compiled agent's usage line — asks the\n * live catalog. When a release moves a skill between categories the two stop\n * agreeing, and a saved entry nobody can find is a saved entry nobody keeps.\n * Re-keying here is what keeps the question answerable: the category is where\n * an entry is STORED, the id is which skill it names, and only the id is\n * identity.\n *\n * A skill already under its live category wins any collision with a stale\n * duplicate of itself — it is the current word for that pair, and one skill\n * may appear once per agent.\n */\nfunction rekeyToLiveCategories(agentConfig: StackAgentConfig): StackAgentConfig {\n const [settled, moved] = partition(\n placeAssignments(agentConfig),\n (placed) => placed.liveCategory === placed.storedCategory,\n );\n\n if (moved.length > 0) {\n verbose(\n `Re-keyed stack entries to their live category: ` +\n moved\n .map((p) => `${p.assignment.id} (${p.storedCategory} -> ${p.liveCategory})`)\n .join(\", \"),\n );\n }\n\n return mapValues(\n groupBy([...settled, ...moved], (placed) => placed.liveCategory),\n (placed) =>\n uniqueBy(\n placed.map((p) => p.assignment),\n (assignment) => assignment.id,\n ),\n );\n}\n\n/**\n * Normalizes a raw stack record (agent -> raw category config) to the typed form.\n * Applies normalizeAgentConfig to each agent entry, then re-keys the result to\n * the live catalog (see {@link rekeyToLiveCategories}).\n *\n * This is the PERSISTED-CONFIG boundary — `loadProjectConfigFromDir` and the\n * config gate's writer entry. A source's `stacks.ts` deliberately does not pass\n * through here: its category key is the author's heading for the agent prompt,\n * shipped alongside the catalog it references, so there is no drift to\n * reconcile and nothing to overrule.\n */\nexport function normalizeStackRecord(\n rawStack: Record<string, Record<string, unknown>>,\n): Record<string, StackAgentConfig> {\n return mapValues(rawStack, (agentConfig) =>\n rekeyToLiveCategories(normalizeAgentConfig(agentConfig)),\n );\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(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),\n ),\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 cause: error,\n });\n }\n}\n\n/**\n * One stack by id, scoped the way the wizard's stack step is.\n *\n * The source's own stacks answer first. The CLI's built-in catalogue stands in\n * only for the public catalogue — the same rule `resolveOfferedStacks` applies to\n * the list the wizard offers, read from the same {@link offersBuiltInStacks} so\n * the two cannot answer differently. They are a pair: that one decides what is\n * OFFERED and this one resolves what was PICKED, so a rule they disagree on\n * offers a stack and then refuses to install it.\n *\n * Under any other source a built-in id names a stack that source does not have,\n * and answering with one would install stacks written against a different\n * catalogue of skills, under a name the user never asked for. Null is the honest\n * answer there; the callers name the id they asked for.\n */\nexport async function loadStackById(\n stackId: string,\n configDir: string,\n source: string,\n): 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 if (!(await offersBuiltInStacks(configDir, source))) {\n verbose(\n `Marketplace '${source}' does not ship stack '${stackId}', and gets no built-in stand-in`,\n );\n return null;\n }\n\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 the default marketplace or the built-ins`);\n }\n return defaultStack;\n}\n\n/**\n * What a null from {@link loadStackById} means, said once.\n *\n * Both callers turn that null into a failure, and both have to name the id they\n * asked for and the source they asked — a stack that cannot be found is only\n * actionable if the message says which stack and where it was looked for. One\n * definition so the two surfaces cannot describe the same rule differently.\n */\nexport function stackNotOfferedMessage(stackId: string, source: string): string {\n return (\n `Stack '${stackId}' is not a stack the source '${source}' offers. ` +\n `A marketplace ships its own stacks; the CLI's built-in ones belong to the default ` +\n `public marketplace alone.`\n );\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 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n (assignments ?? []).map((assignment): SkillReference => {\n if (!hasSkill(assignment.id)) {\n warn(\n `Skill '${assignment.id}' for category '${category}' not found in matrix. It may be a custom or local skill.`,\n { suppressInTest: true },\n );\n }\n return {\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","import path from \"path\";\nimport { groupBy, unique } from \"remeda\";\nimport type {\n AgentName,\n Category,\n CategoryPath,\n Domain,\n MergedSkillsMatrix,\n ProjectConfig,\n SkillId,\n} from \"../../types\";\nimport { loadProjectConfigFromDir } from \"./project-config\";\nimport { isHomeDirectory } from \"../installation/is-home-directory\";\n// The gate's private token module, imported here by exception (eslint records\n// it): this is one of the two enforcement guards, and `gate-token.ts` is a\n// dependency-free leaf, so the import cannot cycle back through the gate.\nimport { GlobalPairWriteViolation } from \"../config-gate/gate-token.js\";\nimport { activeAgentNames, activeProjectAgentNames } from \"./scope-predicates\";\nimport {\n CLAUDE_SRC_DIR,\n CLI_INVOKE_COMMAND,\n GLOBAL_INSTALL_ROOT,\n LOCAL_PSEUDO_CATEGORY,\n STANDARD_FILES,\n} from \"../../consts\";\nimport { directoryExists, fileExists, writeFile } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport { bytewise } from \"../../utils/string\";\nimport { typedEntries, typedKeys } from \"../../utils/typed-object\";\nimport { EFFORT_NAMES, MODEL_NAMES } from \"../../types/matrix\";\n\nconst MULTI_LINE_THRESHOLD = 6;\n\n/**\n * Emitted for a union with no members. `never` is the identity element for a\n * union: an empty install must accept NO member, and `never | \"web-framework-react\"`\n * reduces to `\"web-framework-react\"`, so a project types file that extends an empty\n * global union still narrows. Emitting `string` here would instead absorb every\n * literal and silently disable type checking of the generated config.ts.\n * Matches generateBlankGlobalConfigTypesSource, which emits `never` for the same state.\n */\nconst EMPTY_UNION_TYPE = \"never\";\n\n/**\n * Extra just-created skill IDs / agent names / domains / categories to fold into\n * a regenerated config-types.ts (entities that exist in config but not yet in the\n * loaded matrix). buildProjectTypesExtras returns Required<ConfigTypesExtras>.\n */\nexport type ConfigTypesExtras = {\n extraSkillIds?: string[];\n extraAgentNames?: string[];\n extraDomains?: string[];\n extraCategories?: string[];\n};\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 * A vocabulary constant as a single-line TypeScript literal union. Deliberately not `formatUnion`:\n * that one breaks onto several lines past a threshold, which would be invalid inside an emitted\n * property, and these lists are fixed and short.\n */\nfunction formatLiteralUnion(members: readonly string[]): string {\n return members.map((m) => `\"${m}\"`).join(\" | \");\n}\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 = \"eject\" | \"plugin\" | \"mixed\";\n\nexport type SkillConfig = {\n id: SkillId;\n scope: \"project\" | \"global\";\n origin: string;\n excluded?: boolean;\n};\n\nexport type AgentScopeConfig = {\n name: AgentName;\n scope: \"project\" | \"global\";\n model?: ${formatLiteralUnion(MODEL_NAMES)};\n effort?: ${formatLiteralUnion(EFFORT_NAMES)};\n excluded?: boolean;\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 /** 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 provenance */\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<ProjectAgentName, StackAgentConfig>>;\n\n /** The marketplace this install reads skills from, as a path or URL */\n marketplace?: string;\n\n /** The name that marketplace's manifest gives it, which plugins are registered under */\n marketplaceName?: 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 selectedDomains?: Domain[];\n\n /** Tracked project installation paths (global config only) */\n projects?: string[];\n}\n`;\n\n/**\n * Loose StackAgentConfig line emitted when no per-category skill constraint applies. Admits a\n * single assignment as well as an array: project configs always get this line, and they carry the\n * bare (unwrapped) form for exclusive categories.\n */\nexport const STACK_AGENT_CONFIG_LOOSE_LINE =\n \"export type StackAgentConfig = Partial<Record<Category, SkillAssignment | SkillAssignment[]>>;\";\n\n/**\n * Assembles a config-types.ts source from its per-alias union lines — the single\n * template shared by generateConfigTypesSource, generateProjectConfigTypesSource,\n * and generateBlankGlobalConfigTypesSource. Their emitted text is identical apart\n * from the alias contents, the StackAgentConfig line, and the optional\n * (project-only) import block.\n *\n * The emitted ProjectConfig interface (PROJECT_CONFIG_INTERFACE_AFTER) deliberately\n * diverges from types/config.ts: it uses the narrowed generated aliases\n * (SelectedAgentName, ProjectAgentName, per-category StackAgentConfig) so a user's\n * config.ts is type-checked against only the installed skills/agents rather than\n * the full runtime union.\n */\nexport function assembleConfigTypesSource(parts: {\n importBlock?: string;\n skillId: string;\n agentName: string;\n selectedAgentName: string;\n projectAgentName: string;\n domain: string;\n category: string;\n stackAgentConfig: string;\n}): string {\n const importSection = parts.importBlock ? `${parts.importBlock}\\n\\n` : \"\";\n return `// AUTO-GENERATED by agents-inc — DO NOT EDIT\n\n${importSection}export type SkillId = ${parts.skillId};\n\nexport type AgentName = ${parts.agentName};\n\nexport type SelectedAgentName = ${parts.selectedAgentName};\n\nexport type ProjectAgentName = ${parts.projectAgentName};\n\nexport type Domain = ${parts.domain};\n\nexport type Category = ${parts.category};\n\n${PROJECT_CONFIG_TYPES_BEFORE}\n${parts.stackAgentConfig}\n\n${PROJECT_CONFIG_INTERFACE_AFTER}`;\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 line when no categories have skills.\n *\n * The union is over WHICH skill may be assigned; exclusivity is about HOW MANY, so an exclusive\n * category emits a bare `SkillAssignment<...>` (no array) however long its candidate list is. A\n * category the matrix does not declare is not treated as exclusive — same rule the installer\n * applies, on the same reasoning: a constraint must fire on a flag the data actually carries.\n */\nfunction generateStackAgentConfig(\n skillsByCategory: Map<Category, SkillId[]>,\n matrix: MergedSkillsMatrix,\n): string {\n if (skillsByCategory.size === 0) {\n return STACK_AGENT_CONFIG_LOOSE_LINE;\n }\n\n const properties = [...skillsByCategory.entries()]\n // A project commits its config-types.ts, so the key order has to be the comparator's rather\n // than the collation of whichever machine last ran the CLI.\n .sort(([a], [b]) => bytewise(a, b))\n .map(([category, skills]) => {\n const arraySuffix = matrix.categories[category]?.exclusive === true ? \"\" : \"[]\";\n return ` \"${category}\"?: SkillAssignment<${formatSkillUnion(skills)}>${arraySuffix};`;\n });\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 eligible = [...new Set(skillIds)]\n .map((id) => ({ id, category: matrix.skills[id]?.category }))\n .filter(\n (entry): entry is { id: SkillId; category: Category } =>\n entry.category !== undefined &&\n entry.category !== LOCAL_PSEUDO_CATEGORY &&\n categorySet.has(entry.category),\n );\n\n return new Map(\n typedEntries(groupBy(eligible, (entry) => entry.category)).map(([category, entries]) => [\n category,\n entries.map((entry) => entry.id),\n ]),\n );\n}\n\n/**\n * A category no loaded catalogue declares, which is the whole of what makes one custom.\n *\n * Deliberately not \"a category a custom skill is in\": a custom skill is PLACED in a category that\n * already exists rather than bringing one, so the skills that REFERENCE a category say nothing\n * about who declared it — and reading them that way labelled a category the public catalogue\n * ships as the user's own. The same holds for a category arriving as an extra: an extra is every\n * literal a just-written config.ts holds, most of them the catalogue's.\n */\nfunction isUndeclaredCategory(category: Category, matrix: MergedSkillsMatrix): boolean {\n return matrix.categories[category] === undefined;\n}\n\n/**\n * A skill the loaded catalogue does not declare, or declares as the user's own.\n *\n * The same rule the category axis takes, plus the one signal skills carry that categories do not:\n * `custom: true` is written into a skill's own metadata, so a skill the matrix holds AND flags is\n * the user's however it got there. What is NOT read is which argument the id arrived in — an extra\n * is a literal the just-written config.ts holds, and on the project standalone path that is the\n * whole configuration, most of it the catalogue's.\n *\n * `local: true` is deliberately not a second signal: an ejected catalogue skill is copied into\n * `.claude/skills/` and rediscovered as local, so it would label the catalogue's own work custom.\n */\nfunction isCustomSkill(skillId: SkillId, matrix: MergedSkillsMatrix): boolean {\n const declared = matrix.skills[skillId];\n return declared === undefined || declared.custom === true;\n}\n\n/**\n * An agent the loaded source does not declare, or declares as the user's own.\n *\n * `agentNames` is every agent that source ships and `customAgentNames` the ones it marks custom,\n * so the pair is the agent axis's equivalent of the matrix: anything outside the first is nobody's\n * declaration, anything inside the second is declared as the user's.\n */\nfunction isCustomAgent(\n agentName: AgentName,\n declared: ReadonlySet<AgentName>,\n flaggedCustom: ReadonlySet<AgentName>,\n): boolean {\n return !declared.has(agentName) || flaggedCustom.has(agentName);\n}\n\n/**\n * A domain no category the loaded catalogue declares carries.\n *\n * This replaces a subtraction over custom categories that can no longer fire: under the category\n * rule above a custom category is by definition absent from `matrix.categories`, and that map was\n * the only thing the subtraction walked.\n */\nfunction isCustomDomain(domain: string, declared: ReadonlySet<string>): boolean {\n return !declared.has(domain);\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 --marketplace 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_INVOKE_COMMAND} init' first`);\n }\n\n const { loadSkillsMatrixFromSource } = await import(\"../loading/source-loader\");\n const { loadMergedAgents } = await import(\"../loading/loader\");\n\n const sourceResult = await loadSkillsMatrixFromSource({\n ...(sourceFlag !== undefined && { sourceFlag }),\n projectDir,\n skipExtraSources: true,\n });\n\n const allAgents = await loadMergedAgents(sourceResult.sourcePath);\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?: ConfigTypesExtras,\n): Promise<void> {\n // The home directory's config-types.ts is the global pair's types half, which\n // only config-gate may write. Refusing here rather than leaving it to the\n // write primitive's tripwire names the offending entry point, and — unlike the\n // tripwire — survives a unit test that mocks `utils/fs`.\n if (isHomeDirectory(projectDir)) {\n throw new GlobalPairWriteViolation(\n path.join(projectDir, CLAUDE_SRC_DIR, STANDARD_FILES.CONFIG_TYPES_TS),\n );\n }\n\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 = !isHomeDirectory(projectDir);\n const globalConfigTypes = isProjectScope ? await getGlobalConfigTypesPath() : null;\n const loadedConfig = await loadProjectConfigFromDir(projectDir);\n\n let source: string;\n if (globalConfigTypes) {\n const agents = loadedConfig?.config.agents;\n const selectedAgentNames = agents ? activeAgentNames(agents) : undefined;\n const projectScopedAgentNames = agents ? activeProjectAgentNames(agents) : undefined;\n source = generateProjectConfigTypesSource({\n globalTypesImportPath: computeGlobalTypesImportPath(projectDir),\n projectSkillIds: extras?.extraSkillIds ?? [],\n projectAgentNames: extras?.extraAgentNames ?? [],\n projectDomains: extras?.extraDomains ?? [],\n projectCategories: extras?.extraCategories ?? [],\n ...(selectedAgentNames?.length ? { selectedAgentNames } : {}),\n ...(projectScopedAgentNames?.length ? { projectScopedAgentNames } : {}),\n });\n verbose(\"Using project config-types.ts that imports from global\");\n } else {\n // Narrowed to the config on disk, exactly as the wizard write path narrows the\n // standalone form. The full matrix is the fallback only when there is no config\n // to narrow to — a union covering every skill the source offers would declare\n // literals the sibling config.ts never installs, and `satisfies` would stop\n // catching a config that names one of them.\n source = generateConfigTypesSource(\n data.matrix,\n data.agentNames,\n data.customAgentNames,\n extras,\n loadedConfig?.config,\n );\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?: ConfigTypesExtras,\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 // Also include config.selectedDomains (user-selected) that may not have skills in this scope\n const configDomains = deriveDomains(categories, matrix);\n domains = unique([\n ...configDomains,\n ...(config.selectedDomains ?? []),\n ...extraDomainsArr,\n ]).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 const declaredAgents = new Set<AgentName>(agentNames);\n const flaggedCustomAgents = new Set<AgentName>(customAgentNames);\n const declaredDomains = new Set<string>(extractDomains(matrix));\n\n const skillIdLine = formatMaybeSectionedUnion(skillIds, (id) => isCustomSkill(id, matrix));\n const agentNameLine = formatMaybeSectionedUnion(sortedAgents, (name) =>\n isCustomAgent(name, declaredAgents, flaggedCustomAgents),\n );\n const domainLine = formatMaybeSectionedUnion(domains, (domain) =>\n isCustomDomain(domain, declaredDomains),\n );\n const categoryLine = formatMaybeSectionedUnion(categories, (category) =>\n isUndeclaredCategory(category, matrix),\n );\n\n const selectedAgents = config?.agents ? activeAgentNames(config.agents) : [];\n const selectedAgentNameLine =\n selectedAgents.length > 0 ? formatUnion(selectedAgents) : \"AgentName\";\n\n const projectScopedAgents = config?.agents ? activeProjectAgentNames(config.agents) : [];\n const projectAgentNameLine =\n projectScopedAgents.length > 0 ? formatUnion(projectScopedAgents) : \"SelectedAgentName\";\n\n const skillsByCategory = buildSkillsByCategory(skillIds, categories, matrix);\n const stackAgentConfigType = generateStackAgentConfig(skillsByCategory, matrix);\n\n return assembleConfigTypesSource({\n skillId: skillIdLine,\n agentName: agentNameLine,\n selectedAgentName: selectedAgentNameLine,\n projectAgentName: projectAgentNameLine,\n domain: domainLine,\n category: categoryLine,\n stackAgentConfig: stackAgentConfigType,\n });\n}\n\n// Sorted deriveDomains over every category — kept separate: this is the full-matrix domain\n// union for the standalone types file, not a per-selection derivation.\nfunction extractDomains(matrix: MergedSkillsMatrix): string[] {\n return deriveDomains(typedKeys(matrix.categories), matrix).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 */\n/** Category present and not the \"local\" pseudo-category. */\nconst isNonLocalCategory = (category: CategoryPath | undefined): category is Category =>\n Boolean(category) && category !== LOCAL_PSEUDO_CATEGORY;\n\nexport function deriveCategories(skillIds: SkillId[], matrix: MergedSkillsMatrix): Category[] {\n return unique(\n skillIds\n .map((id) => matrix.skills[id]?.category)\n // Boundary cast: CategoryPath to Category for matrix key lookup\n .filter(isNonLocalCategory),\n );\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 */\nexport function deriveDomains(categories: Category[], matrix: MergedSkillsMatrix): string[] {\n return unique(\n categories\n .map((cat) => matrix.categories[cat]?.domain)\n .filter((domain): domain is Domain => domain !== undefined),\n );\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 EMPTY_UNION_TYPE;\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 EMPTY_UNION_TYPE;\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 EMPTY_UNION_TYPE;\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 /** Selected agent names from config (narrows SelectedAgentName) */\n selectedAgentNames?: string[];\n /** Project-scoped agent names (narrows ProjectAgentName for stack keys) */\n projectScopedAgentNames?: 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 projectCategories = options.projectCategories ?? [];\n const categoryUnion =\n projectCategories.length > 0\n ? formatExtendedUnion(\"GlobalCategory\", projectCategories)\n : \"GlobalCategory\";\n\n const selectedAgentNameUnion = options.selectedAgentNames?.length\n ? formatUnion(options.selectedAgentNames)\n : \"AgentName\";\n\n const projectAgentNameUnion = options.projectScopedAgentNames?.length\n ? formatUnion(options.projectScopedAgentNames)\n : \"SelectedAgentName\";\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 const importBlock = `import type {\n SkillId as GlobalSkillId,\n AgentName as GlobalAgentName,\n Domain as GlobalDomain,\n${categoryImport}} from \"${importPath}\";`;\n\n return assembleConfigTypesSource({\n importBlock,\n skillId: skillIdUnion,\n agentName: agentNameUnion,\n selectedAgentName: selectedAgentNameUnion,\n projectAgentName: projectAgentNameUnion,\n domain: domainUnion,\n category: categoryUnion,\n stackAgentConfig: STACK_AGENT_CONFIG_LOOSE_LINE,\n });\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","export function truncateText(text: string, maxLength: number): string {\n if (text.length <= maxLength) return text;\n return text.slice(0, maxLength - 1) + \"\\u2026\";\n}\n\n/** Converts a kebab-case string to a space-separated Title Case string. */\nexport function toTitleCase(kebabCase: string): string {\n return kebabCase\n .split(\"-\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n}\n\n/**\n * Locale-free string ordering for anything emitted into a file somebody commits. `localeCompare`\n * with no locale argument reads the process's default collation, which Node takes from LC_ALL /\n * LANG — so it is a colleague's desktop language, not a future ICU build, that reorders a\n * regenerated catalogue. Lithuanian and Latvian both place `y` immediately after `i`, which is\n * enough to swap the shipped `mobile-storage` and `mobile-styling`. `<` compares code units and\n * cannot.\n */\nexport function bytewise(a: string, b: string): number {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n","import path from \"path\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\n\nimport { fileExists, readFile, writeFile } from \"../../utils/fs\";\nimport { getCurrentDate } from \"../versioning\";\nimport { SCHEMA_PATHS, STANDARD_FILES, YAML_FORMATTING } from \"../../consts\";\nimport { yamlSchemaComment, stripYamlSchemaComment } from \"../../utils/yaml-schema\";\nimport type { SkillId } from \"../../types\";\nimport { formatZodIssues, 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 * The skill's own DIRECTORY inside the repository `source` names — `skills/brainstorming`,\n * never the SKILL.md.\n *\n * Recorded only where it is the whole address. A marketplace resolves every id it serves, so a\n * skill ejected from one is installed again by its id and where inside that repository it lived\n * is nobody else's business. A skill a shared configuration CARRIED answers to no catalogue at\n * all, and this pair — repository and directory — is the only address it has: without it, the\n * producer that shares this installation can name the id and not the content behind it.\n */\n path?: 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 * 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}: ${formatZodIssues(result.error.issues)}`);\n return null;\n }\n\n return result.data;\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 origin - Where the bytes came from: the repository ref, and the directory inside it for\n * a skill nothing but that directory can install again. A bag rather than two\n * positional strings, because two adjacent optional strings can be swapped\n * silently and these two mean entirely different things.\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 origin: Pick<ForkedFromMetadata, \"source\" | \"path\"> = {},\n): Promise<void> {\n const metadataPath = path.join(destPath, STANDARD_FILES.METADATA_YAML);\n const rawContent = await readFile(metadataPath);\n const { yamlContent } = stripYamlSchemaComment(rawContent);\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 = {\n ...(parseResult.success ? parseResult.data : {}),\n forkedFrom: {\n skillId,\n contentHash,\n date: getCurrentDate(),\n ...(origin.source !== undefined && { source: origin.source }),\n ...(origin.path !== undefined && { path: origin.path }),\n },\n };\n\n await writeMetadataYaml(metadataPath, metadata, `${yamlSchemaComment(SCHEMA_PATHS.metadata)}\\n`);\n}\n\n/**\n * Serializes skill metadata with the standard line-width policy and writes it,\n * optionally prefixed by a yaml-language-server schema comment.\n */\nexport async function writeMetadataYaml(\n filePath: string,\n metadata: unknown,\n schemaComment = \"\",\n): Promise<void> {\n const yamlContent = stringifyYaml(metadata, { lineWidth: YAML_FORMATTING.LINE_WIDTH_NONE });\n await writeFile(filePath, schemaComment + yamlContent);\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\nconst ISO_DATE_LENGTH = 10;\n\nexport function getCurrentDate(): string {\n return new Date().toISOString().slice(0, ISO_DATE_LENGTH);\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\nexport function parseMajorVersion(version: string): number {\n const [, major] = version.match(/^(\\d+)\\./) ?? [];\n return major === undefined ? 1 : parseInt(major, 10);\n}\n\nexport function 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 const contentHash = (await fileExists(hashFilePath))\n ? (await readFile(hashFilePath)).trim()\n : undefined;\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","/** Generates a yaml-language-server schema comment for the top of YAML files. */\nexport function yamlSchemaComment(schemaPath: string): string {\n return `# yaml-language-server: $schema=${schemaPath}`;\n}\n\n/**\n * Splits YAML file content into its leading yaml-language-server schema\n * comment (empty string when absent, trailing newline included when present)\n * and the parseable YAML body.\n */\nexport function stripYamlSchemaComment(content: string): {\n schemaComment: string;\n yamlContent: string;\n} {\n const lines = content.split(\"\\n\");\n if (lines[0]?.startsWith(\"# yaml-language-server:\")) {\n return { schemaComment: `${lines[0]}\\n`, yamlContent: lines.slice(1).join(\"\\n\") };\n }\n return { schemaComment: \"\", yamlContent: content };\n}\n","import path from \"path\";\n\nimport { copy, ensureDir, isPathWithin } from \"../../utils/fs\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { computeFileHash } from \"../versioning\";\nimport { EJECT_SOURCE, SOURCE_SRC_DIR, STANDARD_FILES } from \"../../consts\";\nimport type { 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 if (!isPathWithin(resolvedPath, expectedParent)) {\n throw new Error(\n `Invalid skill path: '${skillPath}' escapes expected directory '${path.resolve(expectedParent)}'`,\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, rootDir: string): string {\n const srcDir = path.join(rootDir, SOURCE_SRC_DIR);\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\n/** Core copy: hash the source SKILL.md, copy the directory, stamp forkedFrom provenance. */\nasync function copySkillTo(\n skill: ResolvedSkill,\n sourcePath: string,\n destPath: string,\n source?: string,\n): Promise<CopiedSkill> {\n const contentHash = await generateSkillHash(sourcePath);\n\n await ensureDir(path.dirname(destPath));\n await copy(sourcePath, destPath);\n\n // No directory: the marketplace this ref names resolves the id itself, so where inside it the\n // skill lived is not part of installing it again. Absent rather than undefined, because that is\n // the difference between \"no ref was given\" and \"the ref is the word undefined\".\n await injectForkedFromMetadata(destPath, skill.id, contentHash, {\n ...(source !== undefined && { source }),\n });\n\n return { skillId: skill.id, contentHash, sourcePath, destPath };\n}\n\nexport async function copySkill(\n skill: ResolvedSkill,\n stackDir: string,\n registryRoot: string,\n source?: string,\n): Promise<CopiedSkill> {\n return copySkillTo(\n skill,\n getSkillSourcePath(skill, registryRoot),\n getSkillDestPath(skill, stackDir),\n source,\n );\n}\n\nexport async function copySkillFromSource(\n skill: ResolvedSkill,\n stackDir: string,\n sourceResult: SourceLoadResult,\n): Promise<CopiedSkill> {\n return copySkillTo(\n skill,\n getSkillSourcePath(skill, sourceResult.sourcePath),\n getSkillDestPath(skill, stackDir),\n sourceResult.sourceConfig.source,\n );\n}\n\n/**\n * In-place CopiedSkill for a local skill left where it already lives (no copy):\n * source and destination are the skill's own local path.\n */\nasync function resolveLocalCopiedSkill(\n skill: ResolvedSkill,\n localPath: string,\n): Promise<CopiedSkill> {\n const contentHash = await generateSkillHash(localPath);\n return {\n skillId: skill.id,\n sourcePath: localPath,\n destPath: localPath,\n contentHash,\n local: true,\n };\n}\n\nexport type CopyProgressCallback = (completed: number, total: number) => void;\n\n/**\n * Copies every selected skill, and reports the ones that could not be copied BY ID.\n *\n * `Promise.all` alone rejects with whichever error arrived first and discards its siblings', and\n * that error is the filesystem's: an `ENOENT` naming a path inside the source cache. The reader is\n * told a file is missing at an address they did not choose, cannot place, and cannot act on — and\n * they learn about the second missing skill only by fixing the first and running again.\n *\n * The condition is ordinary rather than exotic: the copy walks the MATRIX and reads from the\n * FETCHED directory, so any disagreement between the two lands here. A user whose CLI predates a\n * marketplace change has no way to make them agree, which makes the id the only actionable thing\n * the failure can carry.\n *\n * It still throws. A partial copy would leave an installation missing skills its config records,\n * which is the orphan-entry state the plugin-install path already refuses.\n */\nasync function copyEachSkill(\n selectedSkillIds: SkillId[],\n copyOne: (skillId: SkillId) => Promise<CopiedSkill>,\n): Promise<CopiedSkill[]> {\n const outcomes = await Promise.all(\n selectedSkillIds.map(async (skillId) => attemptCopy(skillId, copyOne)),\n );\n const failures = outcomes.filter(isCopyFailure);\n\n if (failures.length > 0) throw new Error(copyFailureMessage(failures, selectedSkillIds.length));\n\n return outcomes.filter(isCopySuccess).map((outcome) => outcome.copied);\n}\n\ntype CopySuccess = { skillId: SkillId; copied: CopiedSkill };\ntype CopyFailure = { skillId: SkillId; problem: string };\ntype CopyOutcome = CopySuccess | CopyFailure;\n\nasync function attemptCopy(\n skillId: SkillId,\n copyOne: (skillId: SkillId) => Promise<CopiedSkill>,\n): Promise<CopyOutcome> {\n try {\n return { skillId, copied: await copyOne(skillId) };\n } catch (error) {\n return { skillId, problem: getErrorMessage(error) };\n }\n}\n\nfunction isCopyFailure(outcome: CopyOutcome): outcome is CopyFailure {\n return \"problem\" in outcome;\n}\n\nfunction isCopySuccess(outcome: CopyOutcome): outcome is CopySuccess {\n return \"copied\" in outcome;\n}\n\n/** One line per skill that failed, so both what failed and why are named for every one of them. */\nfunction copyFailureMessage(failures: CopyFailure[], attempted: number): string {\n const lines = failures.map((failure) => ` ${failure.skillId}: ${failure.problem}`);\n\n return `Could not copy ${failures.length} of ${attempted} skills:\\n${lines.join(\"\\n\")}`;\n}\n\nexport async function copySkillsToPluginFromSource(\n selectedSkillIds: SkillId[],\n pluginDir: string,\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\n return copyEachSkill(selectedSkillIds, async (skillId) => {\n const skill = getSkillById(skillId);\n\n const selectedSource = sourceSelections?.[skillId];\n const userSelectedRemote = selectedSource && selectedSource !== EJECT_SOURCE;\n\n const result =\n skill.local && skill.localPath && !userSelectedRemote\n ? await resolveLocalCopiedSkill(skill, skill.localPath)\n : await copySkillFromSource(skill, pluginDir, sourceResult);\n\n completed++;\n onProgress?.(completed, total);\n\n return result;\n });\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 return copySkillTo(\n skill,\n getSkillSourcePath(skill, sourceResult.sourcePath),\n getFlattenedSkillDestPath(skill, localSkillsDir),\n sourceResult.sourceConfig.source,\n );\n}\n\nexport async function copySkillsToLocalFlattened(\n selectedSkillIds: SkillId[],\n localSkillsDir: string,\n sourceResult: SourceLoadResult,\n sourceSelections?: Partial<Record<SkillId, string>>,\n): Promise<CopiedSkill[]> {\n return copyEachSkill(selectedSkillIds, async (skillId) => {\n const skill = getSkillById(skillId);\n\n const selectedSource = sourceSelections?.[skillId];\n const userSelectedRemote = selectedSource && selectedSource !== EJECT_SOURCE;\n if (!skill.local || !skill.localPath || userSelectedRemote) {\n return copySkillToLocalFlattened(skill, localSkillsDir, sourceResult);\n }\n\n const destPath = getFlattenedSkillDestPath(skill, localSkillsDir);\n if (path.resolve(skill.localPath) === path.resolve(destPath)) {\n return resolveLocalCopiedSkill(skill, skill.localPath);\n }\n\n const contentHash = await generateSkillHash(skill.localPath);\n await ensureDir(path.dirname(destPath));\n await copy(skill.localPath, destPath);\n\n return { skillId: skill.id, sourcePath: skill.localPath, destPath, contentHash };\n });\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 { formatZodIssues, skillMetadataLoaderSchema } from \"../schemas\";\nimport type { z } from \"zod\";\n\ntype SkillMetadata = z.infer<typeof skillMetadataLoaderSchema>;\nimport { DEFAULT_BRANDING, STANDARD_FILES } from \"../../consts\";\nimport { stripYamlSchemaComment } from \"../../utils/yaml-schema\";\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\nexport type SkillCompilationRun = {\n compiled: CompiledSkillPlugin[];\n /** Directory basenames of skills that failed to compile this run. */\n failed: 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 { yamlContent } = stripYamlSchemaComment(content);\n\n const result = skillMetadataLoaderSchema.safeParse(parseYaml(yamlContent));\n if (!result.success) {\n warn(`Invalid metadata.yaml at '${skillPath}': ${formatZodIssues(result.error.issues)}`);\n return null;\n }\n return result.data;\n } catch (error) {\n warn(`Failed to read metadata.yaml at '${skillPath}': ${getErrorMessage(error)}`);\n return null;\n }\n}\n\nfunction generateReadme(skillName: string, frontmatter: SkillFrontmatter): string {\n return `# ${skillName}\n\n${frontmatter.description}\n\n## Installation\n\nAdd this plugin to your Claude Code configuration:\n\n\\`\\`\\`json\n{\n \"plugins\": [\"${skillName}\"]\n}\n\\`\\`\\`\n\n## Usage\n\nThis skill is automatically available when installed.\n\n---\n\n*Generated by ${DEFAULT_BRANDING.NAME} skill-plugin-compiler*\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 ...(metadata?.author !== undefined && { author: metadata.author }),\n ...(metadata?.category !== undefined && { category: metadata.category }),\n version,\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);\n await writeFile(path.join(pluginDir, STANDARD_FILES.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<SkillCompilationRun> {\n const compiled: CompiledSkillPlugin[] = [];\n const failed: string[] = [];\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 compiled.push(result);\n log(` [OK] ${result.skillName}`);\n } catch (error) {\n const errorMessage = getErrorMessage(error);\n const dirBasename = path.basename(skillPath);\n failed.push(dirBasename);\n warn(`Failed to compile skill from '${dirBasename}': ${errorMessage}`);\n }\n }\n\n return { compiled, failed };\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 { 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 AGENT_PLUGIN_PREFIX = \"agent-\";\n\nexport type SkillManifestOptions = {\n skillName: string;\n description?: string;\n author?: string;\n authorEmail?: string;\n category?: string;\n version?: string;\n keywords?: string[];\n};\n\nexport type AgentManifestOptions = {\n agentName: string;\n description?: string;\n version?: string;\n};\n\nfunction buildAuthor(name?: string, email?: string): PluginAuthor | undefined {\n if (!name) {\n return undefined;\n }\n return { name, ...(email ? { email } : {}) };\n}\n\nexport function generateSkillPluginManifest(options: SkillManifestOptions): PluginManifest {\n const author = buildAuthor(options.author, options.authorEmail);\n return {\n name: options.skillName,\n version: options.version ?? DEFAULT_VERSION,\n skills: \"./skills/\",\n ...(options.description ? { description: options.description } : {}),\n ...(author ? { author } : {}),\n ...(options.category ? { category: options.category } : {}),\n ...(options.keywords?.length ? { keywords: options.keywords } : {}),\n };\n}\n\nexport function generateAgentPluginManifest(options: AgentManifestOptions): PluginManifest {\n return {\n name: `${AGENT_PLUGIN_PREFIX}${options.agentName}`,\n version: options.version ?? DEFAULT_VERSION,\n agents: \"./agents/\",\n ...(options.description ? { description: options.description } : {}),\n };\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","import os from \"os\";\nimport path from \"path\";\n\nimport { zip } from \"remeda\";\n\nimport { getErrorMessage } from \"../../utils/errors\";\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 STANDARD_FILES,\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}: ${getErrorMessage(error)}`);\n return null;\n }\n}\n\nexport async function getPluginSkillIds(pluginSkillsDir: string): Promise<SkillId[]> {\n const skillFiles = await glob(`**/${STANDARD_FILES.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 type { ClaudePluginScope, SkillScope } from \"../../types/config.js\";\n\n/**\n * Marketplace-qualified plugin reference (`{id}@{marketplace}`) — the form the\n * Claude CLI plugin registry expects. Bare ids do not match registry entries.\n */\nexport function buildMarketplacePluginRef(id: string, marketplace: string): string {\n return `${id}@${marketplace}`;\n}\n\n/**\n * Inverse of buildMarketplacePluginRef: extracts the skill id from a\n * `{id}@{marketplace}` reference. Returns the whole string when no `@` is present.\n */\nexport function parseMarketplacePluginRef(ref: string): string {\n const separator = ref.indexOf(\"@\");\n return separator === -1 ? ref : ref.slice(0, separator);\n}\n\n/**\n * Maps a cc scope to the Claude CLI plugin scope: `\"global\"` installs are\n * user-scoped in Claude (registered in `~/.claude/settings.json`); anything\n * else — including an absent scope — is project-scoped.\n */\nexport function toClaudePluginScope(scope: SkillScope | undefined): ClaudePluginScope {\n return scope === \"global\" ? \"user\" : \"project\";\n}\n","import { readdir } from \"fs/promises\";\nimport type { Dirent } from \"fs\";\n\nimport { DEFAULT_DISPLAY_VERSION, DEFAULT_PLUGIN_NAME } from \"../../consts\";\nimport { verbose } from \"../../utils/logger\";\nimport { typedKeys } from \"../../utils/typed-object\";\nimport { loadProjectConfig } from \"../configuration\";\nimport {\n detectInstallation,\n installBaseDir,\n isHomeDirectory,\n resolveInstallPaths,\n INSTALL_MODE_LABELS,\n type Installation,\n type InstallMode,\n} from \"../installation\";\nimport type { SkillDefinitionMap } from \"../../types\";\nimport type { SkillScope } from \"../../types/config\";\nimport { getProjectPluginsDir } from \"./plugin-finder\";\nimport { discoverAllPluginSkills, listPluginNames } from \"./plugin-discovery\";\n\nconst AGENT_FILE_EXTENSION = \".md\";\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 skillCount: number;\n agentCount: number;\n configPath: string;\n /** Every directory that actually holds compiled agents; empty when no scope has any. */\n agentDirs: 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 if (!installation) return null;\n\n const scopes = installedScopes(installation);\n const skillCount = await countInstalledSkills(installation, scopes);\n const agentDirCounts = await countCompiledAgentsPerScope(installation, scopes);\n\n const loaded = await loadProjectConfig(installation.projectDir);\n const name = loaded?.config.name || DEFAULT_PLUGIN_NAME;\n\n return {\n mode: installation.mode,\n name,\n skillCount,\n agentCount: sumCounts(agentDirCounts),\n configPath: installation.configPath,\n agentDirs: agentDirCounts.filter(hasEntries).map((scopeCount) => scopeCount.dir),\n };\n}\n\n/**\n * Scopes whose artifacts belong to this installation, in report order (global\n * first, mirroring the init success report). A project context also owns\n * everything installed globally under HOME, so both roots are counted; at the\n * home root the two resolve to the same directory and only one pass runs so\n * nothing is counted twice.\n */\nfunction installedScopes(installation: Installation): SkillScope[] {\n return isHomeDirectory(installation.projectDir) ? [\"project\"] : [\"global\", \"project\"];\n}\n\ntype ScopeCount = {\n dir: string;\n count: number;\n};\n\nfunction hasEntries(scopeCount: ScopeCount): boolean {\n return scopeCount.count > 0;\n}\n\nfunction sumCounts(scopeCounts: ScopeCount[]): number {\n return scopeCounts.reduce((total, scopeCount) => total + scopeCount.count, 0);\n}\n\nasync function sumOverScopes(\n scopes: SkillScope[],\n count: (scope: SkillScope) => Promise<number>,\n): Promise<number> {\n const counts = await Promise.all(scopes.map(count));\n return counts.reduce((total, current) => total + current, 0);\n}\n\n/** Plugin-mode skills live in the plugin registry, not under a scope's skills dir. */\nasync function countInstalledSkills(\n installation: Installation,\n scopes: SkillScope[],\n): Promise<number> {\n if (installation.mode === \"plugin\") return countPluginSkills(installation.projectDir, scopes);\n\n return sumOverScopes(scopes, (scope) =>\n countDirEntries(resolveInstallPaths(installation.projectDir, scope).skillsDir, (entry) =>\n entry.isDirectory(),\n ),\n );\n}\n\n/**\n * Compiled-agent count per scope, keyed by the directory it was read from, so\n * callers can both total the counts and name the directories the agents are\n * actually in — a default install driven from a project directory compiles\n * every agent under HOME, and naming the project directory there names a\n * directory that was never written.\n */\nasync function countCompiledAgentsPerScope(\n installation: Installation,\n scopes: SkillScope[],\n): Promise<ScopeCount[]> {\n return Promise.all(\n scopes.map(async (scope) => {\n const dir = resolveInstallPaths(installation.projectDir, scope).agentsDir;\n return { dir, count: await countDirEntries(dir, isCompiledAgentFile) };\n }),\n );\n}\n\nfunction isCompiledAgentFile(entry: Dirent): boolean {\n return entry.isFile() && entry.name.endsWith(AGENT_FILE_EXTENSION);\n}\n\n/** Counts entries in `dir` matching `pred`; 0 when the directory is missing or unreadable. */\nasync function countDirEntries(dir: string, pred: (entry: Dirent) => boolean): Promise<number> {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n return entries.filter(pred).length;\n } catch {\n return 0;\n }\n}\n\n/**\n * Counts the skills each scope's `settings.json` enables, resolved through the\n * global plugin cache; 0 on failure.\n */\nasync function countPluginSkills(projectDir: string, scopes: SkillScope[]): Promise<number> {\n try {\n const skillsPerScope = await Promise.all(\n scopes.map((scope) => discoverAllPluginSkills(installBaseDir(projectDir, scope))),\n );\n return countDistinctSkillIds(skillsPerScope);\n } catch {\n return 0;\n }\n}\n\n/**\n * A skill enabled under both roots is one skill, so plugin scopes merge by id\n * where eject scopes — whose skills dirs are disjoint — sum (`sumOverScopes`).\n */\nfunction countDistinctSkillIds(skillsPerScope: SkillDefinitionMap[]): number {\n return new Set(skillsPerScope.flatMap(typedKeys)).size;\n}\n\nexport function formatInstallationDisplay(info: InstallationInfo): string {\n const agentDirLines = info.agentDirs.map((dir) => `\\n Agents: ${dir}`).join(\"\");\n\n return `Installation: ${info.name}\n Mode: ${INSTALL_MODE_LABELS[info.mode]}\n Skills: ${info.skillCount}\n Agents: ${info.agentCount}\n Config: ${info.configPath}${agentDirLines}`;\n}\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 CLI_INVOKE_COMMAND,\n DEFAULT_BRANDING,\n PLUGINS_SUBDIR,\n STANDARD_DIRS,\n EJECT_SOURCE,\n} from \"../../consts\";\nimport { getProjectConfigPath } from \"./install-base-dir\";\nimport type { ProjectConfig, SkillConfig } from \"../../types/config\";\nimport type { InstallMode } from \"../../types/matrix\";\n\n// Re-exported from types/matrix.ts for existing importers of the installation barrel\nexport type { InstallMode };\n\nexport const INSTALL_MODE_LABELS = {\n plugin: \"Plugin\",\n mixed: \"Mixed\",\n eject: \"Eject\",\n} as const satisfies Record<InstallMode, string>;\n\n/**\n * How a mode is described wherever a command tells the user what KIND of install is\n * about to happen — `init`'s install-plan line, and `edit`'s line for the skills it\n * is switching. One definition because it is one statement about one operation:\n * switching a skill to plugin mode installs it natively exactly as a fresh plugin\n * install does, and used to be announced in words `init` never printed.\n *\n * `mixed` is absent by construction. Nothing is switched TO mixed — it is a shape a\n * whole selection can have, described with per-mode counts only the install plan\n * holds, so `init` composes that one line itself.\n */\nexport const INSTALL_MODE_DESCRIPTIONS = {\n plugin: `${INSTALL_MODE_LABELS.plugin} (native install)`,\n eject: `${INSTALL_MODE_LABELS.eject} (copy to .claude/skills/)`,\n} as const satisfies Record<Exclude<InstallMode, \"mixed\">, string>;\n\nexport type Installation = {\n mode: InstallMode;\n configPath: string;\n agentsDir: string;\n skillsDir: string;\n projectDir: string;\n};\n\n/**\n * Whether a successfully-loaded config declares nothing to install — no skills and no agents.\n *\n * Exported rather than kept private to its one caller below because two surfaces have to agree on\n * exactly which configs are content-less: this detection, which maps them to `null` so `init`\n * routes to the wizard instead of the dashboard, and `doctor`, which has to name that state rather\n * than repeat the `null` as `not found`. Two answers to that question is how one screen ended up\n * validating a file and calling it missing four lines apart.\n */\nexport function declaresNoContent(config: ProjectConfig): boolean {\n return config.skills.length === 0 && config.agents.length === 0;\n}\n\n/** Derive install mode from skills array at runtime */\nexport function deriveInstallMode(skills: SkillConfig[]): InstallMode {\n if (skills.length === 0) return \"eject\";\n const hasEject = skills.some((s) => s.origin === EJECT_SOURCE);\n const hasPlugin = skills.some((s) => s.origin !== EJECT_SOURCE);\n if (hasEject && hasPlugin) return \"mixed\";\n return hasEject ? \"eject\" : \"plugin\";\n}\n\n// Use loadProjectConfigFromDir directly (not detectInstallation) to avoid the\n// project→global fallback recursing back into this detection.\nasync function detectInstallationInDir(dir: string): Promise<Installation | null> {\n const configPath = getProjectConfigPath(dir);\n\n if (!(await fileExists(configPath))) {\n return null;\n }\n\n // The config file exists. loadProjectConfigFromDir throws ConfigLoadError for a\n // corrupt config, so a returned value is always a usable config — a corrupt\n // config surfaces to the caller (compile reports it) instead of silently\n // becoming a phantom eject installation that resurrects every built-in agent.\n const loaded = await loadProjectConfigFromDir(dir);\n if (!loaded) {\n // The file vanished between the fileExists check and the load.\n return null;\n }\n\n // A successfully-loaded config that declares neither skills nor agents is\n // content-less and does not count as an installation — init must route to the\n // setup wizard, not the dashboard. This is the shared detection function, so\n // returning null here covers both the project-config and global-config\n // manifestations. A reporting surface must not read this `null` as \"no config\n // here\": see declaresNoContent, which doctor asks the same question of.\n if (declaresNoContent(loaded.config)) {\n return null;\n }\n\n const mode: InstallMode = deriveInstallMode(loaded.config.skills);\n\n return {\n mode,\n configPath,\n agentsDir: path.join(dir, CLAUDE_DIR, STANDARD_DIRS.AGENTS),\n // Mixed mode has local skills in .claude/skills/ and plugins in cache;\n // use .claude/skills/ as the primary skillsDir (same as eject mode)\n skillsDir: path.join(dir, CLAUDE_DIR, mode === \"plugin\" ? PLUGINS_SUBDIR : \"skills\"),\n projectDir: dir,\n };\n}\n\n/** Detect installation in a specific directory only (no global fallback). */\nexport async function detectProjectInstallation(projectDir: string): Promise<Installation | null> {\n return detectInstallationInDir(projectDir);\n}\n\n/** Detect installation in the home directory (global scope). */\nexport async function detectGlobalInstallation(): Promise<Installation | null> {\n return detectInstallationInDir(os.homedir());\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_INVOKE_COMMAND} init' to create one.`,\n );\n }\n\n return installation;\n}\n","import os from \"os\";\nimport path from \"path\";\nimport { unique } from \"remeda\";\nimport type {\n AgentDefinition,\n AgentName,\n CompileAgentConfig,\n CompileConfig,\n ProjectConfig,\n SkillDefinition,\n SkillId,\n Stack,\n StackAgentConfig,\n} from \"../../types\";\nimport { isHomeDirectory } from \"./is-home-directory\";\nimport { resolveInstallPaths, type InstallPaths } from \"./install-base-dir\";\nimport { matrix } from \"../matrix/matrix-provider\";\nimport type { AgentScopeConfig, SkillConfig, SkillScope } from \"../../types/config\";\nimport type { WizardResultV2 } from \"../../components/wizard/wizard\";\nimport { type CopiedSkill } from \"../skills\";\nimport {\n type MergeResult,\n type AuthoritativeScope,\n mergeWithExistingConfig,\n loadProjectConfig,\n loadProjectConfigFromDir,\n} from \"../configuration\";\nimport { loadMergedAgents, loadSkillsByIds, type SourceLoadResult } from \"../loading\";\nimport { loadStackById, getStackSkillIds, stackNotOfferedMessage } from \"../stacks\";\nimport { resolveAgents, buildSkillRefsFromConfig } from \"../resolver\";\nimport { createLiquidEngine } from \"../compiler\";\nimport { writeCompiledAgentsByScope } from \"../agents/write-compiled-agents\";\nimport { generateProjectConfigFromSkills, buildStackProperty } from \"../configuration\";\nimport { scopeEligibilityKey, isScopePairCompatible } from \"../configuration/config-generator\";\nimport {\n isActiveAt,\n activeSkillScopeMap,\n activeAgentScopeMap,\n effectivelyExcludedSkillIds,\n} from \"../configuration/scope-predicates\";\nimport { writeScopedFromWizard } from \"../config-gate/index.js\";\nimport { ensureDir } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport { typedFromEntries } from \"../../utils/typed-object\";\nimport { DEFAULT_PLUGIN_NAME } from \"../../consts\";\n\ntype LocalResolvedSkill = SkillDefinition & {\n content: string;\n};\n\n/**\n * Options for the eject skill installation pipeline.\n *\n * Passed to {@link installEject} to drive the full installation flow:\n * skill copying, config generation, agent compilation, and file writing.\n */\nexport type EjectInstallOptions = {\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 `--marketplace` flag override (e.g., \"github:org/repo\"). Takes precedence over\n * the marketplace from config when writing the `marketplace` field in config.ts */\n sourceFlag?: string;\n};\n\n/**\n * Result of a completed eject skill installation.\n *\n * Returned by {@link installEject} with details about what was written to disk,\n * enabling the caller to display a summary to the user.\n */\nexport type EjectInstallResult = {\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\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\nexport function buildEjectSkillsMap(\n copiedSkills: CopiedSkill[],\n): Partial<Record<SkillId, LocalResolvedSkill>> {\n return typedFromEntries(\n copiedSkills.flatMap((cs) => {\n const skill = matrix.skills[cs.skillId];\n if (!skill) return [];\n return [\n [\n cs.skillId,\n {\n id: cs.skillId,\n description: skill.description,\n path: cs.destPath,\n content: \"\", // Content not needed for skill references\n },\n ],\n ];\n }),\n );\n}\n\n/**\n * Returns the ids of skills active in the CURRENT wizard selection that were\n * NOT active in the persisted PRIOR config. Filters `excluded: true` on both\n * sides — excluded entries don't participate in stack membership, so flipping\n * a skill from excluded back to active counts as \"newly added\".\n *\n * `priorSkills === undefined` (first init) collapses the prior active set to\n * empty — every current skill is new this session. The generator's seeding\n * branch is what actually produces useful output in that case, so treating\n * every skill as \"new\" is safe.\n */\nfunction computeNewlyAddedSkillIds(\n currentSkills: readonly SkillConfig[],\n priorSkills: readonly SkillConfig[] | undefined,\n): readonly SkillId[] {\n const priorActiveIds = new Set((priorSkills ?? []).filter((s) => !s.excluded).map((s) => s.id));\n const currentActiveIds = currentSkills.filter((s) => !s.excluded).map((s) => s.id);\n return unique(currentActiveIds.filter((id) => !priorActiveIds.has(id)));\n}\n\n/**\n * Returns `(agent, skillId)` keys whose scope-compatibility was GAINED this\n * session — the pair is scope-compatible now but was NOT scope-compatible (or\n * was absent entirely) in the persisted config. Admits pure scope-flip cases\n * that `computeNewlyAddedSkillIds` (keyed by id only) cannot express.\n *\n * Scope rule: `isScopePairCompatible` from config-generator — the single\n * definition shared with the generator's own compatibility filter.\n *\n * Keys are produced by `scopeEligibilityKey` so lookup membership matches the\n * generator's internal set-membership check.\n */\nfunction computeScopeEligibilityGained(\n currentSkills: readonly SkillConfig[],\n currentAgents: readonly AgentScopeConfig[],\n priorSkills: readonly SkillConfig[] | undefined,\n priorAgents: readonly AgentScopeConfig[] | undefined,\n): ReadonlySet<string> {\n const priorSkillScope = activeSkillScopeMap(priorSkills);\n const priorAgentScope = activeAgentScopeMap(priorAgents);\n\n const gained = new Set<string>();\n const activeCurrentSkills = currentSkills.filter((s) => !s.excluded);\n const activeCurrentAgents = currentAgents.filter((a) => !a.excluded);\n\n for (const agent of activeCurrentAgents) {\n for (const skill of activeCurrentSkills) {\n if (!isScopePairCompatible(skill.scope, agent.scope)) continue;\n\n const priorSkillScopeValue = priorSkillScope.get(skill.id);\n const priorAgentScopeValue = priorAgentScope.get(agent.name);\n const wasCompatiblePreviously =\n priorSkillScopeValue !== undefined &&\n priorAgentScopeValue !== undefined &&\n isScopePairCompatible(priorSkillScopeValue, priorAgentScopeValue);\n\n if (!wasCompatiblePreviously) {\n gained.add(scopeEligibilityKey(agent.name, skill.id));\n }\n }\n }\n return gained;\n}\n\n/**\n * The stack the written config carries.\n *\n * A producer that knows per-`(skill, agent)` assignments has already decided what every sub-agent\n * holds and what preloads, so its stack REPLACES the ownership-derived one rather than merging\n * with it. Ownership rules hand every scope-compatible skill to every selected agent — exactly the\n * curation a shared configuration exists to carry — and inherit `preloaded` from a prior or\n * stack-YAML entry, which is silent about what the sharer chose. A stack id in such a payload\n * still names the config's description, but its own expansion is not overlaid for the same reason:\n * it would add back the skills and agents the assignments left out.\n *\n * Only a stack the generator itself built is replaced. With no agents selected there is nothing to\n * own, and the absent key is what tells the merger to leave the stack already on disk alone.\n */\nfunction resolveStackProperty(\n generated: ProjectConfig[\"stack\"],\n assigned: WizardResultV2[\"assignedStack\"],\n): ProjectConfig[\"stack\"] {\n return generated && assigned ? assigned : generated;\n}\n\n/**\n * The identity a freshly-written config carries.\n *\n * A project config is named for the directory it configures — the same identity\n * `eject` passes as its `fallbackName` and the loader repairs a missing `name`\n * to. At `$HOME` there is no project to name: `path.basename(os.homedir())` is\n * the OS account name, which identifies the USER rather than the installation\n * and differs per machine for one logical global install, so the global config\n * keeps the product constant instead.\n *\n * A config already on disk keeps the name it saved either way — `mergeConfigs`\n * carries identity fields over from the existing config, so this seed only ever\n * names a config being created.\n */\nfunction configNameFor(projectDir: string): string {\n return isHomeDirectory(projectDir) ? DEFAULT_PLUGIN_NAME : path.basename(projectDir);\n}\n\n/**\n * The per-agent curation this save must preserve, from every config that carries\n * any.\n *\n * A GLOBAL sub-agent's curation lives in the global config ALONE — a project\n * config's stack is filtered down to project-scoped agents on the way out, so a\n * global agent has no row of its own there. Reading the project config by itself\n * therefore makes a `s` toggle (G→P) look like an agent nobody has ever curated,\n * and the generator's seed branch rebuilds its catalogue from relevance defaults,\n * silently dropping every assignment the shared resolver would not re-derive.\n *\n * Both configs are carriers and both are merged; the project's word wins per\n * agent, since a project-scoped agent's row is the one the project owns. The\n * global config is READ here and never written — a project-context edit moves an\n * agent INTO this project, it never migrates global state out.\n */\nasync function loadCuratedStack(\n projectDir: string,\n projectStack: ProjectConfig[\"stack\"],\n): Promise<Partial<Record<AgentName, StackAgentConfig>>> {\n // At `$HOME` the config already loaded IS the global one — re-reading it would\n // merge it with itself.\n const globalStack = isHomeDirectory(projectDir) ? undefined : await loadGlobalStack();\n\n // ProjectConfig.stack types its agents as Record<string, StackAgentConfig> (it\n // comes from parsed TS/JSON); the declared return type is where those keys are\n // narrowed to AgentName, so this load boundary needs no cast of its own.\n return { ...globalStack, ...projectStack };\n}\n\n/** The global install's per-agent stack, absent until a global config exists. */\nasync function loadGlobalStack(): Promise<ProjectConfig[\"stack\"]> {\n return (await loadProjectConfigFromDir(os.homedir()))?.config.stack;\n}\n\nasync function buildEjectConfig(\n wizardResult: WizardResultV2,\n sourceResult: SourceLoadResult,\n projectDir: string,\n): Promise<{ config: ProjectConfig; loadedStack: Stack | null }> {\n const skillIds = unique(wizardResult.skills.map((s) => s.id));\n verbose(\n `buildEjectConfig: selectedStackId='${wizardResult.selectedStackId}', ` +\n `skills=[${skillIds.join(\", \")}], ` +\n `selectedAgents=[${wizardResult.selectedAgents.join(\", \")}]`,\n );\n\n const { source } = sourceResult.sourceConfig;\n const loadedStack = wizardResult.selectedStackId\n ? await loadStackById(wizardResult.selectedStackId, sourceResult.sourcePath, source)\n : null;\n if (wizardResult.selectedStackId) {\n verbose(\n `buildEjectConfig: loadedStack=${loadedStack ? `found (id='${loadedStack.id}')` : \"NOT FOUND\"}`,\n );\n if (!loadedStack) {\n throw new Error(stackNotOfferedMessage(wizardResult.selectedStackId, source));\n }\n }\n\n const existing = await loadProjectConfig(projectDir);\n const existingStack = await loadCuratedStack(projectDir, existing?.config.stack);\n\n // D-220 delta: skills that are new to this session's top-level selection\n // relative to the persisted config. The diff is filtered to active (non-excluded)\n // skills on BOTH sides — excluded entries are not \"present\" from the perspective\n // of stack membership, so flipping an exclusion back to active should register\n // as a newly-added skill. `existing === null` (first init) collapses to \"every\n // skill is new this session\", which the generator's seeding branch tolerates.\n const newlyAddedSkillIds = computeNewlyAddedSkillIds(\n wizardResult.skills,\n existing?.config.skills,\n );\n\n // D-220 scope-eligibility delta: `(agent, skillId)` pairs that are scope-compatible\n // NOW but were not scope-compatible in the persisted config (either the skill's\n // scope was flipped, the agent's scope was flipped, or one of them was absent\n // before). Admits the scope-flip case that a skill-id-only diff would miss.\n const scopeEligibilityGained = computeScopeEligibilityGained(\n wizardResult.skills,\n wizardResult.agentConfigs,\n existing?.config.skills,\n existing?.config.agents,\n );\n\n // Pass user's agent selection and skill configs to config generator.\n // Both skillConfigs and agentConfigs are always passed when selectedAgents is\n // set — the config generator enforces that invariant to prevent silent\n // \"project\" scope defaults on missing lookups.\n const agentOptions: {\n selectedAgents?: AgentName[];\n skillConfigs: SkillConfig[];\n agentConfigs: AgentScopeConfig[];\n existingStack: Partial<Record<AgentName, StackAgentConfig>>;\n newlyAddedSkillIds: readonly SkillId[];\n scopeEligibilityGained: ReadonlySet<string>;\n } = {\n skillConfigs: wizardResult.skills,\n agentConfigs: wizardResult.agentConfigs,\n existingStack,\n newlyAddedSkillIds,\n scopeEligibilityGained,\n ...(wizardResult.selectedAgents.length > 0 && {\n selectedAgents: wizardResult.selectedAgents,\n }),\n };\n\n // With a stack: overlay the stack as `existingStack` so its (agent, category, skill)\n // triples reach the ownership-based builder with a load already decided — the\n // author's flag where a third-party stacks file wrote one, and the shared mapping's\n // verdict where none was written, which is every entry of a built-in stack.\n // `buildStackProperty` is where that decision is made, so applying a stack is a NEW\n // selection: it never arrives flagless and is never read as a curated lazy.\n // The on-disk stack spreads LAST and wins per agent, so re-running over an installed\n // config preserves what the user saved. Ownership rules still govern which agents and\n // categories land in the final stack, so Phase A (init) and Phase B (edit) produce\n // equivalent stacks for the same selection.\n const effectiveOptions = loadedStack\n ? { ...agentOptions, existingStack: { ...buildStackProperty(loadedStack), ...existingStack } }\n : agentOptions;\n const generated = generateProjectConfigFromSkills(\n configNameFor(projectDir),\n skillIds,\n effectiveOptions,\n );\n const stack = resolveStackProperty(generated.stack, wizardResult.assignedStack);\n const localConfig: ProjectConfig = {\n ...generated,\n ...(stack && { stack }),\n ...(loadedStack ? { description: loadedStack.description } : {}),\n };\n\n verbose(\n `buildEjectConfig 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): ProjectConfig {\n const result = { ...config };\n\n // Only persist selected domains when non-empty (sparse output)\n if (wizardResult.selectedDomains.length > 0) {\n result.selectedDomains = wizardResult.selectedDomains;\n }\n\n if (sourceFlag) {\n result.marketplace = sourceFlag;\n } else if (sourceResult.sourceConfig.source) {\n result.marketplace = sourceResult.sourceConfig.source;\n }\n\n if (sourceResult.marketplace) {\n result.marketplaceName = sourceResult.marketplace;\n }\n\n return result;\n}\n\nexport async function buildAndMergeConfig(\n wizardResult: WizardResultV2,\n sourceResult: SourceLoadResult,\n projectDir: string,\n sourceFlag?: string,\n authoritativeScope?: AuthoritativeScope,\n): Promise<MergeResult> {\n const { config } = await buildEjectConfig(wizardResult, sourceResult, projectDir);\n verbose(\n `buildAndMergeConfig: before merge — stack=${config.stack ? Object.keys(config.stack).length + \" agents\" : \"UNDEFINED\"}`,\n );\n const configWithMetadata = setConfigMetadata(config, wizardResult, sourceResult, sourceFlag);\n const result = await mergeWithExistingConfig(configWithMetadata, {\n projectDir,\n ...(authoritativeScope !== undefined && { authoritativeScope }),\n });\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 function buildCompileAgents(\n config: ProjectConfig,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n): Partial<Record<AgentName, CompileAgentConfig>> {\n const activeAgents = config.agents.filter((a) => !a.excluded);\n const excludedSkillIds = effectivelyExcludedSkillIds(config.skills);\n\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) => isActiveAt(s, \"global\")).map((s) => s.id),\n );\n\n // D-217: attach each skill's `origin` to its SkillReference so the compiler can\n // decide between `${id}:${id}` (plugin) and bare id (eject) on a per-skill\n // basis. Missing entries are intentional — user-authored local skills have no\n // SkillConfig and legitimately carry no origin.\n const sourceById = new Map<SkillId, string>(config.skills.map((s) => [s.id, s.origin]));\n\n const buildAgentCompileEntry = (agentConfig: AgentScopeConfig): CompileAgentConfig => {\n // Model/effort are the agent's own settings, not its skills' — a bare agent with no stack\n // entry still carries them, so they are resolved before the skill-less early-out.\n const tuning: CompileAgentConfig = {\n ...(agentConfig.model !== undefined && { model: agentConfig.model }),\n ...(agentConfig.effort !== undefined && { effort: agentConfig.effort }),\n };\n\n const agentStack = config.stack?.[agentConfig.name];\n if (!agentStack) return tuning;\n // Filter out excluded skills; global agents only see global skills (cross-scope safety net)\n const filteredRefs = buildSkillRefsFromConfig(agentStack)\n .filter(\n (ref) =>\n !excludedSkillIds.has(ref.id) &&\n (agentConfig.scope !== \"global\" || globalSkillIds.has(ref.id)),\n )\n .map((ref) => {\n const source = sourceById.get(ref.id);\n return { ...ref, ...(source !== undefined && { source }) };\n });\n return { ...tuning, skills: filteredRefs };\n };\n\n return typedFromEntries<AgentName, CompileAgentConfig>(\n activeAgents\n .filter((agentConfig) => agents[agentConfig.name])\n .map((agentConfig) => [agentConfig.name, buildAgentCompileEntry(agentConfig)]),\n );\n}\n\nexport function buildAgentScopeMap(config: ProjectConfig): Map<AgentName, SkillScope> {\n return activeAgentScopeMap(config.agents);\n}\n\n/**\n * Shared install tail: writes scoped configs, then compiles and writes agents.\n * Both install modes call this after building their merged config — only the\n * skills used for compilation and the plugin description differ.\n */\nasync function writeConfigAndCompileAgents(params: {\n finalConfig: ProjectConfig;\n agents: Partial<Record<AgentName, AgentDefinition>>;\n localSkills: Partial<Record<SkillId, LocalResolvedSkill>>;\n sourceResult: SourceLoadResult;\n projectDir: string;\n paths: InstallPaths;\n isProjectInstall: boolean;\n description: string;\n}): Promise<AgentName[]> {\n const { finalConfig, agents, localSkills, sourceResult, projectDir, paths } = params;\n\n await writeScopedFromWizard({\n finalConfig,\n matrix: sourceResult.matrix,\n agents,\n projectDir,\n projectConfigPath: paths.configPath,\n // During init, the project installation is being created — it exists if we're in a project context\n projectInstallationExists: params.isProjectInstall,\n });\n\n const compileConfig: CompileConfig = {\n name: DEFAULT_PLUGIN_NAME,\n description: params.description,\n agents: buildCompileAgents(finalConfig, agents),\n };\n return compileAndWriteAgents(\n compileConfig,\n agents,\n localSkills,\n sourceResult,\n projectDir,\n paths.agentsDir,\n buildAgentScopeMap(finalConfig),\n );\n}\n\nasync function compileAndWriteAgents(\n compileConfig: CompileConfig,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n localSkills: Partial<Record<SkillId, LocalResolvedSkill>>,\n sourceResult: SourceLoadResult,\n projectDir: string,\n agentsDir: string,\n agentScopeMap?: Map<AgentName, SkillScope>,\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 outcomes = await writeCompiledAgentsByScope({\n resolvedAgents,\n sourcePath: sourceResult.sourcePath,\n engine,\n projectAgentsDir: agentsDir,\n ...(agentScopeMap !== undefined && { agentScopeMap }),\n });\n\n // Install treats any compile failure as fatal — surface the first one.\n const failure = outcomes.find((outcome) => !outcome.ok);\n if (failure) throw failure.error;\n\n return outcomes.map((outcome) => outcome.name);\n}\n\n/** Result of plugin-mode config installation — same as EjectInstallResult without copied skills or skillsDir */\nexport type PluginConfigResult = Omit<EjectInstallResult, \"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 one the loaded source offers\n */\nexport async function installPluginConfig(\n options: EjectInstallOptions,\n): Promise<PluginConfigResult> {\n const { wizardResult, sourceResult, projectDir, sourceFlag } = options;\n\n const projectPaths = resolveInstallPaths(projectDir, \"project\");\n\n // Create directories based on installation context, not data content.\n // ensureDir is idempotent (mkdir -p), so calling it when dirs already exist is safe.\n const isProjectInstall = !isHomeDirectory(projectDir);\n if (isProjectInstall) {\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 // 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 writeConfigAndCompileAgents({\n finalConfig,\n agents,\n localSkills: skillsForCompilation,\n sourceResult,\n projectDir,\n paths: projectPaths,\n isProjectInstall,\n description:\n finalConfig.description || `Plugin setup with ${wizardResult.skills.length} skills`,\n });\n\n return {\n config: finalConfig,\n configPath: projectPaths.configPath,\n compiledAgents: compiledAgentNames,\n wasMerged: mergeResult.merged,\n ...(mergeResult.existingConfigPath !== undefined && {\n mergedConfigPath: mergeResult.existingConfigPath,\n }),\n agentsDir: projectPaths.agentsDir,\n };\n}\n\n/**\n * Executes the full eject skill installation pipeline.\n *\n * This is the main entry point for the \"eject\" 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 one the loaded source offers\n *\n * @remarks\n * **Side effects:** Creates directories and writes files under `{projectDir}/.claude/`.\n */\nexport async function installEject(options: EjectInstallOptions): Promise<EjectInstallResult> {\n const { wizardResult, sourceResult, projectDir, sourceFlag } = options;\n\n const projectPaths = resolveInstallPaths(projectDir, \"project\");\n const globalPaths = resolveInstallPaths(projectDir, \"global\");\n\n // Create directories based on installation context, not data content.\n // ensureDir is idempotent (mkdir -p), so calling it when dirs already exist is safe.\n const isProjectInstall = !isHomeDirectory(projectDir);\n if (isProjectInstall) {\n await prepareDirectories(projectPaths);\n } else {\n // Always ensure .claude-src/ exists for config (even when installing from ~/)\n await ensureDir(path.dirname(projectPaths.configPath));\n }\n // Always ensure global skills directory exists when there is a global installation context\n await ensureDir(globalPaths.skillsDir);\n\n // Copy skills to their scope-appropriate directories, replacing any stale\n // ejected copies of skills now sourced from a marketplace. Imported lazily:\n // copyLocalSkills lives in the operations layer (which imports back into\n // installation), so a static import here would form a load-time cycle.\n const { copyLocalSkills } = await import(\"../operations/skills/copy-local-skills\");\n const { projectCopied, globalCopied } = await copyLocalSkills(\n wizardResult.skills,\n projectDir,\n sourceResult,\n { deleteAlternateSourceSkills: true },\n );\n const copiedSkills = [...projectCopied, ...globalCopied];\n\n const ejectSkillsForResolution = buildEjectSkillsMap(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 const compiledAgentNames = await writeConfigAndCompileAgents({\n finalConfig,\n agents,\n localSkills: ejectSkillsForResolution,\n sourceResult,\n projectDir,\n paths: projectPaths,\n isProjectInstall,\n description: finalConfig.description || `Eject setup with ${wizardResult.skills.length} skills`,\n });\n\n return {\n copiedSkills,\n config: finalConfig,\n configPath: projectPaths.configPath,\n compiledAgents: compiledAgentNames,\n wasMerged: mergeResult.merged,\n ...(mergeResult.existingConfigPath !== undefined && {\n mergedConfigPath: mergeResult.existingConfigPath,\n }),\n skillsDir: projectPaths.skillsDir,\n agentsDir: projectPaths.agentsDir,\n };\n}\n","import { createHash } from \"crypto\";\nimport { isRecord } from \"../../utils/type-guards.js\";\nimport { downloadTemplate, type DownloadTemplateResult } from \"giget\";\nimport os from \"os\";\nimport path from \"path\";\nimport type { z } from \"zod\";\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 MARKETPLACE_JSON,\n marketplaceManifestPath,\n} from \"../../consts\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport {\n ensureDir,\n directoryExists,\n fileExists,\n readFileOptional,\n readFileSafe,\n remove,\n writeFile,\n} from \"../../utils/fs\";\nimport { log, verbose, warn } from \"../../utils/logger\";\nimport { sourceUnreachableUsingCache, STATUS_MESSAGES } from \"../../utils/messages\";\nimport { DEFAULT_SOURCE, isLocalSource } from \"../configuration\";\nimport {\n formatZodIssues,\n marketplaceSchema,\n sourceRevalidationSchema,\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 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 { subdir } = options;\n\n if (isLocalSource(source)) {\n return fetchFromLocalSource(source, subdir);\n }\n\n return fetchFromRemoteSource(source, 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(\n `Local marketplace not found: '${absolutePath}'\\n\\n` +\n `Nothing is at that path, and a local marketplace must be a directory holding skills.\\n\\n` +\n `Check it for a typo, or name a marketplace that exists:\\n` +\n ` --marketplace ${DEFAULT_SOURCE}`,\n );\n }\n\n verbose(`Using local marketplace: ${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 */\nexport function getGigetCacheDir(source: string): string | undefined {\n const protoMatch = source.match(SOURCE_PROTO_RE);\n\n // http/https providers use the full URL, not parseable as git URI\n if (protoMatch && (protoMatch[1] === \"http\" || protoMatch[1] === \"https\")) {\n return undefined;\n }\n\n const providerName = protoMatch?.[1] ?? \"github\";\n const rawSource = protoMatch ? source.slice(protoMatch[0].length) : source;\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, subdir?: string): Promise<FetchResult> {\n const cacheDir = getCacheDir(source);\n const fullSource = subdir ? `${source}/${subdir}` : source;\n\n verbose(`Fetching from remote: ${fullSource}`);\n verbose(`Cache directory: ${cacheDir}`);\n\n if (await directoryExists(cacheDir)) {\n const verdict = await revalidateCachedCopy(cacheDir, source);\n const cached: FetchResult = { path: cacheDir, fromCache: true, source: fullSource };\n\n if (verdict === \"current\" || verdict === \"unreachable\") {\n verbose(`Using cached marketplace: ${cacheDir}`);\n return cached;\n }\n\n announceRefetch(verdict);\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 await recordFetchedCopy(cacheDir, result);\n markCopyCurrentForThisRun(cacheDir);\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\n/**\n * What a revalidation learned about the copy in the cache.\n *\n * `unrecorded` is a cache with no fetch record beside it — written before this\n * check existed, or by hand. Nothing can be asked about it, so it is re-fetched\n * once to establish a record, and that re-fetch is not a change to announce.\n */\ntype CacheVerdict = \"current\" | \"superseded\" | \"unrecorded\" | \"unreachable\";\n\ntype SourceRevalidation = z.infer<typeof sourceRevalidationSchema>;\n\n/**\n * How long a revalidation may spend asking before the cached copy is used\n * instead. Against the default marketplace the question costs ~260ms, so five\n * seconds is around twenty times a healthy answer: a link slow enough to need\n * that much is still given the chance to answer, rather than being told its copy\n * may be stale when the source was reachable all along. Being unreachable is the\n * rare case, and a longer honest wait for it is cheaper than a wrong verdict on\n * a slow one. The bound still exists — the platform's own connect timeout is\n * ~10s, which is the wait no user with a dropped connection should sit through\n * for an answer their cache already holds.\n */\nconst REVALIDATION_TIMEOUT_MS = 5000;\n\n/** Where a cache directory's fetch record sits: beside it, never inside it. */\nconst FETCH_RECORD_SUFFIX = \".etag.json\";\n\n/**\n * One question per source per process. A single command loads the same source\n * more than once — the matrix and the marketplace label are separate calls — and\n * the answer cannot change between them.\n */\nconst askedThisRun = new Map<string, Promise<CacheVerdict>>();\n\n/**\n * The one line a re-fetch nobody asked for owes the user — and silence for\n * `unrecorded`, where the CLI cannot place the copy it holds and the re-fetch is\n * housekeeping rather than news.\n *\n * The parameter is the two verdicts that reach a download, not the whole union:\n * a new verdict that must not fall through to one fails here at the call site.\n */\nfunction announceRefetch(verdict: Extract<CacheVerdict, \"superseded\" | \"unrecorded\">): void {\n if (verdict === \"superseded\") {\n log(STATUS_MESSAGES.MARKETPLACE_HAS_NEWER_CONTENT);\n }\n}\n\nfunction revalidateCachedCopy(cacheDir: string, source: string): Promise<CacheVerdict> {\n const asked = askedThisRun.get(cacheDir);\n if (asked) return asked;\n\n const verdict = classifyCachedCopy(cacheDir, source);\n askedThisRun.set(cacheDir, verdict);\n return verdict;\n}\n\n/**\n * The answer for a copy this run has just downloaded, without asking for it: the\n * record written beside it names the tarball the source served a moment ago, so\n * within this run the copy is current by construction. Without it, the later\n * loads of the same command re-read a `superseded` answer that was true when it\n * was given and has been acted on since — and download it all over again.\n */\nfunction markCopyCurrentForThisRun(cacheDir: string): void {\n askedThisRun.set(cacheDir, Promise.resolve(\"current\"));\n}\n\n/**\n * The one question a run asks about a cached copy, and everything that answer\n * owes the user.\n *\n * An unreachable source's staleness is named here rather than at the call site\n * because the verdict is memoised and the line is owed once per source per run:\n * left outside, every later load of the same run repeats a warning about a\n * question that was only asked once.\n */\nasync function classifyCachedCopy(cacheDir: string, source: string): Promise<CacheVerdict> {\n const record = await readFetchRecord(cacheDir);\n if (!record) return \"unrecorded\";\n\n if (record.etag === undefined) {\n verbose(`No ETag was recorded for ${record.tar} — keeping the cached copy`);\n return \"current\";\n }\n\n try {\n const live = await fetchEtag(record.tar);\n if (live === undefined) {\n verbose(`${record.tar} answered without an ETag — keeping the cached copy`);\n return \"current\";\n }\n return live === record.etag ? \"current\" : \"superseded\";\n } catch (error) {\n verbose(`Could not revalidate ${record.tar}: ${getErrorMessage(error)}`);\n warn(sourceUnreachableUsingCache(source));\n return \"unreachable\";\n }\n}\n\n/**\n * The tarball's ETag as the host reports it now, asked for the same way giget\n * asks — a HEAD, from the same runtime — so the two agree on what the value for\n * a given source is. A private repository needs the token giget uses; it is read\n * from the environment per request and never written into the record.\n */\nasync function fetchEtag(tar: string): Promise<string | undefined> {\n const auth = process.env.GIGET_AUTH;\n const response = await fetch(tar, {\n method: \"HEAD\",\n ...(auth && { headers: { Authorization: `Bearer ${auth}` } }),\n signal: AbortSignal.timeout(REVALIDATION_TIMEOUT_MS),\n });\n return response.headers.get(\"etag\") ?? undefined;\n}\n\n/**\n * Where the record for a cached copy lives — exported because a second surface has to agree with\n * this one on the address: `e2e/fixtures/default-source-cache.ts` seeds a copy of the DEFAULT\n * source, and a run over a seeded copy with no record here re-downloads it over the network, which\n * is the one thing that fixture exists to avoid.\n */\nexport function fetchRecordPath(cacheDir: string): string {\n return `${cacheDir}${FETCH_RECORD_SUFFIX}`;\n}\n\nasync function readFetchRecord(cacheDir: string): Promise<SourceRevalidation | undefined> {\n const raw = await readFileOptional(fetchRecordPath(cacheDir));\n if (!raw) return undefined;\n\n const parsed = sourceRevalidationSchema.safeParse(parseJsonOrUndefined(raw));\n if (!parsed.success) {\n verbose(`Unusable fetch record at ${fetchRecordPath(cacheDir)} — re-fetching the marketplace`);\n return undefined;\n }\n\n return parsed.data;\n}\n\n/**\n * Records what would prove this copy current, so the next load can ask in one\n * request.\n *\n * The tarball URL is read off giget's own result rather than rebuilt here, which\n * is what keeps this provider-agnostic — it is whatever giget resolved for the\n * source. giget's result type erases its fields to an index signature, so the\n * value arrives untyped and is narrowed rather than trusted; without one there\n * is nothing to ask about and the copy stays unrecorded.\n */\nasync function recordFetchedCopy(cacheDir: string, result: DownloadTemplateResult): Promise<void> {\n const tar: unknown = result.tar;\n if (typeof tar !== \"string\") {\n verbose(\"No tarball URL came back from the download — the copy cannot be revalidated\");\n return;\n }\n\n const etag = await fetchEtag(tar).catch(() => undefined);\n const record: SourceRevalidation = { tar, ...(etag !== undefined && { etag }) };\n await writeFile(fetchRecordPath(cacheDir), JSON.stringify(record));\n}\n\nfunction parseJsonOrUndefined(raw: string): unknown {\n try {\n return JSON.parse(raw);\n } catch {\n return undefined;\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\n/**\n * Thrown when a marketplace has no manifest at all, which every other failure in\n * {@link fetchMarketplace} is not.\n *\n * A type rather than a sentence a caller matches on: absent and unreadable have\n * different remedies — add the file, versus repair the file that is already there —\n * and the only way a caller can report them apart is if the throw says which it is.\n * A caller that does not care still catches an ordinary `Error`.\n */\nexport class MarketplaceManifestAbsentError extends Error {}\n\nexport async function fetchMarketplace(source: string): Promise<MarketplaceFetchResult> {\n const result = await fetchFromSource(source, {\n subdir: \"\", // Root of repo\n });\n\n const marketplacePath = marketplaceManifestPath(result.path);\n\n // The FILE, not its directory: a plugin repository ships `.claude-plugin/plugin.json`\n // with no marketplace beside it, and a directory check calls that manifest readable\n // and leaves the absence to surface as a read error two statements later.\n if (!(await fileExists(marketplacePath))) {\n throw new MarketplaceManifestAbsentError(\n `Marketplace not found at: ${source}\\n\\n` +\n `The .claude-plugin/marketplace.json file is missing from this repository.\\n\\n` +\n `Possible causes:\\n` +\n \" - The marketplace 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 marketplace repository.\",\n );\n }\n\n const content = await readFileSafe(marketplacePath, MAX_MARKETPLACE_FILE_SIZE);\n const parsed: unknown = 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: ${formatZodIssues(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 (isRecord(parsed)) {\n warnUnknownFields(parsed, EXPECTED_MARKETPLACE_KEYS, MARKETPLACE_JSON);\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,\n };\n}\n","import { unique } from \"remeda\";\n\nimport { KEBAB_CASE_PATTERN } from \"../consts.js\";\n\n/** The characters {@link KEBAB_CASE_PATTERN} is built from, tested one at a time. */\nconst KEBAB_CASE_CHARACTER = /[a-z0-9-]/;\n\n/**\n * The characters a name carries that kebab-case does not admit, deduplicated and in\n * first-appearance order.\n *\n * Empty when the name breaks the rule some other way — a leading digit, a doubled or\n * a trailing hyphen — which is why a refusal states the rule as well as the list: an\n * author handed `@scope/thing` can act on `@` and `/` directly, and one handed\n * `-thing` has nothing to delete.\n */\nexport function charactersOutsideKebabCase(name: string): string[] {\n return unique([...name].filter((character) => !KEBAB_CASE_CHARACTER.test(character)));\n}\n\n/**\n * Validates a user-supplied entity name against the kebab-case convention.\n * Returns an error message naming the entity (e.g. \"Marketplace\", \"Skill\"),\n * or null when the name is valid.\n */\nexport function validateKebabCaseName(name: string, noun: string): string | null {\n if (!name || name.trim() === \"\") {\n return `${noun} name is required`;\n }\n\n if (!KEBAB_CASE_PATTERN.test(name)) {\n return `${noun} name must be kebab-case (lowercase letters, numbers, and hyphens, starting with a letter)`;\n }\n\n return null;\n}\n","import {\n CLI_INVOKE_COMMAND,\n DEFAULT_BRANDING,\n DEFAULT_PLUGIN_NAME,\n EDITOR_URL,\n LOCAL_SKILLS_PATH,\n MARKETPLACE_JSON,\n STANDARD_FILES,\n editorConfigUrl,\n} from \"../consts.js\";\nimport type { UnusableSkillMetadata } from \"../lib/loading/index.js\";\nimport { charactersOutsideKebabCase } from \"../lib/validate-kebab-name.js\";\nimport type { AgentName, SkillId } from \"../types/index.js\";\n\nexport const ERROR_MESSAGES = {\n UNKNOWN_ERROR: \"Unknown error occurred\",\n UNKNOWN_ERROR_SHORT: \"Unknown error\",\n NO_INSTALLATION: `No installation found. Run '${CLI_INVOKE_COMMAND} init' first to set up ${DEFAULT_BRANDING.NAME}`,\n FAILED_RESOLVE_SOURCE: \"Failed to resolve marketplace\",\n FAILED_LOAD_AGENT_PARTIALS: \"Failed to load agent partials\",\n FAILED_COMPILE_AGENTS: \"Failed to compile agents\",\n CLAUDE_CLI_NOT_FOUND: `Claude CLI not found — '${CLI_INVOKE_COMMAND} update' refreshes marketplaces through it. Install Claude Code first: https://claude.ai/code`,\n /**\n * What `compile` refuses with when every pass discovered zero skills. It is reached only\n * after an installation was detected, so the state it describes is a configuration with\n * nothing installed under it — the same state `doctor` reports as `config-empty` and\n * names `init` for, because `init` on a config that declares nothing opens the wizard\n * rather than the dashboard. `edit` is the wrong half of the pair here: it modifies the\n * currently installed skills, and there are none to modify.\n */\n NO_SKILLS_TO_COMPILE: `No skills found. Run '${CLI_INVOKE_COMMAND} init' to choose skills, or add your own under ${LOCAL_SKILLS_PATH}/.`,\n} as const;\n\nexport const SUCCESS_MESSAGES = {\n UNINSTALL_COMPLETE: \"Uninstall complete!\",\n INIT_SUCCESS: `${DEFAULT_BRANDING.NAME} initialized successfully!`,\n PLUGIN_COMPILE_COMPLETE: \"Plugin compile complete!\",\n} as const;\n\nexport const STATUS_MESSAGES = {\n INSTALLING_PLUGINS: \"Installing skill plugins...\",\n LOADING_SKILLS: \"Loading skills...\",\n LOADING_MARKETPLACE_SOURCE: \"Loading marketplace...\",\n RECOMPILING_AGENTS: \"Recompiling agents...\",\n COMPILING_AGENTS: \"Compiling agents...\",\n DISCOVERING_SKILLS: \"Discovering skills...\",\n RESOLVING_SOURCE: \"Resolving marketplace...\",\n RESOLVING_MARKETPLACE_SOURCE: \"Resolving marketplace...\",\n LOADING_AGENT_PARTIALS: \"Loading agent partials...\",\n FETCHING_REPOSITORY: \"Fetching repository...\",\n COPYING_SKILLS: \"Copying skills...\",\n /**\n * Printed when revalidation found the remote marketplace had moved on. It is the\n * only warning a user gets that this load costs a download rather than a\n * cache read, so it goes out before the download starts, not after.\n */\n MARKETPLACE_HAS_NEWER_CONTENT: \"Marketplace has newer content — fetching the update...\",\n} as const;\n\n/**\n * The partials `readAgentFiles` compiles a sub-agent out of, in the order it reads them —\n * and therefore what `eject agent-partials` puts under the reader's control. Spelled from\n * {@link STANDARD_FILES} rather than as prose so the sentence below cannot name a file the\n * compiler does not read: it named \"templates, agent intro, workflow, and examples\" for\n * years, four nouns matching nothing that ships.\n */\nconst AGENT_PARTIAL_FILES = [\n STANDARD_FILES.IDENTITY_MD,\n STANDARD_FILES.PLAYBOOK_MD,\n STANDARD_FILES.CRITICAL_REQUIREMENTS_MD,\n STANDARD_FILES.CRITICAL_REMINDERS_MD,\n STANDARD_FILES.OUTPUT_MD,\n];\n\nexport const INFO_MESSAGES = {\n NO_CHANGES_MADE: \"No changes made.\",\n RUN_COMPILE: `Run '${CLI_INVOKE_COMMAND} compile' to include imported skills in your agents.`,\n NO_AGENTS_TO_RECOMPILE: \"No agents to recompile\",\n NO_PLUGIN_INSTALLATION: \"No plugin installation found.\",\n NO_LOCAL_INSTALLATION: \"No local installation found.\",\n NOT_INSTALLED: `${DEFAULT_BRANDING.NAME} is not installed in this project.`,\n CONFIG_TYPES_REFRESHED: `Refreshed ${STANDARD_FILES.CONFIG_TYPES_TS}`,\n /**\n * `update` refreshes marketplaces and stops there. An ejected skill is a copy the\n * user owns and may have edited, so overwriting it from the source would discard\n * their work — this line says so once, as information rather than a warning.\n */\n EJECTED_SKILLS_USER_OWNED: `Ejected skills are yours to own — '${CLI_INVOKE_COMMAND} update' does not change them.`,\n NO_PLUGIN_MARKETPLACES: \"No plugin marketplaces are configured — nothing to refresh.\",\n /** Printed under the destination `eject agent-partials` just named, so it names files only. */\n AGENT_PARTIALS_CUSTOMIZABLE: `Each sub-agent directory there holds ${AGENT_PARTIAL_FILES.join(\", \")} — edit those to customize that sub-agent.`,\n} as const;\n\n/** Closing line of a plugin install, printed wherever one runs. */\nexport function pluginsInstalled(count: number): string {\n return `Installed ${count} skill plugins`;\n}\n\n/**\n * What an eject copy did, wherever `edit` performs one — a newly added local skill,\n * or a skill switched from plugin mode back to eject. Both copy through\n * `copyLocalSkills` at each skill's own scope, so both owe the same sentence.\n *\n * A count and no destination, deliberately: the copies are split between the\n * project directory and `$HOME` by each skill's scope, and one hardcoded path\n * would misname the other half.\n */\nexport function localSkillsCopied(count: number): string {\n return `Copied ${count} local skill(s)`;\n}\n\n/**\n * What a recompile pass did, as two numbers rather than one.\n *\n * The count it replaced was the roster the pass walked, so a run that rewrote\n * nothing and a run that rewrote everything printed the same sentence — the line\n * reported intent rather than outcome. `rewritten` is agents whose file this pass\n * wrote; `unchanged` is agents it found already correct and left alone.\n *\n * `subject` is the noun each caller counts in, because `compile` reports per\n * scope pass (\"global agents\") and `edit` reports the whole run's (\"agents\").\n */\nexport function recompileSummary(rewritten: number, unchanged: number, subject: string): string {\n return `${rewritten} ${subject} rewritten, ${unchanged} unchanged`;\n}\n\n/**\n * The same distinction for the fan-out a global change performs across every\n * OTHER registered project: a project whose agents all came back byte-identical\n * was visited and left alone, and says so instead of being counted as recompiled.\n */\nexport function propagatedRecompileSummary(\n rewritten: number,\n unchanged: number,\n failed: number,\n): string {\n const failureSuffix = failed > 0 ? ` (${failed} failed)` : \"\";\n return `Recompiled agents in ${rewritten} registered projects, ${unchanged} unchanged${failureSuffix}`;\n}\n\n/**\n * Warning printed for an installed, actively-selected skill that no sub-agent's stack\n * carries. The install itself is correct — the files are on disk and `config.ts` records\n * them — but nothing will ever load the skill, and every other surface reports the run\n * as clean. This line is the only one that says so.\n */\nexport function skillAssignedToNoAgent(skillId: SkillId): string {\n return `Skill '${skillId}' is assigned to no sub-agent — nothing will load it.`;\n}\n\n/**\n * The reason behind {@link skillAssignedToNoAgent} whenever it is the scope rule: a\n * project-scoped skill never reaches a global-scoped sub-agent. Names every sub-agent the\n * rule kept the skill away from, so one line accounts for every dropped pair.\n *\n * Shared by the save path (`init` / `edit`, where the assignment was never built) and by\n * `compile` (where a hand-edited `config.ts` declares the pair and the compile-time filter\n * drops it). One verdict, one sentence — a second spelling would read as a second rule.\n */\nexport function scopeBlockedStackAssignment(agentNames: AgentName[], skillId: SkillId): string {\n const subject = agentNames.length === 1 ? \"Sub-agent\" : \"Sub-agents\";\n const named = agentNames.map((name) => `'${name}'`).join(\", \");\n return `${subject} ${named} cannot carry project-scoped skill '${skillId}' — global-scoped sub-agents only carry global-scoped skills.`;\n}\n\n/**\n * Hint printed when a project-context compile resolves zero project agents but\n * the config still declares global-scope agents. Names the global context and\n * the count so the \"No agents to recompile\" no-op isn't silent after a global\n * stack change.\n */\nexport function globalScopedAgentsHint(count: number): string {\n const subject = count === 1 ? \"agent is\" : \"agents are\";\n return `${count} ${subject} global-scoped — run '${CLI_INVOKE_COMMAND} compile' from your home directory, or edit from this project, to recompile them.`;\n}\n\n/** Summary printed after `update` refreshed every marketplace its config named. */\nexport function marketplacesRefreshed(count: number): string {\n return `Update complete! ${count} ${count === 1 ? \"marketplace\" : \"marketplaces\"} refreshed.`;\n}\n\n/** Warning printed for one marketplace the Claude CLI could not refresh. */\nexport function marketplaceRefreshFailed(marketplace: string, reason: string): string {\n return `Could not update marketplace ${marketplace}: ${reason}`;\n}\n\n/**\n * Warning printed when a remote source could not be reached to check whether the\n * cached copy is still current, and the copy was used anyway.\n *\n * The load succeeds — an offline user gets the marketplace they already have\n * rather than an error — so the line's whole job is to name what it is they got.\n */\nexport function sourceUnreachableUsingCache(source: string): string {\n return `Could not reach ${source} — using the cached copy, which may be out of date.`;\n}\n\n/**\n * Fatal summary naming every marketplace that failed to refresh. Each cause was\n * already warned individually; this is what makes the run exit non-zero.\n */\nexport function marketplacesRefreshFailed(marketplaces: string[]): string {\n const subject = marketplaces.length === 1 ? \"marketplace\" : \"marketplaces\";\n return `${marketplaces.length} ${subject} could not be updated: ${marketplaces.join(\", \")}`;\n}\n\n/**\n * `build marketplace`'s refusal when package.json names no author, so the manifest\n * would carry an owner with no name.\n *\n * Refused rather than warned because `marketplaceOwnerSchema` requires that name: a\n * manifest written without one is a file this CLI's own reader rejects, and a build\n * that exits 0 having produced it reports success for a marketplace nobody can add.\n */\nexport function marketplaceOwnerHasNoName(packageJsonPath: string): string {\n return [\n `A marketplace's owner must have a name, and no name could be read from 'author' in ${packageJsonPath}.`,\n `Nothing was written: a ${MARKETPLACE_JSON} whose 'owner.name' is empty is refused by this CLI's own reader, so the build would have reported success for a marketplace nobody can install from.`,\n `Set 'author' in that file — either \"Jane Doe <jane@example.com>\" or { \"name\": \"Jane Doe\" } — and build again.`,\n ].join(\"\\n\\n\");\n}\n\n/**\n * `build marketplace`'s refusal when package.json carries a version that is only a version\n * to a reader who does not check it.\n *\n * `marketplaceSchema` requires `min(1)` here, and nothing upstream did: the package.json\n * schema types the field as a bare string, and the generator's `??` default treats `\"\"` as\n * a value because it is not nullish. So an empty version reached the manifest, the build\n * exited 0, and the file was refused the first time this CLI read it back — the same\n * write-then-fail-on-read shape the zero-plugin refusal closed.\n */\nexport function marketplaceHasNoVersion(packageJsonPath: string): string {\n return [\n `A marketplace must have a version, and 'version' in ${packageJsonPath} is empty.`,\n `Nothing was written: a ${MARKETPLACE_JSON} whose 'version' is empty is refused by this CLI's own reader, so the build would have reported success for a marketplace nobody can install from.`,\n `Set 'version' in that file — \"0.1.0\" if this is its first release — and build again.`,\n ].join(\"\\n\\n\");\n}\n\n/**\n * `build marketplace`'s refusal when the name read from package.json is not one a\n * marketplace may publish under.\n *\n * The way out is the flag rather than a rename of the npm package: an npm scoped name\n * is a legitimate thing for a package to have and an illegitimate marketplace name, so\n * the two identities are allowed to differ. Every offending character is named, because\n * `@scope/thing` gives an author two edits to make and a rule alone gives them none.\n */\nexport function marketplaceNameNotPublishable(name: string, packageJsonPath: string): string {\n const offenders = charactersOutsideKebabCase(name);\n return [\n `Marketplace name '${name}', read from 'name' in ${packageJsonPath}, is not a name a marketplace may publish under.`,\n ...(offenders.length > 0\n ? [\n `It carries ${offenders.map((character) => `'${character}'`).join(\" and \")}, which a marketplace name may not.`,\n ]\n : []),\n `A marketplace name is kebab-case: lowercase letters, numbers and hyphens, starting with a letter.`,\n `Publish under a name of your own instead: '${CLI_INVOKE_COMMAND} build marketplace --name <your-marketplace>'.`,\n ].join(\"\\n\\n\");\n}\n\n/**\n * Warning printed when a compile pass finished but the scope's config-types.ts\n * could not be regenerated (e.g. the skills source was unreachable). The compiled\n * agents are fine; only the type unions may still be stale.\n */\nexport function configTypesRefreshFailed(reason: string): string {\n return `Could not refresh ${STANDARD_FILES.CONFIG_TYPES_TS} — type unions may be stale: ${reason}`;\n}\n\n/**\n * Summary printed after a global uninstall pruned the inlined global-scoped\n * config entries from the registered projects.\n */\nexport function registeredProjectsUpdated(count: number): string {\n return `Updated ${count} registered ${count === 1 ? \"project\" : \"projects\"}`;\n}\n\n/**\n * Warning printed when a global uninstall could not update one registered\n * project (missing directory or unreadable config). The uninstall continues.\n */\nexport function registeredProjectUpdateSkipped(projectPath: string): string {\n return `Could not update registered project at ${projectPath} — its config may still reference the uninstalled global content`;\n}\n\n/**\n * The file and the reason behind {@link skillMetadataUnusableError}, LOGGED rather than\n * carried in the error itself: oclif hard-wraps error text at the terminal width, and a path\n * broken across two lines is one nobody can copy. The error names the skills; this names\n * their files, unwrapped, immediately above it.\n *\n * The reason is the reader's own message and can run to several lines — a YAML parse error\n * carries the position and the offending line, which is the point of naming the file at all.\n * For a file that parsed, it is the fields the file leaves out, named as missing.\n */\nexport function skillMetadataUnusableDetail({\n skillDirName,\n metadataPath,\n reason,\n}: UnusableSkillMetadata): string {\n return ` ${skillDirName} — ${metadataPath}\\n ${reason}`;\n}\n\n/**\n * Which skills the refusal is about, and that their files are named above it. Shared by both\n * refusals below because it is one sentence about one verdict — the commands differ on what\n * the file being unreadable COSTS, not on what it says.\n *\n * Every offending skill is named rather than the first, so one run fixes the lot.\n */\nfunction metadataUnusableOpening(entries: UnusableSkillMetadata[]): string {\n const named = entries.map(({ skillDirName }) => `'${skillDirName}'`).join(\", \");\n const subject = entries.length === 1 ? \"that skill\" : \"those skills\";\n return `The ${STANDARD_FILES.METADATA_YAML} of ${named} does not describe ${subject} — the file and the reason are named above.`;\n}\n\n/**\n * The two ways out, and where the whole list of skills in this state is reported. Also shared:\n * a refusal that named a different way out per command would be describing a different fault.\n */\nconst METADATA_UNUSABLE_WAY_OUT = `Fix the file, or delete the skill directory — '${CLI_INVOKE_COMMAND} doctor' reports every skill in this state.`;\n\n/**\n * Refusal printed when `compile` meets an installed skill whose metadata.yaml exists but\n * describes no skill — either nothing can be parsed out of it, or it parses without the\n * fields a skill is described by. It is the sibling of {@link configUnreadableError} one\n * layer down: the file is there, and nothing can be made of it.\n *\n * Compile refuses rather than skips because a skipped skill is invisible. The same file is\n * refused by the local-skill discovery that regenerates `config-types.ts`, so a compile that\n * loaded the skill from its SKILL.md anyway would write agents around a skill the generated\n * types never carry — which is what it used to do, in the same run, silently.\n */\nexport function skillMetadataUnusableError(entries: UnusableSkillMetadata[]): string {\n return [\n metadataUnusableOpening(entries),\n `A skill this file cannot describe is skipped when ${STANDARD_FILES.CONFIG_TYPES_TS} is regenerated, so compiling it would write agents around a skill the generated types never carry.`,\n METADATA_UNUSABLE_WAY_OUT,\n ].join(\"\\n\");\n}\n\n/**\n * The same refusal raised by `init` and `edit`, where what the file costs is different: the\n * wizard resolves the installed roster against the catalogue, and a skill nothing can be\n * loaded for reaches no screen — so the entry naming it is dropped from `config.ts` and\n * reported as a removal the user never asked for.\n *\n * That is the right answer for a skill the marketplace no longer carries and the wrong one\n * here, where the files are sitting in the install and one repairable file stands between\n * them and the catalogue. So the run stops with the entry intact, exactly as `compile` stops\n * over the same verdict about the same file, rather than spending the record of an install\n * on a YAML typo and billing the marketplace for it.\n */\nexport function savedSkillMetadataUnusableError(entries: UnusableSkillMetadata[]): string {\n return [\n metadataUnusableOpening(entries),\n `A config entry naming a skill this file cannot describe is dropped as one this marketplace does not carry — and a file that can be repaired must not cost an install its record.`,\n METADATA_UNUSABLE_WAY_OUT,\n ].join(\"\\n\");\n}\n\n/**\n * `init --from` is greenfield-only. A shared configuration is installed whole — its own\n * `assignments` map REPLACES the ownership-derived stack rather than merging with it — so there is\n * no coherent answer to what it should do when it meets a setup that is already there. Both\n * refusals below name `uninstall`, because that is the whole of the way through.\n */\nconst SHARED_CONFIG_GREENFIELD_HINT =\n \"installing a shared configuration is a fresh setup, not a merge\";\n\n/**\n * Where a freshly minted id can be acted on, which is the whole of what makes it a share.\n *\n * Exactly two things read one — this CLI and the editor the configuration reopens in — and both\n * commands that mint an id (`share`, and `edit --ui`) print both lines, because an id nobody can\n * act on is not a share. One definition rather than two, so the two commands cannot come to\n * describe the same id differently.\n */\nexport function sharedConfigDestinations(id: string): string[] {\n return [\n ` Install it: ${CLI_INVOKE_COMMAND} init --from ${id}`,\n ` Open it: ${editorConfigUrl(id)}`,\n ];\n}\n\n/** Refusal printed when the directory `init --from` was run in is already installed. */\nexport function sharedConfigExistingInstall(configPath: string): string {\n return `An installation already exists at ${configPath}. Run '${CLI_INVOKE_COMMAND} uninstall' first — ${SHARED_CONFIG_GREENFIELD_HINT}.`;\n}\n\n/**\n * Refusal printed when this project is clean but the payload writes into the user's own\n * ~/.claude, which is already installed. Only a payload carrying global-scoped entries can reach\n * that far, so a project-only configuration is never refused for it.\n */\nexport function sharedConfigGlobalInstall(configPath: string): string {\n return `This configuration installs global-scoped content, and a global installation already exists at ${configPath}. Run '${CLI_INVOKE_COMMAND} uninstall' from your home directory first — ${SHARED_CONFIG_GREENFIELD_HINT}.`;\n}\n\n/**\n * Refusal printed when `init --from` runs at the home directory and the payload carries\n * project-scoped entries.\n *\n * It is NOT a greenfield refusal, and deliberately says nothing about `uninstall`: the payload is\n * installable and the location is not, so the way out is another directory rather than a removal.\n * A global installation holds only global-scoped content, and at the home root both scopes resolve\n * to the same files — so a project-scoped entry does not land elsewhere, it lands in the global\n * config wearing a label that contradicts the file it is in.\n *\n * Every offender is named, skills and sub-agents alike, because they are separate decisions in the\n * payload and only the sharer knows which one they meant — the same reason the unwritable-pair\n * refusal names both halves of every pair.\n */\nexport function sharedConfigProjectScopeAtHome(\n skillIds: readonly SkillId[],\n agentNames: readonly AgentName[],\n): string {\n return [\n \"This configuration cannot be installed here: the home directory is the global scope, and a \" +\n \"global installation holds only global-scoped content — so these project-scoped entries \" +\n \"have nowhere to be written:\",\n ...skillIds.map((id) => ` skill ${id} (scope: project)`),\n ...agentNames.map((name) => ` sub-agent ${name} (scope: project)`),\n \"Run this from inside a project directory, or re-share it with each entry above at global scope.\",\n ].join(\"\\n\");\n}\n\n/**\n * The ids a decode could not place, named rather than counted.\n *\n * \"3 skills were skipped\" cannot be acted on; the ids can, and this is the one moment a user\n * can tell whether what was shared is what they are getting. One definition because both\n * consumers of a shared configuration report it — `init --from` on the way into a clean\n * directory, `edit --from` on the way over an installed one — and a skip that read differently\n * per command would look like a different kind of skip.\n */\nexport function skippedUnknownSkills(skillIds: readonly string[]): string {\n return `Skipped ${skillIds.length} skill(s) this catalog does not know: ${skillIds.join(\", \")}`;\n}\n\n/** The sub-agent half of {@link skippedUnknownSkills}, judged against `AGENT_NAMES`. */\nexport function skippedUnknownAgents(agentNames: readonly string[]): string {\n return `Skipped ${agentNames.length} unknown sub-agent(s): ${agentNames.join(\", \")}`;\n}\n\n/**\n * What a shared configuration brought with it rather than named. Named for the same reason the\n * skips are: these are the entries no catalogue can explain, so this line is the only place a\n * user learns what arrived inside the configuration itself.\n */\nexport function carriedSkillsWritten(skillIds: readonly string[]): string {\n return `Wrote ${skillIds.length} skill(s) this configuration carries: ${skillIds.join(\", \")}`;\n}\n\n/**\n * The fixed text of `edit --from`'s removal plan.\n *\n * Applying a shared configuration makes this project MATCH it, so a skill the previous\n * configuration installed and this payload omits is removed. That is the whole reason the\n * command is interactive, and the reason the heading names removal rather than the apply:\n * additions and re-tunings need no permission, and the change summary prints them afterwards.\n */\nexport const SHARED_CONFIG_APPLY = {\n PREVIEW_HEADING: \"Applying this configuration will remove:\",\n SKILLS_HEADING: \"Skills:\",\n AGENTS_HEADING: \"Sub-agents:\",\n /**\n * The two headings a PROJECT run prints instead, for entries that live at global scope. They\n * exist only there: at the home directory every entry is global, so a heading saying so would\n * label the whole list with the one fact the location already states.\n */\n GLOBAL_SKILLS_HEADING: \"Skills installed globally:\",\n GLOBAL_AGENTS_HEADING: \"Sub-agents installed globally:\",\n /** Printed in place of the sections when the payload takes nothing away. */\n NOTHING_REMOVED: \"Nothing is removed — this configuration only adds and re-tunes.\",\n CONFIRM: \"Apply this configuration?\",\n} as const;\n\n/**\n * Refusal printed when `edit --from` has no terminal to confirm its removals at.\n *\n * A confirm nobody can answer must never become a yes, so this refuses rather than applying\n * silently. It names the other command deliberately: `init --from` installs the same\n * configuration into a clean directory and removes nothing, so it is safe headless and is the\n * whole of what a pipeline can do with an id.\n */\nexport function sharedConfigNeedsTerminal(id: string): string {\n return [\n `Applying configuration '${id}' removes whatever it leaves out, so it has to be confirmed — and there is no terminal here to confirm it at.`,\n `Run '${CLI_INVOKE_COMMAND} edit --from ${id}' from a terminal, or '${CLI_INVOKE_COMMAND} init --from ${id}' in a clean directory, which installs without removing anything.`,\n ].join(\"\\n\");\n}\n\n/**\n * Refusal printed when `edit --ui` and `edit --from` are asked for at once. They are the two\n * ends of one round trip — one hands this installation to the editor, the other applies a\n * configuration back — and there is no order in which doing both in a single run means\n * anything.\n */\nexport const SHARED_CONFIG_ONE_DIRECTION =\n \"--ui and --from are the two directions of the same round trip: --ui hands this installation to the editor, and --from applies one back. Run one, then the other.\";\n\n/**\n * The removal plan's statement of CONSEQUENCE for entries a project run removes at global scope.\n *\n * A global install is one installation every registered project reads, so removing one from\n * inside a project changes projects the person confirming is not looking at and did not choose\n * to be looking at. Nothing is refused over that — the ruling is that they may do it — but a yes\n * given without it is a yes to a change nobody described, so the reach is counted AND named:\n * \"2 other projects\" cannot be weighed against anything, and a path can.\n *\n * Printed only from a PROJECT. Inside the global installation the location IS the scope and the\n * person chose it, so the ordinary apply confirm is the whole of the gate there — see\n * `edit`'s two plan branches.\n */\nexport function globallyInstalledRemoved(otherProjects: readonly string[]): string {\n return [\n \"These are installed globally, and a global install is shared by every project on this machine.\",\n ...globalRemovalReach(otherProjects),\n `To keep them, answer no and re-share the configuration with them included.`,\n ].join(\"\\n\");\n}\n\n/** Who else the removal above lands on: every registered project but the one being edited. */\nfunction globalRemovalReach(otherProjects: readonly string[]): string[] {\n if (otherProjects.length === 0) {\n return [\n \"No other project is registered here, so nothing else changes today — a project set up later inherits whatever the global install holds then.\",\n ];\n }\n\n return [\n `Also affects ${otherProjects.length} other registered project(s):`,\n ...otherProjects.map((projectDir) => ` ${projectDir}`),\n ];\n}\n\n/**\n * The removal plan's statement for skills the round trip does not own.\n *\n * `forkedFrom` decides ownership: the CLI stamps it into every skill directory it writes, and a\n * skill written by hand into `.claude/skills/` carries none — so no shared configuration ever\n * carried it, and this one made no statement about it. Deleting it would be this command\n * inventing an instruction nobody gave.\n */\nexport function authoredHereKept(skillIds: readonly SkillId[]): string {\n return [\n \"Kept — written here rather than installed, so a shared configuration never carried them:\",\n ...skillIds.map((id) => ` skill ${id}`),\n `Remove them with '${CLI_INVOKE_COMMAND} edit'.`,\n ].join(\"\\n\");\n}\n\n/**\n * The removal plan's statement for skills this configuration NAMES that this catalogue cannot\n * place.\n *\n * The skips reported earlier say what did not arrive; this says what stayed because of it, and\n * the two are one fact read from either end. A destructive apply removes on intent and never on\n * its own inability: the payload asked for these ids, so their absence from the decode is this\n * catalogue's limit rather than an instruction, and deleting an installed skill over it would\n * delete it because the catalogue moved.\n *\n * The remedy is the catalogue rather than the skill, which is the whole difference from the two\n * statements above: nothing is wrong with what is installed, and nothing the user does to it\n * makes the configuration's instruction applicable.\n */\nexport function unplaceableKept(skillIds: readonly SkillId[]): string {\n return [\n \"Kept — named by this configuration, and this catalogue cannot place them:\",\n ...skillIds.map((id) => ` skill ${id}`),\n `Run '${CLI_INVOKE_COMMAND} update' to refresh this installation's marketplace, then apply the configuration again.`,\n ].join(\"\\n\");\n}\n\n/**\n * Refusal printed when a command that must read an existing configuration meets one it\n * cannot load. There are no versioned migrations, so an unreadable configuration is\n * recreated rather than repaired — and `uninstall` deliberately keeps working on one, which\n * is what makes the first instruction a real way out rather than a suggestion to delete\n * directories by hand. The editor is the other: it builds a configuration the CLI installs\n * by id.\n *\n * `configLoadFailure` is a `ConfigLoadError` message, so the offending file and the reason\n * are already in it and are not restated here.\n *\n * `doctor` is named last and deliberately: it reports this same file as its own finding, with the\n * same way out. It could not be named until it did — it used to call a config that exists but\n * cannot be read `.claude-src/config.ts not found` and send the reader to `init`, contradicting\n * every line below (CLI-430).\n */\nexport function configUnreadableError(configLoadFailure: string): string {\n return [\n configLoadFailure,\n `There is no automatic repair for this — recreate the configuration: '${CLI_INVOKE_COMMAND} uninstall' still works on a config it cannot read, then '${CLI_INVOKE_COMMAND} init'.`,\n `Or build one at ${EDITOR_URL} and install it with '${CLI_INVOKE_COMMAND} init --from <id>'.`,\n `'${CLI_INVOKE_COMMAND} doctor' reports the same file, alongside whatever else is wrong here.`,\n ].join(\"\\n\");\n}\n\n/**\n * Warning printed when a global uninstall could not update the registered\n * projects at all (e.g. the skills source failed to load). The uninstall\n * itself still completes.\n */\nexport function registeredProjectsUpdateFailed(reason: string): string {\n return `Could not update registered projects — their configs may still reference the uninstalled global content: ${reason}`;\n}\n\n/**\n * Statement printed in the uninstall removal plan, and again in the summary, for the agent\n * files this run leaves where they are. Every agent the compiler writes carries a provenance\n * marker, so an agent file without one was written by somebody else — and saying so is what\n * makes the removal beside it a claim about provably-ours rather than about a directory.\n *\n * Printed both before the confirmation and after the removal, from the one plan, so what the\n * user approved and what the run reports cannot disagree.\n */\nexport function unmarkedAgentsKept(agentsDir: string, count: number): string {\n const subject = count === 1 ? \"agent\" : \"agents\";\n const object = count === 1 ? \"it\" : \"them\";\n return `Kept ${count} ${subject} in ${agentsDir}/ — no ${DEFAULT_PLUGIN_NAME} marker, so this CLI did not compile ${object}.`;\n}\n\n/**\n * The uninstall removal plan's fixed text: the heading the whole plan is printed under,\n * and the heading each removal is grouped beneath. A heading is a promise about the lines\n * below it, so one is printed only when the plan carries a removal that sits under it.\n * Both renderers — the `--yes` printer and the confirm UI — read them from here, so the\n * preview a user approves and the list a `--yes` run prints cannot drift apart.\n */\nexport const UNINSTALL_PLAN = {\n PREVIEW_HEADING: \"The following will be removed:\",\n PLUGINS_HEADING: \"Plugins:\",\n CLI_MANAGED_FILES_HEADING: \"CLI-managed files:\",\n CONFIG_HEADING: \"Config:\",\n} as const;\n\n/**\n * The plan's line for the local skills directory. The directory is not removed wholesale —\n * only the skills whose `forked-from` metadata names a marketplace are — so the line says\n * which of its contents the run is claiming.\n */\nexport function localSkillsRemoval(skillsDir: string): string {\n return `${skillsDir}/ (matching the marketplace)`;\n}\n\n/**\n * The plan's line for the compiled agents directory, marking it as the CLI's to delete\n * rather than the user's. Printed when the run can name which agents those are — from the\n * configuration, or from the provenance marker each compiled file carries when the\n * configuration is gone. {@link unmarkedAgentsKept} names the rest.\n */\nexport function compiledAgentsRemoval(agentsDir: string): string {\n return `${agentsDir}/ (CLI-compiled)`;\n}\n","import os from \"os\";\n\nimport { isHomeDirectory } from \"../installation/is-home-directory\";\nimport { DEFAULT_PUBLIC_SOURCE_NAME, EJECT_SOURCE } from \"../../consts\";\nimport type {\n MergedSkillsMatrix,\n ResolvedSkill,\n SkillId,\n SkillSource,\n SkillSourceType,\n} from \"../../types\";\nimport { verbose } from \"../../utils/logger\";\nimport { typedEntries, typedKeys } from \"../../utils/typed-object\";\nimport { isDefaultSource, type ResolvedConfig } from \"../configuration\";\nimport { discoverAllPluginSkills } from \"../plugins\";\n\n/**\n * True when the tagging pass looked at this skill and found only the copy on disk.\n *\n * The one reading of `availableSources` every surface that asks \"can this be a plugin?\"\n * must share: the Sources grid offers a cell on it and the install pipeline refuses on\n * it, and a second copy of the rule is how those two come to disagree. Asked of the\n * tagged sources rather than of `custom` — what a plugin install needs is a marketplace\n * that HAS the skill, and who wrote it decides nothing. A skill the pass never reached\n * carries no sources at all and answers `false`: absence of an answer is not an answer.\n */\nexport function isLocalOnlySkill(skill: ResolvedSkill | undefined): boolean {\n return (\n skill?.availableSources !== undefined &&\n !skill.availableSources.some((source) => source.type !== \"local\")\n );\n}\n\n/**\n * Appends a source to the skill's availableSources, initializing the array on\n * first tag. In-place mutation is this module's documented tagging contract.\n */\nfunction addAvailableSource(\n skill: { availableSources?: SkillSource[] },\n source: SkillSource,\n): void {\n skill.availableSources = skill.availableSources ?? [];\n skill.availableSources.push(source);\n}\n\n/**\n * Annotates every skill in the matrix with its install-mode availability metadata.\n *\n * Runs a four-phase tagging pipeline that mutates `primaryMatrix.skills` in place:\n * 1. **Primary** -- tags every skill the marketplace CARRIES with it (public or private),\n * skipping the ids in `unbackedSkillIds`\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. **Active source** -- sets `activeSource` to the installed variant, or first available\n *\n * After this function completes, each skill in the matrix has `availableSources` -- at most\n * the local copy and the one marketplace, which are the two install modes the Sources step\n * offers -- 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 * marketplace is a private one or the default public source\n * @param projectDir - Absolute path to the project root, used to locate plugin directories\n * @param marketplace - Optional marketplace name resolved from the source's marketplace.json.\n * Takes precedence over `sourceConfig.marketplace` when provided.\n * @param unbackedSkillIds - Ids the matrix holds that the marketplace does NOT carry: skills\n * the local merge introduced from `.claude/skills/`. They are left\n * out of the primary tag, because a marketplace entry on a skill no\n * marketplace has is a plugin install that cannot happen. Defaults\n * to empty, which is what a matrix built without a local merge means.\n *\n * @remarks\n * **Side effects:** Mutates `primaryMatrix` in place.\n */\nexport async function loadSkillsFromAllSources(\n primaryMatrix: MergedSkillsMatrix,\n sourceConfig: ResolvedConfig,\n projectDir: string,\n marketplace?: string,\n unbackedSkillIds: ReadonlySet<SkillId> = new Set(),\n): Promise<void> {\n const resolvedMarketplace = marketplace ?? sourceConfig.marketplace;\n const primarySourceName = resolvedMarketplace ?? DEFAULT_PUBLIC_SOURCE_NAME;\n const primarySourceType: SkillSourceType = isDefaultSource(sourceConfig.source)\n ? \"public\"\n : \"private\";\n\n tagPrimarySourceSkills(primaryMatrix, primarySourceName, primarySourceType, unbackedSkillIds);\n tagLocalSkills(primaryMatrix);\n await tagPluginSkills(primaryMatrix, projectDir, primarySourceName, primarySourceType);\n setActiveSources(primaryMatrix);\n}\n\nfunction tagPrimarySourceSkills(\n matrix: MergedSkillsMatrix,\n sourceName: string,\n sourceType: SkillSourceType,\n unbackedSkillIds: ReadonlySet<SkillId>,\n): void {\n for (const [id, skill] of typedEntries(matrix.skills)) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n if (!skill) continue;\n if (unbackedSkillIds.has(id)) continue;\n\n const source: SkillSource = {\n name: sourceName,\n type: sourceType,\n installed: false,\n primary: true,\n };\n\n addAvailableSource(skill, source);\n }\n}\n\nfunction tagLocalSkills(matrix: MergedSkillsMatrix): void {\n let count = 0;\n for (const [, skill] of typedEntries(matrix.skills)) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n if (!skill) continue;\n if (!skill.local) continue;\n\n const source: SkillSource = {\n name: EJECT_SOURCE,\n type: \"local\",\n installed: true,\n installMode: \"eject\",\n };\n\n addAvailableSource(skill, 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(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(projectDir: string): Promise<SkillId[]> {\n const pluginSkills = await discoverAllPluginSkills(projectDir);\n const skillIds = typedKeys<SkillId>(pluginSkills);\n\n // D-160: Also discover global plugins when editing from a project directory.\n // Follows the same global+project merge pattern as local skills in source-loader.ts.\n const homeDir = os.homedir();\n if (!isHomeDirectory(projectDir)) {\n const globalPluginSkills = await discoverAllPluginSkills(homeDir);\n const globalSkillIds = typedKeys<SkillId>(globalPluginSkills);\n if (globalSkillIds.length > 0) {\n verbose(`Found ${globalSkillIds.length} global plugin skill(s)`);\n const merged = new Set([...skillIds, ...globalSkillIds]);\n return [...merged];\n }\n }\n\n if (skillIds.length === 0) {\n verbose(\"No plugin skills discovered from settings.json\");\n }\n\n return skillIds;\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 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\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 [firstSource] = skill.availableSources;\n if (!firstSource) continue;\n skill.activeSource = skill.availableSources.find((s) => s.installed) ?? firstSource;\n }\n}\n","import path from \"path\";\nimport { DIRS, STANDARD_FILES } from \"../consts\";\nimport type {\n AgentConfig,\n AgentDefinition,\n AgentName,\n CompileAgentConfig,\n CompileConfig,\n Skill,\n SkillDefinitionMap,\n SkillReference,\n StackAgentConfig,\n} from \"../types\";\nimport { fileExists } from \"../utils/fs\";\nimport { verbose } from \"../utils/logger\";\nimport { typedEntries, typedFromEntries, 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 ...(ref.source !== undefined && { source: ref.source }),\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 the skill references an agent compiles with.\n *\n * The compile config is the only source: `buildCompileAgents` has already expanded\n * the project config's stack into `skills` by the time this runs.\n *\n * @param agentConfig - Compile-time agent config\n * @returns The agent's explicit skill references, or an empty array when it names none\n */\nexport function resolveAgentSkillRefs(agentConfig: CompileAgentConfig): SkillReference[] {\n return agentConfig.skills ?? [];\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 the agent's compile config\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 * @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 */\n// Nothing below is asynchronous any more: `resolveAgentSkillRefs` never was, and\n// dropping its `async` emptied this one too. The `Promise` stays because it is the\n// published shape — two production callers await it and local-installer.test.ts\n// doubles it with `mockResolvedValue`, so unwinding it is a change to the compile\n// pipeline rather than to this line.\n// eslint-disable-next-line @typescript-eslint/require-await -- published shape, see above\nexport async function resolveAgents(\n agents: Partial<Record<AgentName, AgentDefinition>>,\n skills: SkillDefinitionMap,\n compileConfig: CompileConfig,\n _projectRoot: string,\n): Promise<Partial<Record<AgentName, AgentConfig>>> {\n const entries = typedEntries<AgentName, CompileAgentConfig>(compileConfig.agents).map(\n ([agentName, agentConfig]) => {\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 skillRefs = resolveAgentSkillRefs(agentConfig);\n const resolvedSkills = resolveSkillReferences(skillRefs, skills);\n\n // The project config carries the user's deliberate choice; the agent's own metadata\n // carries the default. Config wins, silently — warning on every compile for a setting\n // someone made on purpose is noise. Neither present leaves the key off entirely.\n const model = agentConfig.model ?? definition.model;\n const effort = agentConfig.effort ?? definition.effort;\n\n return [\n agentName,\n {\n name: agentName,\n title: definition.title,\n description: definition.description,\n ...(model !== undefined && { model }),\n ...(effort !== undefined && { effort }),\n tools: definition.tools,\n skills: resolvedSkills,\n ...(definition.path !== undefined && { path: definition.path }),\n ...(definition.sourceRoot !== undefined && { sourceRoot: definition.sourceRoot }),\n ...(definition.agentBaseDir !== undefined && { agentBaseDir: definition.agentBaseDir }),\n },\n ] as const;\n },\n );\n\n return typedFromEntries(entries);\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 EJECT_SOURCE,\n PROJECT_ROOT,\n STANDARD_FILES,\n STANDARD_DIRS,\n} from \"../consts\";\nimport { resolveClaudeMd } from \"./resolver\";\nimport { cliVersion, stampProvenanceMarker } from \"./agents/agent-provenance\";\nimport { validateCompiledAgent, printOutputValidationResult } from \"./output-validator\";\nimport type {\n AgentConfig,\n AgentName,\n CompiledAgentData,\n CompileContext,\n PluginSkillRef,\n Skill,\n} from \"../types\";\nimport { typedEntries, typedValues } 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 // Boundary cast: .replace() widens the branded string T; stripping characters keeps it in T's domain\n return sanitized as T;\n}\n\nfunction sanitizeStringArray(values: string[], fieldName: string): string[] {\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 ...(s.pluginRef !== undefined && {\n pluginRef: sanitizeLiquidSyntax(s.pluginRef, \"skill.pluginRef\"),\n }),\n }));\n}\n\n/**\n * Sanitizes user-controlled metadata fields in compiled agent data to prevent\n * Liquid template injection. Strips `{{`, `}}`, `{%`, `%}` from agent\n * metadata and skill metadata before template rendering.\n *\n * Content fields (identity, playbook, output, criticalRequirementsTop,\n * criticalReminders) are passed through unchanged — LiquidJS does not\n * re-evaluate template syntax inside variable values, so double-curlies\n * in content (e.g. GitHub Actions `${{ secrets.X }}`) are safe.\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\"),\n ...(data.agent.disallowedTools !== undefined && {\n disallowedTools: sanitizeStringArray(data.agent.disallowedTools, \"agent.disallowedTools\"),\n }),\n ...(data.agent.model !== undefined && {\n model: sanitizeLiquidSyntax(data.agent.model, \"agent.model\"),\n }),\n ...(data.agent.effort !== undefined && {\n effort: sanitizeLiquidSyntax(data.agent.effort, \"agent.effort\"),\n }),\n ...(data.agent.permissionMode !== undefined && {\n permissionMode: sanitizeLiquidSyntax(data.agent.permissionMode, \"agent.permissionMode\"),\n }),\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 identity: data.identity,\n playbook: data.playbook,\n output: data.output,\n criticalRequirementsTop: data.criticalRequirementsTop,\n criticalReminders: data.criticalReminders,\n skills: sanitizedSkills,\n preloadedSkills: sanitizedPreloaded,\n dynamicSkills: sanitizedDynamic,\n preloadedSkillIds: sanitizedPreloadedIds,\n };\n}\n\ntype AgentFiles = Pick<\n CompiledAgentData,\n \"identity\" | \"playbook\" | \"output\" | \"criticalRequirementsTop\" | \"criticalReminders\"\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 identity = await readFile(path.join(agentDir, STANDARD_FILES.IDENTITY_MD));\n const playbook = await readFile(path.join(agentDir, STANDARD_FILES.PLAYBOOK_MD));\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 output = await readFileOptional(path.join(agentDir, STANDARD_FILES.OUTPUT_MD), \"\");\n if (!output) {\n output = await readFileOptional(path.join(categoryDir, STANDARD_FILES.OUTPUT_MD), \"\");\n }\n\n return { identity, playbook, output, criticalRequirementsTop, criticalReminders };\n}\n\nexport function buildAgentTemplateContext(\n name: AgentName,\n agent: AgentConfig,\n files: AgentFiles,\n mapSkill: (skill: Skill) => Skill = (skill) => skill,\n): CompiledAgentData {\n const skills = agent.skills.map(mapSkill);\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 return {\n agent,\n ...files,\n skills,\n preloadedSkills,\n dynamicSkills,\n preloadedSkillIds,\n };\n}\n\n/**\n * Renders the agent template and stamps the result with the provenance marker.\n *\n * Both compile entry points render through here, so there is no path that writes a compiled\n * agent this CLI cannot later recognise as its own — which is what `uninstall` reads back\n * when the configuration naming the agents is gone. The stamp replaces rather than inserts,\n * so a template that emits the marker itself still produces exactly one.\n */\nasync function renderCompiledAgent(engine: Liquid, data: CompiledAgentData): Promise<string> {\n // Boundary cast: liquidjs types renderFile as `Promise<any>` because a template\n // can render to any value. The agent template renders a markdown file, and both\n // callers have declared `Promise<string>` since they were written.\n const rendered = (await engine.renderFile(\"agent\", sanitizeCompiledAgentData(data))) as string;\n return stampProvenanceMarker(rendered, await cliVersion());\n}\n\n/**\n * Compiles a single agent into a rendered Markdown prompt by reading its\n * constituent files (identity, playbook, output, critical requirements/reminders)\n * 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 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 (identity.md, playbook.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 renderCompiledAgent(engine, 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: Partial<Record<AgentName, AgentConfig>>,\n ctx: CompileContext,\n engine: Liquid,\n): Promise<void> {\n const outDir = path.join(ctx.outputDir, STANDARD_DIRS.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 { cause: error },\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: Partial<Record<AgentName, AgentConfig>>,\n ctx: CompileContext,\n): Promise<void> {\n const allSkills = pipe(\n typedValues(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 { cause: error },\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, STANDARD_DIRS.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 { cause: error },\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(\n projectDir,\n CLAUDE_SRC_DIR,\n STANDARD_DIRS.AGENTS,\n path.basename(DIRS.templates),\n );\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, STANDARD_DIRS.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, STANDARD_DIRS.AGENTS));\n await remove(path.join(outputDir, STANDARD_DIRS.SKILLS));\n await remove(path.join(outputDir, STANDARD_DIRS.COMMANDS));\n}\n\n/**\n * D-217: per-skill pluginRef decision. A skill renders as `${id}:${id}` only\n * when it has an explicit non-eject source on its SkillReference — i.e. it was\n * installed from a marketplace. `undefined` source (user-authored local skills\n * with no SkillConfig entry) and `\"eject\"` both fall through to bare id.\n */\nfunction pluginRefFor(skill: Skill): { pluginRef?: PluginSkillRef } {\n if (skill.source === undefined || skill.source === EJECT_SOURCE) return {};\n return { pluginRef: `${skill.id}:${skill.id}` as const };\n}\n\nexport async function compileAgentForPlugin(\n name: AgentName,\n agent: AgentConfig,\n fallbackRoot: string,\n engine: Liquid,\n): Promise<string> {\n verbose(`Compiling agent: ${name}`);\n\n const files = await readAgentFiles(name, agent, fallbackRoot);\n\n // D-217: per-skill pluginRef attachment. Each skill's own `source` decides\n // whether it renders as `${id}:${id}` (plugin-installed) or bare id (ejected).\n // This correctly handles mixed-mode agents where some skills are plugin and\n // others are ejected. Missing `source` (user-authored local skills with no\n // SkillConfig entry) falls through to bare id — the expected case, not a\n // silent fallback.\n const data = buildAgentTemplateContext(name, agent, files, (skill) => ({\n ...skill,\n ...pluginRefFor(skill),\n }));\n\n return renderCompiledAgent(engine, data);\n}\n","import path from \"path\";\nimport { z } from \"zod\";\n\nimport { DEFAULT_PLUGIN_NAME, PROJECT_ROOT } from \"../../consts\";\nimport { readFile } from \"../../utils/fs\";\n\n/**\n * The provenance marker every compiled agent carries: an HTML comment on the first line\n * after the frontmatter, naming the generator, its version, and the fact that the file is\n * rewritten rather than edited.\n *\n * **A body comment, deliberately not a frontmatter field.** Claude Code documents sixteen\n * supported frontmatter keys and says nothing about how it treats an unknown one, so a\n * stricter release could reject every agent this CLI has ever written. The body is free-form\n * by contract, which makes a marker there safe, greppable, versioned, and the do-not-edit\n * notice at the same time.\n *\n * The version is informational — {@link hasProvenanceMarker} matches on the marker's SHAPE,\n * so an agent compiled by any release is recognised by any other. Matching the exact text\n * would sweep only the agents the running version happened to write.\n */\nconst MARKER_OPEN = `<!-- Generated by ${DEFAULT_PLUGIN_NAME} v`;\nconst MARKER_NOTICE = \" — do not edit; compile rewrites this file\";\nconst MARKER_CLOSE = \" -->\";\n\nconst FRONTMATTER_FENCE = \"---\";\n\nconst PACKAGE_JSON_FILE = \"package.json\";\n\n/** The one field the marker needs from this CLI's own manifest. */\nconst ownPackageJsonSchema = z.object({ version: z.string().min(1) });\n\nexport function provenanceMarker(version: string): string {\n return `${MARKER_OPEN}${version}${MARKER_NOTICE}${MARKER_CLOSE}`;\n}\n\n/** Whether a line is a marker this CLI wrote, at any version and under any wording. */\nfunction isProvenanceMarker(line: string): boolean {\n return line.startsWith(MARKER_OPEN) && line.endsWith(MARKER_CLOSE);\n}\n\n/**\n * The index of the first body line: past the closing frontmatter fence when there is one,\n * and the top of the file when there is not — a template override may render no frontmatter,\n * and the marker still needs a defined home.\n */\nfunction bodyStartIndex(lines: readonly string[]): number {\n if (lines[0] !== FRONTMATTER_FENCE) return 0;\n const closingFence = lines.indexOf(FRONTMATTER_FENCE, 1);\n if (closingFence === -1) return 0;\n return closingFence + 1;\n}\n\n/**\n * Whether this CLI compiled the agent file this content came from.\n *\n * The marker's POSITION is part of the claim: an agent that merely quotes the line further\n * down (a prompt about this very feature, say) is the user's, and a sweep reading that as\n * provenance would delete a file nothing here wrote.\n */\nexport function hasProvenanceMarker(content: string): boolean {\n const lines = content.split(\"\\n\");\n const firstBodyLine = lines[bodyStartIndex(lines)];\n return firstBodyLine !== undefined && isProvenanceMarker(firstBodyLine);\n}\n\n/**\n * The same content carrying exactly one provenance marker, on the first line after the\n * frontmatter.\n *\n * Idempotent by replacement rather than by insertion: content that already carries a marker\n * has that line rewritten, so stamping twice at one version is a fixed point and a version\n * bump moves the line instead of stacking a second one beside it.\n */\nexport function stampProvenanceMarker(content: string, version: string): string {\n const lines = content.split(\"\\n\");\n const bodyStart = bodyStartIndex(lines);\n const replacedLines = hasProvenanceMarker(content) ? 1 : 0;\n\n return [\n ...lines.slice(0, bodyStart),\n provenanceMarker(version),\n ...lines.slice(bodyStart + replacedLines),\n ].join(\"\\n\");\n}\n\nlet ownVersion: Promise<string> | undefined;\n\n/**\n * This CLI's own published version, read once per process from the package manifest beside\n * the code — the same `PROJECT_ROOT` the bundled agent partials and templates resolve from,\n * so the version in a marker is the version of the compiler that wrote it.\n */\nexport function cliVersion(): Promise<string> {\n ownVersion ??= readOwnVersion();\n return ownVersion;\n}\n\nasync function readOwnVersion(): Promise<string> {\n const manifestPath = path.join(PROJECT_ROOT, PACKAGE_JSON_FILE);\n const raw: unknown = JSON.parse(await readFile(manifestPath));\n\n const parsed = ownPackageJsonSchema.safeParse(raw);\n if (!parsed.success) {\n throw new Error(`Could not read this CLI's own version from ${manifestPath}`);\n }\n return parsed.data.version;\n}\n","import type { ValidationResult } from \"../types\";\n\n/**\n * A passing validation result with no errors or warnings. A factory rather than a\n * shared constant so each caller owns its arrays — callers merge and prefix results,\n * and a shared instance would let one mutation leak into every other holder.\n */\nexport function validResult(): ValidationResult {\n return { valid: true, errors: [], warnings: [] };\n}\n\n/** A failing validation result carrying a single error message. */\nexport function invalidResult(message: string): ValidationResult {\n return { valid: false, errors: [message], warnings: [] };\n}\n\n/**\n * Flattens several validation partials into one result. `valid` is derived from\n * whether any errors were collected. Generic over the error/warning element type\n * so it can serve any {errors, warnings} partial, string-based ValidationResult\n * included.\n */\nexport function mergeValidationResults<E, W>(\n results: ReadonlyArray<{ errors: E[]; warnings: W[] }>,\n): { valid: boolean; errors: E[]; warnings: W[] } {\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","import os from \"os\";\nimport path from \"path\";\nimport type { Liquid } from \"liquidjs\";\nimport { compileAgentForPlugin } from \"../compiler.js\";\nimport { resolveInstallPaths } from \"../installation/install-base-dir.js\";\nimport { writeFile, fileExists, readFile } from \"../../utils/fs.js\";\nimport { typedEntries } from \"../../utils/typed-object.js\";\nimport type { AgentConfig, AgentName, SkillScope } from \"../../types/index.js\";\n\nexport type AgentWriteOutcome =\n | {\n name: AgentName;\n ok: true;\n scope: SkillScope;\n targetDir: string;\n /**\n * Whether this pass actually wrote the file. False means the compiled output\n * matched what was already on disk, so nothing was written — which is what\n * lets a recompile summary tell a real one from a no-op instead of counting\n * the roster it walked.\n */\n rewritten: boolean;\n }\n | { name: AgentName; ok: false; error: unknown };\n\n/**\n * Whether the target already holds exactly this content, making a write a no-op.\n *\n * Skipping that write is what gives \"unchanged\" a meaning a caller can check: an\n * agent reported unchanged keeps its mtime, and an mtime is the only trace a\n * rewrite-with-identical-bytes leaves anywhere.\n */\nasync function holdsExactly(filePath: string, content: string): Promise<boolean> {\n return (await fileExists(filePath)) && (await readFile(filePath)) === content;\n}\n\n/**\n * Where an agent goes when `agentScopeMap` has nothing to say about it — either because the caller\n * passed no map at all (`agents-inc update` recompiles that way) or because this agent is not in\n * the one it passed (a hand-authored agent under `.claude/agents/` has no config row).\n *\n * This is a ROUTING answer, not a selection default: `\"project\"` here means \"the directory the\n * caller named in `projectAgentsDir`\", which for an unrouted write is the only defensible target.\n * It is deliberately NOT `DEFAULT_SELECTION_OPTIONS.scope` from `@workspace/matrix` — that constant\n * says what an untouched *pick* installs as, and adopting it here would relocate the agents of every\n * caller that never asked for global routing into the user's `~/.claude/agents`.\n */\nconst UNROUTED_AGENT_SCOPE: SkillScope = \"project\";\n\n/**\n * Compiles each resolved agent and writes it to its scope's agents directory:\n * global agents to `~/.claude/agents/`, project agents to `projectAgentsDir`.\n * Per-agent failures are collected as outcomes — callers own the policy\n * (recompile reports and continues; install hard-errors).\n *\n * Neither directory is created up front. `writeFile` makes a target's parent on\n * the way past, so a directory appears exactly when an agent routes into it —\n * which is what keeps a wholly project-scoped pass from leaving an empty\n * `~/.claude/agents/` behind in a home that has no global install.\n */\nexport async function writeCompiledAgentsByScope(params: {\n resolvedAgents: Partial<Record<AgentName, AgentConfig>>;\n sourcePath: string;\n engine: Liquid;\n projectAgentsDir: string;\n agentScopeMap?: Map<AgentName, SkillScope>;\n}): Promise<AgentWriteOutcome[]> {\n const globalAgentsDir = resolveInstallPaths(os.homedir(), \"global\").agentsDir;\n\n const outcomes: AgentWriteOutcome[] = [];\n for (const [name, agent] of typedEntries<AgentName, AgentConfig>(params.resolvedAgents)) {\n try {\n const output = await compileAgentForPlugin(name, agent, params.sourcePath, params.engine);\n const scope = params.agentScopeMap?.get(name) ?? UNROUTED_AGENT_SCOPE;\n const targetDir = scope === \"global\" ? globalAgentsDir : params.projectAgentsDir;\n const targetPath = path.join(targetDir, `${name}.md`);\n const rewritten = !(await holdsExactly(targetPath, output));\n if (rewritten) await writeFile(targetPath, output);\n outcomes.push({ name, ok: true, scope, targetDir, rewritten });\n } catch (error) {\n outcomes.push({ name, ok: false, error });\n }\n }\n return outcomes;\n}\n","import os from \"os\";\nimport path from \"path\";\nimport type { ProjectConfig, SkillId } from \"../../types\";\nimport type { SkillConfig } from \"../../types/config\";\nimport type { AuthoritativeScope } from \"../configuration/config-merger\";\nimport { CLAUDE_SRC_DIR, CLI_INVOKE_COMMAND } from \"../../consts\";\nimport { ensureDir, writeFile } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport { isHomeDirectory } from \"../installation/is-home-directory\";\nimport { getProjectConfigPath } from \"../installation/install-base-dir\";\nimport { loadProjectConfigFromDir } from \"../configuration/project-config\";\nimport { normalizeStackRecord } from \"../stacks/stacks-loader\";\nimport { isActiveAt } from \"../configuration/scope-predicates\";\nimport { splitConfigByScope } from \"../configuration/config-generator\";\nimport { generateConfigSource } from \"../configuration/config-writer\";\nimport {\n regenerateConfigTypes,\n type ConfigTypesExtras,\n} from \"../configuration/config-types-writer\";\nimport {\n classifyGlobalChange,\n consequenceTier,\n tierPropagates,\n tierRegeneratesTypes,\n NO_CHANGES,\n type GlobalChangeSet,\n} from \"./classify.js\";\nimport { resolveGateDeps, type GateDeps, type LoadedGateDeps } from \"./deps.js\";\nimport { GlobalPairWriteViolation, withGateToken } from \"./gate-token.js\";\nimport {\n ensureBlankPair as ensureBlankPairInternal,\n writeGlobalConfigHalf,\n writeGlobalPair,\n writeGlobalTypesHalf,\n} from \"./pair-writer.js\";\nimport {\n buildConfigTypesBackgroundData,\n buildProjectTypesExtras,\n mergeGlobalConfigs,\n normalizeProjectPath,\n propagateGlobalChangesToProjects,\n pruneGlobalEntriesFromRegisteredProjects,\n reconcileProjectSplitAgainstGlobal,\n resolveEffectiveGlobalConfig,\n writeProjectConfigPair,\n type PropagationResult,\n} from \"./propagate.js\";\nimport { NOTHING_RECOMPILED, recompilePropagated } from \"./recompile.js\";\nimport type { PropagatedRecompileSummary } from \"../operations/project/recompile-project-agents.js\";\n\nexport type { GateDeps } from \"./deps.js\";\nexport type { ConsequenceTier, GlobalChangeSet } from \"./classify.js\";\nexport { GlobalPairWriteViolation } from \"./gate-token.js\";\n\n/**\n * What one gated write did, for the caller to render.\n *\n * A write that propagates recompiles the propagated projects' agents itself:\n * both audited gaps in the previous contract (a project-context source\n * migration, a global uninstall) were instances of a caller forgetting to. A\n * report the caller may only log cannot go stale the same way, and per-project\n * failure isolation already lives in `recompilePropagatedProjectAgents`, so\n * internalizing the recompile adds no new failure mode.\n */\nexport type GateReport = {\n /** True when either half of the global pair was actually rewritten. */\n globalWritten: boolean;\n changes: GlobalChangeSet;\n propagated: PropagationResult;\n recompile: PropagatedRecompileSummary;\n};\n\n/**\n * The gate's public entry points are the ONLY code that mints the pair-write\n * privilege, and each one holds it across its whole consequence flow rather than\n * around the individual write (D-309).\n *\n * `pair-writer.ts` used to open the token inside each of its own functions, which\n * meant reaching that module by any route — a dynamic import, a re-export — came\n * with the privilege attached, and the runtime tripwire in `utils/fs.ts` had\n * nothing left to refuse. Moving the mint here inverts that: the private writers\n * REQUIRE a token they cannot produce, so authorization is a property of how the\n * write was ENTERED, which is exactly what the gate is meant to guarantee.\n *\n * The window is wider than the write itself — propagation and the recompile run\n * inside it too. That is accepted: everything in the window is the gate's own\n * code carrying out consequences the same entry already owes.\n *\n * Every entry below that writes or drives a write opens the token with\n * `withGateToken`, including `propagateGlobalRemoval`, which today reaches only\n * project pairs — the rule is \"a gate entry holds the privilege for its flow\",\n * not \"the ones whose current implementation happens to need it\".\n *\n * The one exception is `writeProjectPartial`. It refuses the home directory as its\n * first act and then writes a PROJECT's own config, which the tripwire never\n * guards; handing it the global-pair privilege would only blunt the refusal it\n * exists to make.\n */\n\n/** A write whose classification obliged nothing beyond the global pair. */\nconst NOTHING_PROPAGATED: PropagationResult = { updated: [], skipped: [] };\n\nfunction report(\n globalWritten: boolean,\n changes: GlobalChangeSet,\n propagated: PropagationResult = NOTHING_PROPAGATED,\n recompile: PropagatedRecompileSummary = NOTHING_RECOMPILED,\n): GateReport {\n return { globalWritten, changes, propagated, recompile };\n}\n\n/**\n * Carries out a classified global change's consequences: fan the change out to\n * every registered project, then recompile the ones it rewrote.\n *\n * `currentProjectDir` is excluded from the fan-out — its own pair is written by\n * the call that triggered this, and its agents are compiled by the command.\n */\nasync function applyConsequences(\n globalConfig: ProjectConfig,\n changes: GlobalChangeSet,\n deps: LoadedGateDeps,\n currentProjectDir?: string,\n): Promise<{ propagated: PropagationResult; recompile: PropagatedRecompileSummary }> {\n const tier = consequenceTier(changes);\n if (!tierPropagates(tier) || !globalConfig.projects?.length) {\n return { propagated: NOTHING_PROPAGATED, recompile: NOTHING_RECOMPILED };\n }\n\n const propagated = await propagateGlobalChangesToProjects(\n globalConfig,\n deps.matrix,\n deps.agents,\n currentProjectDir,\n { regenerateTypes: tierRegeneratesTypes(tier) },\n );\n if (propagated.updated.length > 0) {\n verbose(`Propagated global changes to ${propagated.updated.length} project(s)`);\n }\n\n const recompile = tierRegeneratesTypes(tier)\n ? await recompilePropagated(propagated.updated)\n : NOTHING_RECOMPILED;\n\n return { propagated, recompile };\n}\n\n/**\n * Loaders for a caller that holds no matrix of its own. Nothing is fetched\n * unless classification proves the write has consequences that read it, so a\n * registration-only mutation stays offline.\n *\n * `matrixOnly` + `skipExtraSources` are the offline policy the other config\n * readers already use: extra-source loading only annotates wizard UI tagging and\n * never changes the emitted config or types.\n */\nexport function lazyGateDeps(projectDir: string): GateDeps {\n return {\n loadMatrix: async () => {\n const { loadSkillsMatrixFromSource } = await import(\"../loading/source-loader.js\");\n const { matrix } = await loadSkillsMatrixFromSource({\n projectDir,\n skipExtraSources: true,\n matrixOnly: true,\n });\n return matrix;\n },\n loadAgents: async () => {\n const { loadAgentDefs } = await import(\"../operations/project/load-agent-defs.js\");\n return (await loadAgentDefs()).agents;\n },\n };\n}\n\nexport type WizardWriteArgs = {\n finalConfig: ProjectConfig;\n matrix: LoadedGateDeps[\"matrix\"];\n agents: LoadedGateDeps[\"agents\"];\n projectDir: string;\n projectConfigPath: string;\n projectInstallationExists: boolean;\n /**\n * How much of what it can see this session owns, from `mergeConfigs`' own vocabulary.\n *\n * Read by the PROJECT branch only, and only to decide whether the global config is made to\n * MATCH this session or merely absorb it. The home branch writes the whole global config from\n * `finalConfig` either way, and `undefined` (init) keeps the additive default.\n */\n authoritativeScope?: AuthoritativeScope;\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 writeScopedFromWizard(args: WizardWriteArgs): Promise<GateReport> {\n return withGateToken(async () => {\n const { finalConfig, matrix, agents, projectDir, projectConfigPath } = args;\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 deps: LoadedGateDeps = { matrix, agents };\n\n if (!isHomeDirectory(projectDir)) {\n return writeFromProjectContext(args, homeDir, deps);\n }\n\n // Installing from ~/ — write directly to global config (no import preamble)\n const priorGlobal = await loadProjectConfigFromDir(homeDir);\n const changes = classifyGlobalChange(priorGlobal?.config, finalConfig);\n const globalWritten = await writeGlobalPair(finalConfig, projectConfigPath, matrix, agents);\n\n const { propagated, recompile } = await applyConsequences(finalConfig, changes, deps);\n return report(globalWritten, changes, propagated, recompile);\n });\n}\n\nasync function writeFromProjectContext(\n args: WizardWriteArgs,\n homeDir: string,\n deps: LoadedGateDeps,\n): Promise<GateReport> {\n const { finalConfig, matrix, agents, projectDir, projectConfigPath } = args;\n\n // Installing from project — split by scope for project config generation.\n const { global: globalConfig, project: projectSplitConfig } = splitConfigByScope(finalConfig);\n const globalConfigPath = getProjectConfigPath(homeDir);\n\n // Merge new global-scoped items into the existing global config.\n // - Existing items are preserved (never removed from global during project init)\n // - New global items are added\n // - If no existing global config, write the full global split\n const existingGlobal = await loadProjectConfigFromDir(homeDir);\n const effective = await resolveEffectiveGlobalConfig(\n globalConfig,\n existingGlobal?.config,\n projectDir,\n args.authoritativeScope,\n );\n const effectiveGlobalConfig = effective.config;\n\n const changes = classifyGlobalChange(existingGlobal?.config, effectiveGlobalConfig);\n\n let globalWritten = false;\n if (effective.changed) {\n await ensureDir(path.dirname(globalConfigPath));\n globalWritten = await writeGlobalPair(effectiveGlobalConfig, globalConfigPath, matrix, agents);\n verbose(`Updated global config at ${globalConfigPath}`);\n } else {\n verbose(\"Global config unchanged, skipping write\");\n }\n\n const { propagated, recompile } = await applyConsequences(\n effectiveGlobalConfig,\n changes,\n deps,\n projectDir,\n );\n\n // Reconcile the project's own entries against the global config this write inlines.\n // Without it this branch hands the raw split straight to the inlining writer, so a\n // skill/agent the project owns at project scope AND a colliding live global install\n // both land as active entries in the same project config.\n const reconciledProjectConfig = reconcileProjectSplitAgainstGlobal(\n projectSplitConfig,\n effectiveGlobalConfig,\n matrix,\n );\n\n // Write project config if the project installation already exists OR if there are project-scoped items.\n // Skip only when no existing project installation AND no project-scoped items — creating an empty\n // project config with just `import globalConfig` and `{ ...globalConfig }` is pointless.\n const hasProjectItems =\n reconciledProjectConfig.skills.length > 0 || reconciledProjectConfig.agents.length > 0;\n\n if (args.projectInstallationExists || hasProjectItems) {\n await ensureDir(path.dirname(projectConfigPath));\n await writeProjectConfigPair(\n projectDir,\n reconciledProjectConfig,\n effectiveGlobalConfig,\n matrix,\n agents,\n );\n verbose(`Updated project config at ${projectConfigPath}`);\n } else {\n verbose(\n \"Skipped project config — no existing project installation and no project-scoped items\",\n );\n }\n\n return report(globalWritten, changes, propagated, recompile);\n}\n\n/**\n * Regenerates a single scope's config-types.ts from its persisted config,\n * matching the wizard write path exactly (D-228 writer selection):\n * - global scope (home dir): standalone unions narrowed to the config's entries\n * - project scope: import-and-extend form (falls back to standalone when no\n * global config-types.ts exists)\n *\n * Writes no config half at either scope: the config on disk is the input.\n * Returns whether a file was actually rewritten (always false at project scope,\n * where the writer does not report).\n */\nexport async function writeScopeConfigTypes(\n projectDir: string,\n config: ProjectConfig,\n deps: LoadedGateDeps,\n extras?: ConfigTypesExtras,\n): Promise<boolean> {\n return withGateToken(async () => {\n if (isHomeDirectory(projectDir)) {\n return writeGlobalTypesHalf(\n config,\n getProjectConfigPath(projectDir),\n deps.matrix,\n deps.agents,\n extras,\n );\n }\n\n await regenerateConfigTypes(\n projectDir,\n Promise.resolve(buildConfigTypesBackgroundData(deps.matrix, deps.agents)),\n extras ?? buildProjectTypesExtras(config, deps.matrix),\n );\n return false;\n });\n}\n\n/**\n * Regenerates a scope's config-types.ts from the config already on disk, which\n * is the truth and is never rewritten — the documented hand-edit workflow is\n * \"edit config.ts, then compile\", so the file the user edited must survive it.\n *\n * At the home directory the types are the standalone unions narrowed to that\n * config, and the fan-out is UNCONDITIONAL: a hand edit leaves no prior state to\n * diff against, so there is nothing to classify and the only safe assumption is\n * that every registered project's inlined copy is stale. At project and\n * marketplace directories the import-and-extend writer applies and nothing is\n * propagated — a project config is nobody else's input.\n */\nexport async function reconcileTypesFromDisk(\n projectDir: string,\n config: ProjectConfig,\n deps: LoadedGateDeps,\n options?: { extras?: ConfigTypesExtras; currentProjectDir?: string },\n): Promise<GateReport> {\n return withGateToken(async () => {\n const changes = classifyGlobalChange(undefined, config);\n const globalWritten = await writeScopeConfigTypes(projectDir, config, deps, options?.extras);\n\n if (!isHomeDirectory(projectDir)) return report(false, changes);\n if (!config.projects?.length) return report(globalWritten, changes);\n\n const propagated = await propagateGlobalChangesToProjects(\n config,\n deps.matrix,\n deps.agents,\n options?.currentProjectDir,\n );\n if (propagated.updated.length > 0) {\n verbose(`Propagated global changes to ${propagated.updated.length} project(s)`);\n }\n const recompile = await recompilePropagated(propagated.updated);\n\n return report(globalWritten, changes, propagated, recompile);\n });\n}\n\n/**\n * The transforms the gate will apply to the global config on a caller's behalf.\n *\n * A closed union rather than a caller-supplied function: every variant is\n * analysable and testable on its own, and no caller-authored transform runs\n * inside the only code allowed to write the pair.\n */\nexport type GlobalMutation =\n | { kind: \"migrate-skill-sources\"; sources: ReadonlyMap<SkillId, string> }\n | { kind: \"deregister-project\"; projectDir: string }\n | { kind: \"set-source\"; source: string; fallbackName: string };\n\n/** The migrated `origin` for an active-global entry, or the entry unchanged. */\nfunction withMigratedSource(\n skill: SkillConfig,\n migratedSources: ReadonlyMap<SkillId, string>,\n): SkillConfig {\n if (!isActiveAt(skill, \"global\")) return skill;\n const origin = migratedSources.get(skill.id);\n if (origin === undefined || origin === skill.origin) return skill;\n return { ...skill, origin };\n}\n\n/**\n * Rewrites `origin` on exactly the active-global entries listed in `migratedSources`,\n * returning every other entry — including global entries this session did not migrate —\n * identical by reference.\n */\nexport function applyMigratedGlobalSources(\n globalSkills: SkillConfig[],\n migratedSources: ReadonlyMap<SkillId, string>,\n): { skills: SkillConfig[]; changed: boolean } {\n const skills = globalSkills.map((skill) => withMigratedSource(skill, migratedSources));\n return { skills, changed: skills.some((skill, index) => skill !== globalSkills[index]) };\n}\n\n/**\n * The config a partial write commits: the scalars and arrays already on disk,\n * with the required fields filled. Mirrors what the partial writer has always\n * defaulted, so a scalar mutation cannot silently empty an install.\n */\nfunction fillRequiredFields(\n partial: Partial<ProjectConfig>,\n fallbackName: string | undefined,\n): ProjectConfig {\n const name = partial.name ?? fallbackName;\n if (!name) {\n throw new Error(\n `Cannot write config: no project config found. Run \\`${CLI_INVOKE_COMMAND} init\\` first.`,\n );\n }\n return { ...partial, name, skills: partial.skills ?? [], agents: partial.agents ?? [] };\n}\n\n/** Applies a mutation to the config on disk, or null when it is a no-op. */\nfunction applyMutation(\n mutation: GlobalMutation,\n current: Partial<ProjectConfig>,\n): Partial<ProjectConfig> | null {\n switch (mutation.kind) {\n case \"migrate-skill-sources\": {\n const { skills, changed } = applyMigratedGlobalSources(\n current.skills ?? [],\n mutation.sources,\n );\n return changed ? { ...current, skills } : null;\n }\n case \"deregister-project\": {\n const projects = current.projects ?? [];\n if (projects.length === 0) return null;\n const normalized = normalizeProjectPath(mutation.projectDir);\n const filtered = projects.filter((p) => p !== normalized);\n return filtered.length === projects.length ? null : { ...current, projects: filtered };\n }\n case \"set-source\":\n return { ...current, marketplace: mutation.source };\n default: {\n const _exhaustive: never = mutation;\n return _exhaustive;\n }\n }\n}\n\n/** The name a mutation invents when the global config has none yet. */\nfunction fallbackNameFor(mutation: GlobalMutation): string | undefined {\n return mutation.kind === \"set-source\" ? mutation.fallbackName : undefined;\n}\n\n/**\n * Applies a typed transform to the global config and carries out whatever its\n * classification obliges. No variant is exempt from classification by\n * construction: a source change propagates because project configs inline the\n * global scalars, and a deregistration does not because nothing inlines the\n * registration list.\n */\nexport async function mutateGlobal(mutation: GlobalMutation, deps: GateDeps): Promise<GateReport> {\n return withGateToken(async () => {\n const homeDir = os.homedir();\n // The full loader, not the scalar one: it normalizes every stack assignment\n // back to `SkillAssignment[]`. The writer compacts an exclusive category to its\n // bare value on the way out, and re-emitting that bare form without\n // normalization drops the category — so a scalar mutation would silently strip\n // every exclusive category from the global stack.\n const loadedGlobal = await loadProjectConfigFromDir(homeDir);\n if (!loadedGlobal) return report(false, NO_CHANGES);\n\n const current = loadedGlobal.config;\n const mutated = applyMutation(mutation, current);\n if (!mutated) return report(false, NO_CHANGES);\n\n const prior = fillRequiredFields(current, fallbackNameFor(mutation));\n const next = fillRequiredFields(mutated, fallbackNameFor(mutation));\n const changes = classifyGlobalChange(prior, next);\n\n const globalWritten = await writeGlobalConfigHalf(next, getProjectConfigPath(homeDir));\n if (!next.projects?.length) return report(globalWritten, changes);\n\n const loaded = await resolveGateDeps(deps, consequenceTier(changes));\n if (!loaded) return report(globalWritten, changes);\n\n const { propagated, recompile } = await applyConsequences(next, changes, loaded);\n return report(globalWritten, changes, propagated, recompile);\n });\n}\n\n/**\n * Prunes the CLI-inlined global entries from every registered project after a\n * GLOBAL uninstall, and recompiles their agents.\n *\n * Writes no pair: the pair this would derive from has just been deleted. That is\n * the reason this is its own entry rather than a flag on a writing one — the\n * removal case must not be reachable from a code path whose job is to write.\n *\n * Call AFTER the global manifest has been removed so the regenerated project\n * types fall back to the standalone form instead of importing from the\n * now-deleted global config-types.ts.\n */\nexport async function propagateGlobalRemoval(\n preRemovalGlobalConfig: ProjectConfig,\n deps: LoadedGateDeps,\n): Promise<GateReport> {\n return withGateToken(async () => {\n const changes = classifyGlobalChange(preRemovalGlobalConfig, {\n ...preRemovalGlobalConfig,\n skills: [],\n agents: [],\n });\n\n const propagated = await pruneGlobalEntriesFromRegisteredProjects(\n preRemovalGlobalConfig,\n deps.matrix,\n deps.agents,\n );\n const recompile = await recompilePropagated(propagated.updated);\n\n return report(false, changes, propagated, recompile);\n });\n}\n\n/**\n * Creates the blank global pair when none exists. No classification and no\n * fan-out: the registration list propagation reads lives in the file that was\n * just found absent, so a pair created here has no registered projects.\n */\nexport async function ensureBlankPair(): Promise<boolean> {\n return withGateToken(() => ensureBlankPairInternal());\n}\n\nexport type WriteProjectPartialOptions = {\n /** Name to invent when the partial has none. Absent → a missing name is an error. */\n fallbackName?: string;\n};\n\n/**\n * The partial with every stack assignment normalized back to `SkillAssignment[]`.\n *\n * Every caller of this entry reads the config with the LENIENT loader\n * (`loadProjectSourceConfig`), overlays one scalar, and hands the result back.\n * That loader passes the on-disk stack through untouched, and the writer emits an\n * exclusive category in its BARE form (`\"web-framework\": \"web-framework-react\"`,\n * no array) — so on a load / re-emit round trip `compactCategories`, which keeps\n * only non-empty arrays, drops the category and the user silently loses an\n * assignment they never touched (D-308).\n *\n * Normalizing at this boundary rather than inside the writer keeps the fix on the\n * one path that can present a denormalized stack: the full loader\n * (`loadProjectConfigFromDir`) already runs `normalizeStackRecord`, so every other\n * writer input arrives normalized.\n */\nfunction withNormalizedStack(partial: Partial<ProjectConfig>): Partial<ProjectConfig> {\n if (!partial.stack) return partial;\n return { ...partial, stack: normalizeStackRecord(partial.stack) };\n}\n\n/**\n * Writes a partial config to a PROJECT's `.claude-src/config.ts`, filling\n * required defaults. Refuses the home directory: the global pair's config half\n * may never be written without its types sibling and without classification.\n */\nexport async function writeProjectPartial(\n projectDir: string,\n partial: Partial<ProjectConfig>,\n options: WriteProjectPartialOptions = {},\n): Promise<void> {\n if (isHomeDirectory(projectDir)) {\n throw new GlobalPairWriteViolation(getProjectConfigPath(projectDir));\n }\n\n const configPath = getProjectConfigPath(projectDir);\n await ensureDir(path.join(projectDir, CLAUDE_SRC_DIR));\n await writeFile(\n configPath,\n generateConfigSource(fillRequiredFields(withNormalizedStack(partial), options.fallbackName)),\n );\n}\n\n/**\n * `normalizeProjectPath` is the single rule for any value compared against the\n * global config's `projects` array, so a reader that only wants to MATCH a\n * registration (never write one) gets it from here rather than reimplementing\n * `fs.realpathSync` and drifting from the rule the registrations were stored\n * under. It writes nothing, so exporting it hands out no privilege.\n */\nexport { mergeGlobalConfigs, normalizeProjectPath };\n","import os from \"os\";\nimport path from \"path\";\nimport type { Category, ProjectConfig, SkillAssignment } from \"../../types\";\nimport { CLAUDE_SRC_DIR, DEFAULT_PLUGIN_NAME, GLOBAL_CONFIG_NAME } from \"../../consts\";\nimport { isSkillAssignment } from \"../../utils/type-guards\";\nimport { byCategoryDeclarationOrder, matrix } from \"../matrix/matrix-provider\";\nimport { assembleConfigTypesSource, STACK_AGENT_CONFIG_LOOSE_LINE } from \"./config-types-writer\";\n\n/**\n * This module renders config sources; it writes nothing. The partial-config\n * writer and the blank-global-pair creator that used to live here are\n * `writeProjectPartial` and `ensureBlankPair` in `config-gate/`, which is the\n * only code allowed to put either half of the pair on disk.\n */\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 * When provided alongside `isProjectConfig`, inlines global skills/agents directly\n * instead of generating `import globalConfig` and spread syntax.\n * Produces a self-contained, readable config snapshot.\n */\n globalConfig?: ProjectConfig;\n};\n\n/** Fields that are extracted into typed named variables below the export default */\nconst EXTRACTED_FIELDS = new Set([\"skills\", \"agents\", \"stack\", \"selectedDomains\"]);\n\n/**\n * The loader schema's own field order, which is the order a config read back off\n * disk arrives in. Emitting in it is what makes the writer a fixed point: the\n * three producers of an in-memory config — the wizard's literal, a Zod-parsed\n * load, a merge that appends at the tail — insert their keys in three different\n * orders, and without this the same values would emit as three different files.\n */\nconst CANONICAL_FIELD_ORDER = [\n \"name\",\n \"description\",\n \"agents\",\n \"skills\",\n \"author\",\n \"selectedDomains\",\n \"stack\",\n \"marketplace\",\n \"marketplaceName\",\n \"agentsSource\",\n \"projects\",\n] as const satisfies readonly (keyof ProjectConfig)[];\n\nconst CANONICAL_FIELDS = new Set<string>(CANONICAL_FIELD_ORDER);\n\n/**\n * The cleaned record rebuilt in canonical order. A key the schema does not name\n * is passthrough data the writer has no order of its own to impose, so those\n * keep the order they arrived in, after every field the schema does name.\n */\nfunction canonicalizeFieldOrder(cleaned: Record<string, unknown>): Record<string, unknown> {\n const inSchemaOrder: [string, unknown][] = CANONICAL_FIELD_ORDER.filter(\n (key) => key in cleaned,\n ).map((key) => [key, cleaned[key]]);\n const passthrough = Object.entries(cleaned).filter(([key]) => !CANONICAL_FIELDS.has(key));\n\n return Object.fromEntries([...inSchemaOrder, ...passthrough]);\n}\n\n/** A record rebuilt with its keys reordered; the values themselves are untouched. */\nfunction withKeysOrderedBy<T>(\n record: Record<string, T>,\n compareKeys: (a: string, b: string) => number,\n): Record<string, T> {\n return Object.fromEntries(Object.entries(record).sort(([a], [b]) => compareKeys(a, b)));\n}\n\n/**\n * Code-unit order over two names — what a bare `.sort()` gives, and so what\n * `generateProjectConfigFromSkills` already emits its sub-agent keys in.\n * `localeCompare` is deliberately not used: it orders the same two names\n * differently under different locales, which would make the emitted bytes a\n * property of the machine.\n */\nfunction compareNamesInCodeUnitOrder(a: string, b: string): number {\n if (a === b) return 0;\n return a < b ? -1 : 1;\n}\n\n/**\n * The stack's key order, decided by the roster rather than by whoever assembled\n * the stack: sub-agents by name, and each sub-agent's categories in the matrix's\n * declaration order — the two orders the generator already builds a stack in.\n *\n * The generator is not the only producer. The seed decode assembles a stack from\n * a shared payload, in the order that payload lists its skills, so the same\n * curation reached disk as different bytes depending on which end of a share\n * round trip wrote it. That is not merely a noisy diff: a compiled sub-agent\n * lists its dynamic skills in the order its stack entry carries them, so the two\n * ends compiled different files from identical configuration.\n */\nfunction canonicalizeStackOrder(\n stack: Record<string, Record<string, unknown>>,\n): Record<string, Record<string, unknown>> {\n const byDeclaration = byCategoryDeclarationOrder();\n const withCategoriesInOrder = Object.entries(stack).map(\n ([agent, categories]) => [agent, withKeysOrderedBy(categories, byDeclaration)] as const,\n );\n\n return withKeysOrderedBy(Object.fromEntries(withCategoriesInOrder), compareNamesInCodeUnitOrder);\n}\n\n/** One config entry as an indented array-element line. */\nfunction renderEntryLine(entry: unknown): string {\n return ` ${JSON.stringify(entry)},`;\n}\n\n/** One scalar field as an indented object-property line. */\nfunction renderScalarField(key: string, value: unknown): string {\n return ` ${JSON.stringify(key)}: ${JSON.stringify(value)},`;\n}\n\ntype ConfigArrays = {\n skills: unknown[];\n agents: unknown[];\n stack: Record<string, unknown> | undefined;\n selectedDomains: unknown[];\n};\n\n/** The four extracted array/stack fields of a cleaned config, defaulted for emission. */\nfunction extractConfigArrays(cleaned: Record<string, unknown>): ConfigArrays {\n // Boundary cast: cleaned comes from JSON.parse(JSON.stringify(...)) so arrays are plain JSON\n // values. The `??` runs BEFORE the cast on purpose — `cleaned` is a Record of `unknown`, and\n // casting first would tell the checker the value is present when the round-trip drops any key\n // whose value was undefined.\n return {\n skills: (cleaned.skills ?? []) as unknown[],\n agents: (cleaned.agents ?? []) as unknown[],\n stack: cleaned.stack as Record<string, unknown> | undefined,\n selectedDomains: (cleaned.selectedDomains ?? []) as unknown[],\n };\n}\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, selectedDomains) 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 selectedDomains.\n */\n/**\n * Shared pre-emission cleanup: JSON round-trip (drops undefined values), optional\n * `projects` removal (project configs never emit the global tracking list),\n * stack compaction (strip flag-less assignments to bare strings while preserving\n * SkillAssignment[] arrays), and canonical ordering of both the top-level fields\n * and the stack's own keys, so the emitted bytes are decided by the config's\n * values alone.\n */\nfunction cleanForEmission(\n config: ProjectConfig,\n options: { dropProjects: boolean },\n): Record<string, unknown> {\n // Boundary cast: `JSON.parse` is typed `any`, and round-tripping an object always\n // yields one — dropping its undefined-valued keys is exactly why this is here.\n const cleaned = JSON.parse(JSON.stringify(config)) as Record<string, unknown>;\n if (options.dropProjects) {\n delete cleaned.projects;\n }\n if (cleaned.stack) {\n // Boundary cast: cleaned comes from JSON.parse(JSON.stringify(...)), so the stack\n // is a plain JSON record of agent -> category -> assignment arrays\n const compacted = compactStackAssignments(\n cleaned.stack as Record<string, Record<string, unknown[]>>,\n );\n cleaned.stack = canonicalizeStackOrder(compacted);\n }\n return canonicalizeFieldOrder(cleaned);\n}\n\nexport function generateConfigSource(config: ProjectConfig, options?: ConfigSourceOptions): string {\n if (options?.isProjectConfig && options.globalConfig) {\n return generateProjectConfigWithInlinedGlobal(\n cleanForEmission(config, { dropProjects: true }),\n cleanForEmission(options.globalConfig, { dropProjects: true }),\n );\n }\n\n if (options?.isProjectConfig) {\n return generateProjectConfigWithGlobalImport(\n cleanForEmission(config, { dropProjects: true }),\n getGlobalConfigImportPath(),\n );\n }\n\n return generateStandaloneConfig(cleanForEmission(config, { dropProjects: false }));\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 const { skills, agents, stack, selectedDomains } = extractConfigArrays(cleaned);\n\n const hasSkills = skills.length > 0;\n const hasAgents = agents.length > 0;\n const hasStack = stack != null && Object.keys(stack).length > 0;\n const hasSelectedDomains = selectedDomains.length > 0;\n\n // Build type imports based on what's used\n const typeImports = buildTypeImports({\n hasSkills,\n hasAgents,\n hasStack,\n hasSelectedDomains,\n });\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 lines.push(`const skills: SkillConfig[] = [`);\n lines.push(skills.map(renderEntryLine).join(\"\\n\"));\n lines.push(`];`);\n }\n\n if (hasAgents) {\n lines.push(``);\n lines.push(`const agents: AgentScopeConfig[] = [`);\n lines.push(agents.map(renderEntryLine).join(\"\\n\"));\n lines.push(`];`);\n }\n\n if (hasStack) {\n lines.push(``);\n const stackBody = JSON.stringify(stack, null, 2);\n lines.push(`const stack: Partial<Record<ProjectAgentName, StackAgentConfig>> = ${stackBody};`);\n }\n\n if (hasSelectedDomains) {\n lines.push(``);\n const items = selectedDomains.map((d) => JSON.stringify(d)).join(\", \");\n lines.push(`const selectedDomains: Domain[] = [${items}];`);\n }\n\n // Extracted fields reference their named variable (or an empty literal when the\n // variable was not emitted); `stack` is omitted entirely when absent.\n const renderExportField = (key: string, value: unknown): string[] => {\n if (!EXTRACTED_FIELDS.has(key)) return [renderScalarField(key, value)];\n if (key === \"skills\") return [` skills${hasSkills ? \"\" : \": []\"},`];\n if (key === \"agents\") return [` agents${hasAgents ? \"\" : \": []\"},`];\n if (key === \"stack\") return hasStack ? [` stack,`] : [];\n return [` selectedDomains${hasSelectedDomains ? \"\" : \": []\"},`];\n };\n const exportFields = Object.entries(cleaned).flatMap(([key, value]) =>\n renderExportField(key, value),\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 hasSelectedDomains: boolean;\n}): string {\n return [\n flags.hasSelectedDomains && \"Domain\",\n \"ProjectConfig\",\n flags.hasStack && \"ProjectAgentName\",\n flags.hasAgents && \"AgentScopeConfig\",\n flags.hasSkills && \"SkillConfig\",\n flags.hasStack && \"StackAgentConfig\",\n ]\n .filter((t): t is string => Boolean(t))\n .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, selectedDomains) are\n * spread 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 const { skills, agents, stack, selectedDomains } = extractConfigArrays(cleaned);\n\n const hasProjectDomains = selectedDomains.length > 0;\n const hasStack = stack != null && Object.keys(stack).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 hasSelectedDomains: 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 = skills.map(renderEntryLine).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 = agents.map(renderEntryLine).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(stack, null, 2);\n lines.push(`const stack: Partial<Record<ProjectAgentName, StackAgentConfig>> = ${stackBody};`);\n }\n\n // Selected domains variable (only if project has selected domains)\n if (hasProjectDomains) {\n lines.push(``);\n const domainItems = selectedDomains.map(renderEntryLine).join(\"\\n\");\n lines.push(`const selectedDomains: Domain[] = [`);\n lines.push(` ...(globalConfig.selectedDomains ?? []),`);\n if (domainItems) lines.push(domainItems);\n lines.push(`];`);\n }\n\n // Build scalar fields (everything that isn't an extracted field or name)\n const scalarFields = Object.entries(cleaned)\n .filter(([key]) => !EXTRACTED_FIELDS.has(key) && key !== \"name\")\n .map(([key, value]) => renderScalarField(key, value))\n .join(\"\\n\");\n\n // Build export default (table of contents at bottom)\n const exportFields: string[] = [\n ` ...globalConfig,`,\n ` name: ${JSON.stringify(resolveProjectName(cleaned))},`,\n ` skills,`,\n ` agents,`,\n ...(hasStack ? [` stack,`] : []),\n ...(hasProjectDomains ? [` selectedDomains,`] : []),\n ...(scalarFields ? [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/** Project configs never inherit \"global\" as their name from the globalConfig spread. */\nfunction resolveProjectName(cleaned: Record<string, unknown>): unknown {\n return cleaned.name && cleaned.name !== GLOBAL_CONFIG_NAME ? cleaned.name : DEFAULT_PLUGIN_NAME;\n}\n\ntype InlinedGlobalPartition = {\n /** Global entries with active entries replaced by their project tombstones. */\n globalSkills: unknown[];\n globalAgents: unknown[];\n /** Active (non-excluded) project entries. */\n projectSkills: unknown[];\n projectAgents: unknown[];\n /** Project stack filtered to project-scoped agents only. */\n filteredStack: Record<string, unknown> | undefined;\n /** Merged unique global + project values. */\n selectedDomains: unknown[];\n};\n\n/**\n * Pure partition of project + global entries for the inlined snapshot.\n *\n * Excluded globals are routed to the project partition by splitConfigByScope,\n * but render under \"// global\" in the output for readability. When inlining,\n * active global entries are replaced by their excluded tombstones — the\n * tombstone masks the global entry for this project; the active project entry\n * (if any) appears separately in the project section. The project stack keeps\n * only project-scoped agents: global agents' stack entries live in the global\n * config only.\n */\nfunction partitionInlinedConfigEntries(\n cleaned: Record<string, unknown>,\n cleanedGlobal: Record<string, unknown>,\n): InlinedGlobalPartition {\n const project = extractConfigArrays(cleaned);\n const global = extractConfigArrays(cleanedGlobal);\n\n const isExcluded = (entry: unknown): boolean =>\n (entry as { excluded?: boolean }).excluded === true;\n const idOf = (entry: unknown): string => (entry as { id: string }).id;\n const nameOf = (entry: unknown): string => (entry as { name: string }).name;\n\n const excludedGlobalSkills = project.skills.filter(isExcluded);\n const excludedGlobalAgents = project.agents.filter(isExcluded);\n const projectSkills = project.skills.filter((s) => !isExcluded(s));\n const projectAgents = project.agents.filter((a) => !isExcluded(a));\n\n const excludedSkillIds = new Set(excludedGlobalSkills.map(idOf));\n const excludedAgentNames = new Set(excludedGlobalAgents.map(nameOf));\n const globalSkills = [\n ...global.skills.filter((s) => !excludedSkillIds.has(idOf(s))),\n ...excludedGlobalSkills,\n ];\n const globalAgents = [\n ...global.agents.filter((a) => !excludedAgentNames.has(nameOf(a))),\n ...excludedGlobalAgents,\n ];\n\n const projectAgentNames = new Set(projectAgents.map(nameOf));\n const filteredStack: Record<string, unknown> | undefined = project.stack\n ? Object.fromEntries(\n Object.entries(project.stack).filter(([agent]) => projectAgentNames.has(agent)),\n )\n : undefined;\n\n return {\n globalSkills,\n globalAgents,\n projectSkills,\n projectAgents,\n filteredStack,\n selectedDomains: [...new Set([...global.selectedDomains, ...project.selectedDomains])],\n };\n}\n\n/**\n * Every scalar the inlined snapshot emits, as ONE canonically-ordered sequence.\n * The project's value wins where it carries one, and the global supplies the\n * rest. A global block followed by a project block could not promise this: the\n * first emission writes every global scalar into the project's own file, so on\n * the next re-emit those same keys arrive from the project half instead and two\n * blocks would order them differently for values that never changed.\n */\nfunction mergeInlinedScalarFields(\n cleaned: Record<string, unknown>,\n cleanedGlobal: Record<string, unknown>,\n): [string, unknown][] {\n return Object.entries(canonicalizeFieldOrder({ ...cleanedGlobal, ...cleaned })).filter(\n ([key]) => !EXTRACTED_FIELDS.has(key) && key !== \"name\",\n );\n}\n\n/**\n * Generates a project config with global skills/agents inlined directly.\n * No `import globalConfig` — the output is a self-contained readable snapshot.\n * Global items appear first with a `// global` comment, followed by project items\n * with a `// project` comment (only when project items exist).\n */\nfunction generateProjectConfigWithInlinedGlobal(\n cleaned: Record<string, unknown>,\n cleanedGlobal: Record<string, unknown>,\n): string {\n const partition = partitionInlinedConfigEntries(cleaned, cleanedGlobal);\n const { globalSkills, globalAgents, projectSkills, projectAgents, filteredStack } = partition;\n\n const hasGlobalSkills = globalSkills.length > 0;\n const hasProjectSkills = projectSkills.length > 0;\n const hasSkills = hasGlobalSkills || hasProjectSkills;\n\n const hasGlobalAgents = globalAgents.length > 0;\n const hasProjectAgents = projectAgents.length > 0;\n const hasAgents = hasGlobalAgents || hasProjectAgents;\n\n const hasStack = filteredStack != null && Object.keys(filteredStack).length > 0;\n const hasSelectedDomains = partition.selectedDomains.length > 0;\n\n const typeImports = buildTypeImports({\n hasSkills,\n hasAgents,\n hasStack,\n hasSelectedDomains,\n });\n\n const lines: string[] = [`import type { ${typeImports} } from \"./config-types\";`];\n\n // Skills variable\n if (hasSkills) {\n lines.push(``);\n lines.push(`const skills: SkillConfig[] = [`);\n lines.push(\n ...(hasGlobalSkills ? [` // global`, ...globalSkills.map(renderEntryLine)] : []),\n ...(hasProjectSkills ? [` // project`, ...projectSkills.map(renderEntryLine)] : []),\n );\n lines.push(`];`);\n }\n\n // Agents variable\n if (hasAgents) {\n lines.push(``);\n lines.push(`const agents: AgentScopeConfig[] = [`);\n lines.push(\n ...(hasGlobalAgents ? [` // global`, ...globalAgents.map(renderEntryLine)] : []),\n ...(hasProjectAgents ? [` // project`, ...projectAgents.map(renderEntryLine)] : []),\n );\n lines.push(`];`);\n }\n\n // Stack variable (project agents only)\n if (hasStack) {\n lines.push(``);\n const stackBody = JSON.stringify(filteredStack, null, 2);\n lines.push(`const stack: Partial<Record<ProjectAgentName, StackAgentConfig>> = ${stackBody};`);\n }\n\n // Selected domains variable (merged global + project, deduplicated)\n if (hasSelectedDomains) {\n lines.push(``);\n const items = partition.selectedDomains.map((d) => JSON.stringify(d)).join(\", \");\n lines.push(`const selectedDomains: Domain[] = [${items}];`);\n }\n\n const scalarFields = mergeInlinedScalarFields(cleaned, cleanedGlobal);\n\n const exportFields: string[] = [\n ` name: ${JSON.stringify(resolveProjectName(cleaned))},`,\n ...scalarFields.map(([key, value]) => renderScalarField(key, value)),\n hasSkills ? ` skills,` : ` skills: [],`,\n hasAgents ? ` agents,` : ` agents: [],`,\n ...(hasStack ? [` stack,`] : []),\n ...(hasSelectedDomains ? [` selectedDomains,`] : []),\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/** True when the assignment asserts something a bare id could not say on its own. */\nfunction carriesFlags(assignment: SkillAssignment): boolean {\n return Boolean(assignment.preloaded || assignment.local || assignment.path);\n}\n\n/**\n * Compacts one SkillAssignment down to the smallest form that still carries its information.\n * - { id: \"...\" } and { id: \"...\", preloaded: false } → \"...\" (the id says everything)\n * - anything carrying a flag (preloaded, local, path) keeps the object form, flags intact\n */\nfunction compactAssignment(assignment: unknown): unknown {\n if (isSkillAssignment(assignment) && !carriesFlags(assignment)) return assignment.id;\n return assignment;\n}\n\n/**\n * True when the active matrix DECLARES this category as holding at most one skill. Read from the\n * matrix singleton so a source repo's category overrides are honoured. A category the matrix does\n * not declare is deliberately NOT treated as exclusive — the same rule local-installer applies.\n */\nfunction isExclusiveCategory(category: string): boolean {\n // Boundary cast: category keys come from JSON-cleaned config data, not the Category union\n return matrix.categories[category as Category]?.exclusive === true;\n}\n\n/**\n * The emitted value for one category's assignments.\n *\n * An exclusive category can only ever hold one skill, so its array wrapper carries nothing the\n * reader needs and the bare value IS the assignment. Non-exclusive categories keep their array\n * even at length one — there the wrapper is load-bearing, because a second skill may join.\n *\n * Two skills in an exclusive category means the caller built something the config cannot express.\n * Dropping the extra would write a config that does not match what was selected, and nothing\n * downstream could tell, so it fails here instead.\n */\nfunction compactCategoryAssignments(category: string, assignments: unknown[]): unknown {\n const compacted = assignments.map(compactAssignment);\n if (!isExclusiveCategory(category)) return compacted;\n\n if (compacted.length > 1) {\n throw new Error(\n `Category '${category}' is exclusive but holds ${compacted.length} skills: ${JSON.stringify(compacted)}`,\n );\n }\n return compacted[0];\n}\n\nfunction compactCategories(categories: Record<string, unknown[]>): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(categories)\n .filter(([, assignments]) => Array.isArray(assignments) && assignments.length > 0)\n .map(([category, assignments]) => [\n category,\n compactCategoryAssignments(category, assignments),\n ]),\n );\n}\n\nfunction compactStackAssignments(\n stack: Record<string, Record<string, unknown[]>>,\n): Record<string, Record<string, unknown>> {\n return Object.fromEntries(\n Object.entries(stack)\n .map(([agent, categories]) => [agent, compactCategories(categories)] as const)\n .filter(([, categories]) => Object.keys(categories).length > 0),\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_CONFIG_NAME}\",\n \"skills\": [],\n \"agents\": [],\n \"selectedDomains\": []\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 assembleConfigTypesSource({\n skillId: \"never\",\n agentName: \"never\",\n selectedAgentName: \"never\",\n projectAgentName: \"SelectedAgentName\",\n domain: \"never\",\n category: \"never\",\n stackAgentConfig: STACK_AGENT_CONFIG_LOOSE_LINE,\n });\n}\n","import { isDeepEqual } from \"remeda\";\nimport type { AgentName, ProjectConfig, SkillId } from \"../../types\";\nimport type { AgentScopeConfig, SkillConfig } from \"../../types/config\";\n\n/**\n * The work one global config write owes, decided from what actually moved\n * between the config on disk and the config being written.\n *\n * T1 — the generated type unions or the compiled agents are derived from what\n * changed: rewrite both halves of the pair, propagate to every registered\n * project, recompile those projects' agents.\n * T2 — a scalar the unions do not encode changed. Project configs inline the\n * global scalars verbatim, so the config half propagates; no union moves,\n * so no types are regenerated and no agent is recompiled.\n * T3 — only the `projects[]` registration list changed. Nothing is propagated,\n * and the matrix / agent definitions propagation would need are never\n * loaded.\n * T4 — nothing moved. No file is touched.\n */\nexport type ConsequenceTier = \"T1\" | \"T2\" | \"T3\" | \"T4\";\n\nexport type GlobalChangeSet = {\n skills: {\n added: SkillId[];\n removed: SkillId[];\n /**\n * Ids whose `origin` moved — the field's name on `SkillConfig`; this one keeps the\n * older word. Separate from `otherChanged` because the per-skill value decides the\n * reference form a compiled agent emits\n * (`<id>:<id>` for a marketplace-sourced skill, the bare id for an ejected\n * one), so a source change that skipped the recompile leaves every\n * registered project's agents naming a reference that no longer resolves.\n */\n sourceChanged: SkillId[];\n otherChanged: SkillId[];\n };\n agents: {\n added: AgentName[];\n removed: AgentName[];\n changed: AgentName[];\n };\n stackChanged: boolean;\n selectedDomainsChanged: boolean;\n /** Names of the inlined scalar fields that moved, in config key order. */\n scalarsChanged: string[];\n projectsChanged: boolean;\n};\n\n/** The identity element of {@link GlobalChangeSet} — nothing moved, so T4. */\nexport const NO_CHANGES: GlobalChangeSet = {\n skills: { added: [], removed: [], sourceChanged: [], otherChanged: [] },\n agents: { added: [], removed: [], changed: [] },\n stackChanged: false,\n selectedDomainsChanged: false,\n scalarsChanged: [],\n projectsChanged: false,\n};\n\n/** The four fields the config writer extracts into typed named variables. */\nconst EXTRACTED_FIELDS = new Set([\"skills\", \"agents\", \"stack\", \"selectedDomains\"]);\n\n/** The registration list — bookkeeping, never emitted into a project config. */\nconst REGISTRATION_FIELD = \"projects\";\n\n/**\n * Normalizes a config the way the writer does immediately before emission: a\n * JSON round-trip, so an explicitly-`undefined` field and an absent one compare\n * equal. Without it every write that merely reconstructs an object produces\n * phantom diffs.\n */\nfunction normalize(config: ProjectConfig): Record<string, unknown> {\n // Boundary cast: `JSON.parse` is typed `any`, and round-tripping an object\n // always yields one — the whole point of the call is that the result is the\n // same record with its undefined-valued keys gone.\n return JSON.parse(JSON.stringify(config)) as Record<string, unknown>;\n}\n\n/** Field value as the writer would emit it, or undefined when absent. */\nfunction field(config: Record<string, unknown>, key: string): unknown {\n return config[key];\n}\n\nfunction skillsById(config: Record<string, unknown>): Map<SkillId, SkillConfig> {\n const skills = (config.skills ?? []) as SkillConfig[];\n return new Map(skills.map((skill) => [skill.id, skill]));\n}\n\nfunction agentsByName(config: Record<string, unknown>): Map<AgentName, AgentScopeConfig> {\n const agents = (config.agents ?? []) as AgentScopeConfig[];\n return new Map(agents.map((agent) => [agent.name, agent]));\n}\n\n/** The scalar keys either side carries, in `next`-first order with `prev` extras appended. */\nfunction scalarKeys(prev: Record<string, unknown>, next: Record<string, unknown>): string[] {\n const isScalarKey = (key: string): boolean =>\n !EXTRACTED_FIELDS.has(key) && key !== REGISTRATION_FIELD;\n const nextKeys = Object.keys(next).filter(isScalarKey);\n const extraPrevKeys = Object.keys(prev).filter(\n (key) => isScalarKey(key) && !nextKeys.includes(key),\n );\n return [...nextKeys, ...extraPrevKeys];\n}\n\nfunction diffSkills(\n prev: Record<string, unknown>,\n next: Record<string, unknown>,\n): GlobalChangeSet[\"skills\"] {\n const before = skillsById(prev);\n const after = skillsById(next);\n\n const added = [...after.keys()].filter((id) => !before.has(id));\n const removed = [...before.keys()].filter((id) => !after.has(id));\n\n const sourceChanged: SkillId[] = [];\n const otherChanged: SkillId[] = [];\n for (const [id, afterEntry] of after) {\n const beforeEntry = before.get(id);\n if (!beforeEntry || isDeepEqual(beforeEntry, afterEntry)) continue;\n if (beforeEntry.origin !== afterEntry.origin) sourceChanged.push(id);\n else otherChanged.push(id);\n }\n\n return { added, removed, sourceChanged, otherChanged };\n}\n\nfunction diffAgents(\n prev: Record<string, unknown>,\n next: Record<string, unknown>,\n): GlobalChangeSet[\"agents\"] {\n const before = agentsByName(prev);\n const after = agentsByName(next);\n\n return {\n added: [...after.keys()].filter((name) => !before.has(name)),\n removed: [...before.keys()].filter((name) => !after.has(name)),\n changed: [...after.keys()].filter((name) => {\n const beforeEntry = before.get(name);\n return beforeEntry !== undefined && !isDeepEqual(beforeEntry, after.get(name));\n }),\n };\n}\n\n/**\n * Diffs the config on disk against the config about to be written. `prev` is\n * undefined when no global config exists yet, which every field reads as a\n * change from absent.\n */\nexport function classifyGlobalChange(\n prev: ProjectConfig | undefined,\n next: ProjectConfig,\n): GlobalChangeSet {\n const before = prev ? normalize(prev) : {};\n const after = normalize(next);\n\n return {\n skills: diffSkills(before, after),\n agents: diffAgents(before, after),\n stackChanged: !isDeepEqual(field(before, \"stack\"), field(after, \"stack\")),\n selectedDomainsChanged: !isDeepEqual(\n field(before, \"selectedDomains\"),\n field(after, \"selectedDomains\"),\n ),\n scalarsChanged: scalarKeys(before, after).filter(\n (key) => !isDeepEqual(field(before, key), field(after, key)),\n ),\n projectsChanged: !isDeepEqual(\n field(before, REGISTRATION_FIELD),\n field(after, REGISTRATION_FIELD),\n ),\n };\n}\n\n/** True when something the type unions or the compiled agents derive from moved. */\nfunction movesTypesOrCompiledAgents(changes: GlobalChangeSet): boolean {\n const { skills, agents } = changes;\n return (\n skills.added.length > 0 ||\n skills.removed.length > 0 ||\n skills.sourceChanged.length > 0 ||\n skills.otherChanged.length > 0 ||\n agents.added.length > 0 ||\n agents.removed.length > 0 ||\n agents.changed.length > 0 ||\n changes.stackChanged ||\n changes.selectedDomainsChanged\n );\n}\n\n/** The work tier a change set obliges. */\nexport function consequenceTier(changes: GlobalChangeSet): ConsequenceTier {\n if (movesTypesOrCompiledAgents(changes)) return \"T1\";\n if (changes.scalarsChanged.length > 0) return \"T2\";\n if (changes.projectsChanged) return \"T3\";\n return \"T4\";\n}\n\n/** True when the tier's consequences need the matrix and agent definitions. */\nexport function tierNeedsDeps(tier: ConsequenceTier): boolean {\n return tier === \"T1\" || tier === \"T2\";\n}\n\n/** True when the tier regenerates the types half and recompiles propagated agents. */\nexport function tierRegeneratesTypes(tier: ConsequenceTier): boolean {\n return tier === \"T1\";\n}\n\n/** True when the tier fans the change out to every registered project. */\nexport function tierPropagates(tier: ConsequenceTier): boolean {\n return tier === \"T1\" || tier === \"T2\";\n}\n","import type { AgentDefinition, AgentName, MergedSkillsMatrix } from \"../../types\";\nimport { tierNeedsDeps, tierRegeneratesTypes, type ConsequenceTier } from \"./classify.js\";\n\n/** The matrix and agent definitions propagation and type generation read. */\nexport type LoadedGateDeps = {\n matrix: MergedSkillsMatrix;\n agents: Partial<Record<AgentName, AgentDefinition>>;\n};\n\n/**\n * What a gate entry needs to carry out a write's consequences.\n *\n * The lazy form exists so a caller that cannot cheaply produce the matrix — an\n * offline uninstall, a deregistration — hands over loaders instead. Whether they\n * run is decided by classification: a registration-only or no-op write has no\n * consequences to carry out, so nothing is loaded and the write stays offline.\n */\nexport type GateDeps =\n | LoadedGateDeps\n | {\n loadMatrix: () => Promise<MergedSkillsMatrix>;\n loadAgents: () => Promise<Partial<Record<AgentName, AgentDefinition>>>;\n };\n\nfunction isLoaded(deps: GateDeps): deps is LoadedGateDeps {\n return \"matrix\" in deps;\n}\n\n/**\n * Resolves `deps` only when `tier` has consequences that read them. Returns null\n * otherwise, and the lazy loaders are never called.\n */\nexport async function resolveGateDeps(\n deps: GateDeps,\n tier: ConsequenceTier,\n): Promise<LoadedGateDeps | null> {\n if (!tierNeedsDeps(tier)) return null;\n if (isLoaded(deps)) return deps;\n\n // Agent definitions are read only where the types half is regenerated, so a\n // config-half-only tier never pays for loading them.\n const [matrix, agents] = await Promise.all([\n deps.loadMatrix(),\n tierRegeneratesTypes(tier) ? deps.loadAgents() : NO_AGENTS,\n ]);\n return { matrix, agents };\n}\n\n/** Agent definitions a tier that regenerates no types never reads. */\nconst NO_AGENTS: Promise<Partial<Record<AgentName, AgentDefinition>>> = Promise.resolve({});\n","import os from \"os\";\nimport path from \"path\";\nimport type { AgentDefinition, AgentName, MergedSkillsMatrix, ProjectConfig } from \"../../types\";\nimport { CLAUDE_SRC_DIR, STANDARD_FILES } from \"../../consts\";\nimport { ensureDir, fileExists, readFile, writeFile } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport { typedKeys } from \"../../utils/typed-object\";\nimport {\n generateBlankGlobalConfigSource,\n generateBlankGlobalConfigTypesSource,\n generateConfigSource,\n} from \"../configuration/config-writer\";\nimport {\n generateConfigTypesSource,\n type ConfigTypesBackgroundData,\n type ConfigTypesExtras,\n} from \"../configuration/config-types-writer\";\nimport { assertGateToken } from \"./gate-token.js\";\n\n/**\n * Nothing in this module MINTS the write privilege — every function below\n * REQUIRES it, and `writeIfChanged` is where that requirement is asserted. The\n * token is opened by the gate's public entry points in `index.ts`, each of which\n * wraps its whole consequence flow.\n *\n * That split is the point (D-309): a callee that opens the privilege on its own\n * behalf hands it to whoever reached it, so a caller that got past module\n * privacy — a dynamic import, a re-export added for convenience — arrived\n * already authorized and the runtime tripwire in `utils/fs.ts` waved it through.\n * Requiring the token instead makes reaching the private writer useless on its\n * own: the privilege belongs to the entry points, not to the writers.\n */\n\n/** Absolute paths of the two halves of the global config pair. */\nexport type GlobalPairPaths = {\n configPath: string;\n typesPath: string;\n};\n\n/**\n * Resolves the global pair's paths. `os.homedir()` at call time, not the\n * module-load-time `GLOBAL_INSTALL_ROOT`, so the paths agree with every other\n * runtime home-dir reader and with test home mocks.\n */\nexport function globalPairPaths(): GlobalPairPaths {\n const dir = path.join(os.homedir(), CLAUDE_SRC_DIR);\n return {\n configPath: path.join(dir, STANDARD_FILES.CONFIG_TS),\n typesPath: path.join(dir, STANDARD_FILES.CONFIG_TYPES_TS),\n };\n}\n\n/** The types sibling of a config path — the two always share a directory. */\nexport function typesPathFor(configPath: string): string {\n return path.join(path.dirname(configPath), STANDARD_FILES.CONFIG_TYPES_TS);\n}\n\n/**\n * Writes `source` to `filePath` unless the file already holds exactly those\n * bytes. Both halves are derived from the same config on every write, so pair\n * coherence holds by derivation and the comparison only suppresses the mtime\n * churn a projects-only or scalar-only change would otherwise inflict on every\n * consumer watching these files. Returns true when the file was written.\n */\nasync function writeIfChanged(filePath: string, source: string): Promise<boolean> {\n assertGateToken(filePath);\n if ((await fileExists(filePath)) && (await readFile(filePath)) === source) return false;\n await writeFile(filePath, source);\n return true;\n}\n\n/** The union inputs the types writer derives its literals from. */\nfunction typesDataFor(\n matrix: MergedSkillsMatrix,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n): ConfigTypesBackgroundData {\n const agentNames = typedKeys(agents);\n return {\n matrix,\n agentNames,\n customAgentNames: agentNames.filter((name) => agents[name]?.custom === true),\n };\n}\n\n/**\n * Standalone (non-importing) type unions narrowed to `config`'s own entries,\n * widened by `extras` — the literals a just-created skill or agent needs before\n * it reaches the config.\n */\nfunction renderStandaloneTypes(\n config: ProjectConfig,\n matrix: MergedSkillsMatrix,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n extras?: ConfigTypesExtras,\n): string {\n const data = typesDataFor(matrix, agents);\n return generateConfigTypesSource(\n data.matrix,\n data.agentNames,\n data.customAgentNames,\n extras,\n config,\n );\n}\n\n/**\n * Writes the config half of the pair at `configPath`. The global config never\n * takes the project writer's import/inline options — it is the file those\n * options resolve against.\n */\nexport async function writeGlobalConfigHalf(\n config: ProjectConfig,\n configPath: string,\n): Promise<boolean> {\n return writeIfChanged(configPath, generateConfigSource(config));\n}\n\n/** Writes the types half of the pair beside `configPath`. */\nexport async function writeGlobalTypesHalf(\n config: ProjectConfig,\n configPath: string,\n matrix: MergedSkillsMatrix,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n extras?: ConfigTypesExtras,\n): Promise<boolean> {\n return writeIfChanged(\n typesPathFor(configPath),\n renderStandaloneTypes(config, matrix, agents, extras),\n );\n}\n\n/** Writes both halves from one config, so they cannot disagree. */\nexport async function writeGlobalPair(\n config: ProjectConfig,\n configPath: string,\n matrix: MergedSkillsMatrix,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n): Promise<boolean> {\n const configWritten = await writeIfChanged(configPath, generateConfigSource(config));\n const typesWritten = await writeIfChanged(\n typesPathFor(configPath),\n renderStandaloneTypes(config, matrix, agents),\n );\n return configWritten || typesWritten;\n}\n\n/**\n * Creates a blank global pair at `~/.claude-src/` when none exists: `config.ts`\n * with empty arrays and `config-types.ts` with `never` unions. Returns true when\n * the files were created, false when they already existed.\n */\nexport async function ensureBlankPair(): Promise<boolean> {\n const { configPath, typesPath } = globalPairPaths();\n\n if (await fileExists(configPath)) {\n verbose(\"Global config already exists, skipping blank creation\");\n return false;\n }\n\n await ensureDir(path.dirname(configPath));\n\n await writeIfChanged(configPath, generateBlankGlobalConfigSource());\n await writeIfChanged(typesPath, generateBlankGlobalConfigTypesSource());\n\n verbose(`Created blank global config at ${path.dirname(configPath)}`);\n return true;\n}\n","import fs from \"fs\";\nimport os from \"os\";\nimport { isDeepEqual, unique } from \"remeda\";\nimport type {\n AgentDefinition,\n AgentName,\n Category,\n MergedSkillsMatrix,\n ProjectConfig,\n SkillAssignment,\n SkillId,\n StackAgentConfig,\n} from \"../../types\";\nimport type { AgentScopeConfig, SkillConfig } from \"../../types/config\";\nimport { getProjectConfigPath } from \"../installation/install-base-dir\";\nimport { loadProjectConfigFromDir } from \"../configuration/project-config\";\nimport { mergeConfigs, type AuthoritativeScope } from \"../configuration/config-merger\";\nimport {\n activeProjectAgentNames,\n isActiveAt,\n isGlobalTombstone,\n type ScopedEntry,\n} from \"../configuration/scope-predicates\";\nimport { generateConfigSource, type ConfigSourceOptions } from \"../configuration/config-writer\";\nimport {\n type ConfigTypesBackgroundData,\n type ConfigTypesExtras,\n deriveCategories,\n deriveDomains,\n regenerateConfigTypes,\n} from \"../configuration/config-types-writer\";\nimport { fileExists, writeFile } from \"../../utils/fs\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { verbose } from \"../../utils/logger\";\nimport { typedEntries, typedKeys } from \"../../utils/typed-object\";\nimport { GLOBAL_CONFIG_NAME, LOCAL_PSEUDO_CATEGORY } from \"../../consts\";\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\n/**\n * Deep-additive stack merge: appends any (agent, category, skill) triple present in\n * `incoming` but missing in `existing`. Never removes or overwrites existing entries\n * (including their `preloaded` flags). Returns a fresh stack object — inputs are not\n * mutated. `changed` is true iff at least one new agent, category, or skill assignment\n * was appended.\n */\nfunction additiveMergeStack(\n existing: Partial<Record<AgentName, StackAgentConfig>> | undefined,\n incoming: Partial<Record<AgentName, StackAgentConfig>> | undefined,\n): { stack: Partial<Record<AgentName, StackAgentConfig>>; changed: boolean } {\n const merged: Partial<Record<AgentName, StackAgentConfig>> = existing\n ? structuredClone(existing)\n : {};\n if (!incoming) return { stack: merged, changed: false };\n\n let changed = false;\n for (const [agentName, incomingAgentStack] of typedEntries<AgentName, StackAgentConfig>(\n incoming,\n )) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n if (!incomingAgentStack) continue;\n\n const existingAgentStack = merged[agentName];\n if (!existingAgentStack) {\n merged[agentName] = structuredClone(incomingAgentStack);\n changed = true;\n continue;\n }\n\n if (mergeAgentCategories(existingAgentStack, incomingAgentStack)) {\n changed = true;\n }\n }\n\n return { stack: merged, changed };\n}\n\n/**\n * Mutates `existingAgentStack` in place by appending any category or skill assignment\n * from `incomingAgentStack` that is not already present. Returns true if anything was\n * appended. Caller must pass a cloned `existingAgentStack` — this function is only\n * called on the merged copy, never on the original input.\n */\nfunction mergeAgentCategories(\n existingAgentStack: StackAgentConfig,\n incomingAgentStack: StackAgentConfig,\n): boolean {\n let changed = false;\n for (const [category, incomingAssignments] of typedEntries<Category, SkillAssignment[]>(\n incomingAgentStack,\n )) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n if (!incomingAssignments) continue;\n\n const existingAssignments = existingAgentStack[category];\n if (!existingAssignments) {\n existingAgentStack[category] = incomingAssignments.map((a) => ({ ...a }));\n changed = true;\n continue;\n }\n\n const existingIds = new Set(existingAssignments.map((a) => a.id));\n for (const assignment of incomingAssignments) {\n if (!existingIds.has(assignment.id)) {\n existingAssignments.push({ ...assignment });\n existingIds.add(assignment.id);\n changed = true;\n }\n }\n }\n return changed;\n}\n\n/**\n * Merges new global-scoped items into an existing global config.\n * Adds skills/agents that don't already exist. Never removes existing items.\n *\n * Exported for unit testing. See `mergeGlobalConfigs` describe block in\n * `local-installer.test.ts`.\n */\nexport function mergeGlobalConfigs(\n existing: ProjectConfig,\n incoming: ProjectConfig,\n): { config: ProjectConfig; changed: boolean } {\n const existingSkillIds = new Set(existing.skills.map((s) => s.id));\n const existingAgentNames = new Set(existing.agents.map((a) => a.name));\n\n const incomingActiveSkills = incoming.skills.filter((s) => !s.excluded);\n const incomingActiveAgents = incoming.agents.filter((a) => !a.excluded);\n const newSkills = incomingActiveSkills.filter((s) => !existingSkillIds.has(s.id));\n const newAgents = incomingActiveAgents.filter((a) => !existingAgentNames.has(a.name));\n\n const mergedSkills = [...existing.skills, ...newSkills];\n const mergedAgents = [...existing.agents, ...newAgents];\n\n // Per-agent stack merge policy: deep-additive. Project-context edits must NEVER remove\n // or overwrite global state; individual projects express their local view via tombstones\n // in the PROJECT config, not by rewriting the GLOBAL config (see commit 403df46:\n // \"never modify global config from project-level operations\").\n //\n // Merge rule per triple (agent, category, skill):\n // - agent absent in existing -> add from incoming\n // - category absent in existing -> add from incoming\n // - skill id absent in existing -> append from incoming\n // - everything already present -> keep existing as-is (including its preloaded flag)\n // Anything present only in `existing` is left untouched.\n const { stack: mergedStack, changed: stackChanged } = additiveMergeStack(\n existing.stack,\n incoming.stack,\n );\n\n // Merge selected domains (union, no duplicates)\n const mergedSelectedDomains = [\n ...new Set([...(existing.selectedDomains ?? []), ...(incoming.selectedDomains ?? [])]),\n ];\n\n // Marketplace identity (`marketplace`, `marketplaceName`) travels on the global partition of\n // `splitConfigByScope` but was previously lost here, leaving the global config with no\n // record of where its plugins came from. `uninstall` reads `config.marketplaceName` to build\n // the `<id>@<marketplace name>` registry key (getCliInstalledPluginKeys) — without it a global\n // uninstall silently owns nothing and leaves registered plugins behind.\n //\n // Precedence is FILL-ONLY: existing wins, incoming is used solely when the global config\n // has no value yet. Both fields are scalar but the merged config is multi-marketplace by\n // construction — this merge never removes skills, so after a second project init from a\n // different marketplace the skills array holds plugins from BOTH, and whichever label is\n // recorded orphans the other's registry key. Repointing is therefore never a strict\n // improvement, and doing it from a project context would silently rewrite global state on\n // behalf of every other registered project (commit 403df46). This also matches\n // `mergeConfigs`, which preserves `existingConfig.marketplaceName` on the home-root install\n // path. Changing global marketplace identity stays an explicit global-scope operation\n // (`init` run from ~), which writes the global config directly and bypasses this merge.\n const mergedMarketplaceName = existing.marketplaceName ?? incoming.marketplaceName;\n const mergedMarketplace = existing.marketplace ?? incoming.marketplace;\n\n // Newly-filled marketplace identity must mark the merge dirty: this flag becomes\n // `resolveEffectiveGlobalConfig`'s `changed`, which is the condition `writeFromProjectContext`\n // (lib/config-gate/index.ts) tests before calling `writeGlobalPair`, so a run whose only delta\n // is the now-known marketplace would otherwise skip the global write and drop the field again.\n const changed =\n newSkills.length > 0 ||\n newAgents.length > 0 ||\n stackChanged ||\n !isDeepEqual(existing.selectedDomains ?? [], mergedSelectedDomains) ||\n mergedMarketplaceName !== existing.marketplaceName ||\n mergedMarketplace !== existing.marketplace;\n\n return {\n config: {\n ...existing,\n skills: mergedSkills,\n agents: mergedAgents,\n stack: mergedStack,\n selectedDomains: mergedSelectedDomains,\n ...(mergedMarketplaceName !== undefined && { marketplaceName: mergedMarketplaceName }),\n ...(mergedMarketplace !== undefined && { marketplace: mergedMarketplace }),\n },\n changed,\n };\n}\n\n/**\n * The single normalization for every value compared against the global config's\n * `projects` array — the one written by {@link registerProjectPath}, the one\n * filtered by {@link deregisterProjectPath}, and the current-project skip in\n * {@link propagateGlobalChangesToProjects}. Symlinks are resolved, so an entry\n * stored under one of them matches byte-for-byte under the others. The two ends\n * normalizing differently is what left symlinked layouts (macOS `/tmp`, a\n * `~/dev/repo` pointing at `/data/repo`) registered forever after an uninstall.\n *\n * Throws when the directory does not exist. That is deliberate: a path that\n * cannot be resolved is an error, not a cue to fall back to a weaker\n * normalization — a second tier would reintroduce exactly the asymmetry this\n * helper exists to remove. The one caller that must survive it (`uninstall`'s\n * deregistration) already wraps the call in a warn-and-continue guard.\n */\nexport function normalizeProjectPath(projectDir: string): string {\n return fs.realpathSync(projectDir);\n}\n\n/**\n * Registers a project directory in the global config's `projects` array.\n * Paths are normalized via {@link normalizeProjectPath} to resolve symlinks.\n * Filters stale entries (where .claude-src/config.ts no longer exists).\n */\nasync function registerProjectPath(\n globalConfig: ProjectConfig,\n projectDir: string,\n): Promise<{ config: ProjectConfig; changed: boolean }> {\n const normalizedPath = normalizeProjectPath(projectDir);\n const existing = globalConfig.projects ?? [];\n\n // Filter stale entries\n const staleChecks = await Promise.all(\n existing.map(async (p) => ({\n path: p,\n hasConfig: await fileExists(getProjectConfigPath(p)),\n })),\n );\n const valid = staleChecks.filter((c) => c.hasConfig).map((c) => c.path);\n\n if (valid.includes(normalizedPath)) {\n const changed = valid.length !== existing.length;\n return { config: changed ? { ...globalConfig, projects: valid } : globalConfig, changed };\n }\n\n return { config: { ...globalConfig, projects: [...valid, normalizedPath] }, changed: true };\n}\n\n/**\n * Removes a project directory from the global config's `projects` array.\n * Loads global config, removes the path, and writes back if changed.\n * Paths are normalized via {@link normalizeProjectPath} — the same rule\n * {@link registerProjectPath} stored them under, so the filter matches.\n *\n * REQUIRES the gate's write token; it does not mint one (D-309). No production\n * path reaches this — `mutateGlobal`'s `deregister-project` variant replaced it\n * at the only call site — so there is no entry point to move the mint up to, and\n * private code opening the privilege for its own caller is exactly what D-309\n * closed. Its remaining callers are specs, which take the token explicitly the\n * same way they do to seed a global-pair fixture.\n */\nexport async function deregisterProjectPath(projectDir: string): Promise<void> {\n const homeDir = os.homedir();\n const existingGlobal = await loadProjectConfigFromDir(homeDir);\n if (!existingGlobal?.config.projects?.length) return;\n\n const normalizedPath = normalizeProjectPath(projectDir);\n const filtered = existingGlobal.config.projects.filter((p) => p !== normalizedPath);\n\n if (filtered.length === existingGlobal.config.projects.length) return;\n\n const updatedConfig = { ...existingGlobal.config, projects: filtered };\n const globalConfigPath = getProjectConfigPath(homeDir);\n // The one write in this module that targets the global pair rather than a\n // project's, so the one the caller's token has to cover. Config half only: the\n // registration list is not inlined anywhere, so the types sibling would come\n // out byte-identical.\n await writeConfigFile(updatedConfig, globalConfigPath);\n verbose(`Deregistered project ${normalizedPath} from global config`);\n}\n\nfunction isProjectScopedEntry(entry: ScopedEntry): boolean {\n return entry.scope === \"project\";\n}\n\n/** True when the global config still has an active (non-excluded) skill for this id. */\nfunction globalHasActiveSkill(globalConfig: ProjectConfig, id: SkillId): boolean {\n return globalConfig.skills.some((s) => s.id === id && isActiveAt(s, \"global\"));\n}\n\n/** True when the global config still has an active (non-excluded) agent for this name. */\nfunction globalHasActiveAgent(globalConfig: ProjectConfig, name: AgentName): boolean {\n return globalConfig.agents.some((a) => a.name === name && isActiveAt(a, \"global\"));\n}\n\n/**\n * Keeps a project's own skill entries when re-inlining fresh global data, dropping\n * tombstones that no longer correspond to a real global install.\n *\n * A tombstone (`scope === \"global\" && excluded`) only has meaning while the global entry\n * it masks still exists. Once the skill has been removed from the global config, the\n * tombstone is stale — carrying it forward would leave the project showing a masked\n * global item that no longer exists. Project-scoped entries are always retained.\n */\nfunction retainProjectOwnedSkills(\n skills: SkillConfig[],\n globalConfig: ProjectConfig,\n): SkillConfig[] {\n return skills.filter(\n (entry) =>\n isProjectScopedEntry(entry) ||\n (isGlobalTombstone(entry) && globalHasActiveSkill(globalConfig, entry.id)),\n );\n}\n\n/** Agent mirror of {@link retainProjectOwnedSkills}. */\nfunction retainProjectOwnedAgents(\n agents: AgentScopeConfig[],\n globalConfig: ProjectConfig,\n): AgentScopeConfig[] {\n return agents.filter(\n (entry) =>\n isProjectScopedEntry(entry) ||\n (isGlobalTombstone(entry) && globalHasActiveAgent(globalConfig, entry.name)),\n );\n}\n\n/**\n * Category a skill belongs to according to the MERGED matrix. `undefined` when the\n * matrix has no entry for the id (a user-authored local skill carries no matrix\n * record) or when the entry sits in the `local` pseudo-category — neither\n * participates in category rules, and neither may throw.\n */\nfunction categoryOfSkill(id: SkillId, matrix: MergedSkillsMatrix): Category | undefined {\n const category = matrix.skills[id]?.category;\n if (category === undefined || category === LOCAL_PSEUDO_CATEGORY) return undefined;\n return category;\n}\n\n/**\n * True when the merged matrix DECLARES this category as holding at most one skill.\n * Read from the matrix passed in rather than `defaultCategories` so a source repo's\n * category overrides are honoured.\n *\n * A category the matrix does not declare is deliberately NOT treated as exclusive.\n * The wizard's toggle handler defaults an undeclared one to exclusive\n * (`use-build-step-props.ts` uses `matrix.categories[categoryId]?.exclusive ?? true`),\n * but a rule that MASKS persisted entries must only fire on a flag the data\n * actually carries.\n */\nfunction isExclusiveCategory(category: Category, matrix: MergedSkillsMatrix): boolean {\n return matrix.categories[category]?.exclusive === true;\n}\n\n/** Categories occupied by an active project-scoped skill, per the merged matrix. */\nfunction activeProjectCategories(\n projectOwnedSkills: SkillConfig[],\n matrix: MergedSkillsMatrix,\n): Set<Category> {\n return new Set(\n projectOwnedSkills\n .filter((s) => isActiveAt(s, \"project\"))\n .map((s) => categoryOfSkill(s.id, matrix))\n .filter((category): category is Category => category !== undefined),\n );\n}\n\n/**\n * The collision that justifies masking a live global skill. Two kinds, both read from the\n * project's OWN entries: IDENTITY — the project owns the same id at project scope; CATEGORY —\n * the project owns a different active skill in the same category and the matrix declares that\n * category exclusive.\n *\n * Shared by the mask producer ({@link maskCollidingGlobalSkills}) and the self-heal that\n * removes a mask once its collision clears ({@link dropOrphanedDerivedMasks}), so the two can\n * never disagree about what a mask means.\n */\nfunction buildProjectCollisionTest(\n projectOwnedSkills: SkillConfig[],\n matrix: MergedSkillsMatrix,\n): (id: SkillId) => boolean {\n const ownedIds = new Set(\n projectOwnedSkills.filter((s) => isActiveAt(s, \"project\")).map((s) => s.id),\n );\n const occupiedExclusiveCategories = new Set(\n [...activeProjectCategories(projectOwnedSkills, matrix)].filter((category) =>\n isExclusiveCategory(category, matrix),\n ),\n );\n\n return (id) => {\n if (ownedIds.has(id)) return true;\n const category = categoryOfSkill(id, matrix);\n return category !== undefined && occupiedExclusiveCategories.has(category);\n };\n}\n\n/**\n * Drops a derived mask that no longer masks anything, so the global install becomes\n * visible again once the collision that produced it is gone.\n *\n * A derived mask and a user-authored tombstone are BYTE-IDENTICAL in config.ts — both are\n * `{ id, scope: \"global\", excluded: true }` — but since D-277 the wizard can no longer mint\n * the second kind on its own: a project-scope deselect of a globally-installed skill is\n * refused, and a domain deselect only drops what the project owns. The one user route to a\n * global tombstone is the `s` scope toggle (G→P), which always pairs the tombstone with an\n * active project entry for the same id — an IDENTITY collision. So every bare mask is\n * machine-derived, and a single retention test suffices: keep it iff the collision that\n * would re-derive it is still there, in `required` and optional categories alike.\n */\nfunction dropOrphanedDerivedMasks(\n projectOwnedSkills: SkillConfig[],\n matrix: MergedSkillsMatrix,\n): SkillConfig[] {\n const collidesWithProjectOwnership = buildProjectCollisionTest(projectOwnedSkills, matrix);\n return projectOwnedSkills.filter(\n (entry) => !isGlobalTombstone(entry) || collidesWithProjectOwnership(entry.id),\n );\n}\n\n/**\n * Agent mirror of {@link dropOrphanedDerivedMasks}, identity collisions only (D-277): agents\n * have no categories, so the project-scoped sibling with the same name is the only thing a\n * mask can be justified by.\n */\nfunction dropOrphanedDerivedAgentMasks(projectOwnedAgents: AgentScopeConfig[]): AgentScopeConfig[] {\n const ownedNames = new Set(activeProjectAgentNames(projectOwnedAgents));\n return projectOwnedAgents.filter(\n (entry) => !isGlobalTombstone(entry) || ownedNames.has(entry.name),\n );\n}\n\n/**\n * Builds the tombstones that mask live global skills this project cannot show\n * alongside what it already owns at project scope. Two collision kinds, both keyed\n * against the SAME live global config:\n *\n * 1. IDENTITY — the project owns the same id at project scope (D-268). Without the\n * mask, `partitionInlinedConfigEntries` re-inlines the global copy as a SECOND\n * active entry, leaving one id active at BOTH scopes instead of rendering the\n * dual-scope `[P][G]` pair.\n * 2. CATEGORY — the project owns a DIFFERENT active skill in the same category and\n * the matrix declares that category exclusive. Reconciliation keyed on identity\n * alone cannot see this, so a project owning Vue plus a global install of React\n * ends up with two active skills in a category that permits one.\n *\n * The project-owned skill wins locally. This is DELIBERATELY ASYMMETRIC with D-260,\n * where a user-initiated radio swap in `toggleTechnology` refuses to displace a\n * globally-locked skill: there the user is actively trying to drop a shared install,\n * whereas here the collision is PUSHED IN by a global install landing on pre-existing\n * project state. Letting global win would silently uninstall the user's own skill.\n *\n * Tombstones are spread from the global entry so they carry the global install's\n * `origin`. A skill the project merely inherits (no active project-scope entry, no\n * exclusive-category collision) is skipped — it stays a single active global entry.\n * A skill the project already tombstones is skipped so re-running is idempotent.\n */\nfunction maskCollidingGlobalSkills(\n projectOwnedSkills: SkillConfig[],\n globalConfig: ProjectConfig,\n matrix: MergedSkillsMatrix,\n): SkillConfig[] {\n const collidesWithProjectOwnership = buildProjectCollisionTest(projectOwnedSkills, matrix);\n const alreadyTombstoned = new Set(projectOwnedSkills.filter(isGlobalTombstone).map((s) => s.id));\n\n return globalConfig.skills\n .filter(\n (globalEntry) =>\n isActiveAt(globalEntry, \"global\") &&\n collidesWithProjectOwnership(globalEntry.id) &&\n !alreadyTombstoned.has(globalEntry.id),\n )\n .map((globalEntry) => ({ ...globalEntry, excluded: true }));\n}\n\n/**\n * Agent mirror of {@link maskCollidingGlobalSkills}, identity collisions only (D-259).\n * Agents have no categories, so there is no grouping dimension to reconcile.\n */\nfunction maskCollidingGlobalAgents(\n projectOwnedAgents: AgentScopeConfig[],\n globalConfig: ProjectConfig,\n): AgentScopeConfig[] {\n const ownedNames = new Set(activeProjectAgentNames(projectOwnedAgents));\n const alreadyTombstoned = new Set(\n projectOwnedAgents.filter(isGlobalTombstone).map((a) => a.name),\n );\n\n return globalConfig.agents\n .filter(\n (globalEntry) =>\n isActiveAt(globalEntry, \"global\") &&\n ownedNames.has(globalEntry.name) &&\n !alreadyTombstoned.has(globalEntry.name),\n )\n .map((globalEntry) => ({ ...globalEntry, excluded: true }));\n}\n\n/**\n * Reconciles a project's OWN entries against the live global config, immediately\n * before the inlining writer merges the two.\n *\n * Applied at BOTH sites that write a project `config.ts` with `globalConfig` inlined:\n * `propagateGlobalChangesToProjects` (a global change fanning out to registered\n * projects) and the project-scope save branch of `writeScopedFromWizard` (an ordinary\n * project `init`/`edit` performed while the colliding skill is already active\n * globally). Either site alone can produce the malformed shape, so both must run it.\n *\n * Self-heal runs BEFORE masking on BOTH axes so a mask whose collision has cleared is\n * removed rather than immediately re-derived, and so masking's `alreadyTombstoned` guard\n * only sees tombstones that are still warranted.\n *\n * Masking is PROJECT-LOCAL: it is applied to the project split only. The global\n * config passed in is read, never rewritten — tombstones never belong in\n * `~/.claude-src/config.ts`.\n */\nexport function reconcileProjectSplitAgainstGlobal(\n projectSplit: ProjectConfig,\n globalConfig: ProjectConfig,\n matrix: MergedSkillsMatrix,\n): ProjectConfig {\n const healedSkills = dropOrphanedDerivedMasks(projectSplit.skills, matrix);\n const healedAgents = dropOrphanedDerivedAgentMasks(projectSplit.agents);\n return {\n ...projectSplit,\n skills: [...healedSkills, ...maskCollidingGlobalSkills(healedSkills, globalConfig, matrix)],\n agents: [...healedAgents, ...maskCollidingGlobalAgents(healedAgents, globalConfig)],\n };\n}\n\n/**\n * Computes the skill ids that this project inherited from global scope but that are\n * no longer active at global scope after the change being propagated — and that the\n * project does not own at project scope. These are the only ids that should be pruned\n * from the project's stack: a project-scoped agent may legitimately reference a\n * globally-installed skill, and once that skill is removed at global scope the\n * reference becomes dangling.\n *\n * `priorProjectSkills` is the project's pre-reconciliation (on-disk, inlined) skills.\n * A global skill that was just removed still appears here as a `scope: \"global\"`,\n * non-excluded entry, which is the signal we key on. Project-scoped skills and\n * user-authored local skills (which carry no SkillConfig entry at all) are never in\n * this set, so they are always preserved.\n */\nfunction computeRemovedGlobalSkillIds(\n priorProjectSkills: SkillConfig[],\n globalConfig: ProjectConfig,\n): Set<SkillId> {\n const activeGlobalIds = new Set(\n globalConfig.skills.filter((s) => isActiveAt(s, \"global\")).map((s) => s.id),\n );\n const projectOwnedIds = new Set(\n priorProjectSkills.filter((s) => isActiveAt(s, \"project\")).map((s) => s.id),\n );\n return new Set(\n priorProjectSkills\n .filter(\n (s) =>\n s.scope === \"global\" &&\n !s.excluded &&\n !activeGlobalIds.has(s.id) &&\n !projectOwnedIds.has(s.id),\n )\n .map((s) => s.id),\n );\n}\n\n/**\n * Prunes stack references to global skills that were just removed at global scope,\n * so a project-scoped agent stops referencing a skill that no longer exists anywhere.\n * Only ids in `removedGlobalSkillIds` are dropped — every other assignment is kept\n * verbatim, in order, with its `preloaded` flag untouched. Categories and agents left\n * empty by the pruning are removed. When nothing was removed, the stack is returned\n * unchanged so unaffected projects produce byte-identical config output.\n */\nfunction retainReconciledStack(\n stack: Record<string, StackAgentConfig> | undefined,\n removedGlobalSkillIds: Set<SkillId>,\n): Record<string, StackAgentConfig> | undefined {\n if (!stack || removedGlobalSkillIds.size === 0) return stack;\n\n const reconciled: Record<string, StackAgentConfig> = {};\n for (const [agent, agentStack] of Object.entries(stack)) {\n const reconciledAgentStack: StackAgentConfig = {};\n for (const [category, assignments] of typedEntries<Category, SkillAssignment[]>(agentStack)) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n if (!assignments) continue;\n const kept = assignments.filter((assignment) => !removedGlobalSkillIds.has(assignment.id));\n if (kept.length > 0) reconciledAgentStack[category] = kept;\n }\n if (typedKeys<Category>(reconciledAgentStack).length > 0) {\n reconciled[agent] = reconciledAgentStack;\n }\n }\n return reconciled;\n}\n\n/** The registered projects one fan-out rewrote, and the ones it could not reach. */\nexport type PropagationResult = {\n updated: string[];\n skipped: string[];\n};\n\nexport type PropagationOptions = {\n /**\n * Whether each project's config-types.ts is rewritten alongside its config.ts.\n * False for a change that moves no type union — a project inlines the global\n * scalars into its config half, but no union is derived from them.\n */\n regenerateTypes?: boolean;\n};\n\n/**\n * The single writer for a project's config pair, used by BOTH sites that emit\n * one: the per-project propagation step below and the project branch of the\n * wizard write.\n *\n * `buildProjectTypesExtras` is fed the EFFECTIVE config — the project's own\n * reconciled rows plus the active global rows the writer is about to inline —\n * at both sites. The emitted config.ts names every one of those rows, so extras\n * derived from the project split alone declare fewer literals than the sibling\n * config.ts uses, and the pair stops type-checking against itself.\n */\nexport async function writeProjectConfigPair(\n projectDir: string,\n reconciledSplit: ProjectConfig,\n effectiveGlobal: ProjectConfig,\n matrix: MergedSkillsMatrix,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n options: PropagationOptions = {},\n): Promise<void> {\n // Reconcile-before-both-writes: the two halves are derived from the same\n // reconciled data in the same call, so neither can describe a config the other\n // does not.\n await writeConfigFile(reconciledSplit, getProjectConfigPath(projectDir), {\n isProjectConfig: true,\n globalConfig: effectiveGlobal,\n });\n\n if (options.regenerateTypes === false) return;\n\n // Uses the same global-aware path for project types — emits\n // `import type { SkillId as GlobalSkillId, ... }` and extends with any\n // project-scoped items the project owns. Without this, a global-scope install\n // would overwrite the project's import-form types with the standalone/inlined\n // form (D-216 Regression #1 / D-228).\n await regenerateConfigTypes(\n projectDir,\n Promise.resolve(buildConfigTypesBackgroundData(matrix, agents)),\n buildProjectTypesExtras(inlinedProjectView(reconciledSplit, effectiveGlobal), matrix),\n );\n}\n\n/**\n * The rows the inlining writer draws a project's config.ts from: the project's\n * own reconciled entries plus everything the global config contributes. Union\n * membership is decided downstream by `buildProjectTypesExtras`, which reads the\n * active entries — a tombstone's id always arrives via the live global row it\n * masks.\n */\nfunction inlinedProjectView(\n reconciledSplit: ProjectConfig,\n effectiveGlobal: ProjectConfig,\n): ProjectConfig {\n return {\n ...reconciledSplit,\n skills: [...effectiveGlobal.skills, ...reconciledSplit.skills],\n agents: [...effectiveGlobal.agents, ...reconciledSplit.agents],\n selectedDomains: unique([\n ...(effectiveGlobal.selectedDomains ?? []),\n ...(reconciledSplit.selectedDomains ?? []),\n ]),\n stack: { ...(effectiveGlobal.stack ?? {}), ...(reconciledSplit.stack ?? {}) },\n };\n}\n\n/**\n * Propagates global config changes to all registered project configs.\n * Updates each project's config-types.ts (type unions) and config.ts (inlined global data).\n * Skips stale project paths and the current project being installed.\n */\nexport async function propagateGlobalChangesToProjects(\n globalConfig: ProjectConfig,\n matrix: MergedSkillsMatrix,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n currentProjectDir?: string,\n options: PropagationOptions = {},\n): Promise<PropagationResult> {\n const projects = globalConfig.projects ?? [];\n if (projects.length === 0) return { updated: [], skipped: [] };\n\n const currentNormalized = currentProjectDir ? normalizeProjectPath(currentProjectDir) : null;\n const updated: string[] = [];\n const skipped: string[] = [];\n\n for (const projectPath of projects) {\n // Skip the project currently being installed (it's already being written)\n if (currentNormalized && projectPath === currentNormalized) continue;\n\n const projectConfigPath = getProjectConfigPath(projectPath);\n if (!(await fileExists(projectConfigPath))) {\n skipped.push(projectPath);\n verbose(`Skipped propagation to ${projectPath} (config not found)`);\n continue;\n }\n\n try {\n const existingProject = await loadProjectConfigFromDir(projectPath);\n if (!existingProject?.config) {\n skipped.push(projectPath);\n continue;\n }\n\n const projectConfig = existingProject.config;\n\n // Derive project split: project-scoped entries plus tombstones that still\n // correspond to a live global install. Tombstones whose global entry has been\n // removed are dropped here so the project stops referencing a global item that\n // no longer exists (D-233 Scenario C). The stack is reconciled against the same\n // now-current global data so a project-scoped agent stops referencing a global\n // skill that was just removed at global scope. `projectConfig.skills` (pre-\n // reconciliation) is used to detect removed globals because the removed entry\n // is still present here as a `scope: \"global\"` reference.\n const removedGlobalSkillIds = computeRemovedGlobalSkillIds(\n projectConfig.skills,\n globalConfig,\n );\n const retained = retainReconciledStack(projectConfig.stack, removedGlobalSkillIds);\n const reconciledStack = retained === undefined ? {} : { stack: retained };\n const projectSplit = reconcileProjectSplitAgainstGlobal(\n {\n ...projectConfig,\n skills: retainProjectOwnedSkills(projectConfig.skills, globalConfig),\n agents: retainProjectOwnedAgents(projectConfig.agents, globalConfig),\n ...reconciledStack,\n },\n globalConfig,\n matrix,\n );\n\n await writeProjectConfigPair(projectPath, projectSplit, globalConfig, matrix, agents, {\n regenerateTypes: options.regenerateTypes ?? true,\n });\n\n updated.push(projectPath);\n verbose(`Propagated global changes to ${projectPath}`);\n } catch (error) {\n skipped.push(projectPath);\n verbose(`Failed to propagate to ${projectPath}: ${getErrorMessage(error)}`);\n }\n }\n\n return { updated, skipped };\n}\n\n/**\n * Prunes CLI-inlined global-scoped entries from every registered project after a\n * GLOBAL uninstall. Reuses {@link propagateGlobalChangesToProjects} with an\n * emptied global config so every global skill/agent reads as removed: project-\n * scoped entries are retained verbatim, inlined global rows and tombstones are\n * dropped, per-agent stack refs lose their global-only ids, and each project's\n * config-types.ts is regenerated.\n *\n * Call AFTER the global .claude-src manifest has been removed so the regenerated\n * project types fall back to the standalone form instead of importing from the\n * now-deleted global config-types.ts. Unreachable project dirs are reported in\n * `skipped`, never thrown.\n */\nexport async function pruneGlobalEntriesFromRegisteredProjects(\n globalConfig: ProjectConfig,\n matrix: MergedSkillsMatrix,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n): Promise<{ updated: string[]; skipped: string[] }> {\n const emptiedGlobal: ProjectConfig = {\n ...globalConfig,\n skills: [],\n agents: [],\n };\n return propagateGlobalChangesToProjects(emptiedGlobal, matrix, agents);\n}\n\n/** What one resolution decided: the config to commit, and the two flags that gate the write. */\ntype ResolvedGlobalConfig = { config: ProjectConfig; changed: boolean };\n\n/**\n * Resolves the global config a project install should write, and registers this project's path.\n * `globalDataChanged` gates propagation; `changed` gates the write itself.\n *\n * `authority` is `mergeConfigs`' own word for how much of what it can see the session owns, and\n * it selects between the two resolutions below. Absent, or `\"owned\"`, keeps the standing\n * additive behaviour.\n */\nexport async function resolveEffectiveGlobalConfig(\n globalSplit: ProjectConfig,\n existingGlobalConfig: ProjectConfig | undefined,\n projectDir: string,\n authority?: AuthoritativeScope,\n): Promise<{ config: ProjectConfig; globalDataChanged: boolean; changed: boolean }> {\n const merged =\n authority === \"all\"\n ? matchGlobalToSession(globalSplit, existingGlobalConfig)\n : addSessionToGlobal(globalSplit, existingGlobalConfig);\n\n const registration = await registerProjectPath(merged.config, projectDir);\n return {\n config: registration.config,\n globalDataChanged: merged.changed,\n changed: merged.changed || registration.changed,\n };\n}\n\n/**\n * The standing resolution, and the one every caller but `edit --from` gets: the session's global\n * items are ADDED and nothing is taken away.\n *\n * A project install has asked nobody about the machine, so it may not decide for it (commit\n * 403df46, \"never modify global config from project-level operations\"). The `hasGlobalItems`\n * shortcut is part of that: a session carrying nothing global is not a statement that the global\n * install should be empty.\n */\nfunction addSessionToGlobal(\n globalSplit: ProjectConfig,\n existingGlobalConfig: ProjectConfig | undefined,\n): ResolvedGlobalConfig {\n const hasGlobalItems = globalSplit.skills.length > 0 || globalSplit.agents.length > 0;\n if (!hasGlobalItems) {\n return {\n config: existingGlobalConfig ?? { name: GLOBAL_CONFIG_NAME, skills: [], agents: [] },\n changed: false,\n };\n }\n\n if (!existingGlobalConfig) return { config: globalSplit, changed: true };\n return mergeGlobalConfigs(existingGlobalConfig, globalSplit);\n}\n\n/**\n * The resolution for a session that owns every scope it can see: the global config is made to\n * MATCH it, so a global entry the session left out is REMOVED rather than preserved.\n *\n * One caller reaches this — a confirmed `edit --from` — and it is not acting on its own\n * initiative: it states a whole roster, its plan showed every global removal under its own\n * heading, named every other registered project the removal reaches, and somebody answered yes.\n * Nothing else in the CLI may write the global config from a project, and this does not widen\n * that: the word arrives from the command, not from the shape of the data.\n *\n * `mergeConfigs` is what does it rather than a merge of this module's own, because \"absent from\n * the session means deselected\" is exactly what `authoritativeScope: \"all\"` already means at the\n * home root. It carries the global installation's identity, its stack fallback and its\n * `projects[]` registry across — a session's split says nothing about who the global\n * installation is or which projects read it, and the fan-out walks that registry.\n *\n * An empty session is a real answer here, so there is no `hasGlobalItems` shortcut: a\n * configuration that installs nothing globally removes what was.\n */\nfunction matchGlobalToSession(\n globalSplit: ProjectConfig,\n existingGlobalConfig: ProjectConfig | undefined,\n): ResolvedGlobalConfig {\n if (!existingGlobalConfig) return { config: globalSplit, changed: true };\n\n const config = mergeConfigs(globalSplit, existingGlobalConfig, { authoritativeScope: \"all\" });\n return { config, changed: !isDeepEqual(config, existingGlobalConfig) };\n}\n\nexport function buildConfigTypesBackgroundData(\n matrix: MergedSkillsMatrix,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n): ConfigTypesBackgroundData {\n const agentNames = typedKeys(agents);\n const customAgentNames = agentNames.filter((name) => agents[name]?.custom === true);\n return { matrix, agentNames, customAgentNames };\n}\n\n/** Category keys the emitted stack holds, across every agent it configures. */\nfunction stackCategories(stack: ProjectConfig[\"stack\"]): Category[] {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n return Object.values(stack ?? {}).flatMap((agentStack) => typedKeys<Category>(agentStack ?? {}));\n}\n\n/**\n * Derives the extras for regenerateConfigTypes so a project's config-types.ts declares every\n * literal its sibling config.ts holds — the two are written from the same config and must not\n * be able to disagree.\n *\n * ALL active (non-excluded) entries, not just project-scoped ones:\n * generateProjectConfigWithInlinedGlobal writes the active global rows into the project's own\n * config.ts verbatim, and the imported Global* unions cover those rows only for as long as the\n * global config still happens to contain them. A later global-scope run narrows those unions\n * and a project nobody touched stops type-checking (TS2322 on a skill id or domain, TS2353 on a\n * stack's category key).\n *\n * Domains and stack categories are read off the config's own arrays as well as derived from its\n * skill rows: `selectedDomains` is a wizard preference no skill row has to back, and neither it\n * nor a stack entry is pruned when the last skill that would derive it leaves.\n */\nexport function buildProjectTypesExtras(\n finalConfig: ProjectConfig,\n matrix: MergedSkillsMatrix,\n): Required<ConfigTypesExtras> {\n const activeSkills = finalConfig.skills.filter((s) => !s.excluded);\n const activeAgents = finalConfig.agents.filter((a) => !a.excluded);\n\n const extraSkillIds = unique(activeSkills.map((s) => s.id));\n const extraAgentNames = unique(activeAgents.map((a) => a.name));\n\n const extraCategories = unique([\n ...deriveCategories(extraSkillIds, matrix),\n ...stackCategories(finalConfig.stack),\n ]);\n const extraDomains = unique([\n ...deriveDomains(extraCategories, matrix),\n ...(finalConfig.selectedDomains ?? []),\n ]);\n\n return { extraSkillIds, extraAgentNames, extraDomains, extraCategories };\n}\n","import type { PropagatedRecompileSummary } from \"../operations/project/recompile-project-agents.js\";\n\n/** The summary of a fan-out that recompiled nothing, so callers render one shape. */\nexport const NOTHING_RECOMPILED: PropagatedRecompileSummary = {\n rewrittenCount: 0,\n unchangedCount: 0,\n failedCount: 0,\n warnings: [],\n};\n\n/**\n * Recompiles the agents of every project a global write propagated into.\n *\n * Imported lazily: `recompile-project-agents` lives in the operations layer,\n * which imports back into `installation`, so a static import here would form a\n * load-time cycle (same rule as `installEject`'s `copyLocalSkills` import).\n * Per-project failure isolation lives in `recompilePropagatedProjectAgents` and\n * is unchanged by running it from inside the write.\n */\nexport async function recompilePropagated(\n projectDirs: string[],\n): Promise<PropagatedRecompileSummary> {\n if (projectDirs.length === 0) return NOTHING_RECOMPILED;\n\n const { recompilePropagatedProjectAgents } =\n await import(\"../operations/project/recompile-project-agents.js\");\n return recompilePropagatedProjectAgents(projectDirs);\n}\n","import { spawn } from \"child_process\";\nimport { z } from \"zod\";\nimport os from \"os\";\nimport type { ClaudePluginScope } from \"../types/config\";\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 must not be empty.\");\n }\n\n if (source.length > MAX_MARKETPLACE_SOURCE_LENGTH) {\n throw new Error(\n `Marketplace 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 contains invalid control characters.\");\n }\n\n if (!SAFE_PLUGIN_PATH_PATTERN.test(source)) {\n throw new Error(\n `Marketplace contains invalid characters: \"${source}\"\\n` +\n \"Marketplaces 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: Buffer) => {\n stdout += data.toString();\n });\n\n proc.stderr.on(\"data\", (data: Buffer) => {\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: ClaudePluginScope, projectDir: string): string {\n return scope === \"user\" ? os.homedir() : projectDir;\n}\n\n/**\n * Which Claude installation a `claude plugin` call reads and writes.\n *\n * Omitted, the call inherits the one its process already points at — the user's\n * own, in production. `configDir` redirects the entire config tree: the\n * marketplace registry, the installed-plugin registry and user settings all move\n * with it. It is how a test drives the Claude CLI without touching the machine\n * running it.\n */\nexport type ClaudeConfigOptions = { configDir?: string };\n\n/**\n * The `execCommand` options fragment that pins the config dir — empty when there\n * is none, so the call inherits its process's environment untouched.\n *\n * `CLAUDE_CONFIG_DIR` takes precedence over `HOME` in the Claude CLI, so passing\n * it also overrides an exported one rather than merely competing with it.\n */\nfunction configDirEnv(options: ClaudeConfigOptions | undefined): { env?: NodeJS.ProcessEnv } {\n if (options?.configDir === undefined) return {};\n return { env: { CLAUDE_CONFIG_DIR: options.configDir } };\n}\n\nexport async function claudePluginInstall(\n pluginPath: string,\n scope: ClaudePluginScope,\n projectDir: string,\n options?: ClaudeConfigOptions,\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, ...configDirEnv(options) });\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\nconst marketplaceInfoListSchema: z.ZodType<MarketplaceInfo[]> = z.array(\n z.object({\n name: z.string(),\n source: z.string(),\n repo: z.string().exactOptional(),\n path: z.string().exactOptional(),\n }),\n);\n\nexport async function claudePluginMarketplaceList(\n options?: ClaudeConfigOptions,\n): Promise<MarketplaceInfo[]> {\n try {\n const result = await execCommand(\n \"claude\",\n [\"plugin\", \"marketplace\", \"list\", \"--json\"],\n configDirEnv(options),\n );\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 const listResult = marketplaceInfoListSchema.safeParse(parsed);\n if (!listResult.success) {\n warn(\"Unexpected marketplace list format — expected an array of marketplace entries\");\n return [];\n }\n\n return listResult.data;\n } catch {\n return [];\n }\n}\n\nexport async function claudePluginMarketplaceExists(\n name: string,\n options?: ClaudeConfigOptions,\n): Promise<boolean> {\n const marketplaces = await claudePluginMarketplaceList(options);\n return marketplaces.some((m) => m.name === name);\n}\n\nexport async function claudePluginMarketplaceAdd(\n source: string,\n options?: ClaudeConfigOptions,\n): Promise<void> {\n validateMarketplaceSource(source);\n\n const args = [\"plugin\", \"marketplace\", \"add\", source];\n let result;\n try {\n result = await execCommand(\"claude\", args, configDirEnv(options));\n } catch (err) {\n throw new Error(`Failed to add marketplace: ${getErrorMessage(err)}`, { cause: 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 claudePluginMarketplaceRemove(\n name: string,\n options?: ClaudeConfigOptions,\n): Promise<void> {\n validatePluginName(name);\n\n const args = [\"plugin\", \"marketplace\", \"remove\", name];\n let result;\n try {\n result = await execCommand(\"claude\", args, configDirEnv(options));\n } catch (err) {\n throw new Error(`Failed to remove marketplace: ${getErrorMessage(err)}`, { cause: err });\n }\n\n if (result.exitCode !== 0) {\n const errorMessage = result.stderr || result.stdout || \"Unknown error\";\n if (errorMessage.includes(\"not found\") || errorMessage.includes(\"not installed\")) {\n return;\n }\n throw new Error(`Failed to remove marketplace: ${errorMessage.trim()}`);\n }\n}\n\nexport async function claudePluginMarketplaceUpdate(\n name: string,\n options?: ClaudeConfigOptions,\n): Promise<void> {\n validatePluginName(name);\n\n const args = [\"plugin\", \"marketplace\", \"update\", name];\n let result;\n try {\n result = await execCommand(\"claude\", args, configDirEnv(options));\n } catch (err) {\n throw new Error(`Failed to update marketplace: ${getErrorMessage(err)}`, { cause: err });\n }\n\n if (result.exitCode !== 0) {\n const errorMessage = result.stderr || result.stdout || \"Unknown error\";\n throw new Error(`Failed to update marketplace: ${errorMessage.trim()}`);\n }\n}\n\nexport async function claudePluginUninstall(\n pluginName: string,\n scope: ClaudePluginScope,\n projectDir: string,\n options?: ClaudeConfigOptions,\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, ...configDirEnv(options) });\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\n/**\n * Best-effort plugin uninstall that tries both scopes.\n *\n * Use when the plugin's actual registered scope is ambiguous — e.g., a skill\n * was re-scoped after install, or we're cleaning up on uninstall and the config\n * scope may not match the registry entry. Tries the primary scope first, then\n * the fallback, silently swallowing errors from each attempt.\n *\n * The plugin reference must be qualified (e.g., `skill-id@marketplace`), matching\n * the form used at install time — bare skill IDs will not match the registry.\n */\nexport async function claudePluginUninstallBestEffort(\n pluginRef: string,\n primaryScope: ClaudePluginScope,\n projectDir: string,\n options?: ClaudeConfigOptions,\n): Promise<void> {\n const fallbackScope = primaryScope === \"project\" ? \"user\" : \"project\";\n try {\n await claudePluginUninstall(pluginRef, primaryScope, projectDir, options);\n } catch {\n // Best-effort: plugin may not be registered with primary scope\n }\n try {\n await claudePluginUninstall(pluginRef, fallbackScope, projectDir, options);\n } catch {\n // Best-effort: plugin may not be registered with fallback scope either\n }\n}\n","import type { SkillId } from \"../../types\";\nimport type { SkillConfig, SkillScope } from \"../../types/config\";\nimport type { SourceLoadResult } from \"../loading\";\n// Type-only, so no module edge is created: the operations layer imports back into\n// this one, and the shape a plugin install reports is defined where installs live.\nimport type { PluginInstallResult } from \"../operations/skills/install-plugin-skills\";\nimport { deleteLocalSkill, copySkillsToLocalFlattened } from \"../skills\";\nimport { claudePluginInstall, claudePluginUninstall } from \"../../utils/exec\";\nimport { buildMarketplacePluginRef, toClaudePluginScope } from \"../plugins/plugin-ref\";\nimport { installBaseDir, resolveInstallPaths } from \"./install-base-dir\";\nimport { verbose } from \"../../utils/logger\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { CLI_INVOKE_COMMAND, EJECT_SOURCE } from \"../../consts\";\n\nexport type SkillMigration = {\n id: SkillId;\n oldSource: string;\n newSource: string;\n oldScope: SkillScope;\n newScope: SkillScope;\n};\n\nexport type MigrationPlan = {\n toEject: SkillMigration[];\n toPlugin: SkillMigration[];\n scopeChanges: SkillMigration[];\n};\n\n/**\n * What the plugin→eject half copied, in the shape {@link PluginInstallResult} reports the\n * opposite direction, so one command surface reports both and neither can drift into a\n * private idea of what a failure looks like.\n *\n * A non-empty `failed` means this run could NOT honor the user's eject intent for those\n * skills, so the caller MUST hard-error before writing any config — otherwise config.ts\n * records `origin: \"eject\"` for a skill that has no local copy. The asymmetry this\n * replaces is what let that ship: the plugin half returned its failures structurally\n * while the eject half turned them into a warning string nobody could act on.\n */\nexport type EjectCopyResult = {\n copied: SkillId[];\n failed: Array<{ id: SkillId; error: string }>;\n};\n\nexport type MigrationResult = {\n ejectCopies: EjectCopyResult;\n /**\n * What the eject→plugin half installed, in the shape a fresh install returns, so\n * one command surface reports both. The refs are built here because this is where\n * each migration's own scope and marketplace are already resolved.\n *\n * A non-empty `failed` means this run could NOT honor the user's plugin intent for\n * those skills, so the caller MUST hard-error before writing any config — otherwise\n * config.ts records a marketplace `origin` for a skill that has no plugin\n * registration.\n */\n pluginInstalls: PluginInstallResult;\n warnings: string[];\n};\n\n/**\n * Hard-error message for failed eject copies — the twin of `pluginInstallFailureError` in\n * `operations/skills/install-plugin-skills.ts`, worded from the same rule: an install intent\n * this run could not honor must stop the run BEFORE any config records it.\n */\nexport function ejectCopyFailureError(failedCount: number): string {\n return `Failed to copy ${failedCount} skill(s) for eject. Eject intent could not be honored. Check that the destination skills directory is writable, then run '${CLI_INVOKE_COMMAND} edit' again — or switch the affected skills back to plugin mode.`;\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 toEject: 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.origin,\n newSource: newSkill.origin,\n oldScope: oldSkill.scope,\n newScope: newSkill.scope,\n };\n\n const wasEject = oldSkill.origin === EJECT_SOURCE;\n const isEject = newSkill.origin === EJECT_SOURCE;\n\n if (wasEject && !isEject) {\n toPlugin.push(migration);\n } else if (!wasEject && isEject) {\n toEject.push(migration);\n }\n\n // Detect scope changes (independent of source changes)\n if (oldSkill.scope !== newSkill.scope && wasEject === isEject) {\n scopeChanges.push(migration);\n }\n }\n\n return { toEject, 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 pluginInstalls: PluginInstallResult = { installed: [], failed: [] };\n\n const ejectCopies = await copyMigratedSkillsToLocal(plan.toEject, projectDir, sourceResult);\n // Only the skills whose copy LANDED, which is the toPlugin rule below read the other way\n // round. Dropping the plugin registration of a skill that has no local copy would leave it\n // installed nowhere, so a working install must survive a failed migration exactly as the\n // ejected working copy survives a failed plugin install.\n const warnings = await uninstallMigratedPlugins(\n migrationsWhoseCopyLanded(plan.toEject, ejectCopies),\n projectDir,\n sourceResult,\n );\n\n // Migrate skills from eject to plugin\n if (plan.toPlugin.length > 0) {\n // Plugin install intent is inviolable: without a marketplace NO migration in\n // this list can be installed, so fail before anything is deleted. Deleting\n // first and downgrading to a warning destroys the user's editable working\n // copy and leaves config entries claiming a plugin that was never installed.\n if (!sourceResult.marketplace) {\n throw new Error(\n `Cannot install skills as plugins: marketplace could not be resolved from ` +\n `'${sourceResult.sourceConfig.source}'. Plugin install mode requires a marketplace — ` +\n `fix the marketplace or switch the affected skills to eject mode.`,\n );\n }\n\n // The same rule applies per skill: install FIRST and delete the ejected working\n // copy only once THAT skill's plugin is registered. A failed install then leaves\n // the skill exactly as it was, and the caller hard-errors on\n // `pluginInstalls.failed` before any config claims the plugin source.\n for (const migration of plan.toPlugin) {\n const pluginScope = toClaudePluginScope(migration.newScope);\n const pluginRef = buildMarketplacePluginRef(migration.id, sourceResult.marketplace);\n try {\n await claudePluginInstall(pluginRef, pluginScope, projectDir);\n } catch (error) {\n pluginInstalls.failed.push({ id: migration.id, error: getErrorMessage(error) });\n continue;\n }\n pluginInstalls.installed.push({ id: migration.id, ref: pluginRef });\n verbose(`Installed plugin for ${migration.id}`);\n await deleteEjectedWorkingCopy(migration, projectDir);\n }\n }\n\n return { ejectCopies, pluginInstalls, warnings };\n}\n\n/**\n * Writes the local copy each newly-ejected skill becomes, and names every one it could not\n * write.\n *\n * The mirror of the toPlugin loop in {@link executeMigration}, and per-skill for the same\n * reasons. Each migration resolves its OWN destination from its own scope, so the two scopes\n * are independent by construction rather than by pass ordering — a refused write under $HOME\n * says nothing about the project tree, and one batched `try` around both once let a single\n * project-scope failure cancel every global copy behind one warning line.\n *\n * Failures are COLLECTED rather than aborted on. The caller hard-errors on any of them before\n * writing config, so stopping at the first buys no safety and costs the user the rest of the\n * list — they would learn about the second unwritable destination only by fixing the first and\n * running again. That is the reasoning `copyEachSkill` already gives for reporting its own\n * failures by id rather than throwing on the first.\n */\nasync function copyMigratedSkillsToLocal(\n migrations: SkillMigration[],\n projectDir: string,\n sourceResult: SourceLoadResult,\n): Promise<EjectCopyResult> {\n const copies: EjectCopyResult = { copied: [], failed: [] };\n\n for (const migration of migrations) {\n const { skillsDir } = resolveInstallPaths(projectDir, migration.newScope);\n try {\n const copied = await copySkillsToLocalFlattened([migration.id], skillsDir, sourceResult);\n copies.copied.push(...copied.map((skill) => skill.skillId));\n } catch (error) {\n copies.failed.push({ id: migration.id, error: getErrorMessage(error) });\n }\n }\n\n return copies;\n}\n\n/** The migrations that now have a local copy on disk, and so no longer need their plugin. */\nfunction migrationsWhoseCopyLanded(\n migrations: SkillMigration[],\n copies: EjectCopyResult,\n): SkillMigration[] {\n const landed = new Set(copies.copied);\n return migrations.filter((migration) => landed.has(migration.id));\n}\n\n/**\n * True when a migration must LEAVE the plugin registered: a skill moving from the global\n * install to a project-local copy keeps the global plugin for every other project, and this\n * project's config tombstone (`excluded: true`) is what keeps this project off it.\n */\nfunction keepsGlobalPluginRegistration(migration: SkillMigration): boolean {\n return migration.oldScope === \"global\" && migration.newScope === \"project\";\n}\n\n/**\n * Drops the plugin registration each newly-ejected skill no longer needs, and names every one\n * it could not drop.\n *\n * Diagnostic-only: the local copy IS the install now, so a stale registration is untidy rather\n * than wrong and must not fail the migration. What it must not do is borrow the copy pass's\n * words — this loop lived inside the copy's `try`, so a `claude plugin uninstall` that threw\n * was reported to the user as `Could not copy skills for eject`, naming work that had in fact\n * succeeded one line above the count proving it.\n */\nasync function uninstallMigratedPlugins(\n migrations: SkillMigration[],\n projectDir: string,\n sourceResult: SourceLoadResult,\n): Promise<string[]> {\n const warnings: string[] = [];\n\n for (const migration of migrations) {\n if (keepsGlobalPluginRegistration(migration)) {\n verbose(`Keeping global plugin for ${migration.id} (migrated to project-eject)`);\n continue;\n }\n if (!sourceResult.marketplace) {\n warnings.push(`Could not uninstall plugin for ${migration.id}: no marketplace configured`);\n continue;\n }\n\n // Scope-precise uninstall keyed to this migration's own scope. A best-effort\n // both-scopes sweep would also drop a same-id plugin registered at the OTHER Claude\n // scope (e.g. a project→eject switch uninstalling the still-needed global/user-scope\n // plugin). The registered scope is unambiguous here, so target it exactly.\n // claudePluginUninstall still swallows \"not installed\" / \"not found\".\n const pluginScope = toClaudePluginScope(migration.oldScope);\n const pluginRef = buildMarketplacePluginRef(migration.id, sourceResult.marketplace);\n try {\n await claudePluginUninstall(pluginRef, pluginScope, projectDir);\n } catch (error) {\n warnings.push(`Could not uninstall plugin for ${migration.id}: ${getErrorMessage(error)}`);\n continue;\n }\n verbose(`Uninstalled plugin for ${migration.id}`);\n }\n\n return warnings;\n}\n\n/**\n * Removes the local copy a now-pluginized skill no longer needs, from the scope it was\n * ejected at. A global copy is kept when the skill moves to project scope — the global\n * copy must remain for other projects.\n */\nasync function deleteEjectedWorkingCopy(\n migration: SkillMigration,\n projectDir: string,\n): Promise<void> {\n if (migration.oldScope === \"global\" && migration.newScope === \"project\") {\n verbose(`Keeping global local skill for ${migration.id} (migrated to project-plugin)`);\n return;\n }\n await deleteLocalSkill(installBaseDir(projectDir, migration.oldScope), migration.id);\n}\n","import path from \"path\";\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 { CLAUDE_DIR, MAX_CONFIG_FILE_SIZE, STANDARD_FILES } from \"../../consts\";\nimport { formatZodErrors } from \"../schema-validator\";\nimport { getPluginManifestPath, getUserPluginsDir } from \"./plugin-finder\";\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 // The one genuine optional here: a settings.json with no plugin enabled omits the\n // key entirely, and `getEnabledPluginKeys` says so in its own diagnostic rather than\n // defaulting it away. `lastUpdated` and `gitCommitSha` used to sit beside the fields\n // below on the same footing and were decoration — declared, never read, and stripped\n // by `z.object` either way.\n enabledPlugins: z.record(z.string(), z.unknown()).exactOptional(),\n })\n .passthrough();\n\n/** The fields every installation record carries, whatever scope it was registered at. */\nconst installationFields = {\n installPath: z.string(),\n version: z.string(),\n installedAt: z.string(),\n};\n\n/**\n * Discriminated on `scope` rather than carrying an optional `projectPath`, because which\n * project a record belongs to is a question only a project-scoped record has: a\n * user-scoped one has no answer, and a project-scoped one without a path is a malformed\n * record that `pickInstallation` would silently decline to match.\n */\nconst pluginInstallationSchema = z.discriminatedUnion(\"scope\", [\n z.object({ scope: z.literal(\"project\"), projectPath: z.string(), ...installationFields }),\n z.object({ scope: z.literal(\"user\"), ...installationFields }),\n z.object({ scope: z.literal(\"local\"), ...installationFields }),\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 = STANDARD_FILES.SETTINGS_JSON;\nconst INSTALLED_PLUGINS_FILE = \"installed_plugins.json\";\n\n/** Absolute path of the claude CLI install registry inside a plugins directory. */\nexport function getInstalledPluginsRegistryPath(pluginsDir: string): string {\n return path.join(pluginsDir, INSTALLED_PLUGINS_FILE);\n}\n\n/**\n * Lists every install recorded in a plugins directory's `installed_plugins.json`\n * (v2 registry — claude CLI >=2.1.220 installs under `cache/<marketplace>/<plugin>/<version>/`),\n * flattened to unique (pluginKey, installPath) pairs across all scopes.\n *\n * Throws when the registry is unreadable or fails schema validation — callers\n * treat the registry as the source of truth for installed plugins, so a broken\n * registry must surface as an error rather than an empty result.\n */\nexport async function listRegisteredPluginInstalls(pluginsDir: string): Promise<ResolvedPlugin[]> {\n const registryPath = getInstalledPluginsRegistryPath(pluginsDir);\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 throw new Error(\n `Invalid ${INSTALLED_PLUGINS_FILE}: ${formatZodErrors(result.error).join(\"; \")}`,\n );\n }\n\n return typedEntries(result.data.plugins).flatMap(([pluginKey, installations]) => {\n const uniquePaths = [...new Set(installations.map((i) => i.installPath))];\n return uniquePaths.map((installPath) => ({ pluginKey, installPath }));\n });\n}\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\ntype RegisteredInstallation = z.infer<typeof pluginInstallationSchema>;\n\n/** This project's own project-scoped installation wins; otherwise the user-scoped one. */\nfunction pickInstallation(\n installations: RegisteredInstallation[],\n projectDir: string,\n): RegisteredInstallation | undefined {\n return (\n installations.find((i) => i.scope === \"project\" && i.projectPath === projectDir) ??\n installations.find((i) => i.scope === \"user\")\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 = getInstalledPluginsRegistryPath(getUserPluginsDir());\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\n return pluginKeys.flatMap((pluginKey) => {\n const installations = registry.plugins[pluginKey];\n if (!installations || installations.length === 0) {\n verbose(`Plugin '${pluginKey}' not found in registry`);\n return [];\n }\n\n const picked = pickInstallation(installations, projectDir);\n if (!picked) {\n verbose(`No matching installation found for '${pluginKey}'`);\n return [];\n }\n\n const scopeSuffix = picked.scope === \"user\" ? \" (user scope)\" : \"\";\n verbose(`Resolved '${pluginKey}' to '${picked.installPath}'${scopeSuffix}`);\n return [{ pluginKey, installPath: picked.installPath }];\n });\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 checks = await Promise.all(\n resolvedPaths.map(async ({ pluginKey, installPath }) => {\n const pluginJsonPath = getPluginManifestPath(installPath);\n const manifestExists = await fileExists(pluginJsonPath);\n if (!manifestExists) {\n verbose(`Plugin '${pluginKey}' manifest does not exist at: '${pluginJsonPath}'`);\n }\n return { pluginKey, installPath, manifestExists };\n }),\n );\n const verified: ResolvedPlugin[] = checks\n .filter((c) => c.manifestExists)\n .map(({ pluginKey, installPath }) => ({ pluginKey, installPath }));\n\n verbose(`Verified ${verified.length} plugin install paths`);\n return verified;\n}\n","import type { SkillDefinitionMap } 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 const perPluginSkills = await Promise.all(\n pluginPaths.map(async ({ pluginKey, installPath }) => {\n verbose(`Discovering skills from plugin: '${pluginKey}'`);\n try {\n return await loadPluginSkills(installPath);\n } catch (error) {\n verbose(`Failed to load skills from '${pluginKey}': ${getErrorMessage(error)}`);\n return {};\n }\n }),\n );\n // Later plugins override earlier (merge follows pluginPaths order); skip absent entries\n for (const pluginSkills of perPluginSkills) {\n for (const [id, skill] of typedEntries(pluginSkills)) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n if (skill) {\n allSkills[id] = skill;\n }\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 { isRecord } from \"../../utils/type-guards.js\";\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 { validResult, invalidResult, mergeValidationResults } from \"../validation-result\";\nimport { extractFrontmatter } from \"../../utils/frontmatter\";\nimport { log } from \"../../utils/logger\";\nimport { formatZodErrors } from \"../schema-validator\";\nimport {\n pluginManifestValidationSchema,\n skillFrontmatterValidationSchema,\n agentFrontmatterValidationSchema,\n} from \"../schemas\";\nimport {\n KEBAB_CASE_PATTERN,\n MAX_PLUGIN_FILE_SIZE,\n PLUGIN_MANIFEST_DIR,\n STANDARD_FILES,\n} from \"../../consts\";\nimport { getPluginManifestPath } from \"./plugin-finder\";\n\nconst PLUGIN_DIR = PLUGIN_MANIFEST_DIR;\nconst PLUGIN_MANIFEST = STANDARD_FILES.PLUGIN_JSON;\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\nfunction isKebabCase(str: string): boolean {\n return KEBAB_CASE_PATTERN.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 invalidResult(`Plugin directory does not exist: ${pluginPath}`);\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, STANDARD_FILES.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 invalidResult(`Manifest file not found: ${manifestPath}`);\n }\n\n // `JSON.parse` returns `any`, and every field read below trusts what it\n // returns. Landing it in `unknown` and narrowing with `isRecord` first is what\n // makes `manifest.name` a checked read of a record rather than a property\n // fetched off `any` — and it names the array/string/null cases the schema\n // would otherwise report as a shape mismatch several lines later.\n let manifest: Record<string, unknown>;\n try {\n const content = await readFileSafe(manifestPath, MAX_PLUGIN_FILE_SIZE);\n const parsed: unknown = JSON.parse(content);\n if (!isRecord(parsed)) return invalidResult(`${PLUGIN_MANIFEST} must contain a JSON object`);\n manifest = parsed;\n } catch (err) {\n return invalidResult(`Invalid JSON in ${PLUGIN_MANIFEST}: ${getErrorMessage(err)}`);\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 invalidResult(`Skill file not found: ${skillPath}`);\n }\n\n const content = await readFile(skillPath);\n const frontmatter = extractFrontmatter(content);\n\n if (frontmatter === null) {\n return invalidResult(\"Missing or invalid YAML frontmatter\");\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 invalidResult(`Agent file not found: ${agentPath}`);\n }\n\n const content = await readFile(agentPath);\n const frontmatter = extractFrontmatter(content);\n\n if (frontmatter === null) {\n return invalidResult(\"Missing or invalid YAML frontmatter\");\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 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 validResult();\n\n const files = await fg(`**/${STANDARD_FILES.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 mergeValidationResults(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 validResult();\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 mergeValidationResults(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 const parsed: unknown = JSON.parse(content);\n return isRecord(parsed) ? parsed : null;\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 = getPluginManifestPath(pluginPath);\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 : validResult();\n\n const agentsResult =\n manifest?.agents && typeof manifest.agents === \"string\"\n ? await validatePluginAgentFiles(pluginPath, manifest.agents)\n : validResult();\n\n return mergeValidationResults([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: invalidResult(`Directory does not exist: ${pluginsDir}`),\n },\n ],\n summary: { total: 0, valid: 0, invalid: 1, withWarnings: 0 },\n };\n }\n\n const allDirs = await listDirectories(pluginsDir);\n const dirChecks = await Promise.all(\n allDirs.map(async (dirName) => ({\n dirName,\n isPlugin: await directoryExists(path.join(pluginsDir, dirName, PLUGIN_DIR)),\n })),\n );\n const pluginDirs = dirChecks.filter((c) => c.isPlugin).map((c) => c.dirName);\n\n if (pluginDirs.length === 0) {\n return {\n valid: false,\n results: [\n {\n name: pluginsDir,\n result: invalidResult(\n `No plugins found in directory: ${pluginsDir}. Plugins must contain a ${PLUGIN_DIR}/ directory.`,\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 validCount = results.filter((r) => r.result.valid).length;\n const summary = {\n total: results.length,\n valid: validCount,\n invalid: results.length - validCount,\n withWarnings: results.filter((r) => r.result.warnings.length > 0).length,\n };\n\n return {\n valid: summary.invalid === 0,\n results,\n summary,\n };\n}\n\nexport function printPluginValidationResult(name: string, result: ValidationResult): void {\n const status = result.valid ? \"\\u2713\" : \"\\u2717\";\n\n if (result.valid && result.warnings.length === 0) {\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 path from \"path\";\nimport { directoryExists, listDirectories, fileExists, readFile } from \"../../utils/fs\";\nimport { verbose, warn } from \"../../utils/logger\";\nimport { LOCAL_PSEUDO_CATEGORY, LOCAL_SKILLS_PATH, STANDARD_FILES } from \"../../consts\";\nimport { parseFrontmatter, readSkillMetadata } from \"../loading\";\nimport type { CategoryPath, Domain, ExtractedSkillMetadata, SkillSlug } from \"../../types\";\nimport { LOCAL_DEFAULTS, METADATA_KEYS } from \"../metadata-keys\";\n\nexport type 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 skillDirs = await listDirectories(localSkillsPath);\n const extracted = await Promise.all(\n skillDirs.map((skillDirName) => extractLocalSkill(localSkillsPath, skillDirName)),\n );\n const skills = extracted.filter((skill) => skill !== null);\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 // One file that describes no skill must skip its own skill, not abort discovery\n // for every command that loads the catalog. `compile` refuses the same judgment's\n // verdict outright, which is what keeps the two passes from disagreeing.\n const read = await readSkillMetadata(metadataPath);\n if (!read.usable) {\n warn(\n `Skipping local skill '${skillDirName}': ${STANDARD_FILES.METADATA_YAML} at ${metadataPath} does not describe it — ${read.reason}`,\n );\n return null;\n }\n\n const metadata = read.metadata;\n\n // `local` is a trapdoor, not a category: it belongs to no domain, so a skill wearing it\n // renders in no tab and is dropped from every sub-agent's stack. Refusing it here is\n // what keeps that from happening silently — the skill is unusable either way, and this\n // way the user is told which field to fix.\n if (metadata.category === LOCAL_PSEUDO_CATEGORY) {\n warn(\n `Skipping local skill '${skillDirName}': ${METADATA_KEYS.CATEGORY} '${LOCAL_PSEUDO_CATEGORY}' is a placeholder, not a real category, so no sub-agent can be given this skill. Set ${METADATA_KEYS.CATEGORY} in ${metadataPath} to a real one.`,\n );\n return null;\n }\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 absolutePath = path.join(localSkillsPath, skillDirName) + path.sep;\n const skillId = frontmatter.name;\n\n const extracted: ExtractedSkillMetadata = {\n id: skillId,\n directoryPath: skillDirName,\n description: metadata.cliDescription || frontmatter.description,\n ...(metadata.usageGuidance !== undefined && { usageGuidance: metadata.usageGuidance }),\n category: metadata.category,\n author: LOCAL_DEFAULTS.AUTHOR,\n path: relativePath,\n local: true,\n localPath: absolutePath,\n domain: metadata.domain,\n ...(metadata.custom !== undefined && { custom: metadata.custom }),\n slug: metadata.slug,\n displayName: metadata.displayName,\n };\n\n verbose(`Extracted local skill: ${skillId}`);\n return extracted;\n}\n","import path from \"path\";\n\nimport { EJECT_SOURCE, STANDARD_FILES } from \"../../consts\";\nimport type { SkillConfig, SkillId } from \"../../types\";\nimport { directoryExists, fileExists, readFile } from \"../../utils/fs\";\nimport { resolveInstallPaths } from \"../installation/install-base-dir\";\nimport { parseFrontmatter, readSkillMetadata, type UnusableSkillMetadata } from \"../loading\";\n\n/**\n * What became of the skill a saved config entry names, when the loaded catalogue does not\n * carry it.\n *\n * The wizard resolves an installed roster against the catalogue, and an id it cannot find is\n * an id it cannot put on any screen — so the merge drops that entry and `edit` reports a\n * removal the user never asked for. Reporting it is right; reporting all of them the same way\n * was not. A marketplace entry the source no longer carries is gone from the CATALOGUE. A\n * local entry is gone from the DISK — or is not gone at all, and its metadata.yaml simply\n * stopped describing it, which is a file to repair rather than a reason to lose the entry.\n *\n * Told apart at the entry's own install path. A local skill lives at\n * `<skillsDir>/<id>` — the one address `copySkillsToLocalFlattened`, `deleteLocalSkill` and\n * `migrateLocalSkillScope` all write to — so the entry names exactly where to look. What is\n * asked there is borrowed rather than invented: {@link readSkillMetadata} gives the same verdict\n * local-skill discovery, `compile` and `doctor` already share about that file, and\n * {@link parseFrontmatter}'s `name` is the same identity discovery registers the skill under.\n */\ntype SavedSkillFate =\n /** No local copy is claimed: the marketplace this entry names no longer carries the skill. */\n | { kind: \"dropped-by-source\" }\n /** Its local install is gone from the disk — nothing is left at the path it was ejected to. */\n | { kind: \"files-gone\"; skillDir: string }\n /** The directory is there but registers no skill by that name (no metadata.yaml, or a SKILL.md naming another). */\n | { kind: \"not-installed-there\"; skillDir: string }\n /** The skill is installed and intact — its declared category is one no domain in this source claims. */\n | { kind: \"unplaceable-category\"; skillDir: string; category: string }\n /** The directory is there and its metadata.yaml describes no skill — repairable, so the run refuses instead. */\n | { kind: \"unusable-metadata\"; detail: UnusableSkillMetadata };\n\ntype ClassifiedSkill = { id: SkillId; fate: SavedSkillFate };\n\n/**\n * The saved entries whose local skill is installed but whose metadata.yaml describes no skill.\n *\n * A run that meets one must stop rather than drop the entry: the file can be repaired, and\n * `compile` already refuses the whole run over the same verdict about the same file. Dropping\n * the entry instead would spend a config record on a YAML typo, and say the marketplace did it.\n */\nexport async function findUnusableSavedSkillMetadata(\n unresolvedIds: readonly SkillId[],\n savedSkills: readonly SkillConfig[],\n projectDir: string,\n): Promise<UnusableSkillMetadata[]> {\n const classified = await classifyUnresolvedSkills(unresolvedIds, savedSkills, projectDir);\n return classified.flatMap(({ fate }) => (fate.kind === \"unusable-metadata\" ? [fate.detail] : []));\n}\n\n/**\n * Why each unresolvable entry went, for `edit`'s Changes block.\n *\n * These removals are the only ones the user did not ask for: the wizard could not represent\n * the skill, so it never appeared on any screen to be deselected, and the merge drops it.\n * Reporting the id alone would read as \"we removed something you chose to remove\"; the reason\n * says which of the things below happened. Every other removal is a deselection the user\n * watched themselves make and needs no reason.\n *\n * An entry {@link findUnusableSavedSkillMetadata} would name is deliberately absent from the\n * map — that run refuses before any of this is printed, so a sentence for it would only ever\n * be a wrong one.\n */\nexport async function unresolvedSkillRemovalReasons(\n unresolvedIds: readonly SkillId[],\n savedSkills: readonly SkillConfig[],\n projectDir: string,\n sourceLabel: string,\n): Promise<ReadonlyMap<SkillId, string>> {\n const classified = await classifyUnresolvedSkills(unresolvedIds, savedSkills, projectDir);\n return new Map(\n classified.flatMap(({ id, fate }) => {\n const reason = removalReason(id, fate, sourceLabel);\n return reason === null ? [] : [[id, reason] as const];\n }),\n );\n}\n\nasync function classifyUnresolvedSkills(\n unresolvedIds: readonly SkillId[],\n savedSkills: readonly SkillConfig[],\n projectDir: string,\n): Promise<ClassifiedSkill[]> {\n return Promise.all(\n unresolvedIds.map(async (id) => {\n const saved = savedSkills.find((entry) => entry.id === id);\n return { id, fate: await classifySavedSkill(id, saved, projectDir) };\n }),\n );\n}\n\n/**\n * An id with no saved entry behind it — a plugin-discovered skill the config never recorded —\n * is read as the marketplace's: there is no local copy claimed for it to have lost.\n */\nasync function classifySavedSkill(\n id: SkillId,\n saved: SkillConfig | undefined,\n projectDir: string,\n): Promise<SavedSkillFate> {\n if (saved?.origin !== EJECT_SOURCE) return { kind: \"dropped-by-source\" };\n\n const skillDir = path.join(resolveInstallPaths(projectDir, saved.scope).skillsDir, id);\n if (!(await directoryExists(skillDir))) return { kind: \"files-gone\", skillDir };\n\n const metadataPath = path.join(skillDir, STANDARD_FILES.METADATA_YAML);\n // A directory with no metadata.yaml at all is not registered with the CLI, and `compile`\n // skips rather than refuses it — so this one is reported and removed, not stopped over.\n if (!(await fileExists(metadataPath))) return { kind: \"not-installed-there\", skillDir };\n\n const read = await readSkillMetadata(metadataPath);\n if (!read.usable) {\n return {\n kind: \"unusable-metadata\",\n detail: { skillDirName: id, metadataPath, reason: read.reason },\n };\n }\n\n // The metadata describes SOME skill. Whether it describes THIS one is SKILL.md's answer — a\n // local skill is identified by its frontmatter name — so a SKILL.md deleted out from under a\n // live metadata.yaml, or renamed under a directory that was not, lands here.\n if (!(await skillMdNames(skillDir, id))) return { kind: \"not-installed-there\", skillDir };\n\n // Everything about the install is intact, so the skill IS in the catalogue and the wizard\n // still could not place it: a category no domain claims, which is the only way left.\n return { kind: \"unplaceable-category\", skillDir, category: read.metadata.category };\n}\n\n/** Whether the SKILL.md installed here names this skill — a local skill's identity is that name. */\nasync function skillMdNames(skillDir: string, id: SkillId): Promise<boolean> {\n const skillMdPath = path.join(skillDir, STANDARD_FILES.SKILL_MD);\n if (!(await fileExists(skillMdPath))) return false;\n\n const frontmatter = parseFrontmatter(await readFile(skillMdPath), skillMdPath);\n return frontmatter?.name === id;\n}\n\n/** The sentence the Changes block puts after the removed row, or null when there is none to give. */\nfunction removalReason(id: SkillId, fate: SavedSkillFate, sourceLabel: string): string | null {\n switch (fate.kind) {\n case \"dropped-by-source\":\n return `not present in ${sourceLabel}`;\n case \"files-gone\":\n return `skill files no longer exist at ${fate.skillDir}`;\n case \"not-installed-there\":\n return `no skill named '${id}' is installed at ${fate.skillDir}`;\n case \"unplaceable-category\":\n return `installed at ${fate.skillDir}, but its category '${fate.category}' is not one this source knows`;\n case \"unusable-metadata\":\n return null;\n default: {\n const exhaustive: never = fate;\n return exhaustive;\n }\n }\n}\n","import path from \"path\";\n\nimport {\n copy,\n directoryExists,\n ensureDir,\n isPathWithin,\n remove,\n removeDirIfEmpty,\n} from \"../../utils/fs\";\nimport { verbose, warn } from \"../../utils/logger\";\nimport { LOCAL_SKILLS_PATH } from \"../../consts\";\nimport { installBaseDir } from \"../installation/install-base-dir\";\nimport type { SkillId, SkillScope } from \"../../types\";\n\n/**\n * Validates a skill ID is safe for use in filesystem paths.\n * Blocks null bytes and path traversal sequences at runtime\n * since TypeScript template literal types don't prevent malformed data from YAML/JSON.\n */\nfunction validateSkillId(skillId: SkillId): boolean {\n return !(\n skillId.length === 0 ||\n skillId.includes(\"\\0\") ||\n skillId.includes(\"..\") ||\n skillId.includes(\"/\") ||\n skillId.includes(\"\\\\\")\n );\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 (!isPathWithin(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 // The skills directory only — `.claude/` above it stays whatever happens here.\n // Removing that one is uninstall's decision, not the edit path's.\n await removeDirIfEmpty(skillsDir);\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.\n * For P→G, removes the old project copy. For G→P (override model), the global copy stays untouched.\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: SkillScope,\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 toScope: SkillScope = fromScope === \"global\" ? \"project\" : \"global\";\n // installBaseDir resolves os.homedir() at runtime so test home-dir mocks apply\n // (GLOBAL_INSTALL_ROOT was captured once at module load — a latent test-mock bug).\n const fromBaseDir = installBaseDir(projectDir, fromScope);\n const toBaseDir = installBaseDir(projectDir, toScope);\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 (!isPathWithin(fromPath, fromSkillsDir)) {\n warn(`Skill ID '${skillId}' resolves outside the source skills directory.`);\n return;\n }\n if (!isPathWithin(toPath, toSkillsDir)) {\n warn(`Skill ID '${skillId}' resolves outside the destination skills directory.`);\n return;\n }\n\n if (!(await directoryExists(fromPath))) {\n if (await directoryExists(toPath)) {\n verbose(`Skill '${skillId}' already at ${toScope} scope — no migration needed`);\n return;\n }\n warn(`Could not migrate skill '${skillId}' — not found at either scope`);\n return;\n }\n\n await ensureDir(toSkillsDir);\n await copy(fromPath, toPath);\n\n // G→P is an override — the global copy stays untouched; the project copy overrides it.\n // Only P→G should delete the old directory.\n if (fromScope === \"project\") {\n await remove(fromPath);\n }\n\n verbose(`Migrated skill '${skillId}' from ${fromScope} to ${toScope}`);\n}\n","import { parse as parseYaml } from \"yaml\";\nimport path from \"path\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { glob, readFile, fileExists } from \"../../utils/fs\";\nimport { verbose, warn } from \"../../utils/logger\";\nimport { 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 formatZodIssues,\n matrixRawMetadataSchema,\n} from \"../schemas\";\nimport type { CategoryMap, ExtractedSkillMetadata, SkillRulesConfig } from \"../../types\";\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(configPath, skillCategoriesFileSchema);\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(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 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 metadata.yaml and validates it 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 * A metadata.yaml that describes no skill — unparseable, or parseable without the\n * fields the schema requires — is warned by path and skips its own skill; one bad\n * file does not take the scan down with it. Skills missing the required\n * `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\n // The safeParse below catches a file that parses without the fields a skill is\n // described by, and cannot catch a file nothing parses out of at all. Both refuse\n // the same way readSkillMetadata does: skip this skill, not the whole scan.\n let rawMetadata: unknown;\n try {\n rawMetadata = parseYaml(metadataContent);\n } catch (error) {\n warn(\n `Skipping '${metadataFile}': unparseable ${STANDARD_FILES.METADATA_YAML} at ${metadataPath} — ${getErrorMessage(error)}`,\n );\n continue;\n }\n\n const metadataResult = matrixRawMetadataSchema.safeParse(rawMetadata);\n\n if (!metadataResult.success) {\n warn(\n `Skipping '${metadataFile}': invalid metadata.yaml — ${formatZodIssues(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 ...(metadata.usageGuidance !== undefined && { usageGuidance: metadata.usageGuidance }),\n category: metadata.category,\n author: metadata.author,\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","import { verbose, warn } from \"../../utils/logger\";\nimport { unique, uniqueBy } from \"remeda\";\nimport { toTitleCase } from \"../../utils/string\";\nimport { DEFAULT_VERSION, LOCAL_PSEUDO_CATEGORY } from \"../../consts\";\nimport { defaultRules } from \"../configuration/default-rules\";\nimport type {\n CategoryDefinition,\n CategoryMap,\n Domain,\n ExtractedSkillMetadata,\n MergedSkillsMatrix,\n RelationshipDefinitions,\n RequireRule,\n ResolvedSkill,\n SkillAlternative,\n SkillId,\n SkillRelation,\n SkillRequirement,\n SkillRulesConfig,\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 verbose(\n `Category '${category}' has no definition in skill-categories.ts — using auto-generated placeholder`,\n );\n const displayName = toTitleCase(category);\n\n return {\n id: category,\n displayName,\n description: `Auto-generated category for ${category}`,\n domain,\n exclusive: false,\n required: false,\n order: AUTO_SYNTH_ORDER,\n };\n}\n\n/**\n * Registers a skill's claim on a slug, first claim winning and every later one\n * named. Exported because the merge is not the only writer: `source-loader`\n * merges a project's local skills into an already-built map, and two writers\n * deciding a collision differently is how a slug comes to mean one skill here\n * and another there.\n *\n * A skill re-stating a claim it already holds is not a collision — a local skill\n * overriding a matrix id inherits that id's slug and arrives back here with it.\n */\nexport function claimSlug(slugMap: SkillSlugMap, slug: SkillSlug, id: SkillId): void {\n const incumbent = slugMap.slugToId[slug];\n if (incumbent === id) return;\n if (incumbent !== undefined) {\n warn(`Duplicate slug '${slug}': already mapped to '${incumbent}', ignoring '${id}'`);\n return;\n }\n\n slugMap.slugToId[slug] = id;\n slugMap.idToSlug[id] = slug;\n}\n\n/** Builds a bidirectional slug <-> ID map from extracted skill metadata. */\nfunction buildSlugMap(skills: ExtractedSkillMetadata[]): SkillSlugMap {\n const slugMap: SkillSlugMap = { slugToId: {}, idToSlug: {} };\n\n for (const skill of skills) {\n claimSlug(slugMap, skill.slug, skill.id);\n }\n\n return slugMap;\n}\n\n/**\n * Resolves every skill into the map the matrix is read through, keyed by id.\n * Warns on duplicate ids (first one wins) — the identity axis {@link buildSlugMap}\n * guards for slugs. Two directories whose SKILL.md declares the same name would\n * otherwise resolve in glob order, and the loser would leave no trace.\n */\nfunction buildResolvedSkillMap(\n skills: ExtractedSkillMetadata[],\n categories: CategoryMap,\n relationships: RelationshipDefinitions,\n slugMap: SkillSlugMap,\n): Partial<Record<SkillId, ResolvedSkill>> {\n const resolvedSkills: Partial<Record<SkillId, ResolvedSkill>> = {};\n\n for (const skill of skills) {\n const existing = resolvedSkills[skill.id];\n if (existing) {\n warn(\n `Duplicate skill id '${skill.id}': already resolved from '${existing.path}', ignoring '${skill.path}'`,\n );\n continue;\n }\n\n resolvedSkills[skill.id] = buildResolvedSkill(skill, categories, relationships, slugMap);\n }\n\n return resolvedSkills;\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 warn(`Unresolved slug '${slug}'${location} — skipping`);\n return null;\n}\n\n/** Every slug the rules name, in the order the four rule kinds declare them. */\nfunction slugsNamedByRules(relationships: RelationshipDefinitions): SkillSlug[] {\n return [\n ...relationships.conflicts.flatMap((rule) => rule.skills),\n ...relationships.discourages.flatMap((rule) => rule.skills),\n ...relationships.requires.flatMap((rule) => [rule.skill, ...rule.needs]),\n ...relationships.alternatives.flatMap((rule) => rule.skills),\n ];\n}\n\n/**\n * The slugs the rules name that no skill carries, deduplicated.\n *\n * Asked of the rules rather than counted off the resolution pass, because that\n * pass walks every rule once per skill: one typo would otherwise be reported as\n * many findings as the source has skills, which is the noise CLI-471 removed.\n */\nfunction collectUnresolvedSlugs(\n relationships: RelationshipDefinitions,\n slugToId: SkillSlugMap[\"slugToId\"],\n): SkillSlug[] {\n return unique(slugsNamedByRules(relationships).filter((slug) => slugToId[slug] === undefined));\n}\n\n/** Merges relationship rule sets: source rules first, so they win first-match lookups. */\nfunction mergeRelationships(\n source: RelationshipDefinitions,\n defaults: RelationshipDefinitions,\n): RelationshipDefinitions {\n return {\n conflicts: [...source.conflicts, ...defaults.conflicts],\n discourages: [...source.discourages, ...defaults.discourages],\n requires: [...source.requires, ...defaults.requires],\n alternatives: [...source.alternatives, ...defaults.alternatives],\n };\n}\n\n/** Below two present members a group rule relates nothing, so it is dropped whole. */\nconst MIN_RELATABLE_GROUP_MEMBERS = 2;\n\n/** Group rules — conflicts, discourages, alternatives — keeping only present slugs. */\nfunction narrowGroupsToSlugs<Rule extends { skills: SkillSlug[] }>(\n rules: Rule[],\n shipped: ReadonlySet<SkillSlug>,\n): Rule[] {\n return rules\n .map((rule) => ({ ...rule, skills: rule.skills.filter((slug) => shipped.has(slug)) }))\n .filter((rule) => rule.skills.length >= MIN_RELATABLE_GROUP_MEMBERS);\n}\n\n/**\n * Requirements, keeping only those a present skill declares over present skills.\n * A rule left needing nothing states no requirement — resolution already treats it\n * that way — so it goes rather than resolving to an empty `needs`.\n */\nfunction narrowRequirementsToSlugs(\n rules: RequireRule[],\n shipped: ReadonlySet<SkillSlug>,\n): RequireRule[] {\n return rules\n .filter((rule) => shipped.has(rule.skill))\n .map((rule) => ({ ...rule, needs: rule.needs.filter((slug) => shipped.has(slug)) }))\n .filter((rule) => rule.needs.length > 0);\n}\n\nfunction narrowToShippedSlugs(\n rules: RelationshipDefinitions,\n shipped: ReadonlySet<SkillSlug>,\n): RelationshipDefinitions {\n return {\n conflicts: narrowGroupsToSlugs(rules.conflicts, shipped),\n discourages: narrowGroupsToSlugs(rules.discourages, shipped),\n requires: narrowRequirementsToSlugs(rules.requires, shipped),\n alternatives: narrowGroupsToSlugs(rules.alternatives, shipped),\n };\n}\n\n/**\n * The relationships a source's skills can actually express: the source's own rules\n * verbatim, plus the built-ins narrowed to the slugs this source ships.\n *\n * The built-in rules are written against the whole public catalogue — 176 slugs — so\n * a source shipping ten of them left the rest dangling. Resolution dropped those\n * references either way; what it ALSO did was warn once per reference per skill, and\n * since the startup band those warnings are painted over the wizard's step. Narrowing\n * first removes the noise and nothing else: a member that resolves to no skill\n * contributed nothing to the resolved matrix to begin with.\n *\n * A source's OWN rules are never narrowed. A slug its author typed and its skills do\n * not carry is that source's defect, and the warning is the only place it is reported.\n */\nexport function relationshipsForSource(\n skills: ExtractedSkillMetadata[],\n sourceRules?: SkillRulesConfig,\n): RelationshipDefinitions {\n const shipped = new Set(skills.map((skill) => skill.slug));\n const builtIn = narrowToShippedSlugs(defaultRules.relationships, shipped);\n return sourceRules ? mergeRelationships(sourceRules.relationships, builtIn) : builtIn;\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 = buildResolvedSkillMap(skills, categories, relationships, slugMap);\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_PSEUDO_CATEGORY) 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 unresolvedSlugs = collectUnresolvedSlugs(relationships, slugMap.slugToId);\n\n const merged: MergedSkillsMatrix = {\n version: DEFAULT_VERSION,\n categories: synthesizedCategories,\n skills: resolvedSkills,\n suggestedStacks: [],\n slugMap,\n ...(unresolvedSlugs.length > 0 && { unresolvedSlugs }),\n generatedAt: new Date().toISOString(),\n };\n\n return merged;\n}\n\n/** All resolved relationship data for a single skill */\ntype ResolvedRelationships = {\n conflictsWith: SkillRelation[];\n discourages: SkillRelation[];\n requires: SkillRequirement[];\n alternatives: SkillAlternative[];\n};\n\n/** Resolves a rule's slugs to canonical ids, warning and skipping any that don't resolve. */\nfunction resolveSlugsOrSkip(slugs: SkillSlug[], resolve: ResolveId, context: string): SkillId[] {\n return slugs.map((slug) => resolve(slug, context)).filter((id): id is SkillId => id !== null);\n}\n\n/**\n * A requirement's needs, or null when any one of them names no skill.\n *\n * Keeping what resolved would apply a requirement nobody wrote: under AND an\n * unresolved need narrows the rule to the survivors, under OR it takes an\n * alternative away — and either is presented to the user under the author's own\n * `reason`. A source's rules are its own (CLI-471 narrows the CLI's built-ins to\n * what a source ships and leaves the source's untouched), so they are taken\n * whole or not at all. The slug is warned here and reported by\n * `checkMatrixHealth`, which is where the author reads it.\n */\nfunction resolveEveryNeed(needs: SkillSlug[], resolve: ResolveId): SkillId[] | null {\n // A rule needing nothing states no requirement, as it did before any of its\n // members could fail to resolve.\n if (needs.length === 0) return null;\n\n const resolved = resolveSlugsOrSkip(needs, resolve, \"requires.needs\");\n return resolved.length === needs.length ? resolved : null;\n}\n\n/**\n * Members of the symmetric groups containing `skillId` (excluding itself),\n * deduplicated on first occurrence, each paired with its group's rule so the\n * caller can lift the annotation (reason/purpose).\n */\nfunction collectSymmetricGroupMembers<Rule extends { skills: SkillSlug[] }>(\n rules: readonly Rule[],\n skillId: SkillId,\n resolve: ResolveId,\n context: string,\n): Array<{ memberId: SkillId; rule: Rule }> {\n const members = rules.flatMap((rule) => {\n const resolved = resolveSlugsOrSkip(rule.skills, resolve, context);\n if (!resolved.includes(skillId)) return [];\n return resolved.filter((id) => id !== skillId).map((memberId) => ({ memberId, rule }));\n });\n return uniqueBy(members, (m) => m.memberId);\n}\n\n/**\n * Resolves all relationship data for a single skill in one pass across all\n * relationship rule types (conflicts, discourages, compatibility, requirements, alternatives).\n */\nfunction resolveRelationships(\n skillId: SkillId,\n relationships: RelationshipDefinitions,\n resolve: ResolveId,\n): ResolvedRelationships {\n // Symmetric groups: members of every group containing this skill, first-occurrence deduped\n const conflictsWith: SkillRelation[] = collectSymmetricGroupMembers(\n relationships.conflicts,\n skillId,\n resolve,\n \"conflicts\",\n ).map(({ memberId, rule }) => ({ skillId: memberId, reason: rule.reason }));\n\n const discourages: SkillRelation[] = collectSymmetricGroupMembers(\n relationships.discourages,\n skillId,\n resolve,\n \"discourages\",\n ).map(({ memberId, rule }) => ({ skillId: memberId, reason: rule.reason }));\n\n const alternatives: SkillAlternative[] = collectSymmetricGroupMembers(\n relationships.alternatives,\n skillId,\n resolve,\n \"alternatives\",\n ).map(({ memberId, rule }) => ({ skillId: memberId, purpose: rule.purpose }));\n\n // Requirements — directional, skill field identifies the dependent\n const requires: SkillRequirement[] = [];\n for (const rule of relationships.requires) {\n const ruleSkillId = resolve(rule.skill, \"requires.skill\");\n if (ruleSkillId !== skillId) continue;\n const resolvedNeeds = resolveEveryNeed(rule.needs, resolve);\n if (!resolvedNeeds) continue;\n requires.push({\n skillIds: resolvedNeeds,\n needsAny: rule.needsAny ?? false,\n reason: rule.reason,\n });\n }\n\n return {\n conflictsWith,\n discourages,\n requires,\n alternatives,\n };\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 const resolved = resolveRelationships(skill.id, relationships, resolve);\n\n return {\n id: skill.id,\n slug,\n displayName: skill.displayName,\n description: skill.description,\n ...(skill.usageGuidance !== undefined && { usageGuidance: skill.usageGuidance }),\n category: skill.category,\n author: skill.author,\n ...resolved,\n path: skill.path,\n ...(skill.custom === true ? { custom: true } : {}),\n };\n}\n","import {\n createSelectionSemantics,\n type IncompatibilityCause,\n type SelectionCatalogFacts,\n type SelectionJudgement,\n type SelectionSemantics,\n} from \"@workspace/matrix\";\nimport { groupBy } from \"remeda\";\nimport { LOCAL_PSEUDO_CATEGORY } from \"../../consts\";\nimport type {\n CategoryPath,\n MergedSkillsMatrix,\n OptionState,\n ResolvedSkill,\n SelectionValidation,\n SkillId,\n SkillOption,\n ValidationError,\n} from \"../../types\";\nimport { typedEntries, typedValues } from \"../../utils/typed-object\";\nimport { matrix, getSkillById, allSkills } from \"./matrix-provider\";\n\nfunction getLabel(skill: Pick<ResolvedSkill, \"displayName\">): string {\n return skill.displayName;\n}\n\nfunction joinWithConjunction(items: string[], conjunction: \"or\" | \"and\"): string {\n if (items.length <= 1) return items[0] ?? \"\";\n if (items.length === 2) return `${items[0]} ${conjunction} ${items[1]}`;\n return `${items.slice(0, -1).join(\", \")} ${conjunction} ${items[items.length - 1]}`;\n}\n\ntype SelectionContext = {\n resolvedSelections: SkillId[];\n selectedSet: Set<SkillId>;\n};\n\nfunction initializeSelectionContext(currentSelections: SkillId[]): SelectionContext {\n const resolvedSelections = currentSelections.map((s) => getSkillById(s).id);\n const selectedSet = new Set<SkillId>(resolvedSelections);\n return { resolvedSelections, selectedSet };\n}\n\n/**\n * The relationship facts the shared selection semantics judge — id, category,\n * conflicts, discourages and requires. Exclusivity defaults to true for a\n * category that does not say, matching the wizard grid's own reading; the\n * `local` pseudo-category is never listed, so it stays non-exclusive here as it\n * does in `validateExclusivity`.\n */\nfunction toSelectionFacts(source: MergedSkillsMatrix): SelectionCatalogFacts {\n return {\n skills: typedValues(source.skills).map((skill) => ({\n id: skill.id,\n categoryId: skill.category,\n conflictsWith: skill.conflictsWith.map((relation) => relation.skillId),\n discourages: skill.discourages.map((relation) => ({\n skillId: relation.skillId,\n reason: relation.reason,\n })),\n requires: skill.requires.map((requirement) => ({\n skillIds: requirement.skillIds,\n needsAny: requirement.needsAny,\n })),\n })),\n exclusiveCategoryIds: new Set(\n typedValues(source.categories)\n .filter((category) => category.exclusive !== false)\n .map((category) => category.id),\n ),\n };\n}\n\n// Rebound whenever `initializeMatrix` swaps the matrix, so the semantics\n// always judge the catalogue currently loaded — merged local skills included.\nlet boundSemantics: SelectionSemantics | undefined;\nlet boundTo: MergedSkillsMatrix | undefined;\n\nfunction judgeSelections(resolvedSelections: SkillId[]): SelectionJudgement {\n if (!boundSemantics || boundTo !== matrix) {\n boundSemantics = createSelectionSemantics(toSelectionFacts(matrix));\n boundTo = matrix;\n }\n return boundSemantics(resolvedSelections);\n}\n\n// The judgement speaks in ids; this surface answers in the wizard's words.\nfunction renderIncompatibility(cause: IncompatibilityCause): string {\n switch (cause.kind) {\n case \"conflict\":\n return `conflicts with ${labelOf(cause.skillId)}`;\n case \"unreachableRequirement\": {\n if (cause.requirement.needsAny) {\n const labels = cause.requirement.skillIds.map(labelOf);\n return `requires ${joinWithConjunction(labels, \"or\")} (all conflict with current selection)`;\n }\n const lostLabels = cause.lostIds.map(labelOf);\n return `requires ${joinWithConjunction(lostLabels, \"and\")} which conflicts with current selection`;\n }\n }\n}\n\nfunction labelOf(skillId: string): string {\n // Boundary cast: every id inside a cause was read out of the matrix's own\n // relationship tables, so it names a skill the matrix holds.\n return getLabel(getSkillById(skillId as SkillId));\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 getSkillById(skillId); // assert the id exists in the matrix\n\n const { resolvedSelections, selectedSet } = initializeSelectionContext(currentSelections);\n return resolvedSelections.filter(\n (selectedId) =>\n selectedId !== skillId &&\n getSkillById(selectedId).requires.some((req) =>\n wouldLoseRequirement(req, skillId, selectedSet),\n ),\n );\n}\n\ntype SkillRequirement = ResolvedSkill[\"requires\"][number];\n\n/** OR (`needsAny`): met when ANY option is selected. AND: met when EVERY id is selected. */\nfunction isRequirementMet(req: SkillRequirement, selectedSet: ReadonlySet<SkillId>): boolean {\n return req.needsAny\n ? req.skillIds.some((id) => selectedSet.has(id))\n : req.skillIds.every((id) => selectedSet.has(id));\n}\n\n/** Ids blocking the requirement: every option for an unmet OR, the absent ids for an AND. */\nfunction missingRequirementIds(\n req: SkillRequirement,\n selectedSet: ReadonlySet<SkillId>,\n): SkillId[] {\n if (isRequirementMet(req, selectedSet)) return [];\n return req.needsAny ? [...req.skillIds] : req.skillIds.filter((id) => !selectedSet.has(id));\n}\n\n/**\n * True when removing `removedId` would leave this requirement unsatisfied:\n * for OR it must be the sole remaining satisfier; for AND, any required id.\n */\nfunction wouldLoseRequirement(\n req: SkillRequirement,\n removedId: SkillId,\n selectedSet: ReadonlySet<SkillId>,\n): boolean {\n if (req.needsAny) {\n const satisfied = req.skillIds.filter((id) => selectedSet.has(id));\n return satisfied.length === 1 && satisfied[0] === removedId;\n }\n return req.skillIds.includes(removedId);\n}\n\n/**\n * For an unselected skill, finds the first selected skill that needs it\n * and whose requirement is currently unmet. Returns the dependent's display name,\n * or undefined if no selected skill has an unmet need for this skill.\n */\nexport function getUnmetRequiredBy(\n skillId: SkillId,\n currentSelections: SkillId[],\n): string | undefined {\n getSkillById(skillId); // assert the id exists in the matrix\n const { resolvedSelections, selectedSet } = initializeSelectionContext(currentSelections);\n\n if (selectedSet.has(skillId)) return undefined;\n\n for (const selectedId of resolvedSelections) {\n const selectedSkill = matrix.skills[selectedId];\n if (!selectedSkill) continue;\n\n for (const req of selectedSkill.requires) {\n if (!req.skillIds.includes(skillId)) continue;\n\n if (req.needsAny) {\n // OR: unmet only if NONE of the options are selected\n if (!req.skillIds.some((id) => selectedSet.has(id))) {\n return selectedSkill.displayName;\n }\n } else {\n // AND: unmet if this specific skill isn't selected\n return selectedSkill.displayName;\n }\n }\n }\n\n return undefined;\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 it has a `discourages` relationship with a\n * currently selected skill (bidirectional check).\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 return getDiscourageReason(skillId, currentSelections) !== undefined;\n}\n\n/**\n * Determines whether a skill is incompatible with the current selection state\n * (shown with red warning). Checks conflictsWith relationships and also\n * detects unsatisfiable requires (all required dependencies conflict with selections).\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 has conflicts with current selections\n */\nexport function isIncompatible(skillId: SkillId, currentSelections: SkillId[]): boolean {\n return getIncompatibleReason(skillId, currentSelections) !== undefined;\n}\n\n/**\n * Checks if a selected skill has unmet dependency requirements.\n * Only meaningful for skills that are currently selected.\n */\nexport function hasUnmetRequirements(skillId: SkillId, currentSelections: SkillId[]): boolean {\n return getUnmetRequirementsReason(skillId, currentSelections) !== undefined;\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 (bidirectional), returning the first matching reason.\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 skill = getSkillById(skillId);\n const { resolvedSelections } = initializeSelectionContext(currentSelections);\n\n return judgeSelections(resolvedSelections).discourageReasonOf(skill.id);\n}\n\n/**\n * Returns a human-readable reason why a skill is incompatible, or undefined if it is not.\n *\n * The verdict is the shared semantics' — a bidirectional conflict with\n * anything the selection reaches, or a requirement the selection has ruled out\n * (to a fixpoint, so a lost base strands everything built on it). This is the\n * selection as it stands: the pick-one swap forgiveness belongs to the grid\n * cell and lives in {@link getCellState}.\n *\n * @param skillId - The skill to get the incompatible reason for\n * @param currentSelections - Currently selected skill IDs\n * @returns Formatted reason string or undefined\n */\nexport function getIncompatibleReason(\n skillId: SkillId,\n currentSelections: SkillId[],\n): string | undefined {\n const skill = getSkillById(skillId);\n const { resolvedSelections } = initializeSelectionContext(currentSelections);\n\n const cause = judgeSelections(resolvedSelections).incompatibilityOf(skill.id);\n return cause === undefined ? undefined : renderIncompatibility(cause);\n}\n\n/**\n * The verdict a grid cell renders, judged against the selection a click on it\n * would produce. A pick-one category is a radio group: the click drops every\n * same-category member — selected or implied — so a conflict the swap\n * resolves is forgiven, and an impossibility it leaves standing (a requirement\n * the rest of the selection has ruled out) keeps its verdict and its reason,\n * exactly as a multi-select category renders it.\n */\nexport function getCellState(skillId: SkillId, currentSelections: SkillId[]): OptionState {\n const skill = getSkillById(skillId);\n const { resolvedSelections } = initializeSelectionContext(currentSelections);\n\n const verdict = judgeSelections(resolvedSelections).verdictOf(skill.id);\n return verdict.status === \"incompatible\"\n ? { status: \"incompatible\", reason: renderIncompatibility(verdict.cause) }\n : verdict;\n}\n\n/**\n * Everything the selection is necessarily built on without having been picked:\n * the requires-closure minus the selection itself. Choosing Next.js is\n * choosing React whether or not React was ever clicked; a requirement\n * offering a choice commits the user to none of its options.\n */\nexport function getImpliedSkills(currentSelections: SkillId[]): SkillId[] {\n const { resolvedSelections } = initializeSelectionContext(currentSelections);\n\n // Boundary cast: the closure only ever adds ids read from the matrix's own\n // `requires` tables, which type them as SkillId.\n return judgeSelections(resolvedSelections).implied as SkillId[];\n}\n\n/**\n * Returns a human-readable reason for unmet requirements, or undefined if all are met.\n */\nexport function getUnmetRequirementsReason(\n skillId: SkillId,\n currentSelections: SkillId[],\n): string | undefined {\n const skill = getSkillById(skillId);\n\n const { selectedSet } = initializeSelectionContext(currentSelections);\n\n for (const requirement of skill.requires) {\n const missing = missingRequirementIds(requirement, selectedSet);\n if (missing.length === 0) continue;\n const names = missing.map((id) => {\n const s = matrix.skills[id];\n return s ? getLabel(s) : id;\n });\n return requirement.needsAny\n ? `requires ${joinWithConjunction(names, \"or\")}`\n : `requires ${joinWithConjunction(names, \"and\")}`;\n }\n\n return undefined;\n}\n\n/**\n * `{ unmetRequirementsReason }` only when there is one to state — an unselected skill,\n * or a selected skill whose requirements are all met, carries no key at all.\n */\nfunction unmetRequirementsReasonFor(\n isSelected: boolean,\n skillId: SkillId,\n currentSelections: SkillId[],\n): { unmetRequirementsReason?: string } {\n if (!isSelected) return {};\n const reason = getUnmetRequirementsReason(skillId, currentSelections);\n return reason === undefined ? {} : { unmetRequirementsReason: reason };\n}\n\nexport function validateConflicts(resolvedSelections: SkillId[]): ValidationError[] {\n const errors: ValidationError[] = [];\n\n for (const [index, skillAId] of resolvedSelections.entries()) {\n const skillA = matrix.skills[skillAId];\n if (!skillA) continue;\n\n for (const skillBId of resolvedSelections.slice(index + 1)) {\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;\n}\n\nexport function validateRequirements(\n resolvedSelections: SkillId[],\n selectedSet: Set<SkillId>,\n): ValidationError[] {\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;\n}\n\nexport function validateExclusivity(resolvedSelections: SkillId[]): ValidationError[] {\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_PSEUDO_CATEGORY) 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;\n}\n\n/**\n * Validates a complete set of skill selections against all matrix constraints.\n *\n * Runs three 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 *\n * `valid` is derived from `errors` rather than asserted: a literal `true` beside a populated\n * `errors` array is a comment with a type annotation, and the first `if (validation.valid)`\n * written against it would pass on every rejected selection there is.\n *\n * @param selections - Complete list of selected skill IDs to validate\n * @returns Validation result with `valid` flag and error list\n */\nexport function validateSelection(selections: SkillId[]): SelectionValidation {\n const { resolvedSelections, selectedSet } = initializeSelectionContext(selections);\n\n const errors = [\n ...validateConflicts(resolvedSelections),\n ...validateRequirements(resolvedSelections, selectedSet),\n ...validateExclusivity(resolvedSelections),\n ];\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n\nfunction advisoryStateFrom(judgement: SelectionJudgement, skillId: SkillId): OptionState {\n // Priority: incompatible > discouraged > normal\n const cause = judgement.incompatibilityOf(skillId);\n if (cause !== undefined) {\n return { status: \"incompatible\", reason: renderIncompatibility(cause) };\n }\n const discourageReason = judgement.discourageReasonOf(skillId);\n if (discourageReason !== undefined) {\n return { status: \"discouraged\", reason: discourageReason };\n }\n return { status: \"normal\" };\n}\n\n/**\n * Builds a list of skill options for a category, annotated with their current\n * advisory state relative to the wizard's selection state.\n *\n * Each skill is checked against the current selections to determine its visual\n * state in the wizard UI. States are prioritized:\n * incompatible > discouraged > normal.\n *\n * @param categoryId - Category path to filter skills by\n * @param currentSelections - Currently selected skill IDs\n * @returns Array of skill options with advisory state annotations\n */\nexport function getAvailableSkills(\n categoryId: CategoryPath,\n currentSelections: SkillId[],\n): SkillOption[] {\n const { resolvedSelections, selectedSet } = initializeSelectionContext(currentSelections);\n const judgement = judgeSelections(resolvedSelections);\n\n return getSkillsByCategory(categoryId).map((skill) => {\n const isSelected = selectedSet.has(skill.id);\n return {\n id: skill.id,\n advisoryState: advisoryStateFrom(judgement, skill.id),\n selected: isSelected,\n hasUnmetRequirements: isSelected && hasUnmetRequirements(skill.id, currentSelections),\n ...unmetRequirementsReasonFor(isSelected, skill.id, currentSelections),\n alternatives: skill.alternatives.map((a) => a.skillId),\n };\n });\n}\n\n/** Returns all resolved skills belonging to the given category. */\nexport function getSkillsByCategory(categoryId: CategoryPath): ResolvedSkill[] {\n return allSkills().filter((skill) => skill.category === categoryId);\n}\n","import type { SkillId, SkillSlug } from \"../../types\";\n\n/**\n * Post-decision-2 vocabulary: conflict groups no longer exist as a mechanism, so a skill is\n * fenced by category exclusivity, by a `requires` rule, or not at all.\n */\nexport type AuditVerdict = \"constrained-via-exclusivity-or-requires\" | \"universal\";\n\n/** SKILLS-01 phase 4 rides this manifest — one audit, two products. */\nexport type SkillClass = \"A\" | \"B\" | \"C\";\n\n/** Worksheet batch that produced a verdict — provenance for the adversarial pass. */\nexport type BatchId =\n | \"web-core\"\n | \"web-state\"\n | \"web-ui\"\n | \"web-platform\"\n | \"api-core\"\n | \"api-data\"\n | \"api-services\"\n | \"ai\"\n | \"mobile\"\n | \"desktop\"\n | \"infra-cli\"\n | \"shared-meta\";\n\nexport type SkillAuditEntry = {\n /** ISO date the verdict was established or last re-confirmed. */\n audited: `${number}-${number}-${number}`;\n verdict: AuditVerdict;\n batch: BatchId;\n /**\n * SKILLS-01 classification. Omitted for the framework skills themselves\n * (react, nextjs, react-native, electron, tauri, …) which are the binding targets.\n * class A → frameworks: []; class B → exactly one; class C → the adapter set.\n */\n classification?: { class: SkillClass; frameworks: SkillSlug[] };\n /** Cited sources — recorded wherever the entry changed a rule. */\n sources?: string[];\n /** Anything the current vocabulary cannot express, handed to D-306 rather than invented here. */\n deferredToD306?: string;\n};\n\n/**\n * Every catalog skill's audit verdict, one entry per skill (CLI-389).\n *\n * Total record, not `Partial`: the type checker enforces \"every SkillId appears\" at compile\n * time, so the \"empty = unaudited, or nobody looked?\" ambiguity is unrepresentable for\n * built-ins. Source-provided skills cannot be covered that way — `checkMatrixHealth` carries\n * the runtime assertion for those.\n *\n * Verdicts were recorded as of the audit, assuming the batches' category dispositions would\n * land; they have, so every row is backed by the live rules and\n * `auditVerdictsPendingApply` below — the exemption list for rows the tree has not caught up\n * with — is empty.\n */\nexport const skillAudit: Record<SkillId, SkillAuditEntry> = {\n // ── B1 — web core: frameworks, meta-frameworks, routing, server state (20) ──\n \"web-framework-react\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-core\",\n },\n \"web-framework-vue-composition-api\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-core\",\n },\n \"web-framework-angular-standalone\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-core\",\n },\n \"web-framework-solidjs\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-core\",\n },\n \"web-framework-svelte\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-core\",\n },\n \"web-meta-framework-nextjs\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-core\",\n },\n \"web-meta-framework-remix\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-core\",\n },\n \"web-meta-framework-nuxt\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-core\",\n },\n \"web-meta-framework-sveltekit\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-core\",\n },\n \"web-meta-framework-astro\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-core\",\n },\n \"web-meta-framework-qwik\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-core\",\n },\n \"web-meta-framework-docusaurus\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-core\",\n classification: { class: \"A\", frameworks: [] },\n sources: [\"https://docusaurus.io\"],\n },\n \"web-meta-framework-vitepress\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-core\",\n classification: { class: \"A\", frameworks: [] },\n sources: [\"https://github.com/honojs/website\", \"https://vitepress.dev\"],\n },\n \"web-routing-react-router\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-core\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n sources: [\"https://reactrouter.com\"],\n },\n \"web-routing-tanstack-router\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-core\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n deferredToD306:\n \"Solid trigger: widen to needsAny [react, solidjs] if Solid content lands in the body (the official @tanstack/solid-router adapter already shipped upstream).\",\n },\n \"web-server-state-react-query\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-core\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n deferredToD306:\n \"The hey-api MUST beside tRPC: the MUST reads literally (generated query options from hey-api — never write custom React Query hooks) and sits in tension beside tRPC-generated options in a hybrid stack; if that MUST is ever re-cut to claim ALL server data, the coexistence rationale reopens.\",\n },\n \"web-data-fetching-swr\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-core\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n },\n \"web-data-fetching-trpc\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-core\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n },\n \"web-data-fetching-graphql-apollo\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-core\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n },\n \"web-data-fetching-graphql-urql\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-core\",\n classification: {\n class: \"C\",\n frameworks: [\"react\", \"vue-composition-api\", \"solidjs\", \"svelte\"],\n },\n },\n\n // ── B2 — web state, forms, i18n, utilities (19) ──\n \"web-state-jotai\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-state\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n deferredToD306:\n \"Jotai beside a store library is a real pattern (atomic UI atoms beside a domain store) with an official bridge extension (jotai-zustand / atomWithStore) but no vendor-documented two-peers steady state; unrepresentable while the zustand skill's MUST is territorial. Reopen trigger: the zustand MUST being re-cut to store-shaped state.\",\n },\n \"web-state-mobx\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-state\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n },\n \"web-state-redux-toolkit\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-state\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n },\n \"web-state-zustand\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-state\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n },\n \"web-state-pinia\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-state\",\n classification: { class: \"B\", frameworks: [\"vue-composition-api\"] },\n },\n \"web-state-ngrx-signalstore\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-state\",\n classification: { class: \"B\", frameworks: [\"angular-standalone\"] },\n },\n \"web-forms-react-hook-form\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-state\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n },\n \"web-forms-tanstack-form\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-state\",\n classification: {\n class: \"C\",\n frameworks: [\"react\", \"vue-composition-api\", \"angular-standalone\", \"solidjs\"],\n },\n deferredToD306:\n \"Svelte-widening trigger: widen the needsAny to svelte/sveltekit when Svelte content lands in the body (@tanstack/svelte-form is stable upstream; the skill claims React/Vue/Solid/Angular/Lit only).\",\n },\n \"web-forms-vee-validate\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-state\",\n classification: { class: \"B\", frameworks: [\"vue-composition-api\"] },\n },\n \"web-forms-zod-validation\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-state\",\n classification: { class: \"A\", frameworks: [] },\n sources: [\"https://zod.dev\"],\n },\n \"web-error-handling-error-boundaries\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-state\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n },\n \"web-error-handling-result-types\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-state\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"web-i18n-next-intl\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-state\",\n classification: { class: \"B\", frameworks: [\"nextjs\"] },\n },\n \"web-i18n-react-intl\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-state\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n },\n \"web-i18n-vue-i18n\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-state\",\n classification: { class: \"B\", frameworks: [\"vue-composition-api\"] },\n },\n \"web-utilities-rxjs\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-state\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"web-utilities-date-fns\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-state\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"web-utilities-vueuse\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-state\",\n classification: { class: \"B\", frameworks: [\"vue-composition-api\"] },\n },\n \"web-utilities-native-js\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-state\",\n classification: { class: \"A\", frameworks: [] },\n },\n\n // ── B3 — web UI, styling, animation, editors (22) ──\n \"web-ui-shadcn-ui\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-ui\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n },\n \"web-ui-mui\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-ui\",\n classification: { class: \"C\", frameworks: [\"react\", \"nextjs\"] },\n },\n \"web-ui-chakra-ui\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-ui\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n },\n \"web-ui-mantine\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-ui\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n },\n \"web-ui-ant-design\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-ui\",\n classification: { class: \"C\", frameworks: [\"react\", \"nextjs\"] },\n },\n \"web-ui-vuetify\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-ui\",\n classification: { class: \"B\", frameworks: [\"vue-composition-api\"] },\n },\n \"web-ui-radix-ui\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-ui\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n },\n \"web-ui-headless-ui\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-ui\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n },\n \"web-ui-base-ui\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-ui\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n sources: [\"https://base-ui.com\"],\n },\n \"web-ui-tanstack-table\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-ui\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n },\n \"web-styling-tailwind\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-ui\",\n classification: { class: \"C\", frameworks: [] },\n },\n \"web-styling-scss-modules\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-ui\",\n classification: { class: \"A\", frameworks: [] },\n deferredToD306:\n \"tailwind <-> scss-modules coexistence is documented (Tailwind's own compatibility page allows but discourages it) — a discourages-shaped pair, no fence today.\",\n },\n \"web-styling-cva\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-ui\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"web-styling-theming\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-ui\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"web-styling-design-tokens\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-ui\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"web-animation-framer-motion\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-ui\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n },\n \"web-animation-css-animations\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-ui\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"web-animation-view-transitions\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-ui\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"web-editor-lexical\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-ui\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n sources: [\"https://lexical.dev\"],\n },\n \"web-editor-tiptap\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-ui\",\n classification: { class: \"C\", frameworks: [\"react\", \"vue-composition-api\"] },\n },\n \"web-3d-react-three-fiber\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-ui\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n sources: [\"https://r3f.docs.pmnd.rs\"],\n },\n \"web-dnd-dnd-kit\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-ui\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n sources: [\n \"skill body (DndContext/useDraggable/useDroppable/useSortable; every import a @dnd-kit/* React package)\",\n 'npm @dnd-kit/core (\"a lightweight React library\")',\n ],\n },\n\n // ── B4 — web platform, testing, tooling (23) ──\n \"web-testing-playwright-e2e\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-platform\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"web-testing-cypress-e2e\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-platform\",\n classification: { class: \"A\", frameworks: [] },\n deferredToD306:\n \"Cypress component testing beside Playwright E2E is unrepresentable — carried by the cy.mount slice; 2026 guidance keys the CT tool to the incumbent E2E runner, so the radio holds.\",\n },\n \"web-testing-react-testing-library\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-platform\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n },\n \"web-testing-vue-test-utils\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-platform\",\n classification: { class: \"B\", frameworks: [\"vue-composition-api\"] },\n },\n \"web-testing-vitest\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-platform\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"web-testing-visual-regression\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-platform\",\n classification: { class: \"A\", frameworks: [] },\n deferredToD306:\n \"Pairs with a capture harness (playwright / cypress / storybook) — advice only; enumerating the harnesses would misstate BackstopJS/Percy-class setups.\",\n },\n \"web-tooling-storybook\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-platform\",\n classification: {\n class: \"C\",\n frameworks: [\n \"react\",\n \"vue-composition-api\",\n \"angular-standalone\",\n \"solidjs\",\n \"svelte\",\n \"qwik\",\n ],\n },\n sources: [\"https://storybook.js.org/docs/configure/integration/frameworks\"],\n deferredToD306:\n \"A community Astro framework exists (storybook-astro.org) but is not official — astro stays fenced out today. Package-health watch: storybook-framework-qwik 0.6.1, personal repo, trails Storybook 10.x.\",\n },\n \"web-tooling-vite\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-platform\",\n classification: { class: \"A\", frameworks: [] },\n deferredToD306:\n \"vite <-> nextjs and vite <-> docusaurus are dubious combos (discourages-shaped, advice not fence) — with the 6-of-15 vite-carrying default-stack rosters that also pin nextjs named as curation debt for the stack owner.\",\n },\n \"web-tooling-component-library\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-platform\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n sources: [\n 'skill body (self-scope on all three surfaces; 3 of 5 MUSTs React/RSC-keyed; the \"use client\" contract)',\n ],\n },\n \"web-realtime-websockets\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-platform\",\n classification: { class: \"C\", frameworks: [\"react\"] },\n },\n \"web-realtime-socket-io\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-platform\",\n classification: { class: \"C\", frameworks: [\"react\"] },\n deferredToD306:\n \"A native-WebSocket third-party feed beside Socket.IO-to-own-server (the external service dictates the protocol) is a scope split the radio cannot express.\",\n },\n \"web-realtime-sse\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-platform\",\n classification: { class: \"C\", frameworks: [\"react\"] },\n },\n \"web-pwa-service-workers\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-platform\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"web-pwa-offline-first\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-platform\",\n classification: { class: \"C\", frameworks: [\"react\"] },\n },\n \"web-dataviz-d3\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-platform\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"web-dataviz-recharts\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-platform\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n sources: [\"https://recharts.org\"],\n },\n \"web-maps-leaflet\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-platform\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"web-maps-mapbox\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-platform\",\n classification: { class: \"A\", frameworks: [] },\n deferredToD306:\n \"mapbox-gl-leaflet embedding (the Leaflet API drives a non-interactive GL layer, so half the mapbox skill applies and half must not be followed); Mapbox-as-tile-service needs no skill pairing at all.\",\n },\n \"web-mocks-msw\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-platform\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"web-files-file-upload-patterns\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-platform\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n },\n \"web-files-image-handling\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"web-platform\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n },\n \"web-performance-web-performance\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-platform\",\n classification: { class: \"C\", frameworks: [\"react\"] },\n },\n \"web-accessibility-web-accessibility\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"web-platform\",\n classification: { class: \"A\", frameworks: [] },\n },\n\n // ── B5 — api core: frameworks, GraphQL, auth, cross-cutting (17) ──\n \"api-framework-hono\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-core\",\n },\n \"api-framework-express\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-core\",\n },\n \"api-framework-fastify\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-core\",\n },\n \"api-framework-nestjs\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-core\",\n },\n \"api-framework-elysia\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-core\",\n },\n \"api-graphql-apollo-server\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-core\",\n classification: { class: \"C\", frameworks: [\"express\", \"fastify\"] },\n },\n \"api-graphql-yoga\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-core\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-graphql-mercurius\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-core\",\n classification: { class: \"B\", frameworks: [\"fastify\"] },\n sources: [\n 'skill body (\"When NOT to use: Not using Fastify (Mercurius is Fastify-only)\")',\n \"mercurius README (npm i fastify mercurius graphql; app.register(mercurius))\",\n ],\n },\n \"api-auth-better-auth-drizzle-hono\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-core\",\n classification: { class: \"B\", frameworks: [\"hono\"] },\n sources: [\n 'skill body (app.on([\"POST\",\"GET\"], \"/auth/*\", …); createMiddleware<{ Variables: AuthVariables }>; c.req.raw)',\n \"https://better-auth.com\",\n ],\n },\n \"api-auth-nextauth\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-core\",\n classification: { class: \"B\", frameworks: [\"nextjs\"] },\n sources: [\"https://authjs.dev\"],\n },\n \"api-auth-clerk\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-core\",\n classification: { class: \"B\", frameworks: [\"nextjs\"] },\n },\n \"api-specs-openapi\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"api-core\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-messaging-webhooks\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"api-core\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-caching-strategies\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"api-core\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-queue-bullmq\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-core\",\n classification: { class: \"A\", frameworks: [] },\n sources: [\n \"https://docs.bullmq.io/guide/redis-tm-compatibility\",\n \"https://upstash.com/docs/redis/integrations/bullmq\",\n ],\n deferredToD306:\n \"BullMQ polls Redis even when idle, so Upstash's per-request Pay-As-You-Go pricing balloons (Upstash recommends a Fixed plan) — curation advice, not a fence.\",\n },\n \"api-performance-api-performance\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"api-core\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-commerce-stripe\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"api-core\",\n classification: { class: \"A\", frameworks: [] },\n },\n\n // ── B6 — api data: databases and BaaS (22) ──\n \"api-database-postgresql\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-database-mysql\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-database-cockroachdb\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-database-drizzle\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-database-prisma\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n deferredToD306:\n \"Prisma-on-Mongo overlaps mongoose as a full Mongo data layer; the pair is deliberately unfenced across the sql-engine/document radios (accepted over-permissiveness).\",\n },\n \"api-database-sequelize\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-database-typeorm\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-database-knex\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-database-mongodb\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-database-mongoose\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-database-edgedb\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-database-surrealdb\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-database-redis\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-database-upstash\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-database-vercel-kv\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n deferredToD306:\n \"vercel-kv -> requires [vercel] deferred, not adopted: product-true (only provisionable on Vercel) but the product is discontinued (Dec 2024) and retirement is the better disposition.\",\n },\n \"api-database-vercel-postgres\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n deferredToD306:\n \"vercel-postgres -> requires [vercel] deferred, not adopted: product-true but the product is discontinued (auto-migrated to Neon) and retirement is the better disposition.\",\n },\n \"api-baas-supabase\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-baas-firebase\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-baas-appwrite\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-baas-neon\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-baas-planetscale\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-baas-turso\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-data\",\n classification: { class: \"A\", frameworks: [] },\n deferredToD306:\n \"turso as an edge-replica secondary beside a primary Postgres host is a real minority pattern the api-db-host radio over-restricts — accepted.\",\n },\n\n // ── B7 — api services: vector, search, CMS, analytics, observability, email (16) ──\n \"api-vector-db-pinecone\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-services\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-vector-db-qdrant\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-services\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-vector-db-chroma\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-services\",\n classification: { class: \"A\", frameworks: [] },\n deferredToD306:\n \"chroma <-> pinecone dev/prod graduation split is the one real minority pattern the vector-db radio blocks.\",\n },\n \"api-vector-db-weaviate\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-services\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-search-elasticsearch\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-services\",\n classification: { class: \"A\", frameworks: [] },\n deferredToD306:\n \"Elasticsearch-for-logs beside Meilisearch-for-product-search is a real dual-role coexistence the api-search radio blocks.\",\n },\n \"api-search-meilisearch\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-services\",\n classification: { class: \"A\", frameworks: [] },\n },\n // Landed by external PR (agents-inc/skills#2) after the B7 batch closed; verdict follows\n // its api-search siblings — the category radio is the constraint, no rules of its own.\n \"api-search-xquik\": {\n audited: \"2026-08-09\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-services\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-cms-payload\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-services\",\n classification: { class: \"C\", frameworks: [\"nextjs\"] },\n deferredToD306:\n \"payload's full surface (admin panel, mounted REST/GraphQL) is Next-hosted today; the taught surface (config, collections, access control, hooks, Local API) is the documented headless mode and host-neutral — the nextjs pairing is recommends-shaped. Re-derive if the body grows Next mounting content, or when the 4.0 framework adapters land.\",\n },\n \"api-cms-sanity\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-services\",\n classification: { class: \"C\", frameworks: [\"react\"] },\n },\n \"api-cms-strapi\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-services\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"api-analytics-setup-posthog\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"api-services\",\n classification: { class: \"C\", frameworks: [\"react\"] },\n },\n \"api-flags-posthog-flags\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"api-services\",\n classification: { class: \"C\", frameworks: [\"react\"] },\n },\n \"api-analytics-posthog-analytics\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"api-services\",\n classification: { class: \"C\", frameworks: [\"react\"] },\n },\n \"api-observability-setup-axiom-pino-sentry\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-services\",\n classification: { class: \"C\", frameworks: [\"nextjs\"] },\n sources: [\n \"skill body (next-axiom, @sentry/nextjs, next.config.ts wrapped withAxiom(withSentryConfig(...)), instrumentation.ts, sentry.{client,server,edge}.config.ts)\",\n 'SKILLS-09 (todo/skills.md) — \"Next-only in all but name\"',\n ],\n },\n \"api-observability-axiom-pino-sentry\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"api-services\",\n classification: { class: \"C\", frameworks: [\"react\"] },\n },\n \"api-email-setup-resend\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-services\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n sources: [\"https://react.email/docs\"],\n },\n \"api-email-resend-react-email\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"api-services\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n deferredToD306:\n \"React-as-template-renderer is not React-as-app-framework: React Email runs in any Node backend, but because react sits in the exclusive web-framework radio the rule fences every Vue/Svelte/Angular project out of the catalog's only email-usage skill.\",\n },\n\n // ── B8 — ai (20) ──\n \"ai-provider-anthropic-sdk\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"ai\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"ai-provider-openai-sdk\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"ai\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"ai-provider-google-gemini-sdk\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"ai\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"ai-provider-mistral-sdk\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"ai\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"ai-provider-cohere-sdk\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"ai\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"ai-provider-elevenlabs\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"ai\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"ai-provider-claude-vision\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"ai\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"ai-provider-openai-whisper\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"ai\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"ai-infrastructure-huggingface-inference\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"ai\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"ai-infrastructure-together-ai\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"ai\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"ai-infrastructure-litellm\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"ai\",\n classification: { class: \"A\", frameworks: [] },\n deferredToD306:\n \"Wire-protocol reuse is not a skill dependency: litellm's TypeScript client literally is new OpenAI({ baseURL }), but the body carries its own complete client pointed away from OpenAI, so it derives no requires [openai-sdk].\",\n },\n \"ai-infrastructure-replicate\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"ai\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"ai-infrastructure-modal\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"ai\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"ai-infrastructure-ollama\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"ai\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"ai-orchestration-langchain\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"ai\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"ai-orchestration-llamaindex\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"ai\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"ai-orchestration-vercel-ai-sdk\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"ai\",\n classification: { class: \"C\", frameworks: [\"react\"] },\n },\n \"ai-observability-langfuse\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"ai\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"ai-observability-promptfoo\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"ai\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"ai-patterns-tool-use-patterns\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"ai\",\n classification: { class: \"A\", frameworks: [] },\n },\n\n // ── B9 — mobile (24) ──\n \"mobile-framework-react-native\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n },\n \"mobile-framework-expo\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n },\n \"mobile-navigation-react-navigation\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"B\", frameworks: [\"react-native\"] },\n sources: [\"https://reactnavigation.org\"],\n },\n \"mobile-navigation-expo-router\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"B\", frameworks: [\"expo\"] },\n sources: [\"https://docs.expo.dev/router/installation/\"],\n },\n \"mobile-styling-nativewind\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"B\", frameworks: [\"react-native\"] },\n sources: [\"https://www.nativewind.dev\"],\n },\n \"mobile-styling-unistyles\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"B\", frameworks: [\"react-native\"] },\n sources: [\"https://www.unistyl.es\"],\n },\n \"mobile-testing-detox\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"B\", frameworks: [\"react-native\"] },\n sources: [\"https://github.com/wix/Detox\"],\n },\n \"mobile-testing-maestro\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"A\", frameworks: [] },\n sources: [\"https://docs.maestro.dev/get-started/supported-platform\"],\n deferredToD306:\n \"Needs an app Maestro can drive; the needsAny enumerates the catalog's current mobile-app producers (react-native, expo, tauri-mobile) — re-derive when that set changes.\",\n },\n \"mobile-ui-components-tamagui\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"C\", frameworks: [\"react-native\", \"react\"] },\n sources: [\"https://tamagui.dev/docs/intro/installation\", \"https://github.com/tamagui/tamagui\"],\n deferredToD306:\n \"Surfaces a mobile-domain UI kit in web-only stacks — a curation question for the web-ui-kit split (group #14), advice-level only.\",\n },\n \"mobile-ui-components-react-native-paper\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"B\", frameworks: [\"react-native\"] },\n sources: [\"https://callstack.github.io/react-native-paper/\"],\n },\n \"mobile-animation-reanimated\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"B\", frameworks: [\"react-native\"] },\n sources: [\"https://docs.swmansion.com/react-native-reanimated/\"],\n },\n \"mobile-animation-gesture-handler\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"B\", frameworks: [\"react-native\"] },\n sources: [\"https://docs.swmansion.com/react-native-gesture-handler/\"],\n },\n \"mobile-animation-skia\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"B\", frameworks: [\"react-native\"] },\n sources: [\"https://shopify.github.io/react-native-skia/\"],\n },\n \"mobile-storage-mmkv\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"B\", frameworks: [\"react-native\"] },\n sources: [\"https://github.com/mrousavy/react-native-mmkv\"],\n },\n \"mobile-storage-sqlite-powersync\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"B\", frameworks: [\"react-native\"] },\n sources: [\"https://docs.powersync.com/resources/supported-platforms\"],\n },\n \"mobile-storage-watermelondb\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"B\", frameworks: [\"react-native\"] },\n sources: [\"https://watermelondb.dev/docs/Implementation/DatabaseAdapters\"],\n deferredToD306:\n \"Upstream runs on React web via the LokiJS adapter; widen the binding if and only if the skill body ever covers it.\",\n },\n \"mobile-deployment-eas\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"B\", frameworks: [\"expo\"] },\n sources: [\"https://docs.expo.dev/build/introduction/\"],\n },\n \"mobile-camera-vision-camera\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"B\", frameworks: [\"react-native\"] },\n sources: [\"https://react-native-vision-camera.com\"],\n },\n \"mobile-hardware-ble-nfc\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"B\", frameworks: [\"react-native\"] },\n sources: [\n \"https://github.com/dotintent/react-native-ble-plx\",\n \"https://github.com/revtel/react-native-nfc-manager\",\n ],\n },\n \"mobile-notifications-push\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"B\", frameworks: [\"react-native\"] },\n sources: [\n \"https://docs.expo.dev/push-notifications/overview/\",\n \"https://rnfirebase.io/messaging/usage\",\n ],\n },\n \"mobile-background-tasks\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"B\", frameworks: [\"react-native\"] },\n sources: [\n \"https://docs.expo.dev/versions/latest/sdk/background-task/\",\n \"https://github.com/transistorsoft/react-native-background-fetch\",\n ],\n },\n \"mobile-deep-linking-app-links\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"B\", frameworks: [\"react-native\"] },\n sources: [\n \"https://docs.expo.dev/linking/overview/\",\n \"https://reactnavigation.org/docs/deep-linking/\",\n ],\n },\n \"mobile-performance-react-native\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"B\", frameworks: [\"react-native\"] },\n sources: [\"https://reactnative.dev/docs/performance\"],\n },\n \"mobile-security-react-native\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"mobile\",\n classification: { class: \"B\", frameworks: [\"react-native\"] },\n sources: [\n \"https://docs.expo.dev/versions/latest/sdk/securestore/\",\n \"https://github.com/oblador/react-native-keychain\",\n ],\n },\n\n // ── B10 — desktop (16) ──\n \"desktop-framework-electron\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"desktop\",\n },\n \"desktop-framework-tauri\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"desktop\",\n },\n \"desktop-ipc-electron\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"desktop\",\n classification: { class: \"B\", frameworks: [\"electron\"] },\n sources: [\"https://www.electronjs.org/docs/latest/tutorial/ipc\"],\n },\n \"desktop-storage-electron\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"desktop\",\n classification: { class: \"B\", frameworks: [\"electron\"] },\n sources: [\n \"https://www.electronjs.org/docs/latest/api/safe-storage\",\n \"https://github.com/sindresorhus/electron-store\",\n ],\n },\n \"desktop-ui-electron\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"desktop\",\n classification: { class: \"B\", frameworks: [\"electron\"] },\n sources: [\"https://www.electronjs.org/docs/latest/api/tray\"],\n },\n \"desktop-testing-electron\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"desktop\",\n classification: { class: \"B\", frameworks: [\"electron\"] },\n sources: [\"https://playwright.dev/docs/api/class-electron\"],\n },\n \"desktop-updates-electron-updater\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"desktop\",\n classification: { class: \"B\", frameworks: [\"electron\"] },\n sources: [\n \"https://github.com/electron-userland/electron-builder\",\n \"https://www.electron.build/auto-update\",\n ],\n deferredToD306:\n \"Defaults to the electron-builder pipeline (reads app-update.yml, written only by electron-builder's PublishManager); Forge apps using the Squirrel maker use Electron's built-in autoUpdater instead; Forge without Squirrel, and custom distributions, can still run electron-updater with custom config / generic provider.\",\n },\n \"desktop-multiwindow-electron\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"desktop\",\n classification: { class: \"B\", frameworks: [\"electron\"] },\n sources: [\"https://www.electronjs.org/docs/latest/api/base-window\"],\n },\n \"desktop-security-electron\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"desktop\",\n classification: { class: \"B\", frameworks: [\"electron\"] },\n sources: [\"https://www.electronjs.org/docs/latest/tutorial/fuses\"],\n },\n \"desktop-packaging-electron-forge\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"desktop\",\n classification: { class: \"B\", frameworks: [\"electron\"] },\n sources: [\"https://www.electronforge.io\"],\n },\n \"desktop-backend-tauri\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"desktop\",\n classification: { class: \"B\", frameworks: [\"tauri\"] },\n sources: [\"https://v2.tauri.app/develop/calling-rust/\"],\n },\n \"desktop-packaging-tauri\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"desktop\",\n classification: { class: \"B\", frameworks: [\"tauri\"] },\n sources: [\"https://v2.tauri.app/distribute/\"],\n },\n \"desktop-plugins-tauri\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"desktop\",\n classification: { class: \"B\", frameworks: [\"tauri\"] },\n sources: [\"https://v2.tauri.app/plugin/\"],\n },\n \"desktop-multiwindow-tauri\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"desktop\",\n classification: { class: \"B\", frameworks: [\"tauri\"] },\n sources: [\"https://v2.tauri.app/develop/calling-frontend/\"],\n },\n \"desktop-security-tauri\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"desktop\",\n classification: { class: \"B\", frameworks: [\"tauri\"] },\n sources: [\"https://v2.tauri.app/security/capabilities/\"],\n },\n \"desktop-mobile-tauri\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"desktop\",\n classification: { class: \"B\", frameworks: [\"tauri\"] },\n sources: [\n \"https://v2.tauri.app/reference/cli\",\n \"https://v2.tauri.app/blog/roadmap-to-tauri-2-0\",\n ],\n },\n\n // ── B11 — infra + CLI (15) ──\n \"infra-ci-cd-github-actions\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"infra-cli\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"infra-ci-cd-docker\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"infra-cli\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"infra-ci-cd-turborepo-ci\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"infra-cli\",\n classification: { class: \"B\", frameworks: [\"turborepo\"] },\n sources: [\"https://turborepo.dev/docs\"],\n },\n \"infra-config-setup-env\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"infra-cli\",\n classification: { class: \"C\", frameworks: [\"nextjs\", \"vite\"] },\n },\n \"infra-containers-kubernetes\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"infra-cli\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"infra-iac-terraform\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"infra-cli\",\n classification: { class: \"A\", frameworks: [] },\n deferredToD306:\n \"Layered terraform + pulumi coexistence via Pulumi's RemoteStateReference (a Pulumi program consuming the outputs of a Terraform-managed layer) is real at org scope; the radio models one engine per project.\",\n },\n \"infra-iac-pulumi\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"infra-cli\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"infra-iac-sst\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"infra-cli\",\n classification: { class: \"A\", frameworks: [] },\n deferredToD306:\n \"sst's typical data plane is @aws-sdk/client-* — the sst skill's own handlers import it; the pairing is recommended, not required, and platform-boundness (SST needs AWS-the-platform, which has no catalog anchor) is unrepresentable in the current vocabulary.\",\n },\n \"infra-platform-vercel\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"infra-cli\",\n classification: { class: \"A\", frameworks: [] },\n deferredToD306:\n \"vercel <-> netlify is a same-slot tension (one primary Git-centric host per app; monorepo split-hosting and migrations are the minority) and vercel <-> cloudflare-workers-as-host is the same shape — dubious combos, declined as fences.\",\n },\n \"infra-platform-netlify\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"infra-cli\",\n classification: { class: \"A\", frameworks: [] },\n deferredToD306:\n \"Carries the same dubious-combo record as vercel: vercel <-> netlify is a same-slot tension declined as a fence.\",\n },\n \"infra-platform-cloudflare-workers\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"infra-cli\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"infra-platform-aws-sdk\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"infra-cli\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"cli-framework-cli-commander\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"infra-cli\",\n },\n \"cli-framework-oclif-ink\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"infra-cli\",\n },\n \"cli-prompts-clack\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"infra-cli\",\n classification: { class: \"A\", frameworks: [] },\n },\n\n // ── B12 — shared + meta (23) ──\n \"shared-monorepo-turborepo\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"shared-monorepo-nx\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"shared-monorepo-pnpm-workspaces\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"shared-tooling-biome\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n deferredToD306:\n \"The steady-state Biome-as-formatter plus bare-ESLint-for-plugin-gaps hybrid is real; it is unrepresentable while the catalog's ESLint skill bundles Prettier. A future bare eslint skill reopens this radio's rationale.\",\n },\n \"shared-tooling-eslint-prettier\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"shared-tooling-typescript-config\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"shared-tooling-git-hooks\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"shared-tooling-changesets\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"meta-config-stack-detect\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"shared-security-auth-security\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"meta-design-expressive-typescript\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"meta-design-composable-components\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"shared-meta\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n sources: [\n 'skill body and all four example files (imports from \"react\"; @base-ui/react/use-render; @base-ui/react/merge-props; forwardRef; JSX-part composition)',\n ],\n },\n \"meta-methodology-research-methodology\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"meta-planning-web-planning\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"meta-planning-api-planning\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"meta-planning-cli-planning\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"meta-planning-ai-planning\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"meta-reviewing-reviewing\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"meta-reviewing-web-reviewing\": {\n audited: \"2026-08-07\",\n verdict: \"constrained-via-exclusivity-or-requires\",\n batch: \"shared-meta\",\n classification: { class: \"B\", frameworks: [\"react\"] },\n sources: [\n 'skill body self-scope (description \"Use when reviewing React components\"; When-to-use \".tsx/.jsx with JSX\"; \"React PR review\" auto-detection) plus a React-keyed majority (4 of 5 MUSTs, 6 of 7 patterns)',\n ],\n },\n \"meta-reviewing-api-reviewing\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"meta-reviewing-cli-reviewing\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"meta-reviewing-ai-reviewing\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n },\n \"meta-reviewing-infra-reviewing\": {\n audited: \"2026-08-07\",\n verdict: \"universal\",\n batch: \"shared-meta\",\n classification: { class: \"A\", frameworks: [] },\n },\n};\n\n/**\n * Rows whose verdict was recorded ahead of the category disposition that backs it, with the\n * batch that owns the change. Both audit checks skip exactly these and nothing else, so any\n * other divergence between the manifest and the rules fails immediately.\n *\n * Empty since every disposition the fan-out ruled on landed: the live rules now back all 238\n * verdicts on their own. It stays as the mechanism for the next audit that runs ahead of its\n * taxonomy — add an entry with the batch that owns it, and delete it when that lands. The\n * consistency test asserts this set matches the live gap exactly, so a stale entry fails just\n * as loudly as a missing one.\n */\nexport const auditVerdictsPendingApply: Partial<Record<SkillId, string>> = {};\n","import { warn } from \"../../utils/logger\";\nimport { LOCAL_PSEUDO_CATEGORY } from \"../../consts\";\nimport type {\n CategoryDefinition,\n CategoryPath,\n MergedSkillsMatrix,\n ResolvedSkill,\n SkillId,\n Category,\n} from \"../../types\";\nimport { isSkillId } from \"../../utils/type-guards\";\nimport { typedEntries } from \"../../utils/typed-object\";\nimport { skillAudit, auditVerdictsPendingApply } from \"../configuration/skill-audit\";\nimport type { SkillAuditEntry } from \"../configuration/skill-audit\";\n\n/**\n * Which check produced an issue. A closed union rather than a free string because a caller may\n * branch on one kind — `source-validator` weighs `rule-unresolved-slug` differently for the\n * author of a marketplace than for someone consuming it — and a misspelled branch there must be\n * a compile error rather than a condition that is quietly never true.\n */\ntype MatrixHealthFinding =\n | \"category-missing-domain\"\n | \"skill-unknown-category\"\n | \"skill-unresolved-relation-ref\"\n | \"rule-unresolved-slug\"\n | \"audit-verdict-contradiction\"\n | \"skill-unaudited\";\n\nexport type MatrixHealthIssue = {\n severity: \"warning\" | \"error\";\n finding: MatrixHealthFinding;\n details: string;\n};\n\nexport function checkMatrixHealth(matrix: MergedSkillsMatrix): MatrixHealthIssue[] {\n const issues = [\n ...checkCategoryDomains(matrix),\n ...checkSkillCategories(matrix),\n ...checkSkillRelationRefs(matrix),\n ...checkUnresolvedRuleSlugs(matrix),\n ...checkAuditVerdictContradictions(matrix),\n ...checkUnauditedSkills(matrix),\n ];\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): MatrixHealthIssue[] {\n return (\n typedEntries<Category, CategoryDefinition>(matrix.categories)\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n .filter(([, cat]) => cat !== undefined && !cat.domain)\n .map(([catId]) => ({\n severity: \"warning\" as const,\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\nfunction checkSkillCategories(matrix: MergedSkillsMatrix): MatrixHealthIssue[] {\n return typedEntries<SkillId, ResolvedSkill>(matrix.skills)\n .filter(\n ([, skill]) =>\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n skill !== undefined &&\n // \"local\" is a pseudo-category that won't exist in matrix.categories — skip it\n skill.category !== LOCAL_PSEUDO_CATEGORY &&\n !matrix.categories[skill.category],\n )\n .map(([skillId, skill]) => ({\n severity: \"warning\" as const,\n finding: \"skill-unknown-category\",\n details: `Skill '${skillId}' references category '${skill.category}' which does not exist in the matrix`,\n }));\n}\n\n/** Every outgoing relation reference on a skill, tagged with the field it came from. */\nfunction relationRefs(skill: ResolvedSkill): Array<{ field: string; ref: SkillId }> {\n return [\n ...skill.conflictsWith.map((relation) => ({ field: \"conflictsWith\", ref: relation.skillId })),\n ...skill.requires.flatMap((requirement) =>\n requirement.skillIds.map((ref) => ({ field: \"requires\", ref })),\n ),\n ];\n}\n\nfunction checkSkillRelationRefs(matrix: MergedSkillsMatrix): MatrixHealthIssue[] {\n return typedEntries<SkillId, ResolvedSkill>(matrix.skills).flatMap(([skillId, skill]) =>\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n skill === undefined\n ? []\n : relationRefs(skill)\n .filter(({ ref }) => !matrix.skills[ref])\n .map(({ field, ref }) => ({\n severity: \"warning\" as const,\n finding: \"skill-unresolved-relation-ref\",\n details: `Skill '${skillId}' has unresolved reference '${ref}' in '${field}'`,\n })),\n );\n}\n\n/**\n * A slug a relationship rule names that no skill carries. The rule containing it\n * states nothing — resolution drops the reference — so the source shipped a rule\n * that cannot act, which is a defect in the source rather than an advisory about\n * it. The CLI's own built-in rules are narrowed to the slugs a source ships\n * before resolution (CLI-471), so nothing here can be the CLI's doing.\n *\n * `error` is the AUTHOR's verdict, and it is the only one this module can reach: a matrix says\n * what is wrong with it and cannot say who is reading. Someone who merely installed from the\n * marketplace can neither open the file nor be harmed by it, and `source-validator` — the one\n * layer that knows which of the two is asking — serves them the same finding as a warning.\n */\nfunction checkUnresolvedRuleSlugs(matrix: MergedSkillsMatrix): MatrixHealthIssue[] {\n return (matrix.unresolvedSlugs ?? []).map((slug) => ({\n severity: \"error\" as const,\n finding: \"rule-unresolved-slug\",\n details: `Unresolved slug '${slug}' in the relationship rules — no skill carries it, so every rule naming it states nothing`,\n }));\n}\n\nfunction isExclusiveCategory(matrix: MergedSkillsMatrix, category: CategoryPath): boolean {\n // \"local\" is a pseudo-category with no definition in matrix.categories — never a fence\n if (category === LOCAL_PSEUDO_CATEGORY) return false;\n\n const definition = matrix.categories[category];\n return definition !== undefined && definition.exclusive;\n}\n\n/**\n * The one definition of \"this skill is fenced\" that the audit's two enforcement points — the\n * runtime contradiction check below and the manifest consistency test — must agree on. Post\n * decision 2 the only fences left are category exclusivity and `requires`.\n */\nexport function isFencedByMatrix(matrix: MergedSkillsMatrix, skillId: SkillId): boolean {\n const skill = matrix.skills[skillId];\n if (skill === undefined) return false;\n\n return skill.requires.length > 0 || isExclusiveCategory(matrix, skill.category);\n}\n\n/** Runtime lookup: the manifest is total over built-ins, but a matrix may carry source skills. */\nfunction auditEntryFor(skillId: SkillId): SkillAuditEntry | undefined {\n return Object.hasOwn(skillAudit, skillId) ? skillAudit[skillId] : undefined;\n}\n\nfunction fenceDescription(matrix: MergedSkillsMatrix, skill: ResolvedSkill): string {\n if (skill.requires.length > 0) return \"it carries a 'requires' rule\";\n return `its category '${skill.category}' is exclusive`;\n}\n\n/**\n * A `universal` verdict claims the skill is selectable beside anything; a `requires` rule or an\n * exclusive category says the opposite. Both cannot be true, so the pair is a contradiction and\n * the audit trail would be lying. Rows in `auditVerdictsPendingApply` are exempt — their verdict\n * was recorded ahead of a category disposition that has not landed yet.\n */\nfunction checkAuditVerdictContradictions(matrix: MergedSkillsMatrix): MatrixHealthIssue[] {\n return typedEntries<SkillId, ResolvedSkill>(matrix.skills)\n .filter(([skillId, skill]) => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n if (skill === undefined || auditVerdictsPendingApply[skillId]) return false;\n const audit = auditEntryFor(skillId);\n\n return audit?.verdict === \"universal\" && isFencedByMatrix(matrix, skillId);\n })\n .map(([skillId, skill]) => ({\n severity: \"error\" as const,\n finding: \"audit-verdict-contradiction\",\n details: `Skill '${skillId}' is audited 'universal' but ${fenceDescription(matrix, skill)}`,\n }));\n}\n\n/**\n * \"Unaudited\" means the manifest was expected to carry a verdict and does not, so the population\n * is the ids the manifest is keyed by: the built-in catalog's. A marketplace's skills carry that\n * marketplace's namespace and are outside the manifest by construction, not unaudited — warning\n * per skill for every one of them would cost a screen of noise and put a clean bill of health out\n * of reach for anyone not on the public catalog. Local skills are the user's own and were already\n * out of scope.\n *\n * `Record<SkillId, SkillAuditEntry>` covers the built-ins exhaustively at compile time, so what\n * remains here is that same totality asserted against a matrix whose keys are open strings at\n * runtime.\n */\nfunction checkUnauditedSkills(matrix: MergedSkillsMatrix): MatrixHealthIssue[] {\n return typedEntries<SkillId, ResolvedSkill>(matrix.skills)\n .filter(\n ([skillId, skill]) =>\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typedEntries/Object.entries launders the `| undefined` a Partial<Record> admits out of its result type, so this guard reads as dead while still covering an explicitly-undefined slot\n skill !== undefined &&\n !skill.local &&\n isSkillId(skillId) &&\n auditEntryFor(skillId) === undefined,\n )\n .map(([skillId]) => ({\n severity: \"warning\" as const,\n finding: \"skill-unaudited\",\n details: `Skill '${skillId}' has no audit verdict — the built-in audit manifest is missing an entry it is meant to carry`,\n }));\n}\n"],"mappings":"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ACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,IAAM,aAAa;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,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","names":["os","unique","path","os","path","os","path","os","path","os","CONTROL_CHAR_PATTERN","path","groupBy","BUILT_IN_MATRIX","z","z","BUILT_IN_MATRIX","matrix","allSkills","z","MODEL_NAMES","agentNameSchema","z","MODEL_NAMES","isAgentName","matrix","skillsById","matrix","z","z","skillRelationSchema","skillRequirementSchema","z","groupBy","indexBy","uniqueBy","os","path","path","groupBy","partition","partition","groupBy","path","path","os","indexBy","uniqueBy","path","groupBy","unique","path","matrix","groupBy","path","matrix","unique","path","path","path","path","path","NULL_BYTE_PATTERN","path","path","path","path","parseYaml","path","PLUGIN_MANIFEST_FILE","path","os","path","path","os","path","path","os","path","path","os","os","path","unique","createHash","os","path","unique","unique","configLoadFailure","createHash","path","os","os","matrix","os","path","pipe","flatMap","uniqueBy","path","z","z","path","path","path","os","path","os","path","os","path","os","path","partition","path","os","EXTRACTED_FIELDS","matrix","os","path","path","os","matrix","fs","isDeepEqual","unique","isDeepEqual","fs","matrix","isExclusiveCategory","unique","isDeepEqual","loadSkillsMatrixFromSource","matrix","os","path","ensureBlankPair","unique","path","os","z","os","SAFE_NAME_PATTERN","os","z","path","z","z","path","allSkills","path","path","readSkillMetadata","path","parseYaml","path","path","path","path","path","path","parseYaml","path","path","parseYaml","unique","uniqueBy","unique","uniqueBy","slug","groupBy","labelOf","groupBy","matrix","field","isExclusiveCategory","os","matrix","path","unique"]}