agents-inc 0.172.0 → 0.173.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 +14 -0
- package/dist/{chunk-MBIOZ5LW.js → chunk-2RTBSLSR.js} +2 -2
- package/dist/{chunk-255DGUCH.js → chunk-3N4FSTVX.js} +12 -6
- package/dist/{chunk-255DGUCH.js.map → chunk-3N4FSTVX.js.map} +1 -1
- package/dist/{chunk-5MGRHS2G.js → chunk-AARQBW5L.js} +22 -12
- package/dist/chunk-AARQBW5L.js.map +1 -0
- package/dist/{chunk-NISWBQNS.js → chunk-BRZA7ZCX.js} +3 -3
- package/dist/{chunk-LUKDDHSI.js → chunk-EHJIQDXR.js} +2 -2
- package/dist/{chunk-MOL2J5HS.js → chunk-F437ICEG.js} +2 -2
- package/dist/{chunk-KCLBLK3F.js → chunk-ITQF35UQ.js} +3 -3
- package/dist/{chunk-7ZOWSCAO.js → chunk-LJQXQTFC.js} +2 -2
- package/dist/{chunk-6LUTY35Q.js → chunk-Q4UNHVPX.js} +4 -4
- package/dist/{chunk-33JICQD5.js → chunk-Q6WRR4BN.js} +4 -5
- package/dist/{chunk-33JICQD5.js.map → chunk-Q6WRR4BN.js.map} +1 -1
- package/dist/{chunk-5PPB6HT6.js → chunk-SPQSNZMM.js} +2 -2
- package/dist/{chunk-Y23MP2OC.js → chunk-VR6QTK5Z.js} +3 -3
- package/dist/{chunk-6CRA46YO.js → chunk-VSPC74SS.js} +41 -19
- package/dist/chunk-VSPC74SS.js.map +1 -0
- package/dist/{chunk-VILFCMRN.js → chunk-WVFBBZEP.js} +252 -102
- package/dist/chunk-WVFBBZEP.js.map +1 -0
- package/dist/commands/build/marketplace.js +2 -2
- package/dist/commands/build/plugins.js +4 -4
- package/dist/commands/compile.js +10 -10
- package/dist/commands/doctor.js +31 -13
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +13 -13
- package/dist/commands/eject.js +23 -28
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/init.js +12 -12
- package/dist/commands/list.js +3 -3
- package/dist/commands/new/marketplace.js +2 -2
- package/dist/commands/search.js +7 -7
- package/dist/commands/share.js +6 -6
- package/dist/commands/uninstall.js +45 -41
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +4 -4
- package/dist/components/common/summary-panel.js +1 -1
- package/dist/hooks/init.js +29 -20
- package/dist/hooks/init.js.map +1 -1
- package/dist/load-agent-defs-E67DSYTN.js +14 -0
- package/dist/{recompile-project-agents-5A44NJRD.js → recompile-project-agents-6G6M2RS6.js} +6 -6
- package/dist/{source-loader-LQNRI5UZ.js → source-loader-W7XCNKNA.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-5MGRHS2G.js.map +0 -1
- package/dist/chunk-6CRA46YO.js.map +0 -1
- package/dist/chunk-VILFCMRN.js.map +0 -1
- package/dist/load-agent-defs-54VIKN4T.js +0 -14
- /package/dist/{chunk-MBIOZ5LW.js.map → chunk-2RTBSLSR.js.map} +0 -0
- /package/dist/{chunk-NISWBQNS.js.map → chunk-BRZA7ZCX.js.map} +0 -0
- /package/dist/{chunk-LUKDDHSI.js.map → chunk-EHJIQDXR.js.map} +0 -0
- /package/dist/{chunk-MOL2J5HS.js.map → chunk-F437ICEG.js.map} +0 -0
- /package/dist/{chunk-KCLBLK3F.js.map → chunk-ITQF35UQ.js.map} +0 -0
- /package/dist/{chunk-7ZOWSCAO.js.map → chunk-LJQXQTFC.js.map} +0 -0
- /package/dist/{chunk-6LUTY35Q.js.map → chunk-Q4UNHVPX.js.map} +0 -0
- /package/dist/{chunk-5PPB6HT6.js.map → chunk-SPQSNZMM.js.map} +0 -0
- /package/dist/{chunk-Y23MP2OC.js.map → chunk-VR6QTK5Z.js.map} +0 -0
- /package/dist/{load-agent-defs-54VIKN4T.js.map → load-agent-defs-E67DSYTN.js.map} +0 -0
- /package/dist/{recompile-project-agents-5A44NJRD.js.map → recompile-project-agents-6G6M2RS6.js.map} +0 -0
- /package/dist/{source-loader-LQNRI5UZ.js.map → source-loader-W7XCNKNA.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/commands/doctor.ts","../../src/cli/lib/doctor/installation-reads.ts","../../src/cli/lib/doctor/ownership.ts","../../src/cli/lib/content-validator.ts","../../src/cli/lib/source-validator.ts"],"sourcesContent":["import os from \"os\";\nimport path from \"path\";\nimport { BaseCommand } from \"../base-command\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport { EXIT_CODES } from \"../lib/exit-codes\";\nimport {\n effectivelyExcludedSkillIds,\n findConfigLoadFailures,\n MarketplaceRefusedError,\n validateProjectConfig,\n SOURCE_ENV_VAR,\n type ResolvedConfig,\n} from \"../lib/configuration\";\nimport { loadSkillsMatrixFromSource, type SourceLoadResult } from \"../lib/loading\";\nimport {\n askingEachMarketplaceItself,\n MarketplaceUnreachableError,\n} from \"../lib/loading/source-fetcher\";\nimport { matrix } from \"../lib/matrix/matrix-provider\";\nimport { getStackSkillIds } from \"../lib/stacks\";\nimport { filterExcludedEntries } from \"../lib/agents\";\nimport { isHomeDirectory, installBaseDir } from \"../lib/installation\";\nimport {\n agentCodec,\n agentsDir,\n hostCompilesAgent,\n relativeConfigPath,\n skillsDir,\n skillsPathPrefix,\n} from \"../lib/installation/install-layout\";\nimport { ambiguityFinding } from \"../lib/installation/provider-flag\";\nimport {\n sourceScopesInPlay,\n type ScopeKind,\n type SourceScope,\n} from \"../lib/installation/source-scopes\";\nimport {\n hostsOf,\n hostsOnDisk,\n installedPluginSkillIds,\n providersInPlay,\n resolveConfigState,\n unofferablePlacements,\n type CheckedInstallation,\n type ConfigState,\n} from \"../lib/doctor/installation-reads\";\nimport { judgeOwnership, type Ownership } from \"../lib/doctor/ownership\";\nimport {\n layoutIsCurrent,\n providerArgument,\n recreateConfigFrom,\n scopeLabel,\n scopeNoun,\n} from \"../utils/messages\";\nimport { isSourceRepo } from \"../lib/source-validator\";\nimport {\n validateInstalledAgents,\n validateInstalledPlugins,\n validateInstalledSkills,\n validateProjectConfigFile,\n validateRegisteredSources,\n type ContentIssue,\n type ContentValidation,\n} from \"../lib/content-validator\";\nimport type {\n AgentName,\n AgentScopeConfig,\n MergedSkillsMatrix,\n ProjectConfig,\n SkillConfig,\n SkillId,\n SkillScope,\n} from \"../types\";\nimport { fileExists } from \"../utils/fs\";\nimport { plural } from \"../utils/string\";\nimport {\n CLI_INVOKE_COMMAND,\n DEFAULT_BRANDING,\n EJECT_SOURCE,\n STANDARD_FILES,\n UI_SYMBOLS,\n type Provider,\n} from \"../consts\";\nimport { countBy, unique } from \"remeda\";\n\ntype CheckKind =\n | \"config\"\n | \"config-empty\"\n | \"installations\"\n | \"source-repo\"\n | \"layout\"\n | \"placements\"\n | \"skills\"\n | \"agents\"\n | \"orphans\"\n | \"orphans-unowned\"\n | \"installed\"\n | \"plugins\"\n | \"source\"\n | \"content-config\"\n | \"content-sources\"\n | \"content-plugins\"\n | \"content-skills\"\n | \"content-agents\";\n\ntype CheckResult = {\n kind: CheckKind;\n status: \"pass\" | \"fail\" | \"warn\" | \"skip\";\n message: string;\n details?: string[];\n /** The installation a block's row is about, where the scope holds two. */\n provider?: Provider;\n};\n\ntype ConfigCheckOutput = {\n result: CheckResult;\n config: ProjectConfig | null;\n};\n\nfunction checkConfigValid(\n state: ConfigState,\n installation: CheckedInstallation,\n): ConfigCheckOutput {\n const theConfig = (verdict: string) => configRowMessage(state, installation, verdict);\n if (state.kind === \"absent\") {\n return {\n result: {\n kind: \"config\",\n status: \"fail\",\n message: theConfig(\"not found\"),\n details: [`Run '${CLI_INVOKE_COMMAND} init' to create a configuration`],\n },\n config: null,\n };\n }\n\n if (state.kind === \"unreadable\") {\n return {\n result: {\n kind: \"config\",\n status: \"fail\",\n message: theConfig(\"exists but could not be loaded\"),\n details: [state.failure.reason],\n },\n config: null,\n };\n }\n\n // Valid but empty: handed on so the rows below don't report \"config invalid\".\n if (state.kind === \"declares-nothing\") {\n return {\n result: {\n kind: \"config-empty\",\n status: \"warn\",\n message: theConfig(\"is valid but declares no skills and no agents\"),\n },\n config: state.config,\n };\n }\n\n const { config } = state;\n const validation = validateProjectConfig(config);\n\n if (!validation.valid) {\n return {\n result: {\n kind: \"config\",\n status: \"fail\",\n message: theConfig(\"has errors\"),\n details: validation.errors,\n },\n config: null,\n };\n }\n\n if (validation.warnings.length > 0) {\n return {\n result: {\n kind: \"config\",\n status: \"warn\",\n message: theConfig(\"has warnings\"),\n details: validation.warnings,\n },\n config,\n };\n }\n\n return {\n result: {\n kind: \"config\",\n status: \"pass\",\n message: theConfig(\"is valid\"),\n },\n config,\n };\n}\n\n/** Names the file actually read: the global config when this directory inherits it. */\nfunction configRowMessage(\n state: ConfigState,\n { projectDir, hosts }: CheckedInstallation,\n verdict: string,\n): string {\n if (state.kind === \"loaded\" && state.inherited)\n return `${theInheritedConfig(hosts.global)}, which ${verdict}`;\n if (state.kind === \"unreadable\") {\n const { scopeRoot, scope } = state.failure;\n return `${theConfigAt(scopeRoot, hosts[scope])} ${verdict}`;\n }\n return `${theConfigAt(projectDir, hosts.project)} ${verdict}`;\n}\n\nfunction theConfigAt(root: string, provider: Provider): string {\n return `${scopeLabel(scopeOf(root))}: ${configNamedFrom(root, provider)}`;\n}\n\nfunction theInheritedConfig(provider: Provider): string {\n return `${scopeLabel(\"project\")}: no ${STANDARD_FILES.CONFIG_TS}, using ${scopeNoun(\"global\")}'s (${configNamedFrom(os.homedir(), provider)})`;\n}\n\nfunction scopeOf(dir: string): ScopeKind {\n return isHomeDirectory(dir) ? \"global\" : \"project\";\n}\n\nfunction configNamedFrom(root: string, provider: Provider): string {\n const relPath = relativeConfigPath(root, provider);\n return isHomeDirectory(root) ? `~/${relPath}` : relPath;\n}\n\n/** The loader has already merged in every local skill it accepts, from both scopes. */\nfunction checkSkillsResolved(config: ProjectConfig, matrix: MergedSkillsMatrix): CheckResult {\n const uniqueSkills = skillIdsToResolve(config);\n\n if (uniqueSkills.length === 0) {\n return {\n kind: \"skills\",\n status: \"pass\",\n message: \"No skills configured\",\n };\n }\n\n const missingSkills = uniqueSkills.filter((skillId) => !(skillId in matrix.skills));\n\n if (missingSkills.length > 0) {\n return {\n kind: \"skills\",\n status: \"fail\",\n message: `${ratio(uniqueSkills.length - missingSkills.length, uniqueSkills.length, \"skill\")} found`,\n details: missingSkills.map((s) => `- ${s} (not found)`),\n };\n }\n\n return {\n kind: \"skills\",\n status: \"pass\",\n message: `${ratio(uniqueSkills.length, uniqueSkills.length, \"skill\")} found`,\n };\n}\n\n/** Both sources: a global-only install has skills but no stack. */\nfunction skillIdsToResolve(config: ProjectConfig): SkillId[] {\n const excludedIds = effectivelyExcludedSkillIds(config.skills);\n const stackIds = config.stack ? getStackSkillIds(config.stack) : [];\n return unique([...stackIds, ...config.skills.map((s) => s.id)]).filter(\n (id) => !excludedIds.has(id),\n );\n}\n\nasync function checkAgentsCompiled(\n config: ProjectConfig,\n installation: CheckedInstallation,\n): Promise<CheckResult> {\n if (config.agents.length === 0) {\n return {\n kind: \"agents\",\n status: \"pass\",\n message: \"No agents configured\",\n };\n }\n\n const agentChecks = await Promise.all(\n config.agents.map((agent) => agentCompileCheck(agent, installation)),\n );\n const unrenderable = agentChecks.filter((c) => c.state === \"unrenderable\");\n const missingAgents = agentChecks.filter((c) => c.state === \"missing\").map((c) => c.name);\n\n // A sub-agent the host leaves out by design is a pass, not a recompile warning.\n if (unrenderable.length === config.agents.length) {\n const hostsLeavingThemOut = unique(unrenderable.map((a) => a.provider)).join(\" or \");\n return {\n kind: \"agents\",\n status: \"pass\",\n message: `No sub-agent in this configuration is carried by ${hostsLeavingThemOut}`,\n details: unrenderable.map((a) => `- ${a.name} (left out of ${a.provider})`),\n };\n }\n\n if (missingAgents.length > 0) {\n return {\n kind: \"agents\",\n status: \"warn\",\n message: needRecompilation(missingAgents.length),\n details: missingAgents.map((a) => `- ${a} (missing)`),\n };\n }\n\n const renderable = config.agents.length - unrenderable.length;\n return {\n kind: \"agents\",\n status: \"pass\",\n message: `${ratio(renderable, renderable, \"agent\")} compiled`,\n };\n}\n\nfunction needRecompilation(count: number): string {\n return `${plural(count, \"agent\")} ${count === 1 ? \"needs\" : \"need\"} recompilation`;\n}\n\ntype AgentCompileCheck = {\n name: AgentName;\n provider: Provider;\n state: \"unrenderable\" | \"compiled\" | \"missing\";\n};\n\n/** Host read per scope: two scopes can be on two providers. */\nasync function agentCompileCheck(\n agent: AgentScopeConfig,\n { projectDir, hosts }: CheckedInstallation,\n): Promise<AgentCompileCheck> {\n const provider = hosts[agent.scope];\n if (!hostCompilesAgent(provider, agent.name)) {\n return { name: agent.name, provider, state: \"unrenderable\" };\n }\n\n const file = `${agent.name}${agentCodec(provider).extension}`;\n const compiled = await fileExists(path.join(agentsDir(provider, agent.scope, projectDir), file));\n return { name: agent.name, provider, state: compiled ? \"compiled\" : \"missing\" };\n}\n\nasync function checkNoOrphans(\n state: ConfigState,\n config: ProjectConfig | null,\n installation: CheckedInstallation,\n): Promise<CheckResult> {\n return ownershipResult(state, await judgeOwnership(state, config, installation));\n}\n\nfunction ownershipResult(\n state: ConfigState,\n { unowned, orphanedAgentFiles }: Ownership,\n): CheckResult {\n if (unowned.skills.length > 0 || unowned.agents.length > 0) {\n return {\n kind: \"orphans-unowned\",\n status: \"fail\",\n message: `${countedArtifacts(unowned.skills, unowned.agents)} installed here, and no configuration declares them`,\n details: [...unowned.skills, ...unowned.agents, ...orphanLines(orphanedAgentFiles)].map(\n (line) => `- ${line}`,\n ),\n };\n }\n\n if (orphanedAgentFiles.length > 0) {\n return {\n kind: \"orphans\",\n status: \"warn\",\n message: plural(orphanedAgentFiles.length, \"orphaned agent file\"),\n details: orphanLines(orphanedAgentFiles).map((line) => `- ${line}`),\n };\n }\n\n // With no configuration and nothing this CLI wrote, there is nothing to own: `init`'s state.\n if (state.kind === \"absent\") return skippedResult(\"orphans\");\n\n return { kind: \"orphans\", status: \"pass\", message: \"No orphaned agent files\" };\n}\n\nfunction orphanLines(fileNames: string[]): string[] {\n return fileNames.map((name) => `${name} (not in config)`);\n}\n\nfunction ratio(found: number, total: number, noun: string): string {\n return `${found}/${plural(total, noun)}`;\n}\n\nfunction countedArtifacts(skills: string[], agents: string[]): string {\n return nonZeroCounts([skills.length, \"skill\"], [agents.length, \"agent\"]);\n}\n\ntype Count = [count: number, noun: string];\n\n/** `2 skills and 1 agent`: a zero is left out rather than counted. */\nfunction nonZeroCounts(...counts: Count[]): string {\n return counts\n .filter(([count]) => count > 0)\n .map(([count, noun]) => plural(count, noun))\n .join(\" and \");\n}\n\n/** The directory is resolved per skill, since scope (and so host) varies within one config. */\nasync function checkSkillsInstalled(\n config: ProjectConfig,\n installation: CheckedInstallation,\n): Promise<CheckResult> {\n const ejectSkills = config.skills.filter((s) => s.origin === EJECT_SOURCE);\n\n if (ejectSkills.length === 0) {\n return {\n kind: \"installed\",\n status: \"pass\",\n message: \"No eject-mode skills configured\",\n };\n }\n\n const skillChecks = await Promise.all(\n ejectSkills.map((skill) => ejectedSkillCheck(skill, installation)),\n );\n const missingSkills = skillChecks.filter((c) => !c.installed);\n\n if (missingSkills.length > 0) {\n return {\n kind: \"installed\",\n status: \"warn\",\n message: `${plural(missingSkills.length, \"skill\")} missing from disk`,\n details: missingSkills.map((s) => `- ${s.id} (not found in ${s.lookedIn}/)`),\n };\n }\n\n return {\n kind: \"installed\",\n status: \"pass\",\n message: `${ratio(ejectSkills.length, ejectSkills.length, \"eject-mode skill\")} installed`,\n };\n}\n\ntype EjectedSkillCheck = { id: SkillId; installed: boolean; lookedIn: string };\n\nasync function ejectedSkillCheck(\n skill: SkillConfig,\n { projectDir, hosts }: CheckedInstallation,\n): Promise<EjectedSkillCheck> {\n const provider = hosts[skill.scope];\n const dir = skillsDir(provider, skill.scope, projectDir);\n const installed = await fileExists(path.join(dir, skill.id, STANDARD_FILES.SKILL_MD));\n\n return {\n id: skill.id,\n installed,\n lookedIn: skillsPathPrefix(provider, skill.scope, projectDir),\n };\n}\n\n/** Plugin-mode skills are checked against the plugin registry per scope, not on disk. */\nasync function checkPluginSkillsInstalled(\n config: ProjectConfig,\n installation: CheckedInstallation,\n): Promise<CheckResult> {\n const pluginSkills = config.skills.filter((s) => s.origin !== EJECT_SOURCE);\n\n if (pluginSkills.length === 0) {\n return {\n kind: \"plugins\",\n status: \"pass\",\n message: \"No plugin-mode skills configured\",\n };\n }\n\n const scopes = unique(pluginSkills.map((s) => s.scope));\n const missingPerScope = await Promise.all(\n scopes.map((scope) => pluginSkillsMissingAt(scope, pluginSkills, installation)),\n );\n const missingSkills = missingPerScope.flat();\n\n if (missingSkills.length > 0) {\n return {\n kind: \"plugins\",\n status: \"warn\",\n message: `${plural(missingSkills.length, \"skill\")} not installed as plugins`,\n details: missingSkills.map((s) => `- ${s} (no enabled plugin found)`),\n };\n }\n\n return {\n kind: \"plugins\",\n status: \"pass\",\n message: `${ratio(pluginSkills.length, pluginSkills.length, \"plugin-mode skill\")} installed`,\n };\n}\n\nasync function pluginSkillsMissingAt(\n scope: SkillScope,\n pluginSkills: SkillConfig[],\n { projectDir, hosts }: CheckedInstallation,\n): Promise<SkillId[]> {\n const installedIds = await installedPluginSkillIds(\n installBaseDir(projectDir, scope),\n hosts[scope],\n );\n return pluginSkills\n .filter((skill) => skill.scope === scope)\n .filter((skill) => !installedIds.has(skill.id))\n .map((skill) => skill.id);\n}\n\nconst MARKETPLACE_CHOSEN_BY = {\n flag: \"named by this run\",\n env: `named by ${SOURCE_ENV_VAR}`,\n project: \"named by this project's configuration\",\n global: \"named by the global configuration\",\n default: \"nothing here names one, so this is the default\",\n} as const satisfies Record<ResolvedConfig[\"sourceOrigin\"], string>;\n\nfunction howItWasReached(source: string, isLocal: boolean): string {\n return isLocal ? `Read ${source} from disk` : `Reached ${source} over the network`;\n}\n\n/** Counts the marketplace's own skills, not the loaded matrix, which also holds local ones. */\nfunction reachedMarketplace(result: SourceLoadResult): CheckResult {\n const { source, sourceOrigin } = result.sourceConfig;\n return {\n kind: \"source\",\n status: \"pass\",\n message: `Connected to ${result.isLocal ? \"local\" : \"remote\"}: ${result.sourcePath}`,\n details: [\n `${plural(result.marketplaceSkillIds.size, \"skill\")} available`,\n `${howItWasReached(source, result.isLocal)} — ${MARKETPLACE_CHOSEN_BY[sourceOrigin]}`,\n ],\n };\n}\n\n/** Asks the marketplace itself: a saved copy is read only once it answers with that copy's ETag. */\nasync function checkSourceReachable({\n projectDir,\n hosts,\n}: CheckedInstallation): Promise<CheckResult> {\n try {\n return reachedMarketplace(\n await askingEachMarketplaceItself(() =>\n loadSkillsMatrixFromSource({ projectDir, provider: hosts.project }),\n ),\n );\n } catch (error) {\n return marketplaceNotLoaded(error);\n }\n}\n\nconst NO_SAVED_COPY_READ =\n \"Doctor asks the marketplace itself, not the saved copy, which other commands still read offline\";\n\nfunction marketplaceNotLoaded(error: unknown): CheckResult {\n if (error instanceof MarketplaceUnreachableError) {\n return {\n kind: \"source\",\n status: \"fail\",\n message: `Could not reach ${error.source}`,\n details: [error.reason, NO_SAVED_COPY_READ],\n };\n }\n\n return {\n kind: \"source\",\n status: \"fail\",\n message: refusedOr(error, \"Failed to load marketplace\"),\n details: [getErrorMessage(error)],\n };\n}\n\ntype ContentCheck = {\n kind: CheckKind;\n name: string;\n noun: string;\n run: (projectDir: string) => Promise<ContentValidation>;\n};\n\n/** `blocks`: operational rows that would only restate this pass's errors, so stand down. */\ntype GatedContentCheck = ContentCheck & {\n readsConfig: boolean;\n blocks: readonly CheckKind[];\n};\n\n/** Validated first and alone: every other row would cascade from an unreadable config. */\nconst CONFIG_CHECK: ContentCheck = {\n kind: \"content-config\",\n name: \"Config\",\n noun: \"config\",\n run: validateProjectConfigFile,\n};\n\n/** Runs before the operational layer so rows with broken inputs can stand down. */\nconst CONTENT_CHECKS: GatedContentCheck[] = [\n {\n kind: \"content-sources\",\n name: \"Marketplaces\",\n noun: \"marketplace\",\n readsConfig: true,\n // A broken marketplace leaves skills out of the matrix ids resolve against.\n blocks: [\"skills\"],\n run: validateRegisteredSources,\n },\n {\n kind: \"content-plugins\",\n name: \"Plugins\",\n noun: \"plugin\",\n readsConfig: false,\n // An unparseable registry resolves as no installs at all.\n blocks: [\"plugins\"],\n run: validateInstalledPlugins,\n },\n {\n kind: \"content-skills\",\n name: \"Skills\",\n noun: \"skill\",\n // Only the config says which unmarked shared-skills directories are this installation's.\n readsConfig: true,\n // `extractLocalSkill` drops a skill with unusable metadata.\n blocks: [\"skills\"],\n run: validateInstalledSkills,\n },\n {\n kind: \"content-agents\",\n name: \"Agents\",\n noun: \"agent\",\n readsConfig: false,\n // No operational row reads agent file contents.\n blocks: [],\n run: validateInstalledAgents,\n },\n];\n\nfunction contentStatus(errors: number, warnings: number): CheckResult[\"status\"] {\n if (errors > 0) return \"fail\";\n if (warnings > 0) return \"warn\";\n return \"pass\";\n}\n\nfunction contentMessage(noun: string, count: number, errors: number, warnings: number): string {\n // A pass that walked nothing can still report an issue (e.g. an unreadable registry).\n if (errors === 0 && warnings === 0) {\n return count === 0 ? `No ${noun}s to validate` : `${plural(count, noun)} validated`;\n }\n return `${plural(count, noun)}: ${plural(errors, \"error\")}, ${plural(warnings, \"warning\")}`;\n}\n\nfunction formatContentIssue(issue: ContentIssue): string {\n const marker = issue.severity === \"error\" ? \"ERROR\" : \"WARN\";\n return `- [${marker}] ${issue.file}: ${issue.message}`;\n}\n\nfunction toContentResult(check: ContentCheck, validation: ContentValidation): CheckResult {\n const errors = validation.issues.filter((issue) => issue.severity === \"error\").length;\n const warnings = validation.issues.length - errors;\n\n return {\n kind: check.kind,\n status: contentStatus(errors, warnings),\n message: contentMessage(check.noun, validation.count, errors, warnings),\n details: [\n ...validation.notes.map((note) => `- ${note}`),\n ...validation.issues.map(formatContentIssue),\n ],\n };\n}\n\n/** Must clear the longest row name (\"Marketplace Repository\"). */\nconst CHECK_WIDTH = 24;\n\nconst SECTION_INDENT = \" \";\nconst ROW_INDENT = \" \";\n\nconst SECTION_CONTENT = \"Content checks\";\nconst SECTION_OPERATIONAL = \"Operational checks\";\nconst SKIP_NO_INSTALLATION = \"Skipped — no installation here (marketplace repository)\";\nconst SKIP_CONFIG_UNREADABLE = \"Skipped — the configuration that names them cannot be read\";\n\nconst SKIP_AFTER_CONFIG_ERROR = \"Skipped — fix the content errors above first\";\n\nfunction skipRestatingContent(nouns: string[]): string {\n return `Skipped — this row would only restate the ${nouns.join(\" and \")} errors above`;\n}\n\nfunction formatCheckName(name: string): string {\n return name.padEnd(CHECK_WIDTH);\n}\n\nfunction formatStatus(status: CheckResult[\"status\"]): string {\n switch (status) {\n case \"pass\":\n return UI_SYMBOLS.CHECK;\n case \"fail\":\n return UI_SYMBOLS.CROSS;\n case \"warn\":\n return UI_SYMBOLS.DISCOURAGED;\n case \"skip\":\n return UI_SYMBOLS.SKIPPED;\n default: {\n const _exhaustive: never = status;\n return _exhaustive;\n }\n }\n}\n\nconst DETAIL_INDENT = `${ROW_INDENT}${\" \".repeat(CHECK_WIDTH)} `;\n\nfunction formatCheckLine(name: string, result: CheckResult): string[] {\n const headerLine = `${ROW_INDENT}${formatCheckName(name)}${formatStatus(result.status)} ${result.message}`;\n const detailLines = (result.details ?? []).flatMap(indentedDetailLines);\n return [headerLine, ...detailLines];\n}\n\n/** A detail can be a multi-paragraph refusal, so every line is indented. */\nfunction indentedDetailLines(detail: string): string[] {\n return detail\n .split(\"\\n\")\n .filter((line) => line !== \"\")\n .map((line) => `${DETAIL_INDENT}${line}`);\n}\n\nfunction formatSummary(results: CheckResult[]): string {\n const counts = countBy(results, (r) => r.status);\n\n const parts = [\n `${counts.pass ?? 0} passed`,\n plural(counts.warn ?? 0, \"warning\"),\n plural(counts.fail ?? 0, \"error\"),\n ];\n\n return `${SECTION_INDENT}Summary: ${parts.join(\", \")}`;\n}\n\ntype Tip = {\n kind: CheckKind;\n status: CheckResult[\"status\"];\n /** Handed the installation the finding is about, which a command acting on it must be told. */\n line: (provider: Provider | undefined) => string;\n};\n\nconst TIPS: Tip[] = [\n {\n kind: \"agents\",\n status: \"warn\",\n line: (provider) =>\n ` Tip: Run '${commandActingOn(provider, \"compile\")}' to generate missing agent files`,\n },\n {\n kind: \"config\",\n status: \"fail\",\n line: () => ` Tip: Run '${CLI_INVOKE_COMMAND} init' to create or fix configuration`,\n },\n {\n kind: \"config-empty\",\n status: \"warn\",\n line: () =>\n ` Tip: Nothing is configured yet — run '${CLI_INVOKE_COMMAND} init' to choose skills and sub-agents`,\n },\n {\n kind: \"orphans-unowned\",\n status: \"fail\",\n line: (provider) =>\n ` Tip: Nothing declares the files above — '${commandActingOn(provider, \"init --from <id>\")}' writes a configuration that can own them again, or '${commandActingOn(provider, \"uninstall\")}' removes them, the compiled agents included: each file listed carries this CLI's own provenance, which is what that command reads when there is no configuration left`,\n },\n {\n kind: \"skills\",\n status: \"fail\",\n line: () => \" Tip: Check skill IDs in config match available skills\",\n },\n {\n kind: \"installed\",\n status: \"warn\",\n // No command named: `eject skills --force` copies every skill, and only at project scope.\n line: () => \" Tip: Re-eject the missing skills from the marketplace to restore their files\",\n },\n];\n\nfunction commandActingOn(provider: Provider | undefined, command: string): string {\n return `${CLI_INVOKE_COMMAND} ${command}${providerArgument(provider)}`;\n}\n\n/** Once per installation a finding names, and once only where the tip names none. */\nfunction formatTips(results: CheckResult[]): string[] {\n return unique(TIPS.flatMap((tip) => linesOf(tip, results)));\n}\n\nfunction linesOf(tip: Tip, results: CheckResult[]): string[] {\n return results\n .filter((result) => answers(tip, result))\n .map((result) => tip.line(result.provider));\n}\n\nfunction answers(tip: Tip, result: CheckResult): boolean {\n return result.kind === tip.kind && result.status === tip.status;\n}\n\n/** `init` refuses an unreadable config, so the remedy is recreating it, once per such config. */\nasync function recreateConfigTips(\n contentResults: CheckResult[],\n projectDir: string,\n): Promise<string[]> {\n if (!failedContentKinds(contentResults).has(CONFIG_CHECK.kind)) return [];\n\n const failures = await findConfigLoadFailures(projectDir).catch(() => []);\n return failures.map(\n (failure) =>\n ` Tip: There is no automatic repair — recreate the configuration by running ${recreateConfigFrom(failure)}`,\n );\n}\n\nconst INSTALLATIONS_ROW_NAME = \"Installations\";\n\n/** A pass, as two installations are no fault; its detail names the flag acting commands need. */\nasync function checkInstallationsInPlay(\n projectDir: string,\n providers: Provider[],\n): Promise<CheckResult> {\n const finding = await ambiguityFinding(projectDir);\n return {\n kind: \"installations\",\n status: \"pass\",\n message: `${providers.length} installations here, each checked below`,\n details: finding === null ? [] : [`- ${finding}`],\n };\n}\n\nfunction installationHeading(provider: Provider): string {\n return `${SECTION_INDENT}The ${provider} installation`;\n}\n\nconst SOURCE_REPO_ROW_NAME = \"Marketplace Repository\";\n\n/** A skip for a marketplace repository nothing is installed in, `null` for any other directory. */\nasync function uninstalledSourceRepo(projectDir: string): Promise<CheckResult | null> {\n // Aborts on the repository's own unreadable config, which `safeCheck` makes this row's finding.\n if (!(await isSourceRepo(projectDir))) return null;\n return { kind: \"source-repo\", status: \"skip\", message: SKIP_NO_INSTALLATION };\n}\n\nconst LAYOUT_ROW_NAME = \"Layout\";\n\n/** Each scope with this installation's source folder on disk, global first. */\nasync function checkLayout({ projectDir, hosts }: CheckedInstallation): Promise<CheckResult[]> {\n const scopes = await sourceScopesInPlay(projectDir, ({ kind }) => hosts[kind]);\n return scopes.map(toLayoutResult);\n}\n\nfunction toLayoutResult(scope: SourceScope): CheckResult {\n return {\n kind: \"layout\",\n status: \"pass\",\n message: layoutIsCurrent(scopeLabel(scope.kind), scope.relName),\n };\n}\n\nconst PLACEMENTS_ROW_NAME = \"Placements Offered\";\n\n/** Reports, as a row, the refusals other commands would stop on; never refuses itself. */\nasync function checkOfferedPlacements(installation: CheckedInstallation): Promise<CheckResult> {\n const findings = await unofferablePlacements(installation);\n\n if (findings.length === 0) {\n return { kind: \"placements\", status: \"pass\", message: \"Every configured skill is placeable\" };\n }\n\n return {\n kind: \"placements\",\n status: \"fail\",\n message: `${plural(findings.length, \"finding\")} would stop a command acting here`,\n details: findings.map((finding) => `- ${finding}`),\n };\n}\n\nfunction skippedResult(kind: CheckKind): CheckResult {\n return { kind, status: \"skip\", message: \"Skipped (config invalid)\" };\n}\n\nfunction sourceUnreachableSkillsResult(): CheckResult {\n return { kind: \"skills\", status: \"skip\", message: \"Skipped (marketplace unreachable)\" };\n}\n\nfunction skippedContentResult(kind: CheckKind): CheckResult {\n return { kind, status: \"skip\", message: SKIP_CONFIG_UNREADABLE };\n}\n\nfunction failedContentKinds(contentResults: CheckResult[]): ReadonlySet<CheckKind> {\n return new Set(contentResults.filter((r) => r.status === \"fail\").map((r) => r.kind));\n}\n\n/** `null` when no content pass this row reads through failed. */\nfunction contentBlockedResult(\n row: CheckKind,\n failedContent: ReadonlySet<CheckKind>,\n): CheckResult | null {\n const blockingNouns = CONTENT_CHECKS.filter((check) => failedContent.has(check.kind))\n .filter((check) => check.blocks.includes(row))\n .map((check) => check.noun);\n\n if (blockingNouns.length === 0) return null;\n\n return { kind: row, status: \"skip\", message: skipRestatingContent(blockingNouns) };\n}\n\nfunction runContentCheck(check: ContentCheck, projectDir: string): Promise<CheckResult> {\n return safeCheck(check.kind, async () => toContentResult(check, await check.run(projectDir)));\n}\n\nasync function runGatedContentCheck(\n check: GatedContentCheck,\n projectDir: string,\n configUnreadable: boolean,\n): Promise<CheckResult> {\n if (check.readsConfig && configUnreadable) return skippedContentResult(check.kind);\n return runContentCheck(check, projectDir);\n}\n\n/** One item after another, each step's results after the last's. */\nasync function flatMapInTurn<Item, Result>(\n items: readonly Item[],\n step: (item: Item) => Promise<Result[]>,\n): Promise<Result[]> {\n return items.reduce<Promise<Result[]>>(\n async (earlier, item) => [...(await earlier), ...(await step(item))],\n Promise.resolve([]),\n );\n}\n\n/** A throw becomes that row's `fail`, so one broken check can't abort the run. */\nasync function safeCheck<Result extends CheckResult | null>(\n kind: CheckKind,\n fn: () => Result | Promise<Result>,\n): Promise<Result | CheckResult> {\n try {\n return await fn();\n } catch (error) {\n return {\n kind,\n status: \"fail\",\n message: refusedOr(error, \"Check threw\"),\n details: [getErrorMessage(error)],\n };\n }\n}\n\n/** A marketplace the check refused is a finding about the config, not a fault in the check. */\nfunction refusedOr(error: unknown, otherwise: string): string {\n return error instanceof MarketplaceRefusedError ? \"Refused\" : otherwise;\n}\n\nexport default class Doctor extends BaseCommand {\n static summary = \"Diagnose common configuration issues\";\n\n static description = `Run diagnostic checks on your ${DEFAULT_BRANDING.NAME} configuration to identify issues with config validity, skill resolution, agent compilation, and marketplace connectivity.`;\n\n static examples = [\"<%= config.bin %> <%= command.id %>\"];\n\n static flags = {};\n\n async run(): Promise<void> {\n await this.parse(Doctor);\n const projectDir = process.cwd();\n\n // `verbose()` stays off: the loaders' trace would interleave with and restate the rows.\n this.printHeader(await this.resolveBrandingName(projectDir));\n const contentResults = await this.runContentChecks(projectDir);\n const operationalResults = await this.runOperationalChecks(projectDir, contentResults);\n const results = [...contentResults, ...operationalResults];\n\n this.printResults(results, await recreateConfigTips(contentResults, projectDir));\n\n if (results.some((r) => r.status === \"fail\")) {\n this.exit(EXIT_CODES.ERROR);\n }\n }\n\n private printHeader(brandingName: string): void {\n this.log(\"\");\n this.log(`${brandingName} Doctor`);\n this.log(\"\");\n this.log(`${SECTION_INDENT}Checking configuration health...`);\n this.log(\"\");\n }\n\n private async runContentChecks(projectDir: string): Promise<CheckResult[]> {\n this.log(`${SECTION_INDENT}${SECTION_CONTENT}`);\n\n const configResult = await runContentCheck(CONFIG_CHECK, projectDir);\n const configUnreadable = configResult.status === \"fail\";\n\n const rows = await Promise.all(\n CONTENT_CHECKS.map(async (check) => ({\n name: check.name,\n result: await runGatedContentCheck(check, projectDir, configUnreadable),\n })),\n );\n\n const allRows = [{ name: CONFIG_CHECK.name, result: configResult }, ...rows];\n\n for (const row of allRows) {\n this.logCheck(row.name, row.result);\n }\n\n return allRows.map((row) => row.result);\n }\n\n private async runOperationalChecks(\n projectDir: string,\n contentResults: CheckResult[],\n ): Promise<CheckResult[]> {\n this.log(\"\");\n this.log(`${SECTION_INDENT}${SECTION_OPERATIONAL}`);\n\n const failedContent = failedContentKinds(contentResults);\n if (failedContent.has(CONFIG_CHECK.kind)) {\n this.log(`${ROW_INDENT}${SKIP_AFTER_CONFIG_ERROR}`);\n return [];\n }\n\n const providers = await providersInPlay(projectDir);\n if (providers.length > 1) {\n return this.checkEachInstallation(projectDir, providers, failedContent);\n }\n return this.checkTheInstallation(projectDir, failedContent);\n }\n\n private async checkTheInstallation(\n projectDir: string,\n failedContent: ReadonlySet<CheckKind>,\n ): Promise<CheckResult[]> {\n const installation = { projectDir, hosts: hostsOnDisk(projectDir) };\n const configState = await resolveConfigState(installation);\n\n if (configState.kind === \"absent\") {\n const sourceRepo = await safeCheck(\"source-repo\", () => uninstalledSourceRepo(projectDir));\n if (sourceRepo !== null) return this.reportSourceRepo(sourceRepo);\n }\n\n return this.runAllChecks(installation, configState, failedContent);\n }\n\n /** A repository nothing is installed in skips the layer; one whose own config breaks is a row. */\n private reportSourceRepo(sourceRepo: CheckResult): CheckResult[] {\n if (sourceRepo.status === \"skip\") {\n this.log(`${ROW_INDENT}${sourceRepo.message}`);\n return [];\n }\n\n this.logCheck(SOURCE_REPO_ROW_NAME, sourceRepo);\n return [sourceRepo];\n }\n\n /** In turn rather than at once: each block prints as it runs, and each load seats the matrix. */\n private async checkEachInstallation(\n projectDir: string,\n providers: Provider[],\n failedContent: ReadonlySet<CheckKind>,\n ): Promise<CheckResult[]> {\n const installations = await safeCheck(\"installations\", () =>\n checkInstallationsInPlay(projectDir, providers),\n );\n this.logCheck(INSTALLATIONS_ROW_NAME, installations);\n\n const blocks = await flatMapInTurn(providers, (provider) =>\n this.checkOneOf(projectDir, provider, failedContent),\n );\n return [installations, ...blocks];\n }\n\n private async checkOneOf(\n projectDir: string,\n provider: Provider,\n failedContent: ReadonlySet<CheckKind>,\n ): Promise<CheckResult[]> {\n this.log(\"\");\n this.log(installationHeading(provider));\n\n const installation = { projectDir, hosts: hostsOf(provider) };\n const results = await this.runAllChecks(\n installation,\n await resolveConfigState(installation),\n failedContent,\n );\n return results.map((result) => ({ ...result, provider }));\n }\n\n private async runAllChecks(\n installation: CheckedInstallation,\n configState: ConfigState,\n failedContent: ReadonlySet<CheckKind>,\n ): Promise<CheckResult[]> {\n const { result: configResult, config } = checkConfigValid(configState, installation);\n this.logCheck(\"Config Valid\", configResult);\n\n const layoutResults = await this.reportLayout(installation);\n\n const placementsResult = await safeCheck(\"placements\", () =>\n checkOfferedPlacements(installation),\n );\n this.logCheck(PLACEMENTS_ROW_NAME, placementsResult);\n\n // Populates the matrix that the skills check reads, so it runs first.\n const sourceResult = await safeCheck(\"source\", () => checkSourceReachable(installation));\n\n const filteredConfig = config ? filterExcludedEntries(config) : null;\n\n const skillsResult = await this.resolveSkillsCheck(config, sourceResult, failedContent);\n this.logCheck(\"Skills Resolved\", skillsResult);\n\n const agentsResult = await this.resolveAgentsCheck(filteredConfig, installation);\n this.logCheck(\"Agents Compiled\", agentsResult);\n\n const orphansResult = await this.resolveOrphansCheck(config, configState, installation);\n this.logCheck(\"No Orphans\", orphansResult);\n\n const installedResult = await this.resolveInstalledCheck(filteredConfig, installation);\n this.logCheck(\"Skills Installed\", installedResult);\n\n const pluginsResult = await this.resolvePluginsCheck(\n filteredConfig,\n installation,\n failedContent,\n );\n this.logCheck(\"Plugins Installed\", pluginsResult);\n\n this.logCheck(\"Marketplace Reachable\", sourceResult);\n\n return [\n configResult,\n ...layoutResults,\n placementsResult,\n skillsResult,\n agentsResult,\n orphansResult,\n installedResult,\n pluginsResult,\n sourceResult,\n ];\n }\n\n private async reportLayout(installation: CheckedInstallation): Promise<CheckResult[]> {\n const rows = await checkLayout(installation);\n\n for (const row of rows) {\n this.logCheck(LAYOUT_ROW_NAME, row);\n }\n return rows;\n }\n\n /** Skips on a config the checks rejected: ownership can't be judged from a rejected file. */\n private async resolveOrphansCheck(\n config: ProjectConfig | null,\n configState: ConfigState,\n installation: CheckedInstallation,\n ): Promise<CheckResult> {\n if (!config && configState.kind !== \"absent\") return skippedResult(\"orphans\");\n return safeCheck(\"orphans\", () => checkNoOrphans(configState, config, installation));\n }\n\n private async resolveSkillsCheck(\n config: ProjectConfig | null,\n sourceResult: CheckResult,\n failedContent: ReadonlySet<CheckKind>,\n ): Promise<CheckResult> {\n if (!config) return skippedResult(\"skills\");\n\n const blocked = contentBlockedResult(\"skills\", failedContent);\n if (blocked) return blocked;\n if (sourceResult.status === \"fail\") return sourceUnreachableSkillsResult();\n\n return safeCheck(\"skills\", () => checkSkillsResolved(config, matrix));\n }\n\n private async resolveAgentsCheck(\n config: ProjectConfig | null,\n installation: CheckedInstallation,\n ): Promise<CheckResult> {\n if (!config) return skippedResult(\"agents\");\n return safeCheck(\"agents\", () => checkAgentsCompiled(config, installation));\n }\n\n private async resolveInstalledCheck(\n config: ProjectConfig | null,\n installation: CheckedInstallation,\n ): Promise<CheckResult> {\n if (!config) return skippedResult(\"installed\");\n return safeCheck(\"installed\", () => checkSkillsInstalled(config, installation));\n }\n\n private async resolvePluginsCheck(\n config: ProjectConfig | null,\n installation: CheckedInstallation,\n failedContent: ReadonlySet<CheckKind>,\n ): Promise<CheckResult> {\n if (!config) return skippedResult(\"plugins\");\n\n const blocked = contentBlockedResult(\"plugins\", failedContent);\n if (blocked) return blocked;\n\n return safeCheck(\"plugins\", () => checkPluginSkillsInstalled(config, installation));\n }\n\n private logCheck(name: string, result: CheckResult): void {\n for (const line of formatCheckLine(name, result)) {\n this.log(line);\n }\n }\n\n private printResults(results: CheckResult[], recreateTips: string[]): void {\n this.log(\"\");\n this.log(formatSummary(results));\n\n const tips = [...formatTips(results), ...recreateTips];\n if (tips.length > 0) {\n this.log(\"\");\n for (const tip of tips) {\n this.log(tip);\n }\n }\n\n this.log(\"\");\n }\n}\n","/**\n * `doctor`'s reads of one installation, each asked of a named provider rather than the one\n * `providerInUse` picks, so one run can report on both installations a scope holds. Two re-express\n * helpers that read the provider only through process state — `getVerifiedPluginInstallPaths` and\n * `unofferablePlacementsFound` — and answer as they do when the hosts are read off the disk.\n */\n\nimport os from \"os\";\n\nimport { ConfigLoadError, loadProjectConfigFromDir } from \"../configuration/project-config.js\";\nimport { scopeRootsInPlay } from \"../installation/source-scopes.js\";\nimport { declaresNoContent } from \"../installation/installation.js\";\nimport { detectInstallations } from \"../installation/detect-installations.js\";\nimport { isHomeDirectory } from \"../installation/is-home-directory.js\";\nimport { providerInUse } from \"../installation/install-layout.js\";\nimport { hostFor } from \"../hosts/host-for.js\";\nimport type { HostPlugin } from \"../hosts/plugin-host.js\";\nimport { refuseUnofferedPlacements } from \"../hosts/offered-placements.js\";\nimport { getPluginManifestPath } from \"../plugins/plugin-finder.js\";\nimport { parseMarketplacePluginRef } from \"../plugins/plugin-ref.js\";\nimport { getErrorMessage } from \"../../utils/errors.js\";\nimport { fileExists } from \"../../utils/fs.js\";\nimport { verbose } from \"../../utils/logger.js\";\nimport type { Provider } from \"../../consts.js\";\nimport type { ProjectConfig, SkillConfig, SkillScope } from \"../../types/index.js\";\n\n/**\n * The provider each scope's paths are read with: off the disk, as a run naming no provider reads\n * them, or one installation's for both, as a run naming `--provider` does. Never set as the run's\n * provider, so one doctor run can ask of each installation in turn.\n */\nexport type Hosts = Record<SkillScope, Provider>;\n\n/** One installation's rows: the directory they are about and the hosts its paths resolve with. */\nexport type CheckedInstallation = { projectDir: string; hosts: Hosts };\n\nexport function hostsOnDisk(projectDir: string): Hosts {\n return { project: providerInUse(projectDir), global: providerInUse(os.homedir()) };\n}\n\nexport function hostsOf(provider: Provider): Hosts {\n return { project: provider, global: provider };\n}\n\n/** The project's installations, or the global ones where the project holds none. */\nexport async function providersInPlay(projectDir: string): Promise<Provider[]> {\n const found = await detectInstallations(projectDir);\n const inTheProject = found.filter((installation) => installation.scope === \"project\");\n const inPlay = inTheProject.length > 0 ? inTheProject : found;\n return inPlay.map((installation) => installation.provider);\n}\n\n/**\n * Unreadable only where a scope holds two installations: the content layer reads the configs in\n * use, so a broken one of those has already stood the operational layer down.\n */\nexport type ConfigState =\n | { kind: \"absent\" }\n | { kind: \"unreadable\"; failure: ConfigLoadError }\n | { kind: \"declares-nothing\"; config: ProjectConfig }\n | { kind: \"loaded\"; config: ProjectConfig; inherited: boolean };\n\n/** The project's own config, else the global one it inherits, each read with its scope's host. */\nexport async function resolveConfigState({\n projectDir,\n hosts,\n}: CheckedInstallation): Promise<ConfigState> {\n try {\n return await readConfigState(projectDir, hosts);\n } catch (error) {\n if (error instanceof ConfigLoadError) return { kind: \"unreadable\", failure: error };\n throw error;\n }\n}\n\nasync function readConfigState(projectDir: string, hosts: Hosts): Promise<ConfigState> {\n const own = await loadProjectConfigFromDir(projectDir, hosts.project);\n if (own && !declaresNoContent(own.config)) {\n return { kind: \"loaded\", config: own.config, inherited: false };\n }\n\n const inherited = isHomeDirectory(projectDir)\n ? null\n : await loadProjectConfigFromDir(os.homedir(), hosts.global);\n if (inherited && !declaresNoContent(inherited.config)) {\n return { kind: \"loaded\", config: inherited.config, inherited: true };\n }\n\n return own ? { kind: \"declares-nothing\", config: own.config } : { kind: \"absent\" };\n}\n\n/**\n * `getVerifiedPluginInstallPaths` asked of a named host rather than the one in use at `baseDir`:\n * enabled plugins whose manifest is still on disk, none at all from a registry it cannot read.\n */\nexport async function installedPluginSkillIds(\n baseDir: string,\n provider: Provider,\n): Promise<ReadonlySet<string>> {\n const plugins = await verifiedPlugins(baseDir, provider);\n return new Set(plugins.map((plugin) => parseMarketplacePluginRef(plugin.pluginKey)));\n}\n\nasync function verifiedPlugins(baseDir: string, provider: Provider): Promise<HostPlugin[]> {\n const enabled = (await pluginsListedBy(provider, baseDir)).filter((plugin) => plugin.enabled);\n const onDisk = await Promise.all(\n enabled.map((plugin) => fileExists(getPluginManifestPath(plugin.installPath))),\n );\n return enabled.filter((_, index) => onDisk[index] === true);\n}\n\nasync function pluginsListedBy(provider: Provider, baseDir: string): Promise<HostPlugin[]> {\n try {\n return await hostFor(provider).listPlugins(baseDir);\n } catch (error) {\n verbose(`Failed to list installed plugins: ${getErrorMessage(error)}`);\n return [];\n }\n}\n\n/**\n * `unofferablePlacementsFound` asked of each scope's named host: both scopes, each refused by its\n * own host, since the two can be on different providers. Project first, as that one walks them.\n */\nexport async function unofferablePlacements({\n projectDir,\n hosts,\n}: CheckedInstallation): Promise<string[]> {\n const projectFirst = [...scopeRootsInPlay(projectDir)].reverse();\n const findings = await Promise.all(\n projectFirst.map(({ kind, root }) => unofferablePlacementIn(root, hosts[kind])),\n );\n return findings.filter((finding): finding is string => finding !== null);\n}\n\nasync function unofferablePlacementIn(root: string, provider: Provider): Promise<string | null> {\n const skills = await configuredSkillsAt(root, provider);\n if (skills === null) return null;\n\n try {\n refuseUnofferedPlacements(skills, hostFor(provider));\n return null;\n } catch (error) {\n return getErrorMessage(error);\n }\n}\n\n/** Degrades on `ConfigLoadError` only, which the Config Valid row reports by name. */\nasync function configuredSkillsAt(root: string, provider: Provider): Promise<SkillConfig[] | null> {\n try {\n const loaded = await loadProjectConfigFromDir(root, provider);\n return loaded?.config.skills ?? null;\n } catch (error) {\n if (error instanceof ConfigLoadError) return null;\n throw error;\n }\n}\n","/**\n * What an installation holds that its configuration does not account for: `doctor`'s No Orphans\n * row. An agents folder a configuration declares is judged against it, whatever wrote the files;\n * one none declares, by this CLI's marker. Skill folders only where no configuration exists at\n * all, by `forkedFrom`: `eject skills` copies in stamped folders that no configuration lists.\n */\n\nimport path from \"path\";\nimport { groupBy, unique } from \"remeda\";\n\nimport type { CheckedInstallation, ConfigState, Hosts } from \"./installation-reads.js\";\nimport { listAgentFilesOf } from \"../agents/index.js\";\nimport {\n agentFilesWithOurProvenanceIn,\n skillDirsWithOurProvenanceIn,\n} from \"../content-validator.js\";\nimport {\n agentCodec,\n agentsDir,\n skillsDir,\n type AgentCodec,\n} from \"../installation/install-layout.js\";\nimport { directoryExists } from \"../../utils/fs.js\";\nimport { typedValues } from \"../../utils/typed-object.js\";\nimport type { ProjectConfig, SkillScope } from \"../../types/index.js\";\n\nexport type Ownership = {\n /** Display paths of what this CLI provably wrote into a folder no configuration declares. */\n unowned: { skills: string[]; agents: string[] };\n /** File names, not paths, in a declared agents folder its configuration does not claim. */\n orphanedAgentFiles: string[];\n};\n\n/**\n * One agents folder, once however many scopes share it, and the names a configuration claims in\n * it: `null` where none declares its scope, so only what this CLI provably wrote there is named.\n */\ntype JudgedAgentFolder = { dir: string; codec: AgentCodec; claimed: ReadonlySet<string> | null };\n\n/** `config` is `null` only where `state` is absent: a config the checks rejected is not judged. */\nexport async function judgeOwnership(\n state: ConfigState,\n config: ProjectConfig | null,\n installation: CheckedInstallation,\n): Promise<Ownership> {\n const agentFolders = agentFoldersToJudge(state, config, installation);\n\n const [skills, agents, orphanedAgentFiles] = await Promise.all([\n unownedSkillDirs(state, installation),\n unownedAgentFiles(agentFolders),\n Promise.all(agentFolders.map(unclaimedAgentFiles)),\n ]);\n return { unowned: { skills, agents }, orphanedAgentFiles: orphanedAgentFiles.flat() };\n}\n\nfunction agentFoldersToJudge(\n state: ConfigState,\n config: ProjectConfig | null,\n { projectDir, hosts }: CheckedInstallation,\n): JudgedAgentFolder[] {\n return oncePerFolder(\n scopesToJudge(state, hosts).map((scope) => ({\n dir: agentsDir(hosts[scope], scope, projectDir),\n codec: agentCodec(hosts[scope]),\n claimed: claimed(state, scope, config && agentNamesClaimedIn(config, scope)),\n })),\n );\n}\n\n/** Only where no configuration exists anywhere: then every stamped folder is a leftover. */\nasync function unownedSkillDirs(\n state: ConfigState,\n { projectDir, hosts }: CheckedInstallation,\n): Promise<string[]> {\n if (state.kind !== \"absent\") return [];\n\n const dirs = unique(\n scopesToJudge(state, hosts).map((scope) => skillsDir(hosts[scope], scope, projectDir)),\n );\n const listed = await Promise.all(dirs.map(skillDirsWithOurProvenanceIn));\n return listed.flat();\n}\n\n/**\n * Project first. Beside its own config a project is judged in the global folders only when they\n * are its provider's: another provider's global ones belong to an installation this config does\n * not describe.\n */\nfunction scopesToJudge(state: ConfigState, hosts: Hosts): SkillScope[] {\n const ownConfig = state.kind !== \"absent\" && !inherits(state);\n return ownConfig && hosts.global !== hosts.project ? [\"project\"] : [\"project\", \"global\"];\n}\n\nfunction inherits(state: ConfigState): boolean {\n return state.kind === \"loaded\" && state.inherited;\n}\n\n/** `null` for a scope no configuration declares: none at all, or a project inheriting one. */\nfunction claimed(\n state: ConfigState,\n scope: SkillScope,\n names: string[] | null,\n): ReadonlySet<string> | null {\n if (names === null || state.kind === \"absent\") return null;\n if (inherits(state) && scope === \"project\") return null;\n return new Set(names);\n}\n\nfunction agentNamesClaimedIn(config: ProjectConfig, scope: SkillScope): string[] {\n return config.agents.filter((agent) => claimsAt(agent, scope)).map((agent) => agent.name);\n}\n\n/** An excluded global entry still serves other projects; an excluded project one serves nothing. */\nfunction claimsAt(entry: { scope: SkillScope; excluded?: boolean }, scope: SkillScope): boolean {\n return entry.scope === scope && (scope === \"global\" || !entry.excluded);\n}\n\n/** Two scopes can share a folder (Claude's at home): judged once, against both claims. */\nfunction oncePerFolder(folders: JudgedAgentFolder[]): JudgedAgentFolder[] {\n return typedValues(groupBy(folders, (folder) => folder.dir)).map((sharing) =>\n sharing.reduce(joinClaims),\n );\n}\n\nfunction joinClaims(into: JudgedAgentFolder, from: JudgedAgentFolder): JudgedAgentFolder {\n if (into.claimed === null) return from;\n if (from.claimed === null) return into;\n return { ...into, claimed: new Set([...into.claimed, ...from.claimed]) };\n}\n\nasync function unownedAgentFiles(agentFolders: JudgedAgentFolder[]): Promise<string[]> {\n const listed = await Promise.all(\n agentFolders\n .filter((folder) => folder.claimed === null)\n .map(({ dir, codec }) => agentFilesWithOurProvenanceIn(dir, codec)),\n );\n return listed.flat();\n}\n\nasync function unclaimedAgentFiles({ dir, codec, claimed }: JudgedAgentFolder): Promise<string[]> {\n if (claimed === null || !(await directoryExists(dir))) return [];\n const files = await listAgentFilesOf(dir, codec);\n return files.filter((file) => !claimed.has(path.basename(file, codec.extension)));\n}\n","import os from \"os\";\nimport path from \"path\";\nimport { partition } from \"remeda\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { STANDARD_FILES } from \"../consts.js\";\nimport { directoryExists, fileExists, listDirectories } from \"../utils/fs.js\";\nimport { listAgentMdFiles, splitAgentsByProvenance } from \"./agents/index.js\";\nimport { readSkillMetadata } from \"./loading/index.js\";\nimport {\n configDirsInPlay,\n findConfigLoadFailures,\n isLocalSource,\n loadInstalledConfig,\n resolvePrimarySourceEntry,\n type ConfigLoadError,\n type LoadedProjectConfig,\n type SourceEntry,\n} from \"./configuration/index.js\";\nimport { isHomeDirectory, resolveInstallPaths } from \"./installation/index.js\";\nimport { getInstalledConfigPath } from \"./installation/install-base-dir.js\";\nimport type { AgentCodec } from \"./installation/install-layout.js\";\nimport {\n getInstalledPluginsRegistryPath,\n getProjectPluginsDir,\n getUserPluginsDir,\n listPluginDirNames,\n listRegisteredPluginInstalls,\n validateAgentFrontmatter,\n validateAllPlugins,\n validatePlugin,\n validateSkillFrontmatter,\n type ResolvedPlugin,\n} from \"./plugins/index.js\";\nimport { splitMetadataValidationIssues, validateSkillMetadata } from \"./schemas.js\";\nimport { readForkedFromMetadata } from \"./skills/index.js\";\nimport { isSourceRepo, validateSource, type MarketplaceReader } from \"./source-validator.js\";\nimport { invalidResult, mergeValidationResults, validResult } from \"./validation-result.js\";\nimport { scopeLabel } from \"../utils/messages.js\";\nimport { plural } from \"../utils/string.js\";\nimport type { ValidationResult } from \"../types/index.js\";\n\n/** How a source repository under the cwd is labelled when it is not a registered source. */\nconst CWD_SOURCE_NAME = \"current directory\";\n\nexport type ContentIssue = {\n severity: \"error\" | \"warning\";\n /** The file or directory a reader has to open to fix the issue. */\n file: string;\n message: string;\n};\n\n/** `notes` records which sources were reached and which skipped; neither errors nor warnings. */\nexport type ContentValidation = {\n count: number;\n issues: ContentIssue[];\n notes: string[];\n};\n\nconst NOTHING_VALIDATED: ContentValidation = { count: 0, issues: [], notes: [] };\n\nfunction mergeValidations(parts: ContentValidation[]): ContentValidation {\n return parts.reduce(\n (acc, part) => ({\n count: acc.count + part.count,\n issues: [...acc.issues, ...part.issues],\n notes: [...acc.notes, ...part.notes],\n }),\n NOTHING_VALIDATED,\n );\n}\n\nfunction displayDir(absolutePath: string): string {\n const home = os.homedir();\n if (absolutePath === home) return \"~\";\n if (absolutePath.startsWith(home + path.sep)) {\n return `~${path.sep}${path.relative(home, absolutePath)}`;\n }\n return absolutePath;\n}\n\nfunction toIssues(file: string, result: ValidationResult): ContentIssue[] {\n return [\n ...result.errors.map((message) => ({ severity: \"error\" as const, file, message })),\n ...result.warnings.map((message) => ({ severity: \"warning\" as const, file, message })),\n ];\n}\n\nconst CONFIG_UNREADABLE = \"exists but could not be loaded\";\n\n/** Reported here, since every operational row reads the config; an absent one is no finding. */\nexport async function validateProjectConfigFile(projectDir: string): Promise<ContentValidation> {\n const [present, failures] = await Promise.all([\n countExistingConfigs(projectDir),\n findConfigLoadFailures(projectDir),\n ]);\n\n return { count: present, issues: failures.map(toUnreadableConfigIssue), notes: [] };\n}\n\n/** Led by whose config it is: from a project, its own or the inherited global one. */\nfunction toUnreadableConfigIssue(failure: ConfigLoadError): ContentIssue {\n return {\n severity: \"error\",\n file: `${scopeLabel(failure.scope)}'s ${displayDir(failure.configPath)}`,\n message: `${CONFIG_UNREADABLE}: ${failure.reason}`,\n };\n}\n\nasync function countExistingConfigs(projectDir: string): Promise<number> {\n const present = await Promise.all(\n configDirsInPlay(projectDir).map((dir) => fileExists(getInstalledConfigPath(dir))),\n );\n return present.filter(Boolean).length;\n}\n\n/** The local marketplace, plus the cwd when it is a skills source repo; remote is skipped. */\nexport async function validateRegisteredSources(projectDir: string): Promise<ContentValidation> {\n // Degrades on an unreadable config: `safeCheck` turns a throw into a failed row.\n const primary = await resolvePrimarySourceEntry(projectDir);\n const registered = [primary];\n const remote = registered.filter((source) => !isLocalSource(source.url));\n const local = await localSourcesToValidate(projectDir, registered);\n\n const outcomes = await Promise.all(\n local.map((source) => validateOneSource(source, readerFor(projectDir, source))),\n );\n\n return {\n count: local.length,\n issues: outcomes.flatMap((outcome) => outcome.issues),\n notes: [\n ...outcomes.map((outcome) => outcome.note),\n ...remote.map((source) => `${source.name} (${source.url}) — skipped (remote)`),\n ],\n };\n}\n\nasync function localSourcesToValidate(\n projectDir: string,\n registered: SourceEntry[],\n): Promise<SourceEntry[]> {\n const local = registered.filter((source) => isLocalSource(source.url));\n const alreadyCovered = local.some((source) => isCwdMarketplace(projectDir, source));\n\n if (alreadyCovered || !(await isSourceRepo(projectDir))) return local;\n\n return [...local, { name: CWD_SOURCE_NAME, url: projectDir }];\n}\n\n/** Whether this marketplace IS the directory the command ran in, however the config spells it. */\nfunction isCwdMarketplace(projectDir: string, source: SourceEntry): boolean {\n return path.resolve(projectDir, source.url) === projectDir;\n}\n\n/** The one place knowing the cwd and each marketplace path; the cwd entry answers `\"author\"`. */\nfunction readerFor(projectDir: string, source: SourceEntry): MarketplaceReader {\n return isCwdMarketplace(projectDir, source) ? \"author\" : \"consumer\";\n}\n\ntype SourceOutcome = { note: string; issues: ContentIssue[] };\n\nasync function validateOneSource(\n source: SourceEntry,\n reader: MarketplaceReader,\n): Promise<SourceOutcome> {\n const label = `${source.name} (${source.url})`;\n try {\n const result = await validateSource(source.url, reader);\n return { note: `${label} — ${plural(result.skillCount, \"skill\")}`, issues: result.issues };\n } catch (error) {\n return {\n note: `${label} — failed`,\n issues: [{ severity: \"error\", file: source.url, message: getErrorMessage(error) }],\n };\n }\n}\n\nexport async function validateInstalledPlugins(projectDir: string): Promise<ContentValidation> {\n const dirs = [\n getUserPluginsDir(),\n ...(isHomeDirectory(projectDir) ? [] : [getProjectPluginsDir(projectDir)]),\n ];\n return mergeValidations(await Promise.all(dirs.map(validatePluginsDirectory)));\n}\n\nasync function validatePluginsDirectory(pluginsDir: string): Promise<ContentValidation> {\n if (!(await directoryExists(pluginsDir))) return NOTHING_VALIDATED;\n\n if (await fileExists(getInstalledPluginsRegistryPath(pluginsDir))) {\n const registryValidation = await validateRegistryPlugins(pluginsDir);\n if (registryValidation !== undefined) return registryValidation;\n }\n\n const pluginDirs = await listPluginDirNames(pluginsDir);\n if (pluginDirs.length === 0) return NOTHING_VALIDATED;\n\n const { results } = await validateAllPlugins(pluginsDir);\n\n return {\n count: results.length,\n issues: results.flatMap(({ name, result }) => toIssues(name, result)),\n notes: [],\n };\n}\n\n/** Undefined when the registry records no installs; the caller then scans direct children. */\nasync function validateRegistryPlugins(pluginsDir: string): Promise<ContentValidation | undefined> {\n let installs: ResolvedPlugin[];\n try {\n installs = await listRegisteredPluginInstalls(pluginsDir);\n } catch (error) {\n return {\n count: 0,\n issues: [\n {\n severity: \"error\",\n file: displayDir(getInstalledPluginsRegistryPath(pluginsDir)),\n message: getErrorMessage(error),\n },\n ],\n notes: [],\n };\n }\n\n if (installs.length === 0) return undefined;\n\n // A vanished installPath fails validatePlugin's structure check rather than crashing.\n const results = await Promise.all(\n installs.map(async ({ pluginKey, installPath }) =>\n toIssues(pluginKey, await validatePlugin(installPath)),\n ),\n );\n\n return { count: installs.length, issues: results.flat(), notes: [] };\n}\n\n/**\n * Only skills this installation owns, since `~/.claude/skills/` is shared: a directory is ours when\n * a config in play names its id or it carries `forkedFrom`. Any other is named, not judged.\n */\nexport async function validateInstalledSkills(projectDir: string): Promise<ContentValidation> {\n const configuredIds = await configuredSkillIds(projectDir);\n return mergeValidations(\n await Promise.all(\n installedDirs(projectDir, \"skillsDir\").map((dir) =>\n validateSkillsDirectory(dir, configuredIds),\n ),\n ),\n );\n}\n\n/** Every skill id the configs this run reads name, across both scopes and both install modes. */\nasync function configuredSkillIds(projectDir: string): Promise<ReadonlySet<string>> {\n const loaded = await Promise.all(\n configDirsInPlay(projectDir).map((dir) => loadInstalledConfig(dir)),\n );\n return new Set(loaded.flatMap(configuredIdsOf));\n}\n\nfunction configuredIdsOf(loaded: LoadedProjectConfig | null): string[] {\n if (!loaded) return [];\n return loaded.config.skills.map((skill) => skill.id);\n}\n\nexport async function validateInstalledAgents(projectDir: string): Promise<ContentValidation> {\n return mergeValidations(\n await Promise.all(installedDirs(projectDir, \"agentsDir\").map(validateAgentsDirectory)),\n );\n}\n\n/** At the home directory both scopes resolve to one place, walked once. */\nfunction installedDirs(projectDir: string, key: \"skillsDir\" | \"agentsDir\"): string[] {\n const global = resolveInstallPaths(projectDir, \"global\")[key];\n if (isHomeDirectory(projectDir)) return [global];\n return [global, resolveInstallPaths(projectDir, \"project\")[key]];\n}\n\n/** Skill folders this CLI provably wrote, as `uninstall` takes them, as display paths. */\nexport async function skillDirsWithOurProvenanceIn(skillsDir: string): Promise<string[]> {\n return listDisplayPaths(skillsDir, listSkillDirsWithOurProvenance);\n}\n\n/** Compiled agent files this CLI provably wrote, as `uninstall` takes them, as display paths. */\nexport async function agentFilesWithOurProvenanceIn(\n agentsDir: string,\n codec: AgentCodec,\n): Promise<string[]> {\n return listDisplayPaths(agentsDir, (dir) => listAgentFilesWithOurProvenance(dir, codec));\n}\n\n/**\n * Asks `splitAgentsByProvenance`, as `uninstall` does, so this lists exactly what it would remove.\n */\nasync function listAgentFilesWithOurProvenance(\n agentsDir: string,\n codec: AgentCodec,\n): Promise<string[]> {\n const { marked } = await splitAgentsByProvenance(agentsDir, codec);\n return marked.map((name) => `${name}${codec.extension}`);\n}\n\n/** By `forkedFrom` alone, as `uninstall` reads it; unreadable metadata carries none. */\nasync function listSkillDirsWithOurProvenance(skillsDir: string): Promise<string[]> {\n const [ours] = await partitionByVerdict(await listDirectories(skillsDir), (name) =>\n carriesOurProvenance(skillsDir, name),\n );\n return ours;\n}\n\nasync function partitionByVerdict(\n names: string[],\n verdict: (name: string) => Promise<boolean>,\n): Promise<[string[], string[]]> {\n const verdicts = await Promise.all(names.map(verdict));\n return partition(names, (_, index) => verdicts[index] === true);\n}\n\nasync function listDisplayPaths(\n dir: string,\n listEntries: (dir: string) => Promise<string[]>,\n): Promise<string[]> {\n if (!(await directoryExists(dir))) return [];\n const entries = await listEntries(dir);\n return entries.map((entry) => displayDir(path.join(dir, entry)));\n}\n\nasync function validateSkillsDirectory(\n skillsDir: string,\n configuredIds: ReadonlySet<string>,\n): Promise<ContentValidation> {\n if (!(await directoryExists(skillsDir))) return NOTHING_VALIDATED;\n\n const skillDirs = await listDirectories(skillsDir);\n if (skillDirs.length === 0) return NOTHING_VALIDATED;\n\n const [ours, foreign] = await partitionByVerdict(skillDirs, (name) =>\n isOurSkillDirectory(skillsDir, name, configuredIds),\n );\n\n const results = await Promise.all(\n ours.map(async (name) => {\n const skillDir = path.join(skillsDir, name);\n return toIssues(displayDir(skillDir), await validateInstalledSkill(skillDir));\n }),\n );\n\n return {\n count: ours.length,\n issues: results.flat(),\n notes: foreign.map((name) => foreignSkillNote(skillsDir, name)),\n };\n}\n\n/** Either claim this installation has on a skill directory. */\nasync function isOurSkillDirectory(\n skillsDir: string,\n name: string,\n configuredIds: ReadonlySet<string>,\n): Promise<boolean> {\n if (configuredIds.has(name)) return true;\n return carriesOurProvenance(skillsDir, name);\n}\n\n/** The `forkedFrom` block the copier stamps; `uninstall` asks exactly this. */\nasync function carriesOurProvenance(skillsDir: string, name: string): Promise<boolean> {\n return (await readForkedFromMetadata(path.join(skillsDir, name))) !== null;\n}\n\n/** Named so the count and the listing do not silently disagree; not a warning. */\nfunction foreignSkillNote(skillsDir: string, name: string): string {\n return `${displayDir(path.join(skillsDir, name))} — not installed by this CLI and named by no configuration here: not validated`;\n}\n\nasync function validateAgentsDirectory(agentsDir: string): Promise<ContentValidation> {\n if (!(await directoryExists(agentsDir))) return NOTHING_VALIDATED;\n\n const agentFiles = await listAgentMdFiles(agentsDir);\n if (agentFiles.length === 0) return NOTHING_VALIDATED;\n\n const results = await Promise.all(\n agentFiles.map(async (fileName) => {\n const agentPath = path.join(agentsDir, fileName);\n return toIssues(displayDir(agentPath), await validateAgentFrontmatter(agentPath));\n }),\n );\n\n return { count: agentFiles.length, issues: results.flat(), notes: [] };\n}\n\nasync function validateInstalledSkill(skillDir: string): Promise<ValidationResult> {\n const [skillMd, metadata] = await Promise.all([\n validateSkillFile(skillDir, STANDARD_FILES.SKILL_MD, validateSkillFrontmatter),\n validateSkillFile(skillDir, STANDARD_FILES.METADATA_YAML, validateInstalledSkillMetadata),\n ]);\n\n return mergeValidationResults([skillMd, metadata]);\n}\n\n/** One of an installed skill's files judged by `validate`, or the error of its absence. */\nasync function validateSkillFile(\n skillDir: string,\n fileName: string,\n validate: (filePath: string) => Promise<ValidationResult>,\n): Promise<ValidationResult> {\n const filePath = path.join(skillDir, fileName);\n if (!(await fileExists(filePath))) return invalidResult(`Missing ${fileName}`);\n return validate(filePath);\n}\n\nasync function validateInstalledSkillMetadata(metadataPath: string): Promise<ValidationResult> {\n // The same verdict compile and discovery use; the strict published-skill checks layer on top.\n const read = await readSkillMetadata(metadataPath);\n if (!read.usable) {\n return invalidResult(`${STANDARD_FILES.METADATA_YAML}: ${read.reason}`);\n }\n\n const metadata = read.metadata;\n const result = validateSkillMetadata(metadata);\n if (result.success) {\n return validResult();\n }\n\n const { errors, warnings } = splitMetadataValidationIssues(result.error, metadata);\n return {\n valid: errors.length === 0,\n errors: errors.map((e) => `${STANDARD_FILES.METADATA_YAML}: ${e}`),\n warnings: warnings.map((w) => `${STANDARD_FILES.METADATA_YAML}: ${w}`),\n };\n}\n","import path from \"path\";\nimport { isRecord } from \"../utils/type-guards.js\";\nimport { parse as parseYaml } from \"yaml\";\nimport { z } from \"zod\";\nimport { glob, readFile, fileExists, directoryExists } from \"../utils/fs\";\nimport {\n DIRS,\n MARKETPLACE_JSON,\n PLUGIN_MANIFEST_DIR,\n SKILL_CATEGORIES_PATH,\n SKILL_RULES_PATH,\n SKILLS_DIR_PATH,\n STACKS_FILE_PATH,\n STANDARD_FILES,\n} from \"../consts\";\nimport {\n agentYamlGenerationSchema,\n metadataValidationSchema,\n splitMetadataValidationIssues,\n validateSkillMetadata,\n skillCategoriesFileSchema,\n skillRulesFileSchema,\n stackConfigValidationSchema,\n stacksConfigSchema,\n} from \"./schemas\";\nimport { parseFrontmatter } from \"./loading/loader\";\nimport { ConfigDefaultExportError, loadConfig, loadSourceRepoConfig } from \"./configuration\";\nimport type { MatrixHealthIssue } from \"./matrix\";\nimport { matrixHealthIssues } from \"./matrix/matrix-health-check\";\nimport {\n loadSkillsMatrixFromSource,\n MarketplaceManifestRequiredError,\n} from \"./loading/source-loader\";\nimport { MarketplaceNameRefusedError } from \"./loading/source-fetcher\";\nimport { matrix } from \"./matrix/matrix-provider\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport { formatZodErrors } from \"./schema-validator\";\n\ntype SourceValidationIssue = {\n severity: \"error\" | \"warning\";\n file: string;\n message: string;\n};\n\nexport type SourceValidationResult = {\n issues: SourceValidationIssue[];\n skillCount: number;\n errorCount: number;\n warningCount: number;\n};\n\n/**\n * `\"author\"` when the marketplace IS the directory the command ran in, else `\"consumer\"`. It\n * changes one finding: a dangling rule slug is the author's to fix and a consumer's to ignore.\n */\nexport type MarketplaceReader = \"author\" | \"consumer\";\n\n/** True when `dir` carries a skills tree, at `src/skills/` or where its source config points. */\nexport async function isSourceRepo(dir: string): Promise<boolean> {\n // Aborts on an unreadable config; `doctor` catches it via `safeCheck`.\n const sourceConfig = await loadSourceRepoConfig(dir);\n return directoryExists(path.join(dir, sourceConfig?.skillsDir ?? SKILLS_DIR_PATH));\n}\n\nfunction isSnakeCase(key: string): boolean {\n return /[a-z]_[a-z]/.test(key);\n}\n\nfunction checkSnakeCaseKeys(rawMetadata: unknown, relPath: string): SourceValidationIssue[] {\n if (!isRecord(rawMetadata)) return [];\n\n return Object.keys(rawMetadata)\n .filter(isSnakeCase)\n .map((key) => ({\n severity: \"error\" as const,\n file: relPath,\n message: `Key '${key}' uses snake_case — use camelCase instead`,\n }));\n}\n\n/** A warning, not an error: the loader still registers the skill by its id. */\nfunction checkDirNameMatchesSkillId(\n skillId: string,\n relPath: string,\n dirName: string,\n): SourceValidationIssue[] {\n if (skillId === dirName) return [];\n return [\n {\n severity: \"warning\",\n file: relPath,\n message: `Directory name '${dirName}' does not match skill id '${skillId}'`,\n },\n ];\n}\n\nasync function checkSkillDirName(\n skillsDir: string,\n skillsDirRelPath: string,\n skillDir: string,\n): Promise<SourceValidationIssue[]> {\n const dirName = path.basename(skillDir);\n const skillMdRelPath = path.join(skillsDirRelPath, skillDir, STANDARD_FILES.SKILL_MD);\n\n try {\n const content = await readFile(path.join(skillsDir, skillDir, STANDARD_FILES.SKILL_MD));\n const frontmatter = parseFrontmatter(content, skillMdRelPath);\n\n if (frontmatter === null) {\n return [\n {\n severity: \"warning\",\n file: skillMdRelPath,\n message: `Cannot verify directory name '${dirName}': missing or invalid ${STANDARD_FILES.SKILL_MD} frontmatter`,\n },\n ];\n }\n\n return checkDirNameMatchesSkillId(frontmatter.name, skillMdRelPath, dirName);\n } catch (error) {\n return [\n {\n severity: \"warning\",\n file: skillMdRelPath,\n message: `Cannot verify directory name '${dirName}': ${getErrorMessage(error)}`,\n },\n ];\n }\n}\n\nfunction validateSkillFilePairs(\n skillMdDirs: Set<string>,\n metadataDirs: Set<string>,\n skillsDir: string,\n): SourceValidationIssue[] {\n const missingMetadata = [...skillMdDirs]\n .filter((dir) => !metadataDirs.has(dir))\n .map((dir) => ({\n severity: \"error\" as const,\n file: path.join(skillsDir, dir),\n message: `Missing ${STANDARD_FILES.METADATA_YAML} — skill directory has ${STANDARD_FILES.SKILL_MD} but no metadata`,\n }));\n\n const missingSkillMd = [...metadataDirs]\n .filter((dir) => !skillMdDirs.has(dir))\n .map((dir) => ({\n severity: \"error\" as const,\n file: path.join(skillsDir, dir),\n message: `Missing ${STANDARD_FILES.SKILL_MD} — skill directory has ${STANDARD_FILES.METADATA_YAML} but no SKILL.md`,\n }));\n\n return [...missingMetadata, ...missingSkillMd];\n}\n\n/** `reader` sets how loud findings are; default `\"author\"`, as under-reporting is worse. */\nexport async function validateSource(\n sourcePath: string,\n reader: MarketplaceReader = \"author\",\n): Promise<SourceValidationResult> {\n const resolvedPath = path.isAbsolute(sourcePath) ? sourcePath : path.resolve(sourcePath);\n\n if (!(await directoryExists(resolvedPath))) {\n return buildResult(\n [{ severity: \"error\", file: resolvedPath, message: \"Marketplace directory does not exist\" }],\n 0,\n );\n }\n\n // Aborts on an unreadable config; `validateOneSource` turns it into an issue.\n const sourceProjectConfig = await loadSourceRepoConfig(resolvedPath);\n const skillsDirRelPath = sourceProjectConfig?.skillsDir ?? SKILLS_DIR_PATH;\n const skillsDir = path.join(resolvedPath, skillsDirRelPath);\n\n if (!(await directoryExists(skillsDir))) {\n return buildResult(\n [{ severity: \"error\", file: skillsDir, message: \"Skills directory does not exist\" }],\n 0,\n );\n }\n\n const { pairIssues, validMetadataFiles } = await pairSkillFiles(skillsDir);\n const skillIssues = await validateSkillsInTurn(skillsDir, skillsDirRelPath, validMetadataFiles);\n\n const crossReferenceIssues = await checkCrossReferences(resolvedPath, reader);\n\n const extraIssues = await Promise.all([\n validateStacks(resolvedPath),\n validateAgents(resolvedPath),\n validateConfigFiles(resolvedPath),\n ]);\n\n return buildResult(\n [...pairIssues, ...skillIssues, ...crossReferenceIssues, ...extraIssues.flat()],\n validMetadataFiles.length,\n );\n}\n\n/** A half pair is reported here, so only complete pairs go on to be validated. */\nasync function pairSkillFiles(\n skillsDir: string,\n): Promise<{ pairIssues: SourceValidationIssue[]; validMetadataFiles: string[] }> {\n const skillMdFiles = await glob(`**/${STANDARD_FILES.SKILL_MD}`, skillsDir);\n const metadataFiles = await glob(`**/${STANDARD_FILES.METADATA_YAML}`, skillsDir);\n\n const skillMdDirs = new Set(skillMdFiles.map((f) => path.dirname(f)));\n const metadataDirs = new Set(metadataFiles.map((f) => path.dirname(f)));\n\n return {\n pairIssues: validateSkillFilePairs(skillMdDirs, metadataDirs, skillsDir),\n validMetadataFiles: metadataFiles.filter((f) => skillMdDirs.has(path.dirname(f))),\n };\n}\n\nasync function validateSkillsInTurn(\n skillsDir: string,\n skillsDirRelPath: string,\n metadataFiles: string[],\n): Promise<SourceValidationIssue[]> {\n const issues: SourceValidationIssue[] = [];\n for (const metadataFile of metadataFiles) {\n issues.push(...(await validateOneSkill(skillsDir, skillsDirRelPath, metadataFile)));\n }\n return issues;\n}\n\n/** Named once so both YAML-reading phases word the failure alike. */\nfunction yamlParseFailure(error: unknown): string {\n return `Failed to parse YAML: ${getErrorMessage(error)}`;\n}\n\n/** An unparseable file reports that and stops: every later check reads the parsed value. */\nasync function validateOneSkill(\n skillsDir: string,\n skillsDirRelPath: string,\n metadataFile: string,\n): Promise<SourceValidationIssue[]> {\n const relPath = path.join(skillsDirRelPath, metadataFile);\n\n let rawMetadata: unknown;\n try {\n rawMetadata = parseYaml(await readFile(path.join(skillsDir, metadataFile)));\n } catch (error) {\n return [{ severity: \"error\", file: relPath, message: yamlParseFailure(error) }];\n }\n\n return [\n ...checkSnakeCaseKeys(rawMetadata, relPath),\n ...checkMetadataSchema(rawMetadata, relPath),\n // Independent of metadata validity — the id lives in SKILL.md frontmatter\n ...(await checkSkillDirName(skillsDir, skillsDirRelPath, path.dirname(metadataFile))),\n ];\n}\n\nfunction checkMetadataSchema(rawMetadata: unknown, relPath: string): SourceValidationIssue[] {\n const result = validateSkillMetadata(rawMetadata);\n if (result.success) return [];\n\n const { errors, warnings } = splitMetadataValidationIssues(result.error, rawMetadata);\n return [\n ...errors.map((message) => ({ severity: \"error\" as const, file: relPath, message })),\n ...warnings.map((message) => ({ severity: \"warning\" as const, file: relPath, message })),\n ];\n}\n\n/** As a reader types it: the file `doctor` tells them to open. */\nconst MARKETPLACE_MANIFEST_PATH = path.join(PLUGIN_MANIFEST_DIR, MARKETPLACE_JSON);\n\n/** Keyed on the whole reader union, so a new reader does not compile until someone decides. */\nconst MANIFEST_REQUIRED_SEVERITY = {\n author: \"warning\",\n consumer: \"error\",\n} as const satisfies Record<MarketplaceReader, SourceValidationIssue[\"severity\"]>;\n\n/** Files the load's health findings without saying them again. */\nasync function checkCrossReferences(\n resolvedPath: string,\n reader: MarketplaceReader,\n): Promise<SourceValidationIssue[]> {\n try {\n await loadSkillsMatrixFromSource({ sourceFlag: resolvedPath, skipExtraSources: true });\n return matrixHealthIssues(matrix).map((healthIssue) =>\n toSourceIssue(healthIssue, resolvedPath, reader),\n );\n } catch (error) {\n return [matrixLoadFailure(error, reader)];\n }\n}\n\n/**\n * No valid manifest: the manifest's finding, at the reader's severity. A refused name: this\n * marketplace's error, since nothing installs. Anything else: a warning. Read off the throw's type.\n */\nfunction matrixLoadFailure(error: unknown, reader: MarketplaceReader): SourceValidationIssue {\n if (error instanceof MarketplaceManifestRequiredError) {\n return {\n severity: MANIFEST_REQUIRED_SEVERITY[reader],\n file: MARKETPLACE_MANIFEST_PATH,\n message: getErrorMessage(error),\n };\n }\n\n if (error instanceof MarketplaceNameRefusedError) {\n return {\n severity: \"error\",\n file: MARKETPLACE_MANIFEST_PATH,\n message: getErrorMessage(error),\n };\n }\n\n return {\n severity: \"warning\",\n file: SKILL_CATEGORIES_PATH,\n message: `Cross-reference validation skipped: failed to load categories/rules: ${getErrorMessage(error)}`,\n };\n}\n\n/** This CLI's own file: the marketplace holds no copy of the verdicts. */\nconst SKILL_AUDIT_PATH = \"src/cli/lib/configuration/skill-audit.ts\";\n\n/** The file the defect is in, as `doctor` shows it; exhaustive, so new kinds must choose. */\nfunction fileHoldingDefect(finding: MatrixHealthIssue[\"finding\"]): string {\n switch (finding) {\n case \"category-missing-domain\":\n case \"skill-unknown-category\":\n return SKILL_CATEGORIES_PATH;\n case \"skill-unresolved-relation-ref\":\n case \"rule-unresolved-slug\":\n return SKILL_RULES_PATH;\n case \"audit-verdict-contradiction\":\n case \"skill-unaudited\":\n return SKILL_AUDIT_PATH;\n default: {\n const exhaustive: never = finding;\n return exhaustive;\n }\n }\n}\n\n/** Only a marketplace's own dangling rule slug moves with the reader; the file never does. */\nfunction toSourceIssue(\n healthIssue: MatrixHealthIssue,\n marketplacePath: string,\n reader: MarketplaceReader,\n): SourceValidationIssue {\n const file = fileHoldingDefect(healthIssue.finding);\n\n if (reader === \"consumer\" && healthIssue.finding === \"rule-unresolved-slug\") {\n return {\n severity: \"warning\",\n file,\n message: consumedMarketplaceMessage(marketplacePath, healthIssue.details),\n };\n }\n\n return {\n severity: healthIssue.severity,\n file,\n message: healthIssue.details,\n };\n}\n\n/** Leads with the marketplace and says there is nothing here for the reader to fix. */\nfunction consumedMarketplaceMessage(marketplacePath: string, details: string): string {\n return `Marketplace '${marketplacePath}': ${details}. Nothing to fix here — the rule is that marketplace's, not this project's`;\n}\n\nasync function validateStacks(resolvedPath: string): Promise<SourceValidationIssue[]> {\n const stacksDir = path.join(resolvedPath, DIRS.stacks);\n if (!(await directoryExists(stacksDir))) return [];\n\n const [skillMetaIssues, configIssues] = await Promise.all([\n validateYamlFiles({\n baseDir: stacksDir,\n relBaseDir: DIRS.stacks,\n pattern: `**/skills/**/${STANDARD_FILES.METADATA_YAML}`,\n schema: metadataValidationSchema,\n }),\n validateYamlFiles({\n baseDir: stacksDir,\n relBaseDir: DIRS.stacks,\n pattern: `*/${STANDARD_FILES.CONFIG_YAML}`,\n schema: stackConfigValidationSchema,\n }),\n ]);\n return [...skillMetaIssues, ...configIssues];\n}\n\n/** Against compilation's input schema (compiling writes no YAML); skips a missing src/agents/. */\nasync function validateAgents(resolvedPath: string): Promise<SourceValidationIssue[]> {\n const agentsDir = path.join(resolvedPath, DIRS.agents);\n if (!(await directoryExists(agentsDir))) return [];\n\n return validateYamlFiles({\n baseDir: agentsDir,\n relBaseDir: DIRS.agents,\n pattern: `**/${STANDARD_FILES.AGENT_METADATA_YAML}`,\n schema: agentYamlGenerationSchema,\n });\n}\n\n/** Runtime-loads each config/*.ts and validates its default export; absent files are skipped. */\nasync function validateConfigFiles(resolvedPath: string): Promise<SourceValidationIssue[]> {\n const results = await Promise.all([\n validateTsConfig(resolvedPath, SKILL_CATEGORIES_PATH, skillCategoriesFileSchema),\n validateTsConfig(resolvedPath, SKILL_RULES_PATH, skillRulesFileSchema),\n validateTsConfig(resolvedPath, STACKS_FILE_PATH, stacksConfigSchema),\n ]);\n return results.flat();\n}\n\n/** One kind of YAML file a source may carry: where it lives, and the schema each must satisfy. */\ntype YamlFileScan = {\n baseDir: string;\n /** `baseDir` in the project-relative form issues report. */\n relBaseDir: string;\n pattern: string;\n schema: z.ZodType<unknown>;\n};\n\nasync function validateYamlFiles(scan: YamlFileScan): Promise<SourceValidationIssue[]> {\n const issues: SourceValidationIssue[] = [];\n const files = await glob(scan.pattern, scan.baseDir);\n\n for (const relFile of files) {\n issues.push(...(await validateYamlFile(scan, relFile)));\n }\n return issues;\n}\n\nasync function validateYamlFile(\n scan: YamlFileScan,\n relFile: string,\n): Promise<SourceValidationIssue[]> {\n const displayPath = path.join(scan.relBaseDir, relFile);\n\n let parsed: unknown;\n try {\n parsed = parseYaml(await readFile(path.join(scan.baseDir, relFile)));\n } catch (error) {\n return [{ severity: \"error\", file: displayPath, message: yamlParseFailure(error) }];\n }\n\n const result = scan.schema.safeParse(parsed);\n if (result.success) return [];\n\n return formatZodErrors(result.error).map((message) => ({\n severity: \"error\" as const,\n file: displayPath,\n message,\n }));\n}\n\n/** `null` (exported nothing) and named-only exports are reported apart, since the fixes differ. */\nasync function validateTsConfig(\n resolvedPath: string,\n relConfigPath: string,\n schema: z.ZodType<unknown>,\n): Promise<SourceValidationIssue[]> {\n const absPath = path.join(resolvedPath, relConfigPath);\n if (!(await fileExists(absPath))) return [];\n\n try {\n const loaded = await loadConfig(absPath, schema);\n if (loaded === null) {\n return [{ severity: \"error\", file: relConfigPath, message: \"Config is empty\" }];\n }\n return [];\n } catch (error) {\n if (error instanceof ConfigDefaultExportError) {\n return [{ severity: \"error\", file: relConfigPath, message: \"Config has no default export\" }];\n }\n return [\n { severity: \"error\", file: relConfigPath, message: formatLoadError(relConfigPath, error) },\n ];\n }\n}\n\n/** References the relative config path, not the absolute one loadConfig embeds. */\nfunction formatLoadError(relConfigPath: string, error: unknown): string {\n const raw = getErrorMessage(error);\n const stripped = raw.replace(/Failed to load config from '[^']+':\\s*/, \"\");\n return `Failed to load ${relConfigPath}: ${stripped}`;\n}\n\nfunction buildResult(issues: SourceValidationIssue[], skillCount: number): SourceValidationResult {\n const errorCount = issues.filter((i) => i.severity === \"error\").length;\n const warningCount = issues.filter((i) => i.severity === \"warning\").length;\n return { issues, skillCount, errorCount, warningCount };\n}\n"],"mappings":"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","names":["os","path","path","os","path","skillsDir","agentsDir","os","path","skillsDir","agentsDir","claimed","path","unique","os","matrix","path"]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/doctor.ts","../../src/cli/lib/doctor/installation-reads.ts","../../src/cli/lib/doctor/ownership.ts","../../src/cli/lib/content-validator.ts","../../src/cli/lib/source-validator.ts"],"sourcesContent":["import os from \"os\";\nimport path from \"path\";\nimport { BaseCommand } from \"../base-command\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport { EXIT_CODES } from \"../lib/exit-codes\";\nimport {\n effectivelyExcludedSkillIds,\n findConfigLoadFailures,\n MarketplaceRefusedError,\n validateProjectConfig,\n SOURCE_ENV_VAR,\n type ResolvedConfig,\n} from \"../lib/configuration\";\nimport { loadSkillsMatrixFromSource, type SourceLoadResult } from \"../lib/loading\";\nimport {\n askingEachMarketplaceItself,\n MarketplaceUnreachableError,\n} from \"../lib/loading/source-fetcher\";\nimport { matrix } from \"../lib/matrix/matrix-provider\";\nimport { getStackSkillIds } from \"../lib/stacks\";\nimport { filterExcludedEntries } from \"../lib/agents\";\nimport { isHomeDirectory, installBaseDir } from \"../lib/installation\";\nimport {\n agentCodec,\n agentsDir,\n hostCompilesAgent,\n relativeConfigPath,\n skillsDir,\n skillsPathPrefix,\n} from \"../lib/installation/install-layout\";\nimport { ambiguityFinding } from \"../lib/installation/provider-flag\";\nimport {\n sourceScopesInPlay,\n type ScopeKind,\n type SourceScope,\n} from \"../lib/installation/source-scopes\";\nimport {\n hostsOf,\n hostsOnDisk,\n installedPluginSkillIds,\n providersInPlay,\n resolveConfigState,\n unofferablePlacements,\n type CheckedInstallation,\n type ConfigState,\n} from \"../lib/doctor/installation-reads\";\nimport { judgeOwnership, type Ownership } from \"../lib/doctor/ownership\";\nimport {\n INFO_MESSAGES,\n layoutIsCurrent,\n providerArgument,\n recreateConfigFrom,\n scopeLabel,\n scopeNoun,\n} from \"../utils/messages\";\nimport { isSourceRepo } from \"../lib/source-validator\";\nimport {\n validateInstalledAgents,\n validateInstalledPlugins,\n validateInstalledSkills,\n validateProjectConfigFile,\n validateRegisteredSources,\n type ContentIssue,\n type ContentValidation,\n} from \"../lib/content-validator\";\nimport type {\n AgentName,\n AgentScopeConfig,\n MergedSkillsMatrix,\n ProjectConfig,\n SkillConfig,\n SkillId,\n SkillScope,\n} from \"../types\";\nimport { fileExists } from \"../utils/fs\";\nimport { plural } from \"../utils/string\";\nimport {\n CLI_INVOKE_COMMAND,\n DEFAULT_BRANDING,\n EJECT_SOURCE,\n STANDARD_FILES,\n UI_SYMBOLS,\n type Provider,\n} from \"../consts\";\nimport { countBy, unique } from \"remeda\";\n\ntype CheckKind =\n | \"config\"\n | \"config-empty\"\n | \"installations\"\n | \"source-repo\"\n | \"layout\"\n | \"placements\"\n | \"skills\"\n | \"agents\"\n | \"orphans\"\n | \"orphans-unowned\"\n | \"installed\"\n | \"plugins\"\n | \"source\"\n | \"content-config\"\n | \"content-sources\"\n | \"content-plugins\"\n | \"content-skills\"\n | \"content-agents\";\n\ntype CheckResult = {\n kind: CheckKind;\n status: \"pass\" | \"fail\" | \"warn\" | \"skip\";\n message: string;\n details?: string[];\n /** The installation a block's row is about, where the scope holds two. */\n provider?: Provider;\n};\n\ntype ConfigCheckOutput = {\n result: CheckResult;\n config: ProjectConfig | null;\n};\n\nfunction checkConfigValid(\n state: ConfigState,\n installation: CheckedInstallation,\n): ConfigCheckOutput {\n const theConfig = (verdict: string) => configRowMessage(state, installation, verdict);\n if (state.kind === \"absent\") {\n return {\n result: {\n kind: \"config\",\n status: \"fail\",\n message: theConfig(\"not found\"),\n details: [`Run '${CLI_INVOKE_COMMAND} init' to create a configuration`],\n },\n config: null,\n };\n }\n\n if (state.kind === \"unreadable\") {\n return {\n result: {\n kind: \"config\",\n status: \"fail\",\n message: theConfig(\"exists but could not be loaded\"),\n details: [state.failure.reason],\n },\n config: null,\n };\n }\n\n // Valid but empty: handed on so the rows below don't report \"config invalid\".\n if (state.kind === \"declares-nothing\") {\n return {\n result: {\n kind: \"config-empty\",\n status: \"warn\",\n message: theConfig(\"is valid but declares no skills and no agents\"),\n },\n config: state.config,\n };\n }\n\n const { config } = state;\n const validation = validateProjectConfig(config);\n\n if (!validation.valid) {\n return {\n result: {\n kind: \"config\",\n status: \"fail\",\n message: theConfig(\"has errors\"),\n details: validation.errors,\n },\n config: null,\n };\n }\n\n if (validation.warnings.length > 0) {\n return {\n result: {\n kind: \"config\",\n status: \"warn\",\n message: theConfig(\"has warnings\"),\n details: validation.warnings,\n },\n config,\n };\n }\n\n return {\n result: {\n kind: \"config\",\n status: \"pass\",\n message: theConfig(\"is valid\"),\n },\n config,\n };\n}\n\n/** Names the file actually read: the global config when this directory inherits it. */\nfunction configRowMessage(\n state: ConfigState,\n { projectDir, hosts }: CheckedInstallation,\n verdict: string,\n): string {\n if (state.kind === \"loaded\" && state.inherited)\n return `${theInheritedConfig(hosts.global)}, which ${verdict}`;\n if (state.kind === \"unreadable\") {\n const { scopeRoot, scope } = state.failure;\n return `${theConfigAt(scopeRoot, hosts[scope])} ${verdict}`;\n }\n return `${theConfigAt(projectDir, hosts.project)} ${verdict}`;\n}\n\nfunction theConfigAt(root: string, provider: Provider): string {\n return `${scopeLabel(scopeOf(root))}: ${configNamedFrom(root, provider)}`;\n}\n\nfunction theInheritedConfig(provider: Provider): string {\n return `${scopeLabel(\"project\")}: no ${STANDARD_FILES.CONFIG_TS}, using ${scopeNoun(\"global\")}'s (${configNamedFrom(os.homedir(), provider)})`;\n}\n\nfunction scopeOf(dir: string): ScopeKind {\n return isHomeDirectory(dir) ? \"global\" : \"project\";\n}\n\nfunction configNamedFrom(root: string, provider: Provider): string {\n const relPath = relativeConfigPath(root, provider);\n return isHomeDirectory(root) ? `~/${relPath}` : relPath;\n}\n\n/** The loader has already merged in every local skill it accepts, from both scopes. */\nfunction checkSkillsResolved(config: ProjectConfig, matrix: MergedSkillsMatrix): CheckResult {\n const uniqueSkills = skillIdsToResolve(config);\n\n if (uniqueSkills.length === 0) {\n return {\n kind: \"skills\",\n status: \"pass\",\n message: \"No skills configured\",\n };\n }\n\n const missingSkills = uniqueSkills.filter((skillId) => !(skillId in matrix.skills));\n\n if (missingSkills.length > 0) {\n return {\n kind: \"skills\",\n status: \"fail\",\n message: `${ratio(uniqueSkills.length - missingSkills.length, uniqueSkills.length, \"skill\")} found`,\n details: missingSkills.map((s) => `- ${s} (not found)`),\n };\n }\n\n return {\n kind: \"skills\",\n status: \"pass\",\n message: `${ratio(uniqueSkills.length, uniqueSkills.length, \"skill\")} found`,\n };\n}\n\n/** Both sources: a global-only install has skills but no stack. */\nfunction skillIdsToResolve(config: ProjectConfig): SkillId[] {\n const excludedIds = effectivelyExcludedSkillIds(config.skills);\n const stackIds = config.stack ? getStackSkillIds(config.stack) : [];\n return unique([...stackIds, ...config.skills.map((s) => s.id)]).filter(\n (id) => !excludedIds.has(id),\n );\n}\n\nasync function checkAgentsCompiled(\n config: ProjectConfig,\n installation: CheckedInstallation,\n): Promise<CheckResult> {\n if (config.agents.length === 0) {\n return {\n kind: \"agents\",\n status: \"pass\",\n message: \"No agents configured\",\n };\n }\n\n const agentChecks = await Promise.all(\n config.agents.map((agent) => agentCompileCheck(agent, installation)),\n );\n const unrenderable = agentChecks.filter((c) => c.state === \"unrenderable\");\n const missingAgents = agentChecks.filter((c) => c.state === \"missing\").map((c) => c.name);\n\n // A sub-agent the host leaves out by design is a pass, not a recompile warning.\n if (unrenderable.length === config.agents.length) {\n const hostsLeavingThemOut = unique(unrenderable.map((a) => a.provider)).join(\" or \");\n return {\n kind: \"agents\",\n status: \"pass\",\n message: `No sub-agent in this configuration is carried by ${hostsLeavingThemOut}`,\n details: unrenderable.map((a) => `- ${a.name} (left out of ${a.provider})`),\n };\n }\n\n if (missingAgents.length > 0) {\n return {\n kind: \"agents\",\n status: \"warn\",\n message: needRecompilation(missingAgents.length),\n details: missingAgents.map((a) => `- ${a} (missing)`),\n };\n }\n\n const renderable = config.agents.length - unrenderable.length;\n return {\n kind: \"agents\",\n status: \"pass\",\n message: `${ratio(renderable, renderable, \"agent\")} compiled`,\n };\n}\n\nfunction needRecompilation(count: number): string {\n return `${plural(count, \"agent\")} ${count === 1 ? \"needs\" : \"need\"} recompilation`;\n}\n\ntype AgentCompileCheck = {\n name: AgentName;\n provider: Provider;\n state: \"unrenderable\" | \"compiled\" | \"missing\";\n};\n\n/** Host read per scope: two scopes can be on two providers. */\nasync function agentCompileCheck(\n agent: AgentScopeConfig,\n { projectDir, hosts }: CheckedInstallation,\n): Promise<AgentCompileCheck> {\n const provider = hosts[agent.scope];\n if (!hostCompilesAgent(provider, agent.name)) {\n return { name: agent.name, provider, state: \"unrenderable\" };\n }\n\n const file = `${agent.name}${agentCodec(provider).extension}`;\n const compiled = await fileExists(path.join(agentsDir(provider, agent.scope, projectDir), file));\n return { name: agent.name, provider, state: compiled ? \"compiled\" : \"missing\" };\n}\n\nasync function checkNoOrphans(\n state: ConfigState,\n config: ProjectConfig | null,\n installation: CheckedInstallation,\n): Promise<CheckResult> {\n return ownershipResult(state, await judgeOwnership(state, config, installation));\n}\n\nfunction ownershipResult(\n state: ConfigState,\n { unowned, orphanedAgentFiles }: Ownership,\n): CheckResult {\n if (unowned.skills.length > 0 || unowned.agents.length > 0) {\n return {\n kind: \"orphans-unowned\",\n status: \"fail\",\n message: `${countedArtifacts(unowned.skills, unowned.agents)} installed here, and no configuration declares them`,\n details: [...unowned.skills, ...unowned.agents, ...orphanLines(orphanedAgentFiles)].map(\n (line) => `- ${line}`,\n ),\n };\n }\n\n if (orphanedAgentFiles.length > 0) {\n return {\n kind: \"orphans\",\n status: \"warn\",\n message: plural(orphanedAgentFiles.length, \"orphaned agent file\"),\n details: orphanLines(orphanedAgentFiles).map((line) => `- ${line}`),\n };\n }\n\n // With no configuration and nothing this CLI wrote, there is nothing to own: `init`'s state.\n if (state.kind === \"absent\") return skippedResult(\"orphans\");\n\n return { kind: \"orphans\", status: \"pass\", message: \"No orphaned agent files\" };\n}\n\nfunction orphanLines(fileNames: string[]): string[] {\n return fileNames.map((name) => `${name} (not in config)`);\n}\n\nfunction ratio(found: number, total: number, noun: string): string {\n return `${found}/${plural(total, noun)}`;\n}\n\nfunction countedArtifacts(skills: string[], agents: string[]): string {\n return nonZeroCounts([skills.length, \"skill\"], [agents.length, \"agent\"]);\n}\n\ntype Count = [count: number, noun: string];\n\n/** `2 skills and 1 agent`: a zero is left out rather than counted. */\nfunction nonZeroCounts(...counts: Count[]): string {\n return counts\n .filter(([count]) => count > 0)\n .map(([count, noun]) => plural(count, noun))\n .join(\" and \");\n}\n\n/** The directory is resolved per skill, since scope (and so host) varies within one config. */\nasync function checkSkillsInstalled(\n config: ProjectConfig,\n installation: CheckedInstallation,\n): Promise<CheckResult> {\n const ejectSkills = config.skills.filter((s) => s.origin === EJECT_SOURCE);\n\n if (ejectSkills.length === 0) {\n return {\n kind: \"installed\",\n status: \"pass\",\n message: \"No eject-mode skills configured\",\n };\n }\n\n const skillChecks = await Promise.all(\n ejectSkills.map((skill) => ejectedSkillCheck(skill, installation)),\n );\n const missingSkills = skillChecks.filter((c) => !c.installed);\n\n if (missingSkills.length > 0) {\n return {\n kind: \"installed\",\n status: \"warn\",\n message: `${plural(missingSkills.length, \"skill\")} missing from disk`,\n details: missingSkills.map((s) => `- ${s.id} (not found in ${s.lookedIn}/)`),\n };\n }\n\n return {\n kind: \"installed\",\n status: \"pass\",\n message: `${ratio(ejectSkills.length, ejectSkills.length, \"eject-mode skill\")} installed`,\n };\n}\n\ntype EjectedSkillCheck = { id: SkillId; installed: boolean; lookedIn: string };\n\nasync function ejectedSkillCheck(\n skill: SkillConfig,\n { projectDir, hosts }: CheckedInstallation,\n): Promise<EjectedSkillCheck> {\n const provider = hosts[skill.scope];\n const dir = skillsDir(provider, skill.scope, projectDir);\n const installed = await fileExists(path.join(dir, skill.id, STANDARD_FILES.SKILL_MD));\n\n return {\n id: skill.id,\n installed,\n lookedIn: skillsPathPrefix(provider, skill.scope, projectDir),\n };\n}\n\n/** Plugin-mode skills are checked against the plugin registry per scope, not on disk. */\nasync function checkPluginSkillsInstalled(\n config: ProjectConfig,\n installation: CheckedInstallation,\n): Promise<CheckResult> {\n const pluginSkills = config.skills.filter((s) => s.origin !== EJECT_SOURCE);\n\n if (pluginSkills.length === 0) {\n return {\n kind: \"plugins\",\n status: \"pass\",\n message: \"No plugin-mode skills configured\",\n };\n }\n\n const scopes = unique(pluginSkills.map((s) => s.scope));\n const missingPerScope = await Promise.all(\n scopes.map((scope) => pluginSkillsMissingAt(scope, pluginSkills, installation)),\n );\n const missingSkills = missingPerScope.flat();\n\n if (missingSkills.length > 0) {\n return {\n kind: \"plugins\",\n status: \"warn\",\n message: `${plural(missingSkills.length, \"skill\")} not installed as plugins`,\n details: missingSkills.map((s) => `- ${s} (no enabled plugin found)`),\n };\n }\n\n return {\n kind: \"plugins\",\n status: \"pass\",\n message: `${ratio(pluginSkills.length, pluginSkills.length, \"plugin-mode skill\")} installed`,\n };\n}\n\nasync function pluginSkillsMissingAt(\n scope: SkillScope,\n pluginSkills: SkillConfig[],\n { projectDir, hosts }: CheckedInstallation,\n): Promise<SkillId[]> {\n const installedIds = await installedPluginSkillIds(\n installBaseDir(projectDir, scope),\n hosts[scope],\n );\n return pluginSkills\n .filter((skill) => skill.scope === scope)\n .filter((skill) => !installedIds.has(skill.id))\n .map((skill) => skill.id);\n}\n\nconst MARKETPLACE_CHOSEN_BY = {\n flag: \"named by this run\",\n env: `named by ${SOURCE_ENV_VAR}`,\n project: \"named by this project's configuration\",\n global: \"named by the global configuration\",\n default: \"nothing here names one, so this is the default\",\n} as const satisfies Record<ResolvedConfig[\"sourceOrigin\"], string>;\n\nfunction howItWasReached(source: string, isLocal: boolean): string {\n return isLocal ? `Read ${source} from disk` : `Reached ${source} over the network`;\n}\n\n/** Counts the marketplace's own skills, not the loaded matrix, which also holds local ones. */\nfunction reachedMarketplace(\n result: SourceLoadResult,\n differingCopiesReplaced: ReadonlySet<string>,\n): CheckResult {\n const { source, sourceOrigin } = result.sourceConfig;\n return {\n kind: \"source\",\n status: \"pass\",\n message: `Connected to ${result.isLocal ? \"local\" : \"remote\"}: ${result.sourcePath}`,\n details: [\n `${plural(result.marketplaceSkillIds.size, \"skill\")} available`,\n `${howItWasReached(source, result.isLocal)} — ${MARKETPLACE_CHOSEN_BY[sourceOrigin]}`,\n ...savedCopyLines(source, differingCopiesReplaced),\n ],\n };\n}\n\n/** Said only when this run's download replaced a saved copy that differed from it. */\nfunction savedCopyLines(source: string, differingCopiesReplaced: ReadonlySet<string>): string[] {\n return differingCopiesReplaced.has(source) ? [INFO_MESSAGES.SAVED_COPY_REPLACED] : [];\n}\n\n/** Downloads the marketplace on every run, so no saved copy is ever read in its place. */\nasync function checkSourceReachable({\n projectDir,\n hosts,\n}: CheckedInstallation): Promise<CheckResult> {\n try {\n return await askingEachMarketplaceItself(async (differingCopiesReplaced) =>\n reachedMarketplace(\n await loadSkillsMatrixFromSource({ projectDir, provider: hosts.project }),\n differingCopiesReplaced,\n ),\n );\n } catch (error) {\n return marketplaceNotLoaded(error);\n }\n}\n\nconst NO_SAVED_COPY_READ =\n \"Doctor asks the marketplace itself, not the saved copy, which other commands still read offline\";\n\nfunction marketplaceNotLoaded(error: unknown): CheckResult {\n if (error instanceof MarketplaceUnreachableError) {\n return {\n kind: \"source\",\n status: \"fail\",\n message: `Could not reach ${error.source}`,\n details: [error.reason, NO_SAVED_COPY_READ],\n };\n }\n\n return {\n kind: \"source\",\n status: \"fail\",\n message: refusedOr(error, \"Failed to load marketplace\"),\n details: [getErrorMessage(error)],\n };\n}\n\ntype ContentCheck = {\n kind: CheckKind;\n name: string;\n noun: string;\n run: (projectDir: string) => Promise<ContentValidation>;\n};\n\n/** `blocks`: operational rows that would only restate this pass's errors, so stand down. */\ntype GatedContentCheck = ContentCheck & {\n readsConfig: boolean;\n blocks: readonly CheckKind[];\n};\n\n/** Validated first and alone: every other row would cascade from an unreadable config. */\nconst CONFIG_CHECK: ContentCheck = {\n kind: \"content-config\",\n name: \"Config\",\n noun: \"config\",\n run: validateProjectConfigFile,\n};\n\n/** Runs before the operational layer so rows with broken inputs can stand down. */\nconst CONTENT_CHECKS: GatedContentCheck[] = [\n {\n kind: \"content-sources\",\n name: \"Marketplaces\",\n noun: \"marketplace\",\n readsConfig: true,\n // A broken marketplace leaves skills out of the matrix ids resolve against.\n blocks: [\"skills\"],\n run: validateRegisteredSources,\n },\n {\n kind: \"content-plugins\",\n name: \"Plugins\",\n noun: \"plugin\",\n readsConfig: false,\n // An unparseable registry resolves as no installs at all.\n blocks: [\"plugins\"],\n run: validateInstalledPlugins,\n },\n {\n kind: \"content-skills\",\n name: \"Skills\",\n noun: \"skill\",\n // Only the config says which unmarked shared-skills directories are this installation's.\n readsConfig: true,\n // `extractLocalSkill` drops a skill with unusable metadata.\n blocks: [\"skills\"],\n run: validateInstalledSkills,\n },\n {\n kind: \"content-agents\",\n name: \"Agents\",\n noun: \"agent\",\n readsConfig: false,\n // No operational row reads agent file contents.\n blocks: [],\n run: validateInstalledAgents,\n },\n];\n\nfunction contentStatus(errors: number, warnings: number): CheckResult[\"status\"] {\n if (errors > 0) return \"fail\";\n if (warnings > 0) return \"warn\";\n return \"pass\";\n}\n\nfunction contentMessage(noun: string, count: number, errors: number, warnings: number): string {\n // A pass that walked nothing can still report an issue (e.g. an unreadable registry).\n if (errors === 0 && warnings === 0) {\n return count === 0 ? `No ${noun}s to validate` : `${plural(count, noun)} validated`;\n }\n return `${plural(count, noun)}: ${plural(errors, \"error\")}, ${plural(warnings, \"warning\")}`;\n}\n\nfunction formatContentIssue(issue: ContentIssue): string {\n const marker = issue.severity === \"error\" ? \"ERROR\" : \"WARN\";\n return `- [${marker}] ${issue.file}: ${issue.message}`;\n}\n\nfunction toContentResult(check: ContentCheck, validation: ContentValidation): CheckResult {\n const errors = validation.issues.filter((issue) => issue.severity === \"error\").length;\n const warnings = validation.issues.length - errors;\n\n return {\n kind: check.kind,\n status: contentStatus(errors, warnings),\n message: contentMessage(check.noun, validation.count, errors, warnings),\n details: [\n ...validation.notes.map((note) => `- ${note}`),\n ...validation.issues.map(formatContentIssue),\n ],\n };\n}\n\n/** Must clear the longest row name (\"Marketplace Repository\"). */\nconst CHECK_WIDTH = 24;\n\nconst SECTION_INDENT = \" \";\nconst ROW_INDENT = \" \";\n\nconst SECTION_CONTENT = \"Content checks\";\nconst SECTION_OPERATIONAL = \"Operational checks\";\nconst SKIP_NO_INSTALLATION = \"Skipped — no installation here (marketplace repository)\";\nconst SKIP_CONFIG_UNREADABLE = \"Skipped — the configuration that names them cannot be read\";\n\nconst SKIP_AFTER_CONFIG_ERROR = \"Skipped — fix the content errors above first\";\n\nfunction skipRestatingContent(nouns: string[]): string {\n return `Skipped — this row would only restate the ${nouns.join(\" and \")} errors above`;\n}\n\nfunction formatCheckName(name: string): string {\n return name.padEnd(CHECK_WIDTH);\n}\n\nfunction formatStatus(status: CheckResult[\"status\"]): string {\n switch (status) {\n case \"pass\":\n return UI_SYMBOLS.CHECK;\n case \"fail\":\n return UI_SYMBOLS.CROSS;\n case \"warn\":\n return UI_SYMBOLS.DISCOURAGED;\n case \"skip\":\n return UI_SYMBOLS.SKIPPED;\n default: {\n const _exhaustive: never = status;\n return _exhaustive;\n }\n }\n}\n\nconst DETAIL_INDENT = `${ROW_INDENT}${\" \".repeat(CHECK_WIDTH)} `;\n\nfunction formatCheckLine(name: string, result: CheckResult): string[] {\n const headerLine = `${ROW_INDENT}${formatCheckName(name)}${formatStatus(result.status)} ${result.message}`;\n const detailLines = (result.details ?? []).flatMap(indentedDetailLines);\n return [headerLine, ...detailLines];\n}\n\n/** A detail can be a multi-paragraph refusal, so every line is indented. */\nfunction indentedDetailLines(detail: string): string[] {\n return detail\n .split(\"\\n\")\n .filter((line) => line !== \"\")\n .map((line) => `${DETAIL_INDENT}${line}`);\n}\n\nfunction formatSummary(results: CheckResult[]): string {\n const counts = countBy(results, (r) => r.status);\n\n const parts = [\n `${counts.pass ?? 0} passed`,\n plural(counts.warn ?? 0, \"warning\"),\n plural(counts.fail ?? 0, \"error\"),\n ];\n\n return `${SECTION_INDENT}Summary: ${parts.join(\", \")}`;\n}\n\ntype Tip = {\n kind: CheckKind;\n status: CheckResult[\"status\"];\n /** Handed the installation the finding is about, which a command acting on it must be told. */\n line: (provider: Provider | undefined) => string;\n};\n\nconst TIPS: Tip[] = [\n {\n kind: \"agents\",\n status: \"warn\",\n line: (provider) =>\n ` Tip: Run '${commandActingOn(provider, \"compile\")}' to generate missing agent files`,\n },\n {\n kind: \"config\",\n status: \"fail\",\n line: () => ` Tip: Run '${CLI_INVOKE_COMMAND} init' to create or fix configuration`,\n },\n {\n kind: \"config-empty\",\n status: \"warn\",\n line: () =>\n ` Tip: Nothing is configured yet — run '${CLI_INVOKE_COMMAND} init' to choose skills and sub-agents`,\n },\n {\n kind: \"orphans-unowned\",\n status: \"fail\",\n line: (provider) =>\n ` Tip: Nothing declares the files above — '${commandActingOn(provider, \"init --from <id>\")}' writes a configuration that can own them again, or '${commandActingOn(provider, \"uninstall\")}' removes them, the compiled agents included: each file listed carries this CLI's own provenance, which is what that command reads when there is no configuration left`,\n },\n {\n kind: \"skills\",\n status: \"fail\",\n line: () => \" Tip: Check skill IDs in config match available skills\",\n },\n {\n kind: \"installed\",\n status: \"warn\",\n // No command named: `eject skills --force` copies every skill, and only at project scope.\n line: () => \" Tip: Re-eject the missing skills from the marketplace to restore their files\",\n },\n];\n\nfunction commandActingOn(provider: Provider | undefined, command: string): string {\n return `${CLI_INVOKE_COMMAND} ${command}${providerArgument(provider)}`;\n}\n\n/** Once per installation a finding names, and once only where the tip names none. */\nfunction formatTips(results: CheckResult[]): string[] {\n return unique(TIPS.flatMap((tip) => linesOf(tip, results)));\n}\n\nfunction linesOf(tip: Tip, results: CheckResult[]): string[] {\n return results\n .filter((result) => answers(tip, result))\n .map((result) => tip.line(result.provider));\n}\n\nfunction answers(tip: Tip, result: CheckResult): boolean {\n return result.kind === tip.kind && result.status === tip.status;\n}\n\n/** `init` refuses an unreadable config, so the remedy is recreating it, once per such config. */\nasync function recreateConfigTips(\n contentResults: CheckResult[],\n projectDir: string,\n): Promise<string[]> {\n if (!failedContentKinds(contentResults).has(CONFIG_CHECK.kind)) return [];\n\n const failures = await findConfigLoadFailures(projectDir).catch(() => []);\n return failures.map(\n (failure) =>\n ` Tip: There is no automatic repair — recreate the configuration by running ${recreateConfigFrom(failure)}`,\n );\n}\n\nconst INSTALLATIONS_ROW_NAME = \"Installations\";\n\n/** A pass, as two installations are no fault; its detail names the flag acting commands need. */\nasync function checkInstallationsInPlay(\n projectDir: string,\n providers: Provider[],\n): Promise<CheckResult> {\n const finding = await ambiguityFinding(projectDir);\n return {\n kind: \"installations\",\n status: \"pass\",\n message: `${providers.length} installations here, each checked below`,\n details: finding === null ? [] : [`- ${finding}`],\n };\n}\n\nfunction installationHeading(provider: Provider): string {\n return `${SECTION_INDENT}The ${provider} installation`;\n}\n\nconst SOURCE_REPO_ROW_NAME = \"Marketplace Repository\";\n\n/** A skip for a marketplace repository nothing is installed in, `null` for any other directory. */\nasync function uninstalledSourceRepo(projectDir: string): Promise<CheckResult | null> {\n // Aborts on the repository's own unreadable config, which `safeCheck` makes this row's finding.\n if (!(await isSourceRepo(projectDir))) return null;\n return { kind: \"source-repo\", status: \"skip\", message: SKIP_NO_INSTALLATION };\n}\n\nconst LAYOUT_ROW_NAME = \"Layout\";\n\n/** Each scope with this installation's source folder on disk, global first. */\nasync function checkLayout({ projectDir, hosts }: CheckedInstallation): Promise<CheckResult[]> {\n const scopes = await sourceScopesInPlay(projectDir, ({ kind }) => hosts[kind]);\n return scopes.map(toLayoutResult);\n}\n\nfunction toLayoutResult(scope: SourceScope): CheckResult {\n return {\n kind: \"layout\",\n status: \"pass\",\n message: layoutIsCurrent(scopeLabel(scope.kind), scope.relName),\n };\n}\n\nconst PLACEMENTS_ROW_NAME = \"Placements Offered\";\n\n/** Reports, as a row, the refusals other commands would stop on; never refuses itself. */\nasync function checkOfferedPlacements(installation: CheckedInstallation): Promise<CheckResult> {\n const findings = await unofferablePlacements(installation);\n\n if (findings.length === 0) {\n return { kind: \"placements\", status: \"pass\", message: \"Every configured skill is placeable\" };\n }\n\n return {\n kind: \"placements\",\n status: \"fail\",\n message: `${plural(findings.length, \"finding\")} would stop a command acting here`,\n details: findings.map((finding) => `- ${finding}`),\n };\n}\n\nfunction skippedResult(kind: CheckKind): CheckResult {\n return { kind, status: \"skip\", message: \"Skipped (config invalid)\" };\n}\n\nfunction sourceUnreachableSkillsResult(): CheckResult {\n return { kind: \"skills\", status: \"skip\", message: \"Skipped (marketplace unreachable)\" };\n}\n\nfunction skippedContentResult(kind: CheckKind): CheckResult {\n return { kind, status: \"skip\", message: SKIP_CONFIG_UNREADABLE };\n}\n\nfunction failedContentKinds(contentResults: CheckResult[]): ReadonlySet<CheckKind> {\n return new Set(contentResults.filter((r) => r.status === \"fail\").map((r) => r.kind));\n}\n\n/** `null` when no content pass this row reads through failed. */\nfunction contentBlockedResult(\n row: CheckKind,\n failedContent: ReadonlySet<CheckKind>,\n): CheckResult | null {\n const blockingNouns = CONTENT_CHECKS.filter((check) => failedContent.has(check.kind))\n .filter((check) => check.blocks.includes(row))\n .map((check) => check.noun);\n\n if (blockingNouns.length === 0) return null;\n\n return { kind: row, status: \"skip\", message: skipRestatingContent(blockingNouns) };\n}\n\nfunction runContentCheck(check: ContentCheck, projectDir: string): Promise<CheckResult> {\n return safeCheck(check.kind, async () => toContentResult(check, await check.run(projectDir)));\n}\n\nasync function runGatedContentCheck(\n check: GatedContentCheck,\n projectDir: string,\n configUnreadable: boolean,\n): Promise<CheckResult> {\n if (check.readsConfig && configUnreadable) return skippedContentResult(check.kind);\n return runContentCheck(check, projectDir);\n}\n\n/** One item after another, each step's results after the last's. */\nasync function flatMapInTurn<Item, Result>(\n items: readonly Item[],\n step: (item: Item) => Promise<Result[]>,\n): Promise<Result[]> {\n return items.reduce<Promise<Result[]>>(\n async (earlier, item) => [...(await earlier), ...(await step(item))],\n Promise.resolve([]),\n );\n}\n\n/** A throw becomes that row's `fail`, so one broken check can't abort the run. */\nasync function safeCheck<Result extends CheckResult | null>(\n kind: CheckKind,\n fn: () => Result | Promise<Result>,\n): Promise<Result | CheckResult> {\n try {\n return await fn();\n } catch (error) {\n return {\n kind,\n status: \"fail\",\n message: refusedOr(error, \"Check threw\"),\n details: [getErrorMessage(error)],\n };\n }\n}\n\n/** A marketplace the check refused is a finding about the config, not a fault in the check. */\nfunction refusedOr(error: unknown, otherwise: string): string {\n return error instanceof MarketplaceRefusedError ? \"Refused\" : otherwise;\n}\n\nexport default class Doctor extends BaseCommand {\n static summary = \"Diagnose common configuration issues\";\n\n static description = `Run diagnostic checks on your ${DEFAULT_BRANDING.NAME} configuration to identify issues with config validity, skill resolution, agent compilation, and marketplace connectivity.`;\n\n static examples = [\"<%= config.bin %> <%= command.id %>\"];\n\n static flags = {};\n\n async run(): Promise<void> {\n await this.parse(Doctor);\n const projectDir = process.cwd();\n\n // `verbose()` stays off: the loaders' trace would interleave with and restate the rows.\n this.printHeader(await this.resolveBrandingName(projectDir));\n const contentResults = await this.runContentChecks(projectDir);\n const operationalResults = await this.runOperationalChecks(projectDir, contentResults);\n const results = [...contentResults, ...operationalResults];\n\n this.printResults(results, await recreateConfigTips(contentResults, projectDir));\n\n if (results.some((r) => r.status === \"fail\")) {\n this.exit(EXIT_CODES.ERROR);\n }\n }\n\n private printHeader(brandingName: string): void {\n this.log(\"\");\n this.log(`${brandingName} Doctor`);\n this.log(\"\");\n this.log(`${SECTION_INDENT}Checking configuration health...`);\n this.log(\"\");\n }\n\n private async runContentChecks(projectDir: string): Promise<CheckResult[]> {\n this.log(`${SECTION_INDENT}${SECTION_CONTENT}`);\n\n const configResult = await runContentCheck(CONFIG_CHECK, projectDir);\n const configUnreadable = configResult.status === \"fail\";\n\n const rows = await Promise.all(\n CONTENT_CHECKS.map(async (check) => ({\n name: check.name,\n result: await runGatedContentCheck(check, projectDir, configUnreadable),\n })),\n );\n\n const allRows = [{ name: CONFIG_CHECK.name, result: configResult }, ...rows];\n\n for (const row of allRows) {\n this.logCheck(row.name, row.result);\n }\n\n return allRows.map((row) => row.result);\n }\n\n private async runOperationalChecks(\n projectDir: string,\n contentResults: CheckResult[],\n ): Promise<CheckResult[]> {\n this.log(\"\");\n this.log(`${SECTION_INDENT}${SECTION_OPERATIONAL}`);\n\n const failedContent = failedContentKinds(contentResults);\n if (failedContent.has(CONFIG_CHECK.kind)) {\n this.log(`${ROW_INDENT}${SKIP_AFTER_CONFIG_ERROR}`);\n return [];\n }\n\n const providers = await providersInPlay(projectDir);\n if (providers.length > 1) {\n return this.checkEachInstallation(projectDir, providers, failedContent);\n }\n return this.checkTheInstallation(projectDir, failedContent);\n }\n\n private async checkTheInstallation(\n projectDir: string,\n failedContent: ReadonlySet<CheckKind>,\n ): Promise<CheckResult[]> {\n const installation = { projectDir, hosts: await hostsOnDisk(projectDir) };\n const configState = await resolveConfigState(installation);\n\n if (configState.kind === \"absent\") {\n const sourceRepo = await safeCheck(\"source-repo\", () => uninstalledSourceRepo(projectDir));\n if (sourceRepo !== null) return this.reportSourceRepo(sourceRepo);\n }\n\n return this.runAllChecks(installation, configState, failedContent);\n }\n\n /** A repository nothing is installed in skips the layer; one whose own config breaks is a row. */\n private reportSourceRepo(sourceRepo: CheckResult): CheckResult[] {\n if (sourceRepo.status === \"skip\") {\n this.log(`${ROW_INDENT}${sourceRepo.message}`);\n return [];\n }\n\n this.logCheck(SOURCE_REPO_ROW_NAME, sourceRepo);\n return [sourceRepo];\n }\n\n /** In turn rather than at once: each block prints as it runs, and each load seats the matrix. */\n private async checkEachInstallation(\n projectDir: string,\n providers: Provider[],\n failedContent: ReadonlySet<CheckKind>,\n ): Promise<CheckResult[]> {\n const installations = await safeCheck(\"installations\", () =>\n checkInstallationsInPlay(projectDir, providers),\n );\n this.logCheck(INSTALLATIONS_ROW_NAME, installations);\n\n const blocks = await flatMapInTurn(providers, (provider) =>\n this.checkOneOf(projectDir, provider, failedContent),\n );\n return [installations, ...blocks];\n }\n\n private async checkOneOf(\n projectDir: string,\n provider: Provider,\n failedContent: ReadonlySet<CheckKind>,\n ): Promise<CheckResult[]> {\n this.log(\"\");\n this.log(installationHeading(provider));\n\n const installation = { projectDir, hosts: hostsOf(provider) };\n const results = await this.runAllChecks(\n installation,\n await resolveConfigState(installation),\n failedContent,\n );\n return results.map((result) => ({ ...result, provider }));\n }\n\n private async runAllChecks(\n installation: CheckedInstallation,\n configState: ConfigState,\n failedContent: ReadonlySet<CheckKind>,\n ): Promise<CheckResult[]> {\n const { result: configResult, config } = checkConfigValid(configState, installation);\n this.logCheck(\"Config Valid\", configResult);\n\n const layoutResults = await this.reportLayout(installation);\n\n const placementsResult = await safeCheck(\"placements\", () =>\n checkOfferedPlacements(installation),\n );\n this.logCheck(PLACEMENTS_ROW_NAME, placementsResult);\n\n // Populates the matrix that the skills check reads, so it runs first.\n const sourceResult = await safeCheck(\"source\", () => checkSourceReachable(installation));\n\n const filteredConfig = config ? filterExcludedEntries(config) : null;\n\n const skillsResult = await this.resolveSkillsCheck(config, sourceResult, failedContent);\n this.logCheck(\"Skills Resolved\", skillsResult);\n\n const agentsResult = await this.resolveAgentsCheck(filteredConfig, installation);\n this.logCheck(\"Agents Compiled\", agentsResult);\n\n const orphansResult = await this.resolveOrphansCheck(config, configState, installation);\n this.logCheck(\"No Orphans\", orphansResult);\n\n const installedResult = await this.resolveInstalledCheck(filteredConfig, installation);\n this.logCheck(\"Skills Installed\", installedResult);\n\n const pluginsResult = await this.resolvePluginsCheck(\n filteredConfig,\n installation,\n failedContent,\n );\n this.logCheck(\"Plugins Installed\", pluginsResult);\n\n this.logCheck(\"Marketplace Reachable\", sourceResult);\n\n return [\n configResult,\n ...layoutResults,\n placementsResult,\n skillsResult,\n agentsResult,\n orphansResult,\n installedResult,\n pluginsResult,\n sourceResult,\n ];\n }\n\n private async reportLayout(installation: CheckedInstallation): Promise<CheckResult[]> {\n const rows = await checkLayout(installation);\n\n for (const row of rows) {\n this.logCheck(LAYOUT_ROW_NAME, row);\n }\n return rows;\n }\n\n /** Skips on a config the checks rejected: ownership can't be judged from a rejected file. */\n private async resolveOrphansCheck(\n config: ProjectConfig | null,\n configState: ConfigState,\n installation: CheckedInstallation,\n ): Promise<CheckResult> {\n if (!config && configState.kind !== \"absent\") return skippedResult(\"orphans\");\n return safeCheck(\"orphans\", () => checkNoOrphans(configState, config, installation));\n }\n\n private async resolveSkillsCheck(\n config: ProjectConfig | null,\n sourceResult: CheckResult,\n failedContent: ReadonlySet<CheckKind>,\n ): Promise<CheckResult> {\n if (!config) return skippedResult(\"skills\");\n\n const blocked = contentBlockedResult(\"skills\", failedContent);\n if (blocked) return blocked;\n if (sourceResult.status === \"fail\") return sourceUnreachableSkillsResult();\n\n return safeCheck(\"skills\", () => checkSkillsResolved(config, matrix));\n }\n\n private async resolveAgentsCheck(\n config: ProjectConfig | null,\n installation: CheckedInstallation,\n ): Promise<CheckResult> {\n if (!config) return skippedResult(\"agents\");\n return safeCheck(\"agents\", () => checkAgentsCompiled(config, installation));\n }\n\n private async resolveInstalledCheck(\n config: ProjectConfig | null,\n installation: CheckedInstallation,\n ): Promise<CheckResult> {\n if (!config) return skippedResult(\"installed\");\n return safeCheck(\"installed\", () => checkSkillsInstalled(config, installation));\n }\n\n private async resolvePluginsCheck(\n config: ProjectConfig | null,\n installation: CheckedInstallation,\n failedContent: ReadonlySet<CheckKind>,\n ): Promise<CheckResult> {\n if (!config) return skippedResult(\"plugins\");\n\n const blocked = contentBlockedResult(\"plugins\", failedContent);\n if (blocked) return blocked;\n\n return safeCheck(\"plugins\", () => checkPluginSkillsInstalled(config, installation));\n }\n\n private logCheck(name: string, result: CheckResult): void {\n for (const line of formatCheckLine(name, result)) {\n this.log(line);\n }\n }\n\n private printResults(results: CheckResult[], recreateTips: string[]): void {\n this.log(\"\");\n this.log(formatSummary(results));\n\n const tips = [...formatTips(results), ...recreateTips];\n if (tips.length > 0) {\n this.log(\"\");\n for (const tip of tips) {\n this.log(tip);\n }\n }\n\n this.log(\"\");\n }\n}\n","/**\n * `doctor`'s reads of one installation, each asked of a named provider rather than the one\n * `providerInUse` picks, so one run can report on both installations a scope holds. Two re-express\n * helpers that read the provider only through process state — `getVerifiedPluginInstallPaths` and\n * `unofferablePlacementsFound` — and answer as they do when the hosts are read off the disk.\n */\n\nimport os from \"os\";\n\nimport { ConfigLoadError, loadProjectConfigFromDir } from \"../configuration/project-config.js\";\nimport { scopeRootsInPlay } from \"../installation/source-scopes.js\";\nimport { declaresNoContent } from \"../installation/installation.js\";\nimport {\n detectInstallations,\n type DetectedInstallation,\n} from \"../installation/detect-installations.js\";\nimport { isHomeDirectory } from \"../installation/is-home-directory.js\";\nimport { providerInUse } from \"../installation/install-layout.js\";\nimport { hostFor } from \"../hosts/host-for.js\";\nimport type { HostPlugin } from \"../hosts/plugin-host.js\";\nimport { refuseUnofferedPlacements } from \"../hosts/offered-placements.js\";\nimport { getPluginManifestPath } from \"../plugins/plugin-finder.js\";\nimport { parseMarketplacePluginRef } from \"../plugins/plugin-ref.js\";\nimport { getErrorMessage } from \"../../utils/errors.js\";\nimport { fileExists } from \"../../utils/fs.js\";\nimport { verbose } from \"../../utils/logger.js\";\nimport type { Provider } from \"../../consts.js\";\nimport type { ProjectConfig, SkillConfig, SkillScope } from \"../../types/index.js\";\n\n/**\n * The provider each scope's paths are read with: off the disk, as a run naming no provider reads\n * them, or one installation's for both, as a run naming `--provider` does. Never set as the run's\n * provider, so one doctor run can ask of each installation in turn.\n */\nexport type Hosts = Record<SkillScope, Provider>;\n\n/** One installation's rows: the directory they are about and the hosts its paths resolve with. */\nexport type CheckedInstallation = { projectDir: string; hosts: Hosts };\n\n/**\n * Each scope's provider off its own folder. A project holding no installation is checked as the\n * global one it inherits, whose provider it takes: its own folder would answer a new one's.\n */\nexport async function hostsOnDisk(projectDir: string): Promise<Hosts> {\n const found = await detectInstallations(projectDir);\n if (inheritsTheGlobalInstallation(found)) return hostsOf(providerInUse(os.homedir()));\n\n const project = providerInUse(projectDir);\n return { project, global: globalBeside(project, found) };\n}\n\nfunction inheritsTheGlobalInstallation(found: readonly DetectedInstallation[]): boolean {\n return found.length > 0 && found.every((installation) => installation.scope === \"global\");\n}\n\n/**\n * A project inherits only its own provider's global, which a home holding both would otherwise\n * answer by roster order.\n */\nfunction globalBeside(project: Provider, found: readonly DetectedInstallation[]): Provider {\n const inherited = found.some(\n (installation) => installation.scope === \"global\" && installation.provider === project,\n );\n return inherited ? project : providerInUse(os.homedir());\n}\n\nexport function hostsOf(provider: Provider): Hosts {\n return { project: provider, global: provider };\n}\n\n/** The project's installations, or the global ones where the project holds none. */\nexport async function providersInPlay(projectDir: string): Promise<Provider[]> {\n const found = await detectInstallations(projectDir);\n const inTheProject = found.filter((installation) => installation.scope === \"project\");\n const inPlay = inTheProject.length > 0 ? inTheProject : found;\n return inPlay.map((installation) => installation.provider);\n}\n\n/**\n * Unreadable only where a scope holds two installations: the content layer reads the configs in\n * use, so a broken one of those has already stood the operational layer down.\n */\nexport type ConfigState =\n | { kind: \"absent\" }\n | { kind: \"unreadable\"; failure: ConfigLoadError }\n | { kind: \"declares-nothing\"; config: ProjectConfig }\n | { kind: \"loaded\"; config: ProjectConfig; inherited: boolean };\n\n/** The project's own config, else the global one it inherits, each read with its scope's host. */\nexport async function resolveConfigState({\n projectDir,\n hosts,\n}: CheckedInstallation): Promise<ConfigState> {\n try {\n return await readConfigState(projectDir, hosts);\n } catch (error) {\n if (error instanceof ConfigLoadError) return { kind: \"unreadable\", failure: error };\n throw error;\n }\n}\n\nasync function readConfigState(projectDir: string, hosts: Hosts): Promise<ConfigState> {\n const own = await loadProjectConfigFromDir(projectDir, hosts.project);\n if (own && !declaresNoContent(own.config)) {\n return { kind: \"loaded\", config: own.config, inherited: false };\n }\n\n const inherited = isHomeDirectory(projectDir)\n ? null\n : await loadProjectConfigFromDir(os.homedir(), hosts.global);\n if (inherited && !declaresNoContent(inherited.config)) {\n return { kind: \"loaded\", config: inherited.config, inherited: true };\n }\n\n return own ? { kind: \"declares-nothing\", config: own.config } : { kind: \"absent\" };\n}\n\n/**\n * `getVerifiedPluginInstallPaths` asked of a named host rather than the one in use at `baseDir`:\n * enabled plugins whose manifest is still on disk, none at all from a registry it cannot read.\n */\nexport async function installedPluginSkillIds(\n baseDir: string,\n provider: Provider,\n): Promise<ReadonlySet<string>> {\n const plugins = await verifiedPlugins(baseDir, provider);\n return new Set(plugins.map((plugin) => parseMarketplacePluginRef(plugin.pluginKey)));\n}\n\nasync function verifiedPlugins(baseDir: string, provider: Provider): Promise<HostPlugin[]> {\n const enabled = (await pluginsListedBy(provider, baseDir)).filter((plugin) => plugin.enabled);\n const onDisk = await Promise.all(\n enabled.map((plugin) => fileExists(getPluginManifestPath(plugin.installPath))),\n );\n return enabled.filter((_, index) => onDisk[index] === true);\n}\n\nasync function pluginsListedBy(provider: Provider, baseDir: string): Promise<HostPlugin[]> {\n try {\n return await hostFor(provider).listPlugins(baseDir);\n } catch (error) {\n verbose(`Failed to list installed plugins: ${getErrorMessage(error)}`);\n return [];\n }\n}\n\n/**\n * `unofferablePlacementsFound` asked of each scope's named host: both scopes, each refused by its\n * own host, since the two can be on different providers. Project first, as that one walks them.\n */\nexport async function unofferablePlacements({\n projectDir,\n hosts,\n}: CheckedInstallation): Promise<string[]> {\n const projectFirst = [...scopeRootsInPlay(projectDir)].reverse();\n const findings = await Promise.all(\n projectFirst.map(({ kind, root }) => unofferablePlacementIn(root, hosts[kind])),\n );\n return findings.filter((finding): finding is string => finding !== null);\n}\n\nasync function unofferablePlacementIn(root: string, provider: Provider): Promise<string | null> {\n const skills = await configuredSkillsAt(root, provider);\n if (skills === null) return null;\n\n try {\n refuseUnofferedPlacements(skills, hostFor(provider));\n return null;\n } catch (error) {\n return getErrorMessage(error);\n }\n}\n\n/** Degrades on `ConfigLoadError` only, which the Config Valid row reports by name. */\nasync function configuredSkillsAt(root: string, provider: Provider): Promise<SkillConfig[] | null> {\n try {\n const loaded = await loadProjectConfigFromDir(root, provider);\n return loaded?.config.skills ?? null;\n } catch (error) {\n if (error instanceof ConfigLoadError) return null;\n throw error;\n }\n}\n","/**\n * What an installation holds that its configuration does not account for: `doctor`'s No Orphans\n * row. An agents folder a configuration declares is judged against it, whatever wrote the files;\n * one none declares, by this CLI's marker. Skill folders only where no configuration exists at\n * all, by `forkedFrom`: `eject skills` copies in stamped folders that no configuration lists.\n */\n\nimport path from \"path\";\nimport { groupBy, unique } from \"remeda\";\n\nimport type { CheckedInstallation, ConfigState, Hosts } from \"./installation-reads.js\";\nimport { listAgentFilesOf } from \"../agents/index.js\";\nimport {\n agentFilesWithOurProvenanceIn,\n skillDirsWithOurProvenanceIn,\n} from \"../content-validator.js\";\nimport {\n agentCodec,\n agentsDir,\n skillsDir,\n type AgentCodec,\n} from \"../installation/install-layout.js\";\nimport { directoryExists } from \"../../utils/fs.js\";\nimport { typedValues } from \"../../utils/typed-object.js\";\nimport type { ProjectConfig, SkillScope } from \"../../types/index.js\";\n\nexport type Ownership = {\n /** Display paths of what this CLI provably wrote into a folder no configuration declares. */\n unowned: { skills: string[]; agents: string[] };\n /** File names, not paths, in a declared agents folder its configuration does not claim. */\n orphanedAgentFiles: string[];\n};\n\n/**\n * One agents folder, once however many scopes share it, and the names a configuration claims in\n * it: `null` where none declares its scope, so only what this CLI provably wrote there is named.\n */\ntype JudgedAgentFolder = { dir: string; codec: AgentCodec; claimed: ReadonlySet<string> | null };\n\n/** `config` is `null` only where `state` is absent: a config the checks rejected is not judged. */\nexport async function judgeOwnership(\n state: ConfigState,\n config: ProjectConfig | null,\n installation: CheckedInstallation,\n): Promise<Ownership> {\n const agentFolders = agentFoldersToJudge(state, config, installation);\n\n const [skills, agents, orphanedAgentFiles] = await Promise.all([\n unownedSkillDirs(state, installation),\n unownedAgentFiles(agentFolders),\n Promise.all(agentFolders.map(unclaimedAgentFiles)),\n ]);\n return { unowned: { skills, agents }, orphanedAgentFiles: orphanedAgentFiles.flat() };\n}\n\nfunction agentFoldersToJudge(\n state: ConfigState,\n config: ProjectConfig | null,\n { projectDir, hosts }: CheckedInstallation,\n): JudgedAgentFolder[] {\n return oncePerFolder(\n scopesToJudge(state, hosts).map((scope) => ({\n dir: agentsDir(hosts[scope], scope, projectDir),\n codec: agentCodec(hosts[scope]),\n claimed: claimed(state, scope, config && agentNamesClaimedIn(config, scope)),\n })),\n );\n}\n\n/** Only where no configuration exists anywhere: then every stamped folder is a leftover. */\nasync function unownedSkillDirs(\n state: ConfigState,\n { projectDir, hosts }: CheckedInstallation,\n): Promise<string[]> {\n if (state.kind !== \"absent\") return [];\n\n const dirs = unique(\n scopesToJudge(state, hosts).map((scope) => skillsDir(hosts[scope], scope, projectDir)),\n );\n const listed = await Promise.all(dirs.map(skillDirsWithOurProvenanceIn));\n return listed.flat();\n}\n\n/**\n * Project first. Beside its own config a project is judged in the global folders only when they\n * are its provider's: another provider's global ones belong to an installation this config does\n * not describe.\n */\nfunction scopesToJudge(state: ConfigState, hosts: Hosts): SkillScope[] {\n const ownConfig = state.kind !== \"absent\" && !inherits(state);\n return ownConfig && hosts.global !== hosts.project ? [\"project\"] : [\"project\", \"global\"];\n}\n\nfunction inherits(state: ConfigState): boolean {\n return state.kind === \"loaded\" && state.inherited;\n}\n\n/** `null` for a scope no configuration declares: none at all, or a project inheriting one. */\nfunction claimed(\n state: ConfigState,\n scope: SkillScope,\n names: string[] | null,\n): ReadonlySet<string> | null {\n if (names === null || state.kind === \"absent\") return null;\n if (inherits(state) && scope === \"project\") return null;\n return new Set(names);\n}\n\nfunction agentNamesClaimedIn(config: ProjectConfig, scope: SkillScope): string[] {\n return config.agents.filter((agent) => claimsAt(agent, scope)).map((agent) => agent.name);\n}\n\n/** An excluded global entry still serves other projects; an excluded project one serves nothing. */\nfunction claimsAt(entry: { scope: SkillScope; excluded?: boolean }, scope: SkillScope): boolean {\n return entry.scope === scope && (scope === \"global\" || !entry.excluded);\n}\n\n/** Two scopes can share a folder (Claude's at home): judged once, against both claims. */\nfunction oncePerFolder(folders: JudgedAgentFolder[]): JudgedAgentFolder[] {\n return typedValues(groupBy(folders, (folder) => folder.dir)).map((sharing) =>\n sharing.reduce(joinClaims),\n );\n}\n\nfunction joinClaims(into: JudgedAgentFolder, from: JudgedAgentFolder): JudgedAgentFolder {\n if (into.claimed === null) return from;\n if (from.claimed === null) return into;\n return { ...into, claimed: new Set([...into.claimed, ...from.claimed]) };\n}\n\nasync function unownedAgentFiles(agentFolders: JudgedAgentFolder[]): Promise<string[]> {\n const listed = await Promise.all(\n agentFolders\n .filter((folder) => folder.claimed === null)\n .map(({ dir, codec }) => agentFilesWithOurProvenanceIn(dir, codec)),\n );\n return listed.flat();\n}\n\nasync function unclaimedAgentFiles({ dir, codec, claimed }: JudgedAgentFolder): Promise<string[]> {\n if (claimed === null || !(await directoryExists(dir))) return [];\n const files = await listAgentFilesOf(dir, codec);\n return files.filter((file) => !claimed.has(path.basename(file, codec.extension)));\n}\n","import os from \"os\";\nimport path from \"path\";\nimport { partition } from \"remeda\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { STANDARD_FILES } from \"../consts.js\";\nimport { directoryExists, fileExists, listDirectories } from \"../utils/fs.js\";\nimport { listAgentMdFiles, splitAgentsByProvenance } from \"./agents/index.js\";\nimport { readSkillMetadata } from \"./loading/index.js\";\nimport {\n configDirsInPlay,\n findConfigLoadFailures,\n isLocalSource,\n loadInstalledConfig,\n resolvePrimarySourceEntry,\n type ConfigLoadError,\n type LoadedProjectConfig,\n type SourceEntry,\n} from \"./configuration/index.js\";\nimport { isHomeDirectory, resolveInstallPaths } from \"./installation/index.js\";\nimport { getInstalledConfigPath } from \"./installation/install-base-dir.js\";\nimport type { AgentCodec } from \"./installation/install-layout.js\";\nimport {\n getInstalledPluginsRegistryPath,\n getProjectPluginsDir,\n getUserPluginsDir,\n listPluginDirNames,\n listRegisteredPluginInstalls,\n validateAgentFrontmatter,\n validateAllPlugins,\n validatePlugin,\n validateSkillFrontmatter,\n type ResolvedPlugin,\n} from \"./plugins/index.js\";\nimport { splitMetadataValidationIssues, validateSkillMetadata } from \"./schemas.js\";\nimport { readForkedFromMetadata } from \"./skills/index.js\";\nimport { isSourceRepo, validateSource, type MarketplaceReader } from \"./source-validator.js\";\nimport { invalidResult, mergeValidationResults, validResult } from \"./validation-result.js\";\nimport { scopeLabel } from \"../utils/messages.js\";\nimport { plural } from \"../utils/string.js\";\nimport type { ValidationResult } from \"../types/index.js\";\n\n/** How a source repository under the cwd is labelled when it is not a registered source. */\nconst CWD_SOURCE_NAME = \"current directory\";\n\nexport type ContentIssue = {\n severity: \"error\" | \"warning\";\n /** The file or directory a reader has to open to fix the issue. */\n file: string;\n message: string;\n};\n\n/** `notes` records which sources were reached and which skipped; neither errors nor warnings. */\nexport type ContentValidation = {\n count: number;\n issues: ContentIssue[];\n notes: string[];\n};\n\nconst NOTHING_VALIDATED: ContentValidation = { count: 0, issues: [], notes: [] };\n\nfunction mergeValidations(parts: ContentValidation[]): ContentValidation {\n return parts.reduce(\n (acc, part) => ({\n count: acc.count + part.count,\n issues: [...acc.issues, ...part.issues],\n notes: [...acc.notes, ...part.notes],\n }),\n NOTHING_VALIDATED,\n );\n}\n\nfunction displayDir(absolutePath: string): string {\n const home = os.homedir();\n if (absolutePath === home) return \"~\";\n if (absolutePath.startsWith(home + path.sep)) {\n return `~${path.sep}${path.relative(home, absolutePath)}`;\n }\n return absolutePath;\n}\n\nfunction toIssues(file: string, result: ValidationResult): ContentIssue[] {\n return [\n ...result.errors.map((message) => ({ severity: \"error\" as const, file, message })),\n ...result.warnings.map((message) => ({ severity: \"warning\" as const, file, message })),\n ];\n}\n\nconst CONFIG_UNREADABLE = \"exists but could not be loaded\";\n\n/** Reported here, since every operational row reads the config; an absent one is no finding. */\nexport async function validateProjectConfigFile(projectDir: string): Promise<ContentValidation> {\n const [present, failures] = await Promise.all([\n countExistingConfigs(projectDir),\n findConfigLoadFailures(projectDir),\n ]);\n\n return { count: present, issues: failures.map(toUnreadableConfigIssue), notes: [] };\n}\n\n/** Led by whose config it is: from a project, its own or the inherited global one. */\nfunction toUnreadableConfigIssue(failure: ConfigLoadError): ContentIssue {\n return {\n severity: \"error\",\n file: `${scopeLabel(failure.scope)}'s ${displayDir(failure.configPath)}`,\n message: `${CONFIG_UNREADABLE}: ${failure.reason}`,\n };\n}\n\nasync function countExistingConfigs(projectDir: string): Promise<number> {\n const present = await Promise.all(\n configDirsInPlay(projectDir).map((dir) => fileExists(getInstalledConfigPath(dir))),\n );\n return present.filter(Boolean).length;\n}\n\n/** The local marketplace, plus the cwd when it is a skills source repo; remote is skipped. */\nexport async function validateRegisteredSources(projectDir: string): Promise<ContentValidation> {\n // Degrades on an unreadable config: `safeCheck` turns a throw into a failed row.\n const primary = await resolvePrimarySourceEntry(projectDir);\n const registered = [primary];\n const remote = registered.filter((source) => !isLocalSource(source.url));\n const local = await localSourcesToValidate(projectDir, registered);\n\n const outcomes = await Promise.all(\n local.map((source) => validateOneSource(source, readerFor(projectDir, source))),\n );\n\n return {\n count: local.length,\n issues: outcomes.flatMap((outcome) => outcome.issues),\n notes: [\n ...outcomes.map((outcome) => outcome.note),\n ...remote.map((source) => `${source.name} (${source.url}) — skipped (remote)`),\n ],\n };\n}\n\nasync function localSourcesToValidate(\n projectDir: string,\n registered: SourceEntry[],\n): Promise<SourceEntry[]> {\n const local = registered.filter((source) => isLocalSource(source.url));\n const alreadyCovered = local.some((source) => isCwdMarketplace(projectDir, source));\n\n if (alreadyCovered || !(await isSourceRepo(projectDir))) return local;\n\n return [...local, { name: CWD_SOURCE_NAME, url: projectDir }];\n}\n\n/** Whether this marketplace IS the directory the command ran in, however the config spells it. */\nfunction isCwdMarketplace(projectDir: string, source: SourceEntry): boolean {\n return path.resolve(projectDir, source.url) === projectDir;\n}\n\n/** The one place knowing the cwd and each marketplace path; the cwd entry answers `\"author\"`. */\nfunction readerFor(projectDir: string, source: SourceEntry): MarketplaceReader {\n return isCwdMarketplace(projectDir, source) ? \"author\" : \"consumer\";\n}\n\ntype SourceOutcome = { note: string; issues: ContentIssue[] };\n\nasync function validateOneSource(\n source: SourceEntry,\n reader: MarketplaceReader,\n): Promise<SourceOutcome> {\n const label = `${source.name} (${source.url})`;\n try {\n const result = await validateSource(source.url, reader);\n return { note: `${label} — ${plural(result.skillCount, \"skill\")}`, issues: result.issues };\n } catch (error) {\n return {\n note: `${label} — failed`,\n issues: [{ severity: \"error\", file: source.url, message: getErrorMessage(error) }],\n };\n }\n}\n\nexport async function validateInstalledPlugins(projectDir: string): Promise<ContentValidation> {\n const dirs = [\n getUserPluginsDir(),\n ...(isHomeDirectory(projectDir) ? [] : [getProjectPluginsDir(projectDir)]),\n ];\n return mergeValidations(await Promise.all(dirs.map(validatePluginsDirectory)));\n}\n\nasync function validatePluginsDirectory(pluginsDir: string): Promise<ContentValidation> {\n if (!(await directoryExists(pluginsDir))) return NOTHING_VALIDATED;\n\n if (await fileExists(getInstalledPluginsRegistryPath(pluginsDir))) {\n const registryValidation = await validateRegistryPlugins(pluginsDir);\n if (registryValidation !== undefined) return registryValidation;\n }\n\n const pluginDirs = await listPluginDirNames(pluginsDir);\n if (pluginDirs.length === 0) return NOTHING_VALIDATED;\n\n const { results } = await validateAllPlugins(pluginsDir);\n\n return {\n count: results.length,\n issues: results.flatMap(({ name, result }) => toIssues(name, result)),\n notes: [],\n };\n}\n\n/** Undefined when the registry records no installs; the caller then scans direct children. */\nasync function validateRegistryPlugins(pluginsDir: string): Promise<ContentValidation | undefined> {\n let installs: ResolvedPlugin[];\n try {\n installs = await listRegisteredPluginInstalls(pluginsDir);\n } catch (error) {\n return {\n count: 0,\n issues: [\n {\n severity: \"error\",\n file: displayDir(getInstalledPluginsRegistryPath(pluginsDir)),\n message: getErrorMessage(error),\n },\n ],\n notes: [],\n };\n }\n\n if (installs.length === 0) return undefined;\n\n // A vanished installPath fails validatePlugin's structure check rather than crashing.\n const results = await Promise.all(\n installs.map(async ({ pluginKey, installPath }) =>\n toIssues(pluginKey, await validatePlugin(installPath)),\n ),\n );\n\n return { count: installs.length, issues: results.flat(), notes: [] };\n}\n\n/**\n * Only skills this installation owns, since `~/.claude/skills/` is shared: a directory is ours when\n * a config in play names its id or it carries `forkedFrom`. Any other is named, not judged.\n */\nexport async function validateInstalledSkills(projectDir: string): Promise<ContentValidation> {\n const configuredIds = await configuredSkillIds(projectDir);\n return mergeValidations(\n await Promise.all(\n installedDirs(projectDir, \"skillsDir\").map((dir) =>\n validateSkillsDirectory(dir, configuredIds),\n ),\n ),\n );\n}\n\n/** Every skill id the configs this run reads name, across both scopes and both install modes. */\nasync function configuredSkillIds(projectDir: string): Promise<ReadonlySet<string>> {\n const loaded = await Promise.all(\n configDirsInPlay(projectDir).map((dir) => loadInstalledConfig(dir)),\n );\n return new Set(loaded.flatMap(configuredIdsOf));\n}\n\nfunction configuredIdsOf(loaded: LoadedProjectConfig | null): string[] {\n if (!loaded) return [];\n return loaded.config.skills.map((skill) => skill.id);\n}\n\nexport async function validateInstalledAgents(projectDir: string): Promise<ContentValidation> {\n return mergeValidations(\n await Promise.all(installedDirs(projectDir, \"agentsDir\").map(validateAgentsDirectory)),\n );\n}\n\n/** At the home directory both scopes resolve to one place, walked once. */\nfunction installedDirs(projectDir: string, key: \"skillsDir\" | \"agentsDir\"): string[] {\n const global = resolveInstallPaths(projectDir, \"global\")[key];\n if (isHomeDirectory(projectDir)) return [global];\n return [global, resolveInstallPaths(projectDir, \"project\")[key]];\n}\n\n/** Skill folders this CLI provably wrote, as `uninstall` takes them, as display paths. */\nexport async function skillDirsWithOurProvenanceIn(skillsDir: string): Promise<string[]> {\n return listDisplayPaths(skillsDir, listSkillDirsWithOurProvenance);\n}\n\n/** Compiled agent files this CLI provably wrote, as `uninstall` takes them, as display paths. */\nexport async function agentFilesWithOurProvenanceIn(\n agentsDir: string,\n codec: AgentCodec,\n): Promise<string[]> {\n return listDisplayPaths(agentsDir, (dir) => listAgentFilesWithOurProvenance(dir, codec));\n}\n\n/**\n * Asks `splitAgentsByProvenance`, as `uninstall` does, so this lists exactly what it would remove.\n */\nasync function listAgentFilesWithOurProvenance(\n agentsDir: string,\n codec: AgentCodec,\n): Promise<string[]> {\n const { marked } = await splitAgentsByProvenance(agentsDir, codec);\n return marked.map((name) => `${name}${codec.extension}`);\n}\n\n/** By `forkedFrom` alone, as `uninstall` reads it; unreadable metadata carries none. */\nasync function listSkillDirsWithOurProvenance(skillsDir: string): Promise<string[]> {\n const [ours] = await partitionByVerdict(await listDirectories(skillsDir), (name) =>\n carriesOurProvenance(skillsDir, name),\n );\n return ours;\n}\n\nasync function partitionByVerdict(\n names: string[],\n verdict: (name: string) => Promise<boolean>,\n): Promise<[string[], string[]]> {\n const verdicts = await Promise.all(names.map(verdict));\n return partition(names, (_, index) => verdicts[index] === true);\n}\n\nasync function listDisplayPaths(\n dir: string,\n listEntries: (dir: string) => Promise<string[]>,\n): Promise<string[]> {\n if (!(await directoryExists(dir))) return [];\n const entries = await listEntries(dir);\n return entries.map((entry) => displayDir(path.join(dir, entry)));\n}\n\nasync function validateSkillsDirectory(\n skillsDir: string,\n configuredIds: ReadonlySet<string>,\n): Promise<ContentValidation> {\n if (!(await directoryExists(skillsDir))) return NOTHING_VALIDATED;\n\n const skillDirs = await listDirectories(skillsDir);\n if (skillDirs.length === 0) return NOTHING_VALIDATED;\n\n const [ours, foreign] = await partitionByVerdict(skillDirs, (name) =>\n isOurSkillDirectory(skillsDir, name, configuredIds),\n );\n\n const results = await Promise.all(\n ours.map(async (name) => {\n const skillDir = path.join(skillsDir, name);\n return toIssues(displayDir(skillDir), await validateInstalledSkill(skillDir));\n }),\n );\n\n return {\n count: ours.length,\n issues: results.flat(),\n notes: foreign.map((name) => foreignSkillNote(skillsDir, name)),\n };\n}\n\n/** Either claim this installation has on a skill directory. */\nasync function isOurSkillDirectory(\n skillsDir: string,\n name: string,\n configuredIds: ReadonlySet<string>,\n): Promise<boolean> {\n if (configuredIds.has(name)) return true;\n return carriesOurProvenance(skillsDir, name);\n}\n\n/** The `forkedFrom` block the copier stamps; `uninstall` asks exactly this. */\nasync function carriesOurProvenance(skillsDir: string, name: string): Promise<boolean> {\n return (await readForkedFromMetadata(path.join(skillsDir, name))) !== null;\n}\n\n/** Named so the count and the listing do not silently disagree; not a warning. */\nfunction foreignSkillNote(skillsDir: string, name: string): string {\n return `${displayDir(path.join(skillsDir, name))} — not installed by this CLI and named by no configuration here: not validated`;\n}\n\nasync function validateAgentsDirectory(agentsDir: string): Promise<ContentValidation> {\n if (!(await directoryExists(agentsDir))) return NOTHING_VALIDATED;\n\n const agentFiles = await listAgentMdFiles(agentsDir);\n if (agentFiles.length === 0) return NOTHING_VALIDATED;\n\n const results = await Promise.all(\n agentFiles.map(async (fileName) => {\n const agentPath = path.join(agentsDir, fileName);\n return toIssues(displayDir(agentPath), await validateAgentFrontmatter(agentPath));\n }),\n );\n\n return { count: agentFiles.length, issues: results.flat(), notes: [] };\n}\n\nasync function validateInstalledSkill(skillDir: string): Promise<ValidationResult> {\n const [skillMd, metadata] = await Promise.all([\n validateSkillFile(skillDir, STANDARD_FILES.SKILL_MD, validateSkillFrontmatter),\n validateSkillFile(skillDir, STANDARD_FILES.METADATA_YAML, validateInstalledSkillMetadata),\n ]);\n\n return mergeValidationResults([skillMd, metadata]);\n}\n\n/** One of an installed skill's files judged by `validate`, or the error of its absence. */\nasync function validateSkillFile(\n skillDir: string,\n fileName: string,\n validate: (filePath: string) => Promise<ValidationResult>,\n): Promise<ValidationResult> {\n const filePath = path.join(skillDir, fileName);\n if (!(await fileExists(filePath))) return invalidResult(`Missing ${fileName}`);\n return validate(filePath);\n}\n\nasync function validateInstalledSkillMetadata(metadataPath: string): Promise<ValidationResult> {\n // The same verdict compile and discovery use; the strict published-skill checks layer on top.\n const read = await readSkillMetadata(metadataPath);\n if (!read.usable) {\n return invalidResult(`${STANDARD_FILES.METADATA_YAML}: ${read.reason}`);\n }\n\n const metadata = read.metadata;\n const result = validateSkillMetadata(metadata);\n if (result.success) {\n return validResult();\n }\n\n const { errors, warnings } = splitMetadataValidationIssues(result.error, metadata);\n return {\n valid: errors.length === 0,\n errors: errors.map((e) => `${STANDARD_FILES.METADATA_YAML}: ${e}`),\n warnings: warnings.map((w) => `${STANDARD_FILES.METADATA_YAML}: ${w}`),\n };\n}\n","import path from \"path\";\nimport { isRecord } from \"../utils/type-guards.js\";\nimport { parse as parseYaml } from \"yaml\";\nimport { z } from \"zod\";\nimport { glob, readFile, fileExists, directoryExists } from \"../utils/fs\";\nimport {\n DIRS,\n MARKETPLACE_JSON,\n PLUGIN_MANIFEST_DIR,\n SKILL_CATEGORIES_PATH,\n SKILL_RULES_PATH,\n SKILLS_DIR_PATH,\n STACKS_FILE_PATH,\n STANDARD_FILES,\n} from \"../consts\";\nimport {\n agentYamlGenerationSchema,\n metadataValidationSchema,\n splitMetadataValidationIssues,\n validateSkillMetadata,\n skillCategoriesFileSchema,\n skillRulesFileSchema,\n stackConfigValidationSchema,\n stacksConfigSchema,\n} from \"./schemas\";\nimport { parseFrontmatter } from \"./loading/loader\";\nimport { ConfigDefaultExportError, loadConfig, loadSourceRepoConfig } from \"./configuration\";\nimport type { MatrixHealthIssue } from \"./matrix\";\nimport { matrixHealthIssues } from \"./matrix/matrix-health-check\";\nimport {\n loadSkillsMatrixFromSource,\n MarketplaceManifestRequiredError,\n} from \"./loading/source-loader\";\nimport { MarketplaceNameRefusedError } from \"./loading/source-fetcher\";\nimport { matrix } from \"./matrix/matrix-provider\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport { formatZodErrors } from \"./schema-validator\";\n\ntype SourceValidationIssue = {\n severity: \"error\" | \"warning\";\n file: string;\n message: string;\n};\n\nexport type SourceValidationResult = {\n issues: SourceValidationIssue[];\n skillCount: number;\n errorCount: number;\n warningCount: number;\n};\n\n/**\n * `\"author\"` when the marketplace IS the directory the command ran in, else `\"consumer\"`. It\n * changes one finding: a dangling rule slug is the author's to fix and a consumer's to ignore.\n */\nexport type MarketplaceReader = \"author\" | \"consumer\";\n\n/** True when `dir` carries a skills tree, at `src/skills/` or where its source config points. */\nexport async function isSourceRepo(dir: string): Promise<boolean> {\n // Aborts on an unreadable config; `doctor` catches it via `safeCheck`.\n const sourceConfig = await loadSourceRepoConfig(dir);\n return directoryExists(path.join(dir, sourceConfig?.skillsDir ?? SKILLS_DIR_PATH));\n}\n\nfunction isSnakeCase(key: string): boolean {\n return /[a-z]_[a-z]/.test(key);\n}\n\nfunction checkSnakeCaseKeys(rawMetadata: unknown, relPath: string): SourceValidationIssue[] {\n if (!isRecord(rawMetadata)) return [];\n\n return Object.keys(rawMetadata)\n .filter(isSnakeCase)\n .map((key) => ({\n severity: \"error\" as const,\n file: relPath,\n message: `Key '${key}' uses snake_case — use camelCase instead`,\n }));\n}\n\n/** A warning, not an error: the loader still registers the skill by its id. */\nfunction checkDirNameMatchesSkillId(\n skillId: string,\n relPath: string,\n dirName: string,\n): SourceValidationIssue[] {\n if (skillId === dirName) return [];\n return [\n {\n severity: \"warning\",\n file: relPath,\n message: `Directory name '${dirName}' does not match skill id '${skillId}'`,\n },\n ];\n}\n\nasync function checkSkillDirName(\n skillsDir: string,\n skillsDirRelPath: string,\n skillDir: string,\n): Promise<SourceValidationIssue[]> {\n const dirName = path.basename(skillDir);\n const skillMdRelPath = path.join(skillsDirRelPath, skillDir, STANDARD_FILES.SKILL_MD);\n\n try {\n const content = await readFile(path.join(skillsDir, skillDir, STANDARD_FILES.SKILL_MD));\n const frontmatter = parseFrontmatter(content, skillMdRelPath);\n\n if (frontmatter === null) {\n return [\n {\n severity: \"warning\",\n file: skillMdRelPath,\n message: `Cannot verify directory name '${dirName}': missing or invalid ${STANDARD_FILES.SKILL_MD} frontmatter`,\n },\n ];\n }\n\n return checkDirNameMatchesSkillId(frontmatter.name, skillMdRelPath, dirName);\n } catch (error) {\n return [\n {\n severity: \"warning\",\n file: skillMdRelPath,\n message: `Cannot verify directory name '${dirName}': ${getErrorMessage(error)}`,\n },\n ];\n }\n}\n\nfunction validateSkillFilePairs(\n skillMdDirs: Set<string>,\n metadataDirs: Set<string>,\n skillsDir: string,\n): SourceValidationIssue[] {\n const missingMetadata = [...skillMdDirs]\n .filter((dir) => !metadataDirs.has(dir))\n .map((dir) => ({\n severity: \"error\" as const,\n file: path.join(skillsDir, dir),\n message: `Missing ${STANDARD_FILES.METADATA_YAML} — skill directory has ${STANDARD_FILES.SKILL_MD} but no metadata`,\n }));\n\n const missingSkillMd = [...metadataDirs]\n .filter((dir) => !skillMdDirs.has(dir))\n .map((dir) => ({\n severity: \"error\" as const,\n file: path.join(skillsDir, dir),\n message: `Missing ${STANDARD_FILES.SKILL_MD} — skill directory has ${STANDARD_FILES.METADATA_YAML} but no SKILL.md`,\n }));\n\n return [...missingMetadata, ...missingSkillMd];\n}\n\n/** `reader` sets how loud findings are; default `\"author\"`, as under-reporting is worse. */\nexport async function validateSource(\n sourcePath: string,\n reader: MarketplaceReader = \"author\",\n): Promise<SourceValidationResult> {\n const resolvedPath = path.isAbsolute(sourcePath) ? sourcePath : path.resolve(sourcePath);\n\n if (!(await directoryExists(resolvedPath))) {\n return buildResult(\n [{ severity: \"error\", file: resolvedPath, message: \"Marketplace directory does not exist\" }],\n 0,\n );\n }\n\n // Aborts on an unreadable config; `validateOneSource` turns it into an issue.\n const sourceProjectConfig = await loadSourceRepoConfig(resolvedPath);\n const skillsDirRelPath = sourceProjectConfig?.skillsDir ?? SKILLS_DIR_PATH;\n const skillsDir = path.join(resolvedPath, skillsDirRelPath);\n\n if (!(await directoryExists(skillsDir))) {\n return buildResult(\n [{ severity: \"error\", file: skillsDir, message: \"Skills directory does not exist\" }],\n 0,\n );\n }\n\n const { pairIssues, validMetadataFiles } = await pairSkillFiles(skillsDir);\n const skillIssues = await validateSkillsInTurn(skillsDir, skillsDirRelPath, validMetadataFiles);\n\n const crossReferenceIssues = await checkCrossReferences(resolvedPath, reader);\n\n const extraIssues = await Promise.all([\n validateStacks(resolvedPath),\n validateAgents(resolvedPath),\n validateConfigFiles(resolvedPath),\n ]);\n\n return buildResult(\n [...pairIssues, ...skillIssues, ...crossReferenceIssues, ...extraIssues.flat()],\n validMetadataFiles.length,\n );\n}\n\n/** A half pair is reported here, so only complete pairs go on to be validated. */\nasync function pairSkillFiles(\n skillsDir: string,\n): Promise<{ pairIssues: SourceValidationIssue[]; validMetadataFiles: string[] }> {\n const skillMdFiles = await glob(`**/${STANDARD_FILES.SKILL_MD}`, skillsDir);\n const metadataFiles = await glob(`**/${STANDARD_FILES.METADATA_YAML}`, skillsDir);\n\n const skillMdDirs = new Set(skillMdFiles.map((f) => path.dirname(f)));\n const metadataDirs = new Set(metadataFiles.map((f) => path.dirname(f)));\n\n return {\n pairIssues: validateSkillFilePairs(skillMdDirs, metadataDirs, skillsDir),\n validMetadataFiles: metadataFiles.filter((f) => skillMdDirs.has(path.dirname(f))),\n };\n}\n\nasync function validateSkillsInTurn(\n skillsDir: string,\n skillsDirRelPath: string,\n metadataFiles: string[],\n): Promise<SourceValidationIssue[]> {\n const issues: SourceValidationIssue[] = [];\n for (const metadataFile of metadataFiles) {\n issues.push(...(await validateOneSkill(skillsDir, skillsDirRelPath, metadataFile)));\n }\n return issues;\n}\n\n/** Named once so both YAML-reading phases word the failure alike. */\nfunction yamlParseFailure(error: unknown): string {\n return `Failed to parse YAML: ${getErrorMessage(error)}`;\n}\n\n/** An unparseable file reports that and stops: every later check reads the parsed value. */\nasync function validateOneSkill(\n skillsDir: string,\n skillsDirRelPath: string,\n metadataFile: string,\n): Promise<SourceValidationIssue[]> {\n const relPath = path.join(skillsDirRelPath, metadataFile);\n\n let rawMetadata: unknown;\n try {\n rawMetadata = parseYaml(await readFile(path.join(skillsDir, metadataFile)));\n } catch (error) {\n return [{ severity: \"error\", file: relPath, message: yamlParseFailure(error) }];\n }\n\n return [\n ...checkSnakeCaseKeys(rawMetadata, relPath),\n ...checkMetadataSchema(rawMetadata, relPath),\n // Independent of metadata validity — the id lives in SKILL.md frontmatter\n ...(await checkSkillDirName(skillsDir, skillsDirRelPath, path.dirname(metadataFile))),\n ];\n}\n\nfunction checkMetadataSchema(rawMetadata: unknown, relPath: string): SourceValidationIssue[] {\n const result = validateSkillMetadata(rawMetadata);\n if (result.success) return [];\n\n const { errors, warnings } = splitMetadataValidationIssues(result.error, rawMetadata);\n return [\n ...errors.map((message) => ({ severity: \"error\" as const, file: relPath, message })),\n ...warnings.map((message) => ({ severity: \"warning\" as const, file: relPath, message })),\n ];\n}\n\n/** As a reader types it: the file `doctor` tells them to open. */\nconst MARKETPLACE_MANIFEST_PATH = path.join(PLUGIN_MANIFEST_DIR, MARKETPLACE_JSON);\n\n/** Keyed on the whole reader union, so a new reader does not compile until someone decides. */\nconst MANIFEST_REQUIRED_SEVERITY = {\n author: \"warning\",\n consumer: \"error\",\n} as const satisfies Record<MarketplaceReader, SourceValidationIssue[\"severity\"]>;\n\n/** Files the load's health findings without saying them again. */\nasync function checkCrossReferences(\n resolvedPath: string,\n reader: MarketplaceReader,\n): Promise<SourceValidationIssue[]> {\n try {\n await loadSkillsMatrixFromSource({ sourceFlag: resolvedPath, skipExtraSources: true });\n return matrixHealthIssues(matrix).map((healthIssue) =>\n toSourceIssue(healthIssue, resolvedPath, reader),\n );\n } catch (error) {\n return [matrixLoadFailure(error, reader)];\n }\n}\n\n/**\n * No valid manifest: the manifest's finding, at the reader's severity. A refused name: this\n * marketplace's error, since nothing installs. Anything else: a warning. Read off the throw's type.\n */\nfunction matrixLoadFailure(error: unknown, reader: MarketplaceReader): SourceValidationIssue {\n if (error instanceof MarketplaceManifestRequiredError) {\n return {\n severity: MANIFEST_REQUIRED_SEVERITY[reader],\n file: MARKETPLACE_MANIFEST_PATH,\n message: getErrorMessage(error),\n };\n }\n\n if (error instanceof MarketplaceNameRefusedError) {\n return {\n severity: \"error\",\n file: MARKETPLACE_MANIFEST_PATH,\n message: getErrorMessage(error),\n };\n }\n\n return {\n severity: \"warning\",\n file: SKILL_CATEGORIES_PATH,\n message: `Cross-reference validation skipped: failed to load categories/rules: ${getErrorMessage(error)}`,\n };\n}\n\n/** This CLI's own file: the marketplace holds no copy of the verdicts. */\nconst SKILL_AUDIT_PATH = \"src/cli/lib/configuration/skill-audit.ts\";\n\n/** The file the defect is in, as `doctor` shows it; exhaustive, so new kinds must choose. */\nfunction fileHoldingDefect(finding: MatrixHealthIssue[\"finding\"]): string {\n switch (finding) {\n case \"category-missing-domain\":\n case \"skill-unknown-category\":\n return SKILL_CATEGORIES_PATH;\n case \"skill-unresolved-relation-ref\":\n case \"rule-unresolved-slug\":\n return SKILL_RULES_PATH;\n case \"audit-verdict-contradiction\":\n case \"skill-unaudited\":\n return SKILL_AUDIT_PATH;\n default: {\n const exhaustive: never = finding;\n return exhaustive;\n }\n }\n}\n\n/** Only a marketplace's own dangling rule slug moves with the reader; the file never does. */\nfunction toSourceIssue(\n healthIssue: MatrixHealthIssue,\n marketplacePath: string,\n reader: MarketplaceReader,\n): SourceValidationIssue {\n const file = fileHoldingDefect(healthIssue.finding);\n\n if (reader === \"consumer\" && healthIssue.finding === \"rule-unresolved-slug\") {\n return {\n severity: \"warning\",\n file,\n message: consumedMarketplaceMessage(marketplacePath, healthIssue.details),\n };\n }\n\n return {\n severity: healthIssue.severity,\n file,\n message: healthIssue.details,\n };\n}\n\n/** Leads with the marketplace and says there is nothing here for the reader to fix. */\nfunction consumedMarketplaceMessage(marketplacePath: string, details: string): string {\n return `Marketplace '${marketplacePath}': ${details}. Nothing to fix here — the rule is that marketplace's, not this project's`;\n}\n\nasync function validateStacks(resolvedPath: string): Promise<SourceValidationIssue[]> {\n const stacksDir = path.join(resolvedPath, DIRS.stacks);\n if (!(await directoryExists(stacksDir))) return [];\n\n const [skillMetaIssues, configIssues] = await Promise.all([\n validateYamlFiles({\n baseDir: stacksDir,\n relBaseDir: DIRS.stacks,\n pattern: `**/skills/**/${STANDARD_FILES.METADATA_YAML}`,\n schema: metadataValidationSchema,\n }),\n validateYamlFiles({\n baseDir: stacksDir,\n relBaseDir: DIRS.stacks,\n pattern: `*/${STANDARD_FILES.CONFIG_YAML}`,\n schema: stackConfigValidationSchema,\n }),\n ]);\n return [...skillMetaIssues, ...configIssues];\n}\n\n/** Against compilation's input schema (compiling writes no YAML); skips a missing src/agents/. */\nasync function validateAgents(resolvedPath: string): Promise<SourceValidationIssue[]> {\n const agentsDir = path.join(resolvedPath, DIRS.agents);\n if (!(await directoryExists(agentsDir))) return [];\n\n return validateYamlFiles({\n baseDir: agentsDir,\n relBaseDir: DIRS.agents,\n pattern: `**/${STANDARD_FILES.AGENT_METADATA_YAML}`,\n schema: agentYamlGenerationSchema,\n });\n}\n\n/** Runtime-loads each config/*.ts and validates its default export; absent files are skipped. */\nasync function validateConfigFiles(resolvedPath: string): Promise<SourceValidationIssue[]> {\n const results = await Promise.all([\n validateTsConfig(resolvedPath, SKILL_CATEGORIES_PATH, skillCategoriesFileSchema),\n validateTsConfig(resolvedPath, SKILL_RULES_PATH, skillRulesFileSchema),\n validateTsConfig(resolvedPath, STACKS_FILE_PATH, stacksConfigSchema),\n ]);\n return results.flat();\n}\n\n/** One kind of YAML file a source may carry: where it lives, and the schema each must satisfy. */\ntype YamlFileScan = {\n baseDir: string;\n /** `baseDir` in the project-relative form issues report. */\n relBaseDir: string;\n pattern: string;\n schema: z.ZodType<unknown>;\n};\n\nasync function validateYamlFiles(scan: YamlFileScan): Promise<SourceValidationIssue[]> {\n const issues: SourceValidationIssue[] = [];\n const files = await glob(scan.pattern, scan.baseDir);\n\n for (const relFile of files) {\n issues.push(...(await validateYamlFile(scan, relFile)));\n }\n return issues;\n}\n\nasync function validateYamlFile(\n scan: YamlFileScan,\n relFile: string,\n): Promise<SourceValidationIssue[]> {\n const displayPath = path.join(scan.relBaseDir, relFile);\n\n let parsed: unknown;\n try {\n parsed = parseYaml(await readFile(path.join(scan.baseDir, relFile)));\n } catch (error) {\n return [{ severity: \"error\", file: displayPath, message: yamlParseFailure(error) }];\n }\n\n const result = scan.schema.safeParse(parsed);\n if (result.success) return [];\n\n return formatZodErrors(result.error).map((message) => ({\n severity: \"error\" as const,\n file: displayPath,\n message,\n }));\n}\n\n/** `null` (exported nothing) and named-only exports are reported apart, since the fixes differ. */\nasync function validateTsConfig(\n resolvedPath: string,\n relConfigPath: string,\n schema: z.ZodType<unknown>,\n): Promise<SourceValidationIssue[]> {\n const absPath = path.join(resolvedPath, relConfigPath);\n if (!(await fileExists(absPath))) return [];\n\n try {\n const loaded = await loadConfig(absPath, schema);\n if (loaded === null) {\n return [{ severity: \"error\", file: relConfigPath, message: \"Config is empty\" }];\n }\n return [];\n } catch (error) {\n if (error instanceof ConfigDefaultExportError) {\n return [{ severity: \"error\", file: relConfigPath, message: \"Config has no default export\" }];\n }\n return [\n { severity: \"error\", file: relConfigPath, message: formatLoadError(relConfigPath, error) },\n ];\n }\n}\n\n/** References the relative config path, not the absolute one loadConfig embeds. */\nfunction formatLoadError(relConfigPath: string, error: unknown): string {\n const raw = getErrorMessage(error);\n const stripped = raw.replace(/Failed to load config from '[^']+':\\s*/, \"\");\n return `Failed to load ${relConfigPath}: ${stripped}`;\n}\n\nfunction buildResult(issues: SourceValidationIssue[], skillCount: number): SourceValidationResult {\n const errorCount = issues.filter((i) => i.severity === \"error\").length;\n const warningCount = issues.filter((i) => i.severity === \"warning\").length;\n return { issues, skillCount, errorCount, warningCount };\n}\n"],"mappings":"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","names":["os","path","path","os","path","skillsDir","agentsDir","os","path","skillsDir","agentsDir","claimed","path","unique","os","matrix","path"]}
|