Conversation
- Consolidate MPI session and draft management into RemoteEdit - Decouple Proxy from RemoteEdit using signals/slots - Move RemoteEdit ownership to MainWindow - Implement draft file persistence in MMapper/Editor/ - Implement atomic auto-save with debounce (2s) and throttle (15s) - Implement draft recovery scan at startup - Integrate RemoteEdit tasks with TasksPanel and AsyncTask system - Add 'Show Editor' functionality for active and recovered tasks
- Centralize MPI session and draft management in RemoteEdit - MainWindow now owns the long-lived RemoteEdit instance - Decouple Proxy from RemoteEdit via direct GMCP subscription in RemoteEdit - Mark all active and recovered edits as AsyncTasks for unified management - Implement draft persistence in MMapper/Editor directory - Implement atomic auto-save with debounce (2s) and throttle (15s) - Add draft recovery scan at startup and immediately after disconnects - Integrate 'Show Editor' in TasksPanel to raise windows or open read-only drafts - Ensure drafts are purged only upon confirmed write/cancel from server - Handle clean and unclean disconnects to preserve draft state
- Establish MMapper/Editor/ scratch directory for draft persistence. - Centralize RemoteEdit management in MainWindow and decouple from Proxy via GMCP signals. - Implement atomic auto-save with 2000ms debounce and 15000ms throttle. - Add startup recovery sequence to scan for orphaned draft files. - Ensure thread safety in background tasks using weak_ptr for session access. - Preserve draft files across disconnections until explicit server confirmation. - Update TasksPanel with "Show Editor" functionality for active and recovered drafts. - Enhance UX for external editor tasks with status notifications.
- Add virtual isRunning() to RemoteEditSession base class. - Override isRunning() in RemoteEditExternalSession to check process state. - Use virtual isRunning() in RemoteEdit::raiseSession to avoid conditional compilation issues with external sessions. - Fix variable shadowing in slot_parseGmcpInput by renaming local error message variable. - Ensure consistent behavior across all platforms including Wasm and Snap.
- Establish MMapper/Editor/ scratch directory for draft persistence. - Centralize RemoteEdit management in MainWindow and decouple from Proxy via GMCP signals. - Implement atomic auto-save with 2000ms debounce and 15000ms throttle. - Add startup recovery sequence to scan for orphaned draft files. - Ensure thread safety in background tasks using weak_ptr for session access. - Preserve draft files across disconnections until explicit server confirmation. - Transition disconnected closed sessions to recovered state in the task list. - Simplified UX: Removed 'raise' feature and clipboard copy on disconnect.
MudTelnet intercepted MUME.Client.Edit/View/Write/CancelEdit GMCP messages and routed them through a legacy Proxy/MpiFilter shim whose connection to RemoteEdit was dropped in an earlier refactor, so edit requests never reached RemoteEdit::slot_remoteEdit. Let these messages flow through the normal GMCP relay instead, which RemoteEdit already listens to directly (the same pattern every other GMCP consumer uses), and remove the now fully dead MpiFilter/MpiFilterToMud plumbing. The "MMapper is opening an Editor/Viewer window" notice moves into RemoteEdit::addSession to preserve the existing user-facing output. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PcHMW6qCb9YobxuXvDSXuU
Cancelling an active edit task (from the Tasks panel, or implicitly on app quit via cancel_all()) called ProgressCounter::setCurrentTask() directly on the main thread after cancellation had already been requested on that task's handle. Every other use of this cooperative cancellation mechanism throws only from inside a background-worker lambda, caught at the corresponding std::future::get() -- these RemoteEdit call sites had neither, so the exception escaped to std::terminate(). Guard the four affected call sites (cancel(), sendToMume(), trySaveLocally(), onDisconnected()) with a try/catch that treats an already-cancelled task as a no-op. Also fix RemoteEditExternalSession never receiving its draft file path: RemoteEdit::addSession() called setDraftFileName() only after the session was already constructed, so RemoteEditProcess always saw an empty path and fell back to an unrelated temp file, breaking crash-recovery for external-editor sessions and leaking that temp file. Provision the draft file name before constructing the session and pass it into the constructor instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PcHMW6qCb9YobxuXvDSXuU
Cancelling a connected edit now sends the GMCP cancel and deletes its draft, so abandoned edits no longer resurrect as recovered drafts on every launch; disconnected edits and recovery windows keep their draft. A failed MUME.Client.Write notifies the user and removes the session instead of leaving a windowless zombie, and Proxy destruction marks sessions disconnected again. Recovery windows no longer offer Submit (their session id belongs to a dead MUME session). Draft filenames include a timestamp so reused MUME session ids cannot collide, and ack handlers skip recovery sessions. Menu actions capture the internal id rather than a shared_ptr to a QObject-parented session, letting m_sessions return to unique_ptr and removing a double-delete at shutdown. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S5DQbj1bGLZZLvDvbb9AsG
RemoteEditWidget becomes an embeddable page inside a new Remote Edits Panel dock rather than a free-floating window per session, so editor windows no longer pile up. Each page scopes its shortcuts to itself and claims them ahead of the shortcut map while focused, so Ctrl+S submits the edit in a tab but still saves the map elsewhere. Unsent drafts are no longer auto-opened at launch. They are listed in the panel (View / Discard), announced once on connect, and restored where they can actually be sent: a new edit whose title matches a pending draft offers to restore it, via an in-page banner for the internal editor or a prompt before an external editor launches. A dropped connection shows an in-page banner instead of a modal dialog. Draft persistence moves behind RemoteEditDraftStore: files under the editor directory natively, QSettings on WebAssembly so drafts survive a page reload without Emscripten filesystem glue. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S5DQbj1bGLZZLvDvbb9AsG
Reviewer's GuideThe PR moves remote-edit handling into a MainWindow-owned, GMCP-connected manager, adds cross-platform durable draft storage and autosave/recovery, and presents edits in a docked tab panel with terminal controls and page-scoped editor shortcuts. Sequence diagram for remote edit draft recoverysequenceDiagram
participant MUME
participant Proxy
participant MainWindow
participant RemoteEdit
participant DraftStore
participant Editor
MUME->>Proxy: MUME.Client.Edit
Proxy->>MainWindow: sig2_sentToUserGmcp
MainWindow->>RemoteEdit: slot_parseGmcpInput
RemoteEdit->>DraftStore: create(sessionId, title, body)
RemoteEdit->>Editor: create edit page
Editor->>RemoteEdit: sig_textModified(content)
RemoteEdit->>DraftStore: save(key, content)
MUME-->>Proxy: connection lost
Proxy->>MainWindow: sig2_disconnected
MainWindow->>RemoteEdit: onDisconnected
RemoteEdit->>Editor: showDisconnected
MUME->>Proxy: reconnect and MUME.Client.Edit
Proxy->>MainWindow: sig2_sentToUserGmcp
MainWindow->>RemoteEdit: slot_parseGmcpInput
RemoteEdit->>DraftStore: findPendingDraft(title)
RemoteEdit->>Editor: offerRecoveredDraft
Editor->>RemoteEdit: Restore
RemoteEdit->>DraftStore: read(key)
RemoteEdit->>Editor: replaceText(content)
Entity relationship diagram for durable remote edit draftserDiagram
REMOTE_EDIT_SESSION {
int session_id
string title
string draft_key
bool connected
}
REMOTE_EDIT_DRAFT {
string key
int session_id
string title
string content
datetime last_modified
}
REMOTE_EDIT_SESSION ||--o| REMOTE_EDIT_DRAFT : persists
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S5DQbj1bGLZZLvDvbb9AsG
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S5DQbj1bGLZZLvDvbb9AsG
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S5DQbj1bGLZZLvDvbb9AsG
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S5DQbj1bGLZZLvDvbb9AsG
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #555 +/- ##
==========================================
- Coverage 27.11% 26.87% -0.25%
==========================================
Files 557 561 +4
Lines 45812 46559 +747
Branches 4876 4979 +103
==========================================
+ Hits 12421 12511 +90
- Misses 33391 34048 +657 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
RemoteEditDraftStore(files natively,QSettingson WebAssembly).RemoteEditownership fromProxytoMainWindow, decoupled via GMCP signals; removeMpiFilter._editscommand to list/cancel/discard sessions from the terminal.Test plan
🤖 Generated with Claude Code
https://claude.ai/code/session_01S5DQbj1bGLZZLvDvbb9AsG
Summary by Sourcery
Preserve remote edit work across failures and restarts while consolidating editing and recovery into a tabbed panel.
New Features:
_editscommand for listing, inspecting, cancelling, discarding, and simulating remote edit sessions.Bug Fixes:
Enhancements:
Chores: