import type { ReviseEditorHandle, ReviseToolbarState } from "@reviseio/editor";
Documents
type ReviseDocumentSource = File | Blob | ArrayBuffer;
/** DOCX is the high-fidelity path; ODT and RTF also bring comments and
* tracked changes in. */
type ReviseDocumentFormat = "docx" | "odt" | "rtf" | "markdown" | "txt" | "html";
interface ReviseDocumentInput {
/** Stable, host-owned. Names this document in APIs, tools, and callbacks. */
id: string;
/** The file to open, in any supported format. Optional: a document joining
* an established collaborative room has no file to open. */
source?: ReviseDocumentSource;
/** The original name for `source`, still accepted. Pass one or the other. */
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 typed any so the public types do not
depend on Yjs. Cast them to Y.Doc and Awareness in your code.
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[];
}
connect, provider, or ydoc.
Roles
/** What a participant may do. Unlike `documentMode`, it cannot be changed
* 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). 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" | "compact" | "floating" | "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/editor/server):
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
/** Configure one transport — turnStream, baseUrl, or token — or agent runs
* fail fast with `agent_not_configured` and send nothing. */
interface ReviseAgentConfig {
/** Author name stamped on comments and tracked changes made through the
* tool surface. Defaults to "Revise Agent". */
name?: string;
/** Your own Revise agent backend. Without it, runs go to Revise's hosted
* agent, which needs a token. */
baseUrl?: string;
/** Required for Revise's hosted agent; an anonymous baseUrl needs none. */
token?: string;
conversationId?: string;
provider?: string;
model?: string;
/** Your own model or gateway. A new value applies to the next run. */
turnStream?: ReviseAgentTurnStream;
/** Skip the run-completion accounting call to baseUrl. Implied by
* turnStream. */
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;
}