Fix startup commands frequently not running on launch (#14)#16
Open
frd1201 wants to merge 1 commit into
Open
Conversation
Per-pane startup commands often failed to run when workspaces launched, intermittently for a single workspace and almost always for the second of two launchOnStartup workspaces. Three timing/lifecycle root causes are addressed: 1. Pane discovery was a single 300ms scan. If the split panes weren't constructed yet, getAllTabs() returned 0 and every command was silently skipped with no retry. StartupCommandService now polls, processing panes as they appear until all of a split's commands are handled (capped). 2. Commands were sent before the PTY session existed. The code blind-fired a 500ms timeout into a shell that wasn't ready, so input was dropped during shell init (clink/conpty in particular). It now waits for session.output$ to exist, then for the shell prompt to render (prompt detection across cmd/clink/PowerShell/bash/zsh, with an output-settle timeout and a hard cap as fallbacks). 3. Background-workspace panes never connected their session, so there was nothing to send to. Startup launches are now serialized: each workspace stays in the foreground until its sessions connect and commands are sent before the next one opens. registerCommands() returns a promise that resolves when the batch is delivered (or a safety timeout elapses).
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
Fixes #14 — per-pane startup commands frequently don't run when a workspace launches: intermittently for a single workspace, and almost always for the second workspace when two have
launchOnStartup: true.There are three independent timing/lifecycle root causes (full evidence in #14); this PR addresses all three.
Changes
1. Poll for panes instead of a single 300 ms shot —
startupCommand.service.tsonTabOpened()previously didsetTimeout(() => processChildTabs(tab), 300)and calledgetAllTabs()exactly once. If the split panes weren't constructed yet at 300 ms, it found 0 tabs and every command for that workspace was silently skipped.Now
processChildTabs()re-scans the split on a short interval, processing panes as they appear, and stops once all of the split's pending commands are handled (or an attempt cap is hit).2. Wait for real readiness before sending —
startupCommand.service.tsCommands were sent before the PTY session existed: the code blind-fired
setTimeout(sendCommand, 500)into a shell that wasn't ready, so the input was dropped during shell init (clink/conpty in particular drop early input).Now each command:
session.output$actually exists, then>/$/#/%/❯/➜), with an output-settle timeout and an overall hard cap as fallbacks.3. Serialize startup launches —
toolbar.provider.tsWhen two
launchOnStartupworkspaces opened, only the active tab initialized its PTYs; the workspace that ended up in the background never got a session, so there was nothing to send to.registerCommands()now returns a promise that resolves when the batch has been delivered (or a safety timeout elapses).openWorkspace()awaits it, so workspaces open one at a time — each stays foreground until its sessions connect and commands are sent before the next opens.Notes
devper CONTRIBUTING.md.npm run build), no new TypeScript errors.Follow-up (not in this PR)
#14 also notes a cleaner long-term option: pass the startup command via the shell's own launch args (
cmd /k,pwsh -NoExit -Command,bash -c '…; exec bash') so the shell runs it itself, removing the typing-based timing heuristics entirely. Happy to explore that separately if preferred.