aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/process.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2026-04-20 15:53:22 +0200
committerGitHub Enterprise <[email protected]>2026-04-20 15:53:22 +0200
commit28a61b12d302e9e0d37d52bf1aa5d19069f3411b (patch)
tree07cd367f4933364781ea69c350025b1b6b703174 /src/zencore/process.cpp
parentzen-test: add CLI integration harness + TestArtifactProvider + CI host stats ... (diff)
downloadarchived-zen-28a61b12d302e9e0d37d52bf1aa5d19069f3411b.tar.xz
archived-zen-28a61b12d302e9e0d37d52bf1aa5d19069f3411b.zip
zen history command (#987)
- Feature: Per-user invocation history for `zen` and `zenserver`; each startup appends a record to a JSONL file capped at the most recent 100 entries. Location: `%LOCALAPPDATA%\Epic\Zen\History\invocations.jsonl` on Windows, `~/.zen/History/invocations.jsonl` on POSIX - `zen history` opens an interactive picker; selecting a zen row re-runs it inline and forwards the exit code, selecting a zenserver row spawns it detached - `zen history --list` (`-l`) prints the table to stdout instead of showing the picker - `zen history --filter zen|zenserver` restricts the listing to one executable - `zen history --print` prints the reconstructed command line of the selected row instead of launching it - `--enable-execution-history` global option on both binaries (default `true`) to opt out per invocation - The history file is attached to Sentry crash reports (alongside the existing zenserver log)
Diffstat (limited to 'src/zencore/process.cpp')
-rw-r--r--src/zencore/process.cpp50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/zencore/process.cpp b/src/zencore/process.cpp
index 4708f15cf..5d37c3715 100644
--- a/src/zencore/process.cpp
+++ b/src/zencore/process.cpp
@@ -906,6 +906,56 @@ BuildArgV(std::vector<char*>& Out, char* CommandLine)
#endif // !WINDOWS || TESTS
+std::string
+GetRawCommandLine()
+{
+#if ZEN_PLATFORM_WINDOWS
+ LPWSTR Raw = ::GetCommandLineW();
+ if (Raw == nullptr)
+ {
+ return {};
+ }
+ return WideToUtf8(Raw);
+#else
+ return {};
+#endif
+}
+
+std::string
+BuildCommandLine(std::span<const std::string> Argv)
+{
+ constexpr AsciiSet QuoteChars = " \t\"";
+
+ std::string Result;
+ for (size_t I = 0; I < Argv.size(); ++I)
+ {
+ if (I > 0)
+ {
+ Result += ' ';
+ }
+
+ const std::string& Arg = Argv[I];
+ const bool NeedsQuotes = Arg.empty() || AsciiSet::HasAny(Arg.c_str(), QuoteChars);
+ if (!NeedsQuotes)
+ {
+ Result += Arg;
+ continue;
+ }
+
+ Result += '"';
+ for (char Ch : Arg)
+ {
+ if (Ch == '"')
+ {
+ Result += '\\';
+ }
+ Result += Ch;
+ }
+ Result += '"';
+ }
+ return Result;
+}
+
#if ZEN_PLATFORM_WINDOWS
static CreateProcResult
CreateProcNormal(const std::filesystem::path& Executable, std::string_view CommandLine, const CreateProcOptions& Options)