import type { Router } from "./router.js";
import type { SkillInfo } from "../eval/skill-scanner.js";
import type { ProviderName } from "../eval/llm.js";
import type { AgentDefinition } from "../agents/agents-registry.js";
export interface InstalledAgentEntry {
    id: string;
    displayName: string;
    featureSupport: AgentDefinition["featureSupport"];
    isUniversal: boolean;
    installed: boolean;
}
export interface InstalledAgentsResponse {
    agents: InstalledAgentEntry[];
    suggested: string;
}
/**
 * Build the response for GET /api/agents/installed.
 * Returns all known agents with installed flag based on detected agents.
 */
export declare function buildInstalledAgentsResponse(detectedAgents: AgentDefinition[]): InstalledAgentsResponse;
export interface AgentScopeEntry {
    id: string;
    displayName: string;
    featureSupport: AgentDefinition["featureSupport"];
    isUniversal: boolean;
    parentCompany: string;
    detected: boolean;
    isDefault: boolean;
    localSkillCount: number;
    globalSkillCount: number;
    pluginSkillCount: number;
    resolvedLocalDir: string;
    resolvedGlobalDir: string;
    lastSync: string | null;
    health: "ok" | "stale" | "missing";
    isRemoteOnly?: boolean;
}
export interface AgentsResponse {
    agents: AgentScopeEntry[];
    suggested: string;
    sharedFolders: Array<{
        path: string;
        consumers: string[];
    }>;
}
export interface PlatformHealth {
    degraded: boolean;
    reason: string | null;
    statsAgeMs: number;
    oldestActiveAgeMs: number;
}
/** Test hook — clear the 60 s cache so the next computePlatformHealth re-fetches. */
export declare function resetPlatformHealthCache(): void;
/**
 * 0778 — Compute platform health by probing two upstream verified-skill.com
 * endpoints. Bounded by a 1500 ms timeout. Errors of any kind return the
 * safe fallback so the studio never amber-flashes on user wifi blips.
 */
export declare function computePlatformHealth(opts?: {
    fetchImpl?: typeof fetch;
    /** Test-only: bypass the in-memory cache. */
    skipCache?: boolean;
}): Promise<PlatformHealth>;
/** Test hook — clear the 30 s cache so the next buildAgentsResponse() re-scans. */
export declare function resetAgentPresenceCache(): void;
interface BuildAgentsOptions {
    /** Project root (typically eval-server cwd). */
    root: string;
    /** Override home dir (primarily for tests / fixture homes). */
    home?: string;
    /** Agents whose CLI binary is on PATH — optional; callers may pre-detect. */
    detectedBinaries?: Set<string>;
}
/**
 * Build the /api/agents response. Filters to agents with presence and
 * includes per-agent counts, resolved paths, and shared-folder grouping.
 *
 * Results are cached for 30s keyed by `(root, home, binaries)` so repeated
 * polls don't re-walk the filesystem.
 */
export declare function buildAgentsResponse(opts: BuildAgentsOptions): Promise<AgentsResponse>;
export interface SkillScopeFilter {
    scope?: string;
    agent?: string;
}
export declare function filterSkillsByScopeAndAgent<T extends SkillInfo>(skills: T[], filter: SkillScopeFilter): T[];
export declare function extractDescription(skillContent: string): string;
export interface SkillMetadataFields {
    description: string | null;
    version: string | null;
    category: string | null;
    author: string | null;
    license: string | null;
    homepage: string | null;
    tags: string[] | null;
    deps: string[] | null;
    mcpDeps: string[] | null;
    entryPoint: string | null;
    lastModified: string | null;
    sizeBytes: number | null;
    sourceAgent: string | null;
    /** 0737 — Canonical https:// URL of the source GitHub repo, derived from
     *  vskill.lock (`sourceRepoUrl` or legacy `source: github:owner/repo`).
     *  Drives the source-file anchor on the Studio detail header. */
    repoUrl: string | null;
    /** 0737 — Relative path inside the repo to the SKILL.md (e.g.
     *  "skills/foo/SKILL.md"). Defaults to "SKILL.md" for flat-layout
     *  installs derived from a legacy `github:` source string. */
    skillPath: string | null;
    /** Env-var names this skill expects (purposes/hints live in `.env.example` comments). */
    secrets: string[] | null;
    /** Language runtime declaration (Python and/or Node.js). */
    runtime: {
        python: string | null;
        pip: string[] | null;
        node: string | null;
    } | null;
    /** Integration-test contract verified by `vskill check`. */
    integrationTests: {
        runner: "vitest" | "pytest" | "none";
        file: string | null;
        requires: string[] | null;
    } | null;
}
/**
 * Minimal YAML frontmatter parser — handles scalars and arrays (inline [a, b]
 * or YAML list form), folded scalars (`key: >` + indented continuation), and
 * the `metadata:` block. We intentionally avoid pulling gray-matter into the
 * eval-server bundle; SKILL.md frontmatter is a well-bounded subset.
 *
 * 0679: also recognizes the canonical agentskills.io shape where `tags` and
 * `target-agents` are nested under a `metadata:` block. Allow-listed children
 * of `metadata:` (see SURFACED_METADATA_KEYS) are surfaced both as top-level
 * keys (`fm.tags`) AND under `metadata.<key>` (e.g., `fm.metadata.tags`), so
 * existing consumers that read `fm.tags` keep working without changes. Other
 * metadata children stay nested-only. If a SKILL.md somehow has BOTH a
 * top-level `tags:` AND a `metadata.tags:` (hand-edited transitional file),
 * the top-level value wins — explicit beats nested.
 */
