diff --git a/README.md b/README.md index 3eec9f46cc..acab87c753 100644 --- a/README.md +++ b/README.md @@ -2332,6 +2332,15 @@ After each run, DeerFlow records a workspace change summary for the run-owned `w Files presented through `present_files` remain part of the thread's artifact state, and the Web UI restores the artifact panel and selected document after a page refresh. When a completed response successfully presents between 2 and 50 files, its final file card also offers one ZIP download. Archive membership comes from the terminal delivery receipt rather than browser-supplied paths, and the ZIP contains the current file versions, which may have changed since the response. The currently selected formal artifact is refreshed once when the run finishes so edits become visible without a manual reload. Existing UTF-8 text artifacts under `/mnt/user-data/outputs` can also be edited and explicitly saved from the panel on Unix and Windows while the thread is idle; saves use content revisions to prevent overwriting agent changes. Source previews also recognize extensionless `Dockerfile` and `Makefile` artifacts by their file names. Unknown file types, including names such as `constructor` and `__proto__`, retain the download fallback. +Unsaved artifact edits survive switching chats, workspace pages, or visiting the +home page and returning in the same browser tab. Drafts stay in memory for the +current account until saved or discarded; changing accounts or signing out clears them. +Public showcase visits and unavailable Gateway auth probes retain hidden drafts +until authentication is known. Recovering as another account or confirming logout +clears the retained content. +Refreshing or closing the tab warns while any chat has unsaved edits. Draft file +contents are not stored in browser storage and do not survive a reload. + Artifact content revisions refresh when an output file is atomically replaced, even if its size and modification time are preserved. Refreshing the preview then provides the new revision for saving; an older preview still requires a reload. diff --git a/frontend/src/AGENTS.md b/frontend/src/AGENTS.md index 9f8108c230..8e770d97bd 100644 --- a/frontend/src/AGENTS.md +++ b/frontend/src/AGENTS.md @@ -28,7 +28,7 @@ Language-map membership checks only own properties; inherited names such as File-tool artifact auto-open work must run in an effect with timer cleanup; never schedule timers while rendering streamed `write_file` or `str_replace` updates. `ThreadState.artifacts` remains the authoritative artifact list. The artifacts provider persists only thread-scoped panel UI state (`open`, selected path, and a refresh bootstrap cache) in session storage; an initial empty stream value must not overwrite that restored state before history finishes loading. Formal artifact content is refreshed once when the run finishes; transient `write-file:` previews remain message-driven. - The detail view exposes explicit editing only for an already-opened formal UTF-8 text artifact under `/mnt/user-data/outputs`. Drafts stay in provider memory until Save so switching right-side panels cannot discard them, render in Markdown/HTML preview, and are protected from remote refreshes by the loaded SHA-256 revision. Saving is disabled during an active run; a changed revision preserves the draft and surfaces a conflict instead of overwriting agent output. + UTF-8 outputs under `/mnt/user-data/outputs` are editable while idle. Root drafts survive SPA/home/showcase routes and unknown auth; confirmed account change/logout clears them. Owner/generation fences reject stale updates. Auth binds through a stable setter context, outside the typing state subscription. Drafts preview in Markdown/HTML and warn on unload off-route. SHA-256 conflicts preserve edits. Layout, draft-context and editor DOM tests cover this. Regular artifact text loads request at most the first 1 MiB through an HTTP byte range. A truncated preview must stay lightweight and expose an explicit full-file action; do not mount CodeMirror for that artifact until the user diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index ac8adf33b4..4222e62572 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -3,6 +3,7 @@ import "@/styles/globals.css"; import { type Metadata } from "next"; import { ThemeProvider } from "@/components/theme-provider"; +import { ArtifactDraftsProvider } from "@/core/artifacts/draft-context"; import { DEFAULT_LOCALE } from "@/core/i18n/locale"; export const metadata: Metadata = { @@ -21,7 +22,7 @@ export default function RootLayout({ >