Skip to content

feat: version history for timeline sequences - #4712

Merged
georgi merged 4 commits into
mainfrom
claude/timeline-versioning-opus-6f7t86
Aug 4, 2026
Merged

feat: version history for timeline sequences#4712
georgi merged 4 commits into
mainfrom
claude/timeline-versioning-opus-6f7t86

Conversation

@georgi

@georgi georgi commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Adds document-level version history for timeline sequences, end to end: storage, API, editor UI, and headless CLI harness.

What's in it

Models (packages/models)

  • New timeline_sequence_versions table (SQLite + Postgres, migration 20260804_000000), following the newer unprefixed document-editor tables. Hardened per the application_versions precedent: FK cascade to timeline_sequences, user_id copied at snapshot time, and a unique (timeline_id, version) index.
  • TimelineSequenceVersion model: snapshot (max+1 numbering with one retry on a write race), listForTimeline, findByVersion, pruneAutosaves (only touches save_type: "autosave" rows), deleteForTimeline.

API (packages/protocol, packages/websocket)

  • Zod schemas and a nested timeline.versions tRPC sub-router: list, get, create, restore, delete — all owner-scoped through the router's existing loadOwned.
  • timeline.update takes a best-effort autosave snapshot at most every 5 minutes (20 autosaves retained; manual/restore rows are never pruned).
  • restore snapshots the current state as save_type: "restore" before writing, so a restore is itself undoable — closing a gap the workflow-versions precedent has. The write goes through the existing updateFieldsIfUnchanged CAS path.
  • timeline.delete removes the sequence's versions (belt-and-braces with the FK cascade).

Web (web/)

  • A History tab in the timeline editor's inspector region, backed by a new useTimelineVersions server-state hook: save named manual snapshots, restore (confirm dialog), delete (destructive confirm). ui_primitives and design tokens throughout.
  • Restore applies the mutation response to the open editor via applyTimelineSequenceToStore (extracted from useLoadTimelineIntoStore): document replaced, fresh baseUpdatedAt token set, undo history cleared — so the 750 ms autosave re-arms on the restored state instead of clobbering it with pre-restore in-memory edits.

CLI + harness (packages/cli)

  • nodetool timeline versions list|show|create|restore|delete, local-DB with --json. restore mirrors the router's semantics and prints a static validation verdict on the restored document.
  • New timeline-versions harness registry entry; nodetool harness audit passes with no undocumented gap. Commands documented in CLAUDE.md.

Testing

  • packages/models: 792 tests (9 new) · packages/protocol: 786 · packages/websocket: 2105 (24 new router tests) · packages/cli: 507 (24 new)
  • web: full Jest suite, 1062 suites / 12,500 tests passing (17 new across hook + panel)
  • Repo typecheck (web, electron) and lint clean. The mobile typecheck leg cannot run in this sandbox (its Expo dependency tree is not installed); no mobile files were touched.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AFVn8LPnkLRAGYUE3ucuKA


Generated by Claude Code

claude added 4 commits August 4, 2026 21:11
New TimelineSequenceVersion model backing document-level version
history for timeline sequences: snapshot with unique-index-backed
version numbering (one retry on a write race), listForTimeline,
findByVersion, pruneAutosaves (autosave rows only), and
deleteForTimeline. Includes SQLite + Postgres schemas, TABLE_COLUMNS
and getCreateSchemaSql entries, and migration 20260804_000000.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AFVn8LPnkLRAGYUE3ucuKA
Adds version-history procedures to the timeline router — versions.list/
get/create/restore/delete — plus protocol Zod schemas and types.
timeline.update takes a best-effort autosave snapshot at most every
5 minutes (20 autosaves kept, manual/restore rows never pruned), and
restore writes a save_type "restore" snapshot of the current state
first so a restore is itself undoable. timeline.delete removes the
sequence's versions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AFVn8LPnkLRAGYUE3ucuKA
Adds a History tab to the timeline editor's inspector region backed by
a new useTimelineVersions server-state hook (list, manual snapshot,
restore, delete over timeline.versions.*). Restore applies the
mutation response to the open editor via applyTimelineSequenceToStore
(extracted from useLoadTimelineIntoStore), which replaces the document,
sets the fresh baseUpdatedAt token, and clears undo history — so the
debounced autosave re-arms on the restored state instead of clobbering
it with pre-restore in-memory edits.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AFVn8LPnkLRAGYUE3ucuKA
Adds a local-DB timeline versions command group — list, show, create,
restore, delete — with --json output. restore mirrors the tRPC
router's semantics: pre-restore snapshot, CAS write of document and
render settings, then a static validation verdict on the restored
document. Registers a timeline-versions harness entry so the timeline
surface owns the version-history paths, and documents the commands in
CLAUDE.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AFVn8LPnkLRAGYUE3ucuKA
@georgi
georgi enabled auto-merge (squash) August 4, 2026 21:48
@georgi
georgi merged commit 2c663a0 into main Aug 4, 2026
27 checks passed
@georgi
georgi deleted the claude/timeline-versioning-opus-6f7t86 branch August 4, 2026 21:56
georgi added a commit that referenced this pull request Aug 5, 2026
* feat: sketch document version history — data layer

Mirror timeline sequence versioning (#4712) for sketches: an
image_document_versions table with a per-document monotonic version
number, an ImageDocumentVersion model (snapshot with unique-violation
retry, autosave pruning that never touches manual/restore snapshots),
the migration plus PG bootstrap DDL, and the protocol schemas for the
document-level version history distinct from per-layer generation takes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018yzrorMvguPf5DMZjMRNP8

* feat: sketch document version history — router, CLI, harness

The sketch tRPC router gains a documentVersions sub-router (list, get,
create, restore, delete) alongside the existing per-layer generation
takes: restore snapshots the pre-restore state first so it is undoable,
sketch.update writes a best-effort autosave at most every five minutes
(20 kept, pruned), and sketch.delete removes the document's history.

nodetool sketch versions list|show|create|restore|delete reads and
writes the same history against the local database; restore CAS-writes
the snapshot back and exits non-zero when the restored document no
longer parses as a JSON object. The sketch surface and its harness are
registered in the harness registry, and CLAUDE.md documents the command.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018yzrorMvguPf5DMZjMRNP8

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants