Repository navigation
Conversation
why: Long member lists scroll the Members heading and the active subgroup heading out of view, so a reader loses which group a member belongs to. The section row already clears the site header; the member headings need the same measured clearance without moving their IDs, permalinks or heading levels. what: - Wrap an owner's Members or Fields section in `.api-members` and stack its real h2 and group h3 below the measured header and section row. Both release at the section end, before inherited and related content. - Derive offsets, scroll margins and activation from the measured heading heights, so wrapped and enlarged text keep clearance. Stay in flow when the viewport cannot keep a reading area beside the bars. - Return a link request for a stuck owner or group heading to its source boundary, including a repeated hash. The anchor handler and the browser keep startup arrival, history traversal, typed hashes, modified clicks, new tabs and cross-page links. - Keep the bars in flow until the page is revealed, so the anchor handler's startup scroll is not skewed by a sticky heading in Firefox. - Return a keyboard-focused heading to its source box, but keep it sticky under a pointer press so the permalink click still lands. - Tint the opaque bar for the arrival cue instead of replacing its surface, including under reduced motion. - Confine sticky rules to screen media; leave scalar, single-group and empty owners without added headings. - Cover grouped, single, scalar and empty owners, release, wrapped headings, link requests, history, startup, the focus and arrival styles and the pending state in the api-page-contents tests.
why: A sticky box is aligned where it is stuck, not where its group starts. A link or typed hash for a group above the viewport landed at the end of that group in every engine, and Firefox did the same for a first link click when a frame rendered before the URL changed. The scroll padding counted only the header and section row, so Shift+Tab left focused links entirely under the Members and group bars. A strip of scrolled text also showed between the section row and the bars. what: - Hold the targeted Members or group heading in flow while a link click or a same-document fragment navigation scrolls, so the browser and the anchor handler align its source box. The Navigation API `navigate` event starts the hold before the browser scrolls a typed or scripted hash; a click in the layout starts it in browsers without that API. Animation frames end the hold, and every navigation signal restarts it. - Give focusable controls in the owner section a scroll margin equal to the measured bars above them: the Members bar, plus the control's own group bar. A heading permalink takes only the bars above its heading. - Cover the gap between the section row and the bars with the page background, using a sticky pseudo-element that adds no height. - Test the hold, its restart and release, the Navigation API entry point, the focus clearance and the cover in api-page-contents.test.ts. Verified: with the Swift Server page at 1800x1000, backward Shift+Tab left 2 of 14 stops under a bar in Chromium and Firefox and 7 in WebKit; none are now. A typed hash for the first group landed at scrollY 3609, 3723 and 3608 (Chromium, Firefox, WebKit), with the group box ending at 207, 94 and 208; it lands at 2677, 2678 and 2678 with the group starting at the reading line. A rail click to the first group from a later one ended at the group end in Firefox in 3 of 24 runs, and in 18 of 24 on a loaded machine; it ended there in 0 of 24 runs, twice, now.
why: The api-page-contents tests mock geometry in a headless DOM, so none of the focus, landing or typed hash failures of the sticky bars could fail them, and each engine aligns a sticky heading differently. what: - Add checkApiStickyHeadings. On the Swift Server page, at desktop and phone widths, it tabs backward through a stuck group, clicks a link to an earlier group once normally and once with the main thread busy, clicks a heading's link again from mid-group and from the group end, and types a hash for a group above the viewport. Each arrival must sit at the reading line, at the start of its group, uncovered, and reached by one scroll that never paints the group end. - Add checkApiStickyHeadingsFail. It removes the focus clearance and the Navigation API from a page and requires the check to reject, so the check cannot pass without them. - Run both in the default browser matrix, and in Chromium, Firefox and WebKit with `check-dev.mjs --api-sticky`. Document the mode in CONTRIBUTING.md. Verified: against the sticky commit alone, check-dev.mjs --api-sticky fails in Chromium and Firefox at "backward tab stop 11 is not entirely hidden by the sticky bars" and in WebKit at "backward tab stop 9 starts below the sticky bars". Run per scenario, a typed hash fails in all three engines. In Firefox a link on a busy page lands with the heading at 48 under the header (scrollY 3723), and a repeated link overshoots to 3915 instead of 3687. With the fix the command passes in all three engines, and the scenarios passed in three consecutive runs each.
why: Keyboard focus, the arrival hold and pending fonts put a member bar back in flow with position: static. The sticky cover that closes the gap under the section row is positioned, so it painted over the top of the static Members bar, its permalink and its focus outline. what: - Hold in-flow bars with position: relative and top: auto, so their z-index keeps them above the cover - Check in real browsers that a focused Members permalink is not covered, with a control that fails when the bar drops to static
why: Prose code literals link every name that resolves to one member. A keyword argument names a parameter of the call being described, so Ruby's `cancel:` linked to Cancellation#cancel, `clients: true` to Snapshot#clients, and `action:` to an unrelated Workspace member. what: - Add SymbolIndex.linkLiteral, which leaves `name:` and `name: value` plain and links other literals as before - Use it for HTML prose, and skip keyword arguments in Markdown export - Test that keyword arguments stay plain while the bare name still links
why: Python, Swift, Ruby and Lua listed only the parameters a doc comment described, so a Ruby Server.start page showed no Parameters section for executable:, config:, timeout: and cancel:, while C# listed its parameters with their types whether documented or not. what: - List each declared parameter with its type in every port - Link every parameter name in the signature to its entry - For Python, list the implementation's parameters, not each @overload stub's, and leave out an undocumented self or cls receiver; leave out Lua's self receiver too - Update the tests that pinned documented-only lists
why: The documentation picker named the tmux CLI Manual and C source reference, but the tmux sidebar listed only Guides, Concepts, Examples and Topics, and the overview cards called them Manual and Reference. what: - Add CLI Manual and C source reference links to the tmux sidebar, after its sections and before the notices - Title the overview cards CLI Manual and C source reference - Test the sidebar links for a pinned tmux version
…s, formats
why: A tmux command such as `list-clients` rendered as a plain link,
with no kind badge or hover card, while the API names beside it carried
both. `session_attached` and `destroy-unattached`, which the tmux manual
documents, were not linked at all.
what:
- Read options, hooks and format variables from the pinned manual per
release, anchored on the same headings the full manual page renders
- Resolve every command, option, hook and format-variable link through
tmuxEntityHref, so the destination of every kind changes in one place
- Link option and hook names written in code, and format variables that
are a whole code span or sit inside a #{...} expression; names the
release does not document, URI templates and calls stay plain
- Keep library symbols ahead of options, hooks and format variables in
HTML, prose Markdown and symbol Markdown, so `pane_id` still reaches a
Rust field where the page documents one
- Render each lone mention with the API kind badge (command $, option o,
hook h, format #) and add the four kinds to the badge palette in the
light, system dark and explicit dark themes; several names in one code
run stay links without badges, and Markdown keeps plain links
- Serve preview cards for command pages and for each manual entry by
anchor, with an "Open manual" action, and make manual links eligible
for hover previews outside the command index and heading permalinks
- Load the highlighter only when the manual is highlighted, so link
resolution no longer imports it
- Test the three mention kinds, the hover-card data and unknown names,
and accept manual entry anchors in the native prose destination check
why: The badges, [source] link and permalink beside a declaration were top-aligned with its code. A formatted native signature pads its code by 0.25rem, so on a one-line declaration such as TypeScript's Server.sessions the controls sat 4.5px above the line's center. Badges aligned by their own baseline sat 0.5px high on every other header, and a heading with a taller line box drifted by more. what: - Align the row's first baselines for native headers at every width and for Python and MCP headers above the 36rem container breakpoint, so controls follow line one of a wrapped signature and ignore the code's padding; center the badge slot on the line the text controls share - Leave the vendored column layout, header height and wrapping as they were; a control group on a row of its own is not moved - Add checkDeclarationControlAlignment to check-native-layout.mjs. It loads TypeScript, Go, Python, Julia, C#, Kotlin, Scala and MCP pages at 1440, 768, 500 and 390px and requires every control beside the code to sit within 1px of the center of the first signature line, and controls that wrap onto their own rows to be level within each row. check-dev.mjs runs it with the signature layouts and the sample loop checks the API probe header - Replace the top-edge assertion in checkNativeSignatureGeometry with a center assertion, and replay the observed hosted Scala geometry as the rejected case Largest control offset from the first line's center, origin/main then this change, measured in Chromium against the dev server: - TypeScript, Go, Julia and C# formatted methods: 4.50px, then 0.00px at 1440 and 768px; TypeScript client.toString at 390px: 4.00px, then 0.00px - Python method and class, Kotlin type: 0.50px, then 0.00px - MCP tool header: 0.50px, then 0.00px; its type definition headings, whose 600-weight face makes a 25px line: 1.80px, then 0.70px - Header heights, code boxes and the stacked layouts are unchanged
why: A prose table row's permalink sat at its first cell's right edge, far from the label it links, and appeared inconsistently with the section permalink. Typography also zeroes the outer padding of the first and last columns, so labels touched the table edge and the row's hover background. what: - Keep the row permalink at the end of its first cell's last line, out of flow so it neither widens the column nor wraps onto its own line - Hide it until the row is hovered, focused or targeted, with the section permalink's theme colors - Give markdown table cells a 0.75rem inline inset, first and last columns included; component tables keep their own padding - Add checkRowPermalinks to check-dev-sample.mjs and run it from the sample and full check-dev flows. Rust, tmux and Ruby tables at 1440, 768 and 390 px in light and dark must put the permalink within 0.5em of the last text line, share one inset across columns, stay quiet at rest, and appear legibly on hover, focus and target
This was referenced Oct 18, 2026
why: `Selection.where(criteria: WhereOf<Model>): Selection<Model>` showed `Model` as plain text. The TypeScript extractor never recorded the parameters of an interface, class or alias, so the linker had nothing to bind, and every port that did record them left the name unlinked or resolved it against a global of the same name. what: - Add `TypeParameter` (name, modifier, kind, bound, default, doc) and `typeParameters` on symbols and signatures. `typeParametersOf` returns the stored list or reads `typeParams` apart per language, so models extracted earlier keep working. - Record container and alias parameters in the TypeScript, Rust, Go, Java and C# specs, fold Rust and C# `where` bounds into the parameter they restrict, and read `@typeParam`, `@template`, `@tparam`, Javadoc `@param <T>` and C# `<typeparam>` onto the parameter. - Extract parameters for Kotlin and Scala (bounds, variance, `where`), Python (PEP 695 lists, `Generic[...]` bases, module TypeVars and the variables a function binds), C++ (class and member template lists, `\tparam`) and Swift (generic parameters and constraints from the symbol graph). - Bind names in one place, `SymbolIndex.typeParameterBindings`: the signature, then the enclosing declarations, honouring Java's static boundary, Rust impl self types and Go receivers by position. Signature and prose links share it, so a bound name links to the anchor `<owner>.type-parameter.<name>` on its declaring page. - `<typeparamref>` becomes a `typeparam` reference that never falls back to a global lookup. - Guard against the C# grammar reading a base type's arguments as a parameter list after a parse error. - `inheritedTypeParameters` lists the enclosing parameters a member's types use, from the same links.
why: A reader of `Selection.where` could not tell what `Model` was. Type parameters were neither documented nor linked, in any port. what: - List a symbol's own parameters under "Type parameters", each with a stable anchor, its bound or constraint, default and documentation. A member page lists the enclosing parameters its signature uses, linked to the owner's anchor and naming the declaring type. - Link each occurrence in native, formatted-layout and unformatted signatures, in bounds, and in prose code literals. Layout ranges that keep a bound name out of the global lookup now link it to its declaration. - Add the section to the on-page contents and to the Markdown export, built from the same bindings as the HTML. - Give type-parameter links `api-type-parameter-name` and a title naming the declaring type, so parameter-name checks keep counting parameters. - Add `check-dev.mjs --type-parameters`: it follows the links on member pages in five ports to the owner's anchor, and compares the Markdown twin. The default browser run includes it. - Update the tests that expected a bound name to be unlinked.
why: The extractors now record type parameters, and the page tests that compare a fresh extraction with the committed model require the two to agree. what: - Regenerate ts, rs, go, csharp, java, kotlin, scala and py from the revisions each model already records, with `gen-api-model.mjs`. The existing models were produced by older extractor versions, so a few unrelated fields move: signature key order in Rust and Java, one C# doc comment and one Java record accessor. - Merge only the type-parameter fields into cxx.json: the local Doxygen is 1.14 and rewrites inline code in other doc comments. - Leave swift.json: `swift build` does not run here (missing libxml2.so.2). Ruby, Julia, Lua, PowerShell and F# come from native artifacts or sources that were not rebuilt; Ruby and Julia are read from their recorded `typeParams`.
why: The manual page for bind-key showed `C-b c` and `c` as code, the same as `new-window` or a flag. A reader could not tell the key to press from the command it runs, and the default binding tables listed keys as bold text. what: - Add tmux-keys.ts with the key grammar from tmux's key-string.c and a policy for how much context a literal needs: modified keys qualify on their spelling, key names in the manual, and every key in a key table, the default binding list or the bind-key, unbind-key, send-keys, send-prefix and list-keys descriptions - Add markTmuxManualKeys, which turns those literals into kbd, nests one kbd per key inside a kbd for a sequence such as C-b c, keeps permalink ids, and drops mandoc's quotation marks around a cap - Leave format strings, option values, command names and bare letters elsewhere in the manual as code - Draw a key cap in the prose theme from the surface and edge tokens, so light and dark share one rule; the layer is utilities because the typography plugin's own kbd rule sits there - Test the grammar and the contexts, the bind-key sequence, the key tables of both pinned versions, command pages against the full manual, and the plain-text Markdown export
why: Guides name keys such as C-c, Enter and Up in inline code, and the attaching guide spelled the detach binding as bold Ctrl-b and d. They read as code beside the manual's key caps. what: - Add a rehype plugin, before the API linker, that marks inline code as kbd when tmux-keys.ts says it names a key: modified notation, a list that holds one, or a name beside "key" or "press" - Keep the word Enter typed into a pane as code - Write the detach binding as `C-b d` with the keys spelled out - Document the convention in WRITING.md; Markdown twins keep backticks - Test the plugin on fragments and on the key mentions of the real guides, topics and port pages
why: Unit tests read the transformed HTML. They do not show that the rendered bind-key page nests the caps, keeps new-window a link, and draws a legible cap in both colour schemes. what: - Add check-tmux-keys.mjs: bind-key renders C-b c as a kbd around two kbd, no key stays code, the command links remain; caps have an outline and raised edge, use the code face, fit 1440 and 390 px and reach 4.5:1 contrast in light and dark - Read the default bindings, the KEY BINDINGS modifiers and two guides, including the word Enter that stays code - Run it in the sample and the full browser matrix, with its pages compiled during setup, and alone with `check-dev.mjs --tmux-keys`
why: A preview link that leads with a kind badge ([M], [C]) drew its dotted underline under the badge letter as well as the name. A text decoration on an ancestor reaches every in-flow descendant, and the badge cannot cancel it, so the line has to sit on the name instead. what: - Put the dotted line on the link's name (.api-symbol-link__name, or the code name in "In other ports") and leave the anchor undecorated when a badge leads it - Drop the prose underline from badge links that are not previews, and let their name draw it - Wrap MCP description link names in .api-symbol-link__name, as prose links already do - Check in a real browser that each badge's rendered box matches the same page drawn without decorations, at rest and hovered, and that the name has exactly one dotted underline; cover prose, headings, tables, MCP, API equivalents, related lists, sidebar, tree and search results - Extend the happy-dom decoration test to the badge link shapes
why: A badge aligned to its name's baseline, so its centre sat below the text centre and the gap to the name varied by context. Measured in Chromium before the change: the centre was 3px low beside body text and a code chip, 8px low in an h2, 5.5px in an h3, 1.5px in a table, 2.5px in related cards and 1.3px in search results. The gap was .3em in prose (4.8px to the chip, 10.8px to its text), .35em in MCP cards, .37em in API equivalents, .6em in related cards, .67em in related contents and .2em in search results. what: - Centre the badge on the link's name with align-self while the name keeps the baseline, so the link's height and its text do not move - Set one .25em gap between a badge and the name in prose, MCP, related, equivalent and search links; navigation and sidebar rows already centre and keep their 4px - Lay out search result names as a flex row so the badge and name share the same gap - Move the related-card summary indent to the new badge and gap width - Assert in the browser check that each badge centre is within 1px of its text centre, the gap is about .25em, and a one-line link stays within its line height
why: Hovering the "Runtime support" card on the workspace overview drew the preview's dotted underline under its title and body. The card links to reference/compatibility/, which the preview policy accepts as a reference page, so the whole block link was marked and a[data-link-preview] painted the line through its heading and paragraph. Cards that link to guides were not matched, which is why only this one showed it. A card already summarizes its destination, and only an inline text run carries the dotted line. what: - Make a link that wraps blocks, or a .doc-card, ineligible for a preview, and remove a mark the parser added before its blocks arrived - Check in a real browser, after hovering every block link on the workspace, port and MCP overview pages, that each dotted link line sits on an inline link without block children, with a prose page as the control that inline preview links keep theirs - Cover the card and block-wrapping link shapes in the preview policy and decoration tests - Test the badge check's dotted line with endsWith
why: A member body (`dl.py > dd`) is padded .75rem, but its first and last children carried their own margins on top of that. A body holding only "In other ports" opened 20px below its header and closed 12px above its border; a trailing description paragraph or example did the same at the bottom, and a leading parameter list added a divider and padding before its label. Each case was patched on its own (the Methods heading, then the Description and Examples headings), so the next shape of body repeated the bug. what: - Trim the top margin of a body's first child, and the bottom margin of its last, through up to three wrappers, in one rule set in api.css - Drop the divider and padding of a field list that opens the body - Drop the bottom margin of the last parameter heading, which sits in a grid item the chain cannot reach - Remove the narrower rules this replaces from global.css and api.css - Add checkMemberBodyInsets to check-native-layout.mjs: it opens member bodies on Go, Julia, Ruby, Python, TypeScript, Swift, C#, Java, PowerShell and MCP pages at 1440 and 390px, finds the first and last painted content, and requires both insets to match the padding and each other within 1px - Run it from check-dev.mjs, alone with --member-bodies - Rewrite declaration-body-spacing.test.ts around the new rules, including the sibling spacing they must leave alone
…es in code why: On /py/latest/workspace/topics/, `tmuxp load`, `tmuxp freeze` and `shell_command_before` rendered as plain code, although the CLI Manual and the Configuration reference have an entry for each. The prose linker only knew library symbols, MCP names on MCP pages and tmux names, so workspace names never reached a resolver. Where a workspace name was linked, it went to the wrong place: `freeze` and `search` led to a library function and the Python standard library, `session_name` to the tmux format variable, and Ruby's `load` to its API. what: - Index each port's CLI Manual commands, option rows and configuration key rows from the workspace pages (scripts/gen-workspace-entities.mjs into site/src/data/workspace-entities.json), anchored on the rows the rendered tables serve; createRowAnchors now numbers rows for the page and the indexer alike - Resolve `<program> <command>` on any page of the port that ships the program, and a bare command, option or key on a user-facing workspace page, through the mention pipeline that badges tmux names: the same badge markup, inline links without a badge inside a longer code run, plain links in Markdown exports - Let the page's own product and port win: a workspace name outranks a library symbol, a standard-library name and a tmux name, while Internals pages and the language API index keep their library symbols - Leave a heading, the first cell of the row that defines a name, and a command's own page plain rather than sending them elsewhere - Prefer a key's entry on the page it is written on, then the first in reference order; a name that is both a command and a key follows its section, or its quotes - Link tools and prompts named inside a longer MCP code run, and resource URIs on workspace pages, which a library symbol never shares - Add a key badge (colon mark, property palette) beside the tmux kinds - Share the linked-version rule between the prose linker and the new links as linkedVersionFor - Check the index in the medium loop and the publication audit, and walk every workspace and MCP page of every port in a test that fails on any code literal naming a command, option, key, tool or resource that renders plain; its negative case renders the maintainer's page without linking and names the three reported literals Measured on the original pipeline: 178 such literals rendered plain across the nine ports with workspace pages, and none do now.
…iptions why: The Python server publishes its docstrings verbatim, so create_session printed `:func:` role text, -eKEY=VALUE and show-environment rendered as unstyled code, and show-environment had no link. The description renderer only knew Markdown and MCP tool names, so every port left its tmux commands, options, hooks and format variables unlinked, and meta descriptions carried raw backticks. what: - Rewrite roles and directives before Markdown renders them: a role becomes a link to the API reference page or MCP tool page that documents its target, or clean code when none exists (a private helper has no page and no extracted source line); :doc: links the upstream docs site; a warning directive becomes the site aside - Run descriptions through the prose mention pipeline so tmux commands, options, hooks and format variables link through tmuxEntityHref with the same badges and previews as prose pages, and drop its links to the object being described - Add a symbols opt-out to that pipeline: an argument named logical_name is not evidence for the library attribute of that name - Give inline literals the API literal chip instead of bare code - Use plain-text summaries for meta descriptions, search and previews - Move the admonition kind table next to the aside it feeds - Sweep every port's tool, prompt and resource descriptions and schema prose through the real renderer, failing on raw roles, directives, backticks, unstyled literals or unlinked tmux names, with negative cases on the origin/main rendering and clean controls - Export a described tmux name as a plain Markdown link with no badge
why: Arguments rendered as a bold additionalProperties row, name: type headings with an Optional tag and a permalink pushed away by flex wrapping, and a Variant block with its own # for every member of string | null, so a seven-argument tool ran to screens of rules and gaps that no other API page has. what: - List each field as the API reference does: bold name, ? when optional, = default, the type in parentheses, the # permalink beside it, then the description at 14px; prompt arguments and URI variables use the same markup - Write a map as Record<string, T>, and keep a union member, array item or map value in the type line unless it carries prose, constraints or fields; folded pointers stay as in-page anchors so every old fragment still lands on its field - Say a closed object rejects other fields once, in prose, instead of in an additionalProperties fact row - Label external type links as the API pages do (rel, JSON Schema title) - Cover the folding rules, anchors and rendered structure in tests
why: An example page opened with a whole tested program, and a step that explained one command had to be a hand-typed copy of part of it. A copy drifts from the program the page runs. The pipeline included only whole files: `region=` needs marker comments in the port source, and the Go quickstart marks its lines with `docs:` comments the region reader does not match. what: - Add excerpt fences: `excerpt="<title>"` quotes the titled block of the same page and `file="<path>"` quotes the port's cached file, each with `from` and `to` anchors that name text on the first and last line - Resolve at build time and in the Markdown and LLM exports from one function, and drop the anchors from the rendered and exported fence - Fail the build, naming the page, when `from` matches no line or several, when `to` matches nothing after `from`, when the range is reversed, and when the titled source block is missing or duplicated - End a range at the first `to` match after `from`, so a block can end at a closing `fi` or `}` that the file repeats - Accept single-quoted attribute values, so an anchor can hold double quotes - Test the resolver, the three failures against a clean control, and the HTML and export paths on a page, including the port cache
why: Each native example opened with its whole script, so a reader met the private socket, the trap, the pane-ID filter and the polling loop at once, with no account of the tmux command behind each part. what: - Restructure attach-and-send-keys, capture-pane-output and workspace-from-file as a short concept paragraph and numbered steps, each introducing one tmux command or idea with a small block and what to observe, then "The complete script" with the unchanged tested file - Take every step block from the page's own tested file through excerpt anchors, so the build fails if a step stops matching the script - Name commands, options and format variables in inline code so the mention pipeline links and badges them; link the guide and concept pages each step relies on; mark keys with the key-cap rule - Keep the old section anchors as ids - List the capture and workspace pages in guide-examples.json so check-example-prose.py runs them; their file hashes are unchanged - Accept a command linked by the mention pipeline in the native-page link test, resolve excerpts before comparing exported fences and prose, and update the key-cap expectation for the new steps - Describe the step blocks on the examples overview Verified: check-example-prose.py --example guide passed for all three pages on tmux 3.7d; 355 tests passed in the focused site files.
why: The TmuxEnvironment example on the Java reference showed `Session
mine = ...` and `.filter(...)` flush against the left margin. The
doc-comment margin was already gone when `javadocToMarkdown` rewrote a
`<pre>{@code ... }</pre>` block, and it then trimmed every line's
leading whitespace, which was the code's own indentation.
what:
- Remove only the block's common margin from a `<pre>` body, line by
line, and keep blank lines blank.
- Stop the opening pattern from consuming the first line's indentation.
- Test the converter and a Java comment through extraction; three of the
new tests fail against the previous implementation, and prose
paragraphs still reflow.
why: Six Java examples stored their code with every leading space removed. what: - Regenerate java.json with gen-api-model.mjs at the revision the model records. Only `examples[].code` changes, in six symbols: TmuxEnvironment, EventSubscription.stream, Notification, Pane.run, WindowLayout and FakeTmux.
…riables why: Prose across the site names tmux options, hooks and format variables that neither the CLI Manual nor the C source reference indexes. A catalog needs each name's type, scope, default and source line for every pinned release, read from the tmux source rather than retyped. what: - Read options-table.c and format.c at each pinned commit: scope, type, default, range, choices, array and style flags, accepted spellings, the literal calls that fire each hook, and the object a format callback reads - Take descriptions from the tmux.1 snapshot, whose digest must match tmux.1 at the commit; share a description between consecutive entries that have none of their own - Refuse an unresolved table cell, a variable with no source location and a snapshot from another release instead of guessing - Add --check, which verifies digests and shape offline and regenerates and compares with --source, plus a negative script, in the medium loop and the publication audit - Commit site/src/data/tmux/catalog/<version>.json Measured: tmux 3.2a has 104 options, 61 hooks and 200 format variables; tmux 3.7c has 153, 68 and 258.
why: A reader who meets `destroy-unattached` or `session_attached` has nowhere to look it up. The CLI Manual indexes commands and the C source reference indexes declarations; neither answers what an option, hook or format variable is, which scope it has, or how it changed between releases. what: - Add /tmux/<version>/catalog/ with a section page per kind and an entry page per name, in the C reference's layout: sidebar tree, search with All, Options, Hooks and Formats tabs, kind badges and an entry page - Show scope, type, default, values, release history, the manual text, the source line, the C declarations behind it and the library members whose documentation names it - Serve tree.json for the sidebar and <entry>.preview.json for hover cards - Add "Options, hooks and formats" to the tmux picker, sidebar, overview, version switcher, docs.json and llms.txt; keep older releases out of the sitemap - Resolve a name's catalog page by release, and keep the matching logic for single words, shared names and command names in one module
why: Docstrings, guides, the CLI Manual and the Markdown exports already
badge tmux names, but an option, hook or format variable led to a manual
anchor. The catalog answers what a name means and which release has it,
so every mention should reach it, and the C declarations and library
members that wrap these names should reach it too.
what:
- Retarget tmuxEntityHref: commands stay in the CLI Manual; options,
hooks and format variables resolve to the catalog page of the selected
release, and an unknown or absent name has none. Manual hover cards
keep their manual destination through tmuxManualEntityHref
- Read a whole literal ("session-created", after-new-window[0]), a
separate hyphenated word of a code run, `#{...}` variables with their
modifiers, quoted names in prose, and the argument of set-option and
set-hook; link a single word or a shared name only beside the word
option, hook or variable
- Keep a language API symbol ahead of a catalog name in HTML and Markdown
- Link names in the CLI Manual text, and each option, hook and variable
it defines to its entry
- Show "tmux catalog" on library members that wrap options or hooks, on
the C declarations of the option, format and notify tables, and in
their Markdown exports
- Count mentions across guides and API docs in an outer-loop test
Measured: of 1791 option, hook and format mentions across the guides and
API docs, 1677 now reach a catalog page, 18 reach a library symbol and
96 stay plain (keyword arguments, parameter names, doctest output).
Before, none could reach a catalog page.
why: The extraction rules, URL scheme and linking order are decisions a maintainer will want to change, and they live across a script, a library and a page. what: - Record the entry kinds and the tmux table each one comes from - Record the extraction guarantees, the URL scheme and the sidebar label - Record the order in which a mention resolves, and what stays plain
why: Probing every extractor with an indented example showed the C++ one flattening a Doxygen `\code` block. `textOf` folded runs of spaces and turned each `<codeline>` into running text, so `a(); b(); c();` reached the page on one line. No committed C++ comment uses `\code` today, so no model changes. what: - Render each `<programlisting>` as a fenced `cpp` block, one line per `<codeline>` with `<sp/>` as a space, and hold it aside while the surrounding text is folded. - Share entity decoding with `codeOf`. - Test indentation, entities and the text around the block; the test fails against the previous extractor.
why: Six Java examples were stored with every leading space removed and nothing noticed: the code still parsed and every link resolved. what: - `check-example-indentation.mjs` finds each multi-line, comment-derived example in its declaration's source file at the revision the model records and compares relative indentation line by line. A block the source does not hold verbatim is counted as unlocated, a port without its checkout as skipped. - `check-example-indentation.negative.mjs` plants the Java shape as a git checkout and model: the flattened example fails and names the line, the intact one and a clean control pass. - Run both in `test-all.sh` after the source-link check. - Measured across the committed models: the six Java examples fail before the fix and none fail in any port after it. Complete examples and console blocks are generated, not comments, so they are not judged.
why: The badge underline check failed in CI and in a local full run on "the badge is underlined while hovered", though no decoration reached the badge: the computed decorations and the pointer-free paint agreed. The two screenshots of the badge strip differed in ten pixels at the rounded corners, by one channel unit each (122 against 123), because the badge sits at a fractional offset and a repaint, such as the one a first hover preview triggers, rasterizes its antialiased corners a unit apart. With the preview answering 150 to 350ms after the hover, 4 of 25 runs of the sample failed this way. A real underline moves whole pixels: the largest channel change was 222. what: - Compare the with and without decoration screenshots with pixelmatch at its default threshold, so antialiasing noise passes and an underline fails; restoring the old anchor rule still fails every variant, at rest and hovered - Add the Python attaching-to-tmux guide, whose C and $ badges sit in prose links, to the sample
why: The parameter list leaves out an undocumented `self` receiver, but the Rust signature still linked it, so every by-value `self` method (Session::kill, ServerBuilder::build and others) pointed at a `.parameter.self` anchor that no longer exists and the assembled-site link check failed. what: - Render an undocumented `self` receiver as a keyword in Rust signatures, using the same rule that drops it from the parameter list - Keep `&self` and documented receivers linked, since the list keeps them - Test that a by-value `self` method links only the parameters it lists
why: The "Choose a solution" menu and the documentation picker printed a two-sentence support-policy paragraph under every concept product, and the concept badge's tooltip repeated it. A menu is for choosing; a reader scanning it got a block of policy text instead of a label. what: - Show concept products in both menus with the same one-line summary other products use, "Working example of the core library", beside the concept badge, and drop the paragraph under an expanded group - Shorten the concept description to "A working example of the core library. It can change without notice." for page notices and data, and use the one-line summary for the badge tooltip and screen readers - Say it in one clause on the MCP overview, linking the concept page for the full explanation - Make the navigation check refuse a paragraph in an expanded menu group and require the one-line summary
why: A kind badge centred its mark's em box, so a capital such as the S of a struct sat about half a pixel high and a lowercase o or m about half a pixel low inside the chip. what: - Trim each badge label to the height of its ink with text-box: cap height for capitals and symbols, x-height for the x-height letters (a, m, o, p, r), so the grid centres what the reader sees - Tag x-height marks with data-mark="x" wherever a badge is built: API badges, the reference tree, prose and tmux mentions, and MCP links - Browsers without text-box support keep the centred em box
why: The GitHub and Packages menus drew Core Library, MCP and Workspace Manager with the same icon, two-line layout and spacing as the links beneath them, so a section name read as another clickable row. The names were never links; they only looked like them. what: - Render each product as a small muted uppercase label with no icon or summary line, no pointer cursor, and no hover, focus or active state - Inset a product's rows under its label, with a larger gap before each label than after it - Name each group by its label with aria-labelledby, using ids that carry the placement so the bar and Menu copies stay unique - Give a menu of one product no heading, since there is nothing to tell apart - Add pickerSections() to shape a menu's rows by product, and test its order, coverage and which menus carry headings - Read each row's group from data-group instead of a relabelled aria-label in the picker tests
why: Nothing measured whether a product heading in the GitHub and Packages menus stayed a label. A heading that took a tab stop, a pointer cursor, a hover paint or an arrow-key stop, or that survived a filter with no rows under it, would pass every existing check. what: - Add check-header-menu-sections.mjs and its --header-menu-sections flag, and run it in the sample and the full browser run - On Python, Java and .NET, assert each heading is not focusable, has no pointer cursor or hover or press change, labels its group by id, differs from item typography in size, case and colour at 4.5:1 contrast, and that Tab and the arrow keys never land on one - Assert filtering hides a heading with its group, restores it on clear, and removes the group name from the accessibility tree - Check Kotlin, a single-product port, has no heading or group role - Check light and dark at 1440 and 390px, with the menu inside the viewport as the phone sheet - Add a negative control: the check rejects the origin/main markup and CSS, and each of a focusable, pointer, hover, plain-typography, flush and unfiltered heading
why: The picker badges a product with its release stage, but the registry data had no stage for Python's MCP server or tmuxp. Python declares its stages on PyPI, where libtmux-mcp is Pre-Alpha while libtmux and tmuxp are Production/Stable, so a version string alone cannot say it: 0.1.0a22 reads as alpha. what: - Probe libtmux, libtmux-mcp and tmuxp on PyPI and record each project's Development Status classifier as its maturity - Leave libtmux's git tag off the two projects released from other repositories - Add the Python entry to registry.json; the other ports' entries are unchanged - Add releaseMaturity() to read a stage from the declaration, the version or the tag, and fail on a stage it cannot read - Add productStatus() to give a product its badge: concept for another port's companion, otherwise its release stage - Add one-sentence summaries per badge and the guide section that explains them, and test every port's products against them
why: Core Library carried no badge while MCP and Workspace Manager carried concept, and a footer line plus a paragraph under each companion explained both. A menu is for choosing, so the explanation belongs on the badge's hover card, with the full text on the guide. A focusable badge inside a row's summary or link would nest one control in another, so the badge has to be the row's sibling. what: - Replace ConceptBadge with StatusBadge: concept or a release stage, from the same data as the install commands, on every product row of the documentation picker, the solution menu and the MCP overview list - Place the badge beside the product name with CSS anchoring, and at the row's end where a browser lacks it, as a sibling of the row's control - Open a card on hover, keyboard focus and tap with the stage as its title, one line of about eight words, and a Read more link to the concept and alpha section; keep it open while the pointer or focus is inside, and close it on Escape before the menu sees the key - Say what each product does in every row, from the picker summaries and the same on every port: API reference and guides, Tools for connected assistants, Repeatable development environments - Remove the footer status line, the paragraph under an expanded concept group and the concept summary constant - Keep the trigger's badge a plain label, because the trigger is itself a control; its name and description carry the status - Add the release stages to the guide's concept and alpha section - Read the trigger and group names without the badge in the checks
…rowser why: Nothing measured that every product row carries its stage badge, that a menu row stays a label and one line, or that a badge explains itself without nesting a control. A missing library badge, a paragraph under a row, a card the keyboard cannot reach, an Escape that closes the menu first, or a badge button inside a summary would pass every existing check. what: - Add check-status-badges.mjs and its --status-badges flag, and run it in the sample and the full browser run - On Rust, Go, Python, Julia and Java, in the picker and the solution menu, assert every product row has exactly one badge beside its name holding the stage its data gives, Core Library included - Assert each row shows its label and one picker summary line, the same on every port, with no paragraph, and that the footer line is gone - Assert no interactive element sits inside another, in both menus - Assert the card opens on focus and hover, is titled with the stage, holds one line under sixty characters and a Read more link that Tab reaches and that resolves to the guide's section, and closes on Escape with focus back on the badge and the menu still open - Assert a phone tap opens and a second tap closes the card - Check light and dark at 1440 and 390px - Add a negative control: the check rejects the pre-badge markup for both menus, which fails on Core Library, and each of a second or wrong badge, a distant badge, a paragraph or long summary, a long card line, the footer line, a nested badge, a card that never shows, no hover, no Escape, an unreachable link and a broken section link
why: A menu row is a label and one line. Nothing stopped a paragraph from reaching the GitHub or Packages menus the way it reached the documentation picker. what: - Assert each row of the header menus has one short line under its label and no paragraph, and no text block in a menu runs past a short line - Add a negative control that puts the long concept paragraph in a menu - Load a page again once when the development server replaces it while optimizing dependencies
why: The text-box trim centred each mark on its ink in theory, but at 1x the result still rounded: an S sat half a pixel high, and an m moved from half a pixel low to half a pixel high, with more space under it than over it. A 17px badge leaves 15px inside its border, an odd height, so no whole-pixel position centres a mark. what: - Grow the compact kind badge from 17px to 18px, leaving an even 16px inside the border; capitals, ascender letters and symbols now sit exactly centred at 1x and within a quarter pixel at 2x - Drop the text-box trim and lift the x-height marks (a, m, o, p, r and the colon) by one pixel, which centres them the same way; only p, whose descender hangs below, stays a pixel low
why: The homepage opens on its default language and switches to the ?port= language once its script runs. After a development-server reload the badge check read the default language's menu and failed with the wrong port. what: - Select the solution menu by its port and wait for it instead of asserting the language right after the page loads
why: Each product row in the homepage solution menu now carries a status badge whose card links to the shared concept page. The launcher check read every link in the menu and required each to point into the chosen port, so the card's link failed it for every port. what: - Read only the menu's destination links when checking that a port's solutions stay within that port
why: The concept guide explained libtmux.org's own badges inside the tmux guides, and parity and translations sat loose at the locale root. None of them is tmux documentation, and each loose /en/<page>/ spends the root namespace. what: - Publish "Support and release stages" at /meta/support/, shortened to four sections. It keeps the #concept-and-alpha section that the status badge cards, the concept notice and the MCP overview link to. - Move parity and translations to /meta/parity/ and /meta/translations/ and update the locale switcher, the untranslated-page notice, the MCP overview, the Japanese home page, the table check and the page-port link list. - Remove the guide from the tmux collection, so the tmux sidebar and the tmux exports no longer carry it. - Redirect /tmux/guides/concept-examples/, /parity/ and /translations/ with the existing RedirectPage (canonical link, script replace and a noscript http-equiv refresh). The catch-all route emits them in the root build of every locale, and the sitemap omits them. - Add meta-pages.test.ts: the redirect table, no tmux sidebar entry (the old entry restored as the negative control), the badge fragment resolving on the support page, and an allowlist of what may sit directly under the locale root (planted pages as the negative control). mcp and third-party-notices are still loose and listed as undecided. - Point the status-badge gate at /meta/support/. Verification: focused vitest files pass (567 tests, 124 skipped for the absent assembled tree); astro check reports 0 errors; the new test fails with the old guide restored or a page planted at the root. The status-badge gate timed out at its 10 s cap on its first run at load near 25 and passed on the second. A full shell build emitted the three meta pages, then hit a 25 minute limit in the tmux reference pages before it reached the redirect routes.
why: Pages about libtmux.org live under /meta/, and the notices page was the last of them still loose at the locale root. what: - Move the notices page to /meta/third-party-notices/ and redirect /third-party-notices/ there in both locales, as for the other moved pages. - Point the footer on every page and the shell footer that the Sphinx pages load at the new URL. - Skip the meta section when grouping a port's documentation menu, as the notices page was skipped before. - Count the notices page with the other meta pages in the root allowlist test, which now leaves only mcp undecided.
why: /mcp/ repeated what each port's MCP page and the homepage solution menu already say: the install widget for one server, a port list and an in-development note. The maintainer chose to drop the root page rather than keep a second overview. what: - Remove the /mcp/ route and its Overview component. The old URL redirects to the site home in both locales, where the solution menu lists each port's MCP server. The redirect target may now be empty, meaning the build's home. - Point the header menu's MCP chip at the current port's MCP home, and omit it on pages with no port or a port without an MCP server. - Do the same in the shell the Sphinx, rustdoc and DocC pages load, which now reads MCP availability from the generated port table. - Send the tool catalogue's install sentence to the Python MCP page, or the building port's. - Drop comments that described the retired page. - Test the redirect, the removed route, the header chips and the shell chips, each with a planted regression as the negative control. The root allowlist now leaves only /mcp/tools/ undecided.
why: The tmux sidebar's CLI Manual, catalog and C source reference links took the docs build's version slug. A local or production build is `latest`, which happens to be a tmux release too, but a pull-request preview is `pr-157`, so every tmux page in English and Japanese linked /tmux/pr-157/manual/, a page that does not exist, and the preview's link check failed. what: - Give the sidebar the version the page's documentation context already uses: the port's version on a port page, the tmux release on a tmux page - Let the glossary navigation harness swap in a stub for a child template - Render the tmux sidebar under a pull-request slug and require tmux release links
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.
Fixes from the 2026-10-18 review of the reference pages, on one branch so they share one CI run, one preview and one deploy. #158 to #163 were folded in here; each closed PR keeps its full discussion and evidence. Later fixes from the same review land on this branch too.
Sticky member and group headings
Long member lists scrolled the Members heading and the active group heading out of view, so a reader lost track of which group a member belonged to. Both headings now stay stuck below the site header and section row, and release at the end of the Members section. This was P0 6, held back from #156 until review found the problems below.
What a reader gets
Fixed after the first review
Verification
node site/scripts/check-dev.mjs --api-stickyruns focus, link, repeated-link and typed-hash scenarios in Chromium, Firefox and WebKit at 1800 and 390px. Its controls fail in each engine without the focus clearance, without the typed-hash handling, or with an unpositioned Members bar.site/test/api-page-contents.test.ts: 69 tests, including the new cases that fail on the unfixed sources.Known gaps
Keyword-argument literals stay unlinked (was #158)
A prose literal shaped like a keyword argument (
name:orname: value) stays plain in HTML and Markdown exports. The RubyServerreference had linkedcancel:toCancellation#cancel,clients: truetoSnapshot#clientsandwhere:toSelection#where. A bare name such ascancelstill links. Test:inline-reference-appearance.test.ts, which fails without the rule.Every parameter listed in every port (was #159)
Python, Swift, Ruby and Lua listed only the parameters a doc comment described, so Ruby
Server.startshowed no Parameters section. Every port now lists each declared parameter with its type, and each parameter name in the signature links to its entry.@overloadstub's.self(or Pythoncls, or Luaself) is the receiver and is neither listed nor linked.tmux CLI Manual and C source reference in the sidebar (was #160)
The tmux sidebar ends with CLI Manual and C source reference for the selected tmux version, and the overview cards use the same names as the documentation picker. Test:
documentation-navigation.test.ts.tmux commands, options, hooks and format variables badged and previewed (was #161)
tmux names in guides, port prose and API doc comments render like API mentions: a kind badge (
$command,#format,ooption,hhook), a hover card from the pinned tmux manual, and a link to the manual entry.tmuxEntityHref(kind, name, version)intmux-links.tsresolves all four kinds.list-clients,session_attachedanddestroy-unattachednow carry badges.session_namestill links to the Rust API field, because library symbols outrank tmux names.Tests:
tmux-mentions.test.ts(42) andlink-preview.test.ts. Screenshots are in #161; delete thetmux-mention-badges-screenshotsbranch after review.Declaration controls level with the first signature line (was #162)
The badges,
[source]and permalink beside a declaration are now level with the centre of the signature's first line, also when the signature wraps. On TSServer.sessionsthey sat 4.5px high, because the formatted signature's padding was counted. The fix is insite/src/styles/api.css; the vendored gp-sphinx CSS is untouched.Gate:
checkDeclarationControlAlignmentincheck-native-layout.mjs, run bycheck-dev.mjs --reference-layout. It measures 48 headers across TS, Go, Python, Julia, C#, Kotlin, Scala and the Rust MCP page at 1440, 768, 500 and 390px. It fails on main (-4.50px) and passes here (worst 0.70px, on MCP type headings).Table row permalinks trail the cell text (was #163)
A prose table row's
¶now sits right after the first cell's last text line, hidden until the row is hovered, focused or targeted. Markdown table cells share a0.75reminline inset, so the first column no longer touches the table edge.Gate:
checkRowPermalinksincheck-dev-sample.mjschecks the Rust, tmux and Ruby CLI tables in light and dark at 1440, 768 and 390px. It fails on main ("permalink starts 39.8px after its text") and passes here.Type parameters documented and linked
ModelinSelection.where(criteria: WhereOf<Model>): Selection<Model>was plain text, because the TypeScript extractor never recorded the type parameters of interfaces, classes or aliases. Extractors now record them, and one linker binds every occurrence to the declaring page's new Type parameters section. Member pages say which declaration owns the parameter, and Markdown exports carry the section.Generic[...]bases and TypeVar bounds. C++ covers templates, concepts and\tparam. Julia and Ruby are read from their recorded parameters.swift buildfails on this host (missinglibxml2.so.2). F# models carry no generics, so'Tstays unlinked.cxx.json, because the local Doxygen differs from the one that produced it.check-dev.mjs --type-parametersfollows the links to the declaring anchor on ts, py, rs, go and java, and fails on the oldts.json.tmux key sequences render as keyboard keys
The tmux manual and guides now render key sequences such as
C-b cas<kbd>caps (<kbd><kbd>C-b</kbd> <kbd>c</kbd></kbd>) instead of code.key-string.c(site/src/lib/tmux-keys.ts). ModifiersC-,M-andS-,^X, and the key names the manual spells (Enter, Escape, BSpace, F1–F12, the keypad and so on) count.tmux-keys.test.ts(95 cases) and the manual and plugin tests.check-dev.mjs --tmux-keysasserts the bind-key page's DOM.Kind badges: no dotted underline, centred, one gap; cards are not previews
M/C). The name now draws the underline and the badge draws none. Non-preview badge links draw their solid underline on the name only.align-self: center) with a.25emgap everywhere. The gap had been anywhere from.2emto.67em, and badges sat 1.5px to 8px low in body text, headings and tables. Nav and sidebar rows were already centred and keep their 4px gap.reference/, so the preview script marked it and painted a dotted underline across the whole card on hover. Links that wrap blocks, and.doc-card, are no longer preview candidates.checkKindBadgeLinksasserts one dotted underline on the name, the badge centre within 1px and a gap of about.25em.checkBlockLinksUndecoratedhovers every block link on the workspace, port and MCP overview pages, with a prose page as the inline control.inline-reference-appearance,link-preview-paintandmcp-referencealso fail on the old source.Member bodies: padding alone sets the inset
On the Go
Server.ConfigFilepage a member body had 20px above its first line and 12px below its last. Elsewhere it was 12px above and 20px below. The cause was a top or bottom margin on the first or last child (a paragraph, a field list or an example) added to the body's 12px padding. One rule insite/src/styles/api.cssreplaces the earlier narrow fixes: edge children ofdl.py > dd, down to three levels, lose their outer margin. A field list that opens the body also loses its divider and top padding. Spacing between siblings is unchanged.Gate:
checkMemberBodyInsets(check-dev.mjs --member-bodies) measures 17 pages across Go, Julia, Ruby, Python, TS, Swift, C#, Java, PowerShell and MCP at 1440 and 390px. It requires the top inset, bottom inset and padding to agree within 1px. Before the fix it failed on 12 pages (76 body lines); now it passes on 54 bodies.Workspace commands, options and keys link to their reference
On the Python workspace topics page,
tmuxp load,tmuxp freezeandshell_command_beforewere plain code. Workspace names never reached a resolver, and where one did link it often went to the wrong target:freezeto a library function,searchto the Python standard library,session_nameto a tmux format.scripts/gen-workspace-entities.mjsgeneratessite/src/data/workspace-entities.jsonfrom each port's CLI Manual commands and option and key tables. The anchors are shared with the rendered rows.--checkruns in the test loops.<program> <command>(e.g.tmuxp load,tmux-workspace load) links on any page of a port that ships that program. A bare command, option or key links on user-facing workspace pages, and the page's own port and product win over library, standard-library and tmux names. Internals and API-index pages keep their library links.$badge, optionso, and keys a new:badge. MCP tool and prompt names inside longer code runs now link without a badge. Markdown exports keep plain links.workspace-mentions.test.tswalks every workspace and MCP page through the real pipeline against an independent oracle, and fails on the reported page without the linker.MCP tool pages: rendered descriptions and API-style arguments
On the Python
create_sessionpage, theenvironmentargument showed a raw:func:libtmux_mcp._utils._coerce_dict_arg.-eKEY=VALUEwas unstyled,show-environmentwas not linked, and the Arguments list looked unlike the API pages._coerce_dict_arghas no page... warning::renders as an aside.symbols: falseflag stops an argument named like a library attribute from linking to it.name? = default (type) #.Record<string, T>shows as a map.create_sessionare unchanged, and folded variant anchors stay as aliases.mcp-descriptions.outer.test.tssweeps every port's MCP descriptions and fails on main's rendering, with clean controls.tmux examples build up to their scripts
The native tmux example pages opened with the complete script. Each page now starts with a short concept paragraph and works through numbered steps, one tmux command or idea at a time, each with a small block and links to the manual. "The complete script" comes last and is tested unchanged.
excerpt="<title>"orfile="<path>"plusfromandtotext anchors. The build fails if thefromanchor matches no line or more than one, or iftois missing or abovefrom. Markdown exports resolve the same excerpts. 29 tests cover this, including mutation checks on each guard.Indentation kept in Javadoc examples
The Java
TmuxEnvironmentexample rendered flush left. The Javadoc extractor stripped the*margin and every space after it, so the model storedtry (…) {\nSession mine = …. It now strips only the margin, so relative indentation inside<pre>{@code}survives, and the Java model is regenerated.examples[].codechanged in the regenerated model.\\codelisting onto one line. No committed C++ comment uses\\codeyet.scripts/check-example-indentation.mjscompares each comment-derived example in every committed model against its source, and runs intest-all.sh. A negative script plants the Java shape.tmux options, hooks and formats catalog
/tmux/<version>/catalog/addsoptions/,hooks/andformats/indexes and a page per entry, in the C reference's layout, with "Used by" lists and hover cards. tmux 3.2a has 104 options, 61 hooks and 200 formats; 3.7c has 153, 68 and 258.tmuxEntityHrefnow sends options, hooks and formats to catalog pages. Commands stay in the CLI Manual.scripts/gen-tmux-catalog.mjs --checkand its negative script run in the test loops. A crawl of 1,335 catalog pages found no broken links.Verification of the combined branch
pnpm run lintexits 0. The two remaining warnings are in files this branch does not change.