/**
 * Filters for `agents secrets list`.
 *
 * The listing had no filtering at all: `--device`/`--device` pick a machine and
 * `--json` picks a format, but nothing selected over the bundles themselves. On
 * a fleet with fifty-odd bundles the answerable questions — which ones read with
 * no Touch ID at all, which hold a raw literal, which have already expired, what
 * has not been touched in three months — meant piping the table through grep, or
 * were simply unanswerable.
 *
 * Everything here is pure: parsing produces a `SecretsListFilter`, and
 * `bundleMatchesFilter` is a predicate over a bundle plus the ambient facts it
 * cannot derive itself (which bundles the broker currently holds, and the
 * current time). That keeps the whole surface unit-testable without a keychain.
 *
 * Shape follows the `agents sessions` house style: comma-separated lists, an
 * unknown value is a loud error naming the valid set (never a silent ignore),
 * and every axis narrows independently so they AND-compose.
 */
import { type SecretsBundle, type SecretsPolicy, type SecretsBackend, type SecretType } from './bundles.js';
/** Ref kinds a var's value can have, from `describeBundle`. */
export declare const REF_KINDS: readonly ["literal", "keychain", "env", "file", "exec"];
export type RefKind = typeof REF_KINDS[number];
/** Default window for `--expiring` with no argument — matches the EXPIRING column. */
export declare const DEFAULT_EXPIRING_DAYS = 30;
/** A parsed, validated filter. Every field is optional; absent ⇒ that axis does
 * not narrow. All present axes must match (AND). */
export interface SecretsListFilter {
    /** Case-insensitive substring over bundle name and description. */
    query?: string;
    policy?: SecretsPolicy[];
    backend?: SecretsBackend[];
    type?: SecretType[];
    kind?: RefKind[];
    /** true ⇒ only bundles the broker holds; false ⇒ only those it does not. */
    held?: boolean;
    /** Only bundles with at least one var whose `expires` is already past. */
    expired?: boolean;
    /** Only bundles with at least one var expiring within this many days. */
    expiringDays?: number;
    /** Only bundles whose `last_used` is older than this epoch-ms (or never used). */
    unusedBefore?: number;
}
/** The raw option bag commander hands us. */
export interface SecretsListFilterOpts {
    policy?: string;
    backend?: string;
    type?: string;
    kind?: string;
    held?: boolean;
    notHeld?: boolean;
    expired?: boolean;
    expiring?: string | boolean;
    unused?: string;
}
/**
 * Validate one comma-separated enum list. An unknown value throws and names the
 * whole valid set — a silent ignore would let `--policy hodl` quietly return
 * every bundle, which reads as "nothing matches that" and is worse than an error.
 * Values are lowercased, matching `parsePolicyOpt`'s handling of policy names.
 */
export declare function parseEnumList<T extends string>(raw: string, flag: string, valid: readonly T[]): T[];
/** Build a validated filter from commander's option bag. Throws on bad input. */
export declare function parseListFilters(opts: SecretsListFilterOpts, query?: string): SecretsListFilter;
/** True when any axis is set — used to decide whether the empty state should
 * explain itself rather than claim there are no bundles at all. */
export declare function filterIsActive(f: SecretsListFilter): boolean;
/** Expiry tallies for one bundle: how many vars are already past, and how many
 * fall due within `withinDays`. */
export declare function bundleExpiry(b: SecretsBundle, now: number, withinDays?: number): {
    expired: number;
    soon: number;
};
/** Ambient facts a bundle can't answer about itself. */
export interface FilterContext {
    /** Bundle name → hold expiry epoch-ms, from the broker. Empty off macOS. */
    held: Map<string, number>;
    now: number;
}
/** Does this bundle satisfy every set axis? Pure. */
export declare function bundleMatchesFilter(b: SecretsBundle, f: SecretsListFilter, ctx: FilterContext): boolean;
/** Sort fields for `--sort`. `name` is the default and matches `listBundles()`.
 * `used` is most-recently-used first and `uses` is most-frequently-accessed
 * first; both read the value-free usage read-model (lib/secrets/usage-db.ts). */
export declare const SORT_FIELDS: readonly ["name", "used", "uses", "created", "updated", "expiry"];
export type SortField = typeof SORT_FIELDS[number];
/**
 * The two value-free usage facts `--sort used|uses` needs, keyed by bundle name.
 * Kept as a minimal shape (not the full BundleUsageSummary) so this module stays
 * pure and unit-testable without opening the SQLite read-model.
 */
export interface BundleUsageHint {
    /** Most recent recorded event across all kinds, ISO 8601, or null. */
    lastUsedAt: string | null;
    /** Recorded `access` (read/inject) count — what `--sort uses` ranks on. */
    uses: number;
}
export declare function parseSortField(raw: string | undefined): SortField;
/** Sort a copy. Time fields are most-recent-first (the useful direction for
 * "what did I touch lately"); `uses` is most-frequently-accessed first; `expiry`
 * is soonest-first; ties fall back to name so the order is stable. `usage`
 * carries the value-free read-model facts `used`/`uses` rank on — when omitted,
 * `used` falls back to the throttled `last_used` stamp and `uses` sees zero. */
export declare function sortBundles(bundles: SecretsBundle[], field: SortField, usage?: Map<string, BundleUsageHint>): SecretsBundle[];
/** Human summary of the active filters, for the empty state. `sessions` only
 * echoes --project/--all on a miss, which leaves you guessing which flag emptied
 * the list; naming every active axis is the difference between "nothing matched"
 * and knowing what to relax. */
export declare function describeFilter(f: SecretsListFilter): string;
