Skip to content

Settings: one page, one app list, and a hotspot picker that also takes a typed name - #104

Open
nsd97 wants to merge 10 commits into
krishhgg:mainfrom
nsd97:settings-hig
Open

nsd97 wants to merge 10 commits into
krishhgg:mainfrom
nsd97:settings-hig

Conversation

@nsd97

@nsd97 nsd97 commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Why

The Settings window was one 520 pt form with about 2,500 pt of content. It showed bundle IDs, SIGSTOP and NSAppSleepDisabled, and a footer that listed about 20 kinds of protected apps. Two "Add running app…" menus sat in different sections and meant opposite things. On a real Mac, Comet went into the freeze list instead of the agent list and was frozen twice during testing. The hotspot name had to be typed, and a straight apostrophe never matches an iPhone's hotspot (#87).

What

  • One page, grouped by what happens: When the lid closes, Apps, Battery, If Wi-Fi drops, General. It fits without scrolling (490 × 897 pt on macOS 27), and its minimize and maximize buttons are dimmed, as the HIG asks of a settings window. On a shorter screen, such as a 13-inch MacBook Air with the Dock at the bottom, it opens no taller than the screen and the form scrolls. It keeps one width, so a long notice wraps.
  • Edit Apps, a sheet with one list.
    • It shows the listed apps this Mac has, each with its icon and one rule: Keep running or Freeze when lid closes.
    • A rule moves the app between agentList and freezeList (Config.setRule), so no app sits on a list the user didn't choose.
    • One Add App menu offers the running apps and Choose…. A new app starts as Keep running. Choose… registers the app with Launch Services first, so an app never opened, such as one just unzipped, still gets its row.
    • Apple apps and Docker Desktop can't be set to freeze, matching FreezePlanner.isDenied.
    • "All other apps" is freezeAllApps, with the "Would freeze now" line. The Docker and App Nap switches moved here, each with a one-line explanation.
  • If Wi-Fi drops, a sheet.
  • Cut (every config.json key stays):
    • The presets editor. Nothing outside Settings reads presets, so Default session length is now a menu over them.
    • The read-only Maximum session and config path rows, the footers, and the bundle IDs.
    • The battery steppers, now menus where 0 reads Never.
  • Code:
    • SettingsView.swift went from 628 lines to 233, with AppsSheet, HotspotSheet, RunningApps and a 25-line SessionManager+Settings for the shared bindings.
    • The keychain reads behind the password field moved unchanged from the view to HotspotPasswordField.
    • SettingsWindow hosts SettingsView directly, without AnyView. It is resizable, with zoom dimmed, only so AppKit can fit it to a short screen, and it refits to the form each time it opens.
    • chipLabel lost its last caller and is gone.
  • Copy:
    • Labels say what happens: "Mute audio", "Turn on Low Power Mode", "Protect against overheating", "Open at login".
    • The one-time "Lid-close settings changed" notice names the new places.
    • README, docs/lid-close.md, docs/extras.md, docs/spec.md and docs/releasing.md follow.

