Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/adr/ADR0001V01R01-SplitConsolePlusAndPromptPlus.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# ADR0001V01R01
</div>

[ADR Index](README.md) • **Next:** [ADR0002 →](ADR0002V01R01-ImmutableCapabilityProfile.md)
[ADR Index](README.md) • **Next:** [ADR0002 →](ADR0002V01R02-ImmutableCapabilityProfile.md)

---

Expand Down
52 changes: 0 additions & 52 deletions docs/adr/ADR0002V01R01-ImmutableCapabilityProfile.md

This file was deleted.

75 changes: 75 additions & 0 deletions docs/adr/ADR0002V01R02-ImmutableCapabilityProfile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<!-- Do not remove this comment, lines and table -->
<!--
| Fields | Values |
| --- | --- |
| ADR | ADR0002V01R02 |
| Version | 01 |
| Revision | 02 |
| Status | Accepted |
| Created | 2026-07-24 |
| Changed | 2026-07-25 |
| Superseded | |
-->

<div align="center">
<img src="../../icon.png" alt="ConsolePlus" width="120" height="120" />

# ADR0002V01R02
</div>

[← ADR0001](ADR0001V01R01-SplitConsolePlusAndPromptPlus.md) • [ADR Index](README.md) • **Next:** [ADR0003 →](ADR0003V01R01-AutomaticInitializationOnFirstAccess.md)

---

# ADR0002V01R02 — Immutable capability profile

- **Status:** Accepted
- **Version:** V01 / Revision R02
- **Created:** 2026-07-24
- **Changed:** 2026-07-25 (R02 — documented the real override path; removed a dead API that
contradicted this decision)

## Context

Rendering decisions (ANSI, Unicode, color depth, interactivity) must be
consistent for the whole process lifetime. Re-detecting per call would be slow
and could produce inconsistent output if the environment appears to change.

## Decision

Detect the environment **once** and expose it as an **immutable snapshot**,
`ConsolePlus.Profile` typed as `IProfileReadOnly`. The profile describes
`ProfileName`, `IsTerminal`, `Interactive`, `SupportUnicode`, `SupportsAnsi`,
`ColorDepth`, captured culture, default/original colors and encodings. Nothing
in the public API mutates the profile after initialization.

**R02 addendum — the one supported override path, and a correction:** callers who need to
override auto-detected values do so via an optional `ConsoleProfile.json` file next to the
executable, read once in `EnvironmentUtil.CreateProfile` **before** detection and before any
downstream caching (e.g. `ConsoleWriter` caches `Profile.ColorDepth` in a `readonly` field at
construction; the ANSI-vs-NoAnsi adapter choice is also made once, at startup — see
[ADR0004V01R01](ADR0004V01R01-AnsiVsNonAnsiDriverSelection.md)). This is why a JSON-file override
works fully while a hypothetical post-init C# mutation API could not — by the time user code could
call it, the values it would change are already cached elsewhere. See
`docs/environment-detection.md` → "Override detection" for the full JSON schema.

This addendum exists because a 2026-07-25 docs audit found a public interface, `IProfileSetup`
(a fluent builder with `SupportsAnsi(AutoDetect)`, `ColorDepth(ColorSystem)`, `Apply()`, etc.), that
had **zero implementers and zero callers anywhere in the repository** — `ProfileConsole` (the
concrete class backing `IProfileReadOnly`) never implemented it, and one of its members
(`TimeMsResizeChange`) was referenced nowhere else at all. It directly contradicted this ADR's
"nothing... mutates the profile after initialization" line. It has been **deleted outright** — the
JSON mechanism above already covered everything it promised, and does so correctly (unaffected by
the caching problem a post-init API would hit). No consumer depended on it (ConsolePlus is
pre-1.0/Beta, so this is not considered a breaking change).

## Consequences

- **Positive:** stable, self-consistent rendering; detection cost paid once;
read-only contract prevents accidental capability changes mid-run; the one real override path
(`ConsoleProfile.json`) is now documented where users would look for it, and no orphaned API
contradicts the immutability guarantee.
- **Negative / trade-off:** environment changes after startup (e.g. a resize of
color support) are not reflected; acceptable because such changes are rare and
restart-scoped. Overriding via `ConsoleProfile.json` requires a restart to take effect (the file
is only read at startup) — there is no live-reload.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# ADR0003V01R01
</div>

[← ADR0002](ADR0002V01R01-ImmutableCapabilityProfile.md) • [ADR Index](README.md) • **Next:** [ADR0004 →](ADR0004V01R01-AnsiVsNonAnsiDriverSelection.md)
[← ADR0002](ADR0002V01R02-ImmutableCapabilityProfile.md) • [ADR Index](README.md) • **Next:** [ADR0004 →](ADR0004V01R01-AnsiVsNonAnsiDriverSelection.md)

