import { type CallbackEnvelopeV1, type CallbackRouteV1 } from "./callback-transport.js"; import type { ExecutorKind } from "./executors.js"; import { type ClaudeTranscriptAnchor, type ClaudeHumanStartedActiveTaskAnchor, type ClaudeHumanStartedActiveTaskCheckpoint } from "./claude-local-transcript-provider.js"; import { type CodexHumanStartedActiveTaskAnchor } from "./terminal-submission-acceptance.js"; import { type CodexRolloutAcceptanceAnchor, type CodexRolloutIdentity, type TerminalSubmissionAcceptanceEvidence } from "./terminal-submission-facts.js"; import { type TerminalControlEvidence } from "./terminal-control-ref.js"; import type { TerminalInteractionSubjectProjection } from "./terminal-interaction-protocol.js"; import type { TerminalInteractionAggregate } from "./terminal-interaction-core.js"; export declare const TERMINAL_WATCH_SCHEMA: "agent-knock-knock/terminal-watch"; export declare const TERMINAL_WATCH_VERSION: 3; export declare const TERMINAL_WATCHES_DIRECTORY = "terminal-watches"; export declare const TERMINAL_WATCH_TERMINAL_STATUSES: readonly ["completed", "failed", "timed_out", "invalidated", "cancelled"]; export declare const TERMINAL_WATCH_STATUSES: readonly ["active", "completed", "failed", "timed_out", "invalidated", "cancelled"]; export declare const TERMINAL_WATCH_NOTIFICATION_KINDS: readonly ["approval", "interaction_required", "interaction_manual_required", "completed", "failed", "timed_out", "invalidated", "cancelled"]; export declare const TERMINAL_WATCH_NOTIFICATION_STATUSES: readonly ["pending", "delivering", "failed", "delivered", "superseded"]; export declare const TERMINAL_WATCH_INTERACTION_POLICIES: readonly ["notify_only", "respond_when_exact"]; export declare const TERMINAL_WATCH_MANUAL_INTERACTION_RESPONSE_KINDS: readonly ["single_select", "multi_select", "free_text", "confirm"]; export declare const TERMINAL_WATCH_MANUAL_INTERACTION_MAX_STEPS = 32; export declare const TERMINAL_WATCH_MANUAL_INTERACTION_MAX_OPTIONS = 8; export declare const TERMINAL_WATCH_MANUAL_INTERACTION_MAX_PROMPT_CHARACTERS = 1000; export declare const TERMINAL_WATCH_MANUAL_INTERACTION_MAX_OPTION_LABEL_CHARACTERS = 300; export declare const TERMINAL_WATCH_MANUAL_INTERACTION_MAX_OPTION_DESCRIPTION_CHARACTERS = 600; export type TerminalWatchStatus = typeof TERMINAL_WATCH_STATUSES[number]; export type TerminalWatchTerminalStatus = typeof TERMINAL_WATCH_TERMINAL_STATUSES[number]; export type TerminalWatchInteractionPolicy = typeof TERMINAL_WATCH_INTERACTION_POLICIES[number]; export interface TerminalWatchTerminalIdentity { terminal_id: string; terminal_endpoint: TerminalControlEvidence; workspace: string; binding_token: string; } export type TerminalWatchAnchor = CodexHumanStartedActiveTaskAnchor | ClaudeHumanStartedActiveTaskAnchor | CodexUserExplicitFallbackWatchAnchor | ClaudeUserExplicitFallbackWatchAnchor | TerminalActivityWatchAnchor; export type TerminalActivityState = "awaiting_approval" | "working" | "idle" | "unknown"; /** * Observation-only fallback for a user-selected live terminal. It deliberately * carries no task ownership claim: when a provider artifact cannot name one * exact task, the Watch follows only this terminal/process activity epoch. */ export interface TerminalActivityWatchAnchor { schema: "agent-knock-knock/terminal-activity-watch-anchor"; version: 1; captured_at: string; terminal_id: string; pid: number; initial_activity_state: TerminalActivityState; native_process_uuid?: string; native_process_birth?: string; agent_version?: string; anchor_fingerprint: string; } export declare function isTerminalActivityWatch(watch: Pick): watch is Pick & { anchor: TerminalActivityWatchAnchor; }; /** * New exact-task Watches opt in to fail-closed interaction response authority. * Best-effort activity Watches can notify about a questionnaire but can never * become terminal-input authorities. */ export declare function initialTerminalWatchInteractionPolicy(anchor: TerminalWatchAnchor): TerminalWatchInteractionPolicy; export declare function createTerminalActivityWatchAnchor(input: { capturedAt: Date; terminalId: string; pid: number; initialActivityState: TerminalActivityState; nativeProcessUuid?: string; nativeProcessBirth?: string; agentVersion?: string; }): TerminalActivityWatchAnchor; export interface CodexUserExplicitFallbackWatchAnchor { schema: "agent-knock-knock/codex-user-explicit-fallback-watch-anchor"; version: 1; captured_at: string; request_hash: string; codex_version: string; acceptance_anchor: CodexRolloutAcceptanceAnchor; anchor_fingerprint: string; } export interface ClaudeUserExplicitFallbackWatchAnchor { schema: "agent-knock-knock/claude-user-explicit-fallback-watch-anchor"; version: 1; captured_at: string; request_hash: string; claude_version: string; transcript_anchor: ClaudeTranscriptAnchor; anchor_fingerprint: string; } export type UserExplicitFallbackWatchAnchor = CodexUserExplicitFallbackWatchAnchor | ClaudeUserExplicitFallbackWatchAnchor; export declare function isUserExplicitFallbackWatch(watch: Pick): watch is Pick & { anchor: UserExplicitFallbackWatchAnchor; }; export declare function terminalUserExplicitFallbackWatchId(input: { messageId: string; physicalToken: string; requestHash: string; }): string; export declare function createCodexUserExplicitFallbackWatchAnchor(input: { acceptanceAnchor: CodexRolloutAcceptanceAnchor; requestHash: string; codexVersion: string; }): CodexUserExplicitFallbackWatchAnchor; export declare function createClaudeUserExplicitFallbackWatchAnchor(input: { transcriptAnchor: ClaudeTranscriptAnchor; requestHash: string; claudeVersion: string; }): ClaudeUserExplicitFallbackWatchAnchor; /** * Mutable, privacy-safe progress through the append-only provider artifact. * The immutable anchor continues to name the exact task; this cursor may only * advance after a provider proves a complete, stable JSONL boundary. */ export interface CodexTerminalWatchObservationCheckpoint { safe_resume_offset_bytes: number; } export interface CodexUserExplicitFallbackWatchAcceptedIdentity { native_thread_id: string; process_uuid: string; process_birth: string; rollout: CodexRolloutIdentity; } export interface CodexUserExplicitFallbackWatchObservationCheckpoint { schema: "agent-knock-knock/codex-user-explicit-fallback-watch-checkpoint"; version: 1; safe_resume_offset_bytes: number; acceptance_evidence?: TerminalSubmissionAcceptanceEvidence; accepted_identity?: CodexUserExplicitFallbackWatchAcceptedIdentity; } export interface ClaudeUserExplicitFallbackWatchObservationCheckpoint { schema: "agent-knock-knock/claude-user-explicit-fallback-watch-checkpoint"; version: 1; safe_resume_offset_bytes: number; acceptance_evidence?: TerminalSubmissionAcceptanceEvidence; accepted_prompt_uuid?: string; } export interface TerminalActivityWatchObservationCheckpoint { schema: "agent-knock-knock/terminal-activity-watch-checkpoint"; version: 1; safe_resume_offset_bytes: 0; has_seen_activity: boolean; consecutive_idle_observations: number; last_activity_state: TerminalActivityState; } export type TerminalWatchObservationCheckpoint = CodexTerminalWatchObservationCheckpoint | CodexUserExplicitFallbackWatchObservationCheckpoint | ClaudeUserExplicitFallbackWatchObservationCheckpoint | ClaudeHumanStartedActiveTaskCheckpoint | TerminalActivityWatchObservationCheckpoint; export declare function initialTerminalWatchObservationCheckpoint(anchor: TerminalWatchAnchor): TerminalWatchObservationCheckpoint; export type TerminalWatchNotificationKind = typeof TERMINAL_WATCH_NOTIFICATION_KINDS[number]; export type TerminalWatchNotificationStatus = typeof TERMINAL_WATCH_NOTIFICATION_STATUSES[number]; export type TerminalWatchManualInteractionResponseKind = "single_select" | "multi_select" | "free_text" | "confirm"; export interface TerminalWatchManualInteractionOption { label: string; description?: string; } /** * Bounded semantic summary for a questionnaire that Terminal Watch can only * ask a human to resolve in the live TUI. It deliberately omits raw screen * contents, native keys, action plans, private prompt fingerprints, and * response authority. */ export interface TerminalWatchManualInteractionSummary { kind: "questionnaire" | "async_question"; response_kind: TerminalWatchManualInteractionResponseKind; required: boolean; current_step: number; total_steps: number; parser_status: "actionable" | "manual_required"; prompt?: string; options?: TerminalWatchManualInteractionOption[]; manual_reason?: string; } /** * One immutable notification payload plus its mutable delivery receipt. * `notification_id` and `idempotency_key` are deterministic from the Watch, * kind, and evidence fingerprint, so a transport retry cannot create a second * logical OpenClaw notification. */ export interface TerminalWatchNotification { notification_id: string; idempotency_key: string; kind: TerminalWatchNotificationKind; evidence_fingerprint: string; reason_code?: string; manual_interaction?: TerminalWatchManualInteractionSummary; callback_route?: CallbackRouteV1; callback_envelope?: CallbackEnvelopeV1; status: TerminalWatchNotificationStatus; attempts: number; created_at: string; last_attempt_at?: string; attempt_id?: string; attempt_lease_expires_at?: string; failed_at?: string; next_attempt_at?: string; last_error_code?: string; delivered_at?: string; superseded_at?: string; } export interface TerminalWatchSettlement { kind: TerminalWatchTerminalStatus; evidence_fingerprint: string; observed_at: string; reason_code?: string; completion_text?: string; completion_id?: string; completion_timestamp?: string; } /** * Privacy-safe durable state for the questionnaire currently attributed to a * Watch. The public projection is intentionally bounded by the interaction * protocol. The aggregate stores only opaque identities, fingerprints, * timestamps, and response receipts; native key plans, raw terminal frames, * and answer text never cross this persistence boundary. */ export interface TerminalWatchCurrentInteraction { projection: TerminalInteractionSubjectProjection; aggregate: TerminalInteractionAggregate; } /** * Durable observation authority for work started by a human in a coding-agent * TUI. It is deliberately not a Conversation, Turn, Session, dispatch receipt, * or terminal-input authority. */ export interface TerminalWatch { schema: typeof TERMINAL_WATCH_SCHEMA; version: typeof TERMINAL_WATCH_VERSION; watch_id: string; revision?: number; agent: ExecutorKind; terminal: TerminalWatchTerminalIdentity; anchor: TerminalWatchAnchor; observation_checkpoint: TerminalWatchObservationCheckpoint; /** Immutable creation-time response policy. Legacy records are notify-only. */ interaction_policy: TerminalWatchInteractionPolicy; current_interaction?: TerminalWatchCurrentInteraction; /** Immutable creation-time diagnostics; none of these veto observation. */ warnings?: string[]; /** Immutable callback authority captured by a native Host at Watch creation. */ callback_route?: CallbackRouteV1; openclaw_session: string; openclaw_bin: string; created_at: string; deadline_at: string; updated_at: string; status: TerminalWatchStatus; last_activity_at: string; settlement?: TerminalWatchSettlement; notification_outbox: TerminalWatchNotification[]; } export type TerminalWatchCallbackEvent = "approval_required" | "interaction_required" | "interaction_manual_required" | TerminalWatchTerminalStatus; export interface TerminalWatchCallbackMessageInput { watchId: string; event: TerminalWatchCallbackEvent; agent: ExecutorKind; terminalId: string; origin?: "user_selected_terminal" | "terminal_user_explicit_fallback" | "terminal_activity_fallback"; detail?: string; completionText?: string; manualInteraction?: TerminalWatchManualInteractionSummary; } /** * Terminal Watch callbacks may wake their owning controller, but never carry * authority to answer a terminal interaction. Keep this projection reusable at * creation and delivery so a persisted predecessor route with `respond:true` * is safely reduced without making the predecessor Watch unreadable. */ export declare function terminalWatchNotificationOnlyRoute(value: unknown): CallbackRouteV1; export declare function terminalWatchCallbackEnvelope(watch: TerminalWatch, notification: TerminalWatchNotification, route: CallbackRouteV1): CallbackEnvelopeV1; export declare function terminalWatchCallbackMessage(input: TerminalWatchCallbackMessageInput): string; /** * A predecessor file is validated against its exact historical presentation * before this in-memory migration runs. Returning the current deterministic * envelope keeps all public validation and every subsequently-saved v3 record * strict; merely reading a legacy file does not rewrite Store history. */ export declare function upgradePredecessorCallbackPresentations(watch: TerminalWatch): TerminalWatch; export declare function terminalWatchNotificationId(watchId: string, kind: TerminalWatchNotificationKind, evidenceFingerprint: string): string; export declare function terminalWatchNotificationIdempotencyKey(watchId: string, notificationId: string): string; export declare function terminalWatchIdentityFingerprint(watch: Pick): string; export declare function terminalWatchRevision(watch: TerminalWatch): number; export type FieldGuard = (value: unknown, label: string) => void; export type StrictShape = Readonly>; export declare const IGNORE_VALUE: FieldGuard; export declare const POSITIVE_INTEGER: FieldGuard; export declare const NON_NEGATIVE_INTEGER: FieldGuard; export declare const ARRAY_VALUE: FieldGuard; export declare const WARNING_LIST: FieldGuard; export declare const ABSOLUTE_PATH: FieldGuard; export declare const NULLABLE_ENDPOINT_STRING: FieldGuard; export interface TerminalWatchNotificationCallbackSnapshot { route: CallbackRouteV1; envelope: CallbackEnvelopeV1; } /** * Parse one optional v1 callback snapshot. Legacy notifications may omit both * fields; a partial or malformed snapshot is never treated as legacy. */ export declare function terminalWatchNotificationCallbackSnapshot(watch: TerminalWatch, notification: TerminalWatchNotification): TerminalWatchNotificationCallbackSnapshot | undefined; export declare function parseTerminalWatchNotificationCallbackSnapshot(watch: TerminalWatch, notification: TerminalWatchNotification, allowPredecessorCallbackPresentation: boolean): TerminalWatchNotificationCallbackSnapshot | undefined; export declare function assertStrictRecord(value: unknown, label: string, shape: StrictShape): asserts value is Record; export declare function literalGuard(expected: unknown): FieldGuard; export declare function oneOfGuard(allowed: readonly unknown[]): FieldGuard; export declare function optionalGuard(guard: FieldGuard): FieldGuard; export declare function nullableGuard(guard: FieldGuard): FieldGuard; export declare function assertExpectedRevision(value: unknown): asserts value is number | null; export declare function assertRecordId(value: unknown, label: string): asserts value is string; export declare function assertContained(candidate: string, parent: string, label: string): void; export declare function assertNotificationKind(value: unknown): asserts value is TerminalWatchNotificationKind; export declare function isTerminalWatchOutcomeNotification(kind: TerminalWatchNotificationKind): kind is TerminalWatchTerminalStatus; export declare function isPositiveSafeInteger(value: unknown): value is number; export declare function isNonNegativeSafeInteger(value: unknown): value is number; export declare function positiveIntegerValue(value: unknown, label: string): number; export declare function assertNonEmptyString(value: unknown, label: string): asserts value is string; export declare function nonEmptyString(value: unknown, label: string): string; export declare function assertSha256(value: unknown, label: string): asserts value is string; export declare function sha256String(value: unknown, label: string): string; export declare function exactUuid(value: unknown, label: string): string; export declare function fingerprintValue(value: unknown): string; export declare function assertAnchorFingerprint(value: Record, label: string): void; export declare function validatedClaudeTranscriptAnchor(value: unknown): ClaudeTranscriptAnchor; export declare function assertTimestamp(value: unknown, label: string): asserts value is string; export declare function assertReasonCode(value: unknown, label: string): void; export declare function assertCompletionText(value: unknown, label: string): void;