Tests

  • New:
    • SettingsTests: hotspot suggestions with either apostrophe, each network once, case and accents ignored; app summaries; Choose… reading a bundle ID, and listing an app Launch Services hadn't seen; session length labels; the window fitting a screen shorter than the form and keeping its width with the longest notice.
    • ConfigTests: app rules (one list per app, no change for the same rule, an app on both lists) and floor choices.
  • Updated:
    • LidCloseCopyTests: the microphone note is now the mute toggle's subtitle.
    • The notice copy in ConfigTests and ConfigLoadTests.
    • SettingsPasswordNoticeTests and FailoverMachineTests call the moved methods.
  • Checks on this branch:
    • swift test: 1,245 tests, none skipped, and no failures on the third commit. Each earlier full run had one timing failure outside Settings, a different test each time: UIStatusTests.testCollapseReadsTheSessionWhenTheSlotsLeaveNotWhenThePillsStartFolding and RecoveryScriptTests.testUninstallRunsRecoveryUnderItsOwnLockAndKeepsLockInode on the first commit, RecoveryScriptTests.testUninstallUsesTheCheckoutBackstopWhenTheAppDeclaresTheVersion on the second. Each passed when run again, and RecoveryScriptTests passed as a whole (232 tests).
    • swift build -c release -Xswiftc -warnings-as-errors
    • ShellCheck, and /bin/bash -n plus the bash 4 grep
    • scripts/check-lid-simulation-gate.sh
  • Real Mac: recorded in docs/release-validation.md under October 12, 2026.
    • Changing a rule in Edit Apps moved the bundle ID between the two lists in config.json.
    • The name field offered networks this Mac has joined, and a typed curly apostrophe was saved byte for byte.
    • A scratch copy with 14 extra rows opened 1084 pt tall, the screen's whole visible height, and its form scrolled to the last row. With the two-change notice, the window stayed 490 pt wide and the notice wrapped.
    • An app bundle that had never been opened was not found by its bundle ID until Choose…'s registration, and was found after it, under its own name.
    • A new "Settings" item is in the release checklist.

Decisions

  • One page, not toolbar panes. The HIG allows a single-pane settings window ("If your settings window doesn’t have multiple panes, use the title App Name Settings"). With these cuts, every setting fits on one screen, with nothing to click through to find the setting you want. Panes were designed too, as the alternative option below, and are a small change from here if you prefer them.
  • One app list with a rule per app, instead of two lists, so the wrong-list mistake above can't happen.
  • Hotspot suggestions use SwiftUI's textInputSuggestions rather than an AppKit combo box.
  • Resizable, but only in height. AppKit fits a window to a short screen only when it is resizable. The form fixes the width and zoom stays dimmed, so on a normal screen the window still opens at the form's size.

Not covered

Screenshots

From a release build on macOS 27.0 with a throwaway config.

Before, upstream main at three scroll positions:

Before: the old Settings window at three scroll positions

After, light and dark:

After: the one-page Settings window in light and dark

Edit Apps and If Wi-Fi drops:

After: the Edit Apps sheet and the iPhone hotspot sheet

The hotspot picker. Typing Avery's with a straight apostrophe offers both of Avery’s devices. This is the same build, except that the joined-networks list returns sample names so no real network shows:

The hotspot name field with Avery's typed, suggesting Avery’s iPhone and Avery’s iPad

Alternative option: toolbar panes (mockups, not built). Every setting stays, split into General, Lid Closed, Agent Apps, Battery and Network panes. I built and recommend the one page above instead: the settings people change most are all on one screen, the app lists open in a sheet only when needed, and there's no last-selected pane to restore. If you'd rather have panes, the sections above map one to one:

Alternative option: the Lid Closed, Agent Apps and Network panes

Sources

🤖 Generated with Claude Code

RetriggerView in GreptileConfidence Score: 5/5 Tier: plus

The PR appears safe to merge; no new actionable issues were found.

Summary

Settings becomes one page, with separate sheets for app rules and hotspot setup.

  • Settings now puts related controls together on one page.
  • Each listed app gets one rule for when the lid closes.
  • The hotspot sheet suggests remembered names and accepts typed names.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  Settings[Settings page] --> Apps[Edit Apps sheet]
  Settings --> Hotspot[Hotspot sheet]
  Settings --> Config[Shared Config]
  Apps --> Rules[Config.setRule]
  Rules --> Config
  Hotspot --> Config
  Hotspot --> Keychain[HotspotSecretStore]
  Config --> Saved[config.json]
  Config --> Session[Session services]
Loading

Reviews (9) · Last reviewed commit: "Merge origin/main into settings-hig" · Reviewed by Greptile

Comment thread Sources/Insomnia/UI/SettingsView.swift Resolved
Comment thread Sources/Insomnia/UI/AppsSheet.swift Resolved
nsd97 added a commit to nsd97/Insomnia that referenced this pull request Oct 12, 2026
Greptile's review of krishhgg#104 found two ways to lose a setting.

