@@ -592,6 +592,37 @@ namespace vix::commands::RunCommand::detail
592592 }
593593 };
594594
595+ std::string rtrim_copy (std::string s)
596+ {
597+ while (!s.empty () &&
598+ (s.back () == ' ' || s.back () == ' \t ' ||
599+ s.back () == ' \n ' || s.back () == ' \r ' ))
600+ {
601+ s.pop_back ();
602+ }
603+ return s;
604+ }
605+
606+ bool looks_like_prompt_fragment (const std::string &chunk)
607+ {
608+ if (chunk.empty ())
609+ return false ;
610+
611+ if (chunk.find (' \n ' ) != std::string::npos ||
612+ chunk.find (' \r ' ) != std::string::npos)
613+ {
614+ return false ;
615+ }
616+
617+ const std::string trimmed = rtrim_copy (chunk);
618+
619+ return trimmed == " >" ||
620+ trimmed == " $" ||
621+ trimmed == " #" ||
622+ trimmed == " >>>" ||
623+ trimmed == " ..." ;
624+ }
625+
595626 struct CMakeNoiseFilter
596627 {
597628 std::string carry;
@@ -763,6 +794,13 @@ namespace vix::commands::RunCommand::detail
763794 if (nl == std::string::npos)
764795 {
765796 carry = data.substr (start);
797+
798+ if (!inReport && looks_like_prompt_fragment (carry))
799+ {
800+ out += carry;
801+ carry.clear ();
802+ }
803+
766804 break ;
767805 }
768806
@@ -854,6 +892,13 @@ namespace vix::commands::RunCommand::detail
854892 if (nl == std::string::npos)
855893 {
856894 carry = data.substr (start);
895+
896+ if (looks_like_prompt_fragment (carry))
897+ {
898+ out += carry;
899+ carry.clear ();
900+ }
901+
857902 break ;
858903 }
859904
@@ -1054,6 +1099,19 @@ namespace vix::commands::RunCommand::detail
10541099 if (useSan)
10551100 return ;
10561101
1102+ if (passthroughRuntime && looks_like_prompt_fragment (printable))
1103+ {
1104+ if (!captureOnly)
1105+ {
1106+ write_all (STDOUT_FILENO, printable.data (), printable.size ());
1107+ printedSomething = true ;
1108+ printedRealOutput = true ;
1109+ result.printed_live = true ;
1110+ lastPrintedChar = printable.back ();
1111+ }
1112+ return ;
1113+ }
1114+
10571115 std::string filtered;
10581116
10591117 printable = sanitizer.filter_for_print (printable);
0 commit comments