Repository navigation
Description
Parent
Parent PRD: #82
What to build
Full end-to-end implementation of the /clear and /clear N slash commands. When a user types /clear (wipe everything) or /clear 3 (keep last 3 turns), the system prunes conversation context, inserts a visual trim point divider in the chat timeline, and restarts the provider session so the agent forgets the trimmed history.
This slice covers every layer: schema contracts, server-side CQRS (command dispatch, event sourcing, read model update), provider session restart, WebSocket dispatch, the composer slash command registration, and the UI divider component.
After this slice, a user can type /clear and see a collapsed divider marking trimmed history. /clear N works identically but preserves the last N turns as bootstrap context for the new session. Git checkpoints for trimmed turns are preserved (not deleted) so undo still works.
Acceptance criteria
-
thread.context.trimcommand schema defined in contracts (with optionalkeepLastNTurnsfield) -
thread.trim-point-createddomain event schema defined in contracts -
OrchestrationThreadread model gains acontextTrimPoints: Array<ContextTrimPoint>field (ordered array withid,createdAt,beforeEntryId,prunedMessageCount,prunedTurnIds) - Decider validates thread exists, determines trim boundary (last message before trim, or last N turns boundary), emits
thread.trim-point-created - Projector appends trim point to thread read model and updates derived timeline state
- Trim command triggers provider session restart: current session is stopped, new session starts with resume cursor past trim boundary. Surviving messages (for
/clear N) are sent as bootstrap context. -
/clearand/clear [N]parse correctly in the composer slash command system and dispatchthread.context.trim -
ContextTrimPointDividercomponent renders in the timeline at the trim boundary, showing "Earlier messages" label and pruned message count, always in collapsed state -
deriveTimelineEntries()produces context-trim entries from the read model -
deriveMessagesTimelineRows()handles the trim entry as a divider row - Git checkpoints for pruned turns remain available (no cleanup of
projection_turnsrows or git refs) - Idempotent: dispatching a trim command on a thread with no messages or no turns produces a no-op trim point (prunedMessageCount = 0)
- Tests cover: command → event → read model, timeline derivation with trim points, slash command parsing
Blocked by
None — can start immediately
Activity
feat: /clear + /clear N — core context trim infrastructure (#83)
/clear + /clear N — core context trim infrastructure (#97)
harrryyd commentedon Jun 8, 2026
Merged in #97.
[codex] sync v0.0.27 retained features (#131)