Skip to content

Adds doc snippet compile validation; fixes v1 API rot in agent docs#5480

Merged
tig merged 2 commits into
developfrom
feature/doc-snippet-validation
Jun 10, 2026
Merged

Adds doc snippet compile validation; fixes v1 API rot in agent docs#5480
tig merged 2 commits into
developfrom
feature/doc-snippet-validation

Conversation

@tig

@tig tig commented Jun 10, 2026

Copy link
Copy Markdown
Member

Summary

Adds Scripts/DocSnippetValidator — a Roslyn-based tool that compiles every fenced C# block in the agent-facing docs (ai-v2-primer.md, .claude/tasks/build-app.md, .claude/cookbook/common-patterns.md) against the freshly built Terminal.Gui.dll — plus a CI workflow that runs it when either the docs or the library change, so API renames break loudly instead of silently rotting the examples agents copy from.

Stacked on #5478 (based on fix/agent-doc-inconsistencies); will retarget to develop when that merges.

What the first run found

14 of 30 snippets did not compile. ai-v2-primer.md was fully green; the cookbook had substantial v1 rot. All fixed against the current API:

Doc said v2 reality
ColorScheme = Colors.ColorSchemes ["Error"] SchemeName = "Error"
new MenuItem ("New", "", action, null, null, KeyCode.N | KeyCode.CtrlMask) new MenuItem { Title = "_New", Key = Key.N.WithCtrl, Action = ... }
TileView removed — Pos/Dim panes + ViewArrangement.RightResizable
TabView / Tab TabsAdd views, Title is the tab label, Value selects
listView.SelectedItemChanged ValueChanged (IValue<int?>); SelectedItem is int?
tableView.SelectedCellChanged / SelectedRow ValueChanged (IValue<TableSelection?>), SelectedCell Point
override OnLoaded () on Runnable OnIsRunningChanged (bool)
OpenDialog.DirectoryPath, settable SaveDialog.FileName Path; FileName is read-only
ListWrapper<string> (List<string>) requires ObservableCollection<T>
int result = MessageBox.Query (...) returns int?
view.AddCommand (...) on an instance AddCommand is protected — call inside the subclass

Also of note: the compressed type index in AGENTS.md claims TableView has SelectedRow/SelectedColumn — it does not. Worth regenerating that index in a follow-up.

How it works

  • Complete compilation units compile as-is (standard usings prepended); blocks with top-level statements compile as programs.
  • Statement fragments are wrapped in a method inside a Runnable<string?> harness with common fields (app, view, button, ...) in scope; fragments that declare methods are retried as class members.
  • Blocks containing // WRONG / / are skipped automatically; <!-- snippet: ignore --> opts a block out explicitly.

Testing

dotnet run --project Scripts/DocSnippetValidator -- Terminal.Gui/bin/Debug/net10.0/Terminal.Gui.dll ai-v2-primer.md .claude/tasks/build-app.md .claude/cookbook/common-patterns.md29 compiled, 1 skipped, 0 failed (and correctly reported all 14 failures before the doc fixes).

🤖 Generated with Claude Code

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2f7956e8f6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Scripts/DocSnippetValidator/SnippetCompiler.cs
tig added a commit that referenced this pull request Jun 10, 2026
Codex review on #5480: the validator only failed on Severity==Error, so a
doc snippet using a v1-compatible [Obsolete] API (e.g. the legacy static
Application.Init) compiled "clean" — letting the exact v1 rot this
workflow prevents slip back in.

Test-first: added testdata/obsolete-api.md (an obsolete-API snippet, not
marked WRONG, excluded from the validated set) and a CI negative-test step
asserting the validator rejects it. With the old behavior the fixture
passed (red).

Fix: elevate CS0618/CS0612 to errors via specificDiagnosticOptions, and
drop the blanket `#pragma warning disable` from the wrappers (it would
otherwise suppress those very warnings; harness noise stays warnings,
which never fail). The negative test now passes (red→green).

