Skip to content

feat(editor): expose bounded imperative undo/redo history control #148

Description

@seonghobae

Buyer-visible host integration gap

Protected main already ships Undo/Redo toolbar controls and keyboard history commands, and CwlEditorHandle.getEditor() lets an advanced host reach the underlying TipTap instance. The stable Inkspan imperative handle itself, however, does not expose history capability or execution. A host that hides/replaces the built-in toolbar, integrates Inkspan into an application command palette, or maps native desktop menu items must therefore depend on TipTap internals merely to invoke the same history behavior Inkspan already owns.

This issue adds one narrow host-control surface; it does not create a new history engine.

Proposed public contract

Extend CwlEditorHandle with:

  • canUndo(): boolean
  • undo(): boolean
  • canRedo(): boolean
  • redo(): boolean

Semantics:

  1. Before editor creation / after destruction, capability methods return false and execution methods return false without throwing.
  2. On a standalone editor, the methods delegate to the exact same TipTap/StarterKit history commands used by the built-in toolbar.
  3. On CollaborativeCwlEditor, the same shared handle delegates to the collaboration-aware undo/redo commands already registered by the Yjs collaboration extension; Inkspan must not add StarterKit local history back into collaboration mode.
  4. Execution returns TipTap command success/failure and does not manufacture document-change, durable-save, revision, audit, transport, authorization, or persistence evidence.
  5. No network, credential, model, database, provider creation, room authority, or host persistence behavior is added.
  6. Existing getEditor() remains available; this feature is a stable narrow convenience boundary, not an attempt to hide TipTap completely.

Test-first acceptance

  • RED from exact protected main@50ac98cfa0ad9e8dd75f93ca437a5679fed4d804: a component test proves the public handle lacks canUndo/undo/canRedo/redo while the editor already has working history commands.
  • GREEN: a real standalone editor mutation becomes undoable, undo() restores the prior document, redo() reapplies it, and capability booleans track those transitions.
  • Cover the pre-editor/null-handle boundary without throwing.
  • Cover the shared collaborative handle with an in-memory Y.Doc and prove the methods use collaboration history rather than local StarterKit history.
  • Preserve existing callbacks, focus behavior, serialization, revision/evidence contracts, keyboard shortcuts, toolbar behavior, package consumers, and 100% owned production statement/branch/function/line coverage.
  • Exact-head CI, Security Scan, SAST, package/browser/Office gates must pass before integration.

Ownership

Inkspan owns only local editor command delegation. Hosts continue to own authorization, durable persistence, tenant policy, audit, collaboration provider/room policy, retention, transport, model use, and any user-facing command/menu copy.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions