fix(windows): eliminate console window flashes using PseudoConsole#22
Merged
cpfiffer merged 2 commits intoletta-ai:mainfrom Feb 24, 2026
Merged
Conversation
On Windows 11 / Windows Terminal, hook execution caused visible console window popups. This replaces the simple npx wrapper (silent-npx.js) with a PseudoConsole (ConPTY) + CREATE_NO_WINDOW approach that runs scripts in a headless console session. New files: - SilentLauncher.cs: C# launcher creating a PseudoConsole with CREATE_NO_WINDOW, stdin/stdout via temp files, and --import tsx/esm for single-process execution - silent-launcher.exe: Compiled as AnyCPU winexe (works on x64 and ARM64) - stdio-preload.cjs: Node.js --require script for temp file I/O - silent-npx.cjs: Cross-platform shim that delegates to silent-launcher.exe on Windows, runs tsx directly elsewhere Also fixes: - Letta API message sync: bumped limit from 50 to 300 and added date sorting (API does not guarantee newest-first ordering) - Background workers on Windows: spawn through silent-launcher.exe with detached:true so workers survive PseudoConsole closure Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
@cpfiffer rdy to merge this? 🙏 |
- Add dual P/Invoke for UpdateProcThreadAttribute (Win11 26300+) vs UpdateProcThreadAttributeList (Win10/older) with EntryPointNotFoundException fallback in SilentLauncher.cs - Extract shared spawnSilentWorker() utility into conversation_utils.ts, replacing ~50 duplicated lines in send_messages_to_letta.ts and sync_letta_memory.ts - Add build.ps1 for reproducible silent-launcher.exe builds - Rebuild silent-launcher.exe with updated source Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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 #20. On Windows 11 / Windows Terminal, every hook execution caused a visible console window flash (popup). This was because
npxspawned throughshell: trueallocated a new console window.This PR replaces the simple npx wrapper (
silent-npx.js) with a three-part solution:SilentLauncher.cs) compiled as awinexecreates a headless PseudoConsole session. Scripts run inside this invisible console — no popup.--import tsx/esmas a Node.js ESM loader instead of the tsx CLI (which spawns a child process). Combined with--require stdio-preload.cjs, stdin/stdout flow through temp files so the PseudoConsole doesn't needSTARTF_USESTDHANDLES(which re-triggers the flash on Win11 26300).silent-launcher.exewithdetached: true. Since the exe is a winexe,detacheddoesn't create a console flash, and workers get their own PseudoConsole so they survive the parent's closure.Additional fixes included
/conversations/{id}/messagesendpoint does not guarantee newest-first ordering. Added explicit date sorting solastSeenMessageIdtracking works correctly.Files changed
hooks/SilentLauncher.cshooks/silent-launcher.exehooks/stdio-preload.cjs--requirescript for temp file stdin/stdouthooks/silent-npx.cjssilent-launcher.exeon Windows, runs tsx directly elsewherehooks/silent-npx.js.cjsversion (required sincepackage.jsonhas"type": "module")hooks/hooks.json.js→.cjsextensionscripts/sync_letta_memory.tsscripts/send_messages_to_letta.tsNon-Windows impact
No behavior change on Linux/macOS. The new
silent-npx.cjsfalls back to running tsx directly (same as before, just without the npx indirection).Test plan
lastSeenMessageIdadvances correctly (no duplicate messages)Supersedes #21.
🤖 Generated with Claude Code