This immediately caught real rot in the cookbook: two snippets used the
now-obsolete TextView (superseded by gui-cs/Editor's EditorView). They
were layout examples, so the incidental editor is now a plain content
View with a note pointing at EditorView. Real docs: 29 compiled, 1
skipped, 0 failed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Base automatically changed from fix/agent-doc-inconsistencies to develop June 10, 2026 14:22
Roslyn-based validator that compiles every fenced C# block in the agent
docs (ai-v2-primer.md, build-app.md, common-patterns.md) against the built
Terminal.Gui assembly, so example rot fails CI instead of misleading
readers. Statement fragments are wrapped in a Runnable<string?> harness;
blocks marked WRONG / `snippet: ignore` are skipped.

Obsolete-API use (CS0618/CS0612) is treated as a failure, not a warning,
so v1 rot like the legacy static Application.Init cannot pass as
"compiled". testdata/obsolete-api.md + a CI negative-test step assert the
validator rejects obsolete APIs. The check caught real rot fixed here:
two cookbook snippets used the obsolete TextView (now a plain content
View, pointing at gui-cs/Editor's EditorView).

Result: 29 compiled, 1 skipped, 0 failed; negative test green.

Rebased onto develop after #5478 merged (squash), keeping only this PR's
files; no overlap with the merged agent-docs lint changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@tig tig force-pushed the feature/doc-snippet-validation branch from 531b87d to 34668cf Compare June 10, 2026 14:27
The workflow built Terminal.Gui without fetch-depth:0, so GitVersion.MsBuild
failed on the shallow clone ("Repository is a shallow clone"). Match the
build-validation workflow's checkout (fetch-depth: 0).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@tig tig merged commit d939953 into develop Jun 10, 2026
15 checks passed
@tig tig deleted the feature/doc-snippet-validation branch June 10, 2026 14:41
tig added a commit that referenced this pull request Jun 12, 2026
* Fixes #5434. Track adornment redraw deltas

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Clean up adornment thickness-delta helpers

Fix indentation of the Margin.ThicknessChanged handler body and factor
the duplicated viewport-size formula out of
GetViewportForAdornmentThickness and GetViewportFrameForAdornmentThickness
into a shared GetViewportSizeForThickness helper.

No behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Bump TextMateSharp and TextMateSharp.Grammars

Bumps TextMateSharp from 2.0.3 to 2.0.4
Bumps TextMateSharp.Grammars from 2.0.3 to 2.0.4

---
updated-dependencies:
- dependency-name: TextMateSharp
  dependency-version: 2.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: TextMateSharp.Grammars
  dependency-version: 2.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Regenerate docfx Mandelbrot.gif with rendered sixel (#5471)

* Bump Spectre.Console from 0.55.2 to 0.56.0 (#5475)

---
updated-dependencies:
- dependency-name: Spectre.Console
  dependency-version: 0.56.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Fixes #5360. Cull fully occluded overlapped opaque subviews during draw

DrawSubViews() now skips drawing an Overlapped sibling when it is entirely
covered by the higher-Z opaque peers already drawn. Such a sibling produces
no visible output — every cell it would draw, including its own
RenderLineCanvas, is clipped away by the clip "holes" those peers punched in
DoDrawComplete — so skipping its Draw is output-neutral. The culled view's
NeedsDraw is cleared (mirroring a drawn-but-fully-clipped pass) so it does not
keep the SuperView perpetually dirty.

Culling is intentionally conservative — it only applies to a candidate that
is itself Overlapped, opaque (content/Border/Padding not Transparent), without
a Margin shadow, and NOT SuperViewRendersLineCanvas. The last guard is what
keeps Tabs correct: tab pages render their borders (and headers) through the
SuperView's LineCanvas painters'-algorithm composition, so they must never be
culled or their header line art would be dropped. The whole check is gated on
the presence of an Overlapped sibling, keeping the common non-overlapping draw
path zero-overhead.

Opaque coverage is the region inside a view's (transparent-by-default) Margin —
the Border frame — which matches the area DoDrawComplete excludes from the clip.

Adds OcclusionCullingTests covering: fully-occluded cull, NeedsDraw clearing,
partial coverage, transparent occluder, transparent candidate, shadowed
candidate, SuperViewRendersLineCanvas candidate, non-Overlapped candidate, the
no-Overlapped-siblings gate, output-neutrality, and a Tabs regression that
inactive pages are never culled.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Address review: don't cull TransparentMouse candidates

The cull path skips Draw()/DoDrawComplete(), which repopulates a view's
CachedDrawnRegion for ViewportSettingsFlags.TransparentMouse layers. That
region is invalidated by SetNeedsDraw(), so culling an opaque TransparentMouse
view left it with a null cache and dropped it from mouse hit-testing
(GetViewsUnderLocation blanket-removes TransparentMouse views with a null
cache) — a state divergence from the drawn-but-clipped path the cull is meant
to mirror.

Add ParticipatesInTransparentMouseHitTesting() and exclude such candidates:
the view's own ViewportSettings, plus any adornment that is TransparentMouse
with non-empty Thickness (adornment caches survive SetNeedsDraw(), but the
first draw must still populate a thick transparent-mouse adornment's cache).
Margin is TransparentMouse by default, so this only excludes views with an
actual Margin thickness — the common empty-margin overlapped view is still
culled.

Adds regression tests: TransparentMouseCandidate_IsNotCulled_AndKeepsHitRegion
(fails without the guard — CachedDrawnRegion is null) and
TransparentMouseMarginCandidate_IsNotCulled.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Fixes stale/contradictory AI agent instructions; adds agent docs lint and tuirec verification guidance (#5478)

* Fix inconsistencies in AI agent instruction files

- Local function naming: camelCase -> PascalCase in REFRESH.md and
  copilot-instructions.md (matches .editorconfig local_functions_rule,
  AGENTS.md, and event-patterns.md)
- Replace stale Tests/UnitTests references with current project names
  (UnitTestsParallelizable / UnitTests.NonParallelizable) across
  AGENTS.md, CONTRIBUTING.md, .aider.md, .cursorrules, .windsurfrules,
  copilot-instructions.md, and .claude workflows/tasks
- Replace deprecated --filter "FullyQualifiedName~" syntax with xUnit v3
  MTP --filter-method/--filter-class in copilot-instructions.md
- Remove machine-local path (D:\s\...) from AGENTS.md planning section
- build-app.md: use Accepted (post-event) for fire-and-forget handlers
  per event-patterns.md; show Accepting only for cancellation; fix
  v1-style new Button ("OK") to v2 object initializer
- build-test-workflow.md: .NET SDK 8.0 -> 10.0.100 per global.json

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Add agent docs lint, tuirec verification guidance, promote local memories

- Add Scripts/lint-agent-docs.ps1 + lint-agent-docs.yml CI workflow: fails
  when known rot patterns reappear in agent instruction files (stale test
  project names, machine-local paths, camelCase local-function guidance,
  deprecated FullyQualifiedName~ filter syntax, SDK version drift vs
  global.json). The lint immediately caught a stale .NET SDK 8.0 claim in
  CONTRIBUTING.md, now fixed.
- Wire tuirec into agent entry points (CLAUDE.md, AGENTS.md, build-app.md):
  agents can verify TUI behavior by recording with tuirec and reading the
  asciinema .cast output back as text, per Scripts/tuirec/README.md.
- Promote durable guidance from machine-specific .claude/projects/ memory
  files into shared rules (.claude/rules/logging-tracing.md and
  fragile-areas.md); untrack .claude/projects/ and gitignore it (the
  directory name encoded a local user path).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Document Windows ConPTY sixel limitation in tuirec README

Discovered while verifying the About Box fire animation: ConPTY strips
sixel DCS and the DA1 sixel handshake, so sixel content cannot be
captured in tuirec recordings on Windows (apps detect Sixel support:
False). Added to the troubleshooting table and validation checklist so
the next agent does not burn recordings rediscovering it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* tuirec README: require measuring grid-anchored sixels, not eyeballing

Agents (including me) recurrently verify the wrong invariant when checking
sixel recordings: confirming the sixel appears, or that agg rendered it
faithfully at the requested cursor cell, and calling it done. That misses
size/position errors — notably the ~4% undersize from tuirec advertising a
cell resolution that does not match agg's rendered font cell (tuirec #84).

Adds a "Verifying Placement and Size (measure - don't eyeball)" section with
the cell-calibration recipe (measure agg's real cell from a known grid
reference; reconcile against the resolution the app used; confirm the
rendered bbox covers the target region), a checklist item, a troubleshooting
row for #84, and rewrites the workflow's "visual confirm" step to require
measurement for grid-anchored content. Also states the general principle:
verify the invariant the change was meant to satisfy, not a proxy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Sync CONTRIBUTING.md TFM to net10.0; lint stale TFMs

Codex review on #5478 flagged that build-test-workflow.md cites
CONTRIBUTING.md as its source of truth, but CONTRIBUTING.md still
described the project as net8.0 (line 28) even though the Required Tools
section was updated to .NET 10 — so the declared source could revert the
fix and mislead readers onto the wrong toolchain.

Test-first: added Rule 6 to lint-agent-docs.ps1 that derives the expected
target-framework moniker from global.json's SDK major and fails on any
mismatched `net<major>.0` reference. It flagged CONTRIBUTING.md:28
(net8.0); fixed that to `C# 14 (net10.0)`. Lint now passes (32 files).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* Adds doc snippet compile validation; fixes v1 API rot in agent docs (#5480)

* Add doc snippet compile validation with obsolete-API rejection

Roslyn-based validator that compiles every fenced C# block in the agent
docs (ai-v2-primer.md, build-app.md, common-patterns.md) against the built
Terminal.Gui assembly, so example rot fails CI instead of misleading
readers. Statement fragments are wrapped in a Runnable<string?> harness;
blocks marked WRONG / `snippet: ignore` are skipped.

Obsolete-API use (CS0618/CS0612) is treated as a failure, not a warning,
so v1 rot like the legacy static Application.Init cannot pass as
"compiled". testdata/obsolete-api.md + a CI negative-test step assert the
validator rejects obsolete APIs. The check caught real rot fixed here:
two cookbook snippets used the obsolete TextView (now a plain content
View, pointing at gui-cs/Editor's EditorView).

Result: 29 compiled, 1 skipped, 0 failed; negative test green.

Rebased onto develop after #5478 merged (squash), keeping only this PR's
files; no overlap with the merged agent-docs lint changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Fix Validate Doc Snippets CI: full history for GitVersion

The workflow built Terminal.Gui without fetch-depth:0, so GitVersion.MsBuild
failed on the shallow clone ("Repository is a shallow clone"). Match the
build-validation workflow's checkout (fetch-depth: 0).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* Notify gui-cs/Editor on NuGet publish (#5483)

Dispatches `terminal-gui-published` (payload: the published SemVer) to
gui-cs/Editor after each publish. Editor's bump-terminal-gui.yml picks it
up, pins the new version, validates with its full test suites, and
republishes Editor against it - making Editor a continuous canary for TG
API churn (see Editor specs/decisions.md DEC-010).

No-op until an EDITOR_DISPATCH_TOKEN secret (PAT with repo scope on
gui-cs/Editor) is configured; Editor also polls NuGet on a 6h schedule as
a fallback, so nothing breaks without it.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* Fix publish.yml: secrets context is invalid in step if conditions

The Editor-notify guard from #5483 used `if: secrets.X != ''`, which is
not an available context for step ifs and invalidated the whole workflow
(publish run 27422643812). Mirror the secret into job-level env and gate
on that, same pattern as the TEMPLATE/clet dispatches in gui-cs/Editor.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Kevin Harder <kevin@kevinharder.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
tig added a commit that referenced this pull request Jun 22, 2026
* Release v2.4.5 (#5476)

* Fixes #5434. Track adornment redraw deltas

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Clean up adornment thickness-delta helpers

Fix indentation of the Margin.ThicknessChanged handler body and factor
the duplicated viewport-size formula out of
GetViewportForAdornmentThickness and GetViewportFrameForAdornmentThickness
into a shared GetViewportSizeForThickness helper.

No behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Bump TextMateSharp and TextMateSharp.Grammars

Bumps TextMateSharp from 2.0.3 to 2.0.4
Bumps TextMateSharp.Grammars from 2.0.3 to 2.0.4

---
updated-dependencies:
- dependency-name: TextMateSharp
  dependency-version: 2.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: TextMateSharp.Grammars
  dependency-version: 2.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Regenerate docfx Mandelbrot.gif with rendered sixel (#5471)

* Bump Spectre.Console from 0.55.2 to 0.56.0 (#5475)

---
updated-dependencies:
- dependency-name: Spectre.Console
  dependency-version: 0.56.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Kevin Harder <kevin@kevinharder.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Release v2.4.6 (#5485)

* Fixes #5434. Track adornment redraw deltas

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Clean up adornment thickness-delta helpers

Fix indentation of the Margin.ThicknessChanged handler body and factor
the duplicated viewport-size formula out of
GetViewportForAdornmentThickness and GetViewportFrameForAdornmentThickness
into a shared GetViewportSizeForThickness helper.

No behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Bump TextMateSharp and TextMateSharp.Grammars

Bumps TextMateSharp from 2.0.3 to 2.0.4
Bumps TextMateSharp.Grammars from 2.0.3 to 2.0.4

---
updated-dependencies:
- dependency-name: TextMateSharp
  dependency-version: 2.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: TextMateSharp.Grammars
  dependency-version: 2.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Regenerate docfx Mandelbrot.gif with rendered sixel (#5471)

* Bump Spectre.Console from 0.55.2 to 0.56.0 (#5475)

---
updated-dependencies:
- dependency-name: Spectre.Console
  dependency-version: 0.56.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Fixes #5360. Cull fully occluded overlapped opaque subviews during draw

DrawSubViews() now skips drawing an Overlapped sibling when it is entirely
covered by the higher-Z opaque peers already drawn. Such a sibling produces
no visible output — every cell it would draw, including its own
RenderLineCanvas, is clipped away by the clip "holes" those peers punched in
DoDrawComplete — so skipping its Draw is output-neutral. The culled view's
NeedsDraw is cleared (mirroring a drawn-but-fully-clipped pass) so it does not
keep the SuperView perpetually dirty.

Culling is intentionally conservative — it only applies to a candidate that
is itself Overlapped, opaque (content/Border/Padding not Transparent), without
a Margin shadow, and NOT SuperViewRendersLineCanvas. The last guard is what
keeps Tabs correct: tab pages render their borders (and headers) through the
SuperView's LineCanvas painters'-algorithm composition, so they must never be
culled or their header line art would be dropped. The whole check is gated on
the presence of an Overlapped sibling, keeping the common non-overlapping draw
path zero-overhead.

Opaque coverage is the region inside a view's (transparent-by-default) Margin —
the Border frame — which matches the area DoDrawComplete excludes from the clip.

Adds OcclusionCullingTests covering: fully-occluded cull, NeedsDraw clearing,
partial coverage, transparent occluder, transparent candidate, shadowed
candidate, SuperViewRendersLineCanvas candidate, non-Overlapped candidate, the
no-Overlapped-siblings gate, output-neutrality, and a Tabs regression that
inactive pages are never culled.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Address review: don't cull TransparentMouse candidates

The cull path skips Draw()/DoDrawComplete(), which repopulates a view's
CachedDrawnRegion for ViewportSettingsFlags.TransparentMouse layers. That
region is invalidated by SetNeedsDraw(), so culling an opaque TransparentMouse
view left it with a null cache and dropped it from mouse hit-testing
(GetViewsUnderLocation blanket-removes TransparentMouse views with a null
cache) — a state divergence from the drawn-but-clipped path the cull is meant
to mirror.

Add ParticipatesInTransparentMouseHitTesting() and exclude such candidates:
the view's own ViewportSettings, plus any adornment that is TransparentMouse
with non-empty Thickness (adornment caches survive SetNeedsDraw(), but the
first draw must still populate a thick transparent-mouse adornment's cache).
Margin is TransparentMouse by default, so this only excludes views with an
actual Margin thickness — the common empty-margin overlapped view is still
culled.

Adds regression tests: TransparentMouseCandidate_IsNotCulled_AndKeepsHitRegion
(fails without the guard — CachedDrawnRegion is null) and
TransparentMouseMarginCandidate_IsNotCulled.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Fixes stale/contradictory AI agent instructions; adds agent docs lint and tuirec verification guidance (#5478)

* Fix inconsistencies in AI agent instruction files

- Local function naming: camelCase -> PascalCase in REFRESH.md and
  copilot-instructions.md (matches .editorconfig local_functions_rule,
  AGENTS.md, and event-patterns.md)
- Replace stale Tests/UnitTests references with current project names
  (UnitTestsParallelizable / UnitTests.NonParallelizable) across
  AGENTS.md, CONTRIBUTING.md, .aider.md, .cursorrules, .windsurfrules,
  copilot-instructions.md, and .claude workflows/tasks
- Replace deprecated --filter "FullyQualifiedName~" syntax with xUnit v3
  MTP --filter-method/--filter-class in copilot-instructions.md
- Remove machine-local path (D:\s\...) from AGENTS.md planning section
- build-app.md: use Accepted (post-event) for fire-and-forget handlers
  per event-patterns.md; show Accepting only for cancellation; fix
  v1-style new Button ("OK") to v2 object initializer
- build-test-workflow.md: .NET SDK 8.0 -> 10.0.100 per global.json

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Add agent docs lint, tuirec verification guidance, promote local memories

- Add Scripts/lint-agent-docs.ps1 + lint-agent-docs.yml CI workflow: fails
  when known rot patterns reappear in agent instruction files (stale test
  project names, machine-local paths, camelCase local-function guidance,
  deprecated FullyQualifiedName~ filter syntax, SDK version drift vs
  global.json). The lint immediately caught a stale .NET SDK 8.0 claim in
  CONTRIBUTING.md, now fixed.
- Wire tuirec into agent entry points (CLAUDE.md, AGENTS.md, build-app.md):
  agents can verify TUI behavior by recording with tuirec and reading the
  asciinema .cast output back as text, per Scripts/tuirec/README.md.
- Promote durable guidance from machine-specific .claude/projects/ memory
  files into shared rules (.claude/rules/logging-tracing.md and
  fragile-areas.md); untrack .claude/projects/ and gitignore it (the
  directory name encoded a local user path).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Document Windows ConPTY sixel limitation in tuirec README

Discovered while verifying the About Box fire animation: ConPTY strips
sixel DCS and the DA1 sixel handshake, so sixel content cannot be
captured in tuirec recordings on Windows (apps detect Sixel support:
False). Added to the troubleshooting table and validation checklist so
the next agent does not burn recordings rediscovering it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* tuirec README: require measuring grid-anchored sixels, not eyeballing

Agents (including me) recurrently verify the wrong invariant when checking
sixel recordings: confirming the sixel appears, or that agg rendered it
faithfully at the requested cursor cell, and calling it done. That misses
size/position errors — notably the ~4% undersize from tuirec advertising a
cell resolution that does not match agg's rendered font cell (tuirec #84).

Adds a "Verifying Placement and Size (measure - don't eyeball)" section with
the cell-calibration recipe (measure agg's real cell from a known grid
reference; reconcile against the resolution the app used; confirm the
rendered bbox covers the target region), a checklist item, a troubleshooting
row for #84, and rewrites the workflow's "visual confirm" step to require
measurement for grid-anchored content. Also states the general principle:
verify the invariant the change was meant to satisfy, not a proxy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Sync CONTRIBUTING.md TFM to net10.0; lint stale TFMs

Codex review on #5478 flagged that build-test-workflow.md cites
CONTRIBUTING.md as its source of truth, but CONTRIBUTING.md still
described the project as net8.0 (line 28) even though the Required Tools
section was updated to .NET 10 — so the declared source could revert the
fix and mislead readers onto the wrong toolchain.

Test-first: added Rule 6 to lint-agent-docs.ps1 that derives the expected
target-framework moniker from global.json's SDK major and fails on any
mismatched `net<major>.0` reference. It flagged CONTRIBUTING.md:28
(net8.0); fixed that to `C# 14 (net10.0)`. Lint now passes (32 files).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* Adds doc snippet compile validation; fixes v1 API rot in agent docs (#5480)

* Add doc snippet compile validation with obsolete-API rejection

Roslyn-based validator that compiles every fenced C# block in the agent
docs (ai-v2-primer.md, build-app.md, common-patterns.md) against the built
Terminal.Gui assembly, so example rot fails CI instead of misleading
readers. Statement fragments are wrapped in a Runnable<string?> harness;
blocks marked WRONG / `snippet: ignore` are skipped.

Obsolete-API use (CS0618/CS0612) is treated as a failure, not a warning,
so v1 rot like the legacy static Application.Init cannot pass as
"compiled". testdata/obsolete-api.md + a CI negative-test step assert the
validator rejects obsolete APIs. The check caught real rot fixed here:
two cookbook snippets used the obsolete TextView (now a plain content
View, pointing at gui-cs/Editor's EditorView).

Result: 29 compiled, 1 skipped, 0 failed; negative test green.

Rebased onto develop after #5478 merged (squash), keeping only this PR's
files; no overlap with the merged agent-docs lint changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Fix Validate Doc Snippets CI: full history for GitVersion

The workflow built Terminal.Gui without fetch-depth:0, so GitVersion.MsBuild
failed on the shallow clone ("Repository is a shallow clone"). Match the
build-validation workflow's checkout (fetch-depth: 0).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* Notify gui-cs/Editor on NuGet publish (#5483)

Dispatches `terminal-gui-published` (payload: the published SemVer) to
gui-cs/Editor after each publish. Editor's bump-terminal-gui.yml picks it
up, pins the new version, validates with its full test suites, and
republishes Editor against it - making Editor a continuous canary for TG
API churn (see Editor specs/decisions.md DEC-010).

No-op until an EDITOR_DISPATCH_TOKEN secret (PAT with repo scope on
gui-cs/Editor) is configured; Editor also polls NuGet on a 6h schedule as
a fallback, so nothing breaks without it.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* Fix publish.yml: secrets context is invalid in step if conditions

The Editor-notify guard from #5483 used `if: secrets.X != ''`, which is
not an available context for step ifs and invalidated the whole workflow
(publish run 27422643812). Mirror the secret into job-level env and gate
on that, same pattern as the TEMPLATE/clet dispatches in gui-cs/Editor.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Kevin Harder <kevin@kevinharder.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Mandelbrot: fill display with image view + regenerate GIF with Kitty graphics (#5511)

* Regenerate Mandelbrot.gif with Kitty graphics rendering

The previous capture forced the Sixel raster protocol because agg could
not render Kitty graphics. tuirec v0.9.0 now defaults to Kitty graphics
and its pinned agg (v1.11.0-sixel, built on a Kitty-capable avt) renders
them, so the Mandelbrot scenario records through its preferred Kitty
path. Recorded with the released tuirec + auto-downloaded agg.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Mandelbrot: fill the display with the image view; richer zoom/pan demo

Anchor the MandelbrotImageView at (0,0) and size it Dim.Fill() so the
fractal fills the whole display region instead of a small centered box,
and move the status label to the bottom edge. Re-record the docfx GIF
with a smoother tour: a multi-step zoom into the seahorse valley, a pan
across the seahorse filaments, and a zoom back out — demonstrating the
smooth zooming and panning the larger image view makes possible.

* Scripts/tuirec: document Kitty graphics as the default raster path

tuirec v0.9.0 advertises a Kitty identity by default, so raster apps
(Mandelbrot, Images) now record via Kitty graphics, which agg
v1.11.0-sixel renders. Add a 'Raster graphics' section covering protocol
selection, how to confirm which protocol the cast captured, that the #84
cell-size mismatch is sixel-only, and a smooth zoom/pan recording tip.
Update the validation checklist and troubleshooting for Kitty + sixel.

* Scripts/tuirec: add exact one-shot recipe for Mandelbrot.gif

Capture the precise keystroke tour, flags, and the design rationale
(seahorse-valley target coords, center-anchored keyboard zoom, the
span ~1.0 / 80-iteration black-out limit, fill layout) so a future agent
can reproduce the hero GIF in one shot instead of re-deriving it.

* Scripts/tuirec: cross-platform commands + runnable verification

Address feedback from an agent that ran the guide on Linux:
- Add bash equivalents alongside PowerShell for the raster recipes,
  validation greps, and error check (the raster recipes are Linux/macOS
  only, but every snippet was PowerShell). Make the Mandelbrot recipe
  bash-primary.
- Add a fresh-container bootstrap (dotnet SDK matching global.json, Go
  install, PATH for ~/.dotnet and GOPATH/bin) and fix the Windows-only
  GOPATH PATH note.
- Give a python3/Pillow one-liner to extract a mid-zoom frame, plus the
  expected readout (Center X ~ -0.74, Y ~ 0.105, Span ~ 1.0) so the
  spot-check measures a landmark instead of a vibe.
- Soften exact payload counts to robust invariants (thousands of Kitty,
  zero sixel, ~0.9 MB) since the count drifts with timing/font-size.
- Note the '#84 font-size adjust' log line is expected and auto-corrected
  in v0.9.0, harmless for the Kitty path.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Kevin Harder <kevin@kevinharder.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
tig added a commit that referenced this pull request Jun 23, 2026
* Release v2.4.5 (#5476)

* Fixes #5434. Track adornment redraw deltas

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Clean up adornment thickness-delta helpers

Fix indentation of the Margin.ThicknessChanged handler body and factor
the duplicated viewport-size formula out of
GetViewportForAdornmentThickness and GetViewportFrameForAdornmentThickness
into a shared GetViewportSizeForThickness helper.

No behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Bump TextMateSharp and TextMateSharp.Grammars

Bumps TextMateSharp from 2.0.3 to 2.0.4
Bumps TextMateSharp.Grammars from 2.0.3 to 2.0.4

---
updated-dependencies:
- dependency-name: TextMateSharp
  dependency-version: 2.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: TextMateSharp.Grammars
  dependency-version: 2.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Regenerate docfx Mandelbrot.gif with rendered sixel (#5471)

* Bump Spectre.Console from 0.55.2 to 0.56.0 (#5475)

---
updated-dependencies:
- dependency-name: Spectre.Console
  dependency-version: 0.56.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Kevin Harder <kevin@kevinharder.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Release v2.4.6 (#5485)

* Fixes #5434. Track adornment redraw deltas

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Clean up adornment thickness-delta helpers

Fix indentation of the Margin.ThicknessChanged handler body and factor
the duplicated viewport-size formula out of
GetViewportForAdornmentThickness and GetViewportFrameForAdornmentThickness
into a shared GetViewportSizeForThickness helper.

No behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Bump TextMateSharp and TextMateSharp.Grammars

Bumps TextMateSharp from 2.0.3 to 2.0.4
Bumps TextMateSharp.Grammars from 2.0.3 to 2.0.4

---
updated-dependencies:
- dependency-name: TextMateSharp
  dependency-version: 2.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: TextMateSharp.Grammars
  dependency-version: 2.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Regenerate docfx Mandelbrot.gif with rendered sixel (#5471)

* Bump Spectre.Console from 0.55.2 to 0.56.0 (#5475)

---
updated-dependencies:
- dependency-name: Spectre.Console
  dependency-version: 0.56.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Fixes #5360. Cull fully occluded overlapped opaque subviews during draw

DrawSubViews() now skips drawing an Overlapped sibling when it is entirely
covered by the higher-Z opaque peers already drawn. Such a sibling produces
no visible output — every cell it would draw, including its own
RenderLineCanvas, is clipped away by the clip "holes" those peers punched in
DoDrawComplete — so skipping its Draw is output-neutral. The culled view's
NeedsDraw is cleared (mirroring a drawn-but-fully-clipped pass) so it does not
keep the SuperView perpetually dirty.

Culling is intentionally conservative — it only applies to a candidate that
is itself Overlapped, opaque (content/Border/Padding not Transparent), without
a Margin shadow, and NOT SuperViewRendersLineCanvas. The last guard is what
keeps Tabs correct: tab pages render their borders (and headers) through the
SuperView's LineCanvas painters'-algorithm composition, so they must never be
culled or their header line art would be dropped. The whole check is gated on
the presence of an Overlapped sibling, keeping the common non-overlapping draw
path zero-overhead.

Opaque coverage is the region inside a view's (transparent-by-default) Margin —
the Border frame — which matches the area DoDrawComplete excludes from the clip.

Adds OcclusionCullingTests covering: fully-occluded cull, NeedsDraw clearing,
partial coverage, transparent occluder, transparent candidate, shadowed
candidate, SuperViewRendersLineCanvas candidate, non-Overlapped candidate, the
no-Overlapped-siblings gate, output-neutrality, and a Tabs regression that
inactive pages are never culled.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Address review: don't cull TransparentMouse candidates

The cull path skips Draw()/DoDrawComplete(), which repopulates a view's
CachedDrawnRegion for ViewportSettingsFlags.TransparentMouse layers. That
region is invalidated by SetNeedsDraw(), so culling an opaque TransparentMouse
view left it with a null cache and dropped it from mouse hit-testing
(GetViewsUnderLocation blanket-removes TransparentMouse views with a null
cache) — a state divergence from the drawn-but-clipped path the cull is meant
to mirror.

Add ParticipatesInTransparentMouseHitTesting() and exclude such candidates:
the view's own ViewportSettings, plus any adornment that is TransparentMouse
with non-empty Thickness (adornment caches survive SetNeedsDraw(), but the
first draw must still populate a thick transparent-mouse adornment's cache).
Margin is TransparentMouse by default, so this only excludes views with an
actual Margin thickness — the common empty-margin overlapped view is still
culled.

Adds regression tests: TransparentMouseCandidate_IsNotCulled_AndKeepsHitRegion
(fails without the guard — CachedDrawnRegion is null) and
TransparentMouseMarginCandidate_IsNotCulled.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Fixes stale/contradictory AI agent instructions; adds agent docs lint and tuirec verification guidance (#5478)

* Fix inconsistencies in AI agent instruction files

- Local function naming: camelCase -> PascalCase in REFRESH.md and
  copilot-instructions.md (matches .editorconfig local_functions_rule,
  AGENTS.md, and event-patterns.md)
- Replace stale Tests/UnitTests references with current project names
  (UnitTestsParallelizable / UnitTests.NonParallelizable) across
  AGENTS.md, CONTRIBUTING.md, .aider.md, .cursorrules, .windsurfrules,
  copilot-instructions.md, and .claude workflows/tasks
- Replace deprecated --filter "FullyQualifiedName~" syntax with xUnit v3
  MTP --filter-method/--filter-class in copilot-instructions.md
- Remove machine-local path (D:\s\...) from AGENTS.md planning section
- build-app.md: use Accepted (post-event) for fire-and-forget handlers
  per event-patterns.md; show Accepting only for cancellation; fix
  v1-style new Button ("OK") to v2 object initializer
- build-test-workflow.md: .NET SDK 8.0 -> 10.0.100 per global.json

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Add agent docs lint, tuirec verification guidance, promote local memories

- Add Scripts/lint-agent-docs.ps1 + lint-agent-docs.yml CI workflow: fails
  when known rot patterns reappear in agent instruction files (stale test
  project names, machine-local paths, camelCase local-function guidance,
  deprecated FullyQualifiedName~ filter syntax, SDK version drift vs
  global.json). The lint immediately caught a stale .NET SDK 8.0 claim in
  CONTRIBUTING.md, now fixed.
- Wire tuirec into agent entry points (CLAUDE.md, AGENTS.md, build-app.md):
  agents can verify TUI behavior by recording with tuirec and reading the
  asciinema .cast output back as text, per Scripts/tuirec/README.md.
- Promote durable guidance from machine-specific .claude/projects/ memory
  files into shared rules (.claude/rules/logging-tracing.md and
  fragile-areas.md); untrack .claude/projects/ and gitignore it (the
  directory name encoded a local user path).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Document Windows ConPTY sixel limitation in tuirec README

Discovered while verifying the About Box fire animation: ConPTY strips
sixel DCS and the DA1 sixel handshake, so sixel content cannot be
captured in tuirec recordings on Windows (apps detect Sixel support:
False). Added to the troubleshooting table and validation checklist so
the next agent does not burn recordings rediscovering it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* tuirec README: require measuring grid-anchored sixels, not eyeballing

Agents (including me) recurrently verify the wrong invariant when checking
sixel recordings: confirming the sixel appears, or that agg rendered it
faithfully at the requested cursor cell, and calling it done. That misses
size/position errors — notably the ~4% undersize from tuirec advertising a
cell resolution that does not match agg's rendered font cell (tuirec #84).

Adds a "Verifying Placement and Size (measure - don't eyeball)" section with
the cell-calibration recipe (measure agg's real cell from a known grid
reference; reconcile against the resolution the app used; confirm the
rendered bbox covers the target region), a checklist item, a troubleshooting
row for #84, and rewrites the workflow's "visual confirm" step to require
measurement for grid-anchored content. Also states the general principle:
verify the invariant the change was meant to satisfy, not a proxy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Sync CONTRIBUTING.md TFM to net10.0; lint stale TFMs

Codex review on #5478 flagged that build-test-workflow.md cites
CONTRIBUTING.md as its source of truth, but CONTRIBUTING.md still
described the project as net8.0 (line 28) even though the Required Tools
section was updated to .NET 10 — so the declared source could revert the
fix and mislead readers onto the wrong toolchain.

Test-first: added Rule 6 to lint-agent-docs.ps1 that derives the expected
target-framework moniker from global.json's SDK major and fails on any
mismatched `net<major>.0` reference. It flagged CONTRIBUTING.md:28
(net8.0); fixed that to `C# 14 (net10.0)`. Lint now passes (32 files).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* Adds doc snippet compile validation; fixes v1 API rot in agent docs (#5480)

* Add doc snippet compile validation with obsolete-API rejection

Roslyn-based validator that compiles every fenced C# block in the agent
docs (ai-v2-primer.md, build-app.md, common-patterns.md) against the built
Terminal.Gui assembly, so example rot fails CI instead of misleading
readers. Statement fragments are wrapped in a Runnable<string?> harness;
blocks marked WRONG / `snippet: ignore` are skipped.

Obsolete-API use (CS0618/CS0612) is treated as a failure, not a warning,
so v1 rot like the legacy static Application.Init cannot pass as
"compiled". testdata/obsolete-api.md + a CI negative-test step assert the
validator rejects obsolete APIs. The check caught real rot fixed here:
two cookbook snippets used the obsolete TextView (now a plain content
View, pointing at gui-cs/Editor's EditorView).

Result: 29 compiled, 1 skipped, 0 failed; negative test green.

Rebased onto develop after #5478 merged (squash), keeping only this PR's
files; no overlap with the merged agent-docs lint changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Fix Validate Doc Snippets CI: full history for GitVersion

The workflow built Terminal.Gui without fetch-depth:0, so GitVersion.MsBuild
failed on the shallow clone ("Repository is a shallow clone"). Match the
build-validation workflow's checkout (fetch-depth: 0).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* Notify gui-cs/Editor on NuGet publish (#5483)

Dispatches `terminal-gui-published` (payload: the published SemVer) to
gui-cs/Editor after each publish. Editor's bump-terminal-gui.yml picks it
up, pins the new version, validates with its full test suites, and
republishes Editor against it - making Editor a continuous canary for TG
API churn (see Editor specs/decisions.md DEC-010).

No-op until an EDITOR_DISPATCH_TOKEN secret (PAT with repo scope on
gui-cs/Editor) is configured; Editor also polls NuGet on a 6h schedule as
a fallback, so nothing breaks without it.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* Fix publish.yml: secrets context is invalid in step if conditions

The Editor-notify guard from #5483 used `if: secrets.X != ''`, which is
not an available context for step ifs and invalidated the whole workflow
(publish run 27422643812). Mirror the secret into job-level env and gate
on that, same pattern as the TEMPLATE/clet dispatches in gui-cs/Editor.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Kevin Harder <kevin@kevinharder.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Mandelbrot: fill display with image view + regenerate GIF with Kitty graphics (#5511)

* Regenerate Mandelbrot.gif with Kitty graphics rendering

The previous capture forced the Sixel raster protocol because agg could
not render Kitty graphics. tuirec v0.9.0 now defaults to Kitty graphics
and its pinned agg (v1.11.0-sixel, built on a Kitty-capable avt) renders
them, so the Mandelbrot scenario records through its preferred Kitty
path. Recorded with the released tuirec + auto-downloaded agg.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Mandelbrot: fill the display with the image view; richer zoom/pan demo

Anchor the MandelbrotImageView at (0,0) and size it Dim.Fill() so the
fractal fills the whole display region instead of a small centered box,
and move the status label to the bottom edge. Re-record the docfx GIF
with a smoother tour: a multi-step zoom into the seahorse valley, a pan
across the seahorse filaments, and a zoom back out — demonstrating the
smooth zooming and panning the larger image view makes possible.

* Scripts/tuirec: document Kitty graphics as the default raster path

tuirec v0.9.0 advertises a Kitty identity by default, so raster apps
(Mandelbrot, Images) now record via Kitty graphics, which agg
v1.11.0-sixel renders. Add a 'Raster graphics' section covering protocol
selection, how to confirm which protocol the cast captured, that the #84
cell-size mismatch is sixel-only, and a smooth zoom/pan recording tip.
Update the validation checklist and troubleshooting for Kitty + sixel.

* Scripts/tuirec: add exact one-shot recipe for Mandelbrot.gif

Capture the precise keystroke tour, flags, and the design rationale
(seahorse-valley target coords, center-anchored keyboard zoom, the
span ~1.0 / 80-iteration black-out limit, fill layout) so a future agent
can reproduce the hero GIF in one shot instead of re-deriving it.

* Scripts/tuirec: cross-platform commands + runnable verification

Address feedback from an agent that ran the guide on Linux:
- Add bash equivalents alongside PowerShell for the raster recipes,
  validation greps, and error check (the raster recipes are Linux/macOS
  only, but every snippet was PowerShell). Make the Mandelbrot recipe
  bash-primary.
- Add a fresh-container bootstrap (dotnet SDK matching global.json, Go
  install, PATH for ~/.dotnet and GOPATH/bin) and fix the Windows-only
  GOPATH PATH note.
- Give a python3/Pillow one-liner to extract a mid-zoom frame, plus the
  expected readout (Center X ~ -0.74, Y ~ 0.105, Span ~ 1.0) so the
  spot-check measures a landmark instead of a vibe.
- Soften exact payload counts to robust invariants (thousands of Kitty,
  zero sixel, ~0.9 MB) since the count drifts with timing/font-size.
- Note the '#84 font-size adjust' log line is expected and auto-corrected
  in v0.9.0, harmless for the Kitty path.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Kevin Harder <kevin@kevinharder.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant