Summary
windhawk-cli can turn logging on (mod config set <id> loggingEnabled true,
debugLoggingEnabled true) but has no way to read what that produces. I'd
like windhawk-cli mod log <id> [--follow] [--lines N].
Why
For anything automated — CI, scripted iteration, an agent driving the
edit → compile → deploy → observe loop — logs are the feedback channel. Today
the CLI covers every step of that loop except the last one, so a workflow that
is otherwise fully headless has to break out to the GUI or to a system-wide
debug listener at exactly the moment something has gone wrong.
The existing channels don't fill the gap well:
- The Windhawk log window is GUI-only.
- A debugger — Debugging the mods
covers attaching CodeLLDB — is the right tool for stepping through a problem,
but it is inherently interactive. It can't be the feedback channel for an
unattended script or a CI run.
- An
OutputDebugString / DBWIN listener works, but only one can exist
machine-wide. It conflicts with DebugView and with Windhawk's own log viewer,
so "watch my mod's output" is mutually exclusive with the other two tools an
author is likely to have open. It is also unfiltered — you get every process
on the machine, not the mod you asked about.
Because of that, mods that need observable output end up implementing their own
file logging. That is duplicated boilerplate in every such mod, it has to be
stripped before release, and each author invents a different file location and
format — so no tool can consume it generically.
Evidence
My mod carries ~40 lines pasted into the source purely to mirror Wh_Log into
a plain file the harness can tail:
static void DevLogWrite(const wchar_t* fmt, ...) {
...
Wh_Log(L"%s", body); // normal channel
// and again, by hand, to %TEMP%\windhawk-dev-<mod-id>.log
HANDLE h = CreateFileW(file, FILE_APPEND_DATA, ...);
...
}
It duplicates something the engine already has, and it must be removed before
submission. Every headless workflow I'm aware of reinvents this.
The engine already knows each mod's identity and already routes Wh_Log
somewhere — so it is the one component positioned to expose a per-mod,
filterable, non-exclusive log stream.
Suggested shape
windhawk-cli mod log <id> [--follow] [--lines N] [--since <time>]
- scoped to one mod, so no cross-process noise
--follow for the iterate loop; a bounded dump by default for scripts
- honours the existing
loggingEnabled / debugLoggingEnabled config rather
than adding a parallel switch
- ideally
--json like the rest of the CLI, with a timestamp and PID per record
(a mod injected into several processes at once produces interleaved output,
and the PID is what makes it readable)
A ring buffer of recent lines per mod would cover most of the value even
without persistence; --follow on top of that is the part that makes an
iterate loop pleasant.
Notes
If the engine doesn't retain log output today, a smaller first step would be
letting a mod opt into engine-managed file logging (a config flag plus a
documented path), so at least the boilerplate above stops being every author's
problem and the location becomes predictable enough for tooling.
Tested on 2.0.0-alpha.2.
Summary
windhawk-clican turn logging on (mod config set <id> loggingEnabled true,debugLoggingEnabled true) but has no way to read what that produces. I'dlike
windhawk-cli mod log <id> [--follow] [--lines N].Why
For anything automated — CI, scripted iteration, an agent driving the
edit → compile → deploy → observe loop — logs are the feedback channel. Today
the CLI covers every step of that loop except the last one, so a workflow that
is otherwise fully headless has to break out to the GUI or to a system-wide
debug listener at exactly the moment something has gone wrong.
The existing channels don't fill the gap well:
covers attaching CodeLLDB — is the right tool for stepping through a problem,
but it is inherently interactive. It can't be the feedback channel for an
unattended script or a CI run.
OutputDebugString/ DBWIN listener works, but only one can existmachine-wide. It conflicts with DebugView and with Windhawk's own log viewer,
so "watch my mod's output" is mutually exclusive with the other two tools an
author is likely to have open. It is also unfiltered — you get every process
on the machine, not the mod you asked about.
Because of that, mods that need observable output end up implementing their own
file logging. That is duplicated boilerplate in every such mod, it has to be
stripped before release, and each author invents a different file location and
format — so no tool can consume it generically.
Evidence
My mod carries ~40 lines pasted into the source purely to mirror
Wh_Logintoa plain file the harness can tail:
It duplicates something the engine already has, and it must be removed before
submission. Every headless workflow I'm aware of reinvents this.
The engine already knows each mod's identity and already routes
Wh_Logsomewhere — so it is the one component positioned to expose a per-mod,
filterable, non-exclusive log stream.
Suggested shape
--followfor the iterate loop; a bounded dump by default for scriptsloggingEnabled/debugLoggingEnabledconfig ratherthan adding a parallel switch
--jsonlike the rest of the CLI, with a timestamp and PID per record(a mod injected into several processes at once produces interleaved output,
and the PID is what makes it readable)
A ring buffer of recent lines per mod would cover most of the value even
without persistence;
--followon top of that is the part that makes aniterate loop pleasant.
Notes
If the engine doesn't retain log output today, a smaller first step would be
letting a mod opt into engine-managed file logging (a config flag plus a
documented path), so at least the boilerplate above stops being every author's
problem and the location becomes predictable enough for tooling.
Tested on 2.0.0-alpha.2.