Skip to content

fix: address the five alpha2 field reports - #34

Merged
HelloThisWorld merged 1 commit into
mainfrom
fix/alpha2-feedback
Aug 4, 2026
Merged

fix: address the five alpha2 field reports#34
HelloThisWorld merged 1 commit into
mainfrom
fix/alpha2-feedback

Conversation

@HelloThisWorld

Copy link
Copy Markdown
Owner

Summary

Fixes the five issues reported from local v1.3.0-alpha2 testing. Four trace
back to the same area: alpha2 was the first release where the shell
integration module ran in a real terminal, and its emission had two defects
that cascaded into the Timeline and the progress bar.

# Report Root cause Fix
1 \\\ before every prompt (\\\\ after a command) The OSC terminator was written as '\\' — in PowerShell single quotes that is a literal two-character string, so every sequence ended ESC \ \ and the terminal printed the leftover backslash (3 = A, cwd, B; 4 = + D) Get-WinTermOscSequence builds the terminator as '\', one character
2 Loaded command carried the prompt path Marks were console side effects during prompt; the host writes those before the returned text, so 133;B landed before the visible prompt and the command region began at the prompt text Invoke-WinTermPrompt returns one string with the marks embedded in FinalTerm order: D (2nd prompt on), A, cwd, prompt text, B
3 Progress bar animates at an idle prompt, without typing ProgressStateMachine mapped CommandStart (133;B = composing input) to a visible indeterminate bar 133;B hides the shell snapshot; only 133;C (command executed) starts the running bar
4 Phantom Command text unavailable / Running row The lifecycle model created an entry at 133;B B is bookkeeping only (closes a previous never-completed command); the entry materializes at OutputStart/CommandFinished. The capability bit recorded at B still yields Running rather than Unknown
5 Rows jump on arrow keys / hover _renderCommandTimeline rebuilt every ListView row on each selection change A per-row content signature detects selection-only updates and moves SelectedIndex without rebuilding

Additionally, a module component blocked by antivirus at parse time (observed
for Compatibility.ps1 under some engines — including on the alpha2 test
machine, which showed a red parse error at session start) is now skipped
silently and recorded in diagnostics. Only functions that actually loaded are
exported, so a blocked component degrades that one capability and nothing
else; shell integration needs only the Private components.

Emission verified against a live session

The wrapped prompt now returns byte-exact FinalTerm order (captured from a
real import, ESC rendered):

first : <ESC>]133;A<ESC>\<ESC>]9;9;"D:\work\winTerm"<ESC>\PS D:\work\winTerm> <ESC>]133;B<ESC>\
second: <ESC>]133;D;0<ESC>\<ESC>]133;A<ESC>\<ESC>]9;9;"D:\work\winTerm"<ESC>\PS D:\work\winTerm> <ESC>]133;B<ESC>\

No stray characters, B after the prompt text, single-character terminators.

Test updates forced by the new semantics

  • LifecycleUpdatesAreIncrementalAndIdempotent: 133;B alone asserts no
    entry
    (still idempotent); the entry materializes at OutputStart as
    Running.
  • ActionLoadRejectsMissingCommandText: the entry-without-text scenario now
    uses an executed command with empty captured text.
  • The no-output CopyOutput refusal now uses a bootstrapped mid-execution
    mark, since a B-only prompt no longer produces an entry.
  • CommandCompletionClearsAtNextPrompt: asserts 133;B shows no bar (idle
    prompt quiet), 133;C shows Indeterminate, D→Success, prompt→hidden, and
    the next idle 133;B stays hidden.
  • SplitOrDetachResetClearsReusableState: rehydration uses CommandExecuted.

Validation performed

Environment: Windows 11 Pro 26100, MSVC 14.44.35207, Windows SDK 10.0.26100.0.

Compiled tests — ran on fresh builds, passed

Suite Result
SettingsModel winTerm classes Total=44, Passed=44, Failed=0
CommandTimelineTests (Control) Total=43, Passed=43, Failed=0

Builds — ran, clean: SettingsModel.UnitTests and Control.UnitTests
x64 Release both exit 0 (the latter includes Microsoft.Terminal.Control.Lib
with the TermControl change).

Live module check — ran: import on this machine (whose antivirus blocks
Compatibility.ps1) produces no console output, exports all six integration
functions, records the skipped component in diagnostics, and the prompt
emission is byte-exact as shown above.

Repository gates — ran, passed: verify-version.ps1,
verify-branding.ps1, test-release-workflow.ps1,
test-ci-classification.ps1, test-command-timeline.ps1,
test-visual-progress.ps1, test-privacy.ps1, test.ps1 -Suite Smoke.

Staticgit diff --check clean; clang-format clean over changed ranges
(TermControl differences verified EOL-representation only).

Not run, with reasontest-shell-integration.ps1 -Shell All: this
machine's antivirus blocks Compatibility.ps1, so the compatibility-command
assertions cannot run locally (they now fail cleanly on the missing command
rather than a parse spill). The suite runs in the release workflow's gates on
clean runners, where alpha1 and alpha2 both passed it.

No screenshot was needed or created. winterm-site is untouched.

