import { type IntegrationAgent } from "./agent-adapters.js"; import { type DiscoveryDirectory } from "./agent-discovery-directories.js"; import { type CodexReviewedHookSource } from "./codex-hook-mcp-dependencies.js"; import { CLAUDE_ORPHAN_MARKER_MODE } from "./claude-plugin-cache-marker.js"; import { type NativeDiscoveryWitnessTolerance } from "./native-discovery-witness-change.js"; import { type ManagedPluginRegistrationWitness } from "./plugin-discovery.js"; import { type CodexHookDiscoveryRecovery } from "./codex-hook-discovery-recovery.js"; import { type NarrowedWitnessLedger } from "./narrowed-witness-ledger.js"; import { type CodexPluginSkillControl, type CodexPluginSourceInput } from "./codex-plugin-skill-controls.js"; import { type RetainedReviewArtifact, type ReviewedArtifact } from "./retained-review-artifacts.js"; import { type CodexSemanticCacheWitness, type CodexSemanticCacheAppOnlyParent, type CodexSemanticCacheReviewedHookParent } from "./codex-semantic-cache-witness.js"; export { captureDiscoveryDirectories, type DiscoveryDirectory } from "./agent-discovery-directories.js"; export interface DiscoverySource { reviewArtifact?: RetainedReviewArtifact; path: string; sha256: string | null; hashMode?: "bytes" | "path-bytes" | "claude-plugin-orphaned-at-v1" | "claude-plugin-manifest-v1" | "claude-plugin-registry" | "claude-marketplace-registry" | "claude-settings-v1" | "claude-settings-v2" | "claude-settings-v3" | "claude-settings-v4" | "claude-settings-v5" | "claude-marketplace-registry-v2" | "codex-settings-v1" | "codex-settings-v2" | "codex-settings-v3" | "codex-settings-v4" | "codex-settings-v5" | "codex-settings-v6" | "codex-settings-v7" | "codex-settings-v8" | "executable-v1" | "sumi-settings-v1" | "claude-marketplace-entry-v1"; hookSources?: CodexReviewedHookSource[]; managedPlugins?: ManagedPluginRegistrationWitness[]; format?: "json" | "toml" | "yaml"; fields?: string[]; marketplace?: string; plugin?: string; } export interface CodexSemanticCacheDiscovery { schema: "hasna.codex-semantic-cache-discovery.v1"; configPath: string; hookRootAlias: { alias: string; target: string; } | null; witness: CodexSemanticCacheWitness; appOnlyParents: CodexSemanticCacheAppOnlyParent[]; reviewedHookParents?: CodexSemanticCacheReviewedHookParent[]; previousPolicySha256: string; supersededSources: DiscoverySource[]; supersededDirectories: DiscoveryDirectory[]; } export interface AgentDiscoveryBinding { codexSemanticCache?: CodexSemanticCacheDiscovery; agent: IntegrationAgent; roots: string[]; sources: DiscoverySource[]; directories?: DiscoveryDirectory[]; method: "automatic" | "reviewed"; builtinNames?: string[]; codexDisabledPluginSkills?: CodexPluginSkillControl[]; codexRetiredMaterializations?: { roots: string[]; parents?: string[]; directories: Array; }; codexInstallationInputs?: { version: string; catalogSha256: string; plugins: CodexPluginSourceInput[]; directories?: DiscoveryDirectory[]; }; } /** An environment gap, not drift: the runtime a review saw cannot be resolved * from this process, so its discovery cannot be re-derived. Callers keep it * blocking and must not report it as NATIVE_SKILL_DRIFT. */ export declare const DISCOVERY_ROOT_UNRESOLVED = "DISCOVERY_ROOT_UNRESOLVED"; export declare function discoveryRootUnresolved(agent: IntegrationAgent, command: string, detail: string): Error; export declare function isDiscoveryRootUnresolved(error: unknown): error is Error; /** A native configuration Skills cannot resolve. The message names the * --discovery-inputs option of the native commands that accept it (hook * install, migrate native). Portable authoring takes no such option and * rewrites the remedy from these fields: `reviewable` marks a hook, plugin hook * or plugin option check that a current discovery review satisfies, and * `source` names the configuration or hook file it checked (a path only). */ export declare class NativeDiscoveryUnresolved extends Error { readonly agent: IntegrationAgent; readonly detail: string; source?: string | undefined; reviewable: boolean; constructor(agent: IntegrationAgent, detail: string, source?: string | undefined); } /** The runtime executable a discovery review resolved through PATH, with the * realpath its launcher led to. The policy stores it beside the binding * (bridge.discoveryExecutables), not inside it, so a consumer that compares * stored bindings keeps the shape it already knows. */ export interface DiscoveryExecutable { command: string; path: string; target: string; } /** Resolve the agent's runtime command through this process's PATH: the * executable this process would actually run. */ export declare function discoveryExecutable(agent: IntegrationAgent): DiscoveryExecutable | null; /** Check a recorded executable by its exact path, ignoring PATH. Null when the * path no longer resolves (missing, dangling, ENOTDIR, EACCES). */ export declare function recordedDiscoveryExecutable(agent: IntegrationAgent, recorded: DiscoveryExecutable): DiscoveryExecutable | null; export interface ReviewedDiscoveryInputs { version: 1; agents: Array<{ agent: IntegrationAgent; roots: string[]; sources: DiscoverySource[]; reviewArtifacts?: ReviewedArtifact[]; directories?: DiscoveryDirectory[]; pluginHooks: "reviewed-no-skill-injection"; }>; } /** Project one native configuration's witnessed fields, exactly as discovery * binds them. Used for both the current file and a preserved reviewed preimage. */ export declare function projectNativeDiscoveryFields(text: string, format: "json" | "toml" | "yaml", fields: readonly string[], path: string): string; /** Codex name reconcile only, after the caller verified that every enrolled * plugin parent in `parents` kept its reviewed capability tuple (manifest apart * from its version, app, MCP and remote receipt). A stale full-byte witness of a * manifest, app or MCP declaration or skill document under one of those parents' * version roots is replaced, in its own digest mode, by the same role's file in * every current version root. Every other witness is kept unchanged, so any * other change still refuses when the rebased binding is verified. */ export declare function rebaseCodexEnrolledCacheWitnesses(binding: AgentDiscoveryBinding, cache: string, parents: readonly string[], strictlySkillsOnly: (parent: string) => boolean): { binding: AgentDiscoveryBinding; rebased: string[]; }; /** Called only after the owning planner validated discovery and capabilities. * New roots must already be body-free; absent roots need the prior typed proof. */ export declare function captureRetiredCodexDiscovery(binding: AgentDiscoveryBinding, controls: CodexPluginSkillControl[], rules: unknown): AgentDiscoveryBinding; /** The witness class that may keep its reviewed digest beneath a positively * verified absent root: a full byte witness, the installer's full manifest * projection or a present version-root orphan marker. Null for every other * source, which must stay current. */ export type RetainedAbsentWitness = "bytes" | "claude-plugin-manifest-v1" | typeof CLAUDE_ORPHAN_MARKER_MODE; /** Only native capability locations covered by the complete typed cache census * qualify. Historical sources remain stored; arbitrary missing files do not. */ export declare function codexSemanticCacheSourceRole(source: DiscoverySource, cacheRoot: string, parents: readonly string[], hookParents?: readonly string[]): boolean; export declare function codexSemanticCacheDirectoryRole(path: string, cacheRoot: string): boolean; export declare function assertCodexSemanticCacheHookSafety(cacheRoot: string, parents: readonly string[], configPath: string, hookRootAlias?: CodexSemanticCacheDiscovery["hookRootAlias"]): void; /** Source-byte and directory-membership drift are NativeDiscoveryWitnessChange * errors. Only the live Codex prompt hook passes `witnessTolerance`; a change it * accepts as a vendor refresh is collected and the remaining checks still run. * Only the live hooks pass `narrowed`: a legacy full-file settings witness that * no longer matches is still current when the narrowed digest recorded for it * matches (see narrowed-witness-ledger.ts), and a matching one is observed. * Every other change and every other failure throws as before. */ export declare function verifyAgentDiscovery(binding: AgentDiscoveryBinding, codexRecovery?: CodexHookDiscoveryRecovery, reviewedRootAliases?: readonly { agent: IntegrationAgent; alias: string; target: string; }[], witnessTolerance?: NativeDiscoveryWitnessTolerance, narrowed?: NarrowedWitnessLedger): void; /** One stored Claude discovery source as an installer sees it. */ export type ClaudeDiscoverySourceVerdict = { status: "current"; } | { status: "retained-absent"; root: string; witness: RetainedAbsentWitness; } | { status: "drift"; reason: "MISSING" | "APPEARED" | "CHANGED" | "MARKER_INVALID" | "REFUSED"; }; /** Read-only, per-source report on a stored Claude discovery binding, in * stored order. A source is retained only through the same absent retired * version rule and predicate verifyAgentDiscovery applies; a refused rule * retains nothing. Every other source is checked by its own witness, exactly * as verification checks it (a typed orphan marker by the marker predicate). * This report never accepts a binding by itself: a caller must also require * verifyAgentDiscovery to accept the same binding. */ export declare function classifyClaudeDiscoverySources(binding: AgentDiscoveryBinding): ClaudeDiscoverySourceVerdict[]; export declare function rebindAgentDiscovery(binding: AgentDiscoveryBinding, changes: Map): AgentDiscoveryBinding; /** Explicit streaming integrity witness. Never read an executable as text or execute it. */ export declare function captureDiscoveryExecutableSources(paths: string[]): DiscoverySource[]; /** Capture exact source bytes, or typed Claude cache marker presence; never execute them. */ export declare function captureDiscoveryByteSources(paths: string[]): DiscoverySource[]; /** Capture executable/source path identity, including links and absent targets. */ export declare function captureDiscoveryPathSources(paths: string[]): DiscoverySource[]; /** Top-level keys whose presence, at any value, makes a project Claude settings * file a higher-precedence discovery source that needs review. Claude 2.1.300 * rewrites `additionalMarketplaces` into `extraKnownMarketplaces` on every * settings read, including local settings, so the alias counts as well. */ export declare const CLAUDE_PROJECT_DISCOVERY_KEYS: readonly ["enabledPlugins", "extraKnownMarketplaces", "additionalMarketplaces", "skillOverrides"]; /** Project settings can introduce a higher-precedence discovery source. Until * its native merge format is supported, refuse that layer rather than certify * the home-only inventory. Ordinary unrelated project settings remain usable. */ export declare function assertProjectDiscovery(agent: IntegrationAgent, directories: string[], home: string, canonical?: (path: string) => string, reviewed?: AgentDiscoveryBinding): void; /** Resolve configured plugin discovery without starting an agent or loading a plugin. * Unknown runtime registrations require explicit reviewed inputs, never a cache guess. */ export declare function agentDiscoveryConfigPath(home: string, agent: IntegrationAgent): string; /** Re-derive an automatic binding and compare it with the stored one. A * mismatch is drift, except when the only difference is a runtime this process * cannot resolve: then it is DISCOVERY_ROOT_UNRESOLVED, which stays blocking. * Only the live Codex prompt hook passes `witnessTolerance`: when roots, method * and every source and directory path are unchanged, only witness digests differ * and the tolerance accepts every one of them, they are collected instead of * refusing. */ export declare function verifyAutomaticDiscoveryClosure(binding: AgentDiscoveryBinding, options: { home: string; canonical: (path: string) => string; change: string; executable?: DiscoveryExecutable; witnessTolerance?: NativeDiscoveryWitnessTolerance; }): void; /** True only when the changed Codex config.toml differs from its reviewed * witness by appended vendor disable rows and/or vendor plugin disables: * removing those entries or restoring a formerly enabled vendor flag reproduces * the stored digest. Witness modes * without a replacement digest (V6, artifacts, managed registries) stay strict. */ export declare function codexVendorConfigChangeOnly(source: DiscoverySource, cache: string): boolean; /** Whether replacing `path` with `text` leaves every recorded witness of it * satisfied, judged by each source's own digest mode without touching the file, * with the same screen-reader receipt tolerance typed V1-V5 verification applies. * Fails closed: a review artifact, managed-plugin or hook-source witness, a * semantic cache binding of the file, or an unsupported mode counts as changed. */ export declare function discoveryTextKeepsWitness(binding: Pick, path: string, text: string): boolean; /** `executable` is the agent's runtime: omitted, it is resolved through PATH; * a value (or null for none) is used as given, so verification never depends * on the caller's PATH. */ type DiscoveryOptions = { home: string; agent: IntegrationAgent; reviewed?: ReviewedDiscoveryInputs; retainedReview?: AgentDiscoveryBinding; canonical?: (path: string) => string; executable?: DiscoveryExecutable | null; }; export declare function resolveAgentDiscovery(options: DiscoveryOptions): AgentDiscoveryBinding; /** Read-only exclusion, not native admission. Retained roots remain excluded, * while current supported controls are re-derived even when old settings or * directory witnesses are stale. Non-enumerable executable inputs still need * their existing review. No witness, policy or enrollment is written. */ export declare function resolveAgentDiscoveryExclusionRoots(options: Omit & { retained?: AgentDiscoveryBinding; narrowed?: NarrowedWitnessLedger; nativeHome?: string; managedHook?: ManagedBridgeHook; }): readonly string[]; /** Metadata-only closure of aliases inside the selected native discovery * trees. Never search the account generally or load a payload/plugin. Each * resolved alias remains excluded while unrelated portable paths stay usable. */ export declare function nativeDiscoveryAliasTargets(roots: readonly string[], home: string): string[]; /** The Skills bridge command and selection profile the policy records for an * agent (`bridge.commands` and `bridge.profiles`), from which hook install * renders its managed hook commands. */ export interface ManagedBridgeHook { command: string; profile: string; supervisor?: { path: string; runtime: string; sha256: string; }; }