file-presentation.tsMerge remote-tracking branch 'origin/staging' into refactor/agent-files-sections # Conflicts: # apps/mail/modules/agents/components/AgentConversationFilesFolder.tsx # apps/mail/modules/conversations/components/files/ConversationFileTree.tsx # apps/mail/modules/files/components/list/FileListColumns.tsx # apps/mail/modules/files/components/list/index.ts # apps/mail/modules/files/components/list/types.ts # apps/mail/tests/modules/files/brain-explorer.test.tsx # apps/mail/tests/modules/files/list/FileListRow.test.tsx # apps/server/src/mastra/tools/debug/debugTool.ts # apps/server/src/services/playbook/playbook-execution-triggers.ts # apps/server/src/services/playbook/playbook-renderers.ts # apps/server/src/services/playbook/resolve-playbook-context.ts # apps/server/src/services/playbook/write-document-guarded.ts # apps/server/src/trpc/routes/documents.tsSep 9, 2026, 9:26 AMformat-file-size.tsfeat(files): the Files kit — one row, one surface, one set of columns (design: unified-files-ui phase 2) Ten row renderers across three surfaces each re-decided indentation, icon chrome, type size, selected colour and separators independently, which is why the same file in /brain and in a conversation looked like two different objects. This is the one place those decisions now live. Structure is Google Drive's — tile, name, then right-aligned columns. Identity is Linear's, read off the two files that already encode it: settings.tsx for the inset hairline and the single card, field.tsx for the no-class-strings rule. The columns declare the container width they need and drop themselves; the list is an @container, not a viewport breakpoint, because the conversation panel is narrow while the window is wide and a `md:` rule would put four columns in a 380px pane. Widths are fixed so a column's x-position never moves between rows. `as="link"` exists so a Drive row can be a real anchor with its actions as siblings rather than buttons nested inside it — a constraint DriveSection states three times and a test now holds. Co-Authored-By: Claude Opus 5 (1M context) <<email>>Aug 31, 2026, 9:52 PMrelative-time.tsfeat(files): the Files kit — one row, one surface, one set of columns (design: unified-files-ui phase 2) Ten row renderers across three surfaces each re-decided indentation, icon chrome, type size, selected colour and separators independently, which is why the same file in /brain and in a conversation looked like two different objects. This is the one place those decisions now live. Structure is Google Drive's — tile, name, then right-aligned columns. Identity is Linear's, read off the two files that already encode it: settings.tsx for the inset hairline and the single card, field.tsx for the no-class-strings rule. The columns declare the container width they need and drop themselves; the list is an @container, not a viewport breakpoint, because the conversation panel is narrow while the window is wide and a `md:` rule would put four columns in a 380px pane. Widths are fixed so a column's x-position never moves between rows. `as="link"` exists so a Drive row can be a real anchor with its actions as siblings rather than buttons nested inside it — a constraint DriveSection states three times and a test now holds. Co-Authored-By: Claude Opus 5 (1M context) <<email>>Aug 31, 2026, 9:52 PMworkspace-visibility.tsdocs(brain): why the agent-namespace match is a UUID, checked rather than assumed Greptile's second pass argued the pattern should not assume a UUID, on the grounds that `aop_agents.id` is a `text` column. True of the schema; not true of the data. Production holds 2215 agents and 414 distinct `agent-*` root segments, and none of them is anything but a UUID or `agent-instructions`. There is also no second signal available: a namespace root is a plain `folder` row, the same document type a person's own folder has. So it is a choice between two regexes whose failure modes are not comparable — too loose loses a folder someone MADE from the tree, the search and the graph at once; too strict shows one extra row. Kept strict, with the numbers and the reasoning written down, and the assumption pinned by a test so the day agent ids stop being UUIDs it goes red there first. Co-Authored-By: Claude Opus 5 (1M context) <<email>>Sep 7, 2026, 6:19 PM