The window was as tall as its form, 896 pt, and not resizable. AppKit
fits a window taller than the screen to it only when the window is
resizable (constrainFrameRect(_:to:)), so on a 13-inch MacBook Air with
the Dock at the bottom, Open at login was below the screen. The window is
now resizable with zoom still dimmed, and the form has one width and no
fixed height, so it scrolls on a short screen. The window refits to the
form each time it opens. The fixed width also stops the one-time
lid-close notice from widening the window to 738 pt.

Choose… saved the app's bundle ID, but an app Launch Services hasn't
seen, such as one just unzipped, has no URL for that ID, so its row was
left out and could not be changed or removed. Choose… now registers the
app (LSRegisterURL) before reading its ID.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Comment thread Sources/Insomnia/UI/RunningApps.swift Resolved
nsd97 and others added 3 commits October 13, 2026 08:53
…s a typed name

The Settings window was one long scrolling form with bundle IDs, SIGSTOP
and NSAppSleepDisabled on screen, and two "Add running app" menus that
meant opposite things; during testing, Comet landed on the freeze list
that way. Settings is now one page that fits without scrolling. Edit Apps
keeps one list with a rule per app, so each app sits on exactly one of
agentList and freezeList. The hotspot name suggests networks this Mac has
joined and still takes a typed name, matching either apostrophe (krishhgg#87).
Every config.json key stays.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Greptile's review of krishhgg#104 found two ways to lose a setting.

The window was as tall as its form, 896 pt, and not resizable. AppKit
fits a window taller than the screen to it only when the window is
resizable (constrainFrameRect(_:to:)), so on a 13-inch MacBook Air with
the Dock at the bottom, Open at login was below the screen. The window is
now resizable with zoom still dimmed, and the form has one width and no
fixed height, so it scrolls on a short screen. The window refits to the
form each time it opens. The fixed width also stops the one-time
lid-close notice from widening the window to 738 pt.

Choose… saved the app's bundle ID, but an app Launch Services hasn't
seen, such as one just unzipped, has no URL for that ID, so its row was
left out and could not be changed or removed. Choose… now registers the
app (LSRegisterURL) before reading its ID.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Greptile's review of 44cb790 found no test for the Launch Services
registration Choose… now does: the existing test reads Calculator's
bundle ID, which passed before the fix too.

testChoosingAnAppLaunchServicesHasNotSeenListsIt builds a stand-in app
with a new bundle ID, checks it isn't found by that ID, runs
bundleID(ofAppAt:) and checks isInstalled now finds it. Without the
LSRegisterURL call the last check fails.

Launch Services ignores apps in temporary folders and bundles with no
executable, so the stand-in is a copy of /usr/bin/true next to the test
bundle. The test unregisters it with lsregister -u and deletes it.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@krishhgg

Copy link
Copy Markdown
Owner

@greptileai please review this PR.

Comment thread Sources/Insomnia/UI/SettingsView.swift Resolved
@krishhgg
krishhgg marked this pull request as draft October 18, 2026 00:32
@krishhgg
krishhgg marked this pull request as ready for review October 18, 2026 00:32
@krishhgg

Copy link
Copy Markdown
Owner

End-to-end test in a VM on macOS 27.0.1

The one-page Settings, Edit Apps and the hotspot sheet all open, show the current config and close with Done. One thing to look at: an app on both lists in an older config.json shows under both summary lines on the page, while Edit Apps shows it once, as Keep running. That is the case in Greptile's open comment.

Setup

A Tart VM on the maintainer's Mac mini, macOS 27.0.1 (26A434) with Xcode 27.0. Each version was built from source and installed with scripts/install.sh, then driven by a script inside the VM using Accessibility and posted mouse events.

This PR's head (3a13fa0). A stand-in Slack.app (bundle id com.tinyspeck.slackmacgap, registered with Launch Services) gave the VM a third-party app that the default lists name. The script (t104c.sh) opened Settings, clicked Edit Apps… and Set Up… and read the sheets. It closed each sheet with Return, which presses Done. It then put Slack on both agentList and freezeList in config.json, as an older config could have it, added 30 tmux targets, relaunched the app and looked again.

Results

Result
Settings page When the lid closes (display, mute audio, Low Power Mode), Apps (Keep running: Terminal; Freeze when lid closes: Slack; Edit Apps…), Battery (40%, 10%, overheating), If Wi-Fi drops (Join an iPhone hotspot, Not set up, Set Up…), then Default session length and Open at login
Edit Apps… one list: Slack "Freeze when lid closes", Terminal "Keep running"; Add App; All other apps "Keep running"; Docker and App Nap switches; Return closed it
Set Up… Hotspot name ("Choose or type a name"), Password, Location access, the tmux options under a disclosure row; Return closed it
Slack on both lists Settings page: "Keep running: Terminal, Slack" and "Freeze when lid closes: Slack". Edit Apps: Slack once, "Keep running"

Settings (the Dock covers the bottom rows):

settings

Edit Apps:

edit apps

The hotspot sheet:

hotspot

Slack on both lists, the page and then Edit Apps:

both lists settings

both lists edit apps

Not covered

  • Choose… in Add App, typing a hotspot name, and saving a password.
  • Joining a hotspot. The VM has no Wi-Fi.
  • The tmux list under the disclosure row. The script's press did not open it (tmux targets shown: 0 in the log).
  • What a session does at lid close with an app on both lists.
  • macOS 26 and real hardware.

The full logs are run-full-lab27.log and run-followup2-lab27.log.

🤖 Generated with Claude Code

@krishhgg krishhgg closed this Oct 18, 2026
@krishhgg krishhgg reopened this Oct 18, 2026
@krishhgg
krishhgg marked this pull request as draft October 18, 2026 05:11
@krishhgg
krishhgg marked this pull request as ready for review October 18, 2026 05:11
@krishhgg

Copy link
Copy Markdown
Owner

Thanks for this. Three things to fix before it can merge.

1. An app on both lists shows two rules

This is the case in Greptile's open thread on SettingsView.swift:88. An older config.json can list one app on both agentList and freezeList. Settings then shows the app under both summary lines, while Edit Apps shows it once, as Keep running, and the freeze planner keeps it running. My VM test above saw exactly this with Slack on both lists.

Picking a rule in Edit Apps doesn't clean it up either. Config.swift:313 returns early when the effective rule is unchanged, so choosing Keep running for that app leaves it on the freeze list.

Fix: in setRule, remove the overlap even when the effective rule stays the same. Build the Settings summary lines from the effective rules (rule(for:)) instead of the raw lists. Add a test for an app on both lists, then resolve Greptile's thread.

2. The hotspot sheet can grow taller than the screen

With many tmux targets, opening the disclosure in HotspotSheet.swift:27 makes the sheet taller than the screen. The vertical fixedSize stops the form from shrinking and scrolling, so the last targets, the Add row and Done can't be reached. In the VM, 30 targets made the sheet 870 points tall, and Done was below the bottom of the screen.

Fix: cap the sheet's height and let the form scroll.

3. The new label tests need an English system

The asserts at SettingsTests.swift:125 expect English text, but lengthLabel formats with the Mac's current locale. On a Mac set to French, for example, these tests fail even though the formatting is right.

Fix: let lengthLabel take a locale, and pass an English one (such as en_US_POSIX) in these tests.

Push the fixes as new commits on this branch (no rebase or force-push). CI, Greptile and the Codex review then run again on the new head. My VM test above covered 3a13fa0, so I'll rerun it on the new head.

🤖 Generated with Claude Code

nsd97 and others added 5 commits October 18, 2026 13:47
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The owner's review of krishhgg#104, and Greptile's open thread on SettingsView,
found that an app an older config.json names on both agentList and
freezeList showed under both summary lines on the Settings page. Edit
Apps showed it once, as Keep running, which is what the freeze planner
does with it. Picking Keep running didn't clean it up either: setRule
returned early when the effective rule was unchanged, so the app stayed
on the freeze list.

The summaries now come from the effective rules (Config.apps(with:),
built on rule(for:)), the same rows Edit Apps shows. setRule takes the
app off every list but the one for its rule even when that rule is
unchanged, and an app already on the right list keeps its place there.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The owner's VM run of krishhgg#104 found that with 30 tmux targets and the tmux
disclosure open, the hotspot sheet was 870 pt tall and Done was below
the bottom of the screen. The sheet's vertical fixedSize held the form
at the height of all its rows, so it could not scroll.

Without it, macOS sizes the sheet itself: a sheet's default sizing on
macOS fits the content's height, up to a maximum it takes from the
height of the window presenting it. In a scratch copy on a 16-inch
MacBook Pro, a sheet like this one with 60 rows in a 929 pt window
stopped at 857 pt with its bottom on screen, while with fixedSize it
was 1084 pt and ran 32 pt off the bottom. Short sheets kept their
height: 295 pt collapsed and 596 pt with 12 rows open, either way.

testTheHotspotSheetCanBeShorterThanItsRows offers the sheet less
height than its rows need and checks it takes no more; with the
fixedSize back it fails.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The owner's review of krishhgg#104 noted that testSessionLengthsReadAsWords
expects English text while lengthLabel formats in the Mac's current
locale, so on a Mac set to French it fails ("1 heure") although the
formatting is right.

lengthLabel takes a locale, Locale.autoupdatingCurrent by default, which
is the locale the units style used before, so Settings reads the same.
The test passes en_US_POSIX.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The release checklist's Settings items now cover an app config.json
names on both lists and the hotspot sheet with 30 tmux targets, and
docs/spec.md says how Settings treats an app on both lists. The
validation record has today's checks of 544b7c9 on a MacBook Pro with
macOS 27.0.1: the summaries, the Edit Apps cleanup, and the hotspot
sheet's height in a scratch copy with the tmux section open.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@nsd97

nsd97 commented Oct 18, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the VM run. All three are fixed in new commits on this branch, on top of a merge of current main (8134726). There was no rebase and no force-push.

1. An app on both lists shows two rules: 891fd8e

  • Summaries: the two lines on the page now come from the effective rules (Config.apps(with:), built on rule(for:)), so Slack on both lists shows once, under Keep running.
  • setRule: it removes the overlap even when the effective rule stays the same. The app keeps its place on the list it stays on.
  • Test: ConfigTests.testAnAppOnBothListsHasOneRuleAndPickingEitherCleansItUp fails with summaries built from the raw lists, and with the old early return.
  • On this Mac: with Slack on both lists, the page read "Keep running: Slack, Terminal" and "Freeze when lid closes: Discord". Choosing Keep running for Slack in Edit Apps left freezeList as ["com.hnc.Discord"]. Greptile's thread is answered and resolved.

2. The hotspot sheet can grow taller than the screen: 5d57192

  • Change: the vertical fixedSize is gone, and that alone caps the sheet. On macOS a sheet's default sizing is .form fitted to its content's height, and .form takes its maximum height from the window presenting it. The form scrolls past that.
  • On this Mac: a scratch copy had the tmux section forced open, because Accessibility couldn't open it here either, and 30 targets. Its sheet opened at 470 × 825 pt inside the 490 × 897 pt Settings window. The form scrolled to agents:30.0 and the Add row, with Done on screen.
  • Short sheets keep their height: in a probe with and without the fixedSize, a collapsed sheet was 295 pt both ways, and 596 pt both ways with 12 rows open.
  • Test: SettingsTests.testTheHotspotSheetCanBeShorterThanItsRows fails with the fixedSize back.

3. The label tests need an English system: 544b7c9

  • Change: lengthLabel takes a locale, Locale.autoupdatingCurrent by default, which is the locale the units style already used. The test passes en_US_POSIX.
  • Check: with xctest's own preferences set to fr_FR, the old test failed on "1 heure", "4 heures" and "3 jours", and the new one passed.

Docs and checks

  • Docs (ac6e05e): release checks for 1 and 2 in docs/releasing.md, a sentence in docs/spec.md, and today's results in docs/release-validation.md.
  • swift test on ac6e05e: 1,252 tests, none skipped, no failures, on macOS 27.0.1 with Xcode 27.1 and tmux installed.
  • Release build: swift build -c release -Xswiftc -warnings-as-errors passes.
  • Scripts: /bin/bash -n on every script, the bash 4 grep and scripts/check-lid-simulation-gate.sh pass.

Sources:

Comment thread Sources/Insomnia/UI/AppsSheet.swift Resolved
Greptile's review of ac6e05e found that an older config.json can name an
Apple app or Docker Desktop on freezeList alone. Edit Apps then showed
"Freeze when lid closes" in a disabled picker, and the summary on the
page listed the app under it, though FreezePlanner.isDenied keeps such
an app running.

rule(for:) now returns what the planner does: Keep running for any
listed app it denies (the agent list, Apple apps, Insomnia, Docker
Desktop), Freeze otherwise. Edit Apps and the summaries both read it.
The row's Remove button already clears the stale entry.

In a release build with TextEdit and Docker Desktop on freezeList alone,
the page read "Keep running: Terminal, TextEdit, Docker" and "Freeze
when lid closes: Discord", both rows read Keep running, and Remove took
TextEdit off freezeList. testAppsThePlannerNeverFreezesShowAsKeepRunning
fails with the previous rule(for:).

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@krishhgg

Copy link
Copy Markdown
Owner

End-to-end test in a VM on macOS 27.0.1, rerun at 43281e6

The fixes work in the VM:

  • An app on both lists now shows once, under Keep running, on the Settings page and in Edit Apps.
  • An Apple app or Docker Desktop on the freeze list only now shows Keep running.
  • With 30 tmux targets and the tmux list open, the hotspot sheet stays on screen and scrolls. Done stays on screen and closes it.

The head reviewed before the fix (3a13fa0) showed the old behavior for each of these.

Setup

The same VM and method as the earlier run: macOS 27.0.1 (26A434) with Xcode 27.0, each version built from source and installed with scripts/install.sh, and the stand-in Slack.app. A stand-in Docker.app (bundle id com.docker.docker, registered with Launch Services and removed afterwards) was added for this run. This PR's head (43281e6) against 3a13fa0.

t104g.sh set config.json by hand, as an older config could have it:

  • Slack on both agentList and freezeList.
  • TextEdit (com.apple.TextEdit) and Docker Desktop on freezeList only.

It then read the Settings page and Edit Apps.

t104h.sh added 30 tmux targets (work:1.0 to work:30.0), opened Set Up… and clicked the tmux disclosure row. It then measured the sheet against the screen's visible area, moved the sheet's scroll bar to the bottom, added work:31.0 with the Add row and clicked Done. The VM's screen is 1440x900 points. It ran once with the Dock hidden (visible area y 30 to 900) on both heads, and once with the Dock shown (y 30 to 819) on this PR's head.

Results

this PR (43281e6) before the fix (3a13fa0)
Settings page, Apps "Keep running: Terminal, Slack, TextEdit and 1 more"; "Freeze when lid closes: None on this Mac" "Keep running: Terminal, Slack"; "Freeze when lid closes: Slack, TextEdit, Docker"
Edit Apps Docker, Slack, Terminal, TextEdit once each, all "Keep running"; Docker, Terminal and TextEdit grayed out Slack "Keep running"; Docker and TextEdit "Freeze when lid closes", grayed out
Hotspot sheet, tmux list open, Dock hidden 470x798 at y 96, bottom edge y 894, on screen 470x870 at y 92, bottom edge y 962, past the screen's bottom (900)
Done at y 850 to 874, on screen; clicking it closed the sheet at y 1108, off screen; the script closed the sheet with Return
Scrolling the sheet has a scroll bar; at the bottom, the Pane field and Add are on screen no scroll bar; the Pane field (y 1036) can't be reached
Add a 31st target 31 rows in the sheet, 31 tmuxTargets in config.json, still 31 after Done not reachable
Same, Dock shown, this PR 470x717 at y 96, bottom edge y 813, above the Dock (819); Done at y 769; Add and Done worked (not run)

The "1 more" on the page is Docker; Edit Apps lists it.

The Settings page and Edit Apps, this PR on top and the head before the fix below:

settings this PR

edit apps this PR

settings before the fix

edit apps before the fix

The hotspot sheet with the tmux list open, this PR (opened, then scrolled to the bottom after adding work:31.0):

hotspot open this PR

hotspot added this PR

With the Dock shown, this PR:

hotspot open dock this PR

Before the fix. The sheet's content is cut off at the top (the hotspot name and password rows are missing), and its bottom, with Done, is past the screen's bottom edge, where the screenshot stops:

hotspot before the fix

Not covered

  • A real Docker Desktop. The stand-in has only the bundle id and name.
  • What a session does at lid close with these lists.
  • Screens shorter than 900 points, and macOS 26 and real hardware.
  • Choose… in Add App, typing a hotspot name, saving a password, and joining a hotspot (the VM has no Wi-Fi).

The full logs are run-fix-lab27.log (Settings page and Edit Apps), run-fix2-lab27.log (hotspot sheet, Dock hidden) and run-fix3-lab27.log (Dock shown). The hotspot steps of t104g.sh in run-fix-lab27.log don't count: its click missed the disclosure row's chevron.

🤖 Generated with Claude Code

Conflicts:
- SettingsView.swift: main added a Default field picker (krishhgg#116), the
  version line and the update check (krishhgg#117) to the old layout. They sit
  in General on the one page: Default field after Default session
  length, the version and the update check after Open at login, as
  main ordered them. releaseCheck is main's, unchanged.
- InsomniaApp.swift: SettingsView without AnyView, as this branch has
  it, with main's ReleaseChecker passed in.
- docs/spec.md: both edits to the presets line.

Also from the merge: the Settings window test passes a ReleaseChecker,
and main's "Settings > App" in README.md, docs and ReleaseCheck.swift
reads "Settings > General", the section's name on the one page.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
krishhgg added a commit that referenced this pull request Oct 19, 2026
#132 cab1050 against main e242782: the Countdown setting, the bar with
Time left and End time in light and dark, the right-click menu, the
12/24 hour switch, an unknown value, and two GIFs (a switch during a
session and one while a start is pending).
#71 ffdb1bc and 2a45e18: the Lock the screen row and its help text.
#104 0baa658 against main: the Settings window, Default field Minutes,
the update check, and the Edit Apps and If Wi-Fi drops sheets.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@krishhgg

Copy link
Copy Markdown
Owner

macOS 27.0.1 VM check of 0baa658 (main merged into the PR)

Everything checked matched what's expected after the merge. Default field set to Minutes opens the pills on Minutes. The Version row and Check for updates work. The Edit Apps and If Wi-Fi drops sheets open and close.

Setup. macOS 27.0.1 (26A434) with Xcode 27. This PR's head 0baa658 against main e242782, each built in the VM and installed with install.sh --allow-unverified-origin --app, from the same config.json. Screen 1440x900.

The Settings window

main is one long form, about five window heights (scrolled to 0, ¼, ½, ¾ and the bottom):

main's Settings window at five scroll positions

This PR, at the top and at the bottom. The window opens centered at 490x791, the screen's full visible height:

Top Bottom

Default field

Check Result
Default field, Hours to Minutes The pop-up reads Minutes, and config.json has "defaultFocusField": "minutes"
Clicking the eye The pills open with Minutes focused
Typing 5, then Enter session started until 2026-10-19T23:51:28Z (300s requested), and session.json is 300 s long

The pills, Minutes focused

5 typed into Minutes

The 5 minute session running

On a first try, the down arrow in the open menu picked Days instead of Minutes. The pills then opened on Days, and 5 then Enter started a 5 day session (432000 s), so that setting held too.

Version and Check for updates

The Version row reads 0.1.0 (1). Check for updates showed "You have the newest stable release, 0.1.0. Newest nightly: nightly-20261019-e24278258445." The log says:

release check: asking GitHub for the latest release and the releases list
release check: installed 0.1.0 (1), newest stable 0.1.0, newest nightly nightly-20261019-e24278258445: up to date

The General section after the update check

Edit Apps and If Wi-Fi drops

Edit Apps… If Wi-Fi drops, Set Up…

Edit Apps opened a 470x488 sheet, and Return closed it. Set Up… opened the 470x387 iPhone hotspot sheet, and Return closed it. Afterwards the window was the same as before.

Seen on the way

With the form scrolled to the bottom, the update report is a line taller than the hint it replaces, so its last line sat below the visible area until the form was scrolled again. That's a small layout point, not a failure.

Run notes: run-lab27.log. Builds: main, this PR. Nothing of the app was left installed in the VM afterwards.

🤖 Generated with Claude Code

@krishhgg

Copy link
Copy Markdown
Owner

Thanks for this, @nsd97. To avoid merge conflicts with the other open pull requests, your branch lands through #147, which merges your head commit 0baa658 unchanged. When #147 merges, GitHub marks this pull request merged and the commits stay yours.

Please don't push to this branch now. A new commit wouldn't be in #147, so this pull request would stay open instead of showing as merged. If something needs changing, comment here or on #147 and it'll go in as a follow-up there.

#147 moves two new controls from #145, Countdown and "Show the countdown in the menu bar", into your General section, and fixes one test: the app summary test now compares with Finder's localized name instead of the literal "Finder".

🤖 Generated with Claude Code

krishhgg added a commit that referenced this pull request Oct 24, 2026
…in the battery link

Greptile's three findings on #104's code in this PR:

- Choose... dropped Apple apps, so Terminal could not come back to Keep
  running, or to its App Nap cover, after a Remove. Config.addApp adds
  any app as Keep running; the running-apps menu still leaves Apple
  apps out.
- Done stayed enabled while a password save waited on the keychain. A
  save that failed after the sheet closed showed its notice nowhere.
  Done and interactive dismissal now wait for the save.
- The battery pickers lost main's caption saying the two levels move
  each other, so Never for Low Power Mode turned the battery end off
  without a word. The caption is back under End the session below.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
krishhgg added a commit that referenced this pull request Oct 27, 2026
Lands #104 at 0baa658, by nsd97.

Conflicts with #84 and #132, resolved here: #104 rebuilds the Settings
page, and #84 (show the countdown in the menu bar) and #132 (countdown
style) each added a control to the old one. Both controls move into
#104's General section after Default field, with #132's onChange that
applies a style change to a running session at once. The spec keeps
#104's presets wording, #132's end time text with the maintainer's time
change fix, and #84's toggle as its own bullet. The release checklist
keeps both sides' bullets.
krishhgg added a commit that referenced this pull request Oct 27, 2026
…in the battery link

Greptile's three findings on #104's code in this PR:

- Choose... dropped Apple apps, so Terminal could not come back to Keep
  running, or to its App Nap cover, after a Remove. Config.addApp adds
  any app as Keep running; the running-apps menu still leaves Apple
  apps out.
- Done stayed enabled while a password save waited on the keychain. A
  save that failed after the sheet closed showed its notice nowhere.
  Done and interactive dismissal now wait for the save.
- The battery pickers lost main's caption saying the two levels move
  each other, so Never for Low Power Mode turned the battery end off
  without a word. The caption is back under End the session below.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants