import { DetectedStack, ToolRequirement } from '../../types';
/**
 * Shared Python venv location for graphify specifically. Graphify is a
 * Python *library* that our graphify.ts subprocess imports directly,
 * not a CLI tool — so it needs a stable venv-relative path we can spawn
 * from, unlike the CLI tools which are better served by pipx (see
 * below).
 *
 * Lives under `~/.cache/dxkit/` so it survives `/tmp` cleanup. Previously
 * `/tmp/graphify-venv` (D013's "~50% flake" was the cleanup + concurrent-
 * run race on first install). `.cache/` is XDG-compliant and persistent;
 * `test -d` in the shell install commands keeps creation idempotent.
 */
export declare const TOOLS_VENV: string;
export interface ToolDefinition extends ToolRequirement {
    /** Binary name(s) to look for in PATH. First match wins. */
    binaries: string[];
    /** Extra absolute paths to probe (e.g. venv, system locations). */
    probePaths?: string[];
    /**
     * For tools that are node packages without a CLI binary (e.g. vitest
     * plugins). When set, detection checks for `node_modules/<pkg>/package.json`
     * instead of scanning PATH / .bin. Takes precedence over binary search.
     */
    nodePackage?: string;
    /**
     * For tools that are Ruby gems without a CLI binary (e.g. SimpleCov,
     * which is required from spec_helper.rb rather than invoked as a
     * command). When set, detection runs `gem list -i <name>` instead of
     * scanning PATH. Takes precedence over binary search. Mirrors the
     * `nodePackage` pattern. Library-only Ruby tools that DO ship a CLI
     * (rubocop, bundler-audit) should keep using `binaries: [...]`
     * instead — the CLI shim is what `findTool` is meant to discover.
     */
    gemPackage?: string;
    /** Platform-specific install commands. */
    installCommands: {
        macos?: string;
        linux?: string;
        windows?: string;
    };
    /** Command that prints version info (used to verify tool works). */
    versionCheck?: string;
    /**
     * Optional applicability gate. Returns a short human-readable reason
     * string when the tool is NOT applicable to the project at `cwd`
     * (e.g. `@vitest/coverage-v8` on a mocha-based repo). Returns null
     * when the tool IS applicable — detection then proceeds normally.
     *
     * The gate runs BEFORE binary/probe lookup so non-applicable tools
     * never get reported as "missing." The CLI surfaces them as "n/a"
     * with the reason string and excludes them from missing-count math
     * so customers don't chase a non-fixable warning.
     */
    applicabilityGuard?: (cwd: string) => string | null;
}
export interface ToolStatus {
    name: string;
    available: boolean;
    path: string | null;
    version: string | null;
    source: 'path' | 'brew' | 'npm-g' | 'pipx' | 'cargo' | 'go' | 'probe' | 'missing' | 'n/a';
    requirement: ToolDefinition;
    /**
     * Populated when `source === 'n/a'`. Carries the reason from the
     * applicabilityGuard so renderers can show e.g. "no vitest in this
     * repo" alongside the n/a status.
     */
    notApplicableReason?: string;
}
/**
 * Find a tool across multiple installation methods.
 * Returns the first matching absolute path, or null.
 */
export declare function findTool(def: ToolDefinition, cwd?: string): ToolStatus;
/** Get the install command for the current platform. */
export declare function getInstallCommand(def: ToolDefinition): string;
/**
 * Environment overlay that redirects an install into the user's
 * configured `.dxkit/tools.json:installDir`. Empty when no install dir
 * is set. We set every ecosystem's bin-dir variable at once — each is a
 * no-op for the ecosystems an install doesn't touch — rather than
 * parsing the install command to guess which package manager runs:
 *
 *   - `PIPX_BIN_DIR`       → pipx-installed app binaries
 *   - `npm_config_prefix`  → npm -g (binaries under `<prefix>/bin`)
 *   - `CARGO_INSTALL_ROOT` → cargo install (binaries under `<root>/bin`)
 *   - `GOBIN`              → go install
 *
 * Passed as an `env` overlay to the install subprocess, so it works
 * identically on POSIX and Windows without shell-specific `VAR=val`
 * prefixing. `loadToolsConfig` already adds both `installDir` and
 * `installDir/bin` to the probe set, so the result is discoverable.
 */
export declare function getInstallEnv(cwd: string): Record<string, string>;
export declare const TOOL_DEFS: Record<string, ToolDefinition>;
/**
 * Build the list of tools required for a given detected stack.
 * This is the single source of truth for detect.ts's `requiredTools` field.
 */
export declare function buildRequiredTools(languages: DetectedStack['languages']): ToolRequirement[];
/** Check status of all required tools for a stack. */
export declare function checkAllTools(languages: DetectedStack['languages'], cwd?: string): ToolStatus[];
//# sourceMappingURL=tool-registry.d.ts.map