Part order fidelity (render order = storage order). AssistantMessage used to split a message's parts by the process flag and render all process parts above all content parts, so tool calls floated away from the text that surrounded them. New messageparts.ts#groupParts groups only consecutive process parts in place; content parts keep their original positions. Live streaming now maintains LiveState.parts in event-arrival order (tool results pair with their calls; artifact.created pushes an artifact_ref so the chip appears mid-run).
Download channel. Artifact chips become icon + open + download; api.artifactDownloadUrl rides the new ?download=1 semantics (backend PR). DocViewer and every artifacts-panel row expose download actions.
Workspace file management. ArtifactsPanel: search, kind filter, upload, per-row preview/download/delete-with-confirm, size and mtime metadata. DocViewer rebuilt as a single-layer OverlayHost (no nested modal): pdf inline iframe, csv/json monospace, binary info card with a download CTA. Inbox result cards open artifacts through the docBridge wired in Workbench.
Settings migration. SettingsModal adopts @ui SettingRow/SettingsGroup with the save button pinned in the shell actions bar; legacy .setting-row styles removed.
Verification
tsc --noEmit clean; vitest run 20 passed (groupParts interleaving/merging/edge cases, humanSize, artifactIcon); production build ok.
make test (Dev combo) green.
Headless 12/12 on a mock server with an interleaved-parts probe message inserted directly into SQLite: DOM order is text → process-collapse → text → artifact-chip; chip/panel/viewer download links carry download=1; panel shows toolbar/filter/upload/meta.
Depends on: Agent-System-UI and Agent-System-Backend same-branch PRs (compound-selector shell, SettingRow ReactNode, download semantics).
## What
**Part order fidelity (render order = storage order).** AssistantMessage used to split a message's parts by the `process` flag and render all process parts above all content parts, so tool calls floated away from the text that surrounded them. New `messageparts.ts#groupParts` groups only *consecutive* process parts in place; content parts keep their original positions. Live streaming now maintains `LiveState.parts` in event-arrival order (tool results pair with their calls; `artifact.created` pushes an artifact_ref so the chip appears mid-run).
**Download channel.** Artifact chips become icon + open + download; `api.artifactDownloadUrl` rides the new `?download=1` semantics (backend PR). DocViewer and every artifacts-panel row expose download actions.
**Workspace file management.** ArtifactsPanel: search, kind filter, upload, per-row preview/download/delete-with-confirm, size and mtime metadata. DocViewer rebuilt as a single-layer OverlayHost (no nested modal): pdf inline iframe, csv/json monospace, binary info card with a download CTA. Inbox result cards open artifacts through the docBridge wired in Workbench.
**Settings migration.** SettingsModal adopts @ui SettingRow/SettingsGroup with the save button pinned in the shell actions bar; legacy `.setting-row` styles removed.
## Verification
- `tsc --noEmit` clean; `vitest run` 20 passed (groupParts interleaving/merging/edge cases, humanSize, artifactIcon); production build ok.
- `make test` (Dev combo) green.
- Headless 12/12 on a mock server with an interleaved-parts probe message inserted directly into SQLite: DOM order is text → process-collapse → text → artifact-chip; chip/panel/viewer download links carry `download=1`; panel shows toolbar/filter/upload/meta.
Depends on: Agent-System-UI and Agent-System-Backend same-branch PRs (compound-selector shell, SettingRow ReactNode, download semantics).
Task card: feature/chat-order-artifact-files (Agent-System-Dev).
Why: AssistantMessage reordered a message's parts by the process flag,
so tool calls floated above the text that surrounded them instead of
appearing where they actually ran; live streams had the same defect via
a fixed template order and never showed artifacts mid-run. Generated
files (e.g. meeting-minutes docx) had no visible download path, the
artifacts panel was a bare list, DocViewer nested a modal inside the
overlay, and settings rows used a legacy grid with a floating save
button.
Evidence: messageparts.ts adds groupParts (order-preserving grouping of
consecutive process parts, unit-tested) plus humanSize/artifactIcon
helpers; Conversation renders blocks in original order and the artifact
chip becomes icon + open + download; LiveState.parts accumulates events
in arrival order including artifact_ref so live view matches the
persisted message; ArtifactsPanel gains search/kind filter/upload and
per-row preview/download/delete-confirm; DocViewer is a single-layer
OverlayHost with pdf iframe, csv/json monospace, and a binary info card
with a download CTA; SettingsModal migrates to @ui SettingRow with the
save button pinned in the shell actions bar; inbox cards receive the
docBridge so result cards can open artifacts. tsc clean, vitest 20
passed, production build succeeds.
Impact: message timelines read in true execution order during and after
runs; every artifact is previewable and downloadable from the message
chip, the workspace panel, and the viewer; settings render on the fixed
two-column shell.
Refs: task feature/chat-order-artifact-files (ui# c3e1f3b backend#
44b51fa).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What
Part order fidelity (render order = storage order). AssistantMessage used to split a message's parts by the
processflag and render all process parts above all content parts, so tool calls floated away from the text that surrounded them. Newmessageparts.ts#groupPartsgroups only consecutive process parts in place; content parts keep their original positions. Live streaming now maintainsLiveState.partsin event-arrival order (tool results pair with their calls;artifact.createdpushes an artifact_ref so the chip appears mid-run).Download channel. Artifact chips become icon + open + download;
api.artifactDownloadUrlrides the new?download=1semantics (backend PR). DocViewer and every artifacts-panel row expose download actions.Workspace file management. ArtifactsPanel: search, kind filter, upload, per-row preview/download/delete-with-confirm, size and mtime metadata. DocViewer rebuilt as a single-layer OverlayHost (no nested modal): pdf inline iframe, csv/json monospace, binary info card with a download CTA. Inbox result cards open artifacts through the docBridge wired in Workbench.
Settings migration. SettingsModal adopts @ui SettingRow/SettingsGroup with the save button pinned in the shell actions bar; legacy
.setting-rowstyles removed.Verification
tsc --noEmitclean;vitest run20 passed (groupParts interleaving/merging/edge cases, humanSize, artifactIcon); production build ok.make test(Dev combo) green.download=1; panel shows toolbar/filter/upload/meta.Depends on: Agent-System-UI and Agent-System-Backend same-branch PRs (compound-selector shell, SettingRow ReactNode, download semantics).
Task card: feature/chat-order-artifact-files (Agent-System-Dev).
b45d1abef0toedb5dbe73e