export declare function parseSkillFrontmatter(content: string): Record<string, string | string[] | Record<string, string | string[]>>;
/**
 * Derive the owning agent id for an installed skill by matching its first
 * relative path segment against AGENTS_REGISTRY.localSkillsDir. Returns null
 * for `origin="source"` or if no registry entry matches.
 */
export declare function deriveSourceAgent(skillDir: string, root: string, origin: "source" | "installed"): string | null;
import { parseGithubRemote, walkUpForGitRoot, detectAuthoredSourceLink, resolveSourceLink, readCopiedSkillSidecar, resetAuthoredSourceLinkCache, resetCopiedSkillSidecarCache } from "./source-link.js";
export { parseGithubRemote, walkUpForGitRoot, detectAuthoredSourceLink, resolveSourceLink, readCopiedSkillSidecar, resetAuthoredSourceLinkCache, resetCopiedSkillSidecarCache, };
/**
 * Build the T-025 metadata payload for a single skill. Reads SKILL.md from
 * disk if present; returns EMPTY_METADATA on any error so the /api/skills
 * response never fails because of a single bad skill.
 */
export declare function buildSkillMetadata(skillDir: string, origin: "source" | "installed", root: string): SkillMetadataFields;
/**
 * 0682 F-001 — Test helper. Resets `currentOverrides` to the default and
 * clears the `studioLoaded` flag so subsequent /api/config calls re-attempt
 * loadStudioSelection. Production code never needs this; it exists solely so
 * vitest can simulate a fresh server boot per-case.
 */
export declare function resetStudioRestoreState(): void;
interface ModelOption {
    id: string;
    label: string;
    pricing?: {
        prompt: number;
        completion: number;
    };
    resolvedId?: string;
}
export declare const PROVIDER_MODELS: Record<ProviderName, ModelOption[]>;
type OpenRouterCacheEntry = {
    value: Array<{
        id: string;
        name: string;
        contextWindow?: number;
        /** USD per 1M tokens (canonical wire unit; converted from per-token at ingestion). */
        pricing: {
            prompt: number;
            completion: number;
        };
    }>;
    fetchedAt: number;
};
export declare const OPENROUTER_CACHE: Map<string, OpenRouterCacheEntry>;
export declare function evictOldestOpenRouterCacheIfFull(): void;
export declare function resetOpenRouterCache(): void;
/** Test hook: clear all probe caches so the next detectAvailableProviders() re-probes. */
export declare function resetDetectionCache(): void;
/**
 * Detection block — surfaces wrapper-folder presence and binary availability
 * so the UI can render accurate "installed" dots and "install me" CTAs.
 *
 * Shape is part of the /api/config response (the frontend types.ts is
 * read-only per the 0682 ownership boundary, so the field is carried as
 * opaque JSON and consumed by useAgentCatalog via its own typing).
 */
export interface DetectionInfo {
    wrapperFolders: Record<string, boolean>;
    binaries: Record<string, boolean>;
}
export declare function resetProjectDetectionCache(): void;
/**
 * Scan the project root for known agent wrapper folders and the system
 * PATH for known agent binaries. Cheap synchronous scan (`existsSync` +
 * `which`) cached for 30 s so repeated `/api/config` polls don't burn CPU.
 */
export declare function detectProjectAgents(root: string): DetectionInfo;
export declare function resolveClaudeCodeModel(): string | null;
export declare function detectAvailableProviders(): Promise<Array<{
    id: ProviderName;
    label: string;
    available: boolean;
    models: ModelOption[];
    resolvedModel?: string | null;
}>>;
export declare function registerRoutes(router: Router, root: string, projectName?: string): void;
