Skip to content

Migrate chat format: frontmatter-per-message with message-indexed cursors #19

Description

@baby-joel

Summary

The current chat format is flat markdown with line-number-based cursors. This is brittle — editing a message shifts every cursor pointing past it, and there's no way to address individual messages or attach per-message metadata.

Proposed Format

Each message becomes its own "document" within the file, with YAML frontmatter and a markdown body, separated by ---:

---
id: 1
from: baby-joel
ts: 2026-03-25T12:05:00
---
UX test session — participants: baby-joel, or.
---
id: 2
from: or
ts: 2026-03-25T12:06:00
to: baby-joel
---
Or here, reading you loud and clear.

Cursor Change

Cursors would store a message index (e.g., 3 = "read through message 3") instead of a line number. This makes cursors stable regardless of message body length or edits.

Benefits

  • Stable cursors — editing a message body doesn't invalidate anyone's cursor
  • Message IDs — can address, reference, or thread individual messages
  • Per-message metadatafrom, to, ts, id, and extensible for future fields
  • Still human-readablecat still produces readable output, just with --- separators
  • Resolves --force cursor bug — the current send --force advances the cursor past unread messages the sender never saw (see related: send should not advance cursor)

Scope

This touches all tasks: send, read, wait, status, list, clear, cursor:clear, plus the full test suite (134 tests). It's a significant migration but the format is a better foundation for everything else we want to build.

Context

Discussed during UX testing session (2026-03-25) between Or and Baby Joel. Agreed to do this after fixing the immediate --force cursor bug.

Metadata

Metadata

Assignees

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