Skip to content

Commit 5c2f5de

Browse files
committed
fix(cli): forward stdin for interactive scripts in run mode
Scripts using vix::io (or any stdin-reading API) were not receiving keyboard input because passthroughRuntime was set to false whenever useVixRuntime was true. - RunScript.cpp: pass passthroughRuntime=true unless --force-server - DirectScriptRunner.cpp: same fix in make_direct_script_plan - ScriptProbe.cpp: exclude vix/* headers from include_path_requires_fallback to avoid redundant fallback path when usesVix already covers it
1 parent c6ab52d commit 5c2f5de

3 files changed

Lines changed: 38 additions & 27 deletions

File tree

src/commands/run/RunScript.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -624,15 +624,20 @@ namespace vix::commands::RunCommand::detail
624624
{
625625
apply_sanitizer_env_if_needed(opt.enableSanitizers, opt.enableUbsanOnly);
626626

627-
const bool isPlainScript = !state.useVixRuntime;
627+
// A script using vix::io (stdin/stdout) needs stdin forwarded just like
628+
// a plain script. Only true long-lived server apps should suppress passthrough.
629+
// Use forceServerLike to distinguish: if the user didn't explicitly say
630+
// --force-server, treat any non-watch script as interactive (passthrough).
631+
const bool isInteractive = !opt.forceServerLike || !state.useVixRuntime;
632+
628633
std::string cmdRun = "VIX_STDOUT_MODE=line " + quote(state.exePath.string());
629634
cmdRun += join_quoted_args_local(opt.runArgs);
630635
cmdRun = wrap_with_cwd_if_needed(opt, cmdRun);
631636

632637
LiveRunResult rr = run_cmd_live_filtered_capture(
633638
cmdRun,
634639
"",
635-
isPlainScript,
640+
isInteractive, // ← corrigé
636641
effective_timeout_sec(opt),
637642
opt.enableSanitizers || opt.enableUbsanOnly);
638643

src/commands/run/detail/DirectScriptRunner.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ namespace vix::commands::RunCommand::detail
399399
plan.binaryPath = plan.cacheDir / (plan.exeName + executable_suffix());
400400

401401
plan.shouldRun = true;
402-
plan.passthroughRuntime = opt.forceServerLike || opt.watch;
402+
plan.passthroughRuntime = !opt.forceServerLike;
403403
plan.effectiveTimeoutSec = effective_timeout_sec(opt);
404404
plan.probe = probe;
405405

src/commands/run/detail/ScriptProbe.cpp

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -99,30 +99,6 @@ namespace vix::commands::RunCommand::detail
9999
return std::nullopt;
100100
}
101101

102-
/**
103-
* @brief Return true when the include clearly looks project-managed.
104-
*
105-
* Direct script mode is intentionally strict:
106-
* - quoted includes are treated as project headers
107-
* - includes containing a path separator are treated as project layout
108-
*/
109-
bool include_path_requires_fallback(const std::string &includePath, bool isQuotedInclude)
110-
{
111-
if (includePath.empty())
112-
return false;
113-
114-
if (isQuotedInclude)
115-
return true;
116-
117-
if (includePath.find('/') != std::string::npos ||
118-
includePath.find('\\') != std::string::npos)
119-
{
120-
return true;
121-
}
122-
123-
return false;
124-
}
125-
126102
/**
127103
* @brief Return true when the include path is a Vix runtime header.
128104
*
@@ -147,6 +123,36 @@ namespace vix::commands::RunCommand::detail
147123
return starts_with(includePath, "vix/");
148124
}
149125

126+
/**
127+
* @brief Return true when the include clearly looks project-managed.
128+
*
129+
* Vix runtime headers (<vix/...>) are excluded from this check:
130+
* they are handled separately via is_vix_runtime_include() and
131+
* already force CMake fallback through usesVix → requiresCMakeTargets.
132+
* Treating them as "project layout" here would cause script_source_requires_cmake_fallback
133+
* to fire redundantly AND prevent the correct fallback reason from being set.
134+
*/
135+
bool include_path_requires_fallback(const std::string &includePath, bool isQuotedInclude)
136+
{
137+
if (includePath.empty())
138+
return false;
139+
140+
// Vix runtime headers are handled by is_vix_runtime_include() — skip them here.
141+
if (is_vix_runtime_include(includePath))
142+
return false;
143+
144+
if (isQuotedInclude)
145+
return true;
146+
147+
if (includePath.find('/') != std::string::npos ||
148+
includePath.find('\\') != std::string::npos)
149+
{
150+
return true;
151+
}
152+
153+
return false;
154+
}
155+
150156
/**
151157
* @brief Return true when the script source layout is not suitable for direct mode.
152158
*

0 commit comments

Comments
 (0)