+ {attention.message}. Manage this tab’s version below. +
+ )} +Release channels are available in published builds.
if (!state) - return{error || 'Loading release information…'}
+ return ( ++ {readError || error || 'Loading release information…'} +
+ ) const active = state.active?.manifest const candidate = state.candidate const hasUpdate = candidate && candidate.releaseId !== active?.releaseId const selection = state.selection.kind === 'channel' ? state.selection.name : 'Pinned release' - const recoveryUrl = '/recovery.html' + location.search + location.hash return ( -+ This tab is running{' '} + {window.runmeRelease.active.manifest.webCommit.slice(0, 8)}. The + selected worker uses a different version; other tabs can update + independently. +
+ +Choose a channel to download its release in the background. Your - installed version stays active until you choose Upgrade all tabs. + selected worker version stays active until you activate the release. + Other tabs keep their current UI until you reload them individually.
- Upgrade {state.transition.phase}. Each tab must preserve its edits - before the upgrade can finish. + {state.transition.phase === 'prepare' + ? 'An older upgrade is pending. Cancel it to start a new upgrade.' + : 'Starting the selected storage worker. Other tabs stay open.'}
{state.transition.phase === 'prepare' && (- {error} + {readError || error}
)}@@ -271,68 +315,6 @@ export function ReleaseControls() { id="release-other-actions" className="mt-3 flex flex-col items-start gap-3" > - - - - {published.map((id) => ( - - ))} {api.activate && cached .filter((m) => m.releaseId !== active?.releaseId) @@ -351,16 +333,8 @@ export function ReleaseControls() { > Remove unused downloads - - Open recovery in another tab -
+ Choose the version Runme should stay on. You can follow a channel + again at any time. +
+{settingsError}
+ )} + + {step === 'select' && ( ++ Choose a published build. Each commit can have more than one + build. +
+ + {listed && !releases.length && ( ++ No published releases found. You can enter a full release ID + instead. +
+ )} ++ Use at least 7 characters of a published commit, or a full + release ID. +
+ + > + )} ++ {selected === installed + ? 'Runme will stop following channel updates. Your running app stays unchanged.' + : 'Pinning downloads this build. Your running app stays unchanged until you activate it.'} +
+ {step === 'review' && ( + + )} + {prepared && error && ( ++ The release was downloaded, but pinning did not finish. Retry or + use recovery below. +
+ )} + {((step === 'done' && selected !== installed) || + (prepared && error)) && + api?.recover && ( + <> ++ Activating saves and reloads this tab. Other tabs stay open. +
+ + > + )} ++ {error} +
+ )} + {(busy || message) && ( ++ {busy ? 'Working…' : message} +
+ )} + ++ If this tab cannot finish, use the independent recovery page. +
+ +
+ {diagnostics}
+
+ )}
+ Runme storage needs to reconnect
{state.message}
- Restart first backs up this tab’s editors in session storage. - Connected tabs reload only after all tabs preserve edits and pending - writes finish. Session copies do not survive closing a tab and are - not persistent autosave. + Storage restart keeps this page and its editors open. Pending editor + saves remain in this tab and retry after reconnecting. Keep this tab + open until saves finish, or download recovery copies before closing + it.
+ + ++ Force restart skips draining pending work. Editor saves can retry; + other operations may have an uncertain outcome. +
> )} + {state.phase !== 'healthy' && ( +
+ {diagnostics}
+
+ )}
+ + Diagnostics do not save or retry notebook operations. A reply + confirms the worker can process diagnostic messages, not that + storage writes are working. +
+ {state.phase === 'blocked' && ( ++ If restart cannot finish, download current editor copies in every + Runme tab first. Then close all Runme tabs for this site and + reopen Runme. If the worker remains stuck, restart the browser + after saving the downloads. Do not clear site data. +
+ )} +{captureMessage}
} {currentDrafts.map((draft, index) => (