feat(headless): typed --console option resolution + command-line flag
Adds the first piece of the interactive headless console (docs/plans/ 2026-09-07-headless-console.md): HeadlessConsoleOptions.Resolve picks --console, then ACDREAM_HEADLESS_CONSOLE=1, then a terminal-shaped default, matching the project's typed-options-object convention rather than a scattered env-var read. HeadlessCommandLine.Parse now accepts --console as a bare flag (no value token) alongside the existing paired options. Both new launch-options.md rows are added in this commit per LaunchOptionsDocumentationTests' bidirectional rule. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
a427d7db05
commit
7bff9c649d
3 changed files with 58 additions and 4 deletions
|
|
@ -93,6 +93,7 @@ dotnet run --project src\AcDream.App\AcDream.App.csproj --no-build -c Release
|
|||
| `ACDREAM_DAT_DIR` | `=<path>` | Fallback dat-directory when no positional argument is given. App: single read at `Program.cs:58`. Cli: read independently per-subcommand (each subcommand does `args.ElementAtOrDefault(N) ?? Env.GetEnvironmentVariable("ACDREAM_DAT_DIR")`) plus once more for the default (no-subcommand) asset-inventory mode at line 152. | Two of the four `Program.cs` line numbers in the raw grep (91, 135) are **not reads** — they're the literal string `ACDREAM_DAT_DIR` inside `Log.Error` usage-text messages, not `GetEnvironmentVariable` calls. Only line 58 is a real read in `AcDream.App`. | none — hard usage error (exit 2) if unset and no positional arg | `Program.cs:58` (App); `Cli/Program.cs:24,35,47,59,71,84,113,125,137,152` (every Cli subcommand) |
|
||||
| `ACDREAM_DISPLAY_PROTOCOL` | `="auto"` / `"x11"` / `"wayland"` (case-insensitive, trimmed); any other value throws `InvalidOperationException` at startup | Linux-only: forces the GLFW 3.4 platform-init hint (X11 vs Wayland vs auto) before any window is created; ignored entirely on Windows (always `Windows` protocol) | An invalid value is fatal at startup (throws before any window exists), not a silent fallback | unset → auto-detected from `XDG_SESSION_TYPE`/`WAYLAND_DISPLAY`/`DISPLAY`, falling back to GLFW `Automatic` | `GraphicalWindowBackendSelection.Resolve` (`GraphicalWindowBackendSelection.cs:26-58`) |
|
||||
| `ACDREAM_FAR_RADIUS` | `=<int>` | Overrides preset's `FarRadius` (outer streaming/reveal window, landblocks) | Enlarging changes streaming memory budget and what's resident/rendered — CLAUDE.md: leave unset for measurement/gate runs (same family as legacy `ACDREAM_STREAM_RADIUS`) | preset's `FarRadius` (Low=5, Medium=8, High=12, Ultra=15) | `QualitySettings.WithEnvOverrides` (`QualityPreset.cs:47`) |
|
||||
| `ACDREAM_HEADLESS_CONSOLE` | `=1` enables | Turns on the headless host's interactive console (docs/plans/2026-09-07-headless-console.md): a background thread reads stdin lines, each drained on the session tick through the SAME plugin-verb/client-slash-command pipeline the graphical chat box uses, with chat/lifecycle/portal output rendered to stdout. Only takes effect for `run` with a single configured session — the launcher's multi-session mode is unaffected. | Starts a background stdin-reader thread and writes plain-text lines to the same stdout stream `HeadlessDiagnosticWriter` already uses for its JSON lines — the two interleave. Only applies to `run`; `--console` (bare flag, no value) always wins over this variable, which in turn always wins over the terminal-shaped default. | unset → on when stdin is a real console, off when redirected (`!Console.IsInputRedirected`, checked once in `Program.cs`) | `HeadlessConsoleOptions.Resolve` (`Configuration/HeadlessConsoleOptions.cs`) → `HeadlessEntryPoint.Run` → `HeadlessProcessHost`'s `consoleEnabled` |
|
||||
| `ACDREAM_LIVE` | `=1` (exactly the literal string `"1"`) | Core switch: connect to a live ACE server instead of running offline/no-connect. | The 4 non-`RuntimeOptions.cs` line numbers in the raw grep are **all comments or log-message text**, not reads — `SessionStartComposition.cs:39` is inside the string `"live: ACDREAM_LIVE set but TEST_USER/TEST_PASS missing; skipping"`; `Program.cs:126` is inside a `--session-config` override log line; `GameWindow.cs:614,627` are doc comments. The only actual parse is `RuntimeOptions.cs:141`. Requires `ACDREAM_TEST_USER`/`ACDREAM_TEST_PASS` too (`HasLiveCredentials`) or the session silently reports `MissingCredentials` and skips. Forced to effectively-on (LiveMode=true) unconditionally by `--session-config` launches regardless of this var. | `false` | `RuntimeOptions.LiveMode` → `SessionStartComposition.cs` (log text only), `Program.cs:126` (log text only), `GameWindow.cs:614,627` (comments only), consumed for real via `RuntimeOptions.HasLiveCredentials` and `WorldSession`/`GameRuntime` session-start gating |
|
||||
| `ACDREAM_MAX_COMPLETIONS_PER_FRAME` | `=<int>` | Overrides preset's per-frame streaming-completion throughput cap | Directly changes the streaming admission budget measured by perf/completion gates — do not vary during a measurement run | preset's value (Low=2, Medium=3, High=4, Ultra=6) | `QualitySettings.WithEnvOverrides` (`QualityPreset.cs:59`) |
|
||||
| `ACDREAM_MSAA_SAMPLES` | `=<int>` (0/2/4/8) | Overrides preset's MSAA sample count | Changes GPU multisample anti-aliasing (visual + GPU-cost change) | preset's `MsaaSamples` (Low=0, Medium=2, High/Ultra=4) | `QualitySettings.WithEnvOverrides` (`QualityPreset.cs:48`) |
|
||||
|
|
@ -143,6 +144,7 @@ config without connecting; `run` connects.
|
|||
| `--config <path>` | The versioned headless session-configuration document. Required. | — |
|
||||
| `--config-dir` / `--data-dir` / `--cache-dir` `<path>` | Override each portable path root. | Merged over the config document's own `process.paths`; the command line wins. |
|
||||
| `-user` / `--user`, `-password` / `--password` | Direct single-session credentials, bypassing the config's credential source. | Plaintext in the process command line — prefer the config's credential reference. |
|
||||
| `--console` | Forces the interactive console on for `run` (bare flag, no value) — see `ACDREAM_HEADLESS_CONSOLE`. | Same side effects as the environment variable; this flag always wins over it. |
|
||||
| `--help` / `-h` (or no args) | Prints usage, exits 0. | — |
|
||||
|
||||
### `AcDream.Launcher`
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ internal sealed record HeadlessCommandLine(
|
|||
string Command,
|
||||
string ConfigurationPath,
|
||||
HeadlessPathOverrides Paths,
|
||||
HeadlessDirectCredentials? DirectCredentials)
|
||||
HeadlessDirectCredentials? DirectCredentials,
|
||||
bool Console = false)
|
||||
{
|
||||
internal static HeadlessCommandLine Parse(
|
||||
IReadOnlyList<string> arguments)
|
||||
|
|
@ -23,15 +24,26 @@ internal sealed record HeadlessCommandLine(
|
|||
string? cacheDirectory = null;
|
||||
string? user = null;
|
||||
string? password = null;
|
||||
for (int index = 1; index < arguments.Count; index += 2)
|
||||
bool console = false;
|
||||
int index = 1;
|
||||
while (index < arguments.Count)
|
||||
{
|
||||
string name = arguments[index];
|
||||
// --console is a bare flag (no value token) — the interactive
|
||||
// console for the run command (see HeadlessConsoleOptions).
|
||||
if (name == "--console")
|
||||
{
|
||||
console = true;
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (index + 1 >= arguments.Count)
|
||||
{
|
||||
throw new HeadlessCommandLineException(
|
||||
"Every command option requires a value.");
|
||||
}
|
||||
|
||||
string name = arguments[index];
|
||||
string value = arguments[index + 1];
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
|
|
@ -65,6 +77,7 @@ internal sealed record HeadlessCommandLine(
|
|||
throw new HeadlessCommandLineException(
|
||||
"Unknown command option.");
|
||||
}
|
||||
index += 2;
|
||||
}
|
||||
|
||||
if (configurationPath is null)
|
||||
|
|
@ -92,7 +105,8 @@ internal sealed record HeadlessCommandLine(
|
|||
cacheDirectory),
|
||||
user is null
|
||||
? null
|
||||
: new HeadlessDirectCredentials(user, password!));
|
||||
: new HeadlessDirectCredentials(user, password!),
|
||||
console);
|
||||
}
|
||||
|
||||
private static void SetOnce(ref string? destination, string value)
|
||||
|
|
|
|||
38
src/AcDream.Headless/Configuration/HeadlessConsoleOptions.cs
Normal file
38
src/AcDream.Headless/Configuration/HeadlessConsoleOptions.cs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
namespace AcDream.Headless.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Typed resolution for the headless interactive console (docs/plans/
|
||||
/// 2026-09-07-headless-console.md). Three inputs, first match wins:
|
||||
/// the <c>--console</c> command-line flag, the
|
||||
/// <c>ACDREAM_HEADLESS_CONSOLE=1</c> environment variable, and finally a
|
||||
/// terminal-shaped default — on when stdin is a real console (an operator
|
||||
/// typing at a keyboard), off when it is redirected (a script, CI runner, or
|
||||
/// piped fixture, where a background reader thread blocked on
|
||||
/// <c>ReadLine</c> would never see input and would just sit idle). See
|
||||
/// docs/launch-options.md for the documented row this owns.
|
||||
/// </summary>
|
||||
internal static class HeadlessConsoleOptions
|
||||
{
|
||||
internal const string EnvironmentVariable = "ACDREAM_HEADLESS_CONSOLE";
|
||||
|
||||
internal static bool Resolve(
|
||||
bool commandLineFlag,
|
||||
bool standardInputIsTerminal) =>
|
||||
Resolve(
|
||||
commandLineFlag,
|
||||
Environment.GetEnvironmentVariable,
|
||||
standardInputIsTerminal);
|
||||
|
||||
internal static bool Resolve(
|
||||
bool commandLineFlag,
|
||||
Func<string, string?> environment,
|
||||
bool standardInputIsTerminal)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(environment);
|
||||
if (commandLineFlag)
|
||||
return true;
|
||||
if (environment(EnvironmentVariable) == "1")
|
||||
return true;
|
||||
return standardInputIsTerminal;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue