Skip to content
Closed
Show file tree
Hide file tree
Changes from 52 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
4b2ae3d
Add failing surface hibernation lifecycle policy tests
austinywang Jun 10, 2026
46f2606
Hibernate idle background terminal surfaces behind an LRU cap
austinywang Jun 10, 2026
8838919
Merge remote-tracking branch 'origin/main' into issue-5731-surface-hi…
austinywang Jun 10, 2026
e617b49
Document why the agent-panel test helper marks surfaces busy
austinywang Jun 10, 2026
db742b8
Track test helper comment in file length budget
austinywang Jun 10, 2026
d30745d
Localize surface hibernation schema descriptions
austinywang Jun 10, 2026
9838586
Merge remote-tracking branch 'origin/main' into issue-5731-surface-hi…
austinywang Jun 10, 2026
8083a3b
Track AgentLaunchSanitizer length from main in budget
austinywang Jun 10, 2026
22b11e6
Harden surface hibernation busy gate, settings UI, and idle-tick cost
austinywang Jun 10, 2026
707e695
Persist hibernated scrollback on every autosave; drop input throttle
austinywang Jun 10, 2026
4b0ab2f
Merge remote-tracking branch 'origin/main' into issue-5731-surface-hi…
austinywang Jun 10, 2026
5d40d1e
Persist hibernated working directory in session snapshots
austinywang Jun 10, 2026
874b1c6
True up budget for hibernated-directory snapshot fix
austinywang Jun 10, 2026
80c604e
Protect visible panels, pending command lines, and main's ghostty poi…
austinywang Jun 10, 2026
e54ca51
Merge remote-tracking branch 'origin/main' into issue-5731-surface-hi…
austinywang Jun 10, 2026
caf6c41
Keep command line pending when text trails the last settling character
austinywang Jun 10, 2026
a825af8
Merge remote-tracking branch 'origin/main' into issue-5731-surface-hi…
austinywang Jun 10, 2026
f700d46
Clear pending shell input only on observed prompt transitions
austinywang Jun 10, 2026
1f28564
Record input synchronously and restore rendered hibernated panels
austinywang Jun 10, 2026
a9167eb
Include shell-integration command state in the hibernation busy gate
austinywang Jun 10, 2026
eb462de
Re-read hibernation settings after async work; route mobile input via…
austinywang Jun 10, 2026
68b1b7a
Merge remote-tracking branch 'origin/main' into issue-5731-surface-hi…
austinywang Jun 10, 2026
3e9a576
Convert policy suite to Swift Testing; harden re-enable and cwd staging
austinywang Jun 10, 2026
73f9106
Fix nested shell-state type and make round-trip test hermetic
austinywang Jun 10, 2026
96eab78
Merge remote-tracking branch 'origin/main' into issue-5731-surface-hi…
austinywang Jun 10, 2026
73eec3b
Honor the documented hidden-workspace window on first tail sample
austinywang Jun 10, 2026
b5db675
Replay restored scrollback in the fish integration
austinywang Jun 10, 2026
5afca77
Abort hibernation on failed scrollback capture; count prompt transiti…
austinywang Jun 10, 2026
683dc21
Merge branch 'main' of https://github.com/manaflow-ai/cmux into issue…
austinywang Jun 10, 2026
e1b2c61
Keep batched trailing text pending across the next prompt transition
austinywang Jun 10, 2026
bfb83e5
Stage hibernated working directories without touching the disk
austinywang Jun 10, 2026
7c095bb
Quarantine stale surfaces in busy probe; cover paste batches; reapply…
austinywang Jun 10, 2026
ead282b
Bound unmounted-idle hibernation batches and stale tail-sampling pres…
austinywang Jun 10, 2026
988908f
Survive one prompt transition per batched command before clearing pen…
austinywang Jun 10, 2026
189d5b0
Restore main-side content reverted by merge mishaps
austinywang Jun 10, 2026
c57ce56
True budget entries after restoring main-side content
austinywang Jun 10, 2026
f8b094a
Bound global-cap drains, seed pending before evaluation, gate restart…
austinywang Jun 10, 2026
85753cc
Wake hibernated terminals for mobile reads; only text-bearing input a…
austinywang Jun 10, 2026
b43f598
Discount prior selections before computing global-cap overflow
austinywang Jun 10, 2026
8299f48
Gate restart on current integration setting; arm pending for text nam…
austinywang Jun 10, 2026
5c1cb8b
Merge remote-tracking branch 'origin/main' into issue-5731-surface-hi…
austinywang Jun 10, 2026
fe24526
Key replay capability off the shell name; treat editing controls as n…
austinywang Jun 10, 2026
732b6a4
Write replay file at hibernate time; seed snapshot fallback; cover sp…
austinywang Jun 10, 2026
dfc052e
Scope tail-fingerprint sampling to the opt-in agent cap
austinywang Jun 10, 2026
dcc6946
Abort hibernation when the replay file cannot be written; clean up ab…
austinywang Jun 10, 2026
7c73096
Purge stale scrollback replay files once per process
austinywang Jun 10, 2026
0f3e304
Scope replay purge per bundle; keep last scrollback for surface-less …
austinywang Jun 10, 2026
05a1ce0
Document the new surface hibernation catalog keys
austinywang Jun 10, 2026
8a0d352
Harden shell-restart gates: non-shell foregrounds and disabled-integr…
austinywang Jun 10, 2026
9646e1f
Fail closed on missing foreground PID and pre-filter process syscalls
austinywang Jun 10, 2026
d464421
merge: resolve conflicts with main
austinywang Jun 10, 2026
dffa233
Keep the replay-file purge off the calling thread
austinywang Jun 10, 2026
ec21726
merge: resolve length-budget conflict with main
austinywang Jun 10, 2026
e47ba95
Make pending survivals additive and key replay support off installed …
austinywang Jun 10, 2026
65df0ac
Clear the scrollback fallback when hibernation captures an empty term…
austinywang Jun 11, 2026
722d3a1
Record key input only when it reaches the terminal; reconcile seeded …
austinywang Jun 11, 2026
44ad65b
Own the staged replay file through the whole restore window
austinywang Jun 11, 2026
b6523fe
Forward duplicate shell reports to hibernation; repair browser-CLI me…
austinywang Jun 11, 2026
b7cab15
Bound per-tick foreground verification to an LRU window
austinywang Jun 11, 2026
668b10d
merge: resolve length-budget conflict with main
austinywang Jun 11, 2026
889a4b9
Cache verified-busy foregrounds and stop arming pending on editing co…
austinywang Jun 11, 2026
21fc212
Requalify seeded shells on bare Enter; keep budget for evictable cand…
austinywang Jun 11, 2026
b9acc1a
merge: resolve length-budget conflict with main
austinywang Jun 11, 2026
40c8368
Write replay files off-actor; fix CRLF classification; restore socket…
austinywang Jun 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 17 additions & 14 deletions .github/swift-file-length-budget.tsv
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# cmux-owned Swift file length budget.
# Format: max_lines<TAB>relative path
# Reduce counts as files shrink. CI fails if tracked files exceed this budget.
32655 CLI/cmux.swift
22098 Sources/TerminalController.swift
19820 Sources/Workspace.swift
32697 CLI/cmux.swift
22159 Sources/TerminalController.swift
19958 Sources/Workspace.swift
19209 Sources/ContentView.swift
18044 Sources/AppDelegate.swift
16539 Sources/GhosttyTerminalView.swift
18047 Sources/AppDelegate.swift
16746 Sources/GhosttyTerminalView.swift
13589 Sources/Panels/BrowserPanel.swift
11916 cmuxTests/AppDelegateShortcutRoutingTests.swift
9939 Sources/TabManager.swift
9959 Sources/TabManager.swift
8494 cmuxTests/CLINotifyProcessIntegrationRegressionTests.swift
7737 Sources/Panels/BrowserPanelView.swift
7198 cmuxTests/WorkspaceUnitTests.swift
Expand Down Expand Up @@ -44,10 +44,10 @@
2290 Sources/FileExplorerView.swift
2260 Sources/TerminalWindowPortal.swift
2208 Sources/Mobile/MobileHostService.swift
2138 Sources/SessionPersistence.swift
2188 Sources/SessionPersistence.swift
2123 cmuxTests/ShortcutAndCommandPaletteTests.swift
2117 cmuxTests/CmuxConfigTests.swift
1996 Sources/KeyboardShortcutSettingsFileStore.swift
2039 Sources/KeyboardShortcutSettingsFileStore.swift
1949 Sources/Panels/BrowserWebAuthnSupport.swift
1860 cmuxTests/NotificationAndMenuBarTests.swift
1793 Sources/SessionIndexStore.swift
Expand Down Expand Up @@ -76,13 +76,14 @@
1144 Sources/VaultAgentProcessScanner.swift
1139 cmuxTests/PiVaultAgentPersistenceTests.swift
1107 Sources/AppDelegate+CmuxSSHURL.swift
1084 cmuxTests/AgentHibernationTests.swift
1096 Sources/GhosttyConfig.swift
1096 cmuxTests/AgentHibernationTests.swift
1068 cmuxTests/FileExplorerStoreTests.swift
1058 cmuxUITests/BonsplitTabDragUITests.swift
1096 Sources/GhosttyConfig.swift
1021 cmuxUITests/TerminalCmdClickUITests.swift
1006 cmuxTests/CmuxSSHURLRequestTests.swift
1000 cmuxTests/CmuxTopSnapshotScopeTests.swift
963 Sources/Panels/TerminalPanel.swift
949 Packages/CmuxMobileTerminal/Sources/CmuxMobileTerminal/TerminalInputTextView.swift
947 Sources/TerminalNotificationPolicy.swift
945 Sources/SessionIndexRegisteredAgents.swift
Expand All @@ -93,10 +94,10 @@
924 Sources/DockPanelView.swift
913 cmuxTests/WorkspaceGroupTests.swift
905 Sources/CmuxSSHURLRequest.swift
894 Sources/CommandPalette/CommandPaletteSettingsToggle.swift
884 cmuxTests/SurfaceHibernationPolicyTests.swift
878 Sources/WorkspaceContentView.swift
868 Sources/Panels/BrowserScreenshotSnapshotter.swift
866 Sources/CommandPalette/CommandPaletteSettingsToggle.swift
863 Sources/Panels/TerminalPanel.swift
856 Packages/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/AppSection.swift
846 cmuxTests/AgentSessionAutoResumeSettingsTests.swift
845 cmuxTests/SSHStartupSignalLifecycleTests.swift
Expand All @@ -119,6 +120,7 @@
705 cmuxUITests/BrowserOmnibarSuggestionsUITests.swift
701 CLI/CMUXCLI+AgentHookDefinitions.swift
698 cmuxTests/RestorableAgentHookProviderResumeTests.swift
697 Sources/App/AgentHibernationController.swift
697 cmuxTests/TerminalNotificationClearAllTests.swift
696 cmuxTests/UpdatePillReleaseVisibilityTests.swift
693 Sources/Panels/BrowserPopupWindowController.swift
Expand All @@ -131,8 +133,8 @@
668 cmuxTests/FeedCoordinatorTests.swift
668 cmuxTests/KeyboardShortcutContextTests.swift
654 Packages/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/KeyboardShortcutsSection.swift
653 Sources/CmuxTopSnapshot.swift
650 Sources/Panels/MarkdownRemoteImageLoader.swift
649 Sources/CmuxTopSnapshot.swift
640 cmuxTests/CommandPaletteNucleoFFITests.swift
638 Packages/CmuxSwiftRender/Sources/CmuxSwiftRender/ExpressionEvaluator.swift
630 Packages/CmuxSettings/Sources/CmuxSettings/Values/ShortcutWhenClause.swift
Expand All @@ -145,8 +147,8 @@
599 Packages/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizerPrimaryPolicies.swift
596 cmuxTests/CmuxEventBusTests.swift
594 Sources/SessionIndexModels.swift
594 Sources/SettingsNavigation.swift
594 cmuxTests/PortalTabDragRoutingTests.swift
589 Sources/SettingsNavigation.swift
588 cmuxTests/CommandPaletteShortcutCustomizationTests.swift
586 Sources/JSONCParser.swift
585 Sources/Cloud/VMClient.swift
Expand All @@ -157,6 +159,7 @@
574 Sources/Feed/FeedTextEditorDebugWindowController.swift
568 Packages/CMUXMobileCore/Sources/CMUXMobileCore/MobileTerminalRenderGrid.swift
566 Packages/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizer.swift
562 Sources/App/WorkspaceRuntimeSettings.swift
562 cmuxTests/AgentExecutableResolverTests.swift
560 cmuxTests/GhosttyConfigPathResolverTests.swift
558 Packages/CmuxGit/Sources/CmuxGit/Parsing/GitMetadataService+Config.swift
Expand Down
17 changes: 17 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,23 @@ jobs:
-only-testing:cmuxTests/AppearanceSettingsTests/testSplitGhosttyThemeUsesSystemDarkWhenAppAppearanceIsStaleLight \
test

