import type { EspFlashSelection } from "../../domain/firmware/espFlashLocation.js"; import type { InvestigationRecordPort } from "../investigation/InvestigationRecordPort.js"; import type { RecoveryAdmission } from "../investigation/InvestigationRetention.js"; import type { ResetInvestigationReceipt } from "../../domain/investigationLifecycle.js"; import type { ExecutableFormatHint } from "../../domain/dosCom.js"; import type { BinaryArchitecture, BinaryTarget, } from "../../domain/binaryTargetTypes.js"; import type { JsonValue } from "../../domain/jsonValue.js"; import type { AnalysisSnapshot } from "../../domain/analysisSnapshot.js"; import type { AnalysisProfileCommitment } from "../../domain/analysisProfile.js"; import type { AnalysisProviderSelector } from "../../domain/providerSelection.js"; import type { BinarySessionDetail } from "../../contracts/sessionStatusContract.js"; import type { AnalysisError } from "../../domain/analysisErrorBase.js"; import type { AnalysisCleanupRetry } from "../../domain/analysisErrorRecovery.js"; import type { Result } from "../../domain/result.js"; import type { EvidenceIntegrityError } from "../../domain/evidenceErrors.js"; import type { AnalysisSnapshotLoader } from "./BinarySessionOpen.js"; import type { WorkflowSnapshotRecordInput } from "./BinarySessionRecords.js"; import type { ResolvedAppBundleResourceRoot } from "../AppBundleExecutable.js"; import type { binaryTargetSummary } from "./BinaryTargetSummary.js"; import type { AnalysisExecution, AnalysisOperation, AnalysisOperationPort, ExecutionOptions, ProviderIdentity, } from "../AnalysisProvider.js"; import type { SavedAnalysisSnapshot } from "../../domain/savedAnalysisSnapshot.js"; export type { SavedAnalysisSnapshot } from "../../domain/savedAnalysisSnapshot.js"; /** Selection observed at the end of one serialized open attempt. */ export type OpenSelectionReceipt = | { readonly kind: "binary"; readonly path: string; readonly sha256: string } | { readonly kind: "resources"; readonly path: string; readonly caller_path: string; } | { readonly kind: "none" }; /** A failure retains its original error and both selection receipts. */ export type BinaryOpenResult = | { readonly ok: true; readonly value: BinaryTarget } | { readonly ok: false; readonly error: AnalysisError; readonly selection: OpenSelectionReceipt; readonly targetAtCompletion: ReturnType< typeof binaryTargetSummary > | null; readonly providerIdAtCompletion: string | null; }; /** Target lifecycle used by CLI and MCP without exposing a concrete provider. */ export interface BinarySessionPort extends AnalysisOperationPort, InvestigationRecordPort { readonly admitRecoveryObservation: RecoveryAdmission; /** Execute only against a positively ready, already-created provider client. */ executeIfProviderReady( operation: AnalysisOperation, parameters: Readonly>, options?: Pick, ): Promise | undefined>; /** Hold the active target binding through a complete composed operation. */ withAdmittedAnalysis( operationName: string, signal: AbortSignal | undefined, operation: (analysis: AnalysisOperationPort) => Promise, ): Promise>; /** Serialize an external mutation and retire any active target afterward. */ withAdmittedExternalMutation( _path: string | undefined, signal: AbortSignal | undefined, operation: () => Promise>, completionFailure: ( value: Result, error: AnalysisError, ) => AnalysisError, operationName?: string, cleanupRecovery?: ( failure: AnalysisError | undefined, ) => Promise>, ): Promise, AnalysisError>>; open( path: string, options?: { readonly signal?: AbortSignal; readonly targetKind?: BinaryTarget["kind"]; readonly formatHint?: ExecutableFormatHint; readonly architecture?: BinaryArchitecture; readonly entryPoint?: string; readonly espFlash?: EspFlashSelection; readonly snapshot?: AnalysisSnapshot; readonly loadSnapshot?: AnalysisSnapshotLoader; readonly providerId?: AnalysisProviderSelector; }, ): Promise; /** Open a resource-only app root without selecting or inventing an executable target. */ openBundleResources( path: string, options?: Pick, ): Promise>; /** * `cleanupRetry` names the caller's same-session retry; the session binds it * to a failed close only while it retains that cleanup for the next close. */ close( options?: Pick & { readonly retainProviderDocuments?: boolean; readonly cleanupRetry?: AnalysisCleanupRetry; }, ): Promise>; /** Seal runtime acquisition and release investigation state after successful cleanup. */ dispose( options?: Pick & { readonly retainProviderDocuments?: boolean; }, ): Promise>; /** Seal future acquisition/admission while previously admitted work drains. */ beginShutdown(): void; /** Drain work, optionally checkpoint, and clear records without closing the active engine. */ resetInvestigation(options?: { readonly savePath?: string; readonly overwrite?: boolean; readonly signal?: AbortSignal; /** Adapter-owned cleanup joins the drained transaction before clearing records. */ readonly retryCleanup?: () => Promise>; }): Promise>; /** Save a snapshot and close while excluding later provider requests. */ closeWithSnapshot( path: string, overwrite: boolean, options?: Pick & { readonly cleanupRetry?: AnalysisCleanupRetry; }, ): Promise>; /** Default complete detail; summary omits provider diagnostics and candidate capabilities. */ status(options?: { readonly signal?: AbortSignal; readonly detail?: BinarySessionDetail; readonly refreshCandidates?: boolean; }): Promise; activeTarget(): BinaryTarget | undefined; /** Read a snapshot with failed descriptors retained for session cleanup retry. */ readAnalysisSnapshot( path: string, signal?: AbortSignal, ): Promise>; exportAnalysisSnapshot(): Result; importAnalysisSnapshot( snapshot: AnalysisSnapshot, ): Result; providerIdentity(operation?: AnalysisOperation): ProviderIdentity; analysisProfile( operation?: AnalysisOperation, ): AnalysisProfileCommitment | undefined; allowsSnapshotReplay(operation: AnalysisOperation): boolean; /** Invalidate cached Evidence before an external command may mutate the target. */ invalidateSnapshotForExternalMutation(): void; recordWorkflowSnapshot( input: WorkflowSnapshotRecordInput, ): Result; onAvailabilityChanged?(listener: () => void | Promise): () => void; onAnalysisSnapshotChanged?(listener: () => void | Promise): () => void; }