Files
paseo/plugins/muse-provider/server/msp.d.ts
T
Mohamed Boudraandmillerben95 8332f4d1ff feat(muse): add Muse Code as a built-in provider plugin (#5719)
* test(muse): record real host protocol fixtures

* feat(muse): add built-in MSP provider

Co-authored-by: millerben95 <millerben95@users.noreply.github.com>

* fix(muse): expose provider settings in the app

The daemon registered host settings without a client contribution, leaving sandbox, network, and workspace trust unreachable. Share the definition with a settings screen and expose it through Command Center even when installed plugins are disabled.

* docs(muse): publish setup and provider support

* test: correct runtime fixtures and restart readiness

* fix(muse): hide reminder housekeeping from the timeline

* fix(muse): use the official Muse Code mark

Source: https://muse.ai/images/favicon/app-squiggle.svg

Preserve the official silhouette path verbatim. Remove its gradient definition and use currentColor, scaling the original 100-unit coordinates into the 24-unit viewBox. Black silhouette renders match pixel-for-pixel.

* fix(muse): adapt to current plugin APIs

Use the screen API introduced with sidebar plugin items. Usage reports now come from source account discovery; remove the retired agent usage-reference request and headline marker, and exercise discovery through the existing provider fixtures.

---------

Co-authored-by: millerben95 <millerben95@users.noreply.github.com>
2026-09-30 14:56:41 +01:00

2691 lines
139 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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<string, unknown>;
/** 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<string, unknown>;
}
/** 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<string, unknown>;
/** 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<string, SessionMcpServerConfig>;
}
/** `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<string, string>;
/** 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<string, string>;
/** 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 `<pluginId>:<skillId>` 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<string, unknown>;
/** 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<string, unknown>;
}
/** `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";