# The full unit-test pass below tolerates app-host crashes by classifying
# the surviving summary lines, so suites that sort after an early crash
# can be skipped without failing the job. Surface hibernation policy
# tests gate memory reclamation (issue 5731) and must always execute.
- name: Run surface hibernation policy regression
run: |
set -euo pipefail
SOURCE_PACKAGES_DIR="$PWD/.ci-source-packages"
xcodebuild -project cmux.xcodeproj -scheme cmux-unit -configuration Debug \
-derivedDataPath "$CMUX_DERIVED_DATA_PATH" \
-clonedSourcePackagesDirPath "$SOURCE_PACKAGES_DIR" \
-disableAutomaticPackageResolution \
-destination "platform=macOS" \
CMUX_SKIP_ZIG_BUILD=1 \
-only-testing:cmuxTests/SurfaceHibernationPolicyTests \
test

- name: Run unit tests
run: |
set -euo pipefail
Expand Down
42 changes: 42 additions & 0 deletions CLI/cmux.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3347,6 +3347,9 @@ struct CMUXCLI {
case "agent-hibernation":
try runAgentHibernation(commandArgs: commandArgs, client: client, jsonOutput: jsonOutput)

case "surface-hibernation":
try runSurfaceHibernation(commandArgs: commandArgs, client: client, jsonOutput: jsonOutput)

case "auth", "login", "logout":
let authArgs = command == "auth" ? commandArgs : [command] + commandArgs
let sub = authArgs.first?.lowercased() ?? "status"
Expand Down Expand Up @@ -5012,6 +5015,7 @@ struct CMUXCLI {
"__codex-teams-watch",
"__tmux-compat",
"agent-hibernation",
"surface-hibernation",
"auth",
"bind-key",
"break-pane",
Expand Down Expand Up @@ -13060,6 +13064,13 @@ struct CMUXCLI {
Enable or disable Agent Hibernation.
Configure idle and live-terminal limits from Settings or cmux settings JSON.
"""
case "surface-hibernation":
return """
Usage: cmux surface-hibernation <on|off> [--json]

Enable or disable Surface Hibernation for idle background terminals.
Configure idle and live-surface limits from Settings or cmux settings JSON.
"""
case "restore-session":
return """
Usage: cmux restore-session
Expand Down Expand Up @@ -22370,6 +22381,36 @@ struct CMUXCLI {
}
}

private func runSurfaceHibernation(
commandArgs: [String],
client: SocketClient,
jsonOutput: Bool
) throws {
guard let subcommand = commandArgs.first?.lowercased() else {
throw CLIError(message: "Usage: cmux surface-hibernation <on|off> [--json]")
}
let response: String
switch subcommand {
case "on", "enable":
response = try sendV1Command("surface_hibernation on", client: client)
case "off", "disable":
response = try sendV1Command("surface_hibernation off", client: client)
default:
throw CLIError(message: "Usage: cmux surface-hibernation <on|off> [--json]")
}

if jsonOutput {
let ok = response == "OK"
var fallback: [String: Any] = ["ok": ok]
if !ok {
fallback["message"] = response
}
print(jsonString(fallback))
} else {
print(response)
}
}

private func shouldApplyClaudeHookVisibleMutation(
sessionStore: ClaudeHookSessionStore,
parsedInput: ClaudeHookParsedInput,
Expand Down Expand Up @@ -32429,6 +32470,7 @@ export default function cmuxPiSessionExtension(pi: ExtensionAPI) {
shortcuts
disable-browser | enable-browser | browser-status
agent-hibernation <on|off>
surface-hibernation <on|off>
restore-session
open <path-or-url>... [--workspace <id|ref|index>] [--surface <id|ref|index>] [--pane <id|ref|index>] [--window <id|ref|index>] [--focus <true|false>] [--no-focus]
diff [patch-file|-] [--source <unstaged|staged|branch|last-turn>] [--unstaged|--staged|--branch|--last-turn] [--workspace <id|ref|index>] [--surface <id|ref|index>] [--window <id|ref|index>] [--cwd <path>] [--base <ref>] [--focus <true|false>] [--no-focus] [--title <text>] [--layout <split|unified>] [--font-size <points>]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,39 @@ public struct TerminalCatalogSection: SettingCatalogSection {
userDefaultsKey: "terminal.agentHibernation.maxLiveTerminals"
)

/// Whether Surface Hibernation reclaims idle plain-shell terminals in
/// hidden workspaces (scrollback and working directory are restored on
/// the next visit).
public let surfaceHibernationEnabled = DefaultsKey<Bool>(
id: "terminal.surfaceHibernation.enabled",
defaultValue: true,
userDefaultsKey: "terminal.surfaceHibernation.enabled"
)

/// Minimum quiet seconds before the live-surface cap may reclaim a
/// background shell terminal.
public let surfaceHibernationIdleSeconds = DefaultsKey<Double>(
id: "terminal.surfaceHibernation.idleSeconds",
defaultValue: 300,
userDefaultsKey: "terminal.surfaceHibernation.idleSeconds"
)

/// Seconds a workspace must stay hidden — with its terminal quiet —
/// before its idle shell surfaces hibernate even under the cap.
public let surfaceHibernationUnmountedIdleSeconds = DefaultsKey<Double>(
id: "terminal.surfaceHibernation.unmountedIdleSeconds",
defaultValue: 1800,
userDefaultsKey: "terminal.surfaceHibernation.unmountedIdleSeconds"
)

/// Maximum simultaneously live terminal surfaces before the oldest
/// eligible background terminals hibernate.
public let surfaceHibernationMaxLiveSurfaces = DefaultsKey<Int>(
id: "terminal.surfaceHibernation.maxLiveSurfaces",
defaultValue: 12,
userDefaultsKey: "terminal.surfaceHibernation.maxLiveSurfaces"
)

public let showTextBoxOnNewTerminals = DefaultsKey<Bool>(
id: "terminal.showTextBoxOnNewTerminals",
defaultValue: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ public struct TerminalSection: View {
@State private var hibernation: DefaultsValueModel<Bool>
@State private var idleSeconds: DefaultsValueModel<Double>
@State private var maxLive: DefaultsValueModel<Int>
@State private var surfaceHibernation: DefaultsValueModel<Bool>
@State private var surfaceIdleSeconds: DefaultsValueModel<Double>
@State private var surfaceUnmountedIdleSeconds: DefaultsValueModel<Double>
@State private var surfaceMaxLive: DefaultsValueModel<Int>

public init(
defaultsStore: UserDefaultsSettingsStore,
Expand All @@ -37,6 +41,10 @@ public struct TerminalSection: View {
_hibernation = State(initialValue: DefaultsValueModel(store: defaultsStore, key: catalog.terminal.agentHibernationEnabled))
_idleSeconds = State(initialValue: DefaultsValueModel(store: defaultsStore, key: catalog.terminal.agentHibernationIdleSeconds))
_maxLive = State(initialValue: DefaultsValueModel(store: defaultsStore, key: catalog.terminal.agentHibernationMaxLiveTerminals))
_surfaceHibernation = State(initialValue: DefaultsValueModel(store: defaultsStore, key: catalog.terminal.surfaceHibernationEnabled))
_surfaceIdleSeconds = State(initialValue: DefaultsValueModel(store: defaultsStore, key: catalog.terminal.surfaceHibernationIdleSeconds))
_surfaceUnmountedIdleSeconds = State(initialValue: DefaultsValueModel(store: defaultsStore, key: catalog.terminal.surfaceHibernationUnmountedIdleSeconds))
_surfaceMaxLive = State(initialValue: DefaultsValueModel(store: defaultsStore, key: catalog.terminal.surfaceHibernationMaxLiveSurfaces))
}

public var body: some View {
Expand Down Expand Up @@ -210,6 +218,64 @@ public struct TerminalSection: View {
)
.accessibilityIdentifier("SettingsTerminalAgentHibernationMaxLiveStepper")
}
SettingsCardDivider()
SettingsCardRow(
configurationReview: .json("terminal.surfaceHibernation.enabled"),
String(localized: "settings.terminal.surfaceHibernation", defaultValue: "Surface Hibernation"),
subtitle: surfaceHibernation.current
? String(localized: "settings.terminal.surfaceHibernation.subtitleOn", defaultValue: "Idle shell terminals in hidden workspaces release their renderer and restart with scrollback and directory restored on the next visit.")
: String(localized: "settings.terminal.surfaceHibernation.subtitleOff", defaultValue: "Terminal surfaces stay live until you close them or quit cmux.")
) {
Toggle("", isOn: Binding(get: { surfaceHibernation.current }, set: { surfaceHibernation.set($0) }))
.labelsHidden()
.controlSize(.small)
.accessibilityIdentifier("SettingsTerminalSurfaceHibernationToggle")
}
SettingsCardDivider()
SettingsCardRow(
configurationReview: .json("terminal.surfaceHibernation.idleSeconds"),
String(localized: "settings.terminal.surfaceHibernation.idleSeconds", defaultValue: "Cap Reclaim After Idle Seconds"),
subtitle: String(localized: "settings.terminal.surfaceHibernation.idleSeconds.subtitle", defaultValue: "A background shell terminal must be quiet for this long before the live-surface cap may reclaim it."),
controlWidth: 140
) {
Stepper(
"\(Int(surfaceIdleSeconds.current))",
value: Binding(get: { surfaceIdleSeconds.current }, set: { surfaceIdleSeconds.set($0) }),
in: 30...604_800,
step: 60
)
.accessibilityIdentifier("SettingsTerminalSurfaceHibernationIdleSecondsStepper")
}
SettingsCardDivider()
SettingsCardRow(
configurationReview: .json("terminal.surfaceHibernation.unmountedIdleSeconds"),
String(localized: "settings.terminal.surfaceHibernation.unmountedIdleSeconds", defaultValue: "Hibernate Hidden Workspaces After Seconds"),
subtitle: String(localized: "settings.terminal.surfaceHibernation.unmountedIdleSeconds.subtitle", defaultValue: "Shell terminals in workspaces hidden and quiet for this long hibernate even under the live-surface cap."),
controlWidth: 140
) {
Stepper(
"\(Int(surfaceUnmountedIdleSeconds.current))",
value: Binding(get: { surfaceUnmountedIdleSeconds.current }, set: { surfaceUnmountedIdleSeconds.set($0) }),
in: 60...2_592_000,
step: 300
)
.accessibilityIdentifier("SettingsTerminalSurfaceHibernationUnmountedIdleSecondsStepper")
}
SettingsCardDivider()
SettingsCardRow(
configurationReview: .json("terminal.surfaceHibernation.maxLiveSurfaces"),
String(localized: "settings.terminal.surfaceHibernation.maxLiveSurfaces", defaultValue: "Max Live Terminal Surfaces"),
subtitle: String(localized: "settings.terminal.surfaceHibernation.maxLiveSurfaces.subtitle", defaultValue: "Every live surface counts toward the cap; only idle, non-busy, hidden ones are reclaimed, oldest first."),
controlWidth: 120
) {
Stepper(
"\(surfaceMaxLive.current)",
value: Binding(get: { surfaceMaxLive.current }, set: { surfaceMaxLive.set($0) }),
in: 1...256,
step: 1
)
.accessibilityIdentifier("SettingsTerminalSurfaceHibernationMaxLiveStepper")
}
}
}

Expand Down
Loading