// Vendored from Muse Code 1.4.1 via muse schema generate-ts. // Stable fingerprint: sha256:e0e163db6ccf00dbe68402ce55d6319b3edc33c421f31e9583b587b2de8a118f // Muse Session Protocol (MSP) v1 TypeScript declarations. // STABLE surface only; experimental twin: experimental/msp.d.ts. // Generated by tbh-protocol (spec 206) from the same schema model as // the JSON Schema bundle (INV-017). Do not edit by hand. export interface ApprovalAmendment { durability: ApprovalAmendmentDurability; rulePreview: string; } export type ApprovalAmendmentDurability = "session" | "localPersistent" | (string & {}); export interface ApprovalChange { choiceId?: string; decision?: ApprovalDecision; executable?: boolean; kind: string; reason?: string; reparsed?: boolean; requirementId?: ApprovalRequirementRef; status?: ApprovalPersistenceStatus; } export interface ApprovalChoice { acceptsFeedback?: boolean; choiceId: string; decision: ApprovalDecision; label: string; rulePreview?: string; scope: ApprovalChoiceScope; } export type ApprovalChoiceScope = "once" | "session" | "localPersistent" | (string & {}); /** `approval/decide` params (tdd SS5.4): the decision. A standard SS3 command — requires the session loaded on this host, requires `commandId`, durable intake before ack, value-identical replay. */ export interface ApprovalDecideParams { /** The approval being decided. */ approvalId: string; /** One of the current `availableChoices`; else -32052. */ choiceId: string; /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** Free-text guidance delivered to the model with the denial. Only valid on choices with `acceptsFeedback`. Never persisted in the durable audit record (live steer only), so it is absent from `approval/resolved` (tdd SS5.4). Omitted and explicit `null` both mean "no feedback" (#23468). */ feedback?: string | null; /** Must equal the approval's `currentRequirementId`. The multi-stage race guard: a decision aimed at stage 1 can never accidentally satisfy stage 2, and a stale value is -32053 (tdd SS5.4). */ requirementId: ApprovalRequirementRef; /** The target session. */ sessionId: string; } /** `approval/decide` result (tdd SS5.4). Admission-ack rules still apply: the authoritative outcome is `approval/resolved` / `approval/updated` on the view stream. */ export interface ApprovalDecideResult { /** The approval this decision was applied to. */ approvalId: string; /** Echoes the client's id. */ commandId: string; /** Admission status. */ status: CommandStatus; /** `false` when the choice satisfied a stage but further requirements remain (the approval stays pending and an updated `approval/request` follows); `true` when this decision produced the terminal `DecisionApplied` (tdd SS5.4). */ terminal: boolean; } export type ApprovalDecision = | "approved" | "approvedForSession" | "approvedPolicyAmendment" | "denied" | "deniedPolicyAmendment" | "timedOut" | "abort" | (string & {}); /** `approval/listPending` params (tdd SS5.7): the pull dual of the re-issued requests. A log-fold read — no lease, works on loaded and unloaded sessions, never subscribes. */ export interface ApprovalListPendingParams { /** The session to read. */ sessionId: string; } /** `approval/listPending` result (tdd SS5.7). Ordering is by opening `viewCursor`; empty arrays when nothing is pending. The result is point-in-time — to act on it race-safely, `approval/decide` carries the `requirementId` guard regardless of how the client learned the state. */ export interface ApprovalListPendingResult { /** Exactly the `approval/request` params of tdd SS5.3, one per pending approval. */ approvals: ApprovalRequestParams[]; /** Exactly the `userInput/request` params of tdd SS5.10, one per pending prompt. */ userInputs: UserInputRequestParams[]; } /** The approval enforcement modes (tdd SS5.12, camelCased `ApprovalBackendMode`). **Closed** by design (D-006, select-never-create): a client selects a preconfigured mode and can never construct one; widening this enum is a deliberate, gate-visible protocol change. */ export type ApprovalMode = "allowAll" | "promptUnmatched" | "onRequest" | "denyUnmatched"; /** Whether a mode change did anything (tdd SS5.12), mirroring `ApprovalReconfigureApplyOutcome`. Apply failures are `commandRejected`. */ export type ApprovalModeApplyOutcome = "completed" | "noop" | (string & {}); /** How an approval mode took effect (tdd SS5.12, the effective-mode projection's `source` vocabulary). Open. */ export type ApprovalModeSource = "startup" | "replay" | "approvalReconfigure" | (string & {}); export interface ApprovalOrigin { command?: string; kind: string; url?: string; } export type ApprovalPersistenceStatus = "succeeded" | "failed" | (string & {}); export type ApprovalPolicyResult = "allow" | "deny" | (string & {}); /** Full params shared by `approval/request` and `approval/requested`. */ export interface ApprovalRequestParams { approvalId: string; availableChoices: ApprovalChoice[]; currentRequirementId: ApprovalRequirementRef; itemId: string; judgeEscalated: boolean; protectedWrite: boolean; rawArgs: string; sessionId: string; sourceRange: SourceRange; /** Present only for a child (native subagent) approval projected onto the parent session's plane (ADR 36182); parent-own approvals omit it. */ subagentOrigin?: ApprovalSubagentOrigin; subject: ApprovalSubject; taskId: string; toolCallId: string; toolName: string; turnId: string; viewCursor: string; } /** Approval-stage token carried in SS5 params and stale-requirement errors. */ export interface ApprovalRequirementRef { approvalId: string; sourceIndex: number; } /** Winning terminal returned to a losing `approval/decide` command. */ export interface ApprovalResolutionSummary { decision: string; resolvedBy: string; viewCursor: string; } export type ApprovalResolvedBy = "user" | "policy" | "llmJudge" | (string & {}); /** `approval/resolved` params: the first durable terminal decision. */ export interface ApprovalResolvedParams { amendment?: ApprovalAmendment; approvalId: string; decidedByCommandId?: string; decision: ApprovalDecision; itemId: string; policyResult: ApprovalPolicyResult; resolvedBy: ApprovalResolvedBy; sessionId: string; sourceRange: SourceRange; stageEvidence: ApprovalStageEvidence[]; /** Present only for a child (native subagent) approval projected onto the parent session's plane (ADR 36182); parent-own approvals omit it. */ subagentOrigin?: ApprovalSubagentOrigin; turnId: string; viewCursor: string; } export interface ApprovalStage { argv: string[]; argvComplete: boolean; position: number; requirementId: ApprovalRequirementRef; resolution: ApprovalStageResolution; suggestedPrefix?: ApprovalSuggestedPrefix; totalStages: number; } export interface ApprovalStageEvidence { argv: string[]; position: number; requirementId: ApprovalRequirementRef; resolution: ApprovalStageResolution; totalStages: number; } export interface ApprovalStageResolution { argvPrefix?: string[]; diagnostic?: string; kind: string; } /** Child (native subagent) provenance for an approval projected onto the PARENT session's approval plane (#36182 / ADR 36182): identifies the originating child run/agent so a client can attribute the prompt. Omitted (`skip_serializing_if`) on the parent's own approvals, so pre-existing parent frames stay byte-identical. */ export interface ApprovalSubagentOrigin { /** The child run that parked on this approval. */ childRunId: string; /** The child session stream id whose records carry this approval. */ childSessionId: string; /** The originating child's subagent id, from the parent session's durable subagent control records. */ subagentId: string; } /** Open approval subject union. Unknown kinds are rendered generically and never auto-approved by clients (tdd SS5.2). */ export interface ApprovalSubject { access?: string; command?: string; host?: string; /** Open discriminator: `shell | fileAccess | network | unixSocket | process | tool`. */ kind: string; origin?: ApprovalOrigin; path?: string; port?: number; protocol?: string; stages?: ApprovalStage[]; target?: string; toolName?: string; workspaceRoot?: string; } export interface ApprovalSuggestedPrefix { argvPrefix: string[]; label: string; } /** `approval/updated` params: the refreshed pending view plus one change. */ export interface ApprovalUpdatedParams { approvalId: string; availableChoices: ApprovalChoice[]; change: ApprovalChange; currentRequirementId: ApprovalRequirementRef; sessionId: string; sourceRange: SourceRange; /** Present only for a child (native subagent) approval projected onto the parent session's plane (ADR 36182); parent-own approvals omit it. */ subagentOrigin?: ApprovalSubagentOrigin; subject: ApprovalSubject; viewCursor: string; } /** One attention flag (tdd SS2.4, ADR 31983 D3): a pending server-initiated request class parked on the session. Open on the wire — clients MUST ignore unknown values; future attention kinds are additive. */ export type AttentionFlag = "approvalPending" | "inputPending" | (string & {}); /** Who durably backgrounded a task (tdd SS4.5.5, `TaskBackgroundedInitiator`). Open — runtime vocabulary. */ export type BackgroundInitiator = "user" | "timeout" | (string & {}); /** The latest branch observation in the snapshot (tdd SS4.6.4, SS4.9.1). */ export interface BranchState { /** The observed branch; `null` on a detached-HEAD observation. */ branch: string | null; /** The detected version-control system; absent when none was detected. */ vcs?: Vcs; /** The observed workspace root. */ workspaceRoot: string; } /** A grantable capability name (SS1.4.4). Open: the reserved `rawLog` entry joins this domain as an additive open-enum extension when SS6 un-defers (#13929, Scenario 5 AS-3) — closed would make that a retype. */ export type CapabilityName = "userShell" | "sessionMcp" | "sessionListStream" | (string & {}); /** The client's requested capability posture (SS1.4.1). Every member defaults; an absent `capabilities` object means all defaults. */ export interface ClientCapabilities { /** Opt into experimental methods, fields, and variants (default `false`). */ experimentalApi?: boolean; /** Exact notification method names the client declines; no wildcards; unknown names accepted and ignored; the protected set (SS1.7) cannot be opted out. */ optOutNotificationMethods?: string[]; /** Names from the capability registry. Unknown entries are not an error and simply do not appear in `grantedCapabilities` — which is why this is a list of free strings rather than of registry names. */ requestedCapabilities?: string[]; /** Whether this client can render a `userInput/request` dialog and answer it (SS5.10). **Absent means capable** (D-047): a client that predates the member keeps today's contract, so no existing client changes its handshake. `false` makes the host withhold `userInput/request` toward this client — the D-027 additive-optional-field + withheld-method convention. Deliberately NOT a `requestedCapabilities` name: that registry records operations a host GRANTS (SS1.4.4), and whether a client can draw a dialog is a fact about the client, never a privilege the host hands out. */ userInputDialogs?: boolean; } /** Client identification inside `initialize` params (SS1.4.1). Diagnostics and telemetry attribution only; never an authority claim (SS1.10). */ export interface ClientInfo { /** Machine identifier, `[a-z0-9_]+` (SS1.4.1). */ name: string; /** Human display name. */ title?: string; /** Client version string. */ version: string; } /** The uniform SS3.1.2 command acknowledgement: admission only, never an outcome. `session/compact` alone may answer `"noop"`; every other command answers `"accepted"`. */ export interface CommandAcceptedResult { /** Echo of the client-minted UUIDv7 `commandId` (SS3.1.1). */ commandId: string; /** `"accepted"` for every admitted command (SS3.1.2; closed vocabulary). */ status: CommandAckStatus; } /** The ack-status vocabulary (`tdd.md` SS3.1/SS3.1.2): `"accepted"` for every admitted command; `session/compact` alone may answer `"noop"`. Closed: SS3.1.2 names exactly these two values, so SDK clients get a discriminated type and validation catches a wrong status (PR #21550 review) — and a client that received a third value would have been told nothing it can act on, unlike [`TurnStartDisposition`], where "acked, not otherwise classified" is a usable reading. */ export type CommandAckStatus = "accepted" | "noop"; /** The SS3.1.2 ack `status`: `accepted` for every admitted command. `session/compact` is the one method that may additionally answer `noop` ([`crate::method::runtime::CompactStatus`]); no other command uses another status (tdd SS3.1.2). */ export type CommandStatus = "accepted" | (string & {}); /** `session/compact`'s ack status (tdd SS3.7): the one method that may answer `noop` in addition to the SS3.1.2 `accepted`. A noop is a success, not an error, and it is durably settled like any other outcome. */ export type CompactStatus = "accepted" | "noop" | (string & {}); /** Compaction outcome (tdd SS4.5.10, the SS3.7 vocabulary). Open. */ export type CompactionOutcome = "compacted" | "noop" | "failed" | "cancelled" | (string & {}); /** What initiated a compaction (tdd SS4.5.10). Open. */ export type CompactionTrigger = "manual" | "auto" | (string & {}); /** Context pressure level (tdd SS4.6.6): hard threshold first, both inclusive `>=`. Open. */ export type ContextPressureLevel = "normal" | "warning" | "blocked" | (string & {}); /** The SS4.9.1 snapshot `contextUsage` block: the latest `(windowTokens, usedTokens, pressure)` triple; the snapshot member is `null` until the fold's generation chain holds a tracked anchor AND the current basis is present (absent is never fabricated). */ export interface ContextUsage { /** Server-computed pressure level. */ pressure: ContextPressureLevel; /** Counted-once occupancy at the latest provider-reported fact. */ usedTokens: number; /** The effective context-window size; absent when the basis has no limit. */ windowTokens?: number; } /** Session running totals of counted-once usage (tdd SS4.6.5). */ export interface CumulativeTokenUsage { /** Output tokens, session total. */ outputTokens: number; /** Counted-once prompt tokens, session total. */ promptTokens: number; /** Counted-once totals, session total. */ totalTokens: number; } /** The effective approval-mode projection (`EffectiveApprovalModeState`, tdd SS5.12): the same object `session/setApprovalMode` returns as `effectiveMode` and the `Session` object carries as `approvalMode`. */ export interface EffectiveApprovalModeState { /** The command that last set it; `null` when no command did. */ lastCommandId: string | null; /** The mode in effect. */ mode: ApprovalMode; /** How the mode took effect. */ source: ApprovalModeSource; } /** The latest effective-model fact in the snapshot (tdd SS4.9.1). */ export interface EffectiveModel { /** The selected model. */ modelId: string; /** The selected provider; `null` when the selection names none. */ providerId: string | null; /** What drove the selection. */ source: ModelChangeSource; } /** The optional `error.data` object (SS1.6). All members additive-optional; `kind` is always present when `data` is. */ export interface ErrorData { /** The next provable UTF-8 boundary on a misaligned text-media `item/readOutput` read (`-32602` `invalidParams`, FR-016b/D-17214-2): absent when no boundary is provable from the stored bytes ahead. */ alignedNextOffset?: number; /** The rejected anchor value on `notFound`/`missingAnchor` and the `-32042` boundary arms (SS4.7.3, SS4.11); on `-32042` it is served as an explicit `null` when the request named no concrete anchor (spec 208 FM-005). */ anchor?: string | null; /** Approval identity on SS5 errors. */ approvalId?: string; /** The stored output's availability on `outputUnavailable` — the durable `ToolOutputAvailability` value, read-time-derived when the durable record still says `available` (SS4.5.5; spec 208 FM-008). */ availability?: string; /** The missing capability, on `capabilityRequired` errors. Typed on the grantable registry, so `rawLog` is outside the v1 domain and joins it as an additive open-enum extension when SS6 un-defers (TEST-009). */ capability?: CapabilityName; /** The configured command-admission bound, on `backpressured` errors. */ capacity?: number; /** Rejected server-minted choice on `approvalChoiceInvalid`. */ choiceId?: string; /** The rejected command's identifier, on `commandRejected` errors. The ratified v1 contract pairs it with `reason` (specs/13929-msp-activation/tdd.md SS3.6 admission-failure table and its `-32030` example), so a client can settle the exact command it sent without parsing the message string. */ commandId?: string; /** Current stage token on `approvalRequirementStale`. */ currentRequirementId?: ApprovalRequirementRef; /** SS1.5.1 descriptor, on `experimentalRequired` errors. */ descriptor?: string; /** Free-form additive detail. */ details?: Record; /** The oldest servable view position on `viewTruncated` (`-32040`, SS4.11); served as an explicit `null` when nothing before the head is servable — the null is present on the wire, never a dropped key (spec 208 FM-005 / Scenario 6.2). */ earliestCursor?: string | null; /** The item whose stored output was requested, on the `item/readOutput` arms (`notFound`, `outputUnavailable`, and the misaligned-offset `invalidParams`). */ itemId?: string; /** The stable camelCase category clients branch on. */ kind: ErrorKind; /** Rejected inclusive fork boundary on `forkBoundaryInvalid`. */ lastTurnId?: string; /** The latest installed boundary's view cursor on the `-32042` arms — always present in the `-32042` JSON and explicitly `null` when no boundary exists (SS4.11, FM-004). */ latestBoundaryCursor?: string | null; /** The exceeded byte limit, on `inputTooLarge` errors. */ limitBytes?: number; /** The requested `outputRef.id`, on the same `item/readOutput` arms. */ outputRef?: string; /** Candidate retained paths on `sessionAmbiguous`. */ paths?: string[]; /** Failure detail vocabulary (e.g. `"missingAnchor"` on `notFound` for a missing view-cursor anchor). */ reason?: string; /** Winning resolution on `approvalAlreadyResolved`. */ resolution?: ApprovalResolutionSummary; /** Whether retrying can succeed (e.g. `overloaded`). When present, overrides the error table row's `retryable` default for this code. */ retryable?: boolean; /** The rejected skill selector on `skillNotFound` (`-32032`, SS3.22.4). */ selector?: string; /** Session identity on errors whose lookup is session-scoped. */ sessionId?: string; /** Winning settlement on `userInputAlreadySettled`. */ settlement?: UserInputSettlementSummary; /** User-input prompt identity on SS5.10 errors. */ userInputId?: string; /** The blocked view position on `pageEventTooLarge` errors. */ viewCursor?: string; } /** A stable `error.data.kind` category (SS1.6): camelCase, the value clients branch on. Open: SS2–SS5 lanes add kinds additively as their methods land (Appendix B already registers them), and the spec's edge-case rule makes a new `kind` additive only because this domain is declared open. */ export type ErrorKind = | "parseError" | "invalidRequest" | "notInitialized" | "alreadyInitialized" | "methodNotFound" | "invalidParams" | "experimentalRequired" | "internal" | "pageEventTooLarge" | "outputResultTooLarge" | "overloaded" | "inputTooLarge" | "capabilityRequired" | "notFound" | "interrupted" | "cancelled" | "sessionNotFound" | "sessionInUse" | "sessionAmbiguous" | "forkBoundaryInvalid" | "sessionNotLoaded" | "sessionStreamMismatch" | "commandRejected" | "backpressured" | "skillNotFound" | "viewTruncated" | "outputUnavailable" | "boundaryPruned" | "boundaryUnusable" | "noBoundary" | "approvalNotFound" | "approvalAlreadyResolved" | "approvalChoiceInvalid" | "approvalRequirementStale" | "approvalReviewerUnavailable" | "userInputNotFound" | "userInputAlreadySettled" | "userInputAnswerInvalid" | (string & {}); /** The `error` member of an error response (SS1.2 §2.4). */ export interface ErrorObject { /** Registry code (Appendix B). Typed as a plain integer on the wire; the value domain is the registry below (INV-018). */ code: number; /** Structured detail; carries `kind` when present. */ data?: ErrorData; /** Human-readable message. Never a branch point (SS1.6). */ message: string; } /** An error response frame (SS1.2 §2.4). Exactly one of `result` or `error` appears on a response; this type is the `error` half. */ export interface ErrorResponse { /** The error payload (Appendix B registry). */ error: ErrorObject; /** Echo of the request id; `null` **only** for an unrecoverable parse error whose offending id could not be recovered (SS1.3). Always serialized, so `None` renders as `null` rather than being omitted — required-but-nullable (see [`require_nullable_id`]). */ id: RequestId | null; /** The literal `"2.0"`. */ jsonrpc: JsonRpcVersion; } /** Where a fork cuts the source history (tdd SS2.5.3). Turn ids are used instead of counts because ids stay stable across compaction and concurrent appends while indices do not. */ export interface ForkCutPoint { /** The last completed turn to copy, inclusive. Naming an in-progress or unknown turn fails `forkBoundaryInvalid`. */ lastTurnId: string; } /** Fork provenance folded from the durable `session.fork.created` record (`ForkProvenance`, tdd SS2.4). */ export interface ForkProvenance { /** The `commandId` of the `session/fork` that created it. */ commandId: string; /** An **opaque provenance string** preserved verbatim from the durable record. Display-only — not one of the SS6.2 cursor families: clients MUST NOT parse it and no method accepts it (tdd SS2.4). */ cutCursor: string; /** Whether the fork named an explicit cut point. */ cutExplicit: boolean; /** The source session this fork was cut from. */ sessionId: string; } /** The session goal block (tdd SS4.6.2, mirrors the runtime's goal state, camelCased). `status` and `percentComplete` are carried **verbatim** — out-of-contract status strings and >100 percents pass through; display clamping is the renderer's job. */ export interface Goal { /** Current work description, when present. */ currentWork?: string; /** Next work description, when present. */ nextWork?: string; /** The goal objective text. */ objective: string; /** Percent complete, verbatim (>100 passes through). */ percentComplete: number; /** Goal status, verbatim from the durable goal state (free string by design: out-of-contract values pass through). */ status: string; } /** `goal/clear` params (tdd SS3.18). An `objective` here is an unknown field and rejects `-32602 invalidParams` — the bare verbs carry exactly this pair. */ export interface GoalClearParams { /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The target session. */ sessionId: string; } /** The shared SS3.18 goal ack, admission-only: all five verbs answer this one shape (the tdd's "Shared contract"), differing only in when `turnId` is present. */ export interface GoalCommandResult { /** Echoes the client's id. */ commandId: string; /** Admission status. */ status: CommandStatus; /** Present by exactly the four SS3.18 result cases: an idle wake carries the fresh goal turn's id; a busy `set`/`edit`/`resume` carries the admission-time active turn's id (a routing fact, not a delivery promise); `pause`/`clear` never carry it; an idle admission whose resulting goal is not unfinished parks the notification and carries none. **Additive-optional**: absent means "no turn named", never fabricated. */ turnId?: string; } /** `goal/edit` params (tdd SS3.18): replace the current goal's objective. Same shape as `goal/set`; the verbs differ in their `missing_goal` precondition, not their payload. */ export interface GoalEditParams { /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The replacement objective; same trim/non-empty rule as `goal/set`. */ objective: string; /** The target session. */ sessionId: string; } /** `goal/pause` params (tdd SS3.18); shape as `goal/clear`. */ export interface GoalPauseParams { /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The target session. */ sessionId: string; } /** `goal/resume` params (tdd SS3.18); shape as `goal/clear`. */ export interface GoalResumeParams { /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The target session. */ sessionId: string; } /** `goal/set` params (tdd SS3.18): set the session's goal objective. */ export interface GoalSetParams { /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The objective text; required, non-empty after Unicode-whitespace trim (the trimmed text is the payload). Empty-after-trim is `-32602 invalidParams` (tdd SS3.18). */ objective: string; /** The target session. */ sessionId: string; } /** What history a lifecycle result actually served (tdd SS2.5.2). Open on the client side: report-what-was-served means a client treats an unknown mode as "page it yourself". */ export type HistoryMode = "anchoredSnapshot" | "inline" | "snapshot" | "none" | (string & {}); /** Why a result served `history.mode: "none"` — spec 208 FM-005's typed unavailability (tdd SS2.5.2; D-050). Open on the client side: an absent (older server) or unknown (newer server) value decodes conservatively as an unknown reason, and `viewCursor` text never substitutes for it (spec 208 INV-19734-1). */ export type HistoryNoneReason = | "excluded" | "cursorSuffix" | "historyBudget" | "projectionUnavailable" | "projectionReadLimit" | (string & {}); /** The `history` request preference of `session/resume` (tdd SS2.5.2). The forced values downgrade `anchored` → `inline` → `snapshot` → `none`; under `auto` the full rung order is anchoredSnapshot → inline → snapshot → elided snapshot → none. */ export type HistoryPreference = "auto" | "inline" | "snapshot" | "anchored"; /** Disposition when a turn is already running (tdd SS3.2). The wire default is `queue`: an SDK caller who has not looked at session state should not silently mutate an in-flight turn. */ export type IfBusy = "queue" | "steer" | "replace"; /** `initialize` request params (SS1.4.1). */ export interface InitializeParams { /** Capability posture; absent means all defaults. */ capabilities?: ClientCapabilities; /** Client identification. */ clientInfo: ClientInfo; } /** The `initialize` result (SS1.4.1). */ export interface InitializeResult { /** Echo of the effective negotiated experimental setting. */ experimentalApi: boolean; /** Subset of the requested capabilities, plus policy-implicit grants. Fixed for the connection lifetime (INV-009). */ grantedCapabilities: CapabilityName[]; /** Absolute path of the muse home directory. */ museHome: string; /** Server runtime platform family. */ platformFamily: PlatformFamily; /** Server operating system. */ platformOs: PlatformOs; /** Envelope schema version and stable-surface fingerprint. */ schema: SchemaInfo; /** Server identification. */ serverInfo: ServerInfo; /** Whether this host persists its sessions (SS2.13). Optional so the addition is additive under SS1.5.4; a v1 host always sends it, and a client reads absent as `durable` because no server that omits it has the ephemeral profile. */ sessionDurability?: SessionDurability; /** Exact user-agent string presented to upstream model providers. */ userAgent: string; } /** One transcript item at one revision (tdd SS4.4.1 common fields plus the per-kind fields of SS4.5.2–4.5.10, all optional and owned by the kind their doc names). `item/started`, `item/updated`, and `item/completed` carry the full object; `item/delta` appends to it by field path. */ export interface Item { /** `subagent`: agent definition path. */ agentPath?: string; /** `toolCall`: the approval that gated this call (tdd SS5); join key for the approval view events. */ approvalId?: string; /** `toolCall`: the model-authored argument JSON, **verbatim**; clients parse. Verbatim keeps the fold byte-deterministic and survives model-emitted almost-JSON (tdd SS4.5.5). */ args?: string; /** `userMessage`: image attachment metadata only — base64 payloads are not echoed back on the view (tdd SS4.5.2). */ attachments?: MessageAttachment[]; /** `toolCall`: `true` once the task was durably backgrounded; delivered via `item/updated`. */ background?: boolean; /** `toolCall`: who backgrounded the task; absent on pre-split records — never inferred (tdd SS4.5.5). */ backgroundInitiator?: BackgroundInitiator; /** `toolCall`: the provider call id (`call_...`), opaque. */ callId?: string; /** `subagent`/`reminderChild`: the child's own session id, readable via `session/read`/`view/page` — child transcript drill-down without a second protocol (tdd SS4.5.7). */ childSessionId?: string; /** `reminderChild`: parent-session-dir-relative child log path; absent when no filesystem log. */ childSessionLogPath?: string; /** `workflow`: folded per-child state, keyed by `(childId, attempt)`, re-emitted whole on every change — the item `revision` is the ordering guard (tdd SS4.5.8). */ children?: WorkflowChild[]; /** `userMessage`/`userShell`: the submitting command — multi-client UIs de-duplicate their local echo on it. */ commandId?: string; /** `userShell`: the command text as submitted. */ commandText?: string; /** `subagent`: camelCased `SubagentControlStatus` (open enum); `status` stays the generic item vocabulary. */ controlStatus?: SubagentControlStatus; /** `subagent`: nesting depth. */ depth?: number; /** `userMessage`: presentation form (tdd SS3.2); absent when the client sent none. */ displayText?: string; /** `userShell`/`subagent`: observed wall-clock duration. */ durationMs?: number; /** `workflow`: launched entry identity. */ entryId?: string; /** `userShell`: the process exit code, when it exited by code. */ exitCode?: number; /** `userShell`: the terminating signal NUMBER, when signalled (e.g. 9) — the durable payload verbatim; nothing maps numbers to names, and the fold never invents one. */ exitSignal?: number; /** `toolCall`: machine-readable failure class (`TaskFailureKind`, snake_case verbatim — durable runtime vocabulary, the SS1.6 casing exemption). */ failureKind?: string; /** `toolCall`/`subagent`: `Failed`/`Rejected`/`Cancelled` reason text, verbatim. */ failureReason?: string; /** Server-provided one-line human summary any kind MAY carry, for generic rendering of kinds a client does not recognize; new kinds SHOULD carry it during their first release cycle (tdd SS4.10). */ fallbackText?: string; /** `reminderChild`: the reminder generation. */ generationId?: number; /** Bare UUIDv7; the item's identity across its whole lifecycle. Identity rule (tdd SS4.4.1): the task id for task-backed kinds (`toolCall`, `subagent`), the pre-minted commit `message_id` for delta-streamed kinds (`agentMessage`, `reasoning`), and the opening durable record's event id for everything else. Opaque to clients. */ itemId: string; /** The item kind (open enum): clients MUST render unknown kinds generically — kind name plus `status` plus `fallbackText` (tdd SS4.10). */ kind: ItemKind; /** `workflow`: the reconciled terminal message, set on completion. */ message?: string; /** `toolCall`: rich content the model saw beyond text; base64 is not inlined on the view (tdd SS4.5.5). */ modelVisibleContent?: ModelVisibleContent[]; /** `subagent`: objective as spawned. */ objective?: string; /** `compaction`: terminal only — folds installed/fallback status. */ outcome?: CompactionOutcome; /** `toolCall`/`userShell`: stored-output reference; fetch the full bytes via `item/readOutput` (served by #208). */ outputRef?: OutputRef; /** `toolCall`: stored structured-patch reference (`kind: "tool_patch"`, `mediaType: "application/json"`); the body is fetched via `item/readOutput` with `patchRef.id`, and the ref survives the SS2.5.2 elided-snapshot rung exactly like `outputRef` without ever being an elision trigger (tdd SS2.5.2, SS4.5.5; #33025). */ patchRef?: OutputRef; /** `toolCall`: server-authored edit-family diff summary (#33025) — always beside `patchRef`; absent = no diff available (tdd SS4.5.5). */ patchSummary?: PatchSummary; /** `reasoning`: provider reasoning item id (e.g. `rs_...`), for provider-side correlation. */ providerItemId?: string; /** `compaction`: noop/failure reason, verbatim (snake_case durable vocabulary, e.g. `"no_compactable_history"`). */ reason?: string; /** RFC3339 timestamp of the item's driving durable record. Absent on ephemeral-opened items until first durable re-emission (tdd SS4.4.1). */ recordedAt?: string; /** `reminderChild`: the reminder agent's id. */ reminderAgentId?: string; /** `subagent`: the result envelope from `ResultReady` (tdd SS4.5.7). */ result?: SubagentResult; /** `workflow`: set on resumed launches. */ resumeFromRunId?: string; /** `userMessage`: `true` after an accepted retract (tdd SS4.5.1); re-emitted via `item/updated`. */ retracted?: boolean; /** Integer >= 1, strictly monotonic per item; apply rule is replace-iff-higher. `item/delta` never bumps it (tdd SS4.4.1). */ revision: number; /** `subagent`: role as spawned. */ role?: string; /** `workflow`: launched script identity. */ scriptId?: string; /** Open enum; terminal = anything other than `"inProgress"`. Unknown values MUST be treated as terminal-unknown and rendered generically (tdd SS4.4.1). */ status: ItemStatus; /** `userMessage`: `true` when injected mid-turn via `turn/steer` or `ifBusy: "steer"`; absent otherwise. */ steered?: boolean; /** `compaction`: summarizer strategy (installed only). */ strategyId?: string; /** `subagent`: durable child identity (`subagent_id`). */ subagentId?: string; /** `compaction`: opaque provenance string naming the compaction boundary. A compaction-anchored read anchor since D-029 (2026-08-12): accepted by `session/resume` and `view/page` (wire shape and validation are the #208 lane's). Still opaque — clients relay it, never parse it (tdd SS4.5.10). */ summarizedThrough?: string; /** `reasoning`: one entry per summary part; part *n* streams via `item/delta` field `"summary.n"` (part boundary = index change). */ summary?: string[]; /** `reminderChild`: the linked task id. */ taskId?: string; /** `userMessage`: the prompt text as submitted. `agentMessage`: the accumulated reply, streamed via `item/delta` field `"text"`. `reasoning`: raw committed reasoning text where the provider exposes it (never streamed in v1, tdd SS4.5.4). */ text?: string; /** `compaction`: token budget snapshot after, when measured. */ tokensAfter?: number; /** `compaction`: token budget snapshot before, when measured. */ tokensBefore?: number; /** `toolCall`: tool name. */ tool?: string; /** `compaction`: what initiated the compaction. */ trigger?: CompactionTrigger; /** `workflow`: camelCased `WorkflowLaunchTriggerSource`, verbatim (durable runtime vocabulary, e.g. `"modelProposal"`). */ triggerSource?: string; /** `true` when the server's per-surface text budget saturated a streamed surface (`agentMessage.text`, `reasoning.summary[*]`, `toolCall.visibleOutput`, `userShell.visibleOutput`); the durable full text remains in the log (tdd SS4.5.4). */ truncated?: boolean; /** The owning turn (== the submitting `commandId` for fresh turns, tdd SS3.1.4). `null` only for `userShell` — the one kind outside a turn (tdd SS4.5.6). */ turnId?: string | null; /** `subagent`: **transitive** observed usage — the child and its own descendants; updated in place, absent until first observation; never folded into `session/tokenUsage.cumulative` (tdd SS4.6.5). */ usage?: TokenUsage; /** `toolCall`/`userShell`: bounded transcript-visible result text (budget per tdd SS4.5.4); streams via `item/delta` field `"output"`. */ visibleOutput?: string; /** `subagent`/`workflow`: the owning durable workflow run id (opaque string — not a UUID family). */ workflowRunId?: string; } /** `item/completed` params (tdd SS4.3): the item reached its terminal state — the authoritative final object. Always cites a durable `sourceRange` (tdd SS4.2). Clients MUST accept `item/completed` for an `itemId` they never saw `item/started` for (single-shot kinds; after a gap fill; tdd SS4.4.1). */ export interface ItemCompletedParams { /** The full item at its terminal revision. */ item: Item; /** The owning session. */ sessionId: string; /** The durable records this event folded from. */ sourceRange: SourceRange; /** Opaque, strictly monotonic view cursor (tdd SS4.1). */ viewCursor: string; } /** `item/delta` params (tdd SS4.3.1): a UTF-8-safe streaming append to an open item's field. Ephemeral-sourced by definition: this params object has **no** `sourceRange` member at all (spec 14653 INV-009 — the schema enforces the exemption). Deltas never bump `revision`. */ export interface ItemDeltaParams { /** The appended text; concatenation of a field path's deltas in cursor order equals that field's value on `item/completed` unless the surface saturated (spec 14653 INV-005). */ delta: string; /** Dotted field path the append targets (`"summary.0"`, `"output"`, ...); absent means `"text"` (tdd SS4.3.1). */ field?: string; /** The open item being appended to. */ itemId: string; /** The owning session. */ sessionId: string; /** Opaque, strictly monotonic view cursor (tdd SS4.1). */ viewCursor: string; } /** The nine v1 item kinds (tdd SS4.5.2–4.5.10). Open: a new kind is additive evolution, and clients MUST render unknown kinds generically (tdd SS4.10). */ export type ItemKind = | "userMessage" | "agentMessage" | "reasoning" | "toolCall" | "userShell" | "subagent" | "workflow" | "reminderChild" | "compaction" | (string & {}); /** The `item/readOutput` content encoding (tdd SS4.7.4). Closed: text media is ALWAYS `utf8` and binary media `base64`; a third value would change the client's decode contract. */ export type ItemReadOutputEncoding = "utf8" | "base64"; /** `item/readOutput` params (tdd SS4.7.4): byte-ranged fetch of stored full output that the view truncated — the `outputRef` fetch path SS3.9 and SS4.5.5 owe. Read-only; works on loaded and unloaded sessions; no lease. */ export interface ItemReadOutputParams { /** The item whose stored output is fetched. */ itemId: string; /** STORED bytes requested; default and max 6 MiB (tdd SS4.7.4). A value above the max is served at the max. */ lengthBytes?: number; /** STORED-byte offset to start from; 0 when omitted. STORED bytes are a property of the output, not of a transport (tdd SS4.7.4). */ offsetBytes?: number; /** The `outputRef.id` from the item (never the `uri`; the uri is display/provenance). */ outputRef: string; /** The session the item belongs to. */ sessionId: string; } /** `item/readOutput` result (tdd SS4.7.4): one stored-byte page. */ export interface ItemReadOutputResult { /** STORED bytes served in THIS response (not the output's total; that is `outputRef.byteLen` on the item). The next page's `offsetBytes` is `offsetBytes + byteLen` — short-serving and advancing are separate, so paging never skips or double-reads a byte (tdd SS4.7.4). */ byteLen: number; /** The served range, decoded per `encoding`. */ content: string; /** How `content` encodes the stored bytes. */ encoding: ItemReadOutputEncoding; /** `true` when this range reached the end of the stored output. */ eof: boolean; /** The stored output's media type (e.g. `text/plain`). */ mediaType: string; /** The STORED-byte offset this response actually served from. */ offsetBytes: number; } /** `item/started` params (tdd SS4.3): a new item opened on the transcript. `sourceRange` is absent when the item opens on an ephemeral record (the delta-streamed kinds); the item's authoritative open is re-stated by its durable-sourced `item/completed` (tdd SS4.2). */ export interface ItemStartedParams { /** The full item at revision 1. */ item: Item; /** The owning session. */ sessionId: string; /** The durable records this event folded from; absent on an ephemeral-sourced open (spec 14653 INV-009). */ sourceRange?: SourceRange; /** Opaque, strictly monotonic view cursor (tdd SS4.1). */ viewCursor: string; } /** Item status (tdd SS4.4.1). Open; terminal = anything other than `"inProgress"`, and unknown values are terminal-unknown, rendered generically. */ export type ItemStatus = | "inProgress" | "completed" | "failed" | "cancelled" | "rejected" | "timedOut" | (string & {}); /** `item/updated` params (tdd SS4.4.2): an open item changed non-terminally in a way deltas cannot express — the full item re-emitted at a higher revision (apply rule: replace iff higher). */ export interface ItemUpdatedParams { /** The full item at a higher revision. */ item: Item; /** The owning session. */ sessionId: string; /** The durable records this event folded from. */ sourceRange: SourceRange; /** Opaque, strictly monotonic view cursor (tdd SS4.1). */ viewCursor: string; } /** The literal `"2.0"` every frame carries (SS1.2). */ export type JsonRpcVersion = "2.0"; /** `userMessage` image attachment metadata (tdd SS4.5.2): metadata only — the durable bytes live in the log and are reachable on the raw altitude. */ export interface MessageAttachment { /** Pixel height, when known. */ height?: number; /** The image media type (e.g. `"image/png"`). */ mediaType: string; /** Attachment type, `"image"` in v1 (free string: attachment vocabulary grows additively with the runtime's intake surface). */ type: string; /** Pixel width, when known. */ width?: number; } /** One visible catalog row (tdd SS3.10). Catalog rows marked hidden never reach the wire, so a client cannot select one. */ export interface ModelCatalogEntry { /** Context limit; `null` when the catalog source declared nothing. */ contextLimit: number | null; /** Cost block; `null` when the catalog source declared nothing. */ cost: ModelCost | null; /** The row's catalog default. Optional only for decoding older hosts; a present value is never null and is always a member of `variants`. Absent under `"unknown"` (ADR 33400 D2). */ defaultReasoningEffort?: ReasoningEffort; /** Description; `null` when the catalog source declared nothing. */ description: string | null; /** Presentation label. */ displayLabel: string; /** Marks the session's effective model when `sessionId` was supplied. May be false for every row — a client MUST NOT assume exactly one. */ isActive: boolean; /** Marks the catalog's default row. May be false for every row. */ isDefault: boolean; /** The selectable model id. */ modelId: string; /** Output limit; `null` when the catalog source declared nothing. */ outputLimit: number | null; /** Provider profile; `null` when the catalog source declared nothing. */ profileId: string | null; /** Provider routing. */ providerId: string; /** Described selectable tiers, a same-order subset of `variants`. Optional only for decoding older hosts; a present value is never null. Absent under `"unknown"` (ADR 33400 D2). */ reasoningEffortVariants?: ModelDescribedReasoningEffort[]; /** Release date; `null` when the catalog source declared nothing. */ releaseDate: string | null; /** Complete ordered selectable efforts. Optional only for decoding older hosts; a present value is never null. Current hosts always send it. */ variants?: ModelReasoningEffortVariants; } /** Where a model catalog came from (tdd SS3.10). **Open**: an unrecognized value is an unknown source, not an error. */ export type ModelCatalogSource = | "providerCatalog" | "fakeCatalog" | "unresolvedCatalog" | "bundledCatalog" | "configCatalog" | (string & {}); /** What drove a model selection (tdd SS4.6.1). Open. */ export type ModelChangeSource = "user" | "default" | "policy" | (string & {}); /** Per-1M-token catalog cost, carried **verbatim** for display and never rounded or re-formatted by the host (tdd SS3.10). Cost arithmetic stays client-local view math. */ export interface ModelCost { /** Cached-input cost, a decimal string. */ cached: string; /** Currency; nullable — today's catalogs are USD. */ currency: string | null; /** Input cost, a decimal string. */ input: string; /** Output cost, a decimal string. */ output: string; } /** One described reasoning-effort tier of a `model/list` row (tdd SS3.10, ADR 33400 D2): a selectable tier plus the catalog's display string for it when declared. */ export interface ModelDescribedReasoningEffort { /** The catalog's per-tier display string; absent when the catalog declared none. Optional only for decoding; a present value is never null. */ description?: string; /** The tier, in the closed D-024 vocabulary. */ tier: ReasoningEffort; } /** `model/list` params (tdd SS3.10): the discovery half of the model-picker gesture. **A query, not a command** — no `commandId`, no durable intake record, no view event. */ export interface ModelListParams { /** When present, the row matching that session's effective model is flagged `isActive`. When absent, no row is active — a client may list before it has a session (tdd SS3.10). */ sessionId?: string; } /** `model/list` result (tdd SS3.10). A snapshot at call time: v1 has no catalog subscription. `models` MAY be empty — a build shipped with no bundled models is a supported configuration. */ export interface ModelListResult { /** Visible rows only, newest `releaseDate` first. */ models: ModelCatalogEntry[]; /** The catalog's profile; `null` when none. */ profileId: string | null; /** The catalog's provider. */ providerId: string; /** Where the catalog came from — how a client tells a live provider catalog from a test fake and labels it honestly. */ source: ModelCatalogSource; } /** A complete ordered effort set, or an explicit unknown capability. */ export type ModelReasoningEffortVariants = ReasoningEffort[] | UnknownModelReasoningEffortVariants; /** A model selection (tdd SS3.8). Empty strings are normalized to absent. */ export interface ModelSelection { /** Presentation label. */ displayLabel?: string; /** Catalog model id. Required. */ modelId: string; /** Provider profile. Omitted and explicit `null` both mean "no profile" (#23468). */ profileId?: string | null; /** Provider routing. */ providerId?: string; } /** Rich content the model saw beyond text (tdd SS4.5.5, `ModelVisibleToolContent`): metadata only — fetch bytes via `item/readOutput` when an `outputRef` exists. */ export interface ModelVisibleContent { /** Pixel height, when known. */ height?: number; /** The content media type. */ mediaType: string; /** The recorded content path. */ path: string; /** The tool that produced the content. */ sourceToolName: string; /** Content type, `"image"` in v1 (free string, grows with the durable vocabulary). */ type: string; /** Pixel width, when known. */ width?: number; } /** A notification frame, either direction (SS1.2 §2.2). No `id`; a notification is never answered. */ export interface Notification { /** Emission time in Unix milliseconds, recorded once at emission; server→client notifications only (SS1.2.5). Optional on the wire so decoders tolerate older servers. */ emittedAtMs?: number; /** The literal `"2.0"`. */ jsonrpc: JsonRpcVersion; /** Notification method name. */ method: string; /** Method-specific parameters; omitted entirely when empty. */ params?: Record; } /** Stored-output reference (tdd SS4.5.5): the camelCased fold of the durable `ToolOutputRef`. The fetch path is `item/readOutput` (#208). */ export interface OutputRef { /** Whether the bytes are servable (tdd SS4.5.5). */ availability: OutputRefAvailability; /** Stored byte length. */ byteLen: number; /** Content digest (e.g. `"sha256:..."`), when recorded. */ digest?: string; /** The stored output's durable id. */ id: string; /** The stored output's kind, verbatim durable vocabulary (e.g. `"tool_output"`; snake_case per the SS1.6 casing exemption). */ kind: string; /** Media type, when recorded. */ mediaType?: string; /** Stored path, when recorded. */ path?: string; /** The stored output's URI. */ uri: string; } /** Whether a stored output's bytes are servable (tdd SS4.5.5). Open — durable runtime vocabulary may grow additively. */ export type OutputRefAvailability = | "available" | "missing" | "unsupported" | "accessFailed" | (string & {}); /** Server-authored edit-family diff summary (tdd SS4.5.5, #33025): `files` counts the stored patch document's file entries; `added` and `removed` are the total `+`/`-` prefixed LINE counts summed over the stored patch's hunks across all files — line counts, never hunk or byte counts. Rides the `toolCall` item beside `patchRef`; the body is fetched via `item/readOutput` with `patchRef.id`. */ export interface PatchSummary { /** Total `+`-prefixed line count across all files' hunks. */ added: number; /** File entries in the stored patch document. */ files: number; /** Total `-`-prefixed line count across all files' hunks. */ removed: number; } /** A pending approval in the snapshot: the SS2.5.2 pointer shape plus the gated `itemId` when one exists (tdd SS4.9.1). */ export interface PendingApprovalPointer { /** The pending approval's id. */ approvalId: string; /** The parked item, when one exists. */ itemId?: string; /** The cursor the approval opened at. */ viewCursor: string; } /** The `pendingRequests` discriminator (tdd SS2.5.2). Open enum, v1 values `approval` and `userInput`. */ export type PendingRequestKind = "approval" | "userInput" | (string & {}); /** A late-joiner pointer at an unsettled server-initiated request (tdd SS2.5.2, SS2.2.1). The full payloads arrive as re-issued server-to-client requests right after a `session/resume` response (tdd SS5.6); `session/read` never re-issues them (tdd SS2.5.5). **A second E4 instance, RULED with E4 (#22785, owner, 2026-08-26): the flat discriminated-object precedent is accepted for this type too, on the `ApprovalSubject` precedent, with the serialized JSON unchanged. A strict union node kind may be funded later; if it is, it must cover both this type and `TurnInputPart`.** SS2.5.2 ratifies two kind-discriminated entry shapes (`{kind: "approval", approvalId, viewCursor}` / `{kind: "userInput", userInputId, viewCursor}`); this is one flat object with both ids optional, so the published schema accepts `{"kind":"approval","userInputId":…}` and an entry carrying no id at all. The v1 model names no object-variant union (the `ApprovalSubject` precedent, followed for `TurnInputPart`), and this instance differs from that one in a way the ruling should see: `kind` here is an OPEN enum, where `TurnInputPart.type` is closed. */ export interface PendingRequestPointer { /** Present on an `approval` entry. */ approvalId?: string; /** The discriminator; v1 values `approval` and `userInput`. */ kind: PendingRequestKind; /** Present on a `userInput` entry. */ userInputId?: string; /** The cursor the request opened at. */ viewCursor: string; } /** A pending user-input prompt in the snapshot (tdd SS4.9.1, SS5.10). */ export interface PendingUserInputPointer { /** The parked item, when one exists. */ itemId?: string; /** The pending prompt's id. */ userInputId: string; /** The cursor the prompt opened at. */ viewCursor: string; } /** The server runtime's platform family (SS1.4.1); may differ from the client's. Closed: SS1.4.1 fixes the value set, so widening it is a deliberate, gate-visible protocol change rather than a silent addition (a later `Closed`→`Open` flip is itself additive, data-model.md §5.2). */ export type PlatformFamily = "unix" | "windows"; /** The server's operating system (SS1.4.1). Closed, for the same reason as [`PlatformFamily`]. */ export type PlatformOs = "macos" | "linux" | "windows"; /** The reasoning-effort tier sampled at submission (tdd SS3.2, SS3.3). The **same closed tier vocabulary** on both the fresh-turn and steer lanes, spelled identically; invalid tiers are invalid params. `none` is a tier of the vocabulary (ask for no reasoning), not a way to say "unset". */ export type ReasoningEffort = | "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | "ultra"; /** What drove a reasoning-effort default change (tdd SS4.6.9). Open; v1's only producer is `user` (an accepted `session/setReasoningEffort`). */ export type ReasoningEffortChangeSource = "user" | "default" | "policy" | (string & {}); /** The snapshot's standing session-default reasoning effort (tdd SS4.9.1, ADR 31255 D1): the fold of the latest completed `runtime.reasoning_effort_reconfigure` fact — the same pair `session/reasoningEffortChanged` carries. */ export interface ReasoningEffortState { /** The standing default tier — the closed SS3.2 vocabulary, spelled identically to `turn/start.reasoningEffort`. */ reasoningEffort: ReasoningEffort; /** Which actor class set the default. */ source: ReasoningEffortChangeSource; } /** One end of a [`SourceRange`]: a record's event id and its sequence number within the stream (tdd SS4.2). */ export interface RecordPosition { /** The record's event id. */ id: string; /** The record's sequence number within its stream. */ sequence: number; } /** A request frame, either direction (SS1.2 §2.1). */ export interface Request { /** Client-chosen id, unique among that client's in-flight requests. */ id: RequestId; /** The literal `"2.0"`. */ jsonrpc: JsonRpcVersion; /** Slash-namespaced camelCase method name. */ method: string; /** Method-specific parameters; omitted entirely when empty, never `null`. */ params?: Record; /** W3C trace passthrough (SS1.8); requests only. */ trace?: TraceContext; } /** A request id (SS1.3): client-chosen string or integer. `1` and `"1"` do not compare equal; each direction owns its own id space. */ export type RequestId = number | string; /** The SS5.3.3 presentation receipt — the client's response to a server-initiated request (`approval/request`, `userInput/request`). The response acknowledges presentation only ("a surface showed or will show this"): it changes no state, the server uses it for diagnostics alone, and the decision/answer travels as a command (`approval/decide`, `userInput/answer`). An error response or a dropped connection means this connection could not present the request; the approval or prompt stays pending and the request is re-issued on the next subscribe (SS5.6). There is no dismiss-without-deciding on the wire. */ export interface RequestReceipt {} /** The `schema` pair in [`InitializeResult`] (SS1.4.1, SS1.5.3). `version` is the wire **envelope** schema version — distinct from the session-view `schemaVersion`, the raw-log `schema_version`, and the 0.x/1.0 stability posture, which is not on the wire at all (INV-006a). */ export interface SchemaInfo { /** `sha256:<64 lower hex>` content hash of this server binary's stable-surface bundle (INV-003). A mismatch is a warning condition, not an error (SS1.4.1). */ fingerprint: string; /** Envelope schema version; `1` in v1, expected to stay `1` for a long time (SS1.4.1). */ version: number; } /** Server identification inside [`InitializeResult`]. */ export interface ServerInfo { /** Server name. */ name: string; /** Server version string. */ version: string; } /** The session object every lifecycle method returns or lists (tdd SS2.4). Additive-optional evolution applies: clients must ignore unknown fields. */ export interface Session { /** The `turnId` of the current foreground turn when `status` is `running`, and `null` when the session is idle (tdd SS2.4). **Required-nullable, per the owner ruling on #22946** ("approve required-nullable", review comment `r3863946961`, 2026-08-26). Both production writers hard-code `"activeTurnId": null` (`session/start/commit_load.rs` for `session/start`, `session/snapshot.rs` feeding resume/read/list/fork) and nothing strips it, so this is what the binary emits and what SS2.4's example spells. The optional-absent shape published it as plain `string` and REJECTED every idle `Session` frame the host sent — the #19923 defect class this PR exists to close. E5's original evidence for optional-absent ("every committed transcript shows the omission") was wrong: those transcripts are hand-authored fixtures, not host recordings. They are corrected in the same change under the ruling's SS1.5 `regenerationJustification`. */ activeTurnId: string | null; /** The folded effective approval mode. **Additive-optional**: a Session object that omits it means the host has not folded a mode, which is why the index-derived `session/list` entry may legitimately omit it (tdd SS2.4, SS5.12). */ approvalMode?: EffectiveApprovalModeState; /** Attention flags (tdd SS2.4, ADR 31983 D3). **Additive-optional**, present only when at least one flag is set; absence is a NON-assertion (nothing pending, or the loaded session's pending source declined to answer). Loaded sessions only: a `notLoaded` row omits it even while its durable pending set is non-empty. */ attention?: AttentionFlag[]; /** Derived workspace branch (tdd SS2.14.1, #27598) — the index's last derived value; the live-change signal stays `session/branchChanged` (SS4.6.4). **Additive-optional**, omitted when underivable. */ branch?: string; /** RFC3339. For a fork this is the fork session id's UUIDv7 mint instant (tdd SS2.4). */ createdAt: string; /** Derived first-user-prompt preview (tdd SS2.14.1, #27598). **Additive-optional**, omitted when underivable. */ firstUserPrompt?: string; /** `null` for root sessions; fork provenance otherwise (tdd SS2.4). */ forkedFrom: ForkProvenance | null; /** Content-activity recency, RFC3339 (tdd SS2.4, ADR 31983 D5). **Additive-optional**: omitted when no content record exists. Never advanced by lifecycle bookkeeping (the resume marker, re-stamps) or a fork's copied seed-replay records, and never precedes `createdAt`. */ lastActivityAt?: string; /** The winning metadata fold's model; `null` when that record omits it. */ modelId: string | null; /** The durable allocated session name (tdd SS2.4/SS2.14.1, #27598; ADR 27598 D2/D4). **Additive-optional**: present when the serving path holds an allocated name, omitted otherwise — absent is never fabricated. Authoritative and renameable via `session/rename`. */ name?: string; /** Absolute path of the session's durable log; non-nullable. Under the ephemeral session profile it is the **empty string**, meaning "no durable log exists" (tdd SS2.13.2) — the one value a client must not hand to a filesystem call. */ path: string; /** The winning metadata fold's provider; `null` when that record omits it. */ providerId: string | null; /** The session identity. */ sessionId: string; /** Load state as this host knows it; `session/list` reports `notLoaded` for sessions loaded by *other* hosts (tdd SS2.4). */ status: SessionStatus; /** Derived display title (tdd SS2.14.1, #27598): a heuristic that may evolve — its carriage, not its derivation, is the contract. **Additive-optional**, omitted when underivable. */ title?: string; /** Completed-turn count from the session view fold (tdd SS2.4). */ turnCount: number; /** RFC3339; never precedes `createdAt` (tdd SS2.4). */ updatedAt: string; /** The winning metadata fold's workspace root; `null` when that record omits it — absent is never fabricated (tdd SS2.4). */ workspaceRoot: string | null; } /** `session/approvalModeChanged` params (tdd SS5.12): the fold of the durable approval-mode reconfigure audit fact — every accepted change writes one; a mode flip without an audit fact is a runtime bug by design. */ export interface SessionApprovalModeChangedParams { /** The requesting client's `clientInfo.name` (tdd SS1.4.1), recorded on the audit fact. */ clientName: string; /** The command that changed it. */ commandId: string; /** The mode now in effect. */ mode: ApprovalMode; /** The owning session. */ sessionId: string; /** How the mode took effect. */ source: ApprovalModeSource; /** The durable records this event folded from. */ sourceRange: SourceRange; /** Opaque, strictly monotonic view cursor (tdd SS4.1). */ viewCursor: string; } /** `session/branchChanged` params (tdd SS4.6.4): a durable workspace-branch observation landed. */ export interface SessionBranchChangedParams { /** The observed branch; `null` on a detached-HEAD observation — a fact, not "unchanged" (tdd SS4.6.4). */ branch?: string; /** The owning session. */ sessionId: string; /** The durable records this event folded from. */ sourceRange: SourceRange; /** The detected version-control system; absent when no repository was detected. */ vcs?: Vcs; /** Opaque, strictly monotonic view cursor (tdd SS4.1). */ viewCursor: string; /** The observed workspace root. */ workspaceRoot: string; } /** `session/closed` params (tdd SS2.6.2; enrolled by #33065): a loaded session was unloaded from this host, broadcast to every initialized connection. After it, the session is `notLoaded`; the log remains on disk and `session/resume` reloads it. A crash emits nothing — only the two orderly unload paths do, and both write the durable `SessionEnd` record first. */ export interface SessionClosedParams { /** Which orderly unload path fired. */ reason: SessionClosedReason; /** The unloaded session. */ sessionId: string; /** The final view head; a client that stores it can later `session/resume {cursor}` and receive exactly the (empty) suffix. An **opaque** view cursor: clients relay it, never parse it (tdd SS4.1). **Required-nullable**: the producers always write the member and write `null` when the final fold failed at unload (`session/idle.rs`, `serve/shutdown.rs`; PR #16779 review) — the host defines no cursor values of its own and never invents one, and the subscriber still learns the session closed. */ viewCursor: string | null; } /** The SS2.6.2 closed-reason vocabulary. Server-produced and published OPEN by owner ruling — the #33065 menu-B pick (PR #33201 comment 5638727249, recorded in the enrollment decision record), which settles that this notification reason enum publishes open rather than resting on E2's result-vocabulary rule by analogy. A crash is deliberately not a reason, because a crash emits no notification at all. */ export type SessionClosedReason = "idle" | "hostShutdown" | (string & {}); /** `session/compact` params (tdd SS3.7): manually compact the session's conversation context — the `/compact` gesture. Compaction runs asynchronously; the ack is admission only. */ export interface SessionCompactParams { /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The target session. */ sessionId: string; /** The run whose context to compact. Omit and the server resolves the session's current/latest run; a session with no resolvable run rejects with `commandRejected` reason `missing_run` (tdd SS3.7). Any syntactically valid UUID: a turn from an older session may carry a v4 or v5 id. A malformed id is `invalidParams`. */ turnId?: string; } /** `session/compact` result (tdd SS3.7). Failures *after* admission (`summarizer_failed`, `install_rejected`, `cancelled`) are not wire errors — they arrive as the compaction's terminal view event. */ export interface SessionCompactResult { /** Echoes the client's id. */ commandId: string; /** Why the command was a noop, e.g. `no_compactable_history`. Present on a `noop` status (tdd SS3.7). */ reason?: string; /** Admission status, or `noop`. */ status: CompactStatus; } /** The open configuration extension object shared by `session/start` and `session/resume` (ADR 32760 D1). Unknown keys are ignored on the wire, never rejected (tdd SS1.5.4, spec 206 INV-015; D-052 resolving [#23456](https://github.com/mslsrc/tbh/issues/23456)): the live decoder is D-042's tolerant path, and TEST-024 keeps every exported bundle free of `additionalProperties: false`. The Rust typed model's `deny_unknown_fields` is internal and never exported — the #22785 E6b closedness export applies nowhere, and the `x-msp-closed` opt-in mechanism stays inert. Recognized `mcpServers` values are typed and validated before they leave the wire boundary. */ export interface SessionConfig { /** Native MCP servers added only to this session runtime. */ mcpServers?: Record; } /** `session/contextUsage` params (tdd SS4.6.6, #14405): context-window pressure — the counted-once occupancy at the latest provider-reported durable fact, joined with the host's pressure basis. Replace wholesale; emitted only when the `(windowTokens, usedTokens, pressure)` triple changes value (identical adoptions emit nothing). */ export interface SessionContextUsageParams { /** Server-computed pressure level over the basis thresholds. */ pressure: ContextPressureLevel; /** The owning session. */ sessionId: string; /** The durable records this event folded from. */ sourceRange: SourceRange; /** Counted-once prompt tokens (#8803) plus output tokens of the driving record, saturating — the honest occupancy floor. */ usedTokens: number; /** Opaque, strictly monotonic view cursor (tdd SS4.1). */ viewCursor: string; /** The effective context-window size from the host's pressure basis; absent when the basis has no limit — the limit part is omitted, never invented (tdd SS4.6.6). */ windowTokens?: number; } /** The persisted deletion terminal, separate from admission (SS3.24). The shared schema is one object. Actual failed producers send both optional fields; completed producers omit both. Clients enforce those obligations before interpreting a known outcome. Preserve unknown strings without treating them as successful completion. */ export interface SessionDeleteCompletedParams { /** Idempotency key of the original deletion command. */ commandId: string; /** Deletion result; an unknown value leaves the command pending. */ outcome: SessionDeleteOutcome; /** Erasure evidence for a failed result; omitted for a completed result. */ physicalChange?: SessionDeletePhysicalChange; /** Required for a failed result and omitted for a completed result. */ reason?: SessionDeleteFailureReason; /** Session named by the original deletion command. */ sessionId: string; } /** Stable deletion-failure vocabulary known to this version (SS3.24). The server emits only these values. Future reason strings remain an open result vocabulary; consumers cannot infer completion from any reason. */ export type SessionDeleteFailureReason = | "ownershipUnavailable" | "sharedSource" | "writerBusy" | "unsafeSource" | "sourceChanged" | "quiescenceFailed" | "cancelled" | "storageFailure" | "cleanupIncomplete" | "unsupportedLayout" | (string & {}); /** Known terminal outcomes. A future outcome cannot authorize success or exit. */ export type SessionDeleteOutcome = "completed" | "failed" | (string & {}); /** `session/delete` params. The host validates a non-nil legacy-valid UUID target and a UUID-v7 command identity before admission. Unknown members are ignored and do not enter the normalized command identity (SS1.5.4). */ export interface SessionDeleteParams { /** UUID-v7 idempotency key for this deletion command. */ commandId: string; /** Non-nil UUID of the session selected for deletion. */ sessionId: string; } /** The failed attempt's immutable snapshot of persisted physical evidence. `possible` is recorded before a detach/unlink, `confirmed` after a proved owned effect. A failure never resets that evidence merely because the session path is absent. Unknown strings remain representable; consumers must treat them conservatively as `possible`. */ export type SessionDeletePhysicalChange = "none" | "possible" | "confirmed" | (string & {}); /** Whether this host writes its sessions to disk (SS1.4.1, SS2.13). A property of the host process, fixed at construction and identical for every session and every connection it serves — never requested, granted, or negotiated, which is why it is not a capability. Open: the unrepresented degraded state (#14401) has candidate resolutions that add a third value here, so closed would make that a breaking change. */ export type SessionDurability = "durable" | "ephemeral" | (string & {}); /** `session/fork` params (tdd SS2.5.3). */ export interface SessionForkParams { /** The SS2.5 idempotency handle (UUIDv7). */ commandId: string; /** Copy history through a completed turn, inclusive. Omitted means "all completed turns" (tdd SS2.5.3). */ cutPoint?: ForkCutPoint; /** Skip inline history in the result and page it later — same as `session/resume` (tdd SS2.5.3). */ excludeItems?: boolean; /** The source session. */ sessionId: string; } /** `session/fork` result (tdd SS2.5.3): the `session/resume` envelope for the **new** session, whose `session.forkedFrom` carries the provenance. */ export interface SessionForkResult { /** The served history. */ history: SessionHistory; /** The late-joiner pointer set. */ pendingRequests: PendingRequestPointer[]; /** The new fork session, carrying `forkedFrom` provenance. */ session: Session; /** The new session's view head. */ viewCursor: string; } /** `session/goalChanged` params (tdd SS4.6.2): the projected goal block's value changed — identical adoptions emit nothing (the change gate), and an explicit `null` clears. Replace wholesale; `null` never means unchanged. */ export interface SessionGoalChangedParams { /** The full current goal block, or `null` to clear. */ goal?: Goal; /** The owning session. */ sessionId: string; /** The durable records this event folded from. */ sourceRange: SourceRange; /** Opaque, strictly monotonic view cursor (tdd SS4.1). */ viewCursor: string; } /** The `history` envelope shared by `session/resume`, `session/fork`, and `session/read` (tdd SS2.5.2). */ export interface SessionHistory { /** The full folded item array when `mode` is `inline`; `null` otherwise. */ items: Item[] | null; /** What was actually served — never what was asked for (tdd SS2.5.2). */ mode: HistoryMode; /** Why no history was served — sent exactly when `mode` is `"none"` (tdd SS2.5.2; D-050, spec 208 INV-19734-1). */ noneReason?: HistoryNoneReason; /** The folded view state when `mode` is `snapshot` or `anchoredSnapshot`; `null` otherwise. */ snapshot: ViewSnapshot | null; } /** `session/listChanged` params (#33084, ADR 33084 D3): one changed row of the `session/list` shape — the full SS2.4 Session object as the answering host's list face serves it at emission (the ADR 29243 live-overlaid row), a replace, never a delta. Emitted only on connections that negotiated the `sessionListStream` capability at `initialize` (ADR 33084 D2); row birth stays on `session/started`, unload pairs with `session/closed`. */ export interface SessionListChangedParams { /** The served list row for the changed session. */ session: Session; } /** `session/list` params (tdd SS2.5.4). Read-only; never touches leases. */ export interface SessionListParams { /** Opaque page cursor from a prior result. Page cursors are a distinct opaque-string family from view cursors and stream cursors, valid only for re-issuing the same listing (tdd SS2.5.4). Omitted and explicit `null` both mean "first page" (#23468). */ cursor?: string | null; /** Page size; default 50, max 200 — the cap is published under #22785 E6c (owner-ruled 2026-08-26). Maximum 200. */ limit?: number; /** Only sessions with log activity after this RFC3339 instant. */ updatedAfter?: string; /** Only sessions whose metadata workspace root equals this path. */ workspaceRoot?: string; } /** `session/list` result (tdd SS2.5.4). Ordering is `updatedAt` descending. */ export interface SessionListResult { /** The next page's cursor; `null` on the last page. */ nextCursor: string | null; /** The page of stored sessions. */ sessions: Session[]; } /** One native MCP server supplied at session construction (ADR 32760 D1). **Closed union** (#33295 owner ruling A1, extending D-033/D-050 to `oneOf`): a validator MUST reject an undeclared `transport` arm — the server fails `session/start` decode on an unknown transport, and a future transport arrives as an explicit schema addition. */ export type SessionMcpServerConfig = | { /** Ordered child arguments. */ args?: string[]; /** Executable name or path. Configuration diagnostics never echo it. */ command: string; /** Explicit child environment additions. */ env?: Record; /** Stdio framing mode; defaults to automatic detection. */ framing?: SessionMcpStdioFraming; /** Required/optional startup posture; defaults to required. */ mode?: SessionMcpServerMode; transport: "stdio"; } | { /** Explicit request headers. */ headers?: Record; /** Required/optional startup posture; defaults to required. */ mode?: SessionMcpServerMode; transport: "streamableHttp"; /** HTTP(S) endpoint. Configuration diagnostics never echo it. */ url: string; }; /** Startup failure posture for a session MCP server. */ export type SessionMcpServerMode = "required" | "optional"; /** Stdio framing choices exposed by session MCP configuration. */ export type SessionMcpStdioFraming = "auto" | "contentLength" | "lineDelimitedJson"; /** `session/modelChanged` params (tdd SS4.6.1): a durable model-selection record landed (tdd SS3.8). */ export interface SessionModelChangedParams { /** The selected model. */ modelId: string; /** The selected provider; `null` when the selection names none. */ providerId?: string; /** The owning session. */ sessionId: string; /** What drove the selection. */ source: ModelChangeSource; /** The durable records this event folded from. */ sourceRange: SourceRange; /** Opaque, strictly monotonic view cursor (tdd SS4.1). */ viewCursor: string; } /** `session/modelRouteUnserved` params (#25603, ADR 25603 D1, spec 5469 Amendment 16): an accepted `login.credential_update` installed a provider that cannot serve the session's STANDING model route. Disclosure only — the standing selection is unchanged (no `session/modelChanged` fires) and the repair path is a routable `session/setModel`. Folded from the durable `runtime.provider_reconfigure.standing_route_unserved` record; additive — clients that predate it skip the unknown method. */ export interface SessionModelRouteUnservedParams { /** The command whose accepted swap installed the provider. */ commandId: string; /** The provider id the swap installed. */ installedProviderId: string; /** The standing (still bound, now unroutable) model. */ modelId: string; /** The standing model's provider; `null` when the selection names none. */ providerId?: string; /** The owning session. */ sessionId: string; /** The durable records this event folded from. */ sourceRange: SourceRange; /** Opaque, strictly monotonic view cursor (tdd SS4.1). */ viewCursor: string; } /** `session/nameChanged` params (tdd SS4.6.7, #27598): the fold of ANY durable session-name record — the FIRST-NAMING automatic allocate as well as an accepted `session/rename` (or the same in-process runtime command). Replace-wholesale like every SS4.6 sibling. */ export interface SessionNameChangedParams { /** The new canonical name now in effect. */ name: string; /** The owning session. */ sessionId: string; /** The durable records this event folded from. */ sourceRange: SourceRange; /** Opaque, strictly monotonic view cursor (tdd SS4.1). */ viewCursor: string; } /** `session/read` params (tdd SS2.5.5): read one stored session **without attaching** — no writer lease, no load, no subscription, no `SessionResumed` record. */ export interface SessionReadParams { /** Metadata-only unless you ask: `false` carries the folded item history. Same name and polarity as `session/resume`/`session/fork`; only the default differs — here it is `true` (tdd SS2.5.5). */ excludeItems?: boolean; /** The session to read. */ sessionId: string; } /** `session/read` result (tdd SS2.5.5). The `viewCursor` is the fold head at read time — a point-in-time read, immediately stale if a foreign host is appending. */ export interface SessionReadResult { /** The served history. */ history: SessionHistory; /** The same pointer shape as `session/resume`. Because `session/read` never subscribes this is a point-in-time log read only: no requests are re-issued after it (tdd SS2.5.5). */ pendingRequests: PendingRequestPointer[]; /** The session as folded point-in-time. */ session: Session; /** The fold head at read time. */ viewCursor: string; } /** `session/reasoningEffortChanged` params (tdd SS4.6.9, ADR 31255 D1): a durable reasoning-effort reconfigure record landed (tdd SS3.21). Replace wholesale, latest wins; the snapshot carries the latest value (SS4.9.1). */ export interface SessionReasoningEffortChangedParams { /** The new session default: the closed eight-string tier vocabulary of tdd SS3.2, spelled identically. */ reasoningEffort: ReasoningEffort; /** The owning session. */ sessionId: string; /** What drove the change. */ source: ReasoningEffortChangeSource; /** The durable records this event folded from. */ sourceRange: SourceRange; /** Opaque, strictly monotonic view cursor (tdd SS4.1). */ viewCursor: string; } /** `session/rename` params (tdd SS2.14.2, #27598): set or change the durable allocated session name through the runtime `session_name` command. One writer; withheld under the ephemeral profile. */ export interface SessionRenameParams { /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The requested name; the runtime's normalization and validation apply. */ name: string; /** The target session. */ sessionId: string; } /** `session/rename` result (tdd SS2.14.2, #27598): `name` is the canonical (normalized) name the durable record settled. */ export interface SessionRenameResult { /** Echoes the client's id. */ commandId: string; /** The settled canonical name. Omitted on the `RecoveryPending` arm, which answers `{commandId, status: "accepted"}` and delivers the name via `session/nameChanged` / `Session.name` (tdd SS2.14.2). */ name?: string; /** Admission status. */ status: CommandStatus; } /** `session/resume` params (tdd SS2.5.2). */ export interface SessionResumeParams { /** The SS2.5 idempotency handle (UUIDv7). A resume that loads a session writes a durable `SessionResumed` record. */ commandId: string; /** The same open construction-time extension object as `session/start`. */ config?: SessionConfig; /** A view cursor previously observed by this client — or an observed `summarizedThrough` compaction anchor (tdd SS4.5.10, D-029). When present the server returns only the suffix and `history.mode` is `none` (tdd SS2.5.2). Omitted and explicit `null` both mean "no cursor" (#23468). */ cursor?: string | null; /** Return only session metadata and live resume state; page history separately with `view/page`. Default `false` (tdd SS2.5.2). */ excludeItems?: boolean; /** History mode preference, default `auto`. A PREFERENCE, not a budget override: when the requested mode does not fit the history budget the server downgrades it and `history.mode` reports what was actually served (tdd SS2.5.2). Ignored when `cursor` or `excludeItems` makes it moot. */ history?: HistoryPreference; /** The session to load. */ sessionId: string; } /** `session/resume` result (tdd SS2.5.2). */ export interface SessionResumeResult { /** The served history. */ history: SessionHistory; /** The late-joiner pointer set; empty when nothing is pending. */ pendingRequests: PendingRequestPointer[]; /** The loaded session. */ session: Session; /** The session view head; the connection is subscribed after it. A still-loaded session a prior `view/unsubscribe` detached is RE-ATTACHED by this resume (spec 208 FR-002a, #28920): live delivery resumes from this head. Explicit-cursor re-attach with `(after, head]` engine replay stays `view/subscribe` (SS4.7.1). */ viewCursor: string; } /** `session/setApprovalMode` params (tdd SS5.12): switch the session's approval enforcement mode mid-session. A standard SS3 command. **Select, never create.** A client may *select* a mode the host's configuration already defines; it may not construct one, supply inline rules, or otherwise describe a policy on the wire — which is why [`ApprovalMode`] is closed. */ export interface SessionSetApprovalModeParams { /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The preconfigured mode to select. The requesting actor is recorded from the connection's `clientInfo.name` (tdd SS1.4.1). */ mode: ApprovalMode; /** The target session. */ sessionId: string; } /** `session/setApprovalMode` result (tdd SS5.12). Applies next-action — an in-flight tool action's pending approval is not retroactively decided by a mode change. */ export interface SessionSetApprovalModeResult { /** Whether the change did anything. */ applyOutcome: ApprovalModeApplyOutcome; /** Echoes the client's id. */ commandId: string; /** The folded effective-mode projection — the same object the `Session` carries as `approvalMode` (tdd SS2.4, SS5.12). */ effectiveMode: EffectiveApprovalModeState; /** Admission status. */ status: CommandStatus; } /** `session/setModel` params (tdd SS3.8): the model-picker gesture. The selection is durable and applies to subsequent model calls. */ export interface SessionSetModelParams { /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The selection. */ model: ModelSelection; /** The target session. */ sessionId: string; } /** `session/setModel` result (tdd SS3.8). If a turn is running the selection is admitted now and applied at the next model-call boundary; the ack does not wait for that boundary. */ export interface SessionSetModelResult { /** Echoes the client's id. */ commandId: string; /** Admission status. */ status: CommandStatus; } /** `session/setReasoningEffort` params (tdd SS3.21, ADR 31255 D1): set the session's standing reasoning-effort default. A turn carrying its own `reasoningEffort` overrides it for that turn only; the default overrides the host's configured default. Same accept/reject and `commandId` idempotency shape as `session/setModel` (SS3.8). */ export interface SessionSetReasoningEffortParams { /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The new session default: the closed eight-string tier vocabulary `turn/start` carries (SS3.2), spelled identically. Invalid tiers are invalid params. A default of `max` rides provider requests verbatim, never clamped (ADR 28621 D8, ADR 31131 D1). */ reasoningEffort: ReasoningEffort; /** The target session. */ sessionId: string; } /** `session/setReasoningEffort` result (tdd SS3.21). The default is durable on ack and applies to turns launched after admission; a running turn keeps the request options it already resolved. */ export interface SessionSetReasoningEffortResult { /** Echoes the client's id. */ commandId: string; /** Admission status. */ status: CommandStatus; } /** `session/start` params (tdd SS2.5.1). */ export interface SessionStartParams { /** The session's starting approval mode; server default when omitted or explicit `null` — both spellings select the default (#23468). Select, never create — the value names a mode the host's configuration already defines (tdd SS2.5.1, SS5.12). This is the only surface that declares a non-interactive run's policy (tdd SS5.11, D-008). */ approvalMode?: ApprovalMode | null; /** The SS2.5 idempotency handle (UUIDv7). Required; the server never mints one. */ commandId: string; /** Reserved for per-session overrides owned by a future Configuration section. Issue #32760 admits only its `mcpServers` member. */ config?: SessionConfig; /** Initial model; server default when omitted. */ modelId?: string; /** Initial provider routing; server default when omitted or explicit `null` — both spellings select the default (#23468). */ providerId?: string | null; /** Exact identity for this new root session. When omitted the server mints a UUIDv7. This field never selects an existing session: a retained or reserved id is rejected `commandRejected` with reason `session_id_conflict` (tdd SS2.5.1). */ sessionId?: string; /** Absolute path, folded into the first metadata record. */ workspaceRoot?: string; /** The session's initial runtime workspace-root set: ordered absolute canonical existing directory paths; the first root is the CWD and plays the primary-root role; every root receives the ADR 11237 `:workspace_roots` rules; extra roots grant no Project Trust. When `workspaceRoot` is also present the two must name the same folder, compared on canonical forms (the raw `workspaceRoot` is canonicalized first; ADR 37313 D9), or the request is invalid params, and so is explicit `null` (the D-049 null-tolerant set is closed and excludes this member). Omitted preserves single-root behavior (tdd SS2.5.1, ADR 37313, #37313). */ workspaceRoots?: string[]; } /** `session/start` result (tdd SS2.5.1). */ export interface SessionStartResult { /** The new session. */ session: Session; /** The session view head after the start fold; the connection is subscribed and receives every view event after this cursor. A deduplicated retry returns this same result (tdd SS2.5.1). */ viewCursor: string; } /** `session/started` params (tdd SS2.6.1; enrolled by #33065): a session became newly loaded on this host via `session/start` or `session/fork` (never `session/resume` — Appendix C, OQ-F), broadcast to every initialized connection. The one member is the same `$defs/Session` object the `session/start`/`session/fork` results carry, so the broadcast and the result describe one fact through one type — the host builds the broadcast payload as a `$defs/Session` — the fresh-start arm reuses the result's `session` member, the start-replay arm builds the live attach snapshot — and the emission is parity-gated against this type at the producer (`session-server` prod-assembly capture) and over the committed transcript corpus (conformance `session_lifecycle_enrollment`). */ export interface SessionStartedParams { /** The newly loaded session, as of the start/fork fold. */ session: Session; } /** A session's load state (tdd SS2.4). */ export type SessionStatus = "notLoaded" | "idle" | "running" | (string & {}); /** `session/statusChanged` params (tdd SS4.6.10, ADR 31983 D2): a loaded session's projected `(status, attention)` value flipped. A command-plane broadcast — delivered to every connection regardless of its view subscription set, never gated, no `sourceRange`; the same facts live on the Session object, which is how a client seeds its table (no initial burst on connect). */ export interface SessionStatusChangedParams { /** Attention flags after the transition; present only when at least one flag is set (tdd SS2.4, ADR 31983 D3). */ attention?: AttentionFlag[]; /** The owning session. */ sessionId: string; /** Load state after the transition (the closed SS2.4 enum, unchanged). */ status: SessionStatus; /** The causing record's view cursor (ADR 31983 D4). Required-nullable: `null` exactly when the paired `session/closed`'s cursor is `null` (the unload fold-failure arm); a definite cursor everywhere else. */ viewCursor: string | null; } /** `session/todoListChanged` params (tdd SS4.6.3): a `TodoSnapshotUpdated` record landed. Replace the whole list on every event; an empty `items` array is a cleared list, not a no-op. */ export interface SessionTodoListChangedParams { /** The full todo list, replaced wholesale. */ items: TodoItem[]; /** The snapshot revision. Diagnostics only, never an ordering guard — `viewCursor` orders (tdd SS4.6.3). */ revision: number; /** The owning session. */ sessionId: string; /** The durable records this event folded from. */ sourceRange: SourceRange; /** The tool that produced the snapshot, verbatim. */ sourceTool: string; /** Opaque, strictly monotonic view cursor (tdd SS4.1). */ viewCursor: string; } /** `session/tokenUsage` params (tdd SS4.6.5): one per model completion that reports usage. Carries the raw counters verbatim plus the server-derived counted-once `promptTokens`/`totalTokens` (#8803: clients display and sum these and never re-derive the provider's cache convention) and the session `cumulative` block. Accumulate-only: `cumulative` never goes backward. */ export interface SessionTokenUsageParams { /** Session running totals at this cursor; the fold owns the accumulation. Subagent/workflow-child usage is never folded in — it rides the owning items (tdd SS4.6.5). */ cumulative: CumulativeTokenUsage; /** Model-call wall time, when measured. */ durationMs?: number; /** Provider finish reason when reported (open vocabulary, verbatim). */ finishReason?: string; /** The effective model that produced this usage; `null` on pre-schema records — never back-filled, an unpriced leg (tdd SS4.6.5). */ modelId?: string; /** Prompt tokens counted exactly once under the provider's cache convention (#8803). Server-derived; deterministic — the provider is in the log. */ promptTokens: number; /** The owning session. */ sessionId: string; /** The durable records this event folded from. */ sourceRange: SourceRange; /** `promptTokens + outputTokens` — the honest per-completion total. */ totalTokens: number; /** The turn whose model call completed. */ turnId: string; /** Raw counters verbatim from the durable record. */ usage: TokenUsage; /** Opaque, strictly monotonic view cursor (tdd SS4.1). */ viewCursor: string; } /** `session/userShell` params (tdd SS3.9): run a user-initiated shell command in the session's workspace — the TUI's `!` escape hatch. **Capability-gated**: the connection must negotiate `userShell` at `initialize`, and the whole justification is the SS1.10 spawn boundary. */ export interface SessionUserShellParams { /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The shell command to run. */ commandText: string; /** The target session. */ sessionId: string; } /** `session/userShell` result (tdd SS3.9): immediate. The shell runs off the command worker so a long command cannot stall the command plane; the output arrives as the `userShell` item's terminal view event. */ export interface SessionUserShellResult { /** Echoes the client's id. */ commandId: string; /** Admission status. */ status: CommandStatus; } /** The view-health state (tdd SS2.5.2 companion). Open enum (`x-msp-openness: open`): a client MUST ignore an unrecognized value. v1 emits only `Unavailable`; openness itself reserves additive room for a future re-arm (ADR 32557 D1 names it `healthy`) and for the #14401 durable-degraded axis, so no never-emitted token is baked onto the stable surface now. */ export type SessionViewHealth = "unavailable" | (string & {}); /** `session/viewHealthChanged` params (ADR 32557; #32557): the named session's live view stream became unavailable, and why. Best-effort: ordered after already-queued view frames and may be dropped (for example when the connection is closing), so a client MUST NOT assume a guaranteed push and still reads `history.noneReason` on its next resume/read (FM-005). */ export interface SessionViewHealthChangedParams { /** The new view-health state. In v1 the host emits only `Unavailable`. */ health: SessionViewHealth; /** Why the view is unavailable — the SAME typed `HistoryNoneReason` vocabulary the pull path stamps on `history.noneReason` (tdd SS2.5.2, D-050), so a client reuses one handler for push and pull. `projectionUnavailable` in v1; present only when `health` is `Unavailable`. Open on the client side: an unknown reason decodes conservatively and renders generically. */ noneReason?: HistoryNoneReason; /** The session whose live view health changed. */ sessionId: string; } /** One typed-invocable shortcut spelling (tdd SS3.22.1). A plugin skill may contribute two rows: its bare-name winner and its qualified `:` form. */ export interface SkillCatalogEntry { /** Present when the skill declares an argument hint. */ argumentHint?: string; /** The skill's palette summary. */ description: string; /** The skill display name the first-party palette shows. */ displayName: string; /** The owning plugin's identifier; present when `source` is `plugin`. */ pluginId?: string; /** The shortcut token without the leading slash — bare (`fix-bug`) or plugin-qualified (`acme:deploy`) — the exact value a `skill` input part submits. Unique within one response. */ selector: string; /** Where the skill comes from. */ source: SkillSource; } /** `skill/changed` params (tdd SS3.22.2): the session's user-invocable set changed; clients re-issue `skill/list`. Advisory — the host may coalesce bursts and guarantees no ordering relative to view events (ADR 32471 D3). */ export interface SkillChangedParams { /** The session whose set changed. */ sessionId: string; } /** `skill/list` params (tdd SS3.22.1). Per-session because skill scope follows the session's workspace and plugin state. */ export interface SkillListParams { /** The target session. */ sessionId: string; } /** `skill/list` result (tdd SS3.22.1): one row per typed-invocable shortcut spelling — exactly the invocations the first-party typed dispatch accepts (spec 11352 INV-007 predicate and the shared shortcut layer's name resolution, both by call-through; ADR 32471 D2). */ export interface SkillListResult { /** The session's user-invocable skill rows. */ skills: SkillCatalogEntry[]; } /** A skill row's source scope (tdd SS3.22.1): the projection of the skills crate's `SkillsSourceScope`. Open (server-produced result vocabulary, the #22785 enum-openness rule): a future scope value is additive. */ export type SkillSource = "bundled" | "user" | "project" | "plugin" | (string & {}); /** The compaction boundary an anchored snapshot is anchored at (tdd SS2.5.2). */ export interface SnapshotAnchor { /** The view cursor of the boundary's `compaction` event. */ boundaryCursor: string; /** The boundary's opaque compaction anchor (tdd SS4.5.10). */ summarizedThrough: string; } /** The complete folded view at the snapshot cursor (tdd SS4.9.1). Additive-optional evolution applies exactly as everywhere else; unknown members MUST be ignored, and preserved if re-serialized. **One served site does not satisfy this type today, escalated under #22785 (E8).** The genesis snapshot rung serves `state: {"items": [...]}` alone (`tbh-session-view-serve`'s `materialized_fold.rs`, the `select_genesis_history` call), while the anchored rung serves the full folded state. A schema-validating client resuming with `{"history": "snapshot"}` against the real fold therefore sees the other required members missing. The fix is a serving change in the #208/#14653 lane (serialize the `SessionViewState` the genesis path already folds, as the anchored path does) plus its own RED against the real fold; it is not a shape change here, because SS4.9.1 ratifies this shape. */ export interface SnapshotState { /** The running foreground turn; `null` when none is running. */ activeTurn: TurnRef | null; /** The effective approval mode at this cursor — the same object the `Session` carries (tdd SS2.4, SS5.12). */ approvalMode: EffectiveApprovalModeState; /** Latest branch observation; `null` when no fact has landed. */ branch: BranchState | null; /** The latest `(windowTokens, usedTokens, pressure)` triple. SS4.9.1 says "`null`/absent" and SS4.9.2's worked example OMITS the member; the binary omits it too, so this is the absent arm — the four siblings above are present-null in the same frame. INV-017 admits one or the other, never both; escalated under #22785. */ contextUsage?: ContextUsage; /** Latest effective model; `null` when no fact has landed. */ effectiveModel: EffectiveModel | null; /** Latest goal block; `null` when no fact has landed. */ goal: Goal | null; /** Every item, in first-opened order, each at its latest revision at the snapshot cursor. One schema per kind, shared with the notification item object — which is what makes snapshot+suffix a pure splice (tdd SS4.9.1). */ items: Item[]; /** The settled canonical session name; `null` when the session was never named (#27598, tdd SS4.9.1 / SS2.14). Folds the same durable `session/nameChanged` record `Session.name` reports. */ name?: string; /** The pending-approval half of the pending set. */ pendingApprovals: PendingApprovalPointer[]; /** The pending-user-input half of the pending set. */ pendingUserInputs: PendingUserInputPointer[]; /** Admitted-but-not-launched submits, in launch order (tdd SS3.1.4). */ queuedTurns: TurnRef[]; /** The latest session-default reasoning effort with its source; ABSENT until a set lands (tdd SS4.9.1 `reasoningEffort`, ADR 31255 D1 — the `contextUsage` absent arm, never present-null). */ reasoningEffort?: ReasoningEffortState; /** Latest todo list; `null` when no fact has landed. */ todoList: TodoListState | null; /** The `cumulative` block of the last `session/tokenUsage` event; zeroes when none (tdd SS4.9.1). */ tokenUsage: CumulativeTokenUsage; /** Completed-turn count at this cursor. */ turnCount: number; } /** The inclusive raw-record range a durable-sourced view event folded from (tdd SS4.2) — the reconciliation token: re-folding the cited records from the canonical fold state immediately before `first` — appended host-death terminals seed from the end-of-records state — reproduces the event (tdd SS7.5; spec 14653 T041/INV-009). In v1 it is an **opaque provenance token**: no wire method reads what it points at (the SS6 raw-log altitude is deferred, #13929). Ephemeral-sourced events (`item/delta`, and an `item/started` that opens on an ephemeral record) carry no `sourceRange` — ephemeral records may be evicted by retention (tdd SS4.2; spec 14653 INV-009). */ export interface SourceRange { /** The first record of the inclusive range. */ first: RecordPosition; /** The last record of the inclusive range; equal to `first` for an event folded from one record. */ last: RecordPosition; /** The stream the folded records live on (run stream, or the session stream's mirror of task/approval/subagent-control records — whichever the fold actually consumed, tdd SS4.2). */ stream: StreamRef; } /** One raw stream named by a [`SourceRange`] (tdd SS4.2). */ export interface StreamRef { /** The stream id. */ id: string; /** The stream kind, verbatim raw-log vocabulary (e.g. `"run"`, `"session"`). A free string, not an enum: `sourceRange` is an opaque provenance token in v1 and the raw stream vocabulary is the deferred SS6 altitude's to freeze (#13929). */ kind: string; } /** Subagent control status (tdd SS4.5.7, camelCased `SubagentControlStatus`). Open; the generic item `status` is the terminal authority. */ export type SubagentControlStatus = | "accepted" | "starting" | "running" | "resultReady" | "closing" | "closed" | "recoveryPending" | "manualReconciliation" | (string & {}); /** Params for `subagent/sendMessage` and `subagent/followupTask` (SS3.16): a child target plus the input body. */ export interface SubagentInputParams { /** The note/task text: trimmed with Unicode-whitespace semantics, rejected when empty after trimming, delivered trimmed with multibyte content byte-for-byte intact (SS3.16). */ body: string; /** Client-minted UUIDv7 command id (SS3.1.1). */ commandId: string; /** Target session (UUIDv7 string; SS3 preamble). */ sessionId: string; /** Durable child id (the SS4.5.7 item's `subagentId`; opaque string). */ subagentId: string; } /** Params for `subagent/interrupt`, `subagent/stop`, and `subagent/close` (SS3.16): a child target plus an optional human-readable reason that is preserved on the durable effect record. */ export interface SubagentOwnerReasonParams { /** Client-minted UUIDv7 command id (SS3.1.1). */ commandId: string; /** Optional reason, preserved on the durable owner-command record. */ reason?: string; /** Target session (UUIDv7 string; SS3 preamble). */ sessionId: string; /** Durable child id (the SS4.5.7 item's `subagentId`; opaque string). */ subagentId: string; } /** A subagent's result envelope (tdd SS4.5.7, `SubagentResultEnvelope`). */ export interface SubagentResult { /** Artifact references, verbatim. */ artifactRefs: string[]; /** Error kind, verbatim durable vocabulary, when the child failed. */ errorKind?: string; /** Evidence references, verbatim. */ evidenceRefs: string[]; /** Structured result data, verbatim, when present. */ structuredData?: Record; /** Bounded result summary (<=512 chars, runtime-enforced). */ summary: string; /** Result text (<=32 KiB), when present. */ text?: string; } /** Params for `subagent/resume`, `subagent/reopen`, and `subagent/readResult` (SS3.16): the bare child target. */ export interface SubagentTargetParams { /** Client-minted UUIDv7 command id (SS3.1.1). */ commandId: string; /** Target session (UUIDv7 string; SS3 preamble). */ sessionId: string; /** Durable child id (the SS4.5.7 item's `subagentId`; opaque string). */ subagentId: string; } /** The one usage payload shape: the `usage/read` result's `usage` member and the `usage/changed` params (ADR 32563 D2/D3). The numbers are point-in-time — `observedAtMs` is the host's arrival stamp, so a client renders "as of", never implies live data (spec 18742 US-FR-004). */ export interface SubscriptionUsage { /** When the host RECEIVED this observation (frame arrival or mint request-send), epoch milliseconds. */ observedAtMs: number; /** The provider's subscription tier id, verbatim. */ tier: string; /** The rolling weekly block. */ weekly: SubscriptionUsageWeekly; /** The current window. */ window: SubscriptionUsageWindow; } /** The rolling weekly block: same semantics as [`SubscriptionUsageWindow`] without a duration (ADR 32563 D2). */ export interface SubscriptionUsageWeekly { /** When the weekly window resets, epoch milliseconds. */ resetsAtMs: number; /** Percent of the weekly budget used (integer ≥ 0, may exceed 100). */ usedPercent: number; } /** The current usage window (the provider's 5-hour-class block): verbatim provider percentages with the reset stamp normalized to epoch milliseconds (ADR 32563 D2). */ export interface SubscriptionUsageWindow { /** When the window resets, epoch milliseconds. */ resetsAtMs: number; /** Percent of the window's budget used: an integer ≥ 0, verbatim from the provider — over-quota values above 100 are valid. */ usedPercent: number; /** The window's length in minutes (> 0). */ windowDurationMins: number; } /** A success response frame (SS1.2 §2.3). */ export interface SuccessResponse { /** Echo of the request id. */ id: RequestId; /** The literal `"2.0"`. */ jsonrpc: JsonRpcVersion; /** Always a JSON object, possibly `{}`, never a bare scalar — so every result can grow additive-optional members (SS1.2). */ result: Record; } /** `task/background` params (tdd §3.13): durably send a running foreground tool task to the background. */ export interface TaskBackgroundParams { /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The target session. */ sessionId: string; /** The task to background, exactly as the view names it: the `toolCall` item's `itemId` IS the task id (SS4.5.5). */ taskId: string; } /** The `task/background` / `task/stop` ack (tdd §3.13/§3.14): admission-only, echoing the targeted task. */ export interface TaskCommandResult { /** Echoes the client's id. */ commandId: string; /** Admission status. */ status: CommandStatus; /** Echoes the targeted task id. */ taskId: string; } /** `task/stopAll` params (tdd §3.15): stop every stoppable background workload live at admission. */ export interface TaskStopAllParams { /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The target session. */ sessionId: string; } /** The `task/stopAll` ack (tdd §3.15): always `accepted`, including over an empty set — a blanket stop over nothing is a satisfied gesture. The ack deliberately carries no stopped-task list; count the kills from the view. */ export interface TaskStopAllResult { /** Echoes the client's id. */ commandId: string; /** Admission status. */ status: CommandStatus; } /** `task/stop` params (tdd §3.14): stop one named background task. Required target, never "whichever is loudest" — §3.15 is the blanket verb. */ export interface TaskStopParams { /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The target session. */ sessionId: string; /** The task to stop, the `toolCall` item's `itemId` (SS4.5.5). */ taskId: string; } /** One todo entry (tdd SS4.6.3). */ export interface TodoItem { /** Present-tense active form, when the tool supplied one. */ activeForm?: string; /** The todo status (camelCased runtime `TodoStatus`). */ status: TodoStatus; /** The todo text. */ text: string; } /** The latest todo-list fact in the snapshot (tdd SS4.6.3, SS4.9.1). */ export interface TodoListState { /** The full todo list. */ items: TodoItem[]; /** The snapshot revision. Diagnostics only, never an ordering guard. */ revision: number; /** The tool that produced the snapshot, verbatim. */ sourceTool: string; } /** Todo status (tdd SS4.6.3): closed in the runtime, wire-open. */ export type TodoStatus = "pending" | "inProgress" | "completed" | "cancelled" | (string & {}); /** Raw token counters, verbatim from the durable record (tdd SS4.6.5, the runtime's `Usage`, camelCased). Not directly summable across providers — sum the counted-once derivations instead (#8803). */ export interface TokenUsage { /** Cache read tokens, only when the provider distinguishes writes/reads. */ cacheReadTokens?: number; /** Cache write tokens, only when the provider distinguishes writes/reads. */ cacheWriteTokens?: number; /** Provider-reported cache tokens (inside or beside `inputTokens`, provider-convention-dependent — the reason `promptTokens` exists). */ cachedTokens: number; /** Provider-reported input tokens. */ inputTokens: number; /** Provider-reported output tokens. */ outputTokens: number; /** Output tokens spent on reasoning, when the provider reports it. */ reasoningTokens: number; } /** Optional W3C trace context, on requests in both directions only — never on responses or notifications (SS1.8). */ export interface TraceContext { /** W3C `traceparent` string; receivers that do not trace ignore it. */ traceparent?: string; /** W3C `tracestate` string. */ tracestate?: string; } /** `turn/cancel` params (tdd SS3.5): plain cancellation on the normal command lane. Same shape as `turn/interrupt`, **without** `retract` — pairing a retract with a plain cancel is durably rejected `not_paired_interrupt`. */ export interface TurnCancelParams { /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The target session. */ sessionId: string; /** The exact turn to cancel; omit to target the current foreground turn. Any syntactically valid UUID: a turn from an older session may carry a v4 or v5 id. A malformed id is `invalidParams`. */ turnId?: string; } /** `turn/cancel` result (tdd SS3.5): identical envelope to `turn/interrupt`. */ export interface TurnCancelResult { /** Echoes the client's id. */ commandId: string; /** Admission status. */ status: CommandStatus; /** The cancelled turn. */ turnId: string; } /** `turn/completed` params (tdd SS4.5.1): the run's durable terminal record landed. */ export interface TurnCompletedParams { /** Turn duration; absent means unmeasured, never fabricated. */ durationMs?: number; /** Present iff `terminal` is `"failed"` (tdd SS4.5.1): mid-turn failures reach the client here — never as a JSON-RPC error. */ error?: TurnError; /** The runtime's free-text terminal reason, verbatim. Display and diagnostics only; never branch on it. */ reason?: string; /** The owning session. */ sessionId: string; /** The durable records this event folded from. */ sourceRange: SourceRange; /** The turn terminal (open enum). */ terminal: TurnTerminal; /** Time to first token, when measured. */ timeToFirstTokenMs?: number; /** The terminated turn. */ turnId: string; /** The turn's aggregate token usage, summed across the turn's model completions (same shape as `session/tokenUsage.usage`). */ usage?: TokenUsage; /** Opaque, strictly monotonic view cursor (tdd SS4.1). */ viewCursor: string; } /** The settled turn-failure object (tdd SS4.5.1): `{kind, message, retryable}`. */ export interface TurnError { /** The failure class (open camelCase enum grounded in the runtime's terminal failure classification). */ kind: TurnErrorKind; /** Human-readable failure text. */ message: string; /** The server's judgment that resubmitting the same input may succeed. */ retryable: boolean; } /** Turn failure classes (tdd SS4.5.1, `TerminalErrorKind` plus the model-task failure class). Open. */ export type TurnErrorKind = | "stepLimit" | "configError" | "projectionError" | "logError" | "workflowLaunchError" | "environmentError" | "modelError" | "launchError" | "authRequired" | (string & {}); /** One ordered content part of a turn submission (tdd SS3.2). File mentions are text, not a part type: write `@relative/path` in a text part. A structured `mention` part is reserved and currently rejected, and an unknown part type is `invalidParams` (tdd SS3.1.2, SS3.2) — which is what closes [`TurnInputPartType`]. Modelled as a discriminated flat object rather than a Rust `enum`, the convention [`crate::view::approval::ApprovalSubject`] already established for a wire union in this crate: the v1 schema model names no object-variant union shape and fails closed on one. The serialized JSON is the tdd shape either way; what a flat object cannot express is "`mediaType` is required exactly when `type` is `image`". **RULED (#22785 E4, owner, 2026-08-26): the precedent is accepted.** A strict union node kind may be funded later as a follow-up; if it is, it must cover [`crate::method::lifecycle::PendingRequestPointer`] too. `height` may only appear together with `width`. `width` may only appear together with `height`. */ export interface TurnInputPart { /** Free-text skill arguments, optional on a `skill` part — the wire twin of what the TUI accepts after the shortcut token (tdd SS3.22.3). */ arguments?: string; /** Base64 payload, required on an `image` part. Invalid base64 or an empty payload is rejected with invalid params. */ base64Data?: string; /** Pixel height; must be provided together with `width` or not at all (tdd SS3.2, #22785 E6c). */ height?: number; /** Media type, required on an `image` part. */ mediaType?: string; /** The skill to invoke, required on a `skill` part (tdd SS3.2, SS3.22.3; ADR 32471 D4): a bare or plugin-qualified shortcut token from `skill/list`. The HOST resolves and expands; an unknown selector is the typed `-32032 skillNotFound` request error. */ selector?: string; /** User prompt text, on a `text` part. Multiple text parts are joined in order into the turn's prompt. */ text?: string; /** The part type. */ type: TurnInputPartType; /** Pixel width; must be provided together with `height` or not at all (tdd SS3.2). Published as a `dependentRequired` pair under #22785 E6c. */ width?: number; } /** The `type` discriminator of a turn input part (tdd SS3.2). Closed: an unknown part type is `invalidParams` (tdd SS3.1.2). */ export type TurnInputPartType = "text" | "image" | "skill"; /** `turn/interrupt` params (tdd SS3.4): the "user pressed stop" gesture, on the runtime's priority lane. */ export interface TurnInterruptParams { /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** Pair a retract intent with the interrupt: if the turn is cancelled before any assistant output committed, the submission is durably retracted (view event `turn/retracted`) so the client may restore the prompt text. A rejected retract does not undo the interrupt. Default `false` (tdd SS3.4). */ retract?: boolean; /** The target session. */ sessionId: string; /** The exact turn to interrupt. Omit to target the session's current foreground turn, resolved at admission; prefer passing the explicit id when you have one (tdd SS3.4). Any syntactically valid UUID: a turn from an older session may carry a v4 or v5 id. A malformed id is `invalidParams`. */ turnId?: string; } /** `turn/interrupt` result (tdd SS3.4). Acceptance means the interrupt was admitted, **not** that the turn is already stopped: the turn is over when you fold its `turn/completed` with terminal `cancelled`. */ export interface TurnInterruptResult { /** Echoes the client's id. */ commandId: string; /** Admission status. */ status: CommandStatus; /** The interrupted turn. */ turnId: string; } /** A turn named by the snapshot's active/queued lists (tdd SS4.9.1). */ export interface TurnRef { /** The `commandId` of the submit that minted it. */ commandId: string; /** The turn's id, pre-minted per tdd SS3.1.4. */ turnId: string; } /** `turn/retracted` params (tdd SS4.5.1): an interrupt-paired retract was durably accepted. The retracted user-message item is re-emitted via `item/updated` with `retracted: true`. */ export interface TurnRetractedParams { /** The retracted submission's command id. */ commandId: string; /** The owning session. */ sessionId: string; /** The durable records this event folded from. */ sourceRange: SourceRange; /** The turn whose submission was retracted. */ turnId: string; /** Opaque, strictly monotonic view cursor (tdd SS4.1). */ viewCursor: string; } /** `turn/retryScheduled` params (tdd SS4.5.1, spec 14412; D-026): a durable turn retry-scheduled fact folded — the failing model attempt's scheduled retry is observable BEFORE the turn terminates, so a streaming client can render "attempt N/M · retrying in Ss · reason" instead of dead air. Non-terminal: it never resolves a turn-wait (tdd SS3.1.4). The delay is the recorded scheduled backoff, never an absolute fire time — clients derive any countdown locally. `sourceRange` cites the session stream's mirror of the task-lifecycle record (tdd SS4.2). */ export interface TurnRetryScheduledParams { /** The attempt that failed (producer-normalized, >= 1). */ attempt: number; /** The turn's model-retry chain bound. */ maxAttempts: number; /** The attempt about to run (producer contract: attempt < nextAttempt <= maxAttempts; not a schema constraint). */ nextAttempt: number; /** The recorded stopping reason through the shared task-detail normalization (non-empty; capped at 160 characters). */ reason: string; /** The scheduled backoff delay in milliseconds, verbatim from the durable fact. */ retryDelayMs: number; /** The owning session. */ sessionId: string; /** The durable record this event folded from (the session stream's mirror of the retry-scheduled task status; `first == last`). */ sourceRange: SourceRange; /** The running turn whose model attempt is being retried. */ turnId: string; /** Opaque, strictly monotonic view cursor (tdd SS4.1). */ viewCursor: string; } /** What `turn/start` did with the input (tdd SS3.2). Resolves OQ-H in v1: since `queue` is the default `ifBusy`, clients need to distinguish these without folding history. */ export type TurnStartDisposition = "started" | "queued" | "steered" | (string & {}); /** `turn/start.providerRequestOptions` is deliberately absent: **RULED (#22785 E3, owner, 2026-08-26) to stay off the published schema.** The schema is the contract, and a free-form-object node kind is revisited only if the experimental field graduates. `turn/start` params (tdd SS3.2). */ export interface TurnStartParams { /** The SS3.1.1 idempotency handle (UUIDv7). The fresh turn's `turnId` derives from it (tdd SS3.1.4). */ commandId: string; /** Presentation form of the prompt for transcripts. Durable; carried on the resulting user-message view item. Never model-visible (tdd SS3.2). */ displayText?: string; /** Disposition when a turn is already running; default `queue`. */ ifBusy?: IfBusy; /** Ordered content parts; required and non-empty. */ input: TurnInputPart[]; /** Reasoning tier sampled at submission for this turn. */ reasoningEffort?: ReasoningEffort; /** The target session. */ sessionId: string; /** A sticky REPLACEMENT of the session's runtime workspace-root set, binding at this turn's launch and persisting for subsequent turns until replaced again — unlike `reasoningEffort`, which is this-turn-only. Same shape and validation as `session/start.workspaceRoots`; invalid params on an explicit `ifBusy: "steer"` submit and so is explicit `null` (the D-049 null-tolerant set is closed); omitted means "unchanged", never "reset" (tdd SS3.2, ADR 37313 D3, #37313). */ workspaceRoots?: string[]; } /** `turn/start` result (tdd SS3.2). */ export interface TurnStartResult { /** Echoes the client's id. */ commandId: string; /** What happened to the input. */ disposition: TurnStartDisposition; /** `true` iff `disposition` is `started`; retained as the boolean shorthand — `disposition` is authoritative (tdd SS3.2). */ startedNewTurn: boolean; /** Admission status. */ status: CommandStatus; /** The turn that will carry (or absorbed) this input. Authoritative: always take it from the ack rather than deriving it (tdd SS3.2). */ turnId: string; } /** `turn/started` params (tdd SS4.5.1): a foreground turn began running — fresh submits immediately, queued submits at their launch boundary, never steered submits. */ export interface TurnStartedParams { /** The submitting command; `turnId == commandId` for fresh turns (tdd SS3.1.4). */ commandId: string; /** The owning session. */ sessionId: string; /** The durable records this event folded from. */ sourceRange: SourceRange; /** The started turn. */ turnId: string; /** Opaque, strictly monotonic view cursor (tdd SS4.1). */ viewCursor: string; } /** `turn/steer` params (tdd SS3.3): exact-target steering into the currently running turn. */ export interface TurnSteerParams { /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The turn you believe is running. Closes the race where the turn completes or is replaced between your read and your steer: input meant for turn A can never leak into turn B (tdd SS3.3). Any syntactically valid UUID: a turn from an older session may carry a v4 or v5 id. A malformed id is `invalidParams`; an id that is not the running turn is refused. */ expectedTurnId: string; /** Same content parts as `turn/start`. */ input: TurnInputPart[]; /** Reasoning tier for the model calls this steer's input reaches. Applies forward, never backward; absent means unspecified, not "reset" (tdd SS3.3, D-024). */ reasoningEffort?: ReasoningEffort; /** The target session. */ sessionId: string; } /** `turn/steer` result (tdd SS3.3). */ export interface TurnSteerResult { /** Echoes the client's id. */ commandId: string; /** Admission status. */ status: CommandStatus; /** The running turn that absorbed the input. */ turnId: string; } /** Turn terminal vocabulary (tdd SS4.5.1): exactly the runtime's `RunTerminalKind` — closed in the runtime, wire-open for evolution. */ export type TurnTerminal = "completed" | "failed" | "cancelled" | (string & {}); /** `turn/unqueue` params (tdd SS3.6): reclaim a queued submit before it launches. It is **not** a stop — a reclaim that arrives after its target launched is durably rejected, never silently upgraded into a cancel. */ export interface TurnUnqueueParams { /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The target session. */ sessionId: string; /** The queued turn to reclaim, exactly as the queueing `turn/start`'s ack minted it and as snapshot `queuedTurns` lists it. Required, and never "whichever is newest" (tdd SS3.6). Any syntactically valid UUID: a turn from an older session may carry a v4 or v5 id. A malformed id is `invalidParams`. */ turnId: string; } /** `turn/unqueue` result (tdd SS3.6). Admission only — but for this command admission *is* the race: an admitted reclaim implies the turn will not launch. The authoritative removal is the `turn/unqueued` view event. */ export interface TurnUnqueueResult { /** Echoes the client's id. */ commandId: string; /** Admission status. */ status: CommandStatus; /** The reclaimed turn. */ turnId: string; } /** `turn/unqueued` params (tdd SS3.6, SS4.5.1): a queued submit's reclaim durably won; its pre-minted turn never runs. Carries the reclaimed `turnId` and the `commandId` of the `turn/start` that queued it, so a client can restore the submission's text exactly as for `turn/retracted`. No `turn/started`/`turn/completed` is ever emitted for this `turnId` (SDK turn-waits settle on this event too, tdd SS3.1.4). `sourceRange` cites the SESSION stream's reclaim record — a reclaimed turn never had a run stream. */ export interface TurnUnqueuedParams { /** The `commandId` of the `turn/start` that queued the reclaimed turn. */ commandId: string; /** The owning session. */ sessionId: string; /** The durable records this event folded from (the session stream's reclaim record). */ sourceRange: SourceRange; /** The reclaimed turn: pre-minted at admission, never launched. */ turnId: string; /** Opaque, strictly monotonic view cursor (tdd SS4.1). */ viewCursor: string; } /** One element of a `view/page` result's `events` array: an **unframed view notification** exactly as tdd SS4.2.1 defines it — the nested pair `{"method", "params"}`, which is the live notification minus `jsonrpc` and `emittedAtMs`, with nothing lifted out of `params` and nothing spliced into it. SS4.2.1 is the single normative definition; SS4.7.3 and SS7.4 both cite it, so the two surfaces cannot drift. */ export interface UnframedViewNotification { /** The event type — the live notification's method name, retained because the type lives only in the notification name and would otherwise be lost (tdd SS4.2.1). */ method: string; /** The notification's params object, verbatim. */ params: UnframedViewNotificationParams; } /** The `params` of an unframed view notification (tdd SS4.2.1, SS4.2). Declares the SS4.2 base members every view notification carries, and stays **open** for the event-specific fields SS4.5/SS4.6/SS5 add per event type. The v1 schema model names no method-correlated union (the SS4.7.3 `events` element's `params` arm is selected by its sibling `method`), so the per-event arms cannot be expressed here without one; enumerating them as an uncorrelated union would additionally exclude `turn/unqueued`, whose notification row is another lane's ratified deferral (#207/#14407) — a published schema that rejects a real page element is the exact #19923 defect this PR exists to close. Recorded as a Design delta on #22785. `sourceRange` is required here and not optional: `view/page` serves durable-sourced events only (tdd SS4.7.3), and durable-sourced is *defined* as carrying a `sourceRange` — the SS4.2 ephemeral-sourced exemption applies to `item/delta`, which `view/page` never replays. */ export interface UnframedViewNotificationParams { /** The owning session (tdd SS4.2). */ sessionId: string; /** The durable records this event folded from (tdd SS4.2, SS6.8). */ sourceRange: SourceRange; /** The event's opaque, strictly monotonic view cursor. It stays **inside** `params`, where every live notification already carries it (tdd SS4.2.1) — nothing is spliced beside `method`. */ viewCursor: string; } /** The only scalar alternative to a known effort array. Kept as a closed singleton so arbitrary strings and uppercase spellings fail decoding. */ export type UnknownModelReasoningEffortVariants = "unknown"; /** `usage/read` result: `{usage?}` — omitted, never `null`, when the host has observed nothing (ADR 32563 D2: truthful absence, no "nothing observed" error). */ export interface UsageReadResult { /** The last-observed subscription usage window, when one exists. */ usage?: SubscriptionUsage; } export interface UserInputAnswer { freeText?: string; note?: string; questionId: string; selectedLabel?: string; selectedLabels?: string[]; } /** `userInput/answer` params (tdd SS5.10.2): answer every question. Each answer carries `questionId` then exactly one of `selectedLabel` (single mode), `selectedLabels` (multiple mode, within min/max bounds), or `freeText` (<=500 chars); plus an optional `note` (<=500). Answers that do not match the prompt fail -32057 `userInputAnswerInvalid`. Image `attachments` are a **reserved** field in v1, rejected if sent, because the blob-upload path they reference is reserved in tdd SS3.2. */ export interface UserInputAnswerParams { /** One entry per question. */ answers: UserInputAnswer[]; /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The target session. */ sessionId: string; /** The prompt being answered. */ userInputId: string; } /** `userInput/answer` result (tdd SS5.10.2). */ export interface UserInputAnswerResult { /** Echoes the client's id. */ commandId: string; /** Admission status. */ status: CommandStatus; /** The prompt this answer settled. */ userInputId: string; } /** `userInput/cancel` params (tdd SS5.10.2): decline to answer; the tool call resolves with a cancelled result the model sees. */ export interface UserInputCancelParams { /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** Why the prompt was declined. */ reason?: string; /** The target session. */ sessionId: string; /** The prompt being declined. */ userInputId: string; } /** `userInput/cancel` result (tdd SS5.10.2). */ export interface UserInputCancelResult { /** Echoes the client's id. */ commandId: string; /** Admission status. */ status: CommandStatus; /** The prompt this cancellation settled. */ userInputId: string; } export interface UserInputClarification { content: string; format: string; } /** `userInput/clarify` params (tdd SS5.10.2): answer with a free-form clarification instead of the structured options — the "let me explain" path; the model receives the clarification text and re-decides. */ export interface UserInputClarifyParams { /** `format` is `"text"` in v1 (open); `content` is <=500 chars. */ clarification: UserInputClarification; /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The target session. */ sessionId: string; /** The prompt being clarified. */ userInputId: string; } /** `userInput/clarify` result (tdd SS5.10.2). */ export interface UserInputClarifyResult { /** Echoes the client's id. */ commandId: string; /** Admission status. */ status: CommandStatus; /** The prompt this clarification settled. */ userInputId: string; } export interface UserInputOption { description?: string; label: string; preview?: UserInputOptionPreview; } export interface UserInputOptionPreview { content: string; format: string; } export type UserInputOutcome = | "answered" | "cancelled" | "interrupted" | "clarified" | "timedOut" | "aborted" | (string & {}); export interface UserInputQuestion { header: string; id: string; options: UserInputOption[]; question: string; selection: UserInputSelection; } /** Full params shared by `userInput/request` and `userInput/requested`. */ export interface UserInputRequestParams { autoResolutionMs?: number; itemId: string; questions: UserInputQuestion[]; sessionId: string; sourceRange?: SourceRange; toolCallId: string; toolName: string; turnId: string; userInputId: string; viewCursor: string; } export interface UserInputSelection { maxSelections?: number; minSelections?: number; mode: UserInputSelectionMode; } export type UserInputSelectionMode = "single" | "multiple"; /** `userInput/settled` params: the first durable prompt settlement. */ export interface UserInputSettledParams { answers: UserInputAnswer[]; clarification: UserInputClarification | null; decidedByCommandId: string | null; outcome: UserInputOutcome; reason: string | null; sessionId: string; sourceRange: SourceRange; userInputId: string; viewCursor: string; } /** Winning terminal returned to a late user-input command. */ export interface UserInputSettlementSummary { outcome: string; viewCursor: string; } /** Version-control system of a branch observation (tdd SS4.6.4). Open. */ export type Vcs = "git" | "sapling" | (string & {}); /** `view/gap` params (spec 208 SS4.8, FM-001): push delivery dropped events, and this names the hole. The bracket is deferred (D-16487-2): it flushes at the subscription's next ACCEPTED delivery, never at enqueue time, so `next` always names an event whose own delivery is proven. A run of consecutive undelivered events coalesces into one bracket keeping the FIRST range's `after` (D-16487-1). The gap rides the protected reserved queue, so no wire-interleaving order against neighbouring deliveries is promised — the cursors carry the semantics (INV-002, D-16487-3). On receipt a client may take either sanctioned recovery (D-030, FR-013): splice-fill — buffer live events at cursors >= `next`, page `(after, next)` forward, discard the overlap, splice — or re-anchor through the anchored read surface. The server requires neither, cannot distinguish clients by their choice, and holds no partial-fill state. */ export interface ViewGapParams { /** The last cursor delivered before the hole — the exclusive lower bound of the undelivered range. An **opaque** view cursor: clients relay it, never parse it (tdd SS4.1). */ after: string; /** The first cursor delivered after the hole — the exclusive upper bound of the undelivered range, and the position delivery continues from. An **opaque** view cursor: clients relay it, never parse it (tdd SS4.1). */ next: string; /** The session whose subscription dropped events. */ sessionId: string; } /** The `view/page` request-mode anchor (tdd SS4.7.3). Declared **open**: the tdd spells it "open string enum, v1 value `latestCompaction`". */ export type ViewPageAnchor = "latestCompaction" | (string & {}); /** The `view/page` paging direction (tdd SS4.7.3). Closed: the tdd spells exactly two values and a third would change the paging contract. */ export type ViewPageDirection = "forward" | "backward"; /** `view/page` params (tdd SS4.7.3): cursor-paged reads of the session view. */ export interface ViewPageParams { /** The cold-client request mode (D-029; spec 208 FR-008), resolved at call time to the latest installed compaction boundary. The one named exception to the SS4.1 observed-only rule. */ anchor?: ViewPageAnchor; /** The exclusive anchor. Forward: the page starts strictly after it; omitted means from the beginning of the view. Backward: the page ends strictly before it; omitted means from the head. Mutually exclusive with `anchor` (tdd SS4.7.3; spec 208 FR-008a). */ cursor?: string; /** Paging direction; `forward` when omitted. */ direction?: ViewPageDirection; /** Maximum events to return, 1–1000. The server MAY return fewer (tdd SS4.7.3's short-serve rule). The 1–1000 range is ratified and now **published**: #22785 E6c is owner-ruled, so the model carries the bound and the bundle renders `minimum`/`maximum` instead of a bare `integer`. Range 1–1000 inclusive. */ limit: number; /** The session to page. */ sessionId: string; } /** The `resolvedAnchor` echo (tdd SS4.7.3): subsequent pages pass ordinary cursors, so the anchor never needs re-resolving. */ export interface ViewPageResolvedAnchor { /** The view cursor of the resolved boundary's `compaction` event. */ boundaryCursor: string; } /** `view/page` result (tdd SS4.7.3). */ export interface ViewPageResult { /** The page's events, always ascending by `viewCursor` in both directions. Durable-sourced only; pages are contiguous and can never skip a cursor. */ events: UnframedViewNotification[]; /** The anchor for the next page in the same direction: forward, the last event's cursor; backward, the first's. `null` at the end of the view in that direction — never omitted. */ nextCursor: string | null; /** The resolution echo, present exactly when the request used `anchor` (tdd SS4.7.3; spec 208 FR-008). */ resolvedAnchor?: ViewPageResolvedAnchor; } /** The `snapshot` object returned by `session/resume` / `session/read` (tdd SS4.9). */ export interface ViewSnapshot { /** Present exactly when `history.mode` is `anchoredSnapshot` (tdd SS2.5.2). */ anchor?: SnapshotAnchor; /** Snapshot schema version. A client whose generated types are older than this must fall back to inline/paged history (tdd SS4.9.2, SS2.5.2). */ schemaVersion: number; /** The complete folded view at `viewCursor` (tdd SS4.9.1). */ state: SnapshotState; /** The cursor the state is folded at; every event after it streams as the suffix (tdd SS4.9). */ viewCursor: string; } /** `view/subscribe` params (tdd SS4.7.1): attach this connection's live view subscription for a session at an explicit cursor — the fine-grained counterpart of the SS2 auto-subscribe, and the gap-free re-attachment path after `view/unsubscribe`. It never loads a session, takes no lease, writes nothing. */ export interface ViewSubscribeParams { /** Resume cursor. When present, the server replays `(after, head]` as ordinary view notifications before any live event — one gapless cursor sequence. Omitted means "from now": no historical replay (tdd SS4.7.1). */ after?: string; /** The session to follow. */ sessionId: string; } /** `view/subscribe` result (tdd SS4.7.1). */ export interface ViewSubscribeResult { /** The view head at subscribe time; the client knows it is live once cursors pass it. */ viewCursor: string; } /** `view/unsubscribe` params (tdd SS4.7.2): remove this connection from the session's view subscription set — the protocol's single unsubscribe operation, at the altitude that owns subscriptions (tdd SS2.5.6 points here). It does not unload the session; unloading is the idle policy (tdd SS2.8). */ export interface ViewUnsubscribeParams { /** The session to stop following. */ sessionId: string; } /** `view/unsubscribe` result (tdd SS4.7.2): the empty object. Idempotent — unsubscribing while not subscribed returns `{}`. */ export interface ViewUnsubscribeResult {} /** `workflow/cancel` params (tdd SS3.19): cancel a live workflow run. */ export interface WorkflowCancelParams { /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The target session. */ sessionId: string; /** The run to cancel, exactly as the `workflow` item names it (SS4.5.8); required, non-empty. */ workflowRunId: string; } /** One workflow child's folded state (tdd SS4.5.8, `WorkflowChildLifecycleFact`), keyed by `(childId, attempt)`. */ export interface WorkflowChild { /** The attempt number. */ attempt: number; /** The child's id within the run. */ childId: string; /** The child's observed duration, when recorded. */ durationMs?: number; /** The child's display label, when recorded. */ label?: string; /** The child's phase, when recorded. */ phase?: string; /** The child's recorded result reference, verbatim, when present — an opaque string, matching the durable owner. */ resultRef?: string; /** camelCased `WorkflowChildLifecycleStatus`, verbatim (durable runtime vocabulary). */ status: string; /** The child's terminal, turn vocabulary (tdd SS4.5.8). */ terminal?: TurnTerminal; /** The child's observed usage, when recorded. */ usage?: TokenUsage; } /** Which control to apply to the child's current attempt (tdd SS3.20). Closed on the wire: an unknown value is `-32602 invalidParams`. */ export type WorkflowChildAction = "skip" | "retry"; /** `workflow/childControl` params (tdd SS3.20): skip or retry one workflow child, keyed by the `(childId, attempt)` pair the `workflow` item's `children[]` carries. */ export interface WorkflowChildControlParams { /** The control to apply. */ action: WorkflowChildAction; /** The child's CURRENT attempt (integer >= 1). A stale value rejects `"stale_attempt"`; re-read the item and re-key — never guess. Minimum 1. */ attempt: number; /** The child, from the item's `children[]`; required, non-empty. */ childId: string; /** The SS3.1.1 idempotency handle (UUIDv7). */ commandId: string; /** The target session. */ sessionId: string; /** The run owning the child (SS4.5.8); required, non-empty. */ workflowRunId: string; } /** The shared SS3.19/SS3.20 admission-only ack: deliberately bare `{commandId, status}` — settlement arrives as the workflow item's view events, never through the ack. */ export interface WorkflowControlResult { /** Echoes the client's id. */ commandId: string; /** Admission status. */ status: CommandStatus; } /** Every wire method in this schema (SS1.9 index). */ export type MspMethod = | "initialize" | "subagent/sendMessage" | "subagent/followupTask" | "subagent/interrupt" | "subagent/stop" | "subagent/resume" | "subagent/reopen" | "subagent/close" | "subagent/readResult" | "session/start" | "session/resume" | "session/fork" | "session/list" | "session/read" | "turn/start" | "turn/steer" | "turn/interrupt" | "turn/cancel" | "turn/unqueue" | "session/compact" | "session/delete" | "session/setModel" | "session/rename" | "session/setReasoningEffort" | "session/userShell" | "model/list" | "skill/list" | "task/background" | "task/stop" | "task/stopAll" | "goal/set" | "goal/edit" | "goal/clear" | "goal/pause" | "goal/resume" | "workflow/cancel" | "workflow/childControl" | "view/subscribe" | "view/unsubscribe" | "view/page" | "item/readOutput" | "approval/decide" | "approval/listPending" | "session/setApprovalMode" | "userInput/answer" | "userInput/cancel" | "userInput/clarify" | "usage/read"; /** Every wire notification in this schema (SS1.9 index). */ export type MspNotification = | "initialized" | "session/started" | "session/closed" | "session/deleteCompleted" | "skill/changed" | "turn/started" | "turn/completed" | "turn/retracted" | "turn/retryScheduled" | "turn/unqueued" | "item/started" | "item/updated" | "item/delta" | "item/completed" | "view/gap" | "approval/requested" | "approval/updated" | "approval/resolved" | "userInput/requested" | "userInput/settled" | "session/modelChanged" | "session/reasoningEffortChanged" | "session/statusChanged" | "session/goalChanged" | "session/todoListChanged" | "session/branchChanged" | "session/tokenUsage" | "session/contextUsage" | "session/approvalModeChanged" | "session/modelRouteUnserved" | "session/nameChanged" | "session/viewHealthChanged" | "session/listChanged" | "usage/changed"; /** Every server-initiated wire request in this schema (SS5.3/SS5.10.1 index). */ export type MspServerRequest = "approval/request" | "userInput/request"; /** Every error `data.kind` in this schema's error table (SS1.6) — each code's primary kind plus its override kinds. */ export type MspErrorDataKind = | "parseError" | "invalidRequest" | "notInitialized" | "alreadyInitialized" | "methodNotFound" | "experimentalRequired" | "invalidParams" | "internal" | "pageEventTooLarge" | "outputResultTooLarge" | "overloaded" | "inputTooLarge" | "capabilityRequired" | "notFound" | "interrupted" | "cancelled" | "sessionNotFound" | "sessionInUse" | "sessionAmbiguous" | "forkBoundaryInvalid" | "sessionNotLoaded" | "sessionStreamMismatch" | "commandRejected" | "backpressured" | "skillNotFound" | "viewTruncated" | "outputUnavailable" | "boundaryPruned" | "boundaryUnusable" | "noBoundary" | "approvalNotFound" | "approvalAlreadyResolved" | "approvalChoiceInvalid" | "approvalRequirementStale" | "approvalReviewerUnavailable" | "userInputNotFound" | "userInputAlreadySettled" | "userInputAnswerInvalid";