Repository navigation
Conversation
tony
force-pushed
the
example-style
branch
2 times, most recently
from
October 4, 2026 14:27
f76db42 to
61f707c
Compare
This was referenced Oct 4, 2026
tony
force-pushed
the
example-style
branch
5 times, most recently
from
October 4, 2026 18:18
27250d4 to
1709964
Compare
tony
added a commit
to libtmux/libtmux-cxx
that referenced
this pull request
Oct 4, 2026
why: Examples render in fixed-width boxes on libtmux.org. Measured there in Chrome, Firefox and WebKit, a code box holds 78 columns at a 1024 px viewport and 99 at 1440 px, so a line near the repository's 88-column limit scrolls sideways on a laptop-width window; libtmux/docs#101 sizes the code font so 80 fit from 1024 px up. The nested config relies on clang-format 18 (CI installs clang-format-18 in the pinned toolchain step), which reads the nearest .clang-format and inherits the parent through InheritParentConfig: https://github.com/llvm/llvm-project/blob/llvmorg-18.1.3/clang/docs/ClangFormatStyleOptions.rst#L178 ColumnLimit is documented at: https://github.com/llvm/llvm-project/blob/llvmorg-18.1.3/clang/docs/ClangFormatStyleOptions.rst#L2981 The root config sets ColumnLimit 88 and the other style keys: https://github.com/libtmux/libtmux-cxx/blob/81506a5e145af4fae8956d2f07310648d75c554d/.clang-format Rejected editing the root .clang-format: library, tests and apps keep 88, and only code a reader sees needs the narrower limit. Rejected // clang-format off around long lines: it hides the lines from the formatter instead of fixing them. Rejected a per-file --style={ColumnLimit: 80} flag in CI: the editor and a local clang-format would disagree with CI. what: - Add examples/.clang-format inheriting the parent config with ColumnLimit 80 - Reformat every example with clang-format-18 -i --style=file on each examples/**/*.cpp and *.hpp; CI's clang-format check reads the nested file - Re-sync the README regions with python3 tools/docs/check_readme.py --fix
tony
added a commit
to libtmux/libtmux-dotnet
that referenced
this pull request
Oct 4, 2026
why: Nothing stopped an example from growing past the width readers see. Code blocks on libtmux.org scroll sideways (overflow-x: auto) at 14 px IBM Plex Mono, and measured in Chrome, Firefox and WebKit they hold 99 columns at 1440 px and 78 at 1024 px; libtmux/docs#101 sizes the code font so 80 fit from 1024 px up. Run against origin/master, this checker and config report 691 lines over 80 in 67 files, across Markdown pages, examples, project files and doc comments; the previous commits fix all but 5 MSBuild property lines, which stay allowed because MSBuild keeps whitespace inside property text. The same checker is used by every libtmux port, so the rule reads the same in each. It reads .github/example-width.toml, checks fenced code in Markdown, whole example sources and code inside doc comments, and skips output, hidden lines and lines that are only a URL. Untagged Markdown fences count as code, so output fences are tagged `text`; MyST `{code-block}` tags are read; East Asian wide characters count as two columns. The config is validated: an unknown key, a glob that matches no tracked file, an exclusion that matches no checked file, or an `[[exclude]]` or `[[allow]]` entry without a reason fails, as does an allow entry that no longer matches a line. allow_ceiling must equal the number of allow entries, so the list grows only through a reviewed change to that number. The config records the digests of the checker and of the shared WRITING.md text, so a local edit to either fails until every port changes together. `--self-test` plants a wide line and a stale entry and requires the checker to report both; failures are also emitted as GitHub `::error` annotations. Three rules keep the gate from going stale. Every tracked file under a directory named examples (any case) must be selected by `markdown`, `sources` or `doc_comments`, or matched by an `[[exclude]]` with a reason, so a new example cannot slip past unchecked. AGENTS.md must link WRITING.md at the last level-1 or level-2 heading above the shared markers. The failure summary ends by saying to fix a wide line by changing the code, not the line breaks, with the WRITING.md anchor. Alternatives considered: - An advisory report: nothing fails, so the count drifts back up. - A one-time cleanup with no gate: undone by the next example edit. - A Markdown linter's line-length rule: cannot tell output and hidden lines from code, or carry an allowlist with reasons. what: - Add eng/docs/check_example_width.py - Add .github/example-width.toml over every *.md file, every C# and F# source and every csproj and fsproj under examples/, examples/api/ NuGet.config, and doc comments under src/ - Exclude with a reason each: decision records, recorded benchmark runs, the generated F# reference, the fsdocs template, NuGet lock files under examples/ and the JSON index examples/api/manifest.json - Allow seven lines with allow_ceiling = 7: the Bad example in WRITING.md's port block, and six MSBuild property elements in project files, whose text keeps any whitespace added to wrap it - Record shared_digest and checker_digest from `--digest` - Run `--self-test` and the check in the build job after F# formatting - Document both commands in CONTRIBUTING.md beside the other gates
tony
added a commit
to libtmux/libtmux-go
that referenced
this pull request
Oct 4, 2026
why: gofumpt never wraps a line, so example programs ran to 150 columns and scrolled sideways in README code blocks. In Chrome, Firefox and WebKit, libtmux.org shows a code block 78 columns wide at a 1024 px viewport and 99 at 1440 px, so a 150-column line needs a horizontal scrollbar at every common width; libtmux/docs#101 sizes the code font so 80 fit from 1024 px up. golangci-lint v2.13.1 already bundles golines v0.15.0: https://github.com/golangci/golangci-lint/blob/v2.13.1/go.mod#L69 with a max-len setting (default 100, tab-len 4): https://github.com/golangci/golangci-lint/blob/v2.13.1/.golangci.reference.yml#L4790-L4796 golines wraps at that width and treats a tab as tab-len columns: https://github.com/golangci/golines/blob/v0.15.0/README.md#L57-L60 `golangci-lint run` enforces enabled formatters like gofumpt, so the width gate needs no new pin or CI step. Alternatives considered: - Run golines as a separate tool: a second pin that can drift from the linter's bundled version. - Enable the lll linter: it reports a long line but cannot wrap it. - Keep shorten-comments on: it would split the `// docs:<name>` marker lines the README generator reads whole, so it stays off. The root module keeps gofumpt alone. Formatter exclusions apply to every formatter at once, so they cannot scope golines to the example_test.go files there. Those files get their own check in a later commit. what: - Enable golines at max-len 80, tab-len 4 in examples/.golangci.yml - Reformat the examples module with `golangci-lint fmt ./...` (v2.13.1), run in examples/ - Regenerate the README regions quoted from those programs with `go generate ./...` in tmux/ - Hand-written rewrites of the breaks that read badly follow, one commit per example
tony
added a commit
to libtmux/libtmux-go
that referenced
this pull request
Oct 4, 2026
why: golines wraps Go source in the examples module and nothing else. Three surfaces a reader sees stayed unchecked. On the tree right after golines ran, this checker and config report 255 lines over 80 columns: 247 on those surfaces, and 8 inside the examples module that golines cannot break: - The Example functions in the tmux, mcp, and tmuxq modules, which render on pkg.go.dev. The root module cannot scope golines to example_test.go files: a formatter exclusion applies to every formatter at once. https://github.com/golangci/golangci-lint/blob/v2.13.1/.golangci.reference.yml#L4806-L4825 - Fenced code in README files, which golines never reads. - Code in doc comments, such as the ScriptedTmux snippet. In Chrome, Firefox and WebKit, libtmux.org shows a code block 78 columns wide at a 1024 px viewport and 99 at 1440 px; libtmux/docs#101 sizes the code font so 80 fit from 1024 px up. golines wraps at max-len with tabs counted as tab-len columns, which is the same measure the checker uses: https://github.com/golangci/golines/blob/v0.15.0/README.md#L57-L60 The checker is the one script every libtmux port uses, so the rule reads the same in each. It ships with `--self-test`, which plants a wide line and fails unless the checker reports it, then fails if an allowed line is reported or a stale allow entry is not, so CI runs it first. It also fails on a config that cannot work: an unknown key, an exclude glob that matches no checked file, an allow entry without a reason, or an allow_ceiling that differs from the number of allow entries. It fails on a tracked file under a directory named `examples` that no pattern selects and no exclude names, so a new example file cannot go unread, and on an AGENTS.md that lacks a link to the WRITING.md heading above the shared section. Its failure summary points to the fix: change the code, not the line breaks. It reads an untagged Markdown fence as code, so output fences are tagged `text`, counts East Asian wide characters as two columns, and exempts only a line that is just a URL after an optional comment, list, or quote marker. Alternatives considered: - The lll linter: it reads neither Markdown fences nor doc comments, and counts a tab as one column unless tab-width is set. https://github.com/golangci/golangci-lint/blob/v2.13.1/.golangci.reference.yml#L2211-L2218 - Enable golines in the root module: it would also rewrap library code that is not an example. - Rewrap by hand and trust review: nothing stops the next example from scrolling sideways again. what: - Add internal/tools/check_example_width.py, run with Python 3 and its standard library only - Add .github/example-width.toml: every Markdown page, the files the check reads (example programs, tests, and the examples module's go.mod and .golangci.yml, which a reader copies), one exclude for examples/LICENSE, which is license text, the checker and shared-text digests, and four allowed lines, each with a reason and written with its raw leading tab: two `// docs:<name>` marker lines the README generator reads whole, one `// Output:` line a test compares, and the wide Bad line in the WRITING.md port block - Set allow_ceiling to the number of allow entries - Run the self-test and then the check as a step of the `generated` job in tests.yml - Document the command in CONTRIBUTING.md beside the other gates
tony
added a commit
to libtmux/libtmux-julia
that referenced
this pull request
Oct 4, 2026
why: Example programs render in fixed-width code boxes on libtmux.org that scroll sideways past a width. Measured there in Chrome, Firefox and WebKit, a code block shows 78 columns at a 1024 px viewport and 99 at 1440 px; libtmux/docs#101 sizes the code font so 80 fit from 1024 px up. The format phase of dev/check-quality.jl used margin 92 for every file, so the examples passed while running wider than the box. JuliaFormatter 2.14.0 format_text reads no .JuliaFormatter.toml: only the file-walking format() entry point looks one up, and dev/check-quality.jl calls format_text. A config file would therefore not change the gate, and the margin has to come from the check itself. Sources, pinned to the v2.14.0 tag: - format_text and its keyword options: https://github.com/domluna/JuliaFormatter.jl/blob/v2.14.0/src/packagedef.jl#L120-L165 - format() is the only caller that merges .JuliaFormatter.toml: https://github.com/domluna/JuliaFormatter.jl/blob/v2.14.0/src/packagedef.jl#L236-L252 - margin option, default 92: https://github.com/domluna/JuliaFormatter.jl/blob/v2.14.0/docs/src/formatting_options.md#L562-L566 - config file lookup and precedence: https://github.com/domluna/JuliaFormatter.jl/blob/v2.14.0/docs/src/config.md Alternatives considered: - .JuliaFormatter.toml in examples/: ignored by format_text. - Margin 80 for all Julia files: reflows src/ and test/ code that readers never see in a code box. - Width check only, no formatter margin: the formatter would rejoin any hand-broken line that fits 92, so the check and formatter would disagree. what: - Add format_margin in dev/check-quality.jl: margin 80 for any path under an examples/ directory, 92 for all other Julia files. - Pass that margin to format_text in the format phase. - Run JuliaFormatter 2.14.0 with DefaultStyle, indent 4, margin 80, format_docstrings=false and whitespace_in_kwargs=false over the five example programs that the margin changes. The doc pages read these files at build time, so no copy needs a sync. - Verified with dev/check-quality.jl format (132 files pass).
tony
added a commit
to libtmux/libtmux-julia
that referenced
this pull request
Oct 4, 2026
why: Code a reader sees on libtmux.org scrolls sideways past 78 columns at a 1024 px viewport and 99 at 1440 px, measured in Chrome, Firefox and WebKit on the rendered site; libtmux/docs#101 sizes the code font so 80 fit from 1024 px up. JuliaFormatter bounds only Julia source: it does not format Markdown, and format_docstrings is off in dev/check-quality.jl, so fences in READMEs, docs pages and docstrings can grow wide while the format phase stays green. Run against origin/master, this checker reports every line over 80 in those surfaces, and the commits before this one fix them all. Sources, pinned to the JuliaFormatter v2.14.0 tag: - format_docstrings defaults to false, and format_text is the only entry point the format phase calls: https://github.com/domluna/JuliaFormatter.jl/blob/v2.14.0/docs/src/formatting_options.md#L378-L382 https://github.com/domluna/JuliaFormatter.jl/blob/v2.14.0/src/packagedef.jl#L120-L165 Alternatives considered: - Formatter margin alone: cannot see Markdown fences or docstrings. - A generic Markdown line-length linter: it checks prose and tables, and cannot skip program output, hidden setup lines or a one-word URL line, so it flags text no author can wrap. - A Julia-only check: the shared checker serves every libtmux port and needs only Python 3.11 and no Julia toolchain. what: - Add dev/check_example_width.py, the checker shared by every libtmux port, with a self-test that plants a wide line, an allowed line and a stale allow entry. It also fails on unknown config keys, globs that match no tracked file and allow entries without a reason; it exempts only URL-only lines, checks untagged Markdown fences as code, reads MyST {code-block} tags, counts East Asian wide characters as two columns, and compares copied formatter configs with the root. It prints GitHub ::error annotations and a --digest of itself and the shared WRITING.md section. - Add .github/example-width.toml: every tracked Markdown file via **/*.md, example programs and the workspace YAML under examples/ directories, and docstring fences. Every tracked file under an examples directory must be selected or excluded, and AGENTS.md must link WRITING.md. The one [[exclude]] covers docs/generated/**, generator output a reader never copies from. The one [[allow]] is the Bad line in WRITING.md's port block, counted by allow_ceiling. checker_digest and shared_digest record the output of python3 dev/check_example_width.py --digest; the second covers the shared WRITING.md section, so a local edit to it fails the check. - Run the self-test and the check in the matrix job of the Julia workflow, and document both commands in CONTRIBUTING.md. - Verified with the self-test and the check on this tree.
tony
added a commit
to libtmux/libtmux-rs
that referenced
this pull request
Oct 4, 2026
why: Code blocks on libtmux.org scroll sideways past a fixed width: measured in Chrome, Firefox and WebKit, a block shows 78 columns at a 1024 px viewport and 99 at 1440 px (a phone scrolls anyway). The repository-wide max_width = 100 therefore hid a horizontal scrollbar in every example a reader opens at laptop width. libtmux/docs#101 sizes the code font so 80 fit from 1024 px up, and 80 is the width the other libtmux ports hold their examples to. rustfmt reads the nearest rustfmt.toml walking up from each file, so a config in each examples directory narrows only the examples while src/ keeps 100. cargo fmt --all and editors both honour it, with no extra flag to forget: - max_width: https://github.com/rust-lang/rust/blob/1.97.1/src/tools/rustfmt/Configurations.md#L1937 - config lookup: https://github.com/rust-lang/rust/blob/1.97.1/src/tools/rustfmt/Configurations.md#L3 Verified with rustfmt 1.9.0-stable (rust 1.97.1). Alternatives considered: - A root max_width = 80: reformats all of src/ for a rendering limit that only examples have. - A --config max_width=80 flag in the justfile: editors and a bare cargo fmt would disagree with CI. - #[rustfmt::skip] per item: hand-wrapped code drifts and is never checked. what: - Add a rustfmt.toml with max_width = 80 to each crates/*/examples directory, copying the root settings otherwise - Reformat the examples with cargo fmt --all - End the match-arm println! calls in recover.rs with a semicolon, which the reformat turned into block-less arms and clippy's semicolon_if_nothing_returned rejects
tony
added a commit
to libtmux/libtmux-ruby
that referenced
this pull request
Oct 4, 2026
why: Examples render in fixed-width boxes that scroll sideways, and 80 columns fits a libtmux.org code block in a laptop-width window once libtmux/docs#101 sizes the code font to fit (78 columns at 1024 px in Chrome without it). syntax_tree holds program source under examples/ to 80, but README and docs code blocks, and comments that no formatter wraps, were unchecked. Before the formatter and example commits, a scan found 170 lines over 80. One checker serves every libtmux port, so the rule behaves the same everywhere: - scripts/check_example_width.py is stdlib-only Python with doctests and a --self-test that plants a wide line, an allowed line and a stale allow entry, so the gate can be shown to fail. - An allow entry names the exact line and a reason; an entry that no longer matches, or has no reason, fails, so the list only shrinks. - The config is validated: an unknown key or a glob that matches no tracked file fails. - Only a line that is a URL is exempt. An untagged Markdown fence counts as code (tag output `text`); rustdoc `# ` lines and MyST `{code-block}` tags are read; East Asian wide characters count as two columns. - A `[[formatter_copies]]` entry requires a copied formatter config to equal its root except lines naming its `key`. - Findings emit GitHub `::error` annotations; `--digest` prints the checker and shared-text hashes. Rejected: - Extending each port's existing checker: thirteen implementations with mismatched coverage. - An advisory report: no enforcement, and the backlog regrows. - Ruby-only RuboCop Layout/LineLength: splits heredoc calls and cannot read Markdown fences. Source, pinned: tomllib is in the standard library from Python 3.11 (https://docs.python.org/3.11/library/tomllib.html); ubuntu-24.04 runners ship Python 3.12. what: - Add scripts/check_example_width.py - Add .github/example-width.toml: every Markdown file (`**/*.md`), the example programs and the workspace file under examples/ (`*.rb`, `*.yaml`), one allow entry for the Bad example in WRITING.md, and the checker and shared-text digests from --digest - Exclude examples/manifest.json: its output strings are compared byte for byte by the example tests, so its lines cannot be rewrapped - Run the self-test and the check in the style CI job - Fail a tracked file under any directory named examples that is neither checked nor excluded, so a new example cannot go unread - Document both commands in CONTRIBUTING
tony
added a commit
to libtmux/libtmux-swift
that referenced
this pull request
Oct 4, 2026
why: Examples render in fixed-width boxes that scroll sideways. In Chrome, Firefox and WebKit a code block on libtmux.org fits 78 columns at a 1024 px viewport and 99 at 1440 px, so a line past 80 scrolls on a laptop-sized window; libtmux/docs#101 sizes the code font so 80 fit from 1024 px up. The repository .swift-format allows 100: https://github.com/libtmux/libtmux-swift/blob/196ffbb47b3339f6a567389329e3af3d87259030/.swift-format#L5 which is also swift-format's default: https://github.com/swiftlang/swift-format/blob/swift-6.2.4-RELEASE/Documentation/Configuration.md?plain=1#L20-L25 swift-format reads the .swift-format nearest each file, starting in the file's own directory and walking up: https://github.com/swiftlang/swift-format/blob/swift-6.2.4-RELEASE/README.md?plain=1#L202-L207 so a copy under Examples/ narrows the examples and leaves Sources/, Tests/ and Benchmarks/ at 100. The CI lint step already passes Examples as a path, so it picks the new file up unchanged. The toolchain is the 6.2.4 pin in .mise.toml: https://github.com/libtmux/libtmux-swift/blob/196ffbb47b3339f6a567389329e3af3d87259030/.mise.toml#L2 Alternatives considered: - lineLength 80 in the root file: reflows the library, its tests and benchmarks for a limit only the examples need. - --configuration on every invocation: the file system is no longer searched, so a bare `swift format` in an editor or by hand disagrees with CI. - Hand-wrapping without a config: the 100-column formatter joins the lines again and `lint --strict` fails. what: - Add Examples/.swift-format, the root file with lineLength 80 - Run `swift format format --in-place --recursive Examples` with the pinned 6.2.4 formatter: 29 files changed, 149 insertions and 66 deletions - Re-copy the README and DocC snippets that the reformat drifted from Examples/ so Scripts/check_examples.py still passes - State the 80-column limit under Examples/ in CONTRIBUTING.md
why: libtmux.org code blocks scroll sideways at laptop widths. The git remote and fetch lines of the setup recipe ran to 90 and 94, and the AggregateError guard in workspace.ts to 88. what: - Continue the remote URL and the 40-character revision on lines of their own after a backslash; neither token can break, and each fits - Put the thrown AggregateError in a braced block in workspace.ts - Update the workspace.ts sha256 and the shellRecipe string in product-examples.json The runner in scripts/check-example-prose.py does not cover product pages, and WRITING.md names no script for them. Ran the displayed recipe by hand: a fresh directory, the page's package.json and workspace.ts saved from the page, then each console command in order with bun 1.4.2 and the tmux under test first on PATH. - tmux 3.2a: tmux -V "tmux 3.2a", every command exit 0, prints "built: 2 windows" and "editor: 2 panes" - tmux 3.7c: tmux -V "tmux 3.7c", every command exit 0, same output - Source revision 3fe1ca654b81b8cbf4a13b777a001a3298c87a6f - complete-examples.test.ts: 170 passed
why: libtmux.org code blocks scroll sideways at laptop widths, and the
deadline line in capture.cpp ran to 85.
what:
- Name the clock once with a using alias and build the deadline and the
loop test from it
- Update the capture.cpp sha256 in capture-examples.json; the shell
recipe is unchanged
Native run, from the repository root:
python3 scripts/check-example-prose.py \
--example capture \
--port cxx \
--output-dir <new directory>
- tmux 3.2a first on PATH: tmux -V "tmux 3.2a", exit 0, passed
- tmux 3.7c first on PATH: tmux -V "tmux 3.7c", exit 0, passed
- Both runs build with Clang 18.1.3 and CMake 3.28.3 and print
"libtmux capture ready"
- Source revision 393d4b0ad666f18a6581f1eb281741a75a7503f0
- complete-examples.test.ts: 170 passed
why: libtmux.org code blocks scroll sideways at laptop widths, and the
socket guard in connect.cpp ran to 91.
what:
- Put the thrown runtime_error in a braced block under the guard
- Update the connect.cpp sha256 in attach-examples.json; the shell
recipe is unchanged
Native run, from the repository root:
python3 scripts/check-example-prose.py \
--example attach \
--port cxx \
--output-dir <new directory>
- tmux 3.2a first on PATH: tmux -V "tmux 3.2a", exit 0, passed
- tmux 3.7c first on PATH: tmux -V "tmux 3.7c", exit 0, passed
- Both runs build with Clang 18.1.3 and CMake 3.28.3, print work and
leave has-session passing
- Source revision 393d4b0ad666f18a6581f1eb281741a75a7503f0
- complete-examples.test.ts: 170 passed
why: libtmux.org code blocks scroll sideways at laptop widths, and three
lines in capture.lua ran to 91, 83 and 85.
what:
- Break the runtime:connect table one field per line
- Name the quoted tmux prefix once in a local and build the command
from it
- Name the wait-for argument list before passing it to server:command
- Update the capture.lua sha256 in capture-examples.json; the shell
recipe is unchanged
Native run, from the repository root with Lua 5.5.1 and LuaRocks 3.13.0
on PATH:
python3 scripts/check-example-prose.py \
--example capture \
--port lua \
--output-dir <new directory>
- tmux 3.2a first on PATH: tmux -V "tmux 3.2a", exit 0, passed
- tmux 3.7c first on PATH: tmux -V "tmux 3.7c", exit 0, passed
- Both runs install luv 1.52.1-0, build the library and print
"libtmux capture ready"
- Source revision 5baa3f9b830ebdbc76fb50b5b3d7a5ad3f76d443
- complete-examples.test.ts: 170 passed
why: libtmux.org code blocks scroll sideways at laptop widths, and three
lines in connect.lua ran to 82, 86 and 91.
what:
- Put the two assert calls one argument per line
- Break the runtime:connect table one field per line
- Update the connect.lua sha256 in attach-examples.json; the shell
recipe is unchanged
Native run, from the repository root with Lua 5.5.1 and LuaRocks 3.13.0
on PATH:
python3 scripts/check-example-prose.py \
--example attach \
--port lua \
--output-dir <new directory>
- tmux 3.2a first on PATH: tmux -V "tmux 3.2a", exit 0, passed
- tmux 3.7c first on PATH: tmux -V "tmux 3.7c", exit 0, passed
- Both runs install luv 1.52.1-0, build the library, print work and
leave has-session passing
- Source revision 5baa3f9b830ebdbc76fb50b5b3d7a5ad3f76d443
- complete-examples.test.ts: 170 passed
why: libtmux.org code blocks scroll sideways at laptop widths, and the
session lookup in connect.rb ran to 82.
what:
- Name the snapshot's sessions before searching them for "work"
- Update the connect.rb sha256 in attach-examples.json; the shell
recipe is unchanged
Native run, from the repository root with Ruby 4.0.7 on PATH:
python3 scripts/check-example-prose.py \
--example attach \
--port ruby \
--output-dir <new directory>
- tmux 3.2a first on PATH: tmux -V "tmux 3.2a", exit 0, passed
- tmux 3.7c first on PATH: tmux -V "tmux 3.7c", exit 0, passed
- Both runs bundle install the library, print work and leave
has-session passing
- Source revision 2599d45369515aaf2fd5793bfe71cdc20de641b6
- complete-examples.test.ts: 170 passed
why: Five lines of Capture.swift were 82, 86, 82, 82 and 89 wide. what: - Name the printf command as a local instead of an inline argument - Break the timeout error, and the cleanup error, across lines - Bind FileHandle.standardError to a local named stderr - Update the Capture.swift sha256 in capture-examples.json Native run: python3 scripts/check-example-prose.py --example capture --port swift --page examples/capture-pane-output, Swift 6.2.4, library revision 254f8b2b. Passed with tmux 3.2a and with tmux 3.7c (tmux -V reports each), printing "libtmux capture ready".
why: Two lines of Connect.swift were 92 and 86 wide. what: - Bind the process environment to a local before the guard - Break the failure message onto its own line - Update the Connect.swift sha256 in attach-examples.json Native run: python3 scripts/check-example-prose.py --example attach --port swift --page guides/attaching-to-tmux, Swift 6.2.4, library revision 254f8b2b. Passed with tmux 3.2a and with tmux 3.7c (tmux -V reports each), printing "work".
why: The git remote add and fetch lines of the setup recipe were 91 and 92 wide. what: - Continue each of the two commands on a second line with "\", putting the URL and the 40-hex revision on lines of their own - Update the shellRecipe in product-examples.json to match - The program is unchanged, so its sha256 is unchanged Native run: the displayed setup and "swift run --jobs 2 MCPExample" in a fresh directory, via a by-hand runner (no script covers product pages), Swift 6.2.4, library revision 254f8b2b. Passed with tmux 3.2a and with tmux 3.7c (tmux -V reports each), printing "tools: list_sessions" and "sessions: mcp-example".
why: The git remote add and fetch lines of the build recipe were 91 and 92 wide. what: - Continue each of the two commands on a second line with "\", putting the URL and the 40-hex revision on lines of their own - Update the shellRecipe in product-examples.json to match - The launcher run-mcp.sh is unchanged, so its sha256 is unchanged Native run: the displayed setup, the libtmux-mcp build and "sh run-mcp.sh" (stdin closed, so the launcher starts its private server, serves, and cleans up on EOF) in a fresh directory, via a by-hand runner (no script covers product pages), Swift 6.2.4, library revision 254f8b2b. Exit 0 with tmux 3.2a and with tmux 3.7c (tmux -V reports each); the launcher logged "serving socket path ... through tmux".
why: Two lines of the program were 86 and 81 wide and the fetch recipe had two lines of 91 and 92. what: - Break the default-command option and the WorkspaceBuilder.build call at the outermost level - Continue the remote add and fetch commands with "\", putting the URL and the 40-hex revision on lines of their own - Update the WorkspaceExample.swift sha256 and the shellRecipe in product-examples.json Native run: the displayed setup and "swift run --jobs 2 WorkspaceExample" in a fresh directory, via a by-hand runner (no script covers product pages), Swift 6.2.4, library revision 254f8b2b. Passed with tmux 3.2a and with tmux 3.7c (tmux -V reports each), printing "built: 2 windows" and "editor: 2 panes".
why: The Rust capture page tells readers to save the program as src/main.rs, but its fixture entry gave only the name, so scripts/check-example-prose.py wrote main.rs at the project root and cargo stopped with "no targets specified in the manifest" (exit 101). The native runner could not verify this page at all. what: - Give the main.rs entry a path of src/main.rs, the field the Swift entries already use for Sources/ Native runs with check-example-prose.py --example capture --port rs: tmux 3.2a and 3.7c pass (cargo +1.97.1 run, exit 0, no missing output). The same command without the path exits 101: cargo finds no target in the manifest before tmux runs.
why: The Java workspace build file declared its dependency on one 81-column line. The coordinate is a single string, but Kotlin's call can break after the opening parenthesis, which leaves the string whole at 69 columns. what: - Put the libtmux-workspace coordinate on its own line inside implementation(...) Ran the page as displayed in a fresh directory (git fetch of libtmux-java 84222831, then ./libtmux-source/gradlew --no-daemon --max-workers=2 -p . run) with tmux 3.2a and 3.7c first on PATH: both print "built: 2 windows" and "editor: 2 panes", exit 0.
why: Five lines of the inspect-sessions program ran 81 to 84 columns: the platform guard, the DOTNET_ROOT copy, the capabilities cast, the result check and the cleanup failure. what: - Break the platform-guard throw and the cleanup failure after the opening parenthesis - Read DOTNET_ROOT into a local before copying it into the environment - Break the capabilities cast after `=` and the result check before `||` - Update the Program.cs sha256 in product-examples.json Native run: the page's recipe in a fresh directory (LibTmux.Mcp 0.0.0-alpha.20 as a local tool, then `dotnet run`), .NET SDK 10.0.400. Passed with tmux 3.2a and with tmux 3.7c, printing "Session: docs-demo (1 window)" and "Owned server stopped."
why: Seven lines of the run-command program ran 81 to 84 columns: the platform guard, the DOTNET_ROOT copy, three exception messages, the cleanup failure and the result check. what: - Break each long throw and the cleanup failure after the opening parenthesis - Read DOTNET_ROOT into a local before copying it into the environment - Break the result check before `||`, as the page's other checks do - Update the Program.cs sha256 in product-examples.json Native run: the page's recipe in a fresh directory (LibTmux.Mcp 0.0.0-alpha.20 as a local tool, then `dotnet run`), .NET SDK 10.0.400. Passed with tmux 3.2a and with tmux 3.7c, printing "Command exit status: 0" and "Captured marker: MCP command ready".
why: Three lines of the inspect-sessions program ran 81 to 83 columns (tabs counted as 4): the cleanup deadline, the close-error join and the session check. what: - Name the background context before the cleanup deadline - Name the close error before joining it - Name the created session's ID before comparing the listing to it - Update the main.go sha256 in product-examples.json Native run: the page's recipe in a fresh directory (libtmux-mcp v0.0.1-alpha.12 installed into .tools, `go mod tidy`, `go run .`), Go 1.26.5. Passed with tmux 3.2a and with tmux 3.7c, printing "demo: 1 window(s), 0 attached client(s)".
why: Five lines of the run-command program ran 81 to 113 columns (tabs counted as 4): the cleanup deadline, the close-error join, the unconfirmed-completion error, the pane check and the incomplete-output error. what: - Name the background context before the cleanup deadline, and the close error before joining it - Name the pane ID and the resolved panes before checking them - Break the unconfirmed-completion message at a word boundary; the joined text is unchanged - Put the incomplete-output format and its arguments on lines of their own - Update the main.go sha256 in product-examples.json Native run: the page's recipe in a fresh directory (libtmux-mcp v0.0.1-alpha.12 installed into .tools, `go mod tidy`, `go run .`), Go 1.26.5. Passed with tmux 3.2a and with tmux 3.7c, printing "exit status: 7" and "command finished", as the page shows.
why: The line that adds async cleanup errors to the failure report in the page-session-metadata program ran 86 columns. what: - Name the async cleanup errors before mapping them into the report - Update the snapshot-sessions.rb sha256 in product-examples.json Native run: the page's recipe in a fresh directory (libtmux-ruby at 9b1545562a, `bundle install` against its frozen lockfile, then `ruby -W:no-experimental snapshot-sessions.rb`), Ruby 4.0.7. Passed with tmux 3.2a and with tmux 3.7c, printing the page's expected output: "Endpoint: example", "build", "editor".
why: Fourteen lines of the inspect-sessions page ran 81 to 110 columns: three dependency lines in Cargo.toml, the list_sessions request and its error, and the startup, inspection, stop and cleanup lines of main.rs. what: - Give the two git dependencies and tokio their own dependency tables in Cargo.toml, so each key sits on its own line - Name the list_sessions request, the serialized error body, the startup result, the inspection future, the stop wait and the kept directory before using them - Shorten the two daemon cleanup messages to "daemon stop verification", which names the wait they report on - Format main.rs with rustfmt at max_width 80 - Update the Cargo.toml and main.rs sha256 in product-examples.json Native run: the page's recipe in a fresh directory (`cargo +1.97.1 generate-lockfile`, then `cargo +1.97.1 run --locked --quiet`), libtmux-rs at a6fc2a6567. Passed with tmux 3.2a and with tmux 3.7c, printing the page's expected output: "session: build", "session: editor".
why: Seven lines of the Rust queries page ran 84 to 98 columns: the cardinality program's query import, and the timeout and retained-directory lines that each of the three programs repeats. what: - Name the demonstration future before the timeout, and the kept directory's display before the failure message, in each program - Format the programs with rustfmt at max_width 80, which moves the query import's names onto their own line inside the braces - Update the three program sha256 values in concept-examples.json Native run: the page's recipe (libtmux-rs cloned at e9be0b6f6d as libtmux-source, then `cargo +1.97.1 run --quiet --bin` matching, cardinality and refresh), Rust 1.97.1. Passed with tmux 3.2a and with tmux 3.7c, printing "active panes: 2", "cardinality: none, one, multiple" and "fresh listing: renamed".
why: The Rust transports page's program ran its timeout line to 92 columns and its retained-directory message to 84. what: - Name the demonstration future before the timeout, and the kept directory's display before the failure message - Update the subprocess.rs sha256 in concept-examples.json Native run: the page's recipe (libtmux-rs cloned at e9be0b6f6d as libtmux-source, then `cargo +1.97.1 run --quiet --bin subprocess`), Rust 1.97.1. Passed with tmux 3.2a and with tmux 3.7c, printing "sessions: work" and "missing session: tmux refused the command".
why: Four lines of the Rust batching guide ran 84 to 99 columns: the libtmux dependency line in Cargo.toml, the incomplete-plan error, the timeout and the retained-directory message. what: - Give libtmux its own dependency table in Cargo.toml, so the path, default-features and features keys sit on their own lines - Name the plan's operations before the incomplete-plan error, the demonstration future before the timeout, and the kept directory's display before the failure message - Update the Cargo.toml and batching.rs sha256 in concept-examples.json Native run: the page's recipe (libtmux-rs cloned at e9be0b6f6d as libtmux-source, then `cargo +1.97.1 run --quiet --bin batching`), Rust 1.97.1. Passed with tmux 3.2a and with tmux 3.7c, printing "marked: 1 dispatches; one, two" and "refused plan: failed, skipped".
why: Three lines of the Rust control-mode guide ran 84 to 107 columns: the libtmux dependency line in Cargo.toml, the timeout and the retained-directory message. what: - Give libtmux its own dependency table in Cargo.toml, so the path, default-features and features keys sit on their own lines - Name the demonstration future before the timeout, and the kept directory's display before the failure message - Update the Cargo.toml and control.rs sha256 in concept-examples.json Native run: the page's recipe (libtmux-rs cloned at e9be0b6f6d as libtmux-source, then `cargo +1.97.1 run --quiet --bin control`), Rust 1.97.1. Passed with tmux 3.2a and with tmux 3.7c, printing "attached control clients: 1" and "connection closed; server still running".
why: The Kotlin and Scala attach guides end their `&&` chain with an 88-column Gradle line that scrolls sideways in a laptop-width code block. what: - Continue the Gradle line with `\`, one flag per line, in both guides - Match the shellRecipe entries in attach-examples.json, which the site test compares with each page's commands The words and their order are unchanged, so the shell runs the same command. Native run, exact displayed setup and program through scripts/check-example-prose.py --example attach, JDK 26.0.2 on Linux: - Kotlin, tmux 3.2a and 3.7c: exit 0, "work" printed - Scala, tmux 3.2a and 3.7c: exit 0, "work" printed
why: 80 columns should fit a libtmux.org code block in a laptop-width window, but a docs-page block held fewer. On a full local assembly, /en/concepts/queries/ leaves 644 px for a code line at a 1024 px viewport and 656 px at 1280, after the line's 14.5 px start padding and the copy button's 48 px gutter. Firefox and WebKit draw 14 px IBM Plex Mono at 8.23 to 8.24 px per character. That holds 78.1 to 78.2 columns at 1024 (CI's Chrome: 78.1) and 79.6 at 1280, so an 80-column line scrolled sideways. The homepage already sizes its code font from its container to fit a column count. what: - Make each prose code block an inline-size container and set --ec-codeFontSize to clamp(0.8125rem, calc((100cqi - 4.0625rem) / (80 * 0.6)), 0.875rem): the default 14 px wherever 80 columns already fit, smaller only below that, never under the homepage's 13 px floor Measured by injecting the rule into a mirror of the deployed page: 81.7 to 81.8 columns at 1024 and 1280 px in Chrome, Firefox and WebKit; 90 at 1366 px and 99 at 1440 px in Firefox and WebKit, unchanged at 14 px. Rejected: narrowing the copy button's gutter (changes every frame for a few pixels), and promising 80 columns only from 1366 px (a 1280 px laptop window would still scroll).
why: WRITING.md held example comments to 100 columns and set no limit for code. Before `fix(site) Fit 80 code columns at laptop widths`, a libtmux.org code block held 78 columns at 1024 px in Firefox and WebKit; with its font rule they fit 81.7 to 81.8 from 1024 px, and 99 at 1440. Each port's example-style PR adds the same section. what: - Paste the shared section under "Documented examples that run", before "Examples across ports"; the existing anchor stays - Drop the 100-column comment limit that the shared section replaces - Make "Code blocks" a heading so the shared section's link resolves - Mark the shared text with shared:examples comments so a checker can digest it - Add "In this repository" in the shared four-bullet shape: the formatter and the width check command, what no formatter touches, the markers that decide whether a fence runs, and how compared output and pinned programs change, followed by a Bad/Good pair from a line the C# transports page needed to fix
why: The routing line named only prose, comments and commits, so it did not send an agent editing a code example on a page to the rules for its width and layout. what: - Add code examples to the WRITING.md trigger list and link the "Documented examples that run" section
why: oxfmt skips Markdown, so nothing held hand-written fences in the site's pages to a width. In Firefox and WebKit, libtmux.org code blocks held 78 columns at 1024 px before `fix(site) Fit 80 code columns at laptop widths` and fit 81.7 to 81.8 after it, and the long lines the check first found ran to 114 columns. The shared checker is the same file in each port that adopts it. Every pinned program and console recipe this branch can change now fits in 80 and was re-run natively. The native Julia pages copy libtmux-julia's programs at the revision site/test/fixtures/program-examples.json pins and check each copy by sha256, so their five wide lines stay until libtmux-julia#7 fits the sources and the pin moves. what: - Add scripts/check_example_width.py with its --self-test, which plants a failure for every rule, plus clean controls - Add .github/example-width.toml: 80 columns over every tracked *.md file, including README.md, WRITING.md and AGENTS.md (CLAUDE.md links to AGENTS.md). Every tracked file under an examples directory is Markdown, so the markdown glob selects all of them and no example file needs an exclude. The one [[exclude]] is notes/research, dated research notes with pasted tool output that no reader copies code from - Allow eight lines, each with its reason: the quoted PEP 508 requirement that pins libtmux to a commit, once in each of the two Python recipes; the deliberately wide Bad line in WRITING.md's port block; and five lines of the pinned Julia programs, output_stream.jl (84 columns), owned_capture.jl (88) and shared_windows.jl (86, 90, 92) - Record checker_digest and shared_digest, the --digest of this checker and of WRITING.md's shared section, so a local edit to either fails the check - Run the self-test and then the check in scripts/test-all.sh and the medium and outer loops - Document the command in CONTRIBUTING.md beside the other gates
why: WRITING.md's shared example section and check_example_width.py are copied into each port that adopts them, and the rule says to change them in all of them together. Nothing enforced it, so a port could drift without any job failing. Alternatives considered: a submodule or package holding the shared files would add a dependency to twelve repositories for a checker and a shared section that every port runs offline, and a bot that opens sync PRs still lets a stale copy merge before the bot runs. what: - Add scripts/check_shared_examples.py: for each port, fetch the checker and WRITING.md from the default branch on raw.githubusercontent.com, digest them like check_example_width.py --digest, and compare with this repository's files - Fail a port without a file unless the PENDING list names it with a reason and the date it was listed, which passes with a notice; fail a pending port that has both files until it leaves the list, and an entry older than 30 days, so the list cannot go stale - Fail a file that differs unless PREVIOUS accepts it - List every port but libtmux-powershell in PENDING; PREVIOUS accepts powershell's merged checker and shared section until 2026-11-10 - Add NOT_FETCHED, empty while every port is public, for a port the script cannot read, such as a private repository whose raw files return 404 without a token; it prints a notice naming where that port is compared instead - Add --self-test with a planted checker mismatch, a planted text mismatch, a missing file, a pending port with both files, a pending entry past 30 days, an entry for a port not in PORTS, a previous version inside and past its window, and clean, unmarked and not-fetched controls; it needs no network - Fail when a public libtmux repository outside PORTS carries the shared markers (listed through GET /orgs/libtmux/repos); --self-test plants one with markers and one without - Add .github/workflows/shared-examples.yml: self-test, then the comparison, weekly and on pushes to main and pull requests that change the shared files or the gate, passing GITHUB_TOKEN from github.token; a port that drifts on its own shows in the weekly run, not on unrelated pull requests - End a failed run with what to change: a file that differs means the shared rules change in every port together; an out-of-date PORTS, PENDING or PREVIOUS entry gets the edit its error line names - Import the checker without writing a __pycache__ beside it - Document the command in CONTRIBUTING.md, marked network-only so the local loops skip it Checked live against the real API with a token: no unlisted adopter was reported and the run exited 0.
why: The width check holds fence source to 80 columns, but the reader sees the block inside a sidebar, margins and the block's own padding. Nothing measured that, so a CSS change could leave a block narrower than the line the check passed and scroll it sideways with no failure. what: - Add site/test/code-block-width.outer.test.ts: serve the assembled tree on a loopback port, open /en/concepts/queries/ at 1024 px and at 1280 px, where the contents column appears, and assert that every code block's scrolling element, less the line's padding, holds at least 80 characters of the code font, measured from an 80-character run - Pair it with a control that runs the same assertion at 390 px and expects it to fail, so a measurement that cannot fail is caught - Load the code font itself before measuring and refuse to measure without it; a second control blocks *.woff2 and expects that refusal - Skip when no assembled tree is present, like the other output suites; CI's test job assembles the site, so it runs there - Name the narrowest block in a failure: the heading above it, any tab panel, list, aside, details or table around it, and its content and character widths - Measure in Chrome unless LIBTMUX_DOCS_BROWSER_CHANNEL names another browser; the rest of the publication audit keeps the pinned Chromium - Mention the suite in CONTRIBUTING.md beside the browser notes In CI's Chrome, without the font rule the narrowest block held 78.1 columns at 1024 px and the check failed (libtmux/docs Actions run 37223904428); with it, the test passes and both controls see the failure they expect. Playwright's bundled Chromium draws the code font at 7.84 px per character where Firefox and WebKit draw 8.23 to 8.24 px, so it holds 80.2 columns at 1024 px without the rule and would pass either way, which is why the test measures in Chrome. fonts.ready can settle before a lazily used face starts loading, which is why the test loads the code font itself.
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Brings the shared libtmux example rules to the docs repository and holds code in the site's Markdown pages to 80 columns. API-page examples, the staged F#, Julia, Kotlin, Scala, Ruby and Lua guides, and
file=quotes render from port revisions pinned before this work. Most fit once each port merges and its pinned revision moves. Three kinds stay wide: the 82- and 86-column setup lines docs' generators write (142 lines in four models), the ports' allowed lines, and compared doctest output.formatscript with no CI caller; this swaps it for oxfmt 0.70.0, the version the ts port pins.What changed
Policy
WRITING.mdgains the shared example rules as subsections inside## Documented examples that run, before### Examples across ports(the existing anchor stays), and drops the old 100-column comment limit the shared section replaces. "Code blocks" becomes a heading so the shared section's link resolves. The "In this repository" block covers oxfmt, how each kind of fence runs and stays held to the width, and the pinned-program rule.AGENTS.mdroutes code examples to it and links the heading the shared section sits under, which the checker requires.Tooling
.oxfmtrc.json, rootformatandformat:check), reformat the source (345 files, +21713/-9065, mechanical), list that commit in.git-blame-ignore-revs, then runformat:checkinscripts/test-all.shand the medium loop.scripts/check_example_width.pyand.github/example-width.tomlread every tracked**/*.mdfile, includingREADME.md,WRITING.mdandAGENTS.md(CLAUDE.mdlinks toAGENTS.md). One[[exclude]]entry skipsnotes/research/**, dated notes with pasted tool output. Eight[[allow]]entries, each with a reason: the quoted PEP 508 requirement that pins libtmux to a commit in the two Python recipes, the deliberately wide Bad line in WRITING.md's port block, and five lines the native Julia pages copy from libtmux-julia at 6f62bd7 (84 to 92 columns). The medium and outer loops andscripts/test-all.shrun the self-test and then the check.<pre>blocks, doc-comment code and reST blocks, and measures the whole source line. Each failure names the file to fix, and a clean run prints how many files it read.ci(examples) Compare shared rules across portsaddsscripts/check_shared_examples.pyand.github/workflows/shared-examples.yml, which compare each port's checker and WRITING.md with this repository's, weekly and on pushes and pull requests that change the shared files; its commit message lists what fails and what passes with a notice.PREVIOUSaccepts the checker and shared section libtmux-powershell#1 merged until 2026-11-10, while libtmux-powershell#14 brings both to the current ones.fix(site) Fit 80 code columns at laptop widthsmakes each prose code block an inline-size container and sets--ec-codeFontSizetoclamp(0.8125rem, calc((100cqi - 4.0625rem) / (80 * 0.6)), 0.875rem), the homepage's container-sized pattern: 14 px wherever 80 columns already fit, never under 13 px.site/test/code-block-width.outer.test.tsopens/en/concepts/queries/at 1024 px and at 1280 px, where the contents column appears, loads the code font itself, and asserts that every code block holds at least 80 characters of it after the sidebar, margins and the copy button's gutter. A control runs the same assertion at 390 px and expects it to fail; another blocks the webfont and expects the test to refuse to measure. CI's test job assembles the site and runs it; the test launches Chrome, while the rest of the audit keeps the pinned Chromium.Examples
Fit the Go send call,Fit Kotlin lines in 80), so each port's maintainers can review their own language; the rest fit shared YAML, CI or shell samples.shellRecipeinsite/test/fixtureswere fitted in 80 and re-pinned, each with a native re-run on tmux 3.2a and 3.7c. The commit messages record the command, tool versions and source revision.fix(fixtures[capture])gives the Rustmain.rsentry the pathsrc/main.rs. The page tells readers to save it there, and without the path the native runner wrotemain.rsat the project root and cargo exited 101.Split the JVM run commandcontinues the attach guides' 88-column Gradle line with\, one flag per line, without reordering a word, so the shell runs the same command;shellRecipeinattach-examples.jsonmatches.Wrap the Gradle lineputs the Java workspace dependency insideimplementation(...)so the coordinate stays whole at 69 columns. The page runs from a fresh directory on tmux 3.2a and 3.7c.Evidence
site/test/complete-examples.test.tspins by sha256, failing 5 of its 170 cases.site/public/**is ignored because those scripts are injected verbatim.How to verify
$ pnpm run format:check$ python3 scripts/check_example_width.py --self-test$ python3 scripts/check_example_width.py$ python3 scripts/check_shared_examples.py --self-testThe comparison needs the network.
$ python3 scripts/check_shared_examples.pyThe width test needs an assembled site; CI's test job builds one and runs it.
$ pnpm test:publicationMerge order
Merge this PR before the ports.
PENDINGlists every port except libtmux-powershell, each with the reason and the date it was listed; an entry older than 30 days fails, so from 2026-11-04 the drift job fails for any port still pending. libtmux-powershell#1 is merged, so the drift job compares powershell's files from its first run, andPREVIOUSaccepts the checker and shared section it merged until 2026-11-10. Once a port's example-style PR merges, the next run of the drift job fails with "both files present; remove it from PENDING" until a follow-up change here removes that port.Not in this PR
scripts/check-example-prose.pydoes not cover product pages, so the Swift and TypeScript workspace and MCP pages were re-run by hand with the commands in their commit messages.