/**
 * Framework detection — extracted from bin.ts so it can run twice:
 *
 *   1. Once at startup, against the user's initial `installDir`
 *      (cwd or `--install-dir <path>`).
 *   2. Again whenever the IntroScreen user picks "Change directory" and
 *      points the wizard at a different tree. We can't ship a real
 *      "what directory should I instrument?" prompt without this — the
 *      old behavior was to bail out and ask the user to re-run with a
 *      flag, which is the exact CLI anti-pattern the v1 fix was
 *      trying to address.
 *
 * The detection task itself was duplicated inline inside bin.ts. Now
 * both call sites share this helper and stay in sync.
 *
 * Cancellation: the IntroScreen flow can fire detection multiple times
 * in quick succession (user retypes the path, hits Enter, types another
 * one). Each call gets a fresh `AbortSignal`; pass it down so a stale
 * detection can't race a fresh one and stomp on `frameworkConfig` with
 * the wrong result. Detection is read-only fs work — aborting just
 * means we discard the result.
 */
import { type DetectionResult } from '../run.js';
import type { FrameworkConfig } from './framework-config.js';
import type { WizardSession } from './wizard-session.js';
import type { Integration } from './constants.js';
import type { DiscoveredFeature } from './wizard-session.js';
/**
 * Structural store interface used by this helper.
 *
 * Defined inline so the lib layer doesn't import from `ui/tui/store`.
 * The real `WizardStore` matches this shape; tests can pass any object
 * that does. Keeping the dependency direction one-way (ui → lib, never
 * the reverse) avoids ESM resolution headaches and keeps the helper
 * usable from non-TUI contexts (CI, agent mode, future apply command).
 */
export interface DetectionTargetStore {
    /** Live view of the wizard session state. */
    readonly session: WizardSession;
    setFrameworkContext(key: string, value: unknown): void;
    setFrameworkConfig(integration: Integration | null, config: FrameworkConfig | null): void;
    setDetectedFramework(label: string): void;
    setDetectionResults(results: DetectionResult[]): void;
    addDiscoveredFeature(feature: DiscoveredFeature): void;
    autoEnableInlineAddons(source: 'auto-tui' | 'auto-ci' | 'auto-agent'): void;
    setDetectionComplete(): void;
    subscribe(listener: () => void): () => void;
}
export interface RunFrameworkDetectionOptions {
    /**
     * Cancellation signal. When aborted before detection completes, the
     * helper resolves WITHOUT mutating the store — used so a re-run
     * triggered by the user picking a different directory doesn't have
     * the previous run's `setDetectionComplete()` fire after it.
     */
    signal?: AbortSignal;
}
/**
 * Run detection + per-framework `gatherContext` + feature discovery and
 * mirror the results into the store. Idempotent — safe to call twice
 * for the same `installDir`. The helper returns when detection is
 * complete OR when the abort signal fires, whichever comes first.
 *
 * The store mutations performed (in order):
 *   - `session.detectionResults = results`
 *   - `setFrameworkContext(...)` for each gathered context key
 *   - `setFrameworkConfig(integration, config)` if a framework matched
 *   - `setDetectedFramework(label)` for the friendly label
 *   - `addDiscoveredFeature(...)` for each opt-in addon
 *   - `autoEnableInlineAddons('auto-tui')`
 *   - `setDetectionComplete()` exactly once at the end
 *
 * The returned promise resolves with the raw detection results so
 * callers can log them. On abort, resolves with whatever results were
 * collected before the signal fired.
 */
export declare function runFrameworkDetection(store: DetectionTargetStore, installDir: string, options?: RunFrameworkDetectionOptions): Promise<DetectionResult[]>;
