import { type Stats } from "fs"; import { type FileHandle } from "fs/promises"; import { type SetupTeamMode } from "../config/team-mode.js"; export declare const OMX_LOCAL_MARKETPLACE_NAME = "oh-my-codex-local"; export declare const OMX_PLUGIN_NAME = "oh-my-codex"; export declare const OMX_LOCAL_PLUGIN_CONFIG_KEY = "oh-my-codex@oh-my-codex-local"; export interface PackagedOmxMarketplace { marketplacePath: string; packageRoot: string; pluginRoot: string; pluginManifestPath: string; } export declare function resolvePackagedOmxMarketplace(packageRoot: string): Promise; interface DirectoryRef { handle: FileHandle; path: string; operationPath: string; scanOperationPath: string; mutationPath: string | null; } interface PluginCacheMutationTestHooks { beforeRename?: (sourcePath: string, destinationPath: string) => void | Promise; beforeMkdirExclusive?: (parentPath: string, name: string) => void | Promise; beforeExclusiveCreate?: (parentPath: string, name: string) => void | Promise; afterStagedFileRead?: (path: string, stats: Stats, bytes: Buffer) => void | Promise; beforeFinalClaimValidation?: (claimPath: string) => void | Promise; beforeCompleteMarker?: (claimPath: string) => void | Promise; beforeStaleLockReclaim?: (lockPath: string, stats: Stats) => void | Promise; beforeRemove?: (path: string, stats: Stats) => void | Promise; beforeRemoveSyscall?: (path: string, stats: Stats) => void | Promise; afterDestructiveCheck?: (path: string, stats: Stats) => void | Promise; } /** @internal Test seam for deterministic cache mutation interposition coverage. */ export declare function setPluginCacheMutationHooksForTest(hooks: PluginCacheMutationTestHooks | undefined): () => void; interface RemoveChildOptions { recursive?: boolean; emptyDirectory?: boolean; force?: boolean; allowInvalidClaimDigest?: boolean; preserveRecursive?: boolean; expectedManagedVersion?: string; preservedPaths?: string[]; beforeDestructiveRemove?: () => Promise; } export declare function readOmxPluginCacheFileNoFollow(path: string, options?: { requireSingleLink?: boolean; anchorDir?: string; }): Promise; export declare function registerOmxPluginCacheLivePin(pluginRoot: string, sessionId: string, ownerPid: number): Promise; export declare function computeOmxPluginCacheClaimDigest(root: string): Promise; export declare function packagedOmxPluginVersion(packagedMarketplace: PackagedOmxMarketplace): Promise; export declare function expectedPackagedOmxSkillNames(packagedMarketplace: PackagedOmxMarketplace, options?: { teamMode?: SetupTeamMode; }): Promise; export declare function omxPluginCacheBase(codexHomeDir: string): string; interface PublicationLockGuard { timer: NodeJS.Timeout; assertOwned: () => Promise; } export declare function removeChildIfIdentity(cacheBaseRef: DirectoryRef, childName: string, childStats: Stats, options: RemoveChildOptions): Promise; /** * #3552: executed assets Codex loads from the plugin cache must be regular files inside a * regular `hooks/` directory inside a regular snapshot root. `readFile`/content equality * follow symlinks to their external targets before any provenance check, so a symlinked * `` cache root or a symlinked executed asset (hooks/hooks.json, * hooks/codex-native-hook.mjs, hooks/omx-command.json) with byte-identical external * content could satisfy the unchanged fast paths while the executed bytes stayed * attacker-writable outside the managed namespace. Returns a human-readable reason when * provenance is broken (missing/symlinked/non-regular root, hooks dir, or asset), or * null when the snapshot's provenance is intact. Callers treat non-null as fail-closed. */ export declare function omxPluginCacheExecutedAssetProvenanceReason(cacheDir: string): Promise; export declare function omxPluginCacheProvenanceReason(cacheDir: string, packagedMarketplace: PackagedOmxMarketplace, expectedVersion?: string, options?: { teamMode?: SetupTeamMode; }): Promise; export declare function discoverOmxPluginCacheDirs(codexHomeDir: string): Promise; export interface OmxPluginCacheState { cacheDir: string; manifestVersion: string | null; skillsPointer: string | null; skillNames: string[] | null; hooksPointer: string | null; mcpServersPointer: string | null; appsPointer: string | null; hookLauncherPinned: boolean; } export declare function readOmxPluginCacheState(cacheDir: string, expectedVersion?: string): Promise; export declare function hasExpectedOmxPluginCache(codexHomeDir: string, packagedMarketplace: PackagedOmxMarketplace, options?: { teamMode?: SetupTeamMode; cacheDirOverride?: string; }): Promise; /** * Compares only plugin-scoped hook assets that Codex executes from the cache. * Manifest pointers and skill lists are validated by callers before using this * as a hook/launcher freshness predicate. * * #3552: the comparison is fail-closed about provenance — every executed asset * is lstat-validated as a regular file before it is read, so a symlinked asset * with byte-identical external content can no longer satisfy the unchanged * fast paths. `false` here means "do not trust this cache snapshot". */ export declare function pluginHookCacheMatchesPackaged(cacheDir: string, packagedMarketplace: PackagedOmxMarketplace): Promise; export interface OmxPluginCacheMaterializeResult { status: "unavailable" | "unchanged" | "materialized" | "stale-launcher"; cacheDir?: string; version?: string; retiredDirs?: string[]; preservedDirs?: string[]; reason?: string; launcherTarget?: string; removalSafe: boolean; } export declare const PLUGIN_LAUNCHER_RECOVERY_HINT = "omx setup --plugin --repair-plugin-cache"; export declare function getUntrustedOmxPluginCacheRecoveryHint(cacheDir: string): string; export declare function readPinnedLauncherRaw(cacheDir: string): Promise<{ raw: string | null; parsed: { command?: unknown; argsPrefix?: unknown; } | null; error?: string; }>; type LauncherIncompatibilityKind = "drift" | "incompatible"; export declare function getPinnedLauncherIncompatibilityReason(cacheDir: string, packagedMarketplace: PackagedOmxMarketplace): Promise<{ reason: string; target?: string; kind?: LauncherIncompatibilityKind; } | null>; export declare function retireUnpinnedManagedSnapshots(codexHomeDir: string, currentVersion: string, anchoredCacheBaseRef?: DirectoryRef, publicationLockHeld?: boolean, preservedDirs?: string[], heldPublicationLockGuard?: PublicationLockGuard): Promise; interface MaterializePackagedOmxPluginCacheOptions { dryRun?: boolean; repairCache?: boolean; teamMode?: SetupTeamMode; onCacheDirPrepared?: (cacheDir: string) => void | Promise; anchoredCacheBaseRef?: DirectoryRef; anchoredCacheDir?: string; cacheDirOverride?: string; } export declare function materializePackagedOmxPluginCache(codexHomeDir: string, packagedMarketplace: PackagedOmxMarketplace | null, options?: MaterializePackagedOmxPluginCacheOptions): Promise; export declare function stripLocalOmxMarketplaceRegistration(config: string): string; export declare function buildLocalOmxMarketplaceRegistration(packageRoot: string): string; export declare function upsertLocalOmxMarketplaceRegistration(config: string, packageRoot: string): string; export declare function hasLocalOmxPluginEnablement(config: string): boolean; export declare function hasLocalOmxPluginMcpServerRegistrations(config: string): boolean; export declare function stripLocalOmxPluginMcpServerRegistrations(config: string): string; export declare function upsertLocalOmxPluginEnablement(config: string): string; export declare function upsertLocalOmxPluginMcpServerEnablement(config: string, enabled: boolean, options?: { removeWhenDisabled?: boolean; }): string; export {}; //# sourceMappingURL=plugin-marketplace.d.ts.map