merge(vt): plain <menu> popup from the campaign branch into the slice-7 panel work (ledger union)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
commit
dbdde0783d
30 changed files with 2530 additions and 83 deletions
|
|
@ -131,3 +131,6 @@ re-review, merge to the campaign branch, then the owner's visual gate.
|
|||
- 2026-09-07 09:10 S7.3 Monsters landed on the panel worktree (`57ced0aff`, `c3b4f7862`; MossTank suite 645 → 651) — same commits as the entry above; recorded again here because the plain-menu-style branch (`cfa703065`) merged into the panel worktree afterward to pick up fix (b) before fix round A started. Fix round A (grid scaling, Profiles leftovers, 260-tall window, Advanced Options / Loot Editor as their own panels, blank trailing slots, fresh screenshots) dispatched on the same worktree after merging the plain-menu style in. S7.4–S7.6 follow.
|
||||
- 2026-09-07 fix round A landed on the panel worktree, four commits: `045cd0a19` (merge `claude/latest-main-sync-497549`, bringing the plain-`<menu>`-style fix (b) in — resolved the ledger/markup/test conflicts by keeping both sides' content), `565a33d78` (grid scaling + Profiles cleanup + popups split into their own panels), `e414b2f56` (AcDream.App.csproj's CopyMossTankPlugin* targets hardcoded mosstank.xml as the only file to copy into `plugins/AcDream.Plugins.MossTank/` — the two new popup markup files silently landed in the App's own bin root instead and would have thrown `FileNotFoundException` on load; caught before any screenshot by inspecting the build output layout, not by a test), `78b42a519` (StartVisible=true fix for both popups — `StartVisible=false` left `PluginWindowVisibilityController`'s "requested visible" axis permanently false with no shelf entry to ever call `OnShown()`, so neither popup ever rendered despite a checked/green checkbox; plus dropped each popup's now-redundant in-content title label, and repositioned both away from the overlapping (440,60) placeholder). Real DAT-font measurements (`AcDream.Cli dump-font-atlas` against the installed DAT: font 0x40000000 MaxCharHeight=16, matching VVS's own assumed row height exactly) replaced the "sy row-pitch" theory in the 07:55 lead's read — the actual fix is a translation of the columns after each overflowing caption (Options +62px, Profiles +16px), not a font-driven vertical scale. Fresh screenshots recaptured end-to-end against a live local ACE with an isolated `ACDREAM_CONFIG_DIR` (stale persisted popup window positions from earlier probe runs would otherwise have overridden the new authored defaults forever — `RetailWindowLayoutPersistence` has no revision bump wired for plugin windows). All six requested screenshots (Options/Profiles/Vitals/Monsters/both popups) confirm: no overlap, no gold buttons, no stacked New/Loot-engine/path-string leftovers, both popups open as genuinely separate windows with clean titles, and the Route/Meta/Loot-editor move-up/move-down slots render real DAT icons instead of blank buttons. MossTank suite 651 → 654 (three new pins: the two-file `SecondaryPopupPanelsFitTheirOwnBoundsAndEveryBindingResolves` theory cases + `NoButtonAnywhereUsesTheUnrenderableArrowGlyphs`); App markup/plugin/menu filter holds 237/237. Deviation carried forward: Macro/Nav CopyTo lost their only in-UI target-name entry (the deleted 3-row block was their sole source; Meta already has one on its own tab) — matches VTank's own Profiles table having no name-draft control at all, but is a real, accepted capability regression pending a future naming-UX slice. Owner's connected visual gate is the next step.
|
||||
- 2026-09-07 S7.4–S7.6 implemented on the panel worktree (base `66b070def`), three commits: `f5409530f` (S7.4 — Items' 2-column name/hands grid, Consumables' "Excluded Scarab Types" icon+text grid and "Add Selected" button, Buffs' Extra Buff Spells / Blacklisted Buff Families lists plus a shared `mosstank-buffpicker.xml` SelfBuffChoiceView-style picker popup registered the same way fix round A's two popups are), `6118062a7` (S7.5 — Route's clWP/clWPc 2-column waypoint grid, the "Follow" nav-mode display remap, `scroll="true"` on the recall menu, and a third nav image button for "Select Nearest Point"), `cc323f6a5` (S7.6 — Meta's 6-column lstMetaRules grid: delete/move-up/move-down cells plus State/Condition/Action text cells opening the existing rule editor). Deviations documented at their own binding site: Items' Hands column is session-local only (no backing wieldable-handedness data anywhere in the plugin surface); Consumables' "Add Selected" accepts any selected owned item rather than requiring VTank's own SpellComponent object-class check (no classifier surface exists for plugins); ExtraBuffSpellNames/BlacklistedBuffFamilyNames (BuffPlan.cs) add storage + UI only, not wired into `BuffPlan.Build`'s cast selection (real casting-algorithm behavior, owned by a future Campaign VT behavior slice); Route's recall menu keeps its real 4 kinds rather than VTank's 27 named recalls (needs real per-recall spell-id data); Route's "Select Nearest Point" moves the tab's own edit selection rather than VTank's live navigation cursor (no mutable cursor exposed to a plugin); Meta's delete cell is a text "X" rather than an icon (no retail DAT delete-glyph id confirmed anywhere in this codebase, unlike the established move-up/move-down `0x060028FC`/`0x060028FD` pair). Every new/changed pin (contract control count 167→177→180→186, the new `mosstank-buffpicker.xml` popup pin, six new `MossTankPanelTests` interaction tests) was shown to fail against a targeted mutation before being confirmed green. MossTank suite 654 → 660; App markup/plugin filter holds 192/192; full solution builds clean in Release. Fresh live screenshots recaptured against the same local ACE recipe fix round A established (isolated `ACDREAM_CONFIG_DIR`/`ACDREAM_DATA_DIR`, an `ACDREAM_UI_PROBE_SCRIPT` route through the five changed tabs plus the new buff picker popup) → `docs/research/2026-09-07-slice7-screenshots/` (`tab-items.png`, `tab-consumables.png`, `tab-buffs.png`, `tab-route.png`, `tab-meta.png` recaptured at 900×300; `popup-buffpicker.png` added at 940×715). All six confirm: plain (non-gold) controls throughout, no overlapping captions, the two new Consumables/Buffs grids and the buff picker popup render correctly, and the Route/Meta move icons render real DAT art. No crashes or ungraceful exits across the probe runs. S7.7 (the gate script) and the owner's connected visual gate remain.
|
||||
- 2026-09-07 09:10 S7.3 Monsters landed on the panel worktree (`57ced0aff`, `c3b4f7862`; MossTank suite 645 → 651): the 23-column grid with VTank's exact cycle lists (P −1…4; Dmg type 14 values; Ex. Vuln 9; PetDmg 10; name click deletes; arrows reorder with DEFAULT pinned). Implementer deviations for the review: Weapon/Offhand cycle MossTank's registered item roster instead of VTank's opaque weapon-type ids (MossTank models concrete owned items); the move-up/down DEFAULT guard is symmetric. Fix round A (grid scaling, Profiles leftovers, 260-tall window, Advanced Options / Loot Editor as their own panels, blank trailing slots, fresh screenshots) dispatched on the same worktree after merging the plain-menu style in. S7.4–S7.6 follow.
|
||||
- 2026-09-07 10:10 fix round A landed on the panel worktree (`045cd0a19` merge of the plain menu, `565a33d78` column shifts + Profiles cleanup + 236-tall window + popup panel files, `e414b2f56` csproj plugin-copy fix, `78b42a519` popups actually render (`StartVisible` gotcha) + fresh screenshots, `66b070def` ledger; MossTank suite 651 → 654). Owner's two complaints verified fixed on the new screenshots. Deviation for the review: Macro/Nav CopyTo lost their in-UI target-name field with the deleted block (VTank has none either). S7.4–S7.6 dispatched on the same worktree.
|
||||
- 2026-09-07 10:20 owner, live: "Drop down menus look horrible, there is also a checkmark on the text there." — the OPEN popup still draws retail art (tan gradient panel, ornate gold scrollbar, checkmark on the selected row). Plain open state (dark list rows, selected fill, plain scrollbar, no checkmark) dispatched on the plain-menu worktree; merges to the campaign branch, then into the panel worktree at fix round B.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Headless console — an interactive CLI for the bot host
|
||||
|
||||
Date: 2026-09-07
|
||||
Status: ACTIVE (owner direction 2026-09-07: "the headless client should have
|
||||
Status: CLOSED 2026-09-07 — merged `8cb284d6f`, connected proof passed (owner direction 2026-09-07: "the headless client should have
|
||||
a CLI as well. Like we have the chat loaded in headless so we can see what it
|
||||
does and we can talk via it if we want and control plugins like /moss bla or
|
||||
/say hello")
|
||||
|
|
@ -66,3 +66,159 @@ it or the lead may, it is not a visual gate.
|
|||
|
||||
## Ledger
|
||||
- 2026-09-07 planned; implementer dispatched.
|
||||
- 2026-09-07 IMPLEMENTED. The dispatch seam already existed:
|
||||
`AcDream.Runtime.Chat.ChatCommandRouter.Submit` is the SAME presentation-
|
||||
free pipeline `LoginCommandSequence` (headless) and every graphical chat
|
||||
window (`ChatWindowController`, `FloatingChatWindowController`,
|
||||
`RetailUiRuntime`) already call — no lift was needed. Added
|
||||
`HeadlessSessionHost.SubmitConsoleLine` (`Hosting/HeadlessSessionHost.cs`)
|
||||
as the one new call site, reusing the host's own retained
|
||||
`LiveChatCommandSurface`/plugin registry (now promoted from ctor locals to
|
||||
fields) instead of a second parser.
|
||||
New files: `Configuration/HeadlessConsoleOptions.cs` (typed `--console` /
|
||||
`ACDREAM_HEADLESS_CONSOLE=1` / terminal-default resolution),
|
||||
`Hosting/HeadlessConsoleInputReader.cs` (background stdin thread → FIFO
|
||||
queue, never executes handler code), `Hosting/HeadlessConsoleController.cs`
|
||||
(drains the queue on the session tick via a new `HeadlessSessionHost.
|
||||
ConsolePump` hook; owns `/quit`/`/status`), `Hosting/
|
||||
HeadlessConsoleChatFormatter.cs` + `Hosting/HeadlessConsoleRenderer.cs`
|
||||
(renders the K2 bot event stream — `IRuntimeEventObserver`, the same
|
||||
interface a bot policy subscribes — as bracket-labelled lines:
|
||||
`[Tell] Bob: hi`, `[Fellowship] …`, `[Local] …`), `Hosting/
|
||||
HeadlessConsoleChatFeedback.cs` (decorates `RuntimeChatCommandFeedback` so
|
||||
retail's transient SpewBox/`ClientLocal` interface text — which never
|
||||
touches `ChatLog`, so it never reaches the K2 event stream — also reaches
|
||||
the console). `/quit` cancels a `CancellationTokenSource` linked into the
|
||||
scheduler's run token in `HeadlessProcessHost` (the SAME graceful-exit
|
||||
path an external Ctrl+C/SIGTERM already takes); `/status` reports
|
||||
generation, position (or "unknown" without a live movement controller),
|
||||
and loaded-plugin count (no plugin today reports a richer macro-state
|
||||
string). Console only attaches for a single-session `run` (per the plan's
|
||||
"out of scope for the first cut" multi-session note); constructed AFTER
|
||||
every session's own credential resolution so the reader thread never
|
||||
races a `StandardInput`-provider password prompt on the same stream.
|
||||
Chosen console default: on when `!Console.IsInputRedirected` (a real
|
||||
operator at a terminal), off when redirected (scripts/CI/piped fixtures,
|
||||
where a blocked `ReadLine` on a background thread would just sit idle) —
|
||||
resolved once in `Program.cs`, the only place that can see the real
|
||||
`Console`.
|
||||
Deviation from the plan's illustrative example: retail's own transcript
|
||||
never prefixes Tell/Local lines with a bracket (`ChatVM.FormatEntry`
|
||||
renders "Bob tells you, ..."/"Bob says, ..." with no label) — Headless
|
||||
cannot reference `AcDream.UI.Abstractions` (the dependency-boundary
|
||||
test), so `HeadlessConsoleChatFormatter` is a deliberately DIFFERENT,
|
||||
terminal-shaped "[Label] Sender: text" rendering using the SAME channel-
|
||||
name strings (matching the plan's literal `[Tell] Bob: hi` example), not
|
||||
a byte-for-byte port of the graphical prose.
|
||||
Tests: `tests/AcDream.Headless.Tests/HeadlessConsoleTests.cs` (20 new
|
||||
tests — options resolution, command-line flag parsing, reader-thread
|
||||
ordering/never-on-reader-thread, controller drain/quit/status, chat
|
||||
formatting, and full `/say`/plain-text/plugin-verb/unknown-verb dispatch
|
||||
against a real `HeadlessSessionHost` + `FixtureSessionOperations`, no live
|
||||
server) plus the existing `LaunchOptionsDocumentationTests` (4/4 green)
|
||||
and `HeadlessDependencyBoundaryTests` (3/3 green, unchanged — Headless
|
||||
still references only `AcDream.Runtime`). Every test in this batch was
|
||||
mutation-checked to fail before the corresponding production line existed
|
||||
(see the implementer's final report for the specific mutations run:
|
||||
skipping the interface-text callback, skipping `_quitRequested.Cancel()`,
|
||||
forcing `TryHandlePluginCommand` to always return false, dropping the
|
||||
reader thread's `Enqueue`, and swapping `ChatChannelKind.Say` for `.Tell`
|
||||
in `SubmitConsoleLine`).
|
||||
Suites: `dotnet test tests/AcDream.Headless.Tests -c Release` → 193
|
||||
passed / 1 pre-existing failure (`LinuxRejectsGroupOrOtherCredentialPermissions`,
|
||||
a Linux-only lane test that cannot run on this Windows host — unrelated
|
||||
to this change) / 194 total. `dotnet test tests/AcDream.Runtime.Tests -c
|
||||
Release` → 1891/1891 passed. `dotnet test tests/AcDream.App.Tests -c
|
||||
Release --filter "FullyQualifiedName~Chat|FullyQualifiedName~Command|
|
||||
FullyQualifiedName~LaunchOptions"` → 414 passed / 2 pre-existing failures
|
||||
(`ChatIndicatorButtonLiveMountProbeTests`/`OptionsPanelLiveMountProbeTests`
|
||||
— both gated on `ACDREAM_PROBE_LIVE_MOUNT=1`, a manual live-DAT probe lane,
|
||||
unrelated to this change) / 3 skipped / 419 total. `dotnet build
|
||||
AcDream.slnx -c Release` green throughout.
|
||||
|
||||
- 2026-09-07 FIX ROUND (Opus review, APPROVE-WITH-FIXES). S1: `ACDREAM_
|
||||
HEADLESS_CONSOLE=0` now disables the console even when stdin is a real
|
||||
terminal — the prior `== "1"` test let `"0"` silently fall through to the
|
||||
terminal-shaped default; the flag is now the sixth entry in
|
||||
`LaunchOptionsDocumentationTests.DefaultOnBehaviorFlags` (a default-on
|
||||
behavior with an A/B off-switch, once set at all, like
|
||||
`ACDREAM_RETAIL_CHASE`). S2: the reader-thread pin is now falsifiable — a
|
||||
fixture `TextReader` records the actual thread id `ReadLine` ran on, and a
|
||||
new test asserts the controller's submit callback runs on neither that
|
||||
thread nor any other unexpected one, only the `DrainDue` caller's. S3: one
|
||||
`HeadlessProcessHost` end-to-end test proves a console line reaches the
|
||||
session's real `SubmitConsoleLine` pipeline and `/quit` returns
|
||||
`HeadlessExitCode.Success`. S4: `HeadlessConsoleController.Handle` now
|
||||
wraps `_submit` in try/catch (mirroring `LoginCommandSequence.DrainDue`)
|
||||
and prints a line for `UnknownCommand`/`Dropped`, so a console typo can
|
||||
never escape into the scheduler's per-session quarantine catch. S5:
|
||||
deleted the per-call `HeadlessConsoleChatFeedback` decorator — it only
|
||||
ever saw text produced by the console's OWN `SubmitConsoleLine` calls.
|
||||
The new `HeadlessConsoleSpewBoxPump` polls the shared `SpewBoxState` on
|
||||
the console's own per-tick pump instead, the SAME seam the graphical
|
||||
overlay's `SpewBoxController.Tick` reads, so server- and plugin-driven
|
||||
`ClientLocal` interface text prints too. S6: `Program.cs` now resolves
|
||||
`standardOutputIsTerminal` next to the stdin probe and threads it through
|
||||
`HeadlessEntryPoint.Run` → `HeadlessProcessHost`, which no longer reads
|
||||
`System.Console.IsOutputRedirected` itself. S7: a multi-session process
|
||||
launched with `--console` now reports `_diagnostics.Message("console",
|
||||
"single-session only")` instead of silently skipping console attachment.
|
||||
N1: corrected two stale dispatch-order doc comments
|
||||
(`HeadlessSessionHost.SubmitConsoleLine`, `HeadlessConsoleController`'s
|
||||
class remarks) to the real `ChatCommandRouter.Submit` order: retail's
|
||||
client-command catalog, local `/help`, plugin verbs, the unregistered-
|
||||
channel-tag fallback, an explicit server command, then plain chat. N2:
|
||||
`HeadlessCommandLine.Console` renamed to `ConsoleEnabled`. N3: `validate`
|
||||
mode now rejects `--console` outright rather than silently ignoring it.
|
||||
N4: **`/status` and `/quit` are console-intercepted verbs — they never
|
||||
reach `ChatCommandRouter`, unlike `@status`, which is a real server
|
||||
command and still passes through untouched.** N5: `HeadlessConsoleRenderer`
|
||||
now dims only lifecycle/command/portal lines; chat and interface text
|
||||
print at the terminal's default weight.
|
||||
Every new/changed test was shown to fail first against a targeted
|
||||
mutation of the corresponding production code (see each commit's own
|
||||
body for the specific mutation) before the fix landed; one commit per
|
||||
item, all with `Co-Authored-By: Claude Fable 5.1`.
|
||||
Suites (Release): `dotnet test tests/AcDream.Headless.Tests` → 207
|
||||
passed / 1 pre-existing Linux-lane failure
|
||||
(`LinuxRejectsGroupOrOtherCredentialPermissions`) / 208 total (up from
|
||||
193/1/194 before this round — 14 new/changed tests). `dotnet test
|
||||
tests/AcDream.App.Tests --filter "FullyQualifiedName~LaunchOptions"` →
|
||||
4/4 passed, including the corrected `OnlyTheSixProductBehaviorFlagsDefaultOn`
|
||||
(renamed from Five). `dotnet build AcDream.slnx -c Release` green
|
||||
throughout.
|
||||
|
||||
### Connected proof recipe (owner runs; NOT run by the implementer)
|
||||
|
||||
Against a running local ACE at `127.0.0.1:9000` with MossTank loaded for
|
||||
the second half:
|
||||
|
||||
```powershell
|
||||
$env:ACDREAM_DAT_DIR = "$env:USERPROFILE\Documents\Asheron's Call"
|
||||
dotnet run --project src\AcDream.Headless\AcDream.Headless.csproj --no-build -c Release -- `
|
||||
run --config <path-to-a-one-session-config.json> `
|
||||
-user testaccount -password testpassword --console
|
||||
```
|
||||
|
||||
The referenced config's one session should target character `+Acdream`
|
||||
(server guid `0x5000000A`) against `127.0.0.1:9000`, an `idle` bot policy,
|
||||
and (for the second half) the MossTank plugin id under `plugins`. Once the
|
||||
console prints `entered world`:
|
||||
|
||||
1. Type `/say hello` and press Enter — expect the SAME line ACE echoes back
|
||||
to any other observer (a retail client or a second acdream session
|
||||
watching `+Acdream`) to also print `[Local] You: hello` in this console
|
||||
(the server's own HearSpeech echo, rendered through the normal chat
|
||||
event stream).
|
||||
2. Type `/status` — expect a line with `generation=`, `position=` (a real
|
||||
cell/local-frame triple once in world), and `plugins=N loaded`.
|
||||
3. With MossTank loaded, type `/vt start` (or whatever verb MossTank
|
||||
registers) — expect MossTank's own handler to run (check its own
|
||||
status/log output) and confirm NOTHING was sent to the wire for that
|
||||
line (no `@vt` server command).
|
||||
4. Type `/quit` — expect a graceful ACE logout (same as the existing
|
||||
Ctrl+C behavior) and the process to exit 0.
|
||||
|
||||
This is not a visual gate; the owner (or the lead) runs it opportunistically
|
||||
before considering the plan CLOSED.
|
||||
- 2026-09-07 narrow re-check: all twelve fix items CLOSED; MERGE-READY. Merged into the campaign branch at `8cb284d6f`; the unknown-verb pin re-targeted to the chat scroll after AD-124 (`074a1561b`). **Connected proof PASSED (lead, 2026-09-07):** `acdream-headless run --config <one idle session, +Acdream> --console` with scripted stdin — `/say hello` → the server's echo printed as `[Local] You: hello`; `/status` → `generation=1 position=unknown plugins=0 loaded` (idle policy has no movement controller); `/quit` → `[session] graceful logout confirmed`, exit 0. The MossTank half (`/vt start`) is owed with slice 2's autostart work. Follow-ups filed as #489 (SpewBox growth without a console; polish; and the JSON diagnostics stream interleaving with chat lines in console mode — the console should quiet or redirect it). Status: CLOSED.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue