agents-inc 0.159.0 → 0.160.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.
- package/CHANGELOG.md +13 -0
- package/dist/{chunk-2Q65K6E3.js → chunk-5K33RJ7Z.js} +10 -10
- package/dist/{chunk-BQJVHD6Y.js → chunk-6CP3CLDE.js} +3 -8
- package/dist/chunk-6CP3CLDE.js.map +1 -0
- package/dist/{chunk-4VMLCWLD.js → chunk-7JQPIMKD.js} +2 -2
- package/dist/{chunk-5YOSLSQJ.js → chunk-C5P7RUDR.js} +3 -3
- package/dist/{chunk-G7TYOPON.js → chunk-CICB4AKA.js} +3 -3
- package/dist/{chunk-FBRLHNUT.js → chunk-CWQLRKWB.js} +3 -3
- package/dist/{chunk-JV4P7BL4.js → chunk-DEWI5HDF.js} +3 -3
- package/dist/{chunk-Z6G24ROK.js → chunk-EPBUWEW4.js} +4 -4
- package/dist/{chunk-IO2DPRDS.js → chunk-GWPKIXBM.js} +2 -2
- package/dist/{chunk-BNHD2GIB.js → chunk-IJ7GWQUR.js} +4 -4
- package/dist/{chunk-4RYWFQK7.js → chunk-IWUFZ6NR.js} +2 -2
- package/dist/{chunk-F35G42TF.js → chunk-J7Q5VYR7.js} +11 -11
- package/dist/{chunk-MPLWPWL4.js → chunk-JQDN7KAZ.js} +2 -2
- package/dist/{chunk-LSSGS2QS.js → chunk-K6MQV6SK.js} +3 -3
- package/dist/{chunk-YVQSDBTK.js → chunk-KCN5N3PB.js} +4 -4
- package/dist/{chunk-WVKGO3Y5.js → chunk-LJ6V54NR.js} +3 -3
- package/dist/{chunk-VCUXNKOY.js → chunk-LX7UXZBN.js} +5 -5
- package/dist/{chunk-VZRO7RYT.js → chunk-OI2H6M5I.js} +1 -103
- package/dist/chunk-OI2H6M5I.js.map +1 -0
- package/dist/{chunk-Z6KROWH4.js → chunk-OJR3ASZI.js} +5 -5
- package/dist/{chunk-V625APR6.js → chunk-OUG6TCQ4.js} +205 -335
- package/dist/chunk-OUG6TCQ4.js.map +1 -0
- package/dist/{chunk-62XKTOUI.js → chunk-PIUCYRLP.js} +5 -15
- package/dist/chunk-PIUCYRLP.js.map +1 -0
- package/dist/{chunk-WVBJRFFM.js → chunk-PWPKZNCV.js} +3 -3
- package/dist/{chunk-SKDTGHCD.js → chunk-Q2HB5SWU.js} +2 -2
- package/dist/{chunk-YAHTF4NO.js → chunk-RJ3JYZJ7.js} +8 -8
- package/dist/chunk-RJ3JYZJ7.js.map +1 -0
- package/dist/{chunk-LVA6XJGR.js → chunk-SLB2SFTX.js} +3 -27
- package/dist/chunk-SLB2SFTX.js.map +1 -0
- package/dist/{chunk-NS5COBTT.js → chunk-VH6P7UGF.js} +3 -3
- package/dist/{chunk-42PQKBVU.js → chunk-VI4X5DN5.js} +4 -4
- package/dist/{chunk-THLQS2AW.js → chunk-XDNGMXOZ.js} +4 -4
- package/dist/{chunk-GPZQCLZJ.js → chunk-XSULY25W.js} +5 -5
- package/dist/{chunk-7Z4N4JWQ.js → chunk-XX657S4U.js} +1 -103
- package/dist/chunk-XX657S4U.js.map +1 -0
- package/dist/commands/build/marketplace.js +6 -6
- package/dist/commands/build/plugins.js +6 -6
- package/dist/commands/compile.js +9 -9
- package/dist/commands/doctor.js +9 -9
- package/dist/commands/edit.js +28 -28
- package/dist/commands/eject.js +9 -9
- package/dist/commands/init.js +28 -28
- package/dist/commands/list.js +7 -7
- package/dist/commands/new/marketplace.js +6 -7
- package/dist/commands/new/marketplace.js.map +1 -1
- package/dist/commands/search.js +9 -9
- package/dist/commands/share.js +7 -7
- package/dist/commands/uninstall.js +9 -9
- package/dist/commands/update.js +5 -5
- package/dist/components/wizard/category-grid.js +2 -2
- package/dist/components/wizard/domain-selection.js +6 -6
- package/dist/components/wizard/run-wizard-session.js +19 -19
- package/dist/components/wizard/skill-agent-summary.js +5 -5
- package/dist/components/wizard/source-grid.js +2 -2
- package/dist/components/wizard/stack-selection.js +5 -5
- package/dist/components/wizard/step-agents.js +6 -6
- package/dist/components/wizard/step-build.js +6 -6
- package/dist/components/wizard/step-confirm.js +8 -8
- package/dist/components/wizard/step-sources.js +6 -6
- package/dist/components/wizard/step-stack.js +6 -6
- package/dist/components/wizard/summary-panel.js +7 -7
- package/dist/components/wizard/wizard-layout.js +8 -8
- package/dist/components/wizard/wizard.js +18 -18
- package/dist/config-exports.js +1 -1
- package/dist/hooks/init.js +28 -28
- package/dist/load-agent-defs-KWHG7P7G.js +13 -0
- package/dist/recompile-project-agents-5FTDDHX7.js +17 -0
- package/dist/{source-loader-CC6ZWKTI.js → source-loader-CDYH2NIM.js} +4 -4
- package/dist/src/agents/_templates/methodologies/anti-over-engineering.liquid +14 -0
- package/dist/src/agents/_templates/methodologies/context-management.liquid +7 -154
- package/dist/src/agents/_templates/methodologies/investigation-requirements.liquid +12 -0
- package/dist/src/agents/_templates/methodologies/success-criteria.liquid +10 -0
- package/dist/stores/wizard-store.js +4 -4
- package/package.json +1 -1
- package/src/agents/_templates/methodologies/anti-over-engineering.liquid +14 -0
- package/src/agents/_templates/methodologies/context-management.liquid +7 -154
- package/src/agents/_templates/methodologies/investigation-requirements.liquid +12 -0
- package/src/agents/_templates/methodologies/success-criteria.liquid +10 -0
- package/dist/chunk-62XKTOUI.js.map +0 -1
- package/dist/chunk-7Z4N4JWQ.js.map +0 -1
- package/dist/chunk-BQJVHD6Y.js.map +0 -1
- package/dist/chunk-LVA6XJGR.js.map +0 -1
- package/dist/chunk-V625APR6.js.map +0 -1
- package/dist/chunk-VZRO7RYT.js.map +0 -1
- package/dist/chunk-YAHTF4NO.js.map +0 -1
- package/dist/load-agent-defs-2H42B2OO.js +0 -13
- package/dist/recompile-project-agents-QIAMBCM4.js +0 -17
- /package/dist/{chunk-2Q65K6E3.js.map → chunk-5K33RJ7Z.js.map} +0 -0
- /package/dist/{chunk-4VMLCWLD.js.map → chunk-7JQPIMKD.js.map} +0 -0
- /package/dist/{chunk-5YOSLSQJ.js.map → chunk-C5P7RUDR.js.map} +0 -0
- /package/dist/{chunk-G7TYOPON.js.map → chunk-CICB4AKA.js.map} +0 -0
- /package/dist/{chunk-FBRLHNUT.js.map → chunk-CWQLRKWB.js.map} +0 -0
- /package/dist/{chunk-JV4P7BL4.js.map → chunk-DEWI5HDF.js.map} +0 -0
- /package/dist/{chunk-Z6G24ROK.js.map → chunk-EPBUWEW4.js.map} +0 -0
- /package/dist/{chunk-IO2DPRDS.js.map → chunk-GWPKIXBM.js.map} +0 -0
- /package/dist/{chunk-BNHD2GIB.js.map → chunk-IJ7GWQUR.js.map} +0 -0
- /package/dist/{chunk-4RYWFQK7.js.map → chunk-IWUFZ6NR.js.map} +0 -0
- /package/dist/{chunk-F35G42TF.js.map → chunk-J7Q5VYR7.js.map} +0 -0
- /package/dist/{chunk-MPLWPWL4.js.map → chunk-JQDN7KAZ.js.map} +0 -0
- /package/dist/{chunk-LSSGS2QS.js.map → chunk-K6MQV6SK.js.map} +0 -0
- /package/dist/{chunk-YVQSDBTK.js.map → chunk-KCN5N3PB.js.map} +0 -0
- /package/dist/{chunk-WVKGO3Y5.js.map → chunk-LJ6V54NR.js.map} +0 -0
- /package/dist/{chunk-VCUXNKOY.js.map → chunk-LX7UXZBN.js.map} +0 -0
- /package/dist/{chunk-Z6KROWH4.js.map → chunk-OJR3ASZI.js.map} +0 -0
- /package/dist/{chunk-WVBJRFFM.js.map → chunk-PWPKZNCV.js.map} +0 -0
- /package/dist/{chunk-SKDTGHCD.js.map → chunk-Q2HB5SWU.js.map} +0 -0
- /package/dist/{chunk-NS5COBTT.js.map → chunk-VH6P7UGF.js.map} +0 -0
- /package/dist/{chunk-42PQKBVU.js.map → chunk-VI4X5DN5.js.map} +0 -0
- /package/dist/{chunk-THLQS2AW.js.map → chunk-XDNGMXOZ.js.map} +0 -0
- /package/dist/{chunk-GPZQCLZJ.js.map → chunk-XSULY25W.js.map} +0 -0
- /package/dist/{load-agent-defs-2H42B2OO.js.map → load-agent-defs-KWHG7P7G.js.map} +0 -0
- /package/dist/{recompile-project-agents-QIAMBCM4.js.map → recompile-project-agents-5FTDDHX7.js.map} +0 -0
- /package/dist/{source-loader-CC6ZWKTI.js.map → source-loader-CDYH2NIM.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/utils/errors.ts","../src/cli/utils/fs.ts","../src/cli/lib/config-gate/gate-token.ts","../src/cli/utils/logger.ts","../src/cli/types/generated/source-types.ts","../src/cli/utils/type-guards.ts","../src/cli/lib/configuration/config.ts","../src/cli/lib/validate-kebab-name.ts","../src/cli/utils/messages.ts","../src/cli/lib/schemas.ts","../src/cli/lib/schema-validator.ts","../src/cli/types/matrix.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-ref.ts","../src/cli/lib/plugins/plugin-finder.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/loader.ts","../src/cli/utils/frontmatter.ts","../src/cli/lib/loading/source-fetcher.ts","../src/cli/lib/loading/multi-source-loader.ts","../src/cli/lib/resolver.ts","../src/cli/utils/exec.ts","../src/cli/lib/installation/mode-migrator.ts","../src/cli/lib/plugins/plugin-validator.ts","../src/cli/lib/validation-result.ts","../src/cli/lib/plugins/plugin-settings.ts","../src/cli/lib/plugins/plugin-discovery.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 CategoryDefinition,\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 { isAgentName } from \"../../utils/type-guards\";\nimport { typedEntries, typedFromEntries, typedKeys, typedValues } 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 MarketplaceNameRefusedError,\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 // ABORT on an unreadable config. Every skill this returns is resolved against the marketplace\n // named here, so a run that got past this rung on a config it could not read would install from\n // a marketplace nobody chose — which is the whole of what the refusal exists to stop.\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 },\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 * Four states rather than two because the failures are not one event: a marketplace with\n * no manifest is an ordinary local directory, one whose manifest is there and unreadable\n * is a broken publication that can still be installed from, and one that publishes under\n * a name Claude Code registers no plugin under can be installed from at all. Collapsing\n * the first two reported every schema violation in that file as an absent file, and a\n * reader who checked found it exactly where the message said it was not; collapsing the\n * last two turned the rule `build marketplace` refuses to publish under into a warning\n * printed above a green tick. `doctor`'s `ConfigState` splits its own the same way and\n * for the same reason.\n */\ntype ManifestState =\n | { kind: \"absent\" }\n | { kind: \"refused\"; reason: string }\n | { kind: \"unreadable\"; reason: string }\n | { kind: \"named\"; name: string };\n\n/**\n * {@link ManifestState} for one marketplace. Which failure it was is read off the throw's\n * TYPE rather than its text: `fetchMarketplace` is the only thing that can tell a file it\n * never found from one it found and refused, and a refused NAME from every other refusal,\n * 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 if (error instanceof MarketplaceNameRefusedError) {\n return { kind: \"refused\", reason: getErrorMessage(error) };\n }\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 *\n * This is where each {@link ManifestState} says whether it ABORTS or DEGRADES, and the\n * two answers are not interchangeable. A manifest that cannot be READ leaves a\n * marketplace whose skills still install, so the load carries on under a label the\n * config or the ref supplies. A manifest that names the marketplace something Claude\n * Code registers no plugin under leaves nothing installable at all, so it ABORTS —\n * carrying on labelled the marketplace by its ref, installed under a name nobody chose,\n * and let `doctor` print a green tick directly beneath its own warning about that file.\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 \"refused\":\n throw new MarketplaceNameRefusedError(state.reason);\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 const matrix = await loadAndMergeFromBasePath(marketplaceDir, marketplaceDir);\n return { ...matrix, categories: categoriesTheseSkillsAreIn(matrix) };\n}\n\n/**\n * The categories a marketplace's own skills are in, and nothing else.\n *\n * {@link loadAndMergeFromBasePath} merges the built-in taxonomy underneath the\n * marketplace's own, so a skill sitting in a built-in category resolves to that\n * category's real definition rather than the humanized stand-in\n * `synthesizeCategory` writes. Right for the merge and wrong for the artefact: a\n * published catalogue cannot claim categories the marketplace ships nothing in,\n * and 102 of them arrived that way — beside a `skills` and a `suggestedStacks`\n * that were the marketplace's own.\n *\n * Membership is read off the SKILLS rather than off the marketplace's own\n * `skill-categories.ts`, because the two disagree in both directions: a skill may\n * sit in a category its author never declared, and a declared category may hold\n * nothing. Narrowing by what is declared would leave a consumer holding a skill\n * whose category the catalogue does not define, which is this bug with the sides\n * swapped.\n */\nfunction categoriesTheseSkillsAreIn(matrix: MergedSkillsMatrix): CategoryMap {\n const occupied = new Set<CategoryPath>(typedValues(matrix.skills).map((skill) => skill.category));\n\n return typedFromEntries(\n typedEntries<Category, CategoryDefinition>(matrix.categories).filter(([id]) =>\n occupied.has(id),\n ),\n );\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 // ABORT on an unreadable config. This file is where a marketplace declares which directories\n // its skills and stacks live in, so falling back to the defaults would walk a tree the\n // marketplace says is somewhere else and report the catalogue as empty.\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/**\n * A stack's sub-agents split by whether the CLI declares one.\n *\n * The keys are read as the STRINGS a stack file spells: `typedKeys` types them `AgentName` because\n * `Stack[\"agents\"]` is keyed by it, but they arrive from a marketplace's own `config/stacks.ts` and\n * nothing between that file and here narrows them — so the membership test below is a real\n * question rather than a formality, and the widening is what lets it be asked.\n *\n * Narrowed with `isAgentName` and deliberately NOT cast. Only the CLI's own `src/agents/` declares\n * a sub-agent a compile pass can honour — that directory is the whole of the roster (owner ruling\n * 2026-08-21) and is what `AGENT_NAMES` is generated from — so this is the union's own membership\n * test rather than a second list to keep in step.\n */\nfunction declaredAgentsIn(stack: Stack): { declared: AgentName[]; undeclared: string[] } {\n const named: string[] = typedKeys<AgentName>(stack.agents);\n return {\n declared: named.filter(isAgentName),\n undeclared: named.filter((name) => !isAgentName(name)),\n };\n}\n\n/**\n * What a stack naming a sub-agent the CLI does not ship is told to the user.\n *\n * The stack is DROPPED FROM rather than refused, and that posture is deliberate. A stack is a\n * suggestion the wizard offers, not an install contract, so refusing it would take every\n * sub-agent in it — the valid ones included — over one typo in a marketplace the user may not\n * own. It is also the posture the rest of this conversion already takes: `resolveStackAgentSkills`\n * drops a skill id the matrix does not carry, and one function answering the same question two\n * ways is worse than either answer. Contrast `refuseCatalogueCollisions` above, which refuses\n * the whole source because a colliding id is UNSAFE — two marketplaces silently shadowing each\n * other on disk — where an undeclared sub-agent is merely uncompilable.\n *\n * What the drop must not be is SILENT, which is what it was: the wizard narrowed these names\n * out of its own grid and told nobody. `warn()` is buffered during a source load and painted as\n * the wizard's startup band, so this reaches the user rather than a stderr the first repaint\n * scrolls away. The stack is named because a marketplace ships many, and the sub-agents are\n * named rather than counted because only the name says what to fix.\n */\nfunction undeclaredAgentsWarning(stack: Stack, undeclared: readonly string[]): string {\n const named = undeclared.map((name) => `'${name}'`).join(\", \");\n return (\n `Stack '${stack.id}' names ${undeclared.length} sub-agent(s) this CLI does not define: ` +\n `${named}. Left out of the stack — a sub-agent must be one the CLI ships.`\n );\n}\n\n/**\n * What a stack naming a skill the catalogue does not carry is told to the user.\n *\n * The skill counterpart of {@link undeclaredAgentsWarning}, and it exists for the same reason: a\n * marketplace's `config/stacks.ts` is authored by hand against a catalogue that moves, so a stack\n * outliving one of its own skills is an ordinary authoring mistake rather than a corrupt file.\n */\nfunction withdrawnSkillsWarning(stack: Stack, withdrawn: readonly string[]): string {\n const named = withdrawn.map((id) => `'${id}'`).join(\", \");\n return (\n `Stack '${stack.id}' names ${withdrawn.length} skill(s) this marketplace's catalogue does ` +\n `not carry: ${named}. Left out of the stack — selecting it would install nothing.`\n );\n}\n\n// Stack values are already skill IDs — no alias resolution needed\nexport function convertStackToResolvedStack(stack: Stack): ResolvedStack {\n const { declared, undeclared } = declaredAgentsIn(stack);\n if (undeclared.length > 0) warn(undeclaredAgentsWarning(stack, undeclared));\n\n const agentConfigs = declared.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 — and filtered\n // against the matrix by the SAME question `resolveStackAgentSkills` asks above. The two used to\n // disagree: the per-category map kept only ids the catalogue carried while this list kept every\n // id the file named, and this is the one that reaches a user. `wizard.tsx` returns it verbatim\n // as the selection when a stack is picked, and the editor's read-model counts and lists it — so\n // a stack outliving one of its own skills selected an id nothing could resolve, and the mismatch\n // surfaced only once somebody picked that stack.\n const named = unique(\n agentConfigs.flatMap(({ agentConfig }) =>\n resolveAgentConfigToSkills(agentConfig).map((ref) => ref.id),\n ),\n );\n const allSkillIds = named.filter((id) => id in currentMatrix.skills);\n const withdrawn = named.filter((id) => !(id in currentMatrix.skills));\n if (withdrawn.length > 0) warn(withdrawnSkillsWarning(stack, withdrawn));\n\n verbose(\n `Stack '${stack.id}' has ${allSkillIds.length} skills from ${agentConfigs.length} agents`,\n );\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 * 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 every\n // slug a user had written themselves resolved to nothing.\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 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 * as every home-dir reader in the codebase now does, so it agrees with test\n * 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 CUSTOM: \"custom\",\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","/** Extract a human-readable message from an unknown error value. */\nexport function getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import fs from \"fs-extra\";\nimport fg from \"fast-glob\";\nimport os from \"os\";\nimport path from \"path\";\nimport { CLAUDE_SRC_DIR, STANDARD_FILES } from \"../consts\";\n// The gate's private token module, imported here by exception (eslint records\n// it): this file is the write choke point every pair write funnels through, and\n// `gate-token.ts` is a dependency-free leaf, so the import cannot cycle.\nimport { assertGateToken } from \"../lib/config-gate/gate-token.js\";\n\n/**\n * True when `child` resolves to `parent` or inside it. Purely lexical\n * (no symlink resolution) — the caller decides throw-vs-warn policy.\n */\nexport function isPathWithin(child: string, parent: string): boolean {\n const resolvedChild = path.resolve(child);\n const resolvedParent = path.resolve(parent);\n return resolvedChild === resolvedParent || resolvedChild.startsWith(resolvedParent + path.sep);\n}\n\nexport async function readFile(filePath: string): Promise<string> {\n return fs.readFile(filePath, \"utf-8\");\n}\n\n/**\n * Reads a file with a size limit check before reading content.\n * Throws if the file exceeds maxSizeBytes. Prevents DoS from oversized files.\n */\nexport async function readFileSafe(filePath: string, maxSizeBytes: number): Promise<string> {\n const stats = await fs.stat(filePath);\n if (stats.size > maxSizeBytes) {\n throw new Error(\n `File too large: '${filePath}' is ${stats.size} bytes (limit: ${maxSizeBytes} bytes)`,\n );\n }\n return fs.readFile(filePath, \"utf-8\");\n}\n\nexport async function readFileOptional(filePath: string, fallback = \"\"): Promise<string> {\n try {\n return await fs.readFile(filePath, \"utf-8\");\n } catch {\n return fallback;\n }\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n return fs.pathExists(filePath);\n}\n\nexport async function directoryExists(dirPath: string): Promise<boolean> {\n try {\n const stat = await fs.stat(dirPath);\n return stat.isDirectory();\n } catch {\n return false;\n }\n}\n\nexport async function listDirectories(dirPath: string): Promise<string[]> {\n try {\n const entries = await fs.readdir(dirPath, { withFileTypes: true });\n return entries.filter((e) => e.isDirectory()).map((e) => e.name);\n } catch {\n return [];\n }\n}\n\n/**\n * @param dot Include files and directories whose name starts with a dot. Off by default, which\n * is what a scan LOOKING for something wants; a read that has to reproduce a directory\n * faithfully wants it on, since a file the read skips is one the copy silently loses.\n */\nexport async function glob(\n pattern: string,\n cwd: string,\n { dot = false }: { dot?: boolean } = {},\n): Promise<string[]> {\n return fg(pattern, { cwd, onlyFiles: true, dot });\n}\n\n/**\n * True when `resolvedPath` is one of the two halves of the global config pair.\n *\n * Compares resolved paths rather than matching on the filename, so it holds\n * against every way of naming the same file — a concatenated path, a relative\n * one, a fragment assembled at runtime — which is exactly what a static check\n * cannot do.\n */\nfunction isGlobalPairPath(resolvedPath: string): boolean {\n const globalConfigDir = path.join(os.homedir(), CLAUDE_SRC_DIR);\n return (\n resolvedPath === path.join(globalConfigDir, STANDARD_FILES.CONFIG_TS) ||\n resolvedPath === path.join(globalConfigDir, STANDARD_FILES.CONFIG_TYPES_TS)\n );\n}\n\nexport async function writeFile(filePath: string, content: string): Promise<void> {\n // Runtime tripwire: every write in the CLI funnels through here, so a pair\n // write attempted without the gate's token dies at its first execution\n // whatever route it took to get here. Costs one path compare per write.\n const resolvedPath = path.resolve(filePath);\n if (isGlobalPairPath(resolvedPath)) assertGateToken(resolvedPath);\n\n await fs.ensureDir(path.dirname(filePath));\n await fs.writeFile(filePath, content, \"utf-8\");\n}\n\nexport async function ensureDir(dirPath: string): Promise<void> {\n await fs.ensureDir(dirPath);\n}\n\nexport async function remove(filePath: string): Promise<void> {\n await fs.remove(filePath);\n}\n\n/**\n * True when `dirPath` holds nothing, and true when it cannot be read at all —\n * an absent directory holds nothing either. Both callers ask the same question\n * of a directory they are about to write into or remove.\n */\nexport async function isDirectoryEmpty(dirPath: string): Promise<boolean> {\n try {\n const entries = await fs.readdir(dirPath);\n return entries.length === 0;\n } catch {\n return true;\n }\n}\n\n/**\n * Removes `dir` when it exists and holds nothing; true when it was removed.\n *\n * A scope directory (`.claude/skills/`, `.claude/agents/`) is an artefact of\n * what it holds, so the removal that empties it takes it too. Emptiness here is\n * FILESYSTEM emptiness and never roster emptiness — a hand-authored agent or any\n * other user-owned file keeps its directory alive, whatever a config says.\n */\nexport async function removeDirIfEmpty(dir: string): Promise<boolean> {\n if (!(await directoryExists(dir))) return false;\n if (!(await isDirectoryEmpty(dir))) return false;\n await remove(dir);\n return true;\n}\n\n/**\n * Copies a tree into an installation, and makes what it wrote writable by its new owner.\n *\n * **`eject` means the user owns the copy**, so the copy has to be editable however the SOURCE\n * happened to be stored. `fs-extra` preserves mode, and nothing normalised it: a marketplace on a\n * read-only mount, in a Nix store path, or written under a restrictive umask produced skills the\n * user could not subsequently edit — and the failure did not surface at the install. It surfaced\n * later, at an unrelated `edit` or mode switch, as `EACCES` on a file the user never made\n * read-only. Every caller of this function is an install or an eject, so every destination is the\n * user's.\n *\n * The owner's write bit is ADDED rather than the mode replaced. A skill may legitimately ship an\n * executable script, and flattening to `644` would break it on the way in — the destination should\n * differ from the source in exactly one respect, which is that its owner can write it.\n *\n * Directories take the same bit for the same reason: a read-only directory refuses a file added\n * beside the copy, which is what an eject-then-edit does next.\n */\nexport async function copy(src: string, dest: string): Promise<void> {\n await fs.copy(src, dest);\n await grantOwnerWrite(dest);\n}\n\nconst OWNER_WRITE = 0o200;\n\nasync function grantOwnerWrite(target: string): Promise<void> {\n const entry = await fs.stat(target);\n await fs.chmod(target, entry.mode | OWNER_WRITE);\n\n if (!entry.isDirectory()) return;\n\n const children = await fs.readdir(target);\n await Promise.all(children.map((child) => grantOwnerWrite(path.join(target, child))));\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\n\n/**\n * The write privilege for the global config pair (`~/.claude-src/config.ts` and\n * its `config-types.ts` sibling).\n *\n * AsyncLocalStorage rather than a module-level boolean: pair writes are async\n * and interleave, so a flag one write clears while another is still in flight\n * revokes a privilege that is still held. The store is scoped to the call tree\n * that opened it, which is exactly the grant being modelled.\n */\nconst gateToken = new AsyncLocalStorage<true>();\n\n/**\n * Thrown when the global pair is written from outside the gate. Names the\n * offending path and the only supported entry point, because every occurrence\n * is a code path that must be moved rather than a user-recoverable condition.\n */\nexport class GlobalPairWriteViolation extends Error {\n constructor(targetPath: string) {\n super(\n `${targetPath} may only be written through config-gate — see src/cli/lib/config-gate/index.ts`,\n );\n this.name = \"GlobalPairWriteViolation\";\n }\n}\n\n/** Runs `fn` holding the pair-write privilege. */\nexport function withGateToken<T>(fn: () => Promise<T>): Promise<T> {\n return gateToken.run(true, fn);\n}\n\n/** True while the current async call tree holds the pair-write privilege. */\nexport function hasGateToken(): boolean {\n return gateToken.getStore() === true;\n}\n\n/** Throws unless the caller holds the pair-write privilege. */\nexport function assertGateToken(targetPath: string): void {\n if (hasGateToken()) return;\n throw new GlobalPairWriteViolation(targetPath);\n}\n","// Logging utility for lib/ modules that don't have access to oclif command context.\n// In oclif commands, prefer using this.log() instead.\n\nlet verboseMode = false;\n\nexport function setVerbose(enabled: boolean): void {\n verboseMode = enabled;\n}\n\nexport function verbose(msg: string): void {\n if (verboseMode) {\n console.log(` ${msg}`);\n }\n}\n\n// Always visible (not gated by verbose mode).\n// Used for user-facing progress output: compilation ticks, summaries, validation results.\nexport function log(msg: string): void {\n console.log(msg);\n}\n\n// --- Startup message buffering ---\n// When buffer mode is enabled (before Ink takes over the terminal), warn() pushes\n// messages into a buffer instead of writing to stderr. The buffer is drained and\n// handed to the wizard, which paints it as a band above the step — stderr is what\n// the wizard's clearTerminal wipes, so a line written there is a line lost.\n\nexport type StartupMessage = {\n level: \"info\" | \"warn\" | \"error\";\n text: string;\n};\n\nlet bufferMode = false;\nlet messageBuffer: StartupMessage[] = [];\n\nexport function enableBuffering(): void {\n bufferMode = true;\n messageBuffer = [];\n}\n\nexport function drainBuffer(): StartupMessage[] {\n const messages = [...messageBuffer];\n messageBuffer = [];\n return messages;\n}\n\nexport function disableBuffering(): void {\n bufferMode = false;\n messageBuffer = [];\n}\n\n// Always visible (not gated by verbose mode).\n// Used for issues the user should know about, like unresolved references.\n//\n// Error/warning message style guide:\n// - Start with a capital letter (restructure if it would capitalize a function name)\n// - End with a period if it's a complete sentence\n// - End without a period if it's a fragment (e.g., \"Skipping 'foo': missing SKILL.md\")\n// - Wrap dynamic values in single quotes: 'value' (not bare or double-quoted)\n// - Do NOT prefix the message with \"Warning:\" — this function adds it automatically\n// - After a colon, use lowercase (e.g., \"Skipping 'foo': invalid frontmatter\")\n// - Use em dash for supplemental info (e.g., \"Missing category — defaulting to 'local'\")\nexport type WarnOptions = {\n /**\n * When true, suppresses this warning in a UNIT run — the gate reads `VITEST` from the\n * environment of the process evaluating it, so it can only ever mean that. Every E2E runner\n * hands the spawned binary `VITEST: undefined`, so an E2E run of the real binary is a test\n * environment in which this warning IS printed. Which runners those are is not a number worth\n * carrying here — it said \"Both\" while there were three, and the third was clearing nothing at\n * all; `src/cli/lib/__tests__/e2e-runner-environment.test.ts` derives the roster and is the\n * only place that count is correct by construction.\n */\n suppressInTest?: boolean;\n};\n\nexport function warn(msg: string, options?: WarnOptions): void {\n if (options?.suppressInTest && process.env.VITEST) {\n return;\n }\n if (bufferMode) {\n messageBuffer.push({ level: \"warn\", text: msg });\n return;\n }\n console.warn(` Warning: ${msg}`);\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","import {\n CATEGORIES,\n DOMAINS,\n AGENT_NAMES,\n SKILL_IDS,\n SKILL_SLUGS,\n} from \"../types/generated/source-types\";\nimport type {\n Category,\n Domain,\n AgentName,\n SkillId,\n SkillSlug,\n} from \"../types/generated/source-types\";\nimport type { CategoryPath, SkillAssignment } from \"../types/skills\";\nimport { LOCAL_PSEUDO_CATEGORY } from \"../consts\";\n\n/** Narrows unknown parse output to a plain object record (rejects arrays and primitives). */\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Runtime check that a string is a valid Category value from the generated union */\nexport function isCategory(value: string): value is Category {\n return (CATEGORIES as readonly string[]).includes(value);\n}\n\n/** Runtime check that a string is a valid Domain value from the generated union */\nexport function isDomain(value: string): value is Domain {\n return (DOMAINS as readonly string[]).includes(value);\n}\n\n/** Runtime check that a string is a valid AgentName value from the generated union */\nexport function isAgentName(value: string): value is AgentName {\n return (AGENT_NAMES as readonly string[]).includes(value);\n}\n\n/** Runtime check that a string is a valid CategoryPath (Category | \"local\") */\nexport function isCategoryPath(value: string): value is CategoryPath {\n return value === LOCAL_PSEUDO_CATEGORY || isCategory(value);\n}\n\n/** Runtime check that a string is a valid SkillId from the generated union */\nexport function isSkillId(value: string): value is SkillId {\n return (SKILL_IDS as readonly string[]).includes(value);\n}\n\n/** Runtime check that a string is a valid SkillSlug from the generated union */\nexport function isSkillSlug(value: string): value is SkillSlug {\n return (SKILL_SLUGS as readonly string[]).includes(value);\n}\n\n/**\n * Structural check for a SkillAssignment object (`{ id, preloaded? }`).\n * The id's SkillId-ness is structural, not union-checked: assignments flow from\n * runtime sources whose skills may not be in the generated union.\n */\nexport function isSkillAssignment(value: unknown): value is SkillAssignment {\n if (typeof value !== \"object\" || value === null) return false;\n // Boundary cast: probing an unknown object's field inside the guard\n return typeof (value as { id?: unknown }).id === \"string\";\n}\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 { configUnreadableError } from \"../../utils/messages\";\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\n/**\n * Reads the settings config at `dir`, or answers `null` when there is none to read.\n *\n * **A file that EXISTS and cannot be loaded is raised, never reported as absence** (owner ruling\n * 2026-08-20). `resolveSource` reads the return value alone, so a swallowed failure was\n * indistinguishable from a config that is not there: the run walked past this rung to\n * {@link DEFAULT_SOURCE} and installed from a marketplace nobody named, while the config naming a\n * private one sat unread on disk. All three ways a config can fail are on the loud side of that\n * line now — a shape the schema refused, a module whose exports are all named, and a file that\n * could not be evaluated at all, which was the one still reported as `null`.\n *\n * A MISSING file keeps its `null`, and that is the whole of what `null` means here: the legitimate\n * state `init` exists for, and the state `edit` reports as \"no installation\".\n *\n * Every call site chose a posture and states it where it stands. All but one ABORT: the marketplace\n * a run installs from is not a thing to guess at, and the two sites that read this file to locate a\n * marketplace's own skills or agent partials would otherwise walk a tree it says is elsewhere. The\n * exception is `validateRegisteredSources`, which DEGRADES — a command whose job is naming what is\n * wrong here has to survive the thing it is naming, so `doctor`'s `safeCheck` turns the raise into\n * a failed row and its `readsConfig: true` rows stand down before reaching here at all. Two further\n * sites are unreachable rather than chosen: `mergeWithExistingConfig` loads the full config first,\n * and `ensureMinimalConfig` reads only where the file is absent.\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 const data = await readSourceConfigOrRefuse(configPath);\n if (!data) return null;\n\n verbose(`Loaded ${scope} config from ${dir}`);\n return data;\n}\n\n/**\n * The config at `configPath`, or `null` when it evaluated and declared nothing.\n *\n * Every way of failing raises. Split out from {@link loadSourceConfig} so that function's own body\n * reads as the two states it answers — no file, or a config — with the third state, a file that\n * will not load, named once here rather than assembled from a `let` and a `try`.\n */\nasync function readSourceConfigOrRefuse(\n configPath: string,\n): Promise<Partial<ProjectConfig> | null> {\n try {\n return await loadConfig(configPath, projectSourceConfigSchema);\n } catch (error) {\n if (describesItsOwnFault(error)) throw error;\n throw unreadableSourceConfig(error);\n }\n}\n\n/**\n * Whether a load failure already names the field or the export at fault, and so is handed on as\n * itself rather than re-worded.\n *\n * The two it admits fault a LINE of a file the user still owns and can go and correct. Everything\n * else says only that the file would not evaluate, which is what {@link unreadableSourceConfig}\n * exists to turn into a way out.\n */\nfunction describesItsOwnFault(error: unknown): boolean {\n return error instanceof ConfigSchemaError || error instanceof ConfigDefaultExportError;\n}\n\n/**\n * The refusal for a config that exists and cannot be evaluated.\n *\n * `loadConfig` already names the file and the parser's own reason — `Failed to load config from\n * '<path>': ParseError: Missing semicolon` — so the cause is handed straight to\n * {@link configUnreadableError} rather than restated. That builder is what `BaseCommand`'s\n * `ensureConfigReadable` prints for the OTHER loader of this very file, so both readers refuse it\n * in one vocabulary and offer the one route that clears it: `uninstall` still works on a config it\n * cannot read.\n */\nfunction unreadableSourceConfig(cause: unknown): Error {\n return new Error(configUnreadableError(getErrorMessage(cause)), { cause });\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};\n\n/**\n * Branding resolved per FIELD: this project's, then the global one's, then the shipped default.\n *\n * Per field rather than per file, and that distinction is the whole of this function. Everything\n * else reads {@link loadEffectiveSourceConfig}, which answers with the project's config if that\n * FILE exists and the global one otherwise — right for `marketplace`, where a project's is its own\n * and inheriting one would install from somewhere nobody named. Branding is the opposite kind of\n * field: it is presentation, a user sets it once for themselves, and a project that says nothing\n * about it is not asking for the shipped name back.\n *\n * Read per file it did exactly that. A user who branded globally stopped seeing their own name the\n * moment any project config existed — which is every installed project — and nothing announced it;\n * the name simply reverted. This function's own docblock described the per-field behaviour for as\n * long as the code did not perform it.\n */\nexport async function resolveBranding(projectDir?: string): Promise<ResolvedBranding> {\n const [own, global] = await Promise.all([\n loadOwnProjectSourceConfig(projectDir),\n loadGlobalSourceConfig(),\n ]);\n\n return {\n name: own?.branding?.name ?? global?.branding?.name ?? DEFAULT_BRANDING.NAME,\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 itself.\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 { 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 PLUGIN_COMPILE_COMPLETE: \"Plugin compile complete!\",\n} as const;\n\n/**\n * `init`'s closing line, under the name the run prints itself as.\n *\n * A builder rather than a constant because it carries `branding.name`, which is per-installation\n * and cannot be baked in at module load. `init` is its one caller and resolves the name once on\n * its own spine, through `BaseCommand.resolveBrandingName`, which is where the default comes\n * from.\n */\nexport function initSucceeded(brandingName: string): string {\n return `${brandingName} initialized successfully!`;\n}\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 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/**\n * What `uninstall` reports when the directory holds nothing of this CLI's, under the name the run\n * prints itself as.\n *\n * A builder for the same reason as {@link initSucceeded}, and it matters more here: `uninstall`\n * heads its output with the configured name and signs off with it, so a constant would put the\n * shipped name in the middle of a run that says the configured one twice around it.\n */\nexport function notInstalledHere(brandingName: string): string {\n return `${brandingName} is not installed in this project.`;\n}\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 sub-agents a recompile pass could not write, named rather than counted.\n *\n * Read off the pass's `failed` roster rather than off the prose it also returns: that roster is\n * the structured answer to \"which ones did not land\", while `warnings` carries entries that are\n * not failures at all — a scope with nothing to compile contributes one on every project-context\n * run, and a summary built from the prose would file that as work owed.\n */\nexport function agentsNotCompiled(agentNames: readonly AgentName[]): string {\n return `${agentNames.length} sub-agent(s) did not compile: ${agentNames.join(\", \")}`;\n}\n\n/**\n * One thing a run set out to do and did not, paired with the one command that finishes it.\n *\n * Both halves are required. A run that names the failure and no way out has told the user their\n * installation is wrong and left them holding it, and one that names a remedy without saying\n * what it remedies is advice about nothing.\n */\nexport type IncompleteWork = {\n /** What did not happen, in the words it was warned about with where they exist. */\n what: string;\n /** The single next thing that finishes it. */\n recovery: string;\n};\n\n/**\n * The ways out a command names when it finishes with work undone.\n *\n * One sentence per KIND of leftover state rather than one per failure site: what a person does\n * about a plugin registration that outlived the skill it was for is the same whichever of the\n * moments left it there, and three spellings of the same instruction read as three different\n * instructions.\n */\nexport const INCOMPLETE_WORK_RECOVERY = {\n RECOMPILE: `Run '${CLI_INVOKE_COMMAND} compile' — the compiled agents on disk are stale until you do.`,\n INSPECT_INSTALLATION: `Run '${CLI_INVOKE_COMMAND} doctor' to see what this installation is left holding.`,\n DELETE_AGENT_FILE:\n \"Delete the file by hand — Claude Code loads a compiled sub-agent this project no longer configures.\",\n} as const;\n\n/**\n * The account a command ends on when its work landed and part of it did not.\n *\n * It restates warnings the run already printed, deliberately: each was emitted where it\n * happened, which is where it is explicable and where the screens of output after it bury it.\n * This block is what a person reads after the fact, and the only place a non-zero exit from a\n * command that finished is explained.\n *\n * The lead-in claims the changes above LANDED, because that is the whole difference between\n * this ending and a refusal, and it is the sentence a reader would dispute.\n */\nexport function completedWithFailures(failures: readonly IncompleteWork[]): string {\n return [\n `Completed with ${failures.length} failure(s) — the changes above landed, these did not:`,\n ...failures.flatMap(failureLines),\n ].join(\"\\n\");\n}\n\n/** One failure as two lines, the remedy indented under the failure it answers. */\nfunction failureLines({ what, recovery }: IncompleteWork): string[] {\n return [` ${what}`, ` ${recovery}`];\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 * 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.\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 { z } from \"zod\";\nimport { partition } from \"remeda\";\nimport type { LocalSkillMetadata } from \"./skills/skill-metadata\";\nimport type { LocalRawMetadata } from \"./skills/local-skill-loader\";\nimport {\n AUTHOR_HANDLE_PATTERN,\n KEBAB_CASE_PATTERN,\n LOCAL_PSEUDO_CATEGORY,\n STANDARD_FILES,\n} from \"../consts\";\nimport { METADATA_KEYS } from \"./metadata-keys\";\nimport { formatZodIssue } from \"./schema-validator\";\nimport { isRecord } from \"../utils/type-guards\";\nimport { warn } from \"../utils/logger\";\nimport { SKILL_SLUGS, CATEGORIES } from \"../types/generated/source-types\";\nimport { EFFORT_NAMES, MODEL_NAMES, PERMISSION_MODES } from \"../types/matrix\";\nimport type {\n AgentHookAction,\n AgentHookDefinition,\n AgentName,\n AgentYamlConfig,\n AlternativeGroup,\n CategoryDefinition,\n CategoryPath,\n ConflictRule,\n DiscourageRule,\n Domain,\n EffortLevel,\n Marketplace,\n MarketplaceMetadata,\n MarketplaceOwner,\n MarketplacePlugin,\n MarketplaceRemoteSource,\n ModelName,\n PermissionMode,\n PluginAuthor,\n PluginManifest,\n ProjectConfig,\n RelationshipDefinitions,\n RequireRule,\n SkillAssignment,\n SkillConfig,\n SkillId,\n SkillSlug,\n Category,\n} from \"../types\";\n\nexport const modelNameSchema = z.enum(MODEL_NAMES) as z.ZodType<ModelName>;\n\nexport const effortLevelSchema = z.enum(EFFORT_NAMES) as z.ZodType<EffortLevel>;\n\nexport const permissionModeSchema = z.enum(PERMISSION_MODES) as z.ZodType<PermissionMode>;\n\nexport const skillSlugSchema = z.enum(SKILL_SLUGS) as z.ZodType<SkillSlug>;\n\n// Accepts: known category, \"local\", or any kebab-case string (custom categories)\nexport const categoryPathSchema = z.string().refine(\n (val): val is CategoryPath => {\n if (val === LOCAL_PSEUDO_CATEGORY) return true;\n if ((CATEGORIES as readonly string[]).includes(val)) return true;\n // Accept any kebab-case string for custom categories\n return KEBAB_CASE_PATTERN.test(val);\n },\n {\n message: \"Must be a valid category path (e.g., 'web-framework', 'shared-testing', or 'local')\",\n },\n) as z.ZodType<CategoryPath>;\n\nexport const agentHookActionSchema: z.ZodType<AgentHookAction> = z.object({\n type: z.enum([\"command\", \"script\", \"prompt\"]),\n command: z.string().exactOptional(),\n script: z.string().exactOptional(),\n prompt: z.string().exactOptional(),\n});\n\nexport const agentHookDefinitionSchema: z.ZodType<AgentHookDefinition> = z.object({\n matcher: z.string().exactOptional(),\n hooks: z.array(agentHookActionSchema).exactOptional(),\n});\n\nexport const hooksRecordSchema = z.record(z.string(), z.array(agentHookDefinitionSchema));\n\n/** Strict hook definition — hooks array is required and must have at least one action */\nconst strictAgentHookDefinitionSchema = z.object({\n matcher: z.string().exactOptional(),\n hooks: z.array(agentHookActionSchema).min(1),\n});\n\n/** Strict hooks record for validation schemas (requires at least one hook action per definition) */\nexport const strictHooksRecordSchema = z.record(\n z.string(),\n z.array(strictAgentHookDefinitionSchema),\n);\n\nexport const skillAssignmentSchema: z.ZodType<SkillAssignment> = z.object({\n id: z.string() as z.ZodType<SkillId>,\n preloaded: z.boolean().exactOptional(),\n local: z.boolean().exactOptional(),\n path: z.string().exactOptional(),\n});\n\n// Lenient: accepts any string for `name` since local/custom skills may not follow strict SkillId pattern\nexport const skillFrontmatterLoaderSchema = z.object({\n /** Lenient (any string): local/custom skills have non-builtin IDs */\n name: z.string() as z.ZodType<SkillId>,\n description: z.string(),\n model: modelNameSchema.exactOptional(),\n});\n\n/**\n * Loader schema for a skill's metadata.yaml.\n *\n * `custom` buys its category NOTHING here. It used to: a `custom: true` skill's\n * category was waved through on a bare kebab-case test while every other skill's\n * went to `categoryPathSchema`. A custom skill is placed in a category that\n * already exists rather than bringing one, so the leniency described a freedom it\n * no longer has, and the same field now answers to the same schema either way.\n * Whether the category is one this installation actually declares is asked where\n * the declarations are — `mergeLocalSkillsIntoMatrix`, not here.\n */\nexport const skillMetadataLoaderSchema = z\n .object({\n category: categoryPathSchema.exactOptional(),\n author: z.string().exactOptional(),\n domain: z.string() as z.ZodType<Domain>,\n custom: z.boolean().exactOptional(),\n })\n .passthrough();\n\n/**\n * Raw metadata.yaml shape read by the matrix loader during skill extraction.\n * Preserved verbatim on the move from matrix-loader.ts.\n */\nexport const matrixRawMetadataSchema = z.object({\n category: categoryPathSchema,\n author: z.string(),\n displayName: z.string().exactOptional(),\n slug: z.string() as z.ZodType<SkillSlug>,\n cliDescription: z.string().exactOptional(),\n usageGuidance: z.string().exactOptional(),\n // Boundary cast: domain is a string at the YAML parse boundary; narrowed to Domain type\n domain: z.string() as z.ZodType<Domain>,\n custom: z.boolean().exactOptional(),\n});\n\nexport const pluginAuthorSchema: z.ZodType<PluginAuthor> = z.object({\n name: z.string().min(1),\n email: z.string().exactOptional(),\n});\n\n// Shared plugin.json shape — the lenient (strip) and strict variants below differ only in unknown-key policy\nconst pluginManifestObjectSchema = z.object({\n name: z.string(),\n version: z.string().exactOptional(),\n description: z.string().exactOptional(),\n author: pluginAuthorSchema.exactOptional(),\n /** Lenient: a plugin authored elsewhere may carry any category string or none at all */\n category: z.string().exactOptional(),\n keywords: z.array(z.string()).exactOptional(),\n commands: z.union([z.string(), z.array(z.string())]).exactOptional(),\n agents: z.union([z.string(), z.array(z.string())]).exactOptional(),\n skills: z.union([z.string(), z.array(z.string())]).exactOptional(),\n hooks: z.union([z.string(), hooksRecordSchema]).exactOptional(),\n});\n\n/** Lenient plugin.json schema (strips unknown keys; used at load boundaries) */\nexport const pluginManifestSchema: z.ZodType<PluginManifest> = pluginManifestObjectSchema;\n\n/** Strict plugin.json schema — rejects unrecognized keys (used by plugin-validator) */\nexport const pluginManifestValidationSchema = pluginManifestObjectSchema.strict();\n\nexport const agentYamlConfigSchema: z.ZodType<AgentYamlConfig> = z.object({\n id: z.string() as z.ZodType<AgentName>,\n title: z.string(),\n description: z.string(),\n model: modelNameSchema.exactOptional(),\n effort: effortLevelSchema.exactOptional(),\n tools: z.array(z.string()),\n disallowedTools: z.array(z.string()).exactOptional(),\n permissionMode: permissionModeSchema.exactOptional(),\n hooks: hooksRecordSchema.exactOptional(),\n outputFormat: z.string().exactOptional(),\n domain: (z.string() as z.ZodType<Domain>).exactOptional(),\n custom: z.boolean().exactOptional(),\n});\n\n// Defined before projectConfigLoaderSchema so it can reference stackAgentConfigSchema\n// Single skill assignment element: either a bare SkillId string or an object { id, preloaded? }\nconst skillAssignmentElementSchema = z.union([\n z.string() as z.ZodType<SkillId>,\n skillAssignmentSchema,\n]);\n\n/**\n * Agent config within a stack: maps category to skill assignment(s).\n * Lenient: accepts bare string, object, or array from YAML.\n * Consumers normalize all values to SkillAssignment[] after parsing.\n */\nexport const stackAgentConfigSchema = z.record(\n z.string(),\n z.union([skillAssignmentElementSchema, z.array(skillAssignmentElementSchema)]),\n);\n\n/**\n * The top-level keys a saved config carried before the marketplace fields were renamed, each\n * mapped to the field its value lives on now. Data rather than a check per key because both\n * loader schemas read the same file and have to refuse the same keys — and `satisfies` ties every\n * replacement to a field that really exists, so the next rename cannot leave this list stale.\n */\nconst RENAMED_CONFIG_FIELDS = { source: \"marketplace\" } as const satisfies Record<\n string,\n keyof ProjectConfig\n>;\n\n/** The same, for the keys a saved config's SKILL ENTRIES carried. */\nconst RENAMED_SKILL_ENTRY_FIELDS = { source: \"origin\" } as const satisfies Record<\n string,\n keyof SkillConfig\n>;\n\nfunction renamedFieldMessage(oldKey: string, newKey: string): string {\n return `\"${oldKey}\" was renamed to \"${newKey}\". Rename the key in this config — the CLI does not read \"${oldKey}\" any more and will not fall back to it.`;\n}\n\nfunction reportRenamedKeys(\n record: Record<string, unknown>,\n renames: Record<string, string>,\n path: PropertyKey[],\n ctx: z.RefinementCtx,\n): void {\n for (const [oldKey, newKey] of Object.entries(renames)) {\n if (!(oldKey in record)) continue;\n ctx.addIssue({\n code: \"custom\",\n path: [...path, oldKey],\n message: renamedFieldMessage(oldKey, newKey),\n });\n }\n}\n\n/**\n * Refuses a saved config that still names a field by the key it had before the rename.\n *\n * Reads the raw document rather than parse output because neither schema would show it one: both\n * are `.passthrough()`, so a stale top-level key survives as unrecognised data, and the skills\n * array is declared, so a stale key on an entry is stripped before any refinement runs. Either way\n * the run would look for the value under its NEW name, find nothing, and quietly install from the\n * default marketplace instead of the one the config named.\n */\nfunction refuseRenamedFields(config: unknown, ctx: z.RefinementCtx): void {\n if (!isRecord(config)) return;\n\n reportRenamedKeys(config, RENAMED_CONFIG_FIELDS, [], ctx);\n\n const { skills } = config;\n if (!Array.isArray(skills)) return;\n for (const [index, entry] of skills.entries()) {\n if (!isRecord(entry)) continue;\n reportRenamedKeys(entry, RENAMED_SKILL_ENTRY_FIELDS, [\"skills\", index], ctx);\n }\n}\n\n/**\n * Both loader schemas behind the same refusal, piped so it runs on the file as written. A failure\n * here short-circuits the shape check, so a config carrying an old key is answered with the rename\n * it needs rather than with the missing-field noise the rename causes.\n */\nconst renamedFieldGuard = z.unknown().superRefine(refuseRenamedFields);\n\n/** The shape {@link projectConfigLoaderSchema} admits once the rename guard has passed. */\nconst projectConfigFields = z\n .object({\n /** Project/plugin name in kebab-case */\n name: z.string().exactOptional(),\n description: z.string().exactOptional(),\n /** Per-agent configuration with scope (e.g., [{ name: \"web-developer\", scope: \"project\" }]) */\n agents: z\n .array(\n z.object({\n name: z.string(),\n scope: z.enum([\"project\", \"global\"]),\n /** Per-agent overrides of the agent's own metadata defaults */\n model: modelNameSchema.exactOptional(),\n effort: effortLevelSchema.exactOptional(),\n excluded: z.boolean().exactOptional(),\n }),\n )\n .exactOptional(),\n /** Per-skill configuration with scope and provenance */\n skills: z\n .array(\n z.object({\n id: z.string() as z.ZodType<SkillId>,\n scope: z.enum([\"project\", \"global\"]),\n origin: z.string(),\n excluded: z.boolean().exactOptional(),\n }),\n )\n .exactOptional(),\n\n /** Author handle (e.g., \"@vince\") */\n author: z.string().exactOptional(),\n /** Selected domains from the wizard (persisted for edit mode restoration) */\n selectedDomains: z.array(z.string() as z.ZodType<Domain>).exactOptional(),\n /** Agent-to-category-to-skill mappings from selected stack (accepts same formats as stacks.ts) */\n stack: z.record(z.string(), stackAgentConfigSchema).exactOptional(),\n /** The marketplace this install reads skills from, as a path or URL (e.g., \"github:my-org/skills\") */\n marketplace: z.string().exactOptional(),\n /** The name that marketplace's manifest gives it, which plugins are registered under */\n marketplaceName: z.string().exactOptional(),\n /** Separate source for agents when different from skills source */\n agentsSource: z.string().exactOptional(),\n /** Tracked project installation paths (global config only) */\n projects: z.array(z.string()).exactOptional(),\n })\n .passthrough();\n\n/**\n * Lenient loader for .claude-src/config.ts (ProjectConfig).\n * name/agents optional since partial configs are valid at load time.\n * Full validation happens in validateProjectConfig().\n */\nexport const projectConfigLoaderSchema = renamedFieldGuard.pipe(projectConfigFields);\n\nconst categoryDefinitionSchema: z.ZodType<CategoryDefinition> = z.object({\n id: z.string() as z.ZodType<Category>,\n displayName: z.string(),\n description: z.string(),\n domain: (z.string() as z.ZodType<Domain>).exactOptional(),\n exclusive: z.boolean(),\n order: z.number(),\n icon: z.string().exactOptional(),\n});\n\n/**\n * What a relationship rule naming an unknown skill says back, in place of the whole\n * generated slug union it was tested against.\n *\n * A rule names skills by slug and every one is held to the PUBLIC catalogue's generated\n * union, so a marketplace author naming a skill they themselves ship is handed roughly 250\n * names belonging to somebody else — which answers a question they did not ask and does not\n * contain the answer to the one they did. Zod's own text for an enum reports the options and\n * never the input, so the slug they actually wrote was the one thing missing from it; the\n * function form is what puts it back.\n *\n * It says \"yet\" deliberately. The constraint is this schema's rather than the loader's — a\n * source's own rules are resolved against that source's own slug map — so the refusal names a\n * limit rather than a law. Whether slugs leave the closed union is a separate question.\n */\nfunction unknownSkillSlugRefusal(input: unknown): string {\n const named = typeof input === \"string\" ? `'${input}'` : \"That value\";\n return (\n `${named} is not a slug the public catalogue carries, and a relationship rule may only ` +\n `name skills the public catalogue carries — this marketplace's own skills cannot be named ` +\n `in one yet. Name a catalogue slug, or leave 'relationships' out: it is optional, and a ` +\n `marketplace shipping no relationship rules loads and installs like any other.`\n );\n}\n\n// Skill references in relationship rules: slugs resolved to canonical IDs by matrix-loader\nconst skillRefInRules = z.enum(SKILL_SLUGS, {\n error: (issue) => unknownSkillSlugRefusal(issue.input),\n}) as z.ZodType<SkillSlug>;\n\n// Shared shape for conflict/discourage/compatibility rules: 2+ slugs plus a reason\nconst skillGroupRuleSchema = z.object({\n skills: z.array(skillRefInRules).min(2),\n reason: z.string(),\n});\n\nconst conflictRuleSchema: z.ZodType<ConflictRule> = skillGroupRuleSchema;\n\nconst discourageRuleSchema: z.ZodType<DiscourageRule> = skillGroupRuleSchema;\n\nconst requireRuleSchema: z.ZodType<RequireRule> = z.object({\n skill: skillRefInRules,\n needs: z.array(skillRefInRules).min(1),\n needsAny: z.boolean().exactOptional(),\n reason: z.string(),\n});\n\nconst alternativeGroupSchema: z.ZodType<AlternativeGroup> = z.object({\n purpose: z.string(),\n skills: z.array(skillRefInRules).min(1),\n});\n\nconst relationshipDefinitionsSchema: z.ZodType<RelationshipDefinitions> = z.object({\n conflicts: z.array(conflictRuleSchema),\n discourages: z.array(discourageRuleSchema),\n requires: z.array(requireRuleSchema),\n alternatives: z.array(alternativeGroupSchema),\n});\n\n/**\n * Standalone skill-categories.ts file schema.\n * Top-level object with version string and categories map using existing categoryDefinitionSchema.\n */\nexport const skillCategoriesFileSchema = z.object({\n version: z.string(),\n categories: z.record(z.string(), categoryDefinitionSchema),\n});\n\n/**\n * Standalone skill-rules.ts file schema.\n * Contains version and aggregate relationship rules between skills.\n */\nexport const skillRulesFileSchema = z.object({\n version: z.string(),\n relationships: relationshipDefinitionsSchema.exactOptional(),\n});\n\n/**\n * Raw metadata from a local skill's metadata.yaml.\n * displayName and category are required — the skill must declare both.\n */\nexport const localRawMetadataSchema = z\n .object({\n /** Short name shown in the wizard grid (e.g., \"my-custom-react\") */\n displayName: z.string(),\n /** Kebab-case short key for alias resolution (e.g., \"react\") */\n slug: z.string() as z.ZodType<SkillSlug>,\n /** One-line description for the wizard */\n cliDescription: z.string().exactOptional(),\n /** Category to place this skill in (e.g., \"web-framework\") */\n category: categoryPathSchema,\n /** When an AI agent should invoke this skill */\n usageGuidance: z.string().exactOptional(),\n /** Domain this skill belongs to (e.g., \"web\", \"api\", \"cli\") */\n domain: z.string() as z.ZodType<Domain>,\n /** True if this skill was created outside the CLI's built-in vocabulary */\n custom: z.boolean().exactOptional(),\n })\n // Passthrough widens the output with an index signature; LocalRawMetadata is the\n // honest declared shape consumers read (same round-1 pattern as localSkillMetadataSchema).\n .passthrough() as z.ZodType<LocalRawMetadata>;\n\n/** Metadata for local skills that were forked/copied from a marketplace skill */\nexport const localSkillMetadataSchema = z\n .object({\n forkedFrom: z\n .object({\n /** Original skill ID before forking — lenient (any string) since custom/extra-source skills have non-builtin IDs */\n skillId: z.string() as z.ZodType<SkillId>,\n /** SHA hash of the original content at fork time (for diff detection) */\n contentHash: z.string(),\n /** ISO date when the fork was created */\n date: z.string(),\n /** Source URL the skill was installed from (e.g., \"github:agents-inc/skills\") */\n source: z.string().exactOptional(),\n /** Directory inside that repository, for a skill only its own bytes can install again */\n path: z.string().exactOptional(),\n })\n .exactOptional(),\n })\n // Passthrough widens the output with an index signature; LocalSkillMetadata carries the\n // same index signature, so this is the honest declared shape for parse results.\n .passthrough() as z.ZodType<LocalSkillMetadata>;\n\nconst stackSchema = z.object({\n id: z.string().min(1),\n name: z.string().min(1),\n description: z.string(),\n /** Maps agent IDs to their category-to-skill assignments */\n agents: z.record(z.string(), stackAgentConfigSchema),\n /** High-level philosophy guiding this stack's technology choices */\n philosophy: z.string().exactOptional(),\n});\n\n// Pre-normalization schema: values may be string or string[].\n// loadStacks() normalizes to StacksConfig (all values SkillId[]) after parsing.\nexport const stacksConfigSchema = z.object({\n stacks: z.array(stackSchema).min(1),\n});\n\nconst marketplaceRemoteSourceSchema: z.ZodType<MarketplaceRemoteSource> = z.object({\n source: z.enum([\"github\", \"url\"]),\n repo: z.string().exactOptional(),\n url: z.string().exactOptional(),\n ref: z.string().exactOptional(),\n});\n\nconst marketplacePluginSchema: z.ZodType<MarketplacePlugin> = z.object({\n name: z.string().min(1),\n /** Local directory path (relative to pluginRoot) or remote source config */\n source: z.union([z.string(), marketplaceRemoteSourceSchema]),\n description: z.string().exactOptional(),\n version: z.string().exactOptional(),\n author: pluginAuthorSchema.exactOptional(),\n /** Lenient: external data may have any category string or none at all */\n category: z.string().exactOptional(),\n keywords: z.array(z.string()).exactOptional(),\n});\n\n// MarketplaceOwner aliases PluginAuthor (identical shape, both require name.min(1))\nconst marketplaceOwnerSchema: z.ZodType<MarketplaceOwner> = pluginAuthorSchema;\n\nconst marketplaceMetadataSchema: z.ZodType<MarketplaceMetadata> = z.object({\n /** Base directory for resolving plugin source paths (e.g., \"plugins/\") */\n pluginRoot: z.string().exactOptional(),\n});\n\n/**\n * What a marketplace name being refused says back, in place of the pattern it was tested against.\n *\n * A raw Zod format issue names the regex, which tells a marketplace author what the CLI checks\n * with and nothing about what to write instead. The rule is spelled the way\n * `marketplaceNameNotPublishable` in `utils/messages.ts` already spells it on the emit side, so\n * the two directions of one rule cannot come to say different things about it.\n *\n * Stated as a `message` on the `regex` check rather than in a `refine`, deliberately: a refinement\n * is unrepresentable in JSON Schema, so `src/schemas/marketplace.schema.json` would silently lose\n * the `pattern` an editor validates `marketplace.json` against.\n */\nconst MARKETPLACE_NAME_REFUSAL =\n \"A marketplace name is kebab-case: lowercase letters, numbers and hyphens, starting with a letter (e.g. 'acme-skills'). Rename it in this manifest — Claude Code registers every plugin under it and accepts no other shape.\";\n\nexport const marketplaceSchema: z.ZodType<Marketplace> = z.object({\n $schema: z.string().exactOptional(),\n /**\n * Kebab-case, because this name is the namespace Claude Code registers plugins under and the\n * CLI piggybacks on what Claude Code accepts (owner ruling 2026-08-20). Held to the same rule\n * `build marketplace` refuses to publish under, so what this CLI emits is what it can read back.\n */\n name: z.string().min(1).regex(KEBAB_CASE_PATTERN, { message: MARKETPLACE_NAME_REFUSAL }),\n version: z.string().min(1),\n description: z.string().exactOptional(),\n owner: marketplaceOwnerSchema,\n metadata: marketplaceMetadataSchema.exactOptional(),\n plugins: z.array(marketplacePluginSchema).min(1),\n});\n\n/**\n * What a cached remote source was fetched from, written beside the cache so the\n * next load can ask whether it is still current in one request.\n *\n * `etag` is absent when the host returned none — a copy that cannot be\n * revalidated at all, which is a different state from one that has not been\n * checked yet.\n */\nexport const sourceRevalidationSchema = z.object({\n /** The tarball URL giget resolved for this source. */\n tar: z.string().min(1),\n etag: z.string().min(1).exactOptional(),\n});\n\n/** Tool permission overrides (allow/deny lists for Claude Code tool access) */\nconst permissionConfigSchema = z.object({\n /** Tool names or patterns to explicitly allow */\n allow: z.array(z.string()).exactOptional(),\n /** Tool names or patterns to explicitly deny */\n deny: z.array(z.string()).exactOptional(),\n});\n\n/** Settings file schema (.claude/settings.yaml) for project-level configuration */\nexport const settingsFileSchema = z\n .object({\n permissions: permissionConfigSchema.exactOptional(),\n })\n .passthrough();\n\n/** Branding overrides for white-labeling the CLI */\nconst brandingConfigSchema = z.object({\n /** Custom CLI name (e.g., \"Acme Dev Tools\") */\n name: z.string().exactOptional(),\n});\n\n/** The shape {@link projectSourceConfigSchema} admits once the rename guard has passed. */\nconst projectSourceConfigFields = z\n .object({\n /** The marketplace this install reads skills from, as a path or URL */\n marketplace: z.string().exactOptional(),\n /** Author handle for this project's config */\n author: z.string().exactOptional(),\n /** The name that marketplace's manifest gives it, which plugins are registered under */\n marketplaceName: z.string().exactOptional(),\n /** Separate source for agent definitions (when different from skills) */\n agentsSource: z.string().exactOptional(),\n /** Branding overrides for white-labeling the CLI */\n branding: brandingConfigSchema.exactOptional(),\n /** Custom skills directory override (default: \"src/skills\") */\n skillsDir: z.string().exactOptional(),\n /** Custom agents directory override (default: \"src/agents\") */\n agentsDir: z.string().exactOptional(),\n /** Custom stacks file path override (default: \"config/stacks.ts\") */\n stacksFile: z.string().exactOptional(),\n /** Custom categories file path override (default: \"config/skill-categories.ts\") */\n categoriesFile: z.string().exactOptional(),\n /** Custom rules file path override (default: \"config/skill-rules.ts\") */\n rulesFile: z.string().exactOptional(),\n })\n .passthrough();\n\n/**\n * Project source configuration from .claude-src/config.ts.\n * Stores multi-source settings, custom directory overrides, and bound skills.\n */\nexport const projectSourceConfigSchema = renamedFieldGuard.pipe(projectSourceConfigFields);\n\n// Strict validation schemas enforce all constraints and use .strict() to reject unknown fields,\n// unlike the lenient loader schemas above which use .passthrough() for forward compatibility at parse boundaries\n\n/** Strict schema for compiled agent metadata.yaml output. Lenient id (any string) since marketplace agents may use custom identifiers. */\nexport const agentYamlGenerationSchema = z\n .object({\n $schema: z.string().exactOptional(),\n id: z.string().min(1),\n title: z.string().min(1),\n description: z.string().min(1),\n model: modelNameSchema.exactOptional(),\n effort: effortLevelSchema.exactOptional(),\n tools: z.array(z.string()).min(1),\n disallowedTools: z.array(z.string()).exactOptional(),\n permissionMode: permissionModeSchema.exactOptional(),\n hooks: strictHooksRecordSchema.exactOptional(),\n outputFormat: z.string().exactOptional(),\n domain: (z.string() as z.ZodType<Domain>).exactOptional(),\n custom: z.boolean().exactOptional(),\n })\n .strict();\n\n/** Strict validation for agent AGENT.md frontmatter (used by plugin-validator) */\nexport const agentFrontmatterValidationSchema = z\n .object({\n /** Agent name in kebab-case (becomes the Task tool identifier) */\n name: z.string().regex(KEBAB_CASE_PATTERN).min(1),\n description: z.string().min(1),\n /** Comma-separated list of allowed tools */\n tools: z.string().exactOptional(),\n /** Comma-separated list of denied tools */\n disallowedTools: z.string().exactOptional(),\n model: modelNameSchema.exactOptional(),\n effort: effortLevelSchema.exactOptional(),\n permissionMode: permissionModeSchema.exactOptional(),\n /** Skill names to preload (embed in agent prompt) */\n skills: z.array(z.string().min(1)).exactOptional(),\n hooks: strictHooksRecordSchema.exactOptional(),\n })\n .strict();\n\n/** Strict validation for SKILL.md frontmatter (matches Claude Code plugin spec) */\nexport const skillFrontmatterValidationSchema = z\n .object({\n name: z.string().min(1),\n description: z.string().min(1),\n /** If true, Claude cannot invoke this skill on its own */\n \"disable-model-invocation\": z.boolean().exactOptional(),\n /** If true, user can invoke this skill directly */\n \"user-invocable\": z.boolean().exactOptional(),\n /** Comma-separated list of tools this skill can use */\n \"allowed-tools\": z.string().exactOptional(),\n model: modelNameSchema.exactOptional(),\n /** \"fork\" means skill runs in a forked context (separate conversation) */\n context: z.enum([\"fork\"]).exactOptional(),\n /** Agent name this skill is scoped to */\n agent: z.string().exactOptional(),\n /** Hint text shown when user invokes the skill */\n \"argument-hint\": z.string().exactOptional(),\n })\n .strict();\n\n/**\n * Provenance object shared verbatim by metadataValidationSchema and\n * customMetadataValidationSchema. The forkedFrom variant in\n * localSkillMetadataSchema (no `version`) is deliberately NOT unified here —\n * its shape differs, so sharing would change validation behavior.\n */\nconst forkedFromSchema = z.object({\n /** Original skill ID */\n skillId: z.string(),\n /** Version of the original at fork time */\n version: z.number().int().min(1).exactOptional(),\n /** Content hash of the original at fork time */\n contentHash: z.string(),\n /** Source URL or identifier */\n source: z.string().exactOptional(),\n /** Directory inside that source, for a skill only its own bytes can install again */\n path: z.string().exactOptional(),\n /** ISO date of the fork */\n date: z.string(),\n});\n\n/**\n * Recommended upper bound for cliDescription in published skills. Exceeding it is\n * advisory only — splitMetadataValidationIssues downgrades it to a warning because\n * the runtime schemas accept any length and the value only feeds wizard description\n * text. Empty (min(1)) remains a hard error.\n */\nconst CLI_DESCRIPTION_MAX_LENGTH = 60;\n\n/**\n * Fields shared by metadataValidationSchema (strict, built-in vocabulary) and\n * customMetadataValidationSchema (relaxed). Only `category` and `slug` differ\n * between the two variants — each adds those via .extend().\n */\nconst skillMetadataBaseSchema = z.object({\n /** Author handle — must start with @ (e.g., \"@vince\") */\n author: z.string().regex(AUTHOR_HANDLE_PATTERN),\n /** Short display name for the wizard grid (max 30 chars) */\n displayName: z.string().min(1).max(30),\n /** One-line description for the wizard (max 60 chars recommended; over-length is a validation warning) */\n cliDescription: z.string().min(1).max(CLI_DESCRIPTION_MAX_LENGTH),\n /** When an AI agent should invoke this skill (min 10 chars to ensure usefulness) */\n usageGuidance: z.string().min(10),\n /** 7-char hex SHA of skill content (for change detection) */\n contentHash: z\n .string()\n .regex(/^[a-f0-9]{7}$/)\n .exactOptional(),\n /** ISO date of last update */\n updated: z.string().exactOptional(),\n /** Provenance tracking when skill was forked from another */\n forkedFrom: forkedFromSchema.exactOptional(),\n /** Domain assignment from metadata */\n domain: (z.string() as z.ZodType<Domain>).exactOptional(),\n /** True if this skill was created outside the CLI's built-in vocabulary */\n custom: z.boolean().exactOptional(),\n});\n\n/**\n * What a published skill's `slug` says back when the public catalogue does not carry it, in\n * place of the whole generated slug union it was tested against.\n *\n * The same defect `unknownSkillSlugRefusal` answers one layer over, and the one an author meets\n * FIRST: they write a `metadata.yaml` before they write a rule. Zod's text for an enum reports\n * the options and never the input, so a marketplace author naming a skill they themselves ship\n * was handed roughly 250 names belonging to somebody else with their own slug missing from it.\n *\n * It differs from the rules-side message in the one way that matters: this refusal has a way\n * out and that one does not. `validateSkillMetadata` reads `custom: true` and validates against\n * `customMetadataValidationSchema`, whose `slug` is any kebab-case name — so the flag is what a\n * skill outside the catalogue's vocabulary is CARRIED by rather than a way around the check\n * (owner ruling 2026-08-22: the union stays closed and `custom: true` is the documented\n * mechanism). Nothing said so until now, which is the whole of what made it read as a trick.\n */\nfunction unknownMetadataSlugRefusal(input: unknown): string {\n const named = typeof input === \"string\" ? `'${input}'` : \"That value\";\n return (\n `${named} is not a slug the public catalogue carries. A published skill's slug is held to ` +\n `that catalogue unless the skill declares it is not from it — add '${METADATA_KEYS.CUSTOM}: true' ` +\n `beside it in this ${STANDARD_FILES.METADATA_YAML} and the slug is read as your marketplace's ` +\n `own, any kebab-case name. That declaration is how a skill outside the catalogue's vocabulary ` +\n `is carried; a skill the catalogue does carry names its catalogue slug and leaves it off.`\n );\n}\n\n/** Strict validation for metadata.yaml in published skills (enforces author format, enum-validated category/slug) */\nexport const metadataValidationSchema = skillMetadataBaseSchema\n .extend({\n /** Domain-prefixed category — must be a known built-in category */\n category: z.enum(CATEGORIES),\n /**\n * Kebab-case short key — must be a known built-in slug, unless the file declares\n * `custom: true` and is judged by {@link customMetadataValidationSchema} instead.\n */\n slug: z.enum(SKILL_SLUGS, {\n error: (issue) => unknownMetadataSlugRefusal(issue.input),\n }),\n })\n .strict();\n\n/** Relaxed validation for custom skill metadata.yaml (any category string, kebab-case slug, allows extra fields) */\nexport const customMetadataValidationSchema = skillMetadataBaseSchema.extend({\n /** Any string category — custom skills may define their own categories */\n category: z.string(),\n /** Kebab-case short key for alias resolution, search, and relationship rules */\n slug: z.string().regex(KEBAB_CASE_PATTERN).min(1).max(50),\n});\n\nconst stackSkillAssignmentSchema = z\n .object({\n id: z.string().min(1),\n /** If true, skill content is embedded in the compiled agent prompt */\n preloaded: z.boolean().exactOptional(),\n })\n .strict();\n\n/** Strict validation for published stack config.yaml (marketplace stacks) */\nexport const stackConfigValidationSchema = z\n .object({\n /** Unique stack identifier in kebab-case */\n id: z.string().regex(KEBAB_CASE_PATTERN).exactOptional(),\n name: z.string().min(1),\n version: z.string(),\n author: z.string().min(1),\n description: z.string().exactOptional(),\n /** ISO date when this stack was first created */\n created: z.string().exactOptional(),\n /** ISO date of last update */\n updated: z.string().exactOptional(),\n /** Primary framework this stack is designed for (e.g., \"nextjs\", \"remix\") */\n framework: z.string().exactOptional(),\n /** All skills used in this stack (flat list, at least one required) */\n skills: z.array(stackSkillAssignmentSchema).min(1),\n /** Agent IDs this stack compiles (at least one required) */\n agents: z.array(z.string().regex(KEBAB_CASE_PATTERN)).min(1),\n /** Per-agent skill assignments: { agentId: { category: [skillAssignment] } } */\n agentSkills: z\n .record(z.string(), z.record(z.string(), z.array(stackSkillAssignmentSchema)))\n .exactOptional(),\n /** High-level philosophy guiding technology choices */\n philosophy: z.string().exactOptional(),\n /** Guiding principles for agents using this stack */\n principles: z.array(z.string().min(1)).exactOptional(),\n tags: z.array(z.string().regex(KEBAB_CASE_PATTERN)).exactOptional(),\n /** Per-skill overrides: alternative suggestions and lock status */\n overrides: z\n .record(\n z.string(),\n z\n .object({\n /** Suggested alternative skill IDs if this one is swapped */\n alternatives: z.array(z.string().min(1)).exactOptional(),\n /** If true, this skill cannot be swapped by the user */\n locked: z.boolean().exactOptional(),\n })\n .strict(),\n )\n .exactOptional(),\n /** Community metrics for sorting/ranking */\n metrics: z\n .object({\n upvotes: z.number().int().min(0).exactOptional(),\n downloads: z.number().int().min(0).exactOptional(),\n })\n .strict()\n .exactOptional(),\n /** Lifecycle hooks triggered by file changes or commands */\n hooks: strictHooksRecordSchema.exactOptional(),\n })\n .strict();\n\n/** Format Zod validation issues into a human-readable string (e.g., \"path.to.field: Expected string; other: Required\") */\nexport function formatZodIssues(issues: z.ZodIssue[]): string {\n return issues.map(formatZodIssue).join(\"; \");\n}\n\n/**\n * Validates raw skill metadata using the relaxed schema for custom skills and\n * the strict schema for built-ins — the one place the custom-vs-strict\n * selection policy lives.\n */\nexport function validateSkillMetadata(rawMetadata: unknown) {\n const schema = isCustomMetadata(rawMetadata)\n ? customMetadataValidationSchema\n : metadataValidationSchema;\n return schema.safeParse(rawMetadata);\n}\n\n/**\n * Names a metadata.yaml's schema failure in the words its author needs: the required\n * fields the file leaves out, listed as missing, and whatever else is wrong said per\n * field. Zod's own text for an absent key reads \"expected string, received undefined\",\n * which describes the type system rather than the file.\n */\nexport function describeMetadataSchemaFailure(\n issues: z.ZodIssue[],\n rawMetadata: Record<string, unknown>,\n): string {\n const [absent, malformed] = partition(issues, (issue) => isAbsentField(issue, rawMetadata));\n return [\n ...(absent.length > 0 ? [nameMissingFields(absent)] : []),\n ...malformed.map(formatZodIssue),\n ].join(\"; \");\n}\n\n/** True for a top-level field the file never declared, as against one it declared wrongly. */\nfunction isAbsentField(issue: z.ZodIssue, rawMetadata: Record<string, unknown>): boolean {\n const [field, ...nested] = issue.path;\n return nested.length === 0 && typeof field === \"string\" && rawMetadata[field] === undefined;\n}\n\nfunction nameMissingFields(absent: z.ZodIssue[]): string {\n const fields = absent.map((issue) => issue.path.join(\".\"));\n return `missing required ${fields.length === 1 ? \"field\" : \"fields\"}: ${fields.join(\", \")}`;\n}\n\nexport type MetadataIssueSplit = {\n /** Hard schema violations — the metadata is broken and must be fixed */\n errors: string[];\n /** Advisory violations (over-length cliDescription) — worth fixing, never fatal */\n warnings: string[];\n};\n\n/** True for the over-length `cliDescription` issue — the only advisory metadata violation. */\nfunction isOverLengthCliDescription(issue: z.ZodIssue): boolean {\n return issue.code === \"too_big\" && issue.path.length === 1 && issue.path[0] === \"cliDescription\";\n}\n\n/** Reads `cliDescription` from raw parsed metadata when it is a string. */\nfunction readCliDescription(raw: unknown): string | undefined {\n if (raw == null || typeof raw !== \"object\") return undefined;\n // Boundary cast: raw comes straight from YAML parsing; the typeof check above narrows to object\n const value = (raw as { cliDescription?: unknown }).cliDescription;\n return typeof value === \"string\" ? value : undefined;\n}\n\n/**\n * Warning text for an over-length `cliDescription`, carrying the actual length.\n * The too_big issue only fires when the value is a string, so the undefined\n * branch is defensive — it falls back to the raw zod issue text.\n */\nfunction formatOverLengthWarning(issue: z.ZodIssue, cliDescription: string | undefined): string {\n if (cliDescription === undefined) return formatZodIssue(issue);\n return `cliDescription is ${cliDescription.length} characters — exceeds the recommended maximum of ${CLI_DESCRIPTION_MAX_LENGTH}`;\n}\n\n/**\n * Splits strict-metadata validation issues into hard errors and advisory warnings.\n *\n * Over-length `cliDescription` (> CLI_DESCRIPTION_MAX_LENGTH chars) is advisory: the\n * runtime schemas accept any length and the value only feeds wizard description text,\n * so validate reports it as a warning carrying the actual length. Empty/missing\n * `cliDescription` and every other issue remain errors.\n */\nexport function splitMetadataValidationIssues(\n error: z.ZodError,\n rawMetadata: unknown,\n): MetadataIssueSplit {\n const [overLength, hardFailures] = partition(error.issues, isOverLengthCliDescription);\n\n const cliDescription = readCliDescription(rawMetadata);\n const warnings = overLength.map((issue) => formatOverLengthWarning(issue, cliDescription));\n\n return { errors: hardFailures.map(formatZodIssue), warnings };\n}\n\n/**\n * Validates that a parsed JSON/YAML value does not exceed a maximum nesting depth.\n * Returns true if the structure is within limits, false if it exceeds maxDepth.\n */\nexport function validateNestingDepth(value: unknown, maxDepth: number): boolean {\n function check(val: unknown, depth: number): boolean {\n if (depth > maxDepth) return false;\n if (Array.isArray(val)) {\n return val.every((item) => check(item, depth + 1));\n }\n if (val !== null && typeof val === \"object\") {\n return Object.values(val).every((v) => check(v, depth + 1));\n }\n return true;\n }\n return check(value, 0);\n}\n\n/**\n * Returns true when raw parsed metadata has `custom: true`.\n * Used to pick between strict (built-in vocabulary) and relaxed (user-authored) validation schemas.\n */\nexport function isCustomMetadata(raw: unknown): boolean {\n if (raw == null || typeof raw !== \"object\") return false;\n if (!(\"custom\" in raw)) return false;\n return raw.custom === true;\n}\n\n/**\n * Logs warnings for unknown fields in a parsed object compared to a list of expected keys.\n * Used at security-critical parsing boundaries for files this CLI owns (marketplace.json), where\n * `.passthrough()` is kept for forward compatibility but unexpected fields should be surfaced.\n * A file owned by another tool is not such a boundary: an unfamiliar key there is that tool's\n * business, and a complete expected-key list for it cannot be maintained.\n */\nexport function warnUnknownFields(\n parsed: Record<string, unknown>,\n expectedKeys: readonly string[],\n context: string,\n): void {\n const expectedSet = new Set(expectedKeys);\n const unknownKeys = Object.keys(parsed).filter((k) => !expectedSet.has(k));\n if (unknownKeys.length > 0) {\n warn(`Unknown fields in ${context}: ${unknownKeys.join(\", \")}`);\n }\n}\n","import { z } from \"zod\";\n\n/** One place for the path-prefixed issue rendering shared by every Zod reporter. */\nexport function formatZodIssue(issue: z.ZodIssue): string {\n const path = issue.path.join(\".\");\n if (issue.code === \"unrecognized_keys\") {\n return `Unrecognized key: \"${issue.keys.join('\", \"')}\"`;\n }\n return path ? `${path}: ${issue.message}` : issue.message;\n}\n\nexport function formatZodErrors(error: z.ZodError): string[] {\n return error.issues.map(formatZodIssue);\n}\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 /** 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/**\n * Slug -> canonical skill ID. Partial because only extracted skills are present.\n *\n * One direction, not two. A reverse `idToSlug` was carried here until 2026-08-23 and had **zero\n * readers anywhere** — every occurrence was a write, and the only thing consuming it was the\n * duplicate-slug asymmetry it made possible. A map nothing reads cannot be out of step with the\n * one that is read, so deleting it retires that whole class rather than guarding it.\n */\nexport type SkillSlugMap = {\n /** Forward: slug -> canonical skill ID */\n slugToId: Partial<Record<SkillSlug, SkillId>>;\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 /** 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};\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 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 // A fresh engine per call, and the module cache stays off, because one run both writes a\n // config and reads it back: `init` writes `config.ts`, loads it, writes it again and loads\n // it twice more, and `compile` re-reads that same file from every path that needs it —\n // installation detection, source resolution, each stack warning, the recompile, and the\n // config-types refresh. A cache spanning a run would answer each read that follows a write\n // with the module as it stood BEFORE it, which is a config the user never wrote. What the\n // cache would save has never been measured, and its ceiling is a few hundred milliseconds\n // on a command already waiting on the network and the disk.\n const jiti = createJiti(import.meta.url, {\n moduleCache: false,\n interopDefault: true,\n alias: { \"agents-inc/config\": CONFIG_EXPORTS_PATH },\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 isSeedScopePairWritable,\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 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 * per-agent curation preservation, 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 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/**\n * Project skills never reach global agents; global skills reach any agent.\n *\n * The rule itself lives on the wire contract (`isSeedScopePairWritable` in\n * `@workspace/matrix/seed`), because the editor and this CLI each used to carry a verbatim copy\n * of it and a shared rule with three implementations is a rule three surfaces can disagree about.\n * This stays as the name the CLI's own call sites read it under.\n */\nexport function isScopePairCompatible(skillScope: SkillScope, agentScope: SkillScope): boolean {\n return isSeedScopePairWritable(skillScope, agentScope);\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 the 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 curation check\n * is 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 per-agent curation preservation.\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 seed-everything 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, 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 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 seed-everything 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 per-agent curation preservation: only when the caller provides the delta set.\n // `newlyAddedSkillIds === undefined` triggers legacy seed-everything behavior\n // (preserves callers that never opt in, 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 BOTH partitions, because a project owns its own domain selection\n * (owner ruling 2026-08-20) — this comment used to claim the project's key was\n * cleared, which the code has never done and which the ruling settles as the wrong behaviour\n * rather than a missing implementation.\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 ride the spread onto BOTH partitions: a project owns its own domain selection\n // rather than inheriting the global one (owner ruling 2026-08-20). Neither literal\n // re-states the key, because neither needs to — the spread already carries it, and the\n // conditional re-set the global literal used to carry was a no-op over that same spread.\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 };\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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 },\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 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 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 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 the shared matrix package left open.\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 /** 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/**\n * Slug -> canonical skill ID. Partial because only extracted skills are present.\n *\n * One direction, not two. A reverse `idToSlug` was carried here until 2026-08-23 and had **zero\n * readers anywhere** — every occurrence was a write, and the only thing consuming it was the\n * duplicate-slug asymmetry it made possible. A map nothing reads cannot be out of step with the\n * one that is read, so deleting it retires that whole class rather than guarding it.\n */\nexport type SkillSlugMap = {\n /** Forward: slug -> canonical skill ID */\n slugToId: Partial<Record<SkillSlug, SkillId>>;\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 /** 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};\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\nimport { DEFAULT_SELECTION_OPTIONS } from \"./read-model/selection-defaults\"\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// Where a thing is written: under one project's `.claude`, or the user's own\n// `~/.claude`. Named once because a skill and a sub-agent each carry one and\n// the rule below compares the two — three spellings of one vocabulary is what\n// let the surfaces disagree about it.\nexport const seedScopeSchema = z.enum([\"project\", \"global\"])\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: seedScopeSchema,\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: seedScopeSchema.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 // The sentence the sharer's config records about itself, which on the CLI\n // side is the description of whatever stack was applied. It travels because\n // `stackId` deliberately does not: a saved config records a stack's\n // EXPANSION and never the id it came from, so the receiver has no id to\n // resolve one out of and the line is simply lost.\n //\n // Carrying the id instead would be worse rather than equivalent. A resolvable\n // stack id does exactly two things on the way in — it supplies this\n // description, and it overlays the stack YAML's own `preloaded` flags — and\n // the assignments above already carry per-(skill, sub-agent) load state in\n // full, so the second is redundant. What the id would ADD is the stack's\n // whole roster: the receiving install spreads the loaded stack first and lets\n // the saved stack win per agent, so a stack sub-agent the sharer REMOVED\n // comes back wholesale. Absent means a config that describes itself with\n // nothing, which is every payload the web app mints.\n description: z.string().exactOptional(),\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 SeedScope = z.infer<typeof seedScopeSchema>\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\n/**\n * Project skills never reach global sub-agents; global skills reach any.\n *\n * A global sub-agent's front-matter is written to `~/.claude`, where every\n * project on the machine sees it, while a project-scoped skill is installed\n * under one project's `.claude` — so a global sub-agent carrying a project\n * skill names something that does not exist from anywhere else.\n *\n * This is the ONE definition. The CLI's `isScopePairCompatible` and the\n * editor's roster marker both read it from here rather than restating it: the\n * rule lived as three verbatim copies across three workspaces, which is exactly\n * the drift a shared contract exists to prevent.\n */\nexport const isSeedScopePairWritable = (\n skillScope: SeedScope,\n agentScope: SeedScope\n) => !(skillScope === \"project\" && agentScope === \"global\")\n\n/**\n * Where a sub-agent's front-matter is written, for an entry that may not exist.\n *\n * The `agents` map is sparse, so an absent entry — and an entry that names no\n * scope — rests on the shared selection default. Read from\n * `DEFAULT_SELECTION_OPTIONS` rather than written out, because a default the\n * wire and the consumer spell differently is the same defect as two copies of\n * the rule above.\n */\nexport const seedAgentScope = (entry: SeedAgent | undefined): SeedScope =>\n entry?.scope ?? DEFAULT_SELECTION_OPTIONS.scope\n\n/** A `(skill, sub-agent)` assignment the config model has nowhere to write. */\nexport type UnwritableSeedAssignment = { skillId: string; agent: string }\n\n// An assignment naming a sub-agent the sharer pinned OFF installs nothing, so\n// it is not a pair at all and cannot be an unwritable one. It leaves before the\n// scope question is asked, exactly as the CLI's decode drops it — a wire\n// stricter than the consumer it protects is its own kind of drift.\nconst isSwitchedOff = (entry: SeedAgent | undefined) => entry?.on === false\n\nconst isUnwritablePair = (\n agents: SeedPayload[\"agents\"],\n skillScope: SeedScope,\n agent: string\n): boolean => {\n const entry = agents[agent]\n if (isSwitchedOff(entry)) return false\n return !isSeedScopePairWritable(skillScope, seedAgentScope(entry))\n}\n\n/**\n * Every `(skill, sub-agent)` pair in this payload that has nowhere to be\n * written. Both halves of each are named because neither alone says what to\n * change: the skill can move to global scope, or the sub-agent can be pinned to\n * the project, and only the sharer knows which they meant.\n *\n * **What this cannot see, and why the refusal built on it belongs at the\n * MINTING end rather than at every read.** An assignment naming a sub-agent the\n * RECEIVER does not know is the same bytes on the wire as one naming a\n * sub-agent resting at global. Only a catalogue tells the two apart, and a wire\n * schema has none — so a consumer that refused on this alone would turn a\n * sub-agent rename into a retroactive break of every link minted before it,\n * which is the leniency `seedToWizardResult` documents at length. The CLI keeps\n * its own catalogue-aware check for that reason; what it no longer keeps is its\n * own copy of the RULE.\n */\nexport const unwritableSeedAssignments = (\n payload: SeedPayload\n): UnwritableSeedAssignment[] =>\n Object.entries(payload.skills).flatMap(([skillId, skill]) =>\n Object.keys(skill.assignments)\n .filter((agent) => isUnwritablePair(payload.agents, skill.scope, agent))\n .map((agent) => ({ skillId, agent }))\n )\n\n/**\n * The payload as something that can be INSTALLED, which is a stronger claim\n * than being well-formed.\n *\n * A SECOND schema rather than a tightening of `seedPayloadSchema`, and the\n * split is the whole design. Minting and reading want different answers to the\n * same question:\n *\n * - **Minting** (the worker's POST, and any client that assembles a payload)\n * should refuse the pair outright, so a link that cannot be installed is\n * never created and never pasted anywhere.\n * - **Reading** must stay lenient. Links holding the pair are already out in\n * the world; the editor opens one, marks the offending row and fixes it in\n * a single click (EDITOR-08), and `GET /configs/:id` re-validates what it\n * serves — so a base schema that refused would turn every such id into a\n * 500 with no way back, and delete the repair flow that exists to rescue\n * them.\n */\nexport const installableSeedPayloadSchema = seedPayloadSchema.superRefine(\n (payload, ctx) => {\n for (const { skillId, agent } of unwritableSeedAssignments(payload)) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"skills\", skillId, \"assignments\", agent],\n message: `a project-scoped skill has nowhere to be written on '${agent}', which rests at global scope`,\n })\n }\n }\n)\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 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:\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.\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 * 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 — the full-deselect case.\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 * Root cause of the duplicate rows this key fixes: 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`: 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 — the full-deselect case.\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.\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.\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.\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 — 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. 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 // ABORT on an unreadable config, and unreachable here: `loadProjectConfig` above reads the same\n // file and already threw `ConfigLoadError` for one it could not load, so this rung is only\n // reached when there is no config to read.\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 AgentDefinition,\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 globalInstallRoot,\n LOCAL_PSEUDO_CATEGORY,\n STANDARD_FILES,\n} from \"../../consts\";\nimport { 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 globalInstallRoot(),\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(globalInstallRoot(), 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, on the same reasoning\n * `isExclusiveCategory` (`config-writer.ts`) and `buildProjectCollisionTest`\n * (`config-gate/propagate.ts`) take: 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 * The one constructor for {@link ConfigTypesBackgroundData}, beside the type it builds.\n *\n * Only `customAgentNames` is derived, and that derivation is the whole reason this is a function\n * rather than an object literal at each call site: it was written out three times — here, in\n * `config-gate/pair-writer.ts` and in `config-gate/propagate.ts` — and three producers of one\n * value are three things that can disagree about which sub-agents an emitted `AgentName` union\n * files under its `// Custom` heading. Closing two of the three would have been worse than\n * closing none: the two that agree make the third read as rigorous while it drifts.\n */\nexport function buildConfigTypesBackgroundData(\n matrix: MergedSkillsMatrix,\n agents: Partial<Record<AgentName, AgentDefinition>>,\n): ConfigTypesBackgroundData {\n const agentNames = typedKeys<AgentName>(agents);\n return {\n matrix,\n agentNames,\n customAgentNames: agentNames.filter((name) => agents[name]?.custom === true),\n };\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 of the data {@link buildConfigTypesBackgroundData} assembles\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\";\nimport { getErrorMessage } from \"../../utils/errors\";\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 read = readYaml(content);\n\n if (!read.parsed) {\n warn(`Invalid metadata.yaml at ${metadataPath}: ${read.reason}`);\n return null;\n }\n\n const result = localSkillMetadataSchema.safeParse(read.value);\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 metadata: LocalSkillMetadata = {\n ...existingMetadataFields(yamlContent, metadataPath),\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\n/** What a YAML read can answer: the document, or why no parser could produce one. */\ntype YamlRead =\n | { readonly parsed: true; readonly value: unknown }\n | { readonly parsed: false; readonly reason: string };\n\n/**\n * Parses YAML without letting a syntax error escape.\n *\n * The two ways a metadata file fails reach a reader by different routes, and only one of them was\n * ever handled here: a wrong SHAPE is caught by the schema's `safeParse`, while a file no parser\n * can read throws out of `parseYaml` BEFORE `safeParse` is called at all. Both readers below\n * promise to survive an invalid file and neither kept that promise for the second kind.\n *\n * `readSkillMetadata` in `lib/loading/loader.ts` is the same guard written out at its own call\n * site; this is that shape, shared by the two readers here rather than repeated.\n */\nfunction readYaml(content: string): YamlRead {\n try {\n return { parsed: true, value: parseYaml(content) };\n } catch (error) {\n return { parsed: false, reason: getErrorMessage(error) };\n }\n}\n\n/**\n * The fields a metadata.yaml already holds, or none of them.\n *\n * Answers empty and warns for EITHER failure — a file no parser can read, or one whose shape the\n * schema refuses. Both are the same event from the author's side: the fields they wrote are about\n * to be replaced by a file carrying only `forkedFrom`, and the warning is the only thing that says\n * so. Keeping the two apart here would mean two warnings for one consequence.\n */\nfunction existingMetadataFields(\n yamlContent: string,\n metadataPath: string,\n): Partial<LocalSkillMetadata> {\n const read = readYaml(yamlContent);\n\n if (read.parsed) {\n const result = localSkillMetadataSchema.safeParse(read.value);\n if (result.success) return result.data;\n }\n\n warn(`Malformed metadata.yaml at '${metadataPath}' — existing fields may be lost`);\n return {};\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\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\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\n/**\n * The optional `author` and `category` a skill's metadata.yaml lends the plugin manifest.\n *\n * Not the `readSkillMetadata` exported from `loading/loader.ts` one import away, whose name this\n * carried until the two proved impossible to tell apart in prose. That one is handed the\n * metadata.yaml's own PATH and answers a verdict — the single judgment of whether a file describes\n * its skill, which `compile`, config-types generation and `doctor` all defer to — and it warns\n * about nothing. This is handed the skill DIRECTORY, answers null for a file that is absent as\n * readily as for one nothing can be read out of, and warns on the way past both, because the\n * compile it feeds runs either way with two manifest fields left off.\n */\nasync function readPluginSkillMetadata(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 readPluginSkillMetadata(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","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 os from \"os\";\nimport path from \"path\";\n\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { fileExists, readFileSafe } from \"../../utils/fs\";\nimport { verbose } from \"../../utils/logger\";\nimport {\n CLAUDE_DIR,\n MAX_PLUGIN_FILE_SIZE,\n PLUGINS_SUBDIR,\n PLUGIN_MANIFEST_DIR,\n PLUGIN_MANIFEST_FILE,\n} from \"../../consts\";\nimport type { PluginManifest } from \"../../types\";\nimport { pluginManifestSchema } from \"../schemas\";\n\nexport function getUserPluginsDir(): string {\n return path.join(os.homedir(), CLAUDE_DIR, PLUGINS_SUBDIR);\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 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","import { readdir } from \"fs/promises\";\nimport type { Dirent } from \"fs\";\n\nimport { DEFAULT_PLUGIN_NAME } from \"../../consts\";\nimport { loadProjectConfig, type LoadedProjectConfig } from \"../configuration\";\nimport {\n detectInstallation,\n isHomeDirectory,\n resolveInstallPaths,\n INSTALL_MODE_LABELS,\n type Installation,\n type InstallMode,\n} from \"../installation\";\nimport type { SkillScope } from \"../../types/config\";\n\nconst AGENT_FILE_EXTENSION = \".md\";\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 getInstallationInfo(): Promise<InstallationInfo | null> {\n const installation = await detectInstallation();\n if (!installation) return null;\n\n const loaded = await loadProjectConfig(installation.projectDir);\n const agentDirCounts = await countCompiledAgentsPerScope(\n installation,\n installedScopes(installation),\n );\n\n return {\n mode: installation.mode,\n name: loaded?.config.name || DEFAULT_PLUGIN_NAME,\n skillCount: countManagedSkills(loaded),\n agentCount: sumCounts(agentDirCounts),\n configPath: installation.configPath,\n agentDirs: agentDirCounts.filter(hasEntries).map((scopeCount) => scopeCount.dir),\n };\n}\n\n/**\n * The number of skills the CLI reports it manages, which is what its own configuration declares\n * and nothing else. Neither the plugin registry nor `.claude/skills/` answers that question:\n * each holds only the half of an installation its own install path writes — so a mixed install\n * read from either one reports a fraction of itself — and each also holds entries this CLI never\n * wrote, which it has no business claiming. The install mode is therefore irrelevant here.\n *\n * A tombstone (`excluded: true`) records a skill this project has switched OFF, so it is not one\n * of them; and a skill enabled under both roots is two registrations of one skill, so the entries\n * merge by id.\n */\nfunction countManagedSkills(loaded: LoadedProjectConfig | null): number {\n if (!loaded) return 0;\n\n const managed = loaded.config.skills.filter((skill) => !skill.excluded);\n return new Set(managed.map((skill) => skill.id)).size;\n}\n\n/**\n * Scopes whose compiled agents belong to this installation, in report order\n * (global 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\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\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 { CLAUDE_DIR, PLUGINS_SUBDIR, STANDARD_DIRS, EJECT_SOURCE } 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","import os from \"os\";\nimport path from \"path\";\nimport { unique } from \"remeda\";\nimport type {\n AgentDefinition,\n AgentName,\n CompileAgentConfig,\n ProjectConfig,\n SkillId,\n Stack,\n StackAgentConfig,\n} from \"../../types\";\nimport { isHomeDirectory } from \"./is-home-directory\";\nimport type { AgentScopeConfig, SkillConfig, SkillScope } from \"../../types/config\";\nimport type { WizardResultV2 } from \"../../components/wizard/wizard\";\nimport {\n type MergeResult,\n type AuthoritativeScope,\n mergeWithExistingConfig,\n loadProjectConfig,\n loadProjectConfigFromDir,\n} from \"../configuration\";\nimport { type SourceLoadResult } from \"../loading\";\nimport { loadStackById, stackNotOfferedMessage } from \"../stacks\";\nimport { buildSkillRefsFromConfig } from \"../resolver\";\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 { verbose } from \"../../utils/logger\";\nimport { typedFromEntries } from \"../../utils/typed-object\";\nimport { DEFAULT_PLUGIN_NAME } from \"../../consts\";\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 sentence this config records about itself, from whichever end of the install knows it.\n *\n * The two are never both present, and the two install paths are the reason. A stack loaded HERE is\n * the wizard path, where the stack object is the authority on its own description. A description\n * carried on the wizard result is the `init --from` path, where `configToSeedPayload` writes\n * `stackId: null` on purpose — so `loadedStack` is null, there is no id to resolve a description\n * out of, and before the payload carried one the line was simply dropped.\n *\n * The loaded stack is asked first anyway, so the ordering is stated rather than left to the fact\n * that the cases do not overlap: a stack the install actually read beats a sentence handed to it.\n */\nfunction resolveDescription(\n loadedStack: Stack | null,\n shared: WizardResultV2[\"description\"],\n): string | undefined {\n return loadedStack === null ? shared : loadedStack.description;\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 buildInstallConfig(\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 `buildInstallConfig: 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 `buildInstallConfig: 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 // Per-agent curation 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 // 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 description = resolveDescription(loadedStack, wizardResult.description);\n const localConfig: ProjectConfig = {\n ...generated,\n ...(stack && { stack }),\n ...(description !== undefined && { description }),\n };\n\n verbose(\n `buildInstallConfig 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 buildInstallConfig(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 // 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","import { parse as parseYaml } from \"yaml\";\nimport path from \"path\";\nimport { getErrorMessage } from \"../../utils/errors\";\nimport { extractFrontmatter } from \"../../utils/frontmatter\";\nimport { glob, readFile, directoryExists, fileExists } from \"../../utils/fs\";\nimport { verbose, warn } from \"../../utils/logger\";\nimport {\n CLAUDE_SRC_DIR,\n DIRS,\n LOCAL_PSEUDO_CATEGORY,\n STANDARD_DIRS,\n STANDARD_FILES,\n PROJECT_ROOT,\n} from \"../../consts\";\nimport type { AgentDefinition, AgentName, SkillDefinitionMap, SkillFrontmatter } from \"../../types\";\nimport {\n describeMetadataSchemaFailure,\n formatZodIssues,\n localRawMetadataSchema,\n skillFrontmatterLoaderSchema,\n agentYamlConfigSchema,\n} from \"../schemas\";\nimport type { LocalRawMetadata } from \"../skills/local-skill-loader\";\nimport { METADATA_KEYS } from \"../metadata-keys\";\n\n/** A skill's metadata.yaml as the fields a skill is described by, or why it describes none. */\nexport type SkillMetadataRead =\n { usable: true; metadata: LocalRawMetadata } | { usable: false; reason: string };\n\n/**\n * Reads one skill's metadata.yaml into the fields a skill is described by — the\n * metadata.yaml counterpart of {@link parseFrontmatter}.\n *\n * This is the single judgment of whether a metadata.yaml describes its skill, and\n * every pass that meets one shares it: `compile`'s skill discovery, the local-skill\n * discovery that feeds config-types generation, and `doctor`'s content layer. What\n * each does about a file that describes nothing differs — compile refuses the run,\n * discovery skips the skill, doctor reports it — but what they CALL describing does\n * not. Compile used to check only that the file existed, and then only that it\n * parsed, so it loaded from SKILL.md a skill the same run's config-types pass had\n * already skipped.\n *\n * Both ways of describing nothing are refused here: a file nothing can be parsed\n * out of, and a file that parses without the fields `localRawMetadataSchema`\n * requires. `doctor` layers its stricter published-skill checks on top of the\n * fields this returns; it does not disagree with them.\n */\nexport async function readSkillMetadata(metadataPath: string): Promise<SkillMetadataRead> {\n let parsed: unknown;\n try {\n parsed = parseYaml(await readFile(metadataPath));\n } catch (error) {\n return { usable: false, reason: getErrorMessage(error) };\n }\n\n if (!isFieldMapping(parsed)) {\n return { usable: false, reason: `expected metadata fields, found ${nameYamlValue(parsed)}` };\n }\n\n const validated = localRawMetadataSchema.safeParse(parsed);\n if (!validated.success) {\n return { usable: false, reason: describeMetadataSchemaFailure(validated.error.issues, parsed) };\n }\n\n return { usable: true, metadata: validated.data };\n}\n\n/**\n * Whether this metadata names the `local` placeholder instead of a real category.\n *\n * `local` is a trapdoor rather than a category: it belongs to no domain, so a skill wearing it\n * joins no grid tab and is dropped from every sub-agent's stack. Both passes that read an\n * installed skill's metadata.yaml share this verdict — the local-skill discovery behind the\n * wizard's matrix, and the discovery behind `compile`'s skill count. One reader loading what the\n * other refused is what printed a discovery total beside a refusal about the same skill, in a\n * single run.\n *\n * The sibling of {@link readSkillMetadata}, one question over: that one asks whether the file\n * describes a skill at all, this one whether the skill it describes can be reached. A file can\n * pass the first and fail this, which is why the two verdicts are separate and why this one is\n * not repairable — nothing in the file is malformed.\n */\nexport function namesPlaceholderCategory(metadata: LocalRawMetadata): boolean {\n return metadata.category === LOCAL_PSEUDO_CATEGORY;\n}\n\nfunction isFieldMapping(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** Names what a metadata.yaml holds when it holds no fields — for the refusal's reason. */\nfunction nameYamlValue(value: unknown): string {\n if (value === null || value === undefined) return \"an empty file\";\n if (Array.isArray(value)) return \"a list\";\n return `a ${typeof value}`;\n}\n\nexport function parseFrontmatter(content: string, filePath?: string): SkillFrontmatter | null {\n const rawFrontmatter = extractFrontmatter(content);\n if (rawFrontmatter === null) return null;\n\n const parsed = skillFrontmatterLoaderSchema.safeParse(rawFrontmatter);\n\n if (!parsed.success) {\n const location = filePath ?? \"unknown file\";\n warn(`Invalid SKILL.md frontmatter in '${location}': ${formatZodIssues(parsed.error.issues)}`);\n return null;\n }\n return parsed.data;\n}\n\ntype LoadAgentsFromDirOptions = {\n /** Relative base recorded on each definition (project agents live under .claude-src/agents). */\n agentBaseDir?: string;\n /** Propagate the `custom: true` metadata flag (source/CLI agents only). */\n includeCustomFlag?: boolean;\n /** Label for the per-agent verbose line. */\n verboseLabel: string;\n};\n\n// Boundary cast: agent keys come from agentYamlConfigSchema which types config.id as AgentName;\n// custom agents (not in the union) are accepted by the schema's z.string() base\nasync function loadAgentsFromDir(\n agentsDir: string,\n sourceRoot: string,\n options: LoadAgentsFromDirOptions,\n): Promise<Partial<Record<AgentName, AgentDefinition>>> {\n const agents: Record<string, AgentDefinition> = {};\n const files = await glob(`**/${STANDARD_FILES.AGENT_METADATA_YAML}`, agentsDir);\n\n for (const file of files) {\n const fullPath = path.join(agentsDir, file);\n try {\n const content = await readFile(fullPath);\n const config = agentYamlConfigSchema.parse(parseYaml(content));\n\n agents[config.id] = {\n title: config.title,\n description: config.description,\n ...(config.model !== undefined && { model: config.model }),\n tools: config.tools,\n path: path.dirname(file),\n sourceRoot,\n ...(options.agentBaseDir ? { agentBaseDir: options.agentBaseDir } : {}),\n ...(config.domain ? { domain: config.domain } : {}),\n ...(options.includeCustomFlag && config.custom === true ? { custom: true } : {}),\n };\n\n verbose(`Loaded ${options.verboseLabel}: ${config.id} from ${file}`);\n } catch (error) {\n warn(`Skipping invalid metadata.yaml at '${fullPath}': ${getErrorMessage(error)}`);\n }\n }\n\n return agents;\n}\n\nexport async function loadAllAgents(\n projectRoot: string,\n): Promise<Partial<Record<AgentName, AgentDefinition>>> {\n return loadAgentsFromDir(path.join(projectRoot, DIRS.agents), projectRoot, {\n includeCustomFlag: true,\n verboseLabel: \"agent\",\n });\n}\n\n/**\n * Loads agent definitions from the CLI repo and a skills source in parallel,\n * merged so source definitions take precedence on name collisions.\n */\nexport async function loadMergedAgents(\n sourcePath: string,\n): Promise<Partial<Record<AgentName, AgentDefinition>>> {\n const [cliAgents, sourceAgents] = await Promise.all([\n loadAllAgents(PROJECT_ROOT),\n loadAllAgents(sourcePath),\n ]);\n return { ...cliAgents, ...sourceAgents };\n}\n\nexport async function loadProjectAgents(\n projectRoot: string,\n): Promise<Partial<Record<AgentName, AgentDefinition>>> {\n const projectAgentsDir = path.join(projectRoot, CLAUDE_SRC_DIR, STANDARD_DIRS.AGENTS);\n\n if (!(await directoryExists(projectAgentsDir))) {\n verbose(`No project agents directory at ${projectAgentsDir}`);\n const noAgents: Record<string, AgentDefinition> = {};\n return noAgents;\n }\n\n return loadAgentsFromDir(projectAgentsDir, projectRoot, {\n // Project agents are in .claude-src/agents/\n agentBaseDir: `${CLAUDE_SRC_DIR}/agents`,\n verboseLabel: \"project agent\",\n });\n}\n\nexport type LoadSkillsFromDirOptions = {\n /** Path prefix recorded on each skill's `path` (e.g. LOCAL_SKILLS_PATH or \"skills\"). */\n pathPrefix?: string;\n /**\n * When true, a SKILL.md whose sibling metadata.yaml is missing, or present but\n * describing no skill, is skipped (local-skill registration rule). Plugin\n * discovery passes false — plugin skills carry no metadata.yaml.\n */\n requireMetadata?: boolean;\n};\n\n/** One skill directory whose metadata.yaml exists but describes no skill. */\nexport type UnusableSkillMetadata = {\n /** The skill's directory name, as it appears under `.claude/skills/`. */\n skillDirName: string;\n /** Absolute path to the offending metadata.yaml. */\n metadataPath: string;\n /** The YAML parser's own message, what the file holds instead of fields, or which fields it lacks. */\n reason: string;\n};\n\nexport type LoadedSkills = {\n skills: SkillDefinitionMap;\n /**\n * Skill directories refused by {@link readSkillMetadata}. Only ever non-empty\n * under `requireMetadata` — a plugin skill carries no metadata.yaml to refuse.\n */\n unusableMetadata: UnusableSkillMetadata[];\n};\n\n/**\n * Loads SKILL.md files from a directory, parsing frontmatter for skill metadata.\n * Returns the skillId -> SkillDefinition map plus every skill directory whose\n * metadata.yaml describes no skill. Missing/invalid frontmatter and per-file read\n * errors are logged and skipped, never thrown.\n */\nexport async function loadSkillsFromDir(\n skillsDir: string,\n options: LoadSkillsFromDirOptions = {},\n): Promise<LoadedSkills> {\n const { pathPrefix = \"\", requireMetadata = false } = options;\n const skills: SkillDefinitionMap = {};\n const unusableMetadata: UnusableSkillMetadata[] = [];\n\n if (!(await directoryExists(skillsDir))) {\n return { skills, unusableMetadata };\n }\n\n const skillFiles = await glob(`**/${STANDARD_FILES.SKILL_MD}`, skillsDir);\n\n for (const skillFile of skillFiles) {\n const skillPath = path.join(skillsDir, skillFile);\n const skillDir = path.dirname(skillPath);\n const relativePath = path.relative(skillsDir, skillDir);\n const skillDirName = path.basename(skillDir);\n const displayPath = pathPrefix ? `${pathPrefix}/${relativePath}/` : `${relativePath}/`;\n\n if (requireMetadata) {\n const metadataPath = path.join(skillDir, STANDARD_FILES.METADATA_YAML);\n if (!(await fileExists(metadataPath))) {\n warn(\n `Skill '${skillDirName}' in '${displayPath}' is missing ${STANDARD_FILES.METADATA_YAML} — skipped. Add ${STANDARD_FILES.METADATA_YAML} to register it with the CLI.`,\n );\n continue;\n }\n\n // A metadata.yaml that describes no skill is reported to the caller rather\n // than loaded around: the local-skill discovery behind config-types\n // generation refuses the same file, and compile refuses the whole run over it.\n const read = await readSkillMetadata(metadataPath);\n if (!read.usable) {\n unusableMetadata.push({ skillDirName, metadataPath, reason: read.reason });\n verbose(` Unusable ${STANDARD_FILES.METADATA_YAML} in '${skillDirName}'`);\n continue;\n }\n\n // Skipped rather than reported, and silently: the file is intact, so there is nothing\n // here to repair or refuse a run over — and the sentence telling the user which field\n // to fix is `extractLocalSkill`'s, which every command reaching here also runs.\n if (namesPlaceholderCategory(read.metadata)) {\n verbose(` Placeholder ${METADATA_KEYS.CATEGORY} in '${skillDirName}'`);\n continue;\n }\n }\n\n try {\n const content = await readFile(skillPath);\n const frontmatter = parseFrontmatter(content, skillPath);\n\n if (!frontmatter?.name) {\n warn(`Skipping skill in '${skillDirName}': missing or invalid frontmatter name`);\n continue;\n }\n\n const canonicalId = frontmatter.name;\n skills[canonicalId] = {\n id: canonicalId,\n path: displayPath,\n description: frontmatter.description || \"\",\n };\n\n verbose(` Loaded skill: ${canonicalId}`);\n } catch (error) {\n verbose(` Failed to load skill: ${skillFile} - ${getErrorMessage(error)}`);\n }\n }\n\n return { skills, unusableMetadata };\n}\n\n/**\n * Loads skills from a plugin's `skills/` subdirectory. Plugin skills carry no\n * metadata.yaml, so metadata is not required here — and nothing can be refused\n * for one, which is why only the skill map comes back.\n */\nexport async function loadPluginSkills(pluginDir: string): Promise<SkillDefinitionMap> {\n const { skills } = await loadSkillsFromDir(path.join(pluginDir, \"skills\"), {\n pathPrefix: \"skills\",\n requireMetadata: false,\n });\n return skills;\n}\n","import { parse as parseYaml } from \"yaml\";\n\nexport function extractFrontmatter(content: string): unknown {\n const frontmatterRegex = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/;\n const match = content.match(frontmatterRegex);\n\n if (!match || !match[1]) {\n return null;\n }\n\n try {\n return parseYaml(match[1]);\n } catch {\n return null;\n }\n}\n","import { 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 cacheRoot,\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 { Marketplace, 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(cacheRoot(), \"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 * `{gigetCacheRoot}/{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\n/**\n * Thrown when the manifest is there, parses, and names the marketplace something this\n * CLI refuses to publish under.\n *\n * A type of its own for the reason {@link MarketplaceManifestAbsentError} is one, and\n * one step further: this is the only manifest defect whose remedy is not \"repair the\n * file so the marketplace can be named\" but \"there is nothing to install here at all\".\n * The name is the namespace Claude Code registers every plugin under, so a name it will\n * not accept leaves a marketplace that loads and can install nothing — which is the\n * state `build marketplace` refuses to publish and this is the same rule read on load.\n * Every other refusal in {@link fetchMarketplace} leaves the marketplace installable\n * and merely unnameable, so it stays an ordinary `Error` and its reader degrades.\n */\nexport class MarketplaceNameRefusedError extends Error {}\n\n/**\n * The manifest field whose value a load then USES, spelled against the type so a rename\n * of it fails here rather than silently stopping the refusal below from firing.\n */\nconst MANIFEST_NAME_FIELD: keyof Marketplace = \"name\";\n\n/**\n * Whether a manifest's refusal is about its name.\n *\n * Read off the issue's PATH rather than its text, for the reason\n * {@link MarketplaceManifestAbsentError} is a type: a message is prose that gets\n * rewritten, and a caller matching on one is a caller that stops working silently.\n */\nfunction refusesTheName(issues: readonly z.ZodIssue[]): boolean {\n return issues.some((issue) => issue.path.length === 1 && issue.path[0] === MANIFEST_NAME_FIELD);\n}\n\n/**\n * A refused manifest as the throw its readers tell apart — see\n * {@link MarketplaceNameRefusedError} for which refusal earns which type. The message is\n * one sentence either way: what separates them is the remedy, not the wording.\n */\nfunction manifestRefusal(marketplacePath: string, issues: readonly z.ZodIssue[]): Error {\n const message =\n `Invalid ${MARKETPLACE_JSON} at: ${marketplacePath}\\n\\n` +\n `Validation errors: ${formatZodIssues([...issues])}`;\n\n return refusesTheName(issues) ? new MarketplaceNameRefusedError(message) : new Error(message);\n}\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 manifestRefusal(marketplacePath, validation.error.issues);\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 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 // 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 type {\n AgentConfig,\n AgentDefinition,\n AgentName,\n CompileAgentConfig,\n CompileConfig,\n Skill,\n SkillDefinitionMap,\n SkillReference,\n StackAgentConfig,\n} from \"../types\";\nimport { verbose } from \"../utils/logger\";\nimport { typedEntries, typedFromEntries, typedKeys } from \"../utils/typed-object\";\nimport { resolveAgentConfigToSkills } from \"./stacks/stacks-loader\";\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 { 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 { 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 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 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 * Lists the keys of all enabled plugins.\n *\n * @param projectDir - Absolute path to the project root\n * @returns Array of plugin keys (e.g., [\"web-framework-react@acme-marketplace\"])\n */\nexport async function listPluginNames(projectDir: string): Promise<string[]> {\n try {\n const pluginPaths = await getVerifiedPluginInstallPaths(projectDir);\n return pluginPaths.map(({ pluginKey }) => pluginKey);\n } catch (error) {\n verbose(`Failed to list plugin names: ${getErrorMessage(error)}`);\n return [];\n }\n}\n","import path from \"path\";\nimport { 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 { namesPlaceholderCategory, 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 // The verdict is `namesPlaceholderCategory`'s and is shared with the discovery behind\n // `compile`'s skill count, so neither pass can load what the other refuses. The SENTENCE\n // is this pass's alone: it is the one that reaches every command, so saying it here says\n // it once per run rather than once per reader.\n if (namesPlaceholderCategory(metadata)) {\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 what could not be placed is the category this\n // metadata.yaml declares — whichever arm brought the id here. `resolveSkillForPopulation` in\n // `stores/wizard-store.ts` returns null both for a skill the catalogue does not carry and for\n // one it carries under a category no domain claims, and an intact install arrives by either:\n // local discovery refuses the placeholder category before the catalogue is built.\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 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 */\n/**\n * Warns when a second skill files an undeclared category under a different domain from the first.\n *\n * A synthesized category takes its domain from **whichever skill the glob reached first**, and the\n * order a directory walk returns is not a decision anybody made. Two skills sharing an undeclared\n * category while declaring different domains therefore file the second under a domain its own\n * `metadata.yaml` contradicts — silently, until now. The value feeds six product readers of\n * `getCategoryDomain`, `config-generator.ts` and `wizard-store.ts` among them, so it shapes both\n * the emitted `config.ts` and where the wizard puts the skill.\n *\n * **Reported, not resolved.** Picking a winner would need a rule the catalogue does not state, and\n * the author is the only one who can say which domain they meant. `checkCategoryDomains` does not\n * cover this — it reports a category with NO domain, and this one has two.\n */\nfunction warnOnDomainDisagreement(\n skill: ExtractedSkillMetadata,\n decidedBy: ExtractedSkillMetadata,\n): void {\n if (skill.domain === decidedBy.domain) return;\n\n warn(\n `Category '${skill.category}' has no definition, so its domain was taken from the first skill ` +\n `naming it — '${decidedBy.id}' (${decidedBy.domain}). '${skill.id}' declares ` +\n `'${skill.domain}' and will be filed under '${decidedBy.domain}'. Declare the category in ` +\n `the marketplace's own config, or make the two skills agree.`,\n );\n}\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 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}\n\n/** Builds the slug -> ID map from extracted skill metadata. */\nfunction buildSlugMap(skills: ExtractedSkillMetadata[]): SkillSlugMap {\n const slugMap: SkillSlugMap = { slugToId: {} };\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 this 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 const synthesizedFrom = new Map<string, ExtractedSkillMetadata>();\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\n // A category the catalogue DECLARES is not ours to synthesize, and not ours to judge either:\n // its domain is stated rather than inferred, so two skills disagreeing about it is a different\n // defect that `checkCategoryDomains` owns. Read from the input map rather than the one being\n // built, so a synthesized entry cannot be mistaken for a declared one.\n if (categories[skill.category]) continue;\n\n const already = synthesizedFrom.get(skill.category);\n if (already === undefined) {\n synthesizedCategories[skill.category] = synthesizeCategory(skill.category, skill.domain);\n synthesizedFrom.set(skill.category, skill);\n verbose(`Auto-synthesized category '${skill.category}' for skill '${skill.id}'`);\n continue;\n }\n\n warnOnDomainDisagreement(skill, already);\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 (the CLI's built-ins are narrowed to\n * what a source ships, and the source's are left 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 { truncateText } from \"../../utils/string\";\nimport {\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\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 * 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 * 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 * 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 * 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 withAuthorsReason(namesTheMissing(names, requirement.needsAny), requirement.reason);\n }\n\n return undefined;\n}\n\n/** What is missing, which only the current selection can say. */\nfunction namesTheMissing(names: string[], needsAny: boolean | undefined): string {\n return `requires ${joinWithConjunction(names, needsAny ? \"or\" : \"and\")}`;\n}\n\n/**\n * How much of a rule author's `reason` a grid cell carries.\n *\n * The cell wraps rather than elides, so an unbounded reason grows the tag, grows the frame, and\n * pushes the top of the wizard off the terminal — measured against the shipped catalogue, whose\n * longest reason is 242 characters and whose React Router entry alone cost four lines. A budget is\n * what keeps a variable-length authored string out of a fixed-height layout.\n *\n * 60 covers the median (46) and every reason under it untouched; 24 of 110 shipped rules are\n * clipped. Chosen against the catalogue as it stands rather than derived from the terminal, so a\n * much narrower window can still wrap one line — the frame-fit specs are what would catch that.\n */\nconst REASON_BUDGET = 60;\n\n/**\n * The rule author's own sentence, appended to the synthesised one and clipped to fit.\n *\n * The two halves say different things and neither replaces the other: the synthesis names WHAT is\n * missing, which static prose cannot know, and the author's `reason` says WHY, which the synthesis\n * cannot infer. `reason` is required by `requireRuleSchema` and enforced across the built-ins, so\n * it is a sentence every marketplace author is already made to write — and nothing read it until\n * 2026-08-23. Both siblings render theirs: `discourages[].reason` in the grid,\n * `conflicts[].reason` through `reportValidationErrors`.\n *\n * Guarded on emptiness rather than assumed present: the schema requires the KEY, not a non-empty\n * string, so a rule carrying `reason: \"\"` must not produce a dangling separator.\n */\nfunction withAuthorsReason(synthesised: string, reason: string): string {\n const stated = reason.trim();\n if (stated === \"\") return synthesised;\n\n return `${synthesised} — ${truncateText(stated, REASON_BUDGET)}`;\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\n/**\n * Builds a list of skill options for a category: which are selected, and which of\n * those are still waiting on a requirement.\n *\n * It deliberately states no advisory verdict. {@link getCellState} is the one that\n * does, because a cell is judged against the selection a click on it would produce\n * — inside a pick-one category the swap forgives a conflict that a raw per-option\n * advisory would still report. The raw advisory this function used to carry was\n * therefore not merely unread but the wrong answer for its only caller,\n * `buildCategoriesForDomain` in `lib/wizard/build-step-logic.ts`, which has always\n * called `getCellState` instead.\n *\n * @param categoryId - Category path to filter skills by\n * @param currentSelections - Currently selected skill IDs\n * @returns Array of skill options with their selection state\n */\nexport function getAvailableSkills(\n categoryId: CategoryPath,\n currentSelections: SkillId[],\n): SkillOption[] {\n const { selectedSet } = initializeSelectionContext(currentSelections);\n\n return getSkillsByCategory(categoryId).map((skill) => {\n const isSelected = selectedSet.has(skill.id);\n return {\n id: skill.id,\n selected: isSelected,\n hasUnmetRequirements: isSelected && hasUnmetRequirements(skill.id, currentSelections),\n ...unmetRequirementsReasonFor(isSelected, skill.id, currentSelections),\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/** The framework-adapter classification 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 * Framework-adapter 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, deferred rather than invented here. */\n deferredToD306?: string;\n};\n\n/**\n * Every catalog skill's audit verdict, one entry per skill.\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 '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, 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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AAA,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;AAEO,IAAM,YAAY;AAAA,EACvB;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;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,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;AAMO,IAAM,UAAU;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAMO,IAAM,cAAc;AAAA,EACzB;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;;;AC71BO,SAAS,SAAS,OAAkD;AACzE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAQO,SAAS,SAAS,OAAgC;AACvD,SAAQ,QAA8B,SAAS,KAAK;AACtD;AAGO,SAAS,YAAY,OAAmC;AAC7D,SAAQ,YAAkC,SAAS,KAAK;AAC1D;AAQO,SAAS,UAAU,OAAiC;AACzD,SAAQ,UAAgC,SAAS,KAAK;AACxD;AAYO,SAAS,kBAAkB,OAA0C;AAC1E,MAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AAExD,SAAO,OAAQ,MAA2B,OAAO;AACnD;;;AC7DA,OAAOE,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,KAAAC,UAAS;;;ACFlB,SAAS,cAAc;AAKvB,IAAM,uBAAuB;AAWtB,SAAS,2BAA2B,MAAwB;AACjE,SAAO,OAAO,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,cAAc,CAAC,qBAAqB,KAAK,SAAS,CAAC,CAAC;AACtF;AAOO,SAAS,sBAAsB,MAAc,MAA6B;AAC/E,MAAI,CAAC,QAAQ,KAAK,KAAK,MAAM,IAAI;AAC/B,WAAO,GAAG,IAAI;AAAA,EAChB;AAEA,MAAI,CAAC,mBAAmB,KAAK,IAAI,GAAG;AAClC,WAAO,GAAG,IAAI;AAAA,EAChB;AAEA,SAAO;AACT;;;ACrBO,IAAM,iBAAiB;AAAA,EAC5B,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,iBAAiB,+BAA+B,kBAAkB,0BAA0B,iBAAiB,IAAI;AAAA,EACjH,uBAAuB;AAAA,EACvB,4BAA4B;AAAA,EAC5B,uBAAuB;AAAA,EACvB,sBAAsB,gCAA2B,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASnE,sBAAsB,yBAAyB,kBAAkB,kDAAkD,iBAAiB;AACtI;AAEO,IAAM,mBAAmB;AAAA,EAC9B,oBAAoB;AAAA,EACpB,yBAAyB;AAC3B;AAUO,SAAS,cAAc,cAA8B;AAC1D,SAAO,GAAG,YAAY;AACxB;AAEO,IAAM,kBAAkB;AAAA,EAC7B,oBAAoB;AAAA,EACpB,gBAAgB;AAAA,EAChB,4BAA4B;AAAA,EAC5B,oBAAoB;AAAA,EACpB,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,kBAAkB;AAAA,EAClB,8BAA8B;AAAA,EAC9B,wBAAwB;AAAA,EACxB,qBAAqB;AAAA,EACrB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMhB,+BAA+B;AACjC;AASA,IAAM,sBAAsB;AAAA,EAC1B,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AACjB;AAEO,IAAM,gBAAgB;AAAA,EAC3B,iBAAiB;AAAA,EACjB,aAAa,QAAQ,kBAAkB;AAAA,EACvC,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,wBAAwB,aAAa,eAAe,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMnE,2BAA2B,2CAAsC,kBAAkB;AAAA,EACnF,wBAAwB;AAAA;AAAA,EAExB,6BAA6B,wCAAwC,oBAAoB,KAAK,IAAI,CAAC;AACrG;AAUO,SAAS,iBAAiB,cAA8B;AAC7D,SAAO,GAAG,YAAY;AACxB;AAGO,SAAS,iBAAiB,OAAuB;AACtD,SAAO,aAAa,KAAK;AAC3B;AAWO,SAAS,kBAAkB,OAAuB;AACvD,SAAO,UAAU,KAAK;AACxB;AAaO,SAAS,iBAAiB,WAAmB,WAAmB,SAAyB;AAC9F,SAAO,GAAG,SAAS,IAAI,OAAO,eAAe,SAAS;AACxD;AAUO,SAAS,kBAAkB,YAA0C;AAC1E,SAAO,GAAG,WAAW,MAAM,kCAAkC,WAAW,KAAK,IAAI,CAAC;AACpF;AAwBO,IAAM,2BAA2B;AAAA,EACtC,WAAW,QAAQ,kBAAkB;AAAA,EACrC,sBAAsB,QAAQ,kBAAkB;AAAA,EAChD,mBACE;AACJ;AAaO,SAAS,sBAAsB,UAA6C;AACjF,SAAO;AAAA,IACL,kBAAkB,SAAS,MAAM;AAAA,IACjC,GAAG,SAAS,QAAQ,YAAY;AAAA,EAClC,EAAE,KAAK,IAAI;AACb;AAGA,SAAS,aAAa,EAAE,MAAM,SAAS,GAA6B;AAClE,SAAO,CAAC,KAAK,IAAI,IAAI,OAAO,QAAQ,EAAE;AACxC;AAOO,SAAS,2BACd,WACA,WACA,QACQ;AACR,QAAM,gBAAgB,SAAS,IAAI,KAAK,MAAM,aAAa;AAC3D,SAAO,wBAAwB,SAAS,yBAAyB,SAAS,aAAa,aAAa;AACtG;AAQO,SAAS,uBAAuB,SAA0B;AAC/D,SAAO,UAAU,OAAO;AAC1B;AAWO,SAAS,4BAA4B,YAAyB,SAA0B;AAC7F,QAAM,UAAU,WAAW,WAAW,IAAI,cAAc;AACxD,QAAM,QAAQ,WAAW,IAAI,CAAC,SAAS,IAAI,IAAI,GAAG,EAAE,KAAK,IAAI;AAC7D,SAAO,GAAG,OAAO,IAAI,KAAK,uCAAuC,OAAO;AAC1E;AAQO,SAAS,uBAAuB,OAAuB;AAC5D,QAAM,UAAU,UAAU,IAAI,aAAa;AAC3C,SAAO,GAAG,KAAK,IAAI,OAAO,8BAAyB,kBAAkB;AACvE;AAGO,SAAS,sBAAsB,OAAuB;AAC3D,SAAO,oBAAoB,KAAK,IAAI,UAAU,IAAI,gBAAgB,cAAc;AAClF;AAGO,SAAS,yBAAyB,aAAqB,QAAwB;AACpF,SAAO,gCAAgC,WAAW,KAAK,MAAM;AAC/D;AASO,SAAS,4BAA4B,QAAwB;AAClE,SAAO,mBAAmB,MAAM;AAClC;AAMO,SAAS,0BAA0B,cAAgC;AACxE,QAAM,UAAU,aAAa,WAAW,IAAI,gBAAgB;AAC5D,SAAO,GAAG,aAAa,MAAM,IAAI,OAAO,0BAA0B,aAAa,KAAK,IAAI,CAAC;AAC3F;AAUO,SAAS,0BAA0B,iBAAiC;AACzE,SAAO;AAAA,IACL,sFAAsF,eAAe;AAAA,IACrG,0BAA0B,gBAAgB;AAAA,IAC1C;AAAA,EACF,EAAE,KAAK,MAAM;AACf;AAYO,SAAS,wBAAwB,iBAAiC;AACvE,SAAO;AAAA,IACL,uDAAuD,eAAe;AAAA,IACtE,0BAA0B,gBAAgB;AAAA,IAC1C;AAAA,EACF,EAAE,KAAK,MAAM;AACf;AAWO,SAAS,8BAA8B,MAAc,iBAAiC;AAC3F,QAAM,YAAY,2BAA2B,IAAI;AACjD,SAAO;AAAA,IACL,qBAAqB,IAAI,0BAA0B,eAAe;AAAA,IAClE,GAAI,UAAU,SAAS,IACnB;AAAA,MACE,cAAc,UAAU,IAAI,CAAC,cAAc,IAAI,SAAS,GAAG,EAAE,KAAK,OAAO,CAAC;AAAA,IAC5E,IACA,CAAC;AAAA,IACL;AAAA,IACA,8CAA8C,kBAAkB;AAAA,EAClE,EAAE,KAAK,MAAM;AACf;AAOO,SAAS,yBAAyB,QAAwB;AAC/D,SAAO,qBAAqB,eAAe,eAAe,qCAAgC,MAAM;AAClG;AAMO,SAAS,0BAA0B,OAAuB;AAC/D,SAAO,WAAW,KAAK,eAAe,UAAU,IAAI,YAAY,UAAU;AAC5E;AAMO,SAAS,+BAA+B,aAA6B;AAC1E,SAAO,0CAA0C,WAAW;AAC9D;AAYO,SAAS,4BAA4B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AACF,GAAkC;AAChC,SAAO,KAAK,YAAY,WAAM,YAAY;AAAA,MAAS,MAAM;AAC3D;AASA,SAAS,wBAAwB,SAA0C;AACzE,QAAM,QAAQ,QAAQ,IAAI,CAAC,EAAE,aAAa,MAAM,IAAI,YAAY,GAAG,EAAE,KAAK,IAAI;AAC9E,QAAM,UAAU,QAAQ,WAAW,IAAI,eAAe;AACtD,SAAO,OAAO,eAAe,aAAa,OAAO,KAAK,sBAAsB,OAAO;AACrF;AAMA,IAAM,4BAA4B,uDAAkD,kBAAkB;AAa/F,SAAS,2BAA2B,SAA0C;AACnF,SAAO;AAAA,IACL,wBAAwB,OAAO;AAAA,IAC/B,qDAAqD,eAAe,eAAe;AAAA,IACnF;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAcO,SAAS,gCAAgC,SAA0C;AACxF,SAAO;AAAA,IACL,wBAAwB,OAAO;AAAA,IAC/B;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAQA,IAAM,gCACJ;AAUK,SAAS,yBAAyB,IAAsB;AAC7D,SAAO;AAAA,IACL,kBAAkB,kBAAkB,gBAAgB,EAAE;AAAA,IACtD,kBAAkB,gBAAgB,EAAE,CAAC;AAAA,EACvC;AACF;AAGO,SAAS,4BAA4B,YAA4B;AACtE,SAAO,qCAAqC,UAAU,UAAU,kBAAkB,4BAAuB,6BAA6B;AACxI;AAOO,SAAS,0BAA0B,YAA4B;AACpE,SAAO,kGAAkG,UAAU,UAAU,kBAAkB,qDAAgD,6BAA6B;AAC9N;AAgBO,SAAS,+BACd,UACA,YACQ;AACR,SAAO;AAAA,IACL;AAAA,IAGA,GAAG,SAAS,IAAI,CAAC,OAAO,WAAW,EAAE,mBAAmB;AAAA,IACxD,GAAG,WAAW,IAAI,CAAC,SAAS,eAAe,IAAI,mBAAmB;AAAA,IAClE;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAWO,SAAS,qBAAqB,UAAqC;AACxE,SAAO,WAAW,SAAS,MAAM,yCAAyC,SAAS,KAAK,IAAI,CAAC;AAC/F;AAGO,SAAS,qBAAqB,YAAuC;AAC1E,SAAO,WAAW,WAAW,MAAM,0BAA0B,WAAW,KAAK,IAAI,CAAC;AACpF;AAOO,SAAS,qBAAqB,UAAqC;AACxE,SAAO,SAAS,SAAS,MAAM,yCAAyC,SAAS,KAAK,IAAI,CAAC;AAC7F;AAUO,IAAM,sBAAsB;AAAA,EACjC,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMhB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA;AAAA,EAEvB,iBAAiB;AAAA,EACjB,SAAS;AACX;AAUO,SAAS,0BAA0B,IAAoB;AAC5D,SAAO;AAAA,IACL,2BAA2B,EAAE;AAAA,IAC7B,QAAQ,kBAAkB,gBAAgB,EAAE,0BAA0B,kBAAkB,gBAAgB,EAAE;AAAA,EAC5G,EAAE,KAAK,IAAI;AACb;AAeO,SAAS,yBAAyB,eAA0C;AACjF,SAAO;AAAA,IACL;AAAA,IACA,GAAG,mBAAmB,aAAa;AAAA,IACnC;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAGA,SAAS,mBAAmB,eAA4C;AACtE,MAAI,cAAc,WAAW,GAAG;AAC9B,WAAO;AAAA,MACL;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,gBAAgB,cAAc,MAAM;AAAA,IACpC,GAAG,cAAc,IAAI,CAAC,eAAe,KAAK,UAAU,EAAE;AAAA,EACxD;AACF;AAUO,SAAS,iBAAiB,UAAsC;AACrE,SAAO;AAAA,IACL;AAAA,IACA,GAAG,SAAS,IAAI,CAAC,OAAO,WAAW,EAAE,EAAE;AAAA,IACvC,qBAAqB,kBAAkB;AAAA,EACzC,EAAE,KAAK,IAAI;AACb;AAgBO,SAAS,gBAAgB,UAAsC;AACpE,SAAO;AAAA,IACL;AAAA,IACA,GAAG,SAAS,IAAI,CAAC,OAAO,WAAW,EAAE,EAAE;AAAA,IACvC,QAAQ,kBAAkB;AAAA,EAC5B,EAAE,KAAK,IAAI;AACb;AAkBO,SAAS,sBAAsBC,oBAAmC;AACvE,SAAO;AAAA,IACLA;AAAA,IACA,6EAAwE,kBAAkB,6DAA6D,kBAAkB;AAAA,IACzK,mBAAmB,UAAU,yBAAyB,kBAAkB;AAAA,IACxE,IAAI,kBAAkB;AAAA,EACxB,EAAE,KAAK,IAAI;AACb;AAOO,SAAS,+BAA+B,QAAwB;AACrE,SAAO,iHAA4G,MAAM;AAC3H;AAWO,SAAS,mBAAmB,WAAmB,OAAuB;AAC3E,QAAM,UAAU,UAAU,IAAI,UAAU;AACxC,QAAM,SAAS,UAAU,IAAI,OAAO;AACpC,SAAO,QAAQ,KAAK,IAAI,OAAO,OAAO,SAAS,eAAU,mBAAmB,wCAAwC,MAAM;AAC5H;AASO,IAAM,iBAAiB;AAAA,EAC5B,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,2BAA2B;AAAA,EAC3B,gBAAgB;AAClB;AAOO,SAAS,mBAAmB,WAA2B;AAC5D,SAAO,GAAG,SAAS;AACrB;AAQO,SAAS,sBAAsB,WAA2B;AAC/D,SAAO,GAAG,SAAS;AACrB;;;AC/tBA,SAAS,KAAAC,UAAS;AAClB,SAAS,iBAAiB;;;ACD1B,OAAkB;AAGX,SAAS,eAAe,OAA2B;AACxD,QAAMC,SAAO,MAAM,KAAK,KAAK,GAAG;AAChC,MAAI,MAAM,SAAS,qBAAqB;AACtC,WAAO,sBAAsB,MAAM,KAAK,KAAK,MAAM,CAAC;AAAA,EACtD;AACA,SAAOA,SAAO,GAAGA,MAAI,KAAK,MAAM,OAAO,KAAK,MAAM;AACpD;AAEO,SAAS,gBAAgB,OAA6B;AAC3D,SAAO,MAAM,OAAO,IAAI,cAAc;AACxC;;;ACCO,IAAM,cAAc,CAAC,UAAU,QAAQ,SAAS,SAAS,SAAS;AAIlE,IAAM,eAAe,CAAC,OAAO,UAAU,QAAQ,SAAS,KAAK;AAI7D,IAAM,mBAAmB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AFkBO,IAAM,kBAAkBC,GAAE,KAAK,WAAW;AAE1C,IAAM,oBAAoBA,GAAE,KAAK,YAAY;AAE7C,IAAM,uBAAuBA,GAAE,KAAK,gBAAgB;AAEpD,IAAM,kBAAkBA,GAAE,KAAK,WAAW;AAG1C,IAAM,qBAAqBA,GAAE,OAAO,EAAE;AAAA,EAC3C,CAAC,QAA6B;AAC5B,QAAI,QAAQ,sBAAuB,QAAO;AAC1C,QAAK,WAAiC,SAAS,GAAG,EAAG,QAAO;AAE5D,WAAO,mBAAmB,KAAK,GAAG;AAAA,EACpC;AAAA,EACA;AAAA,IACE,SAAS;AAAA,EACX;AACF;AAEO,IAAM,wBAAoDA,GAAE,OAAO;AAAA,EACxE,MAAMA,GAAE,KAAK,CAAC,WAAW,UAAU,QAAQ,CAAC;AAAA,EAC5C,SAASA,GAAE,OAAO,EAAE,cAAc;AAAA,EAClC,QAAQA,GAAE,OAAO,EAAE,cAAc;AAAA,EACjC,QAAQA,GAAE,OAAO,EAAE,cAAc;AACnC,CAAC;AAEM,IAAM,4BAA4DA,GAAE,OAAO;AAAA,EAChF,SAASA,GAAE,OAAO,EAAE,cAAc;AAAA,EAClC,OAAOA,GAAE,MAAM,qBAAqB,EAAE,cAAc;AACtD,CAAC;AAEM,IAAM,oBAAoBA,GAAE,OAAOA,GAAE,OAAO,GAAGA,GAAE,MAAM,yBAAyB,CAAC;AAGxF,IAAM,kCAAkCA,GAAE,OAAO;AAAA,EAC/C,SAASA,GAAE,OAAO,EAAE,cAAc;AAAA,EAClC,OAAOA,GAAE,MAAM,qBAAqB,EAAE,IAAI,CAAC;AAC7C,CAAC;AAGM,IAAM,0BAA0BA,GAAE;AAAA,EACvCA,GAAE,OAAO;AAAA,EACTA,GAAE,MAAM,+BAA+B;AACzC;AAEO,IAAM,wBAAoDA,GAAE,OAAO;AAAA,EACxE,IAAIA,GAAE,OAAO;AAAA,EACb,WAAWA,GAAE,QAAQ,EAAE,cAAc;AAAA,EACrC,OAAOA,GAAE,QAAQ,EAAE,cAAc;AAAA,EACjC,MAAMA,GAAE,OAAO,EAAE,cAAc;AACjC,CAAC;AAGM,IAAM,+BAA+BA,GAAE,OAAO;AAAA;AAAA,EAEnD,MAAMA,GAAE,OAAO;AAAA,EACf,aAAaA,GAAE,OAAO;AAAA,EACtB,OAAO,gBAAgB,cAAc;AACvC,CAAC;AAaM,IAAM,4BAA4BA,GACtC,OAAO;AAAA,EACN,UAAU,mBAAmB,cAAc;AAAA,EAC3C,QAAQA,GAAE,OAAO,EAAE,cAAc;AAAA,EACjC,QAAQA,GAAE,OAAO;AAAA,EACjB,QAAQA,GAAE,QAAQ,EAAE,cAAc;AACpC,CAAC,EACA,YAAY;AAMR,IAAM,0BAA0BA,GAAE,OAAO;AAAA,EAC9C,UAAU;AAAA,EACV,QAAQA,GAAE,OAAO;AAAA,EACjB,aAAaA,GAAE,OAAO,EAAE,cAAc;AAAA,EACtC,MAAMA,GAAE,OAAO;AAAA,EACf,gBAAgBA,GAAE,OAAO,EAAE,cAAc;AAAA,EACzC,eAAeA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAExC,QAAQA,GAAE,OAAO;AAAA,EACjB,QAAQA,GAAE,QAAQ,EAAE,cAAc;AACpC,CAAC;AAEM,IAAM,qBAA8CA,GAAE,OAAO;AAAA,EAClE,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACtB,OAAOA,GAAE,OAAO,EAAE,cAAc;AAClC,CAAC;AAGD,IAAM,6BAA6BA,GAAE,OAAO;AAAA,EAC1C,MAAMA,GAAE,OAAO;AAAA,EACf,SAASA,GAAE,OAAO,EAAE,cAAc;AAAA,EAClC,aAAaA,GAAE,OAAO,EAAE,cAAc;AAAA,EACtC,QAAQ,mBAAmB,cAAc;AAAA;AAAA,EAEzC,UAAUA,GAAE,OAAO,EAAE,cAAc;AAAA,EACnC,UAAUA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,cAAc;AAAA,EAC5C,UAAUA,GAAE,MAAM,CAACA,GAAE,OAAO,GAAGA,GAAE,MAAMA,GAAE,OAAO,CAAC,CAAC,CAAC,EAAE,cAAc;AAAA,EACnE,QAAQA,GAAE,MAAM,CAACA,GAAE,OAAO,GAAGA,GAAE,MAAMA,GAAE,OAAO,CAAC,CAAC,CAAC,EAAE,cAAc;AAAA,EACjE,QAAQA,GAAE,MAAM,CAACA,GAAE,OAAO,GAAGA,GAAE,MAAMA,GAAE,OAAO,CAAC,CAAC,CAAC,EAAE,cAAc;AAAA,EACjE,OAAOA,GAAE,MAAM,CAACA,GAAE,OAAO,GAAG,iBAAiB,CAAC,EAAE,cAAc;AAChE,CAAC;AAGM,IAAM,uBAAkD;AAGxD,IAAM,iCAAiC,2BAA2B,OAAO;AAEzE,IAAM,wBAAoDA,GAAE,OAAO;AAAA,EACxE,IAAIA,GAAE,OAAO;AAAA,EACb,OAAOA,GAAE,OAAO;AAAA,EAChB,aAAaA,GAAE,OAAO;AAAA,EACtB,OAAO,gBAAgB,cAAc;AAAA,EACrC,QAAQ,kBAAkB,cAAc;AAAA,EACxC,OAAOA,GAAE,MAAMA,GAAE,OAAO,CAAC;AAAA,EACzB,iBAAiBA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,cAAc;AAAA,EACnD,gBAAgB,qBAAqB,cAAc;AAAA,EACnD,OAAO,kBAAkB,cAAc;AAAA,EACvC,cAAcA,GAAE,OAAO,EAAE,cAAc;AAAA,EACvC,QAASA,GAAE,OAAO,EAAwB,cAAc;AAAA,EACxD,QAAQA,GAAE,QAAQ,EAAE,cAAc;AACpC,CAAC;AAID,IAAM,+BAA+BA,GAAE,MAAM;AAAA,EAC3CA,GAAE,OAAO;AAAA,EACT;AACF,CAAC;AAOM,IAAM,yBAAyBA,GAAE;AAAA,EACtCA,GAAE,OAAO;AAAA,EACTA,GAAE,MAAM,CAAC,8BAA8BA,GAAE,MAAM,4BAA4B,CAAC,CAAC;AAC/E;AAQA,IAAM,wBAAwB,EAAE,QAAQ,cAAc;AAMtD,IAAM,6BAA6B,EAAE,QAAQ,SAAS;AAKtD,SAAS,oBAAoB,QAAgB,QAAwB;AACnE,SAAO,IAAI,MAAM,qBAAqB,MAAM,kEAA6D,MAAM;AACjH;AAEA,SAAS,kBACP,QACA,SACAC,QACA,KACM;AACN,aAAW,CAAC,QAAQ,MAAM,KAAK,OAAO,QAAQ,OAAO,GAAG;AACtD,QAAI,EAAE,UAAU,QAAS;AACzB,QAAI,SAAS;AAAA,MACX,MAAM;AAAA,MACN,MAAM,CAAC,GAAGA,QAAM,MAAM;AAAA,MACtB,SAAS,oBAAoB,QAAQ,MAAM;AAAA,IAC7C,CAAC;AAAA,EACH;AACF;AAWA,SAAS,oBAAoB,QAAiB,KAA4B;AACxE,MAAI,CAAC,SAAS,MAAM,EAAG;AAEvB,oBAAkB,QAAQ,uBAAuB,CAAC,GAAG,GAAG;AAExD,QAAM,EAAE,OAAO,IAAI;AACnB,MAAI,CAAC,MAAM,QAAQ,MAAM,EAAG;AAC5B,aAAW,CAAC,OAAO,KAAK,KAAK,OAAO,QAAQ,GAAG;AAC7C,QAAI,CAAC,SAAS,KAAK,EAAG;AACtB,sBAAkB,OAAO,4BAA4B,CAAC,UAAU,KAAK,GAAG,GAAG;AAAA,EAC7E;AACF;AAOA,IAAM,oBAAoBD,GAAE,QAAQ,EAAE,YAAY,mBAAmB;AAGrE,IAAM,sBAAsBA,GACzB,OAAO;AAAA;AAAA,EAEN,MAAMA,GAAE,OAAO,EAAE,cAAc;AAAA,EAC/B,aAAaA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAEtC,QAAQA,GACL;AAAA,IACCA,GAAE,OAAO;AAAA,MACP,MAAMA,GAAE,OAAO;AAAA,MACf,OAAOA,GAAE,KAAK,CAAC,WAAW,QAAQ,CAAC;AAAA;AAAA,MAEnC,OAAO,gBAAgB,cAAc;AAAA,MACrC,QAAQ,kBAAkB,cAAc;AAAA,MACxC,UAAUA,GAAE,QAAQ,EAAE,cAAc;AAAA,IACtC,CAAC;AAAA,EACH,EACC,cAAc;AAAA;AAAA,EAEjB,QAAQA,GACL;AAAA,IACCA,GAAE,OAAO;AAAA,MACP,IAAIA,GAAE,OAAO;AAAA,MACb,OAAOA,GAAE,KAAK,CAAC,WAAW,QAAQ,CAAC;AAAA,MACnC,QAAQA,GAAE,OAAO;AAAA,MACjB,UAAUA,GAAE,QAAQ,EAAE,cAAc;AAAA,IACtC,CAAC;AAAA,EACH,EACC,cAAc;AAAA;AAAA,EAGjB,QAAQA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAEjC,iBAAiBA,GAAE,MAAMA,GAAE,OAAO,CAAsB,EAAE,cAAc;AAAA;AAAA,EAExE,OAAOA,GAAE,OAAOA,GAAE,OAAO,GAAG,sBAAsB,EAAE,cAAc;AAAA;AAAA,EAElE,aAAaA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAEtC,iBAAiBA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAE1C,cAAcA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAEvC,UAAUA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,cAAc;AAC9C,CAAC,EACA,YAAY;AAOR,IAAM,4BAA4B,kBAAkB,KAAK,mBAAmB;AAEnF,IAAM,2BAA0DA,GAAE,OAAO;AAAA,EACvE,IAAIA,GAAE,OAAO;AAAA,EACb,aAAaA,GAAE,OAAO;AAAA,EACtB,aAAaA,GAAE,OAAO;AAAA,EACtB,QAASA,GAAE,OAAO,EAAwB,cAAc;AAAA,EACxD,WAAWA,GAAE,QAAQ;AAAA,EACrB,OAAOA,GAAE,OAAO;AAAA,EAChB,MAAMA,GAAE,OAAO,EAAE,cAAc;AACjC,CAAC;AAiBD,SAAS,wBAAwB,OAAwB;AACvD,QAAM,QAAQ,OAAO,UAAU,WAAW,IAAI,KAAK,MAAM;AACzD,SACE,GAAG,KAAK;AAKZ;AAGA,IAAM,kBAAkBA,GAAE,KAAK,aAAa;AAAA,EAC1C,OAAO,CAAC,UAAU,wBAAwB,MAAM,KAAK;AACvD,CAAC;AAGD,IAAM,uBAAuBA,GAAE,OAAO;AAAA,EACpC,QAAQA,GAAE,MAAM,eAAe,EAAE,IAAI,CAAC;AAAA,EACtC,QAAQA,GAAE,OAAO;AACnB,CAAC;AAED,IAAM,qBAA8C;AAEpD,IAAM,uBAAkD;AAExD,IAAM,oBAA4CA,GAAE,OAAO;AAAA,EACzD,OAAO;AAAA,EACP,OAAOA,GAAE,MAAM,eAAe,EAAE,IAAI,CAAC;AAAA,EACrC,UAAUA,GAAE,QAAQ,EAAE,cAAc;AAAA,EACpC,QAAQA,GAAE,OAAO;AACnB,CAAC;AAED,IAAM,yBAAsDA,GAAE,OAAO;AAAA,EACnE,SAASA,GAAE,OAAO;AAAA,EAClB,QAAQA,GAAE,MAAM,eAAe,EAAE,IAAI,CAAC;AACxC,CAAC;AAED,IAAM,gCAAoEA,GAAE,OAAO;AAAA,EACjF,WAAWA,GAAE,MAAM,kBAAkB;AAAA,EACrC,aAAaA,GAAE,MAAM,oBAAoB;AAAA,EACzC,UAAUA,GAAE,MAAM,iBAAiB;AAAA,EACnC,cAAcA,GAAE,MAAM,sBAAsB;AAC9C,CAAC;AAMM,IAAM,4BAA4BA,GAAE,OAAO;AAAA,EAChD,SAASA,GAAE,OAAO;AAAA,EAClB,YAAYA,GAAE,OAAOA,GAAE,OAAO,GAAG,wBAAwB;AAC3D,CAAC;AAMM,IAAM,uBAAuBA,GAAE,OAAO;AAAA,EAC3C,SAASA,GAAE,OAAO;AAAA,EAClB,eAAe,8BAA8B,cAAc;AAC7D,CAAC;AAMM,IAAM,yBAAyBA,GACnC,OAAO;AAAA;AAAA,EAEN,aAAaA,GAAE,OAAO;AAAA;AAAA,EAEtB,MAAMA,GAAE,OAAO;AAAA;AAAA,EAEf,gBAAgBA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAEzC,UAAU;AAAA;AAAA,EAEV,eAAeA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAExC,QAAQA,GAAE,OAAO;AAAA;AAAA,EAEjB,QAAQA,GAAE,QAAQ,EAAE,cAAc;AACpC,CAAC,EAGA,YAAY;AAGR,IAAM,2BAA2BA,GACrC,OAAO;AAAA,EACN,YAAYA,GACT,OAAO;AAAA;AAAA,IAEN,SAASA,GAAE,OAAO;AAAA;AAAA,IAElB,aAAaA,GAAE,OAAO;AAAA;AAAA,IAEtB,MAAMA,GAAE,OAAO;AAAA;AAAA,IAEf,QAAQA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,IAEjC,MAAMA,GAAE,OAAO,EAAE,cAAc;AAAA,EACjC,CAAC,EACA,cAAc;AACnB,CAAC,EAGA,YAAY;AAEf,IAAM,cAAcA,GAAE,OAAO;AAAA,EAC3B,IAAIA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACpB,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACtB,aAAaA,GAAE,OAAO;AAAA;AAAA,EAEtB,QAAQA,GAAE,OAAOA,GAAE,OAAO,GAAG,sBAAsB;AAAA;AAAA,EAEnD,YAAYA,GAAE,OAAO,EAAE,cAAc;AACvC,CAAC;AAIM,IAAM,qBAAqBA,GAAE,OAAO;AAAA,EACzC,QAAQA,GAAE,MAAM,WAAW,EAAE,IAAI,CAAC;AACpC,CAAC;AAED,IAAM,gCAAoEA,GAAE,OAAO;AAAA,EACjF,QAAQA,GAAE,KAAK,CAAC,UAAU,KAAK,CAAC;AAAA,EAChC,MAAMA,GAAE,OAAO,EAAE,cAAc;AAAA,EAC/B,KAAKA,GAAE,OAAO,EAAE,cAAc;AAAA,EAC9B,KAAKA,GAAE,OAAO,EAAE,cAAc;AAChC,CAAC;AAED,IAAM,0BAAwDA,GAAE,OAAO;AAAA,EACrE,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA,EAEtB,QAAQA,GAAE,MAAM,CAACA,GAAE,OAAO,GAAG,6BAA6B,CAAC;AAAA,EAC3D,aAAaA,GAAE,OAAO,EAAE,cAAc;AAAA,EACtC,SAASA,GAAE,OAAO,EAAE,cAAc;AAAA,EAClC,QAAQ,mBAAmB,cAAc;AAAA;AAAA,EAEzC,UAAUA,GAAE,OAAO,EAAE,cAAc;AAAA,EACnC,UAAUA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,cAAc;AAC9C,CAAC;AAGD,IAAM,yBAAsD;AAE5D,IAAM,4BAA4DA,GAAE,OAAO;AAAA;AAAA,EAEzE,YAAYA,GAAE,OAAO,EAAE,cAAc;AACvC,CAAC;AAcD,IAAM,2BACJ;AAEK,IAAM,oBAA4CA,GAAE,OAAO;AAAA,EAChE,SAASA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMlC,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,MAAM,oBAAoB,EAAE,SAAS,yBAAyB,CAAC;AAAA,EACvF,SAASA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACzB,aAAaA,GAAE,OAAO,EAAE,cAAc;AAAA,EACtC,OAAO;AAAA,EACP,UAAU,0BAA0B,cAAc;AAAA,EAClD,SAASA,GAAE,MAAM,uBAAuB,EAAE,IAAI,CAAC;AACjD,CAAC;AAUM,IAAM,2BAA2BA,GAAE,OAAO;AAAA;AAAA,EAE/C,KAAKA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACrB,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,cAAc;AACxC,CAAC;AAGD,IAAM,yBAAyBA,GAAE,OAAO;AAAA;AAAA,EAEtC,OAAOA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,cAAc;AAAA;AAAA,EAEzC,MAAMA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,cAAc;AAC1C,CAAC;AAGM,IAAM,qBAAqBA,GAC/B,OAAO;AAAA,EACN,aAAa,uBAAuB,cAAc;AACpD,CAAC,EACA,YAAY;AAGf,IAAM,uBAAuBA,GAAE,OAAO;AAAA;AAAA,EAEpC,MAAMA,GAAE,OAAO,EAAE,cAAc;AACjC,CAAC;AAGD,IAAM,4BAA4BA,GAC/B,OAAO;AAAA;AAAA,EAEN,aAAaA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAEtC,QAAQA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAEjC,iBAAiBA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAE1C,cAAcA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAEvC,UAAU,qBAAqB,cAAc;AAAA;AAAA,EAE7C,WAAWA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAEpC,WAAWA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAEpC,YAAYA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAErC,gBAAgBA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAEzC,WAAWA,GAAE,OAAO,EAAE,cAAc;AACtC,CAAC,EACA,YAAY;AAMR,IAAM,4BAA4B,kBAAkB,KAAK,yBAAyB;AAMlF,IAAM,4BAA4BA,GACtC,OAAO;AAAA,EACN,SAASA,GAAE,OAAO,EAAE,cAAc;AAAA,EAClC,IAAIA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACpB,OAAOA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACvB,aAAaA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,OAAO,gBAAgB,cAAc;AAAA,EACrC,QAAQ,kBAAkB,cAAc;AAAA,EACxC,OAAOA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,IAAI,CAAC;AAAA,EAChC,iBAAiBA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,cAAc;AAAA,EACnD,gBAAgB,qBAAqB,cAAc;AAAA,EACnD,OAAO,wBAAwB,cAAc;AAAA,EAC7C,cAAcA,GAAE,OAAO,EAAE,cAAc;AAAA,EACvC,QAASA,GAAE,OAAO,EAAwB,cAAc;AAAA,EACxD,QAAQA,GAAE,QAAQ,EAAE,cAAc;AACpC,CAAC,EACA,OAAO;AAGH,IAAM,mCAAmCA,GAC7C,OAAO;AAAA;AAAA,EAEN,MAAMA,GAAE,OAAO,EAAE,MAAM,kBAAkB,EAAE,IAAI,CAAC;AAAA,EAChD,aAAaA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA,EAE7B,OAAOA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAEhC,iBAAiBA,GAAE,OAAO,EAAE,cAAc;AAAA,EAC1C,OAAO,gBAAgB,cAAc;AAAA,EACrC,QAAQ,kBAAkB,cAAc;AAAA,EACxC,gBAAgB,qBAAqB,cAAc;AAAA;AAAA,EAEnD,QAAQA,GAAE,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,cAAc;AAAA,EACjD,OAAO,wBAAwB,cAAc;AAC/C,CAAC,EACA,OAAO;AAGH,IAAM,mCAAmCA,GAC7C,OAAO;AAAA,EACN,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACtB,aAAaA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA,EAE7B,4BAA4BA,GAAE,QAAQ,EAAE,cAAc;AAAA;AAAA,EAEtD,kBAAkBA,GAAE,QAAQ,EAAE,cAAc;AAAA;AAAA,EAE5C,iBAAiBA,GAAE,OAAO,EAAE,cAAc;AAAA,EAC1C,OAAO,gBAAgB,cAAc;AAAA;AAAA,EAErC,SAASA,GAAE,KAAK,CAAC,MAAM,CAAC,EAAE,cAAc;AAAA;AAAA,EAExC,OAAOA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAEhC,iBAAiBA,GAAE,OAAO,EAAE,cAAc;AAC5C,CAAC,EACA,OAAO;AAQV,IAAM,mBAAmBA,GAAE,OAAO;AAAA;AAAA,EAEhC,SAASA,GAAE,OAAO;AAAA;AAAA,EAElB,SAASA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,cAAc;AAAA;AAAA,EAE/C,aAAaA,GAAE,OAAO;AAAA;AAAA,EAEtB,QAAQA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAEjC,MAAMA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAE/B,MAAMA,GAAE,OAAO;AACjB,CAAC;AAQD,IAAM,6BAA6B;AAOnC,IAAM,0BAA0BA,GAAE,OAAO;AAAA;AAAA,EAEvC,QAAQA,GAAE,OAAO,EAAE,MAAM,qBAAqB;AAAA;AAAA,EAE9C,aAAaA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAAA;AAAA,EAErC,gBAAgBA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,0BAA0B;AAAA;AAAA,EAEhE,eAAeA,GAAE,OAAO,EAAE,IAAI,EAAE;AAAA;AAAA,EAEhC,aAAaA,GACV,OAAO,EACP,MAAM,eAAe,EACrB,cAAc;AAAA;AAAA,EAEjB,SAASA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAElC,YAAY,iBAAiB,cAAc;AAAA;AAAA,EAE3C,QAASA,GAAE,OAAO,EAAwB,cAAc;AAAA;AAAA,EAExD,QAAQA,GAAE,QAAQ,EAAE,cAAc;AACpC,CAAC;AAkBD,SAAS,2BAA2B,OAAwB;AAC1D,QAAM,QAAQ,OAAO,UAAU,WAAW,IAAI,KAAK,MAAM;AACzD,SACE,GAAG,KAAK,2JAC6D,cAAc,MAAM,6BACpE,eAAe,aAAa;AAIrD;AAGO,IAAM,2BAA2B,wBACrC,OAAO;AAAA;AAAA,EAEN,UAAUA,GAAE,KAAK,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,EAK3B,MAAMA,GAAE,KAAK,aAAa;AAAA,IACxB,OAAO,CAAC,UAAU,2BAA2B,MAAM,KAAK;AAAA,EAC1D,CAAC;AACH,CAAC,EACA,OAAO;AAGH,IAAM,iCAAiC,wBAAwB,OAAO;AAAA;AAAA,EAE3E,UAAUA,GAAE,OAAO;AAAA;AAAA,EAEnB,MAAMA,GAAE,OAAO,EAAE,MAAM,kBAAkB,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAC1D,CAAC;AAED,IAAM,6BAA6BA,GAChC,OAAO;AAAA,EACN,IAAIA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA,EAEpB,WAAWA,GAAE,QAAQ,EAAE,cAAc;AACvC,CAAC,EACA,OAAO;AAGH,IAAM,8BAA8BA,GACxC,OAAO;AAAA;AAAA,EAEN,IAAIA,GAAE,OAAO,EAAE,MAAM,kBAAkB,EAAE,cAAc;AAAA,EACvD,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACtB,SAASA,GAAE,OAAO;AAAA,EAClB,QAAQA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACxB,aAAaA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAEtC,SAASA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAElC,SAASA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAElC,WAAWA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAEpC,QAAQA,GAAE,MAAM,0BAA0B,EAAE,IAAI,CAAC;AAAA;AAAA,EAEjD,QAAQA,GAAE,MAAMA,GAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC,EAAE,IAAI,CAAC;AAAA;AAAA,EAE3D,aAAaA,GACV,OAAOA,GAAE,OAAO,GAAGA,GAAE,OAAOA,GAAE,OAAO,GAAGA,GAAE,MAAM,0BAA0B,CAAC,CAAC,EAC5E,cAAc;AAAA;AAAA,EAEjB,YAAYA,GAAE,OAAO,EAAE,cAAc;AAAA;AAAA,EAErC,YAAYA,GAAE,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,cAAc;AAAA,EACrD,MAAMA,GAAE,MAAMA,GAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC,EAAE,cAAc;AAAA;AAAA,EAElE,WAAWA,GACR;AAAA,IACCA,GAAE,OAAO;AAAA,IACTA,GACG,OAAO;AAAA;AAAA,MAEN,cAAcA,GAAE,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,cAAc;AAAA;AAAA,MAEvD,QAAQA,GAAE,QAAQ,EAAE,cAAc;AAAA,IACpC,CAAC,EACA,OAAO;AAAA,EACZ,EACC,cAAc;AAAA;AAAA,EAEjB,SAASA,GACN,OAAO;AAAA,IACN,SAASA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,cAAc;AAAA,IAC/C,WAAWA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,cAAc;AAAA,EACnD,CAAC,EACA,OAAO,EACP,cAAc;AAAA;AAAA,EAEjB,OAAO,wBAAwB,cAAc;AAC/C,CAAC,EACA,OAAO;AAGH,SAAS,gBAAgB,QAA8B;AAC5D,SAAO,OAAO,IAAI,cAAc,EAAE,KAAK,IAAI;AAC7C;AAOO,SAAS,sBAAsB,aAAsB;AAC1D,QAAM,SAAS,iBAAiB,WAAW,IACvC,iCACA;AACJ,SAAO,OAAO,UAAU,WAAW;AACrC;AAQO,SAAS,8BACd,QACA,aACQ;AACR,QAAM,CAAC,QAAQ,SAAS,IAAI,UAAU,QAAQ,CAAC,UAAU,cAAc,OAAO,WAAW,CAAC;AAC1F,SAAO;AAAA,IACL,GAAI,OAAO,SAAS,IAAI,CAAC,kBAAkB,MAAM,CAAC,IAAI,CAAC;AAAA,IACvD,GAAG,UAAU,IAAI,cAAc;AAAA,EACjC,EAAE,KAAK,IAAI;AACb;AAGA,SAAS,cAAc,OAAmB,aAA+C;AACvF,QAAM,CAAC,OAAO,GAAG,MAAM,IAAI,MAAM;AACjC,SAAO,OAAO,WAAW,KAAK,OAAO,UAAU,YAAY,YAAY,KAAK,MAAM;AACpF;AAEA,SAAS,kBAAkB,QAA8B;AACvD,QAAM,SAAS,OAAO,IAAI,CAAC,UAAU,MAAM,KAAK,KAAK,GAAG,CAAC;AACzD,SAAO,oBAAoB,OAAO,WAAW,IAAI,UAAU,QAAQ,KAAK,OAAO,KAAK,IAAI,CAAC;AAC3F;AAUA,SAAS,2BAA2B,OAA4B;AAC9D,SAAO,MAAM,SAAS,aAAa,MAAM,KAAK,WAAW,KAAK,MAAM,KAAK,CAAC,MAAM;AAClF;AAGA,SAAS,mBAAmB,KAAkC;AAC5D,MAAI,OAAO,QAAQ,OAAO,QAAQ,SAAU,QAAO;AAEnD,QAAM,QAAS,IAAqC;AACpD,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAOA,SAAS,wBAAwB,OAAmB,gBAA4C;AAC9F,MAAI,mBAAmB,OAAW,QAAO,eAAe,KAAK;AAC7D,SAAO,qBAAqB,eAAe,MAAM,yDAAoD,0BAA0B;AACjI;AAUO,SAAS,8BACd,OACA,aACoB;AACpB,QAAM,CAAC,YAAY,YAAY,IAAI,UAAU,MAAM,QAAQ,0BAA0B;AAErF,QAAM,iBAAiB,mBAAmB,WAAW;AACrD,QAAM,WAAW,WAAW,IAAI,CAAC,UAAU,wBAAwB,OAAO,cAAc,CAAC;AAEzF,SAAO,EAAE,QAAQ,aAAa,IAAI,cAAc,GAAG,SAAS;AAC9D;AAMO,SAAS,qBAAqB,OAAgB,UAA2B;AAC9E,WAAS,MAAM,KAAc,OAAwB;AACnD,QAAI,QAAQ,SAAU,QAAO;AAC7B,QAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,aAAO,IAAI,MAAM,CAAC,SAAS,MAAM,MAAM,QAAQ,CAAC,CAAC;AAAA,IACnD;AACA,QAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU;AAC3C,aAAO,OAAO,OAAO,GAAG,EAAE,MAAM,CAAC,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC;AAAA,IAC5D;AACA,WAAO;AAAA,EACT;AACA,SAAO,MAAM,OAAO,CAAC;AACvB;AAMO,SAAS,iBAAiB,KAAuB;AACtD,MAAI,OAAO,QAAQ,OAAO,QAAQ,SAAU,QAAO;AACnD,MAAI,EAAE,YAAY,KAAM,QAAO;AAC/B,SAAO,IAAI,WAAW;AACxB;AASO,SAAS,kBACd,QACA,cACA,SACM;AACN,QAAM,cAAc,IAAI,IAAI,YAAY;AACxC,QAAM,cAAc,OAAO,KAAK,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,IAAI,CAAC,CAAC;AACzE,MAAI,YAAY,SAAS,GAAG;AAC1B,SAAK,qBAAqB,OAAO,KAAK,YAAY,KAAK,IAAI,CAAC,EAAE;AAAA,EAChE;AACF;;;AG38BA,OAAOE,WAAU;AACjB,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB;AAS3B,IAAM,sBAAsBC,MAAK;AAAA,EAC/BA,MAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAAA,EAC3C;AACF;AAWO,IAAM,oBAAN,cAAgC,MAAM;AAAA,EAC3C,YACW,YACA,QACT;AACA,UAAM,gCAAgC,UAAU,MAAM,MAAM,EAAE;AAHrD;AACA;AAGT,SAAK,OAAO;AAAA,EACd;AAAA,EALW;AAAA,EACA;AAKb;AAYO,IAAM,2BAAN,cAAuC,MAAM;AAAA,EAClD,YAAqB,YAAoB;AACvC,UAAM,cAAc,UAAU,yBAAyB;AADpC;AAEnB,SAAK,OAAO;AAAA,EACd;AAAA,EAHqB;AAIvB;AAQA,IAAM,mBAAmB;AAOzB,SAAS,oBAAoB,WAA6B;AACxD,MAAI,SAAS,SAAS,KAAK,UAAU,YAAY,OAAW,QAAO,UAAU;AAC7E,SAAO;AACT;AAGA,SAAS,wBAAwB,WAA6B;AAC5D,SAAO,SAAS,SAAS,KAAK,oBAAoB,aAAa,EAAE,aAAa;AAChF;AAGA,SAAS,eAAe,OAAyB;AAC/C,SAAO,SAAS,QAAS,OAAO,UAAU,YAAY,OAAO,KAAK,KAAK,EAAE,WAAW;AACtF;AAWA,eAAsB,WAAc,YAAoB,QAA0C;AAChG,MAAI,CAAE,MAAM,WAAW,UAAU,GAAI;AACnC,YAAQ,uBAAuB,UAAU,EAAE;AAC3C,WAAO;AAAA,EACT;AAEA,MAAI;AACJ,MAAI;AASF,UAAM,OAAO,WAAW,YAAY,KAAK;AAAA,MACvC,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB,OAAO,EAAE,qBAAqB,oBAAoB;AAAA,IACpD,CAAC;AAED,gBAAY,MAAM,KAAK,OAAO,UAAU;AAAA,EAC1C,SAAS,OAAO;AACd,UAAM,IAAI,MAAM,+BAA+B,UAAU,MAAM,gBAAgB,KAAK,CAAC,IAAI;AAAA,MACvF,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,QAAM,MAAM,oBAAoB,SAAS;AAKzC,MAAI,eAAe,GAAG,GAAG;AACvB,YAAQ,aAAa,UAAU,kBAAkB;AACjD,WAAO;AAAA,EACT;AAEA,MAAI,wBAAwB,SAAS,GAAG;AACtC,UAAM,IAAI,yBAAyB,UAAU;AAAA,EAC/C;AAEA,MAAI,QAAQ;AACV,UAAM,SAAS,OAAO,UAAU,GAAG;AACnC,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,IAAI,kBAAkB,YAAY,gBAAgB,OAAO,MAAM,MAAM,CAAC;AAAA,IAC9E;AACA,WAAO,OAAO;AAAA,EAChB;AAGA,SAAO;AACT;;;AC9IA,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAeV,SAAS,eAAe,YAAoB,OAAuC;AACxF,SAAO,UAAU,WAAWC,IAAG,QAAQ,IAAI;AAC7C;AAGO,SAAS,qBAAqB,KAAqB;AACxD,SAAOC,MAAK,KAAK,KAAK,gBAAgB,eAAe,SAAS;AAChE;AAQO,SAAS,oBACd,YACA,QAAoB,WACN;AACd,QAAM,UAAU,eAAe,YAAY,KAAK;AAChD,SAAO;AAAA,IACL,WAAWA,MAAK,KAAK,SAAS,iBAAiB;AAAA,IAC/C,WAAWA,MAAK,KAAK,SAAS,YAAY,cAAc,MAAM;AAAA,IAC9D,YAAY,qBAAqB,OAAO;AAAA,EAC1C;AACF;;;APtBO,IAAM,iBAAiB,GAAG,cAAc,aAAa;AACrD,IAAM,iBAAiB;AA6D9B,eAAe,iBACb,KACA,OACwC;AACxC,QAAM,aAAa,UAAU,YAAY,YAAY;AACrD,QAAM,aAAa,qBAAqB,GAAG;AAE3C,MAAI,CAAE,MAAM,WAAW,UAAU,GAAI;AACnC,YAAQ,GAAG,UAAU,wBAAwB,UAAU,EAAE;AACzD,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,MAAM,yBAAyB,UAAU;AACtD,MAAI,CAAC,KAAM,QAAO;AAElB,UAAQ,UAAU,KAAK,gBAAgB,GAAG,EAAE;AAC5C,SAAO;AACT;AASA,eAAe,yBACb,YACwC;AACxC,MAAI;AACF,WAAO,MAAM,WAAW,YAAY,yBAAyB;AAAA,EAC/D,SAAS,OAAO;AACd,QAAI,qBAAqB,KAAK,EAAG,OAAM;AACvC,UAAM,uBAAuB,KAAK;AAAA,EACpC;AACF;AAUA,SAAS,qBAAqB,OAAyB;AACrD,SAAO,iBAAiB,qBAAqB,iBAAiB;AAChE;AAYA,SAAS,uBAAuB,OAAuB;AACrD,SAAO,IAAI,MAAM,sBAAsB,gBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC;AAC3E;AAUA,eAAsB,wBACpB,YACwC;AACxC,SAAO,iBAAiB,YAAY,gBAAgB,UAAU,IAAI,WAAW,SAAS;AACxF;AAGA,eAAsB,yBAAiE;AACrF,SAAO,iBAAiBC,IAAG,QAAQ,GAAG,QAAQ;AAChD;AAQA,eAAe,0BACb,YACuC;AACvC,QAAM,gBAAgB,MAAM,2BAA2B,UAAU;AACjE,MAAI,cAAe,QAAO,EAAE,QAAQ,eAAe,QAAQ,UAAU;AAErE,QAAM,eAAe,MAAM,uBAAuB;AAClD,MAAI,aAAc,QAAO,EAAE,QAAQ,cAAc,QAAQ,SAAS;AAElE,SAAO;AACT;AAWA,eAAe,2BACb,YACwC;AACxC,MAAI,eAAe,UAAa,gBAAgB,UAAU,EAAG,QAAO;AACpE,SAAO,wBAAwB,UAAU;AAC3C;AAMA,eAAsB,cAAc,SAAwD;AAC1F,QAAM,EAAE,QAAQ,MAAM,WAAW,IAAI;AACrC,QAAM,YAAY,MAAM,0BAA0B,UAAU;AAG5D,QAAM,kBAAkB,WAAW,OAAO;AAC1C,QAAM,mBAAmB,oBAAoB,UAAa,EAAE,aAAa,gBAAgB;AAEzF,MAAI,SAAS,QAAW;AACtB,4BAAwB,IAAI;AAC5B,YAAQ,kCAAkC,IAAI,EAAE;AAChD,WAAO,EAAE,QAAQ,MAAM,cAAc,QAAQ,GAAG,iBAAiB;AAAA,EACnE;AAEA,QAAM,YAAY,WAAW,SAAS,cAAc,IAAI;AACxD,MAAI,cAAc,QAAW;AAC3B,WAAO,EAAE,QAAQ,WAAW,cAAc,OAAO,GAAG,iBAAiB;AAAA,EACvE;AAEA,MAAI,WAAW,OAAO,aAAa;AACjC,YAAQ,oBAAoB,UAAU,MAAM,YAAY,UAAU,OAAO,WAAW,EAAE;AACtF,WAAO;AAAA,MACL,QAAQ,UAAU,OAAO;AAAA,MACzB,cAAc,UAAU;AAAA,MACxB,GAAG;AAAA,IACL;AAAA,EACF;AAEA,UAAQ,8BAA8B,cAAc,EAAE;AACtD,SAAO,EAAE,QAAQ,gBAAgB,cAAc,WAAW,GAAG,iBAAiB;AAChF;AAUA,IAAM,qBAAqB;AAM3B,SAAS,wBAAwB,MAAoB;AACnD,MAAI,KAAK,KAAK,MAAM,IAAI;AACtB,UAAM,IAAI;AAAA,MACR,GAAG,kBAAkB;AAAA,IACvB;AAAA,EACF;AACA,uBAAqB,KAAK,KAAK,GAAG,kBAAkB;AACtD;AAUA,SAAS,gBAAoC;AAC3C,QAAM,WAAW,QAAQ,IAAI,cAAc;AAC3C,MAAI,CAAC,SAAU,QAAO;AAEtB,QAAM,UAAU,SAAS,KAAK;AAC9B,MAAI,YAAY,IAAI;AAClB,SAAK,GAAG,cAAc,sEAAiE;AACvF,WAAO;AAAA,EACT;AAEA,MAAI;AACF,yBAAqB,SAAS,cAAc;AAAA,EAC9C,SAAS,OAAO;AACd;AAAA,MACE,GAAG,cAAc;AAAA,EAAwE,gBAAgB,KAAK,CAAC;AAAA,IACjH;AACA,WAAO;AAAA,EACT;AAEA,UAAQ,oBAAoB,cAAc,aAAa,OAAO,EAAE;AAChE,SAAO;AACT;AA2BA,eAAsB,gBAAgB,YAAgD;AACpF,QAAM,CAAC,KAAK,MAAM,IAAI,MAAM,QAAQ,IAAI;AAAA,IACtC,2BAA2B,UAAU;AAAA,IACrC,uBAAuB;AAAA,EACzB,CAAC;AAED,SAAO;AAAA,IACL,MAAM,KAAK,UAAU,QAAQ,QAAQ,UAAU,QAAQ,iBAAiB;AAAA,EAC1E;AACF;AAWA,eAAsB,0BAA0B,YAA2C;AACzF,QAAM,iBAAiB,MAAM,cAAc,EAAE,QAAQ,UAAU,WAAW,CAAC;AAC3E,SAAO;AAAA,IACL,MAAM;AAAA,IACN,KAAK,eAAe;AAAA,IACpB,aAAa;AAAA,EACf;AACF;AAEA,IAAM,mBAAmB;AAAA,EACvB,cAAc;AAAA;AAAA,EACd,cAAc;AAAA;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGA,IAAM,yBAAyB;AAC/B,IAAM,oBAAoB;AAG1B,IAAM,oBAAoB;AAG1B,IAAM,yBAAyB;AAI/B,IAAM,mBAAmB;AAIzB,IAAM,uBACJ;AAGF,IAAM,uBACJ;AAUK,SAAS,qBAAqB,QAAgB,UAAwB;AAE3E,MAAI,kBAAkB,KAAK,MAAM,GAAG;AAClC,UAAM,IAAI;AAAA,MACR,GAAG,QAAQ;AAAA;AAAA;AAAA;AAAA,IAGJ,QAAQ;AAAA,IACR,QAAQ;AAAA,IACjB;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,mBAAmB;AACrC,UAAM,IAAI;AAAA,MACR,GAAG,QAAQ,uBAAuB,OAAO,MAAM,oBAAoB,iBAAiB;AAAA;AAAA;AAAA;AAAA,IAG7E,QAAQ;AAAA,IACR,QAAQ;AAAA,IACjB;AAAA,EACF;AAEA,QAAM,kBAAkB,iBAAiB,KAAK,CAAC,WAAW,OAAO,WAAW,MAAM,CAAC;AAEnF,MAAI,iBAAiB;AACnB,yBAAqB,QAAQ,iBAAiB,QAAQ;AAAA,EACxD,OAAO;AACL,sBAAkB,QAAQ,QAAQ;AAAA,EACpC;AACF;AAEA,SAAS,qBAAqB,QAAgB,UAAkB,UAAwB;AACtF,QAAM,oBAAoB,OAAO,MAAM,SAAS,MAAM,EAAE,KAAK;AAE7D,MAAI,kBAAkB,SAAS,wBAAwB;AACrD,UAAM,IAAI;AAAA,MACR,GAAG,QAAQ,4BAA4B,MAAM;AAAA;AAAA;AAAA;AAAA,IAGtC,QAAQ;AAAA,IACR,QAAQ;AAAA,IACjB;AAAA,EACF;AAGA,MAAI,uBAAuB,KAAK,iBAAiB,GAAG;AAClD,UAAM,IAAI;AAAA,MACR,GAAG,QAAQ,qCAAqC,MAAM;AAAA;AAAA;AAAA;AAAA,IAG/C,QAAQ;AAAA,IACR,QAAQ;AAAA,IACjB;AAAA,EACF;AAGA,MAAI,aAAa,cAAc,aAAa,WAAW;AACrD,oBAAgB,QAAQ,QAAQ;AAAA,EAClC;AAGA,MAAI,aAAa,cAAc,aAAa,WAAW;AACrD,yBAAqB,QAAQ,mBAAmB,QAAQ;AAAA,EAC1D;AACF;AAEA,SAAS,gBAAgB,QAAgB,UAAwB;AAE/D,QAAM,gBAAgB,OAAO,QAAQ,gBAAgB,EAAE;AAEvD,QAAM,mBAAmB,cAAc,MAAM,GAAG,EAAE,CAAC,KAAK;AACxD,QAAM,WAAW,iBAAiB,MAAM,GAAG,EAAE,CAAC,KAAK;AAGnD,QAAM,kBAAkB,iBAAiB,WAAW,GAAG,KAAK,iBAAiB,SAAS,GAAG;AACzF,MAAI,CAAC,YAAa,CAAC,SAAS,SAAS,GAAG,KAAK,aAAa,eAAe,CAAC,iBAAkB;AAC1F,UAAM,IAAI;AAAA,MACR,GAAG,QAAQ,yBAAyB,MAAM;AAAA;AAAA;AAAA;AAAA,IAGnC,QAAQ;AAAA,IACR,QAAQ;AAAA,IACjB;AAAA,EACF;AAGA,MAAI,qBAAqB,KAAK,QAAQ,KAAK,qBAAqB,KAAK,gBAAgB,GAAG;AACtF,UAAM,IAAI;AAAA,MACR,GAAG,QAAQ,iDAAiD,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,IAI3D,QAAQ;AAAA,IACR,QAAQ;AAAA,IACjB;AAAA,EACF;AACF;AAEA,SAAS,qBAAqB,QAAgB,UAAkB,UAAwB;AAEtF,MAAI,CAAC,SAAS,SAAS,GAAG,GAAG;AAC3B,UAAM,IAAI;AAAA,MACR,GAAG,QAAQ,0CAA0C,MAAM;AAAA;AAAA;AAAA;AAAA,IAGpD,QAAQ;AAAA,IACR,QAAQ;AAAA,IACjB;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,QAAgB,UAAwB;AAGjE,QAAMC,wBAAuB;AAC7B,MAAIA,sBAAqB,KAAK,MAAM,GAAG;AACrC,UAAM,IAAI;AAAA,MACR,GAAG,QAAQ,kCAAkC,MAAM;AAAA;AAAA;AAAA;AAAA,IAG5C,QAAQ;AAAA,IACR,QAAQ;AAAA,IACjB;AAAA,EACF;AAIA,MAAI,iBAAiB,KAAK,MAAM,GAAG;AACjC,UAAM,IAAI;AAAA,MACR,GAAG,QAAQ,kCAAkC,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,IAI5C,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACjB;AAAA,EACF;AACF;AAgBO,SAAS,gBAAgB,QAAyB;AACvD,SAAO,WAAW;AACpB;AAGA,IAAM,wBAAwBC,GAAE,OAAO,EAAE,MAAMA,GAAE,OAAO,EAAE,CAAC;AAiB3D,eAAsB,0BAA0B,UAAoC;AAClF,QAAM,MAAM,MAAM,iBAAiBC,MAAK,KAAK,UAAU,eAAe,YAAY,CAAC;AACnF,SAAO,oBAAoB,GAAG,MAAM;AACtC;AAGA,SAAS,oBAAoB,KAA4B;AACvD,MAAI;AACJ,MAAI;AACF,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,QAAQ;AACN,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,sBAAsB,UAAU,IAAI;AACnD,SAAO,OAAO,UAAU,OAAO,KAAK,OAAO;AAC7C;AAeA,eAAsB,oBAAoB,UAAkB,QAAkC;AAC5F,SAAO,gBAAgB,MAAM,KAAM,MAAM,0BAA0B,QAAQ;AAC7E;AAEO,SAAS,cAAc,QAAyB;AACrD,MAAI,OAAO,WAAW,GAAG,KAAK,OAAO,WAAW,GAAG,GAAG;AACpD,WAAO;AAAA,EACT;AAEA,QAAM,oBAAoB,iBAAiB,KAAK,CAAC,WAAW,OAAO,WAAW,MAAM,CAAC;AAErF,MAAI,CAAC,mBAAmB;AACtB,QAAI,OAAO,SAAS,IAAI,KAAK,OAAO,SAAS,GAAG,GAAG;AACjD,YAAM,IAAI;AAAA,QACR,6BAA6B,MAAM;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AAEA,SAAO,CAAC;AACV;;;AQvlBA,SAAS,WAAAC,UAAS,SAAS,aAAAC,kBAAiB;;;ACkerC,IAAMC,aAAY;AAAA,EACvB;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;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,IAAMC,cAAa;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,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;A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","names":["os","unique","path","fs","os","fs","os","os","path","z","configLoadFailure","z","path","z","path","path","path","os","path","os","path","os","CONTROL_CHAR_PATTERN","z","path","groupBy","partition","SKILL_IDS","CATEGORIES","DOMAINS","AGENT_NAMES","BUILT_IN_MATRIX","z","z","DOMAINS","SKILL_IDS","CATEGORIES","AGENT_NAMES","categoryDefinitionSchema","BUILT_IN_MATRIX","DOMAINS","isDomain","isDomain","matrix","allSkills","SKILL_IDS","z","MODEL_NAMES","agentNameSchema","z","AGENT_NAMES","modelNameSchema","MODEL_NAMES","SKILL_IDS","AGENT_NAMES","isAgentName","matrix","matrix","z","z","z","skillRelationSchema","skillRequirementSchema","z","partition","groupBy","indexBy","uniqueBy","os","path","path","groupBy","partition","unique","partition","groupBy","path","unique","path","os","indexBy","uniqueBy","path","groupBy","unique","path","matrix","groupBy","unique","path","path","path","path","path","NULL_BYTE_PATTERN","path","path","path","path","parseYaml","path","PLUGIN_MANIFEST_FILE","path","os","path","path","os","os","path","path","os","os","path","unique","parseYaml","path","parseYaml","parseYaml","path","createHash","os","path","createHash","path","os","os","matrix","os","unique","path","os","z","os","SAFE_NAME_PATTERN","os","z","path","fg","path","fg","path","z","z","path","allSkills","path","parseYaml","path","path","path","path","path","path","parseYaml","path","path","parseYaml","unique","uniqueBy","unique","uniqueBy","slug","groupBy","labelOf","groupBy","matrix","os","matrix","path","unique"]}
|