feat(runtime): share chat commands and run login sequence

This commit is contained in:
Erik 2026-08-14 20:27:45 +02:00
parent 5535d0adac
commit 41b15efd4d
57 changed files with 1739 additions and 345 deletions

View file

@ -99,16 +99,15 @@ internal sealed record HeadlessSessionDescriptor
/// <summary>
/// Campaign LA slice LA1: plugin ids to load from the standard plugins
/// directory (<c>docs/plans/2026-08-14-launcher-campaign.md</c> LA1).
/// Absent means load every discovered plugin (today's dev behavior);
/// LA5 wires this into an actual allow-list filter. Parsed and carried
/// here now so the session-config shape is stable before LA5 lands.
/// Absent means load every discovered plugin (the developer flow);
/// explicit empty means load none. LA5 host composition consumes this
/// as the actual allow-list filter.
/// </summary>
public List<string>? Plugins { get; init; }
/// <summary>
/// Campaign LA slice LA1: ordered chat-typed strings run once the
/// session enters world. LA6 wires actual execution; parsed and carried
/// here now.
/// Campaign LA slice LA1/LA6: ordered chat-typed strings run through the
/// shared Runtime parser/router once the session enters world.
/// </summary>
public List<string>? LoginCommands { get; init; }
@ -123,8 +122,7 @@ internal sealed record HeadlessSessionDescriptor
/// <summary>
/// Campaign LA slice LA1: absolute path for this session's status-event
/// JSONL stream (<c>docs/superpowers/specs/2026-08-14-launcher-campaign-design.md</c>
/// §6). Absent means no <see cref="AcDream.Runtime.Session.SessionStatusWriter"/>
/// is constructed for this session.
/// §6). Absent selects the writer's permanent no-op mode.
/// </summary>
public string? StatusFile { get; init; }
}

View file

@ -323,8 +323,9 @@ internal static class HeadlessConfigurationLoader
/// Campaign LA slice LA1: validates the four new optional per-session
/// fields shared with the App session-config reader (see
/// <c>docs/plans/2026-08-14-launcher-campaign.md</c> LA1's pinned
/// contract). All four stay optional; only their SHAPE is checked here
/// — parsing/executing <c>plugins</c>/<c>loginCommands</c> is LA5/LA6.
/// contract). All four stay optional; this loader owns their strict
/// shape checks while LA5/LA6 host composition consumes the resulting
/// plugin allow-list and ordered login-command sequence.
/// </summary>
private static void ValidateLaunchContractFields(HeadlessSessionDescriptor session)
{