Checklist

  • The change is focused and does not include unrelated formatting.
  • Tests were added or updated where appropriate.
  • All tests claimed above actually ran and passed.
  • User-facing behavior and limitations are documented in this repository.
  • This source/docs commit updates the root CHANGELOG.md.
  • The Wiki Development-Changes.md ledger has been pushed with the final source SHA, link, summary, and checkpoint/release.
  • Documentation screenshots reuse a suitable existing sanitized winterm-site asset, or no screenshot was added.
  • Version or schema changes include compatibility and migration notes.
  • Package identity, winterm.exe, and Microsoft Terminal coexistence remain isolated.
  • No command text, terminal output, clipboard content, credentials, or private paths are logged.
  • New source and script files contain the appropriate MIT license header.
  • I did not include generated build output, secrets, certificates, or local absolute paths.

Source ↔ Wiki mapping

Source commit Wiki commit Wiki pages
09bd1b5 214dfca Development-Changes

Boundary

No persistent history, no output cache, no output search, no heuristic prompt
detection, no telemetry. Workspace schema (2), docking model (1), shell
protocol (1), theme schema (1), update manifest schema (1), package identity,
and signing policy are unchanged. Version metadata is unchanged. No
winterm-site change.

Next step after this merges: prepare and publish v1.3.0-alpha3 for local
re-testing.

Local testing of v1.3.0-alpha2 reported five issues. Four share one root
area: the first real-terminal run of the shell integration module.

1. Stray backslashes before every prompt. Write-WinTermOsc terminated each
   sequence with ([char]27 + '\\'); in PowerShell single quotes '\\' is a
   literal two-character string, so every emission was ESC ] payload ESC
   backslash backslash. The terminal consumed the well-formed sequence and
   printed the leftover backslash: three before the first prompt (A, cwd,
   B) and four after a command (D as well). The terminator is now '\', one
   character, built in Get-WinTermOscSequence.

2. The Timeline recorded the whole prompt line and Load inserted the
   prompt path into the input. The marks were written as console side
   effects while the prompt function ran, and the console host writes a
   prompt function's console output before its returned text, so 133;B
   landed before the visible prompt and the command region began at the
   prompt text. Invoke-WinTermPrompt now returns one string with the marks
   embedded in FinalTerm order: D (from the second prompt on), A, the cwd
   report, the original prompt text, then B.

3. The Visual Progress bar animated forever on an idle shell-integrated
   prompt, even without typing. ProgressStateMachine mapped CommandStart
   (133;B, the user composing input) to a visible indeterminate bar. B now
   hides the shell snapshot; only CommandExecuted (133;C) starts the
   running bar, and CommandFinished and the next prompt behave as before.

4. A phantom "Command text unavailable / Running" entry appeared for the
   active prompt. The lifecycle model created an entry at CommandStart.
   A 133;B-only mark is the user composing input, not a command, so B is
   now bookkeeping only: it closes out a previous command that never
   reported completion, and the entry materializes at OutputStart or
   CommandFinished. The capability bit recorded at B still lets the entry
   read Running rather than Unknown.

5. Timeline rows jumped when moving the selection with the arrow keys or
   hovering. _renderCommandTimeline rebuilt every ListView row on each
   selection change. A per-row content signature now detects
   selection-only updates and moves SelectedIndex without rebuilding.

Additionally, a module component blocked by antivirus at parse time
(observed for Compatibility.ps1 under some engines, printing a parse error
at session start) is now skipped silently and recorded in diagnostics.
Only functions that actually loaded are exported, so a blocked component
degrades that one capability and nothing else.

Tests updated for the new semantics: an executed command with empty text
still refuses text actions, the no-output CopyOutput refusal now uses a
bootstrapped mid-execution mark, idle 133;B asserts no bar and no entry,
and the split-reset rehydration uses CommandExecuted. Verified against a
live PowerShell session: the returned prompt is byte-exact FinalTerm
order with single-character terminators.

No persistent history, no output cache, no heuristic prompt detection, no
telemetry. Workspace schema, docking model, shell protocol, theme schema,
update manifest schema, package identity, and signing policy are
unchanged.
@HelloThisWorld
HelloThisWorld merged commit e0fd786 into main Aug 4, 2026
5 checks passed
HelloThisWorld added a commit that referenced this pull request Aug 4, 2026
Promotes the five alpha2 field-report fixes, already on main through pull
request #34, to a third installable alpha. This commit only moves the
release metadata.

- Set application version 1.3.0-alpha3, PowerShell module prerelease suffix
  alpha3, and tag v1.3.0-alpha3. The channel stays alpha, and the module
  version stays 1.3.0.
- Advance the package/file version to 1.3.0.2 across the MSIX manifest and
  the three Win32 resource scripts; the display ProductVersion strings carry
  1.3.0-alpha3.
- Update the version literals pinned by verify-version.ps1,
  verify-branding.ps1, test-visual-progress.ps1, test.ps1, and
  package-shell-assets.ps1.
- Add the 1.3.0-alpha3 release notes with a "Changes since alpha2" section
  covering the five fixes and the antivirus resilience note, and retitle the
  changelog's unreleased section.

The release workflow marks any non-stable channel with --prerelease and
--latest=false, so /releases/latest keeps resolving to v1.2.0, the alpha is
not listed on the winTerm website, and the WinGet workflow skips it.
Workspace schema, docking model, shell protocol, theme schema, update
manifest schema, package identity, and signing policy are unchanged.
@HelloThisWorld
HelloThisWorld deleted the fix/alpha2-feedback branch August 5, 2026 12:51
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.

1 participant