import type { Result, ResultAsync } from './consumer-neverthrow.js';

export interface RedactedCause {
	readonly safeMessage: string;
	readonly safeStack?: string;
}
export type CatalogError = {
	readonly type: "CATALOG_MODULE_NOT_FOUND";
	readonly path: string;
} | {
	readonly type: "CATALOG_MODULE_LOAD_FAILED";
	readonly path: string;
	readonly cause: RedactedCause;
} | {
	readonly type: "CATALOG_MODULE_OUTSIDE_ROOT";
	readonly path: string;
	readonly resolvedPath: string;
} | {
	readonly type: "CATALOG_MODULE_WORLD_WRITABLE";
	readonly path: string;
	readonly mode: number;
	readonly offender: "file" | "ancestor";
	readonly ancestorPath?: string;
} | {
	readonly type: "CATALOG_MODULE_INVALID_SHAPE";
	readonly path: string;
	readonly reason: string;
} | {
	readonly type: "CATALOG_VERSION_MISMATCH";
	readonly path: string;
	readonly expected: number;
	readonly actual: unknown;
} | {
	readonly type: "CATALOG_FETCH_FAILED";
	readonly phase: "specs" | "suites";
	readonly cause: RedactedCause;
} | {
	readonly type: "CATALOG_FETCH_TIMEOUT";
	readonly phase: "specs" | "suites";
	readonly timeoutMs: number;
} | {
	readonly type: "CATALOG_RESULT_TOO_LARGE";
	readonly phase: "specs" | "suites";
	readonly count: number;
	readonly limit: number;
} | {
	readonly type: "CATALOG_SPEC_CONTENT_REJECTED";
	readonly kind: "spec" | "suite";
	readonly id: string;
	readonly reason: string;
} | {
	readonly type: "CATALOG_DUPLICATE_ID";
	readonly kind: "spec" | "suite";
	readonly id: string;
} | {
	readonly type: "CATALOG_INVALID_ID";
	readonly kind: "spec" | "suite";
	readonly id: string;
} | {
	readonly type: "CATALOG_CACHE_WRITE_FAILED";
	readonly path: string;
	readonly cause: RedactedCause;
} | {
	readonly type: "CATALOG_CACHE_CLEANUP_FAILED";
	readonly path: string;
	readonly cause: RedactedCause;
};
export declare function redactCause(value: unknown): RedactedCause;
export type SpecId = string & {
	readonly __brand: "SpecId";
};
export type SuiteId = string & {
	readonly __brand: "SuiteId";
};
export interface SpecStep {
	readonly index: number;
	readonly intent: string;
	readonly outcome?: string;
	readonly hint?: string;
	readonly isOptional: boolean;
}
export type SpecStatus = "draft" | "active" | "deprecated";
export interface Spec {
	readonly id: SpecId;
	readonly feature: string;
	readonly owner?: string;
	readonly status: SpecStatus;
	readonly tags: readonly string[];
	readonly requires: readonly string[];
	readonly links: readonly string[];
	readonly scenarioId?: string;
	readonly timeoutSeconds?: number;
	readonly setup: string;
	readonly steps: readonly SpecStep[];
	readonly assertions: readonly string[];
}
export interface CatalogSpec {
	readonly id: SpecId;
	readonly spec: Spec;
}
export declare const toSpecId: (value: string) => Result<SpecId, CatalogError>;
export declare const toSuiteId: (value: string) => Result<SuiteId, CatalogError>;
export interface FreestyleEntry {
	readonly prompt?: string;
	readonly title?: string;
	readonly timeoutSeconds?: number;
}
export interface HookConfig {
	readonly script: string;
	readonly env?: Record<string, string>;
	readonly timeoutSeconds?: number;
	readonly retries?: number;
}
export interface SuiteHooks {
	readonly beforeEach?: HookConfig;
}
export interface SuiteConfig {
	readonly specs: readonly string[];
	readonly freestyle: readonly FreestyleEntry[];
	readonly hooks?: SuiteHooks;
}
export interface CatalogSuite {
	readonly id: SuiteId;
	readonly config: SuiteConfig;
}
export declare const CATALOG_INTERFACE_VERSION: 1;
export interface Catalog {
	readonly catalogVersion: typeof CATALOG_INTERFACE_VERSION;
	getSpecs(): ResultAsync<readonly CatalogSpec[], CatalogError>;
	getSuites(): ResultAsync<readonly CatalogSuite[], CatalogError>;
}
export type SpecParseError = {
	type: "MALFORMED_FRONTMATTER";
	cause: unknown;
} | {
	type: "MISSING_SETUP_SECTION";
	suggestedHeading?: string;
} | {
	type: "MISSING_STEPS_SECTION";
	suggestedHeading?: string;
} | {
	type: "EMPTY_STEPS_SECTION";
};
export declare function parseSpecShared(raw: string): Result<{
	readonly spec: Spec;
	readonly frontmatter: Record<string, unknown>;
}, SpecParseError>;

export {};