---

Expand Down
2 changes: 1 addition & 1 deletion docs/adr/ADR0004V01R01-AnsiVsNonAnsiDriverSelection.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# ADR0004V01R01
</div>

[← ADR0003](ADR0003V01R01-AutomaticInitializationOnFirstAccess.md) • [ADR Index](README.md) • **Next:** [ADR0005 →](ADR0005V01R01-AnsiconLegacyWindowsSupport.md)
[← ADR0003](ADR0003V01R01-AutomaticInitializationOnFirstAccess.md) • [ADR Index](README.md) • **Next:** [ADR0005 →](ADR0005V01R02-AnsiconLegacyWindowsSupport.md)

---

Expand Down
52 changes: 0 additions & 52 deletions docs/adr/ADR0005V01R01-AnsiconLegacyWindowsSupport.md

This file was deleted.

61 changes: 61 additions & 0 deletions docs/adr/ADR0005V01R02-AnsiconLegacyWindowsSupport.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<!-- Do not remove this comment, lines and table -->
<!--
| Fields | Values |
| --- | --- |
| ADR | ADR0005V01R02 |
| Version | 01 |
| Revision | 02 |
| Status | Accepted |
| Created | 2026-07-24 |
| Changed | 2026-07-25 |
| Superseded | |
-->

<div align="center">
<img src="../../icon.png" alt="ConsolePlus" width="120" height="120" />

# ADR0005V01R02
</div>

[← ADR0004](ADR0004V01R01-AnsiVsNonAnsiDriverSelection.md) • [ADR Index](README.md) • **Next:** [ADR0006 →](ADR0006V01R01-AutoDetectTriState.md)

---

# ADR0005V01R02 — ANSICON launch (not injection) for legacy Windows

- **Status:** Accepted
- **Version:** V01 / Revision R02
- **Created:** 2026-07-24
- **Changed:** 2026-07-25 (R02 — corrected the mechanism description; the original text described
DLL injection, but the real implementation never did that)

## Context

Modern Windows (10+) supports ANSI via Virtual Terminal Processing, but
pre-Windows 10 consoles do not. Requiring users to install a third-party tool
would break the "just works" promise on legacy systems.

**R02 correction:** the original (R01) text of this ADR described the mechanism as DLL injection
(`LdrLoadDll` via `CreateRemoteThread`). A 2026-07-25 docs audit traced the real implementation in
`src/Core/LegacyAnsiBootstrapper.cs` and found no DLL injection or remote-thread APIs anywhere in
this codebase — the R01 description was inaccurate from the start (the same inaccurate claim had
also propagated into 3 hand-written docs, corrected in the same pass).

## Decision

Bundle [ANSICON](https://github.com/adoxa/ansicon) and **launch it
automatically** on legacy Windows consoles that lack native ANSI support.
`LegacyAnsiBootstrapper` runs the bundled `ansicon.exe` (matching the process
architecture, x86 or x64) via `Process.Start(..., "-p")` and waits for it to
exit — no DLL injection or remote-thread APIs are involved — providing
transparent ANSI escape-sequence support with no manual installation or
configuration.

## Consequences

- **Positive:** ANSI rendering works transparently on old Windows without user
action.
- **Negative / trade-off:** ships a native third-party executable per
architecture, which some environments/AV tooling may flag merely for being an
unfamiliar bundled binary; scoped strictly to legacy Windows where native
ANSI is absent.
2 changes: 1 addition & 1 deletion docs/adr/ADR0006V01R01-AutoDetectTriState.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# ADR0006V01R01
</div>

[← ADR0005](ADR0005V01R01-AnsiconLegacyWindowsSupport.md) • [ADR Index](README.md) • **Next:** [ADR0007 →](ADR0007V01R01-GracefulDegradation.md)
[← ADR0005](ADR0005V01R02-AnsiconLegacyWindowsSupport.md) • [ADR Index](README.md) • **Next:** [ADR0007 →](ADR0007V01R01-GracefulDegradation.md)

---

Expand Down
2 changes: 1 addition & 1 deletion docs/adr/ADR0014V01R01-LowLevelAnsiAndAlternateScreen.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# ADR0014V01R01
</div>

[← ADR0013](ADR0013V01R01-EmojiShortcodeModel.md) • [ADR Index](README.md) • **Next:** [ADR0015 →](ADR0015V01R01-GeneratedApiDocsOffLimits.md)
[← ADR0013](ADR0013V01R01-EmojiShortcodeModel.md) • [ADR Index](README.md) • **Next:** [ADR0015 →](ADR0015V01R02-GeneratedApiDocsOffLimits.md)

---

Expand Down
50 changes: 0 additions & 50 deletions docs/adr/ADR0015V01R01-GeneratedApiDocsOffLimits.md

This file was deleted.

Loading
Loading