Add Startup settings: auto-connect to a host, open a new chat, last chat or terminal - #66
Open
jankarres wants to merge 7 commits into
Open
Add Startup settings: auto-connect to a host, open a new chat, last chat or terminal#66jankarres wants to merge 7 commits into
jankarres wants to merge 7 commits into
Conversation
jankarres
force-pushed
the
jan/startup-behaviour
branch
from
August 19, 2026 09:25
92e7b1c to
995abf2
Compare
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.
Getting from the app icon to a usable chat costs six taps and about seventeen seconds on every cold launch, and this brings it to zero for anyone who wants that. It adds a
Startupsection to "Settings" that decides two things about a launch: which host to connect to, and what to open once connected. Closes #62.Both default to what the app does today, so nothing changes for anyone who does not open the page.
Switch auto-connect on and the second group wakes up. Agent and project appear only for the targets that need them.
The result, with
Last used hostplusNew chat. Zero taps, where it used to be six.cold-start.mp4
How it is put together
lib/settings.tsgets astartupgroup next toserver,editorandterminal, same defaults-plus-normalizer shape. That also handles migration, since an old settings file just gets the defaults filled in on the next read.lib/startupPlan.tsis the whole decision, pure and unit tested: settings plus live state in, a plan out. No I/O.state/startup.tsruns the sequence, connect, wait, resolve, open, with a cancel check at every await and a module-levelhasRunso it can only ever fire on a cold start.components/StartupRunner.tsxrendersnulland just starts the thing. It sits inApp.tsxrather than inside the provider, because the provider also wraps onboarding and the rule must not fire during first run.components/StartupBanner.tsxis the visible half, rendered by the Home tab in the slotOfflineBanneralready uses.lib/navigate.tsxpulls the chat, sessions, git client, system monitor and ports pushes out of the seven components that each had a copy. The chat push alone carries eleven props, and I did not want the startup path to become one more place they have to stay in sync.Behaviour worth calling out
The strip is cancellable, and leaving the Home tab cancels it too, since
TabViewunmounts the tab and the cleanup runs. That came free and is the behaviour you want anyway.If the target cannot be reached, the app stays on Home and says why once. No fallback chain: opening a new chat because the last one is missing would be worse than doing nothing.
pickResumableSessionsorts byupdatedAtclient-side rather than trusting the order the host sends. For a list a wrong order is cosmetic, but for "open the newest chat" it would quietly open the wrong conversation.Two small things the navigate extraction changes rather than preserves.
providerNamenow falls back fromagent.titletoagent.namebefore the raw id, where two of the old copies used the title alone and rendered an empty subtitle if a host reported none. And the ports page in the "More" tab is loaded dynamically now like every other page, because a static import insidelib/navigate.tsxwould drag four pages into the initial bundle.Testing
pnpm typecheckandpnpm formatclean.pnpm testis 116 tests, up from 97, the new ones all onstartupPlan. The production browser build compiles.Ran end to end on the browser target against a real CLI host: each connect mode, the cold start above, cancel during connect, a tab switch mid-sequence, and both failure paths. Untested on Android and iOS, I did not set up the mobile build toolchain for this.
Before you merge
Two decisions you may see differently.
Startupgot its own settings category because it carries seven controls and governs the whole app rather than one surface, and the rule is global rather than per host, on the assumption that a phone tends to point at the same machine. Both are cheap to change.If anything here should be different, conceptually or in the code, tell me and I will take care of it. Same if you would rather have it in smaller pieces: auto-connect with the
Hometarget first, thenlib/navigate.tsxand the five remaining targets.