import type { ReviseEditorHandle, ReviseToolbarState } from "@reviseio/sdk";
Documents
type ReviseDocumentSource = File | Blob | ArrayBuffer;
/** DOCX is the only format carrying comments and tracked changes. */
type ReviseDocumentFormat = "docx" | "markdown" | "txt" | "html";
interface ReviseDocumentInput {
/** Stable, host-owned. Names this document in APIs, tools, and callbacks. */
id: string;
/** The source file. Optional: a document joining an established
* collaborative room has no file to open. The name is historical — any
* supported format goes here. */
docx?: ReviseDocumentSource;
/** Share this document over a Yjs transport you own. */
collaboration?: ReviseCollaborationConfig;
/** Overrides the editor-wide role for this document. */
role?: ReviseDocumentRole;
/** Inferred from filename, then MIME type, defaulting to DOCX. */
format?: ReviseDocumentFormat;
title?: string;
documentMode?: ReviseDocumentMode;
readOnly?: boolean;
zoom?: ReviseZoom;
defaultCommentsOpen?: boolean;
agent?: ReviseAgentConfig;
}
interface ReviseOpenDocumentOptions {
/** Newly opened documents become active by default. */
activate?: boolean;
}
interface ReviseOpenDocument {
id: string;
title: string;
status: "opening" | "ready" | "error";
active: boolean;
error?: string;
}
interface ReviseDocumentCollectionState {
activeDocumentId: string | null;
documents: ReviseOpenDocument[];
}
type ReviseDocumentScoped<T> = T & { forDocument(documentId: string): T };
Collaboration
ReviseYDoc and ReviseAwareness are any: they are your Yjs types, and
the SDK deliberately does not import Yjs into its public types so that the
package has no hard dependency on it. Cast them to Y.Doc and Awareness
on your side.
type ReviseYDoc = any;
type ReviseAwareness = any;
interface ReviseCollaborationProvider {
document?: ReviseYDoc;
doc?: ReviseYDoc;
getYDoc?: () => ReviseYDoc;
awareness?: ReviseAwareness | null;
}
type ReviseCollaborationConnect = (
ydoc: ReviseYDoc,
awareness: ReviseAwareness,
) => ReviseCollaborationProvider | { destroy?: () => void } | void;
interface ReviseCollaborationConfig {
/** Recommended. The editor builds the document; you attach a transport. */
connect?: ReviseCollaborationConnect;
/** A provider that already owns its document. Validated before use. */
provider?: ReviseCollaborationProvider;
/** A document you own. Validated before use; prefer `connect`. */
ydoc?: ReviseYDoc;
/** Remote carets and presence. Pass null to opt out. */
awareness?: ReviseAwareness | null;
/** The transaction origin your transport applies remote updates with.
* Required when passing `ydoc` without a `provider`. */
remoteOrigin?: unknown;
/** Whether the transport finished its initial sync. The document stays
* closed until this is true. */
synced?: boolean;
/** "if-empty" (default) writes the source file into an empty room;
* "never" always joins. */
seed?: "if-empty" | "never";
}
interface RevisePeer {
clientId: number;
isLocal: boolean;
id?: string;
name?: string;
email?: string;
image?: string;
color: string;
}
interface ReviseCollaborationState {
enabled: boolean;
synced: boolean;
peers: RevisePeer[];
}
Roles
/** What a participant may do. A boundary, not a starting point: unlike
* `documentMode` it cannot be escaped from inside the editor. */
type ReviseDocumentRole = "editor" | "suggester" | "viewer";
interface ReviseRolePolicy {
readonly modes: readonly ReviseDocumentMode[];
readonly canEdit: boolean;
readonly canEditDirectly: boolean;
readonly canResolveSuggestions: boolean;
readonly canComment: boolean;
}
declare function rolePolicy(role: ReviseDocumentRole): ReviseRolePolicy;
/** Thrown by `tools.execute()` and `agent.run()` when a role forbids the call. */
declare class ReviseRoleError extends Error {
readonly role: ReviseDocumentRole;
readonly action: string;
}
Tracked changes
interface ReviseTrackedChange {
id: string;
/** Word's three revision kinds, plus "move" for a linked move pair. A
* replacement appears as both a delete and an insert, as it does in Word.
* A linked move is ONE change: `deletedText` is the text at the source,
* `insertedText` the text at the destination, and resolving it settles
* both locations atomically. */
kind: "insert" | "delete" | "format" | "move";
/** A person, "Revise Agent", an external agent, or "Anonymous". */
author: string;
authorType: "human" | "ai";
agentModel?: string;
/** Epoch milliseconds. */
createdAt?: number;
description?: string;
/** Blocks this change touches, in document order. */
blockIds: string[];
/** For kind "move": blocks the text moved out of, in document order. */
moveSourceBlockIds?: string[];
/** For kind "move": blocks the text moved into, in document order. */
moveDestinationBlockIds?: string[];
insertedText?: string;
deletedText?: string;
commentThreadId?: string;
}
Settings
interface ReviseTrackedChangesSettings {
/** Start review with deleted text shown inline (strikethrough). Reviewers
* used to Word usually want this on. Default false. */
showRemovalsInReview?: boolean;
/** "revise" (default): per-kind colors with a soft background tint.
* "word": classic redlines — all revisions in red, insertions underlined,
* deletions struck through, no background tint. */
markupStyle?: "revise" | "word";
}
interface ReviseEditorSettings {
trackedChanges?: ReviseTrackedChangesSettings;
}
Modes and zoom
type ReviseDocumentMode = "editing" | "suggesting" | "viewing";
type ReviseToolbarMode = "native" | "none";
type ReviseZoom = number | "fit-width";
interface ReviseZoomState {
zoom: ReviseZoom;
scale: number; // effective canvas scale; computed for fit-width
}
Toolbar and view state
interface ReviseToolbarState {
ready: boolean;
readOnly: boolean;
documentMode: ReviseDocumentMode;
activeTab: "edit" | "layout" | "insert" | "tools" | "review";
hasSelection: boolean;
canUndo: boolean;
canRedo: boolean;
formatting: Record<string, unknown> & {
bold?: boolean;
italic?: boolean;
underline?: boolean;
strikethrough?: boolean;
color?: string;
backgroundColor?: string;
fontFamily?: string;
};
heading?: 1 | 2 | 3 | 4 | 5 | 6;
alignment?: "left" | "center" | "right" | "justify";
lineSpacing?: number;
fontSizePt?: number;
blockType: { type: string; variant?: string } | null;
review: {
open: boolean;
targetCount: number;
currentTargetSuggestionCount: number;
allOpenSuggestionCount: number;
showRemovals: boolean;
viewMode: "all-markup" | "final" | "original";
};
}
interface ReviseViewState {
ready: boolean;
title: string;
documentMode: ReviseDocumentMode;
readOnly: boolean;
commentsOpen: boolean;
commentCount: number;
reviewOpen: boolean;
reviewTargetCount: number;
}
Review and comments
interface ReviseReviewState {
open: boolean;
commentsOpen: boolean;
targetCount: number;
currentTargetSuggestionCount: number;
allOpenSuggestionCount: number;
openSuggestionIds: string[];
currentSuggestionIds: string[];
visibleAgentSuggestionIds: string[];
activeCommentId: string | null;
showRemovals: boolean;
viewMode: "all-markup" | "final" | "original";
commentThreads: ReviseCommentThread[];
}
interface ReviseCommentAnchor {
blockId: string;
start: number;
end: number;
}
interface ReviseCommentRecord {
id: string;
author: string;
initials?: string;
authorId?: string;
authorImageUrl?: string;
createdAt: string;
bodyMd: string;
mentions?: ReviseCommentMention[];
parentId?: string;
relatedSuggestionIds?: string[];
resolved?: boolean;
}
interface ReviseCommentThread {
root: ReviseCommentRecord;
replies: ReviseCommentRecord[];
anchor: ReviseCommentAnchor | null;
relatedSuggestionIds: string[];
}
Selection
interface ReviseSelectionSnapshot {
documentId: string | null;
anchor: ReviseSelectionPosition | null;
focus: ReviseSelectionPosition | null;
start: ReviseSelectionPosition | null;
end: ReviseSelectionPosition | null;
target: ReviseTextTarget | null;
selectionTarget: ReviseSelectionTarget | null;
activeMarks: string[];
activeCommentIds: string[];
activeChangeIds: string[];
quotedText: string;
text: string; // alias for quotedText
collapsed: boolean;
empty: boolean; // alias for collapsed
}
type ReviseSelectionCapture = ReviseSelectionSnapshot & {
documentId: string;
target: ReviseTextTarget;
selectionTarget: ReviseSelectionTarget;
};
type ReviseSelectionRestoreResult =
| { success: true }
| { success: false; reason: string };
Tools
interface ReviseEditorToolDefinition {
name: string;
description: string;
inputSchema: Record<string, unknown>;
}
interface ReviseEditorToolExecutionOptions {
documentId?: string;
directMode?: boolean;
}
// The shared tool contract (also exported by @reviseio/sdk/backend):
type ReviseToolResult<Name> =
| { ok: true; value: ReviseToolResponse<Name> }
| { ok: false; error: ReviseToolFailure<Name> };
interface ReviseToolResponse<Name> {
callId: string;
tool: Name;
message: string | null;
data: ReviseToolData<Name>;
context: { format: "revise-html"; html: string } | null;
suggestionIds: string[] | null;
}
interface ReviseToolFailure<Name> {
callId: string;
tool: Name;
code: string;
message: string;
}
interface ReviseSuggestionDecision {
resolved: string[];
missing: string[];
unresolved: string[];
}
Agent
interface ReviseAgentConfig {
/** Author name stamped on comments and tracked changes made through the
* tool surface. Defaults to "Revise Agent". */
name?: string;
baseUrl?: string;
token?: string;
conversationId?: string;
provider?: string;
model?: string;
turnStream?: ReviseAgentTurnStream;
disableMetrics?: boolean;
}
interface ReviseAgentEvent {
state: "idle" | "streaming" | "complete" | "error";
activeTool: string | null;
status: string | null;
error?: string;
messages: ReviseAgentMessage[];
}
interface ReviseAgentRunResult extends ReviseAgentEvent {
actionCount: number;
}
Fonts
interface ReviseFontDefinition {
family: string; // canonical, stored in the document and written to DOCX
label?: string; // picker label; defaults to family
cssFamily?: string; // browser preview stack; defaults to family
fontWeight?: number | string;
}