ConversationMention.tsfeat: Current | Future agenda documents (design: agenda-current-future-restructure phases 3, 5, 6) Three phases land together because they are interdependent — the markdown grammar, the path cutover and the band reconciler all touch the same seam and were built concurrently. Phase 3 (client): retires conversationGroup. The load-bearing change is the @-mention flow — selecting a conversation used to call promoteTaskToGroup, which WRAPPED the task in a group; that single call produced the nesting this redesign removes. It now inserts an inline conversationNode chip and still sets the conversationId attr, which stays the owning FK. promote-task-to-group.ts and ConversationGroupNode.tsx are deleted, conversation resolution in agenda-task-walk reads attr -> inline chips -> nearest shallower row, and the Tab / Shift-Tab cases that moved tasks in and out of a group container are gone (nesting is indentLevel now). The markdown grammar drops the group token and finally serializes dueDate, closing a data-loss bug that would otherwise have collapsed every band in the Future view. Phase 5: one agenda document per view instead of one per calendar day. `user/agendas/{current,future}`; the rolling flag is gone because Current IS the rolling doc by definition. Current holds everything due on or before today with no lookback floor; Future holds everything after. Phase 6: the Future document is divided into five relative bands derived from each task's dueDate on every read. Because that membership drifts at midnight, reflowBands moves rows between bands — the one place the reconciler is allowed to reflow, deliberately against the daily reconciler's no-reflow rule. Verified headlessly against this repo's server (port 8790) as <email>: `agenda tree future` returns all five bands correctly bucketed (07-22 tomorrow, 07-23 day-after, 07-24 next-week, Aug next-month, Sep future) with inline chips and group subsections only where populated; `agenda tree current` returns the group sections plus the __past__ lane. 222 server tests, 218 mail tests. Co-Authored-By: Claude Opus 4.8 (1M context) <<email>>Jul 21, 2026, 4:42 PMConversationMentionList.tsxrefactor: consolidate document code into documents/ + add {{ event mention Frontend: move the editor primitive, file-link/, mention/, yjs/, and history/ under apps/mail/modules/documents/ so every doc-editor concern lives in one place. Rename AgendaConversationMention -> ConversationMention and generalize it to take an onSelect callback so the agenda keeps its task-promotion dispatch while regular docs insert a plain conversationNode chip. Backend: rename services/document-store/ -> services/documents/ and absorb services/sse/doc-event-bus.ts + services/sse/doc-events-delta.ts alongside their tests. New: {{ event mention in documents. Custom Tiptap suggestion matcher requires the literal {{ prefix; picker shows a type-icon, title, conversation context, and relative time; selecting inserts an eventNode chip. New tRPC route crm.searchEventsForMention runs a global search across the user's crm_events (emails, slack, meetings, calls, notes, custom) joined to company info. crm_conversation_updates lives in its own table and stays excluded by design. Co-Authored-By: Claude Opus 4.7 (1M context) <<email>>May 26, 2026, 9:30 AMEventChip.tsxfeat: typed cells, live ref chips, and tables as first-class files (design: table-documents phases 6, 7) Phase 6 — a cell chip and a prose chip are literally the same component. ConversationNode and EventNode were split the way FileLinkChip already was (Content + the NodeViewProps wrapper that mounts it), so behaviour stays identical by construction: same data hooks, same click handler, same setSelectedArtifact path. The only PM-specific parts were NodeViewWrapper and reading node.attrs, which is why the extraction is small. Editing mounts a one-line TipTap instance for the focused cell ONLY, configured with the EXISTING suggestion extensions — so typing `@` in a table cell runs the same extension, the same search, and inserts the same node as typing `@` in a prose document, rather than a parallel implementation that drifts. Exactly one editor is alive at a time, so the descriptor-tree costs that rule out a ProseMirror grid never apply here. Phase 7 — "New table" in the file-creation menu, a table graph-node kind, "N rows × M columns" from the metadata the server hook already writes, the grid in the artifact panel (discriminated inside FileArtifact on the FETCHED documentType, since the outer switch is on ContextKind where a table is just a `file`), a read-only grid on the public share page, resolveOpenDoc, and Download as Excel/CSV wired to documents.exportTable. Also completes Phase 10's agent-facing half: the `table` tool's `create` now takes a `from` clause, so an agent materializes rows from a real query instead of transcribing them. The query runs BEFORE the document is provisioned, so an over-cap or malformed filter leaves no half-built table behind, and truncation plus any binding error is surfaced as a tool warning rather than silently yielding a short or empty column. Three fixes found by running the suites rather than by reading: - The tool description had grown to 2134 chars, past the 2048 limit Claude Code truncates at — text past the cutoff is silently dropped for every caller. Trimmed to 2030 while ADDING the `from` guidance, which is the part most worth having early. - tableTool.test.ts enumerated its mock of the documents barrel, so every new import in the tool broke the file with a mock error rather than a real failure. It now spreads the real module. - A cell-ref offset expectation was hand-counted one short (`[[conversation: 9f2e]]` is 22 chars, so end is 27). The implementation was right; the test now asserts by slicing the value, since these offsets exist precisely so the grid can interleave text and chips. Tests: 1787 server, 55 mail across the table/home/files suites. Both apps typecheck clean. Co-Authored-By: Claude Opus 5 (1M context) <<email>>Aug 10, 2026, 5:04 PMEventMention.tsrefactor: consolidate document code into documents/ + add {{ event mention Frontend: move the editor primitive, file-link/, mention/, yjs/, and history/ under apps/mail/modules/documents/ so every doc-editor concern lives in one place. Rename AgendaConversationMention -> ConversationMention and generalize it to take an onSelect callback so the agenda keeps its task-promotion dispatch while regular docs insert a plain conversationNode chip. Backend: rename services/document-store/ -> services/documents/ and absorb services/sse/doc-event-bus.ts + services/sse/doc-events-delta.ts alongside their tests. New: {{ event mention in documents. Custom Tiptap suggestion matcher requires the literal {{ prefix; picker shows a type-icon, title, conversation context, and relative time; selecting inserts an eventNode chip. New tRPC route crm.searchEventsForMention runs a global search across the user's crm_events (emails, slack, meetings, calls, notes, custom) joined to company info. crm_conversation_updates lives in its own table and stays excluded by design. Co-Authored-By: Claude Opus 4.7 (1M context) <<email>>May 26, 2026, 9:30 AMEventMentionList.tsxrefactor: consolidate document code into documents/ + add {{ event mention Frontend: move the editor primitive, file-link/, mention/, yjs/, and history/ under apps/mail/modules/documents/ so every doc-editor concern lives in one place. Rename AgendaConversationMention -> ConversationMention and generalize it to take an onSelect callback so the agenda keeps its task-promotion dispatch while regular docs insert a plain conversationNode chip. Backend: rename services/document-store/ -> services/documents/ and absorb services/sse/doc-event-bus.ts + services/sse/doc-events-delta.ts alongside their tests. New: {{ event mention in documents. Custom Tiptap suggestion matcher requires the literal {{ prefix; picker shows a type-icon, title, conversation context, and relative time; selecting inserts an eventNode chip. New tRPC route crm.searchEventsForMention runs a global search across the user's crm_events (emails, slack, meetings, calls, notes, custom) joined to company info. crm_conversation_updates lives in its own table and stays excluded by design. Co-Authored-By: Claude Opus 4.7 (1M context) <<email>>May 26, 2026, 9:30 AMEventNode.tsxfeat: typed cells, live ref chips, and tables as first-class files (design: table-documents phases 6, 7) Phase 6 — a cell chip and a prose chip are literally the same component. ConversationNode and EventNode were split the way FileLinkChip already was (Content + the NodeViewProps wrapper that mounts it), so behaviour stays identical by construction: same data hooks, same click handler, same setSelectedArtifact path. The only PM-specific parts were NodeViewWrapper and reading node.attrs, which is why the extraction is small. Editing mounts a one-line TipTap instance for the focused cell ONLY, configured with the EXISTING suggestion extensions — so typing `@` in a table cell runs the same extension, the same search, and inserts the same node as typing `@` in a prose document, rather than a parallel implementation that drifts. Exactly one editor is alive at a time, so the descriptor-tree costs that rule out a ProseMirror grid never apply here. Phase 7 — "New table" in the file-creation menu, a table graph-node kind, "N rows × M columns" from the metadata the server hook already writes, the grid in the artifact panel (discriminated inside FileArtifact on the FETCHED documentType, since the outer switch is on ContextKind where a table is just a `file`), a read-only grid on the public share page, resolveOpenDoc, and Download as Excel/CSV wired to documents.exportTable. Also completes Phase 10's agent-facing half: the `table` tool's `create` now takes a `from` clause, so an agent materializes rows from a real query instead of transcribing them. The query runs BEFORE the document is provisioned, so an over-cap or malformed filter leaves no half-built table behind, and truncation plus any binding error is surfaced as a tool warning rather than silently yielding a short or empty column. Three fixes found by running the suites rather than by reading: - The tool description had grown to 2134 chars, past the 2048 limit Claude Code truncates at — text past the cutoff is silently dropped for every caller. Trimmed to 2030 while ADDING the `from` guidance, which is the part most worth having early. - tableTool.test.ts enumerated its mock of the documents barrel, so every new import in the tool broke the file with a mock error rather than a real failure. It now spreads the real module. - A cell-ref offset expectation was hand-counted one short (`[[conversation: 9f2e]]` is 22 chars, so end is 27). The implementation was right; the test now asserts by slicing the value, since these offsets exist precisely so the grid can interleave text and chips. Tests: 1787 server, 55 mail across the table/home/files suites. Both apps typecheck clean. Co-Authored-By: Claude Opus 5 (1M context) <<email>>Aug 10, 2026, 5:04 PM