Edit workspace files directly on web (#2270)

* feat(files): edit workspace files on web

Keep source buffers synchronized with host file changes and require an explicit overwrite or reload when revisions diverge.

* feat(panels): surface and protect modified tabs

Expose tooltip and modification state through the generic panel boundary so tabs can show stable metadata and guard every close route consistently.

* fix(tests): use portable fake timeout handle

* fix(files): harden editor conflict handling

Preserve modified panel state across tab eviction, use precise revisions for optimistic writes, coalesce concurrent file watchers, and localize the editor interface.

* fix(files): close editor concurrency gaps

Coalesce clean reloads, preserve subscriber identities and file permissions, suspend pending saves during close confirmation, and carry precise revisions through file reads.

* test(files): expect read revision metadata
This commit is contained in:
Mohamed Boudra
2026-07-21 04:41:19 +08:00
committed by GitHub
parent 9292f58896
commit 4bda2dfea9
69 changed files with 3678 additions and 241 deletions
+32
View File
@@ -465,6 +465,7 @@ export const en = {
},
tabs: {
loading: "Loading...",
modified: "Unsaved changes",
loadingAgentTitle: "Loading agent title",
emptyPane: "No tabs in this pane.",
fallback: {
@@ -534,6 +535,12 @@ export const en = {
close: "Close",
cancel: "Cancel",
archive: "Archive",
unsavedTitle: "Unsaved changes",
unsavedMessage:
"This tab has changes that have not been saved. Closing it will discard the draft.",
closeWithoutSaving: "Close without saving",
closePaneTitle: "Close pane?",
bulkUnsaved: "{{count}} tab(s) have unsaved changes. Closing will discard those drafts.",
closeTerminalTitle: "Close terminal?",
closeTerminalMessage: "Any running process in this terminal will be stopped immediately.",
archiveRunningAgentTitle: "Archive running agent?",
@@ -1457,6 +1464,25 @@ export const en = {
binaryPreviewUnavailable: "Binary preview unavailable",
failedToLoad: "Failed to load file",
failedToLoadPreview: "Failed to load file preview",
editor: {
fileSize: "File size {{size}}",
lines: "{{count}} lines",
editorStatus: "Editor status {{status}}",
unsavedChanges: "Unsaved changes",
saving: "Saving...",
saveFailed: "Save failed",
changedOnDisk: "Changed on disk",
vimMode: "Vim mode {{mode}}",
cursor: "Line {{line}}, column {{column}}",
preview: "Preview",
source: "Source",
unavailableTitle: "File unavailable on disk",
conflictDescription: "The local buffer was preserved. Choose which version to keep.",
overwrite: "Overwrite",
reload: "Reload",
reloadTitle: "Reload from disk?",
reloadMessage: "Your local changes will be lost.",
},
},
diff: {
changesLabel: "Changes",
@@ -1552,12 +1578,18 @@ export const en = {
sections: {
general: "General",
appearance: "Appearance",
editor: "Editor",
shortcuts: "Shortcuts",
integrations: "Integrations",
permissions: "Permissions",
diagnostics: "Diagnostics",
about: "About",
},
editor: {
title: "Editor",
vimKeybindings: "Vim keybindings",
vimHint: "Applies to source files on web and desktop.",
},
hostSections: {
connections: "Connections",
agents: "Agents",