Skip to content

Show the workspace and control examples on the docs site - #93

Merged
tony merged 5 commits into
masterfrom
examples-standalone-92
Nov 5, 2026
Merged

tony merged 5 commits into
masterfrom
examples-standalone-92

Conversation

@tony

@tony tony commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Closes #92

What changed, and why:

The docs site shows each API example as a program a reader saves in an empty directory with a one-gem Gemfile, and states one tmux floor, 3.3a, for every page. Three programs could not be shown that way, so libtmux/docs#247 held them back. This makes all three publishable.

  • examples/api/workspace_apply.rb writes its workspace document to a temporary workspace.yaml and loads that, instead of loading ../workspace.yaml from the checkout. Workspace.load still reads a file, the expected output is unchanged, and a unit test keeps the document equal to examples/workspace.yaml.
  • Version 2 of examples/manifest.json lets an API example list the tmux capabilities it needs in api.capabilities; the two control programs list control-mode. scripts/examples resolves each id against the library's capability registry. A documented symbol the library refuses on every call below a capability's release makes the capability required; the command channels and select_layout, which pass the caller's own command or layout on, do not. An unknown or missing capability fails the check. A version 1 manifest, as in earlier releases, is read as before, and the check loads the registry only for a version 2 manifest, so a docs rebuild of an earlier release with this generator exports as it did, with no release stated.
  • The docs export adds tmux_releases, the release each API page states: the highest release of its capabilities, or the port floor, so the docs site can read a release instead of ranking tmux releases itself. libtmux/docs does not read it yet; the follow-up there drops the three held programs and states each page's release.
  • The registry lists more of the routes to each refusal: Async::Server#open_control and ControlConnection.new for control mode, Async::Server#delete_buffer for named buffer deletion, Async::Server#new_session for tmux 3.7's name check, run_group and the Async run and run_group in every capability and workaround that listed Server#run, and Async::ControlConnection#exchange beside ControlConnection#exchange. capabilities.json is regenerated.
  • The installed-example test expects UnsupportedFeatureError for the capabilities a program lists that the daemon lacks, by the library's own available?, in place of a match on #open_control and a literal 3.7.

The capability ids were chosen over a hand-written api.tmux release and over a release derived from the registry's apis lists; the third commit's message gives the reasons. LibTmux::Async::ControlConnection.new does not check for control mode itself; that is left as it is.

Checks run:

  • scripts/check mid at each of the five commits: 299 to 306 runs, 0 failures.
  • scripts/export-docs from this branch, run in a checkout of v0.1.0.alpha.2 (no capability registry) and of v0.1.1 as docs.yml runs it: both export, and api.json is byte-identical to master's generator's export of the same tree (699 and 701 public methods).
  • scripts/check packaging on tmux 3.8a: 5 runs, 0 failures. test/packaging/package_test.rb on tmux 3.3a, where the control programs take the refusal path: 1 run, 190 assertions, 0 failures.
  • test/integration/tmux_features_test.rb on tmux 3.3a (14 runs) and 3.8a. The new test runs every route the registry names for named buffer deletion; planting run_group without the gated command fails it with "UnsupportedFeatureError expected but nothing was raised".
  • Async::Server#new_session(name: "a:b", ...) is refused on tmux 3.7, and split-window -p on tmux 3.4 is refused through Server#run, Server#run_group, Async::Server#run and Async::Server#run_group.
  • Unit tests fail for an unknown id, a missing control-mode, capabilities in a version 1 manifest, a record that names one channel but not its twins, and a workspace document that drifts from examples/workspace.yaml; each was planted and failed.
  • Saved alone in an empty directory with the released gems from RubyGems: workspace_apply.rb prints the expected output on tmux 3.3a and 3.8a (the version on master stops with LibTmux::Workspace::ConfigError); control.rb and async_control.rb raise UnsupportedFeatureError on 3.3a and print their output on 3.8a.

Tool use: Claude Code, directed by the maintainer, wrote the changes and ran the checks above.

why: The docs site shows each API example as a program to save in an
empty directory with a one-gem Gemfile. examples/api/workspace_apply.rb
loaded ../workspace.yaml from the checkout, so saved alone it stopped
with LibTmux::Workspace::ConfigError, and the docs site held it off the
Workspace.load page (#92).

what:
- The program writes the same document to a temporary workspace.yaml
  and loads that, so Workspace.load still reads a file; the planned
  steps, the apply and the expected output are unchanged.
- The manifest description and the libtmux-workspace README excerpt
  follow, and the README no longer says it loads the checkout's file.
- A unit test holds the program's document equal to
  examples/workspace.yaml, which the README and the other workspace
  program still use.
@tony
tony force-pushed the examples-standalone-92 branch from 03587ae to f0d45d1 Compare November 5, 2026 01:55
@tony
tony force-pushed the examples-standalone-92 branch from f0d45d1 to 7573573 Compare November 5, 2026 02:07
@tony
tony force-pushed the examples-standalone-92 branch from 7573573 to 4d16965 Compare November 5, 2026 02:23
tony added 4 commits November 4, 2026 20:32
why: capabilities.json lists, per capability and workaround, the public
methods whose call it can refuse. It missed routes that reach the same
refusal: Async::Server#open_control and ControlConnection.new for
control mode, Async::Server#delete_buffer for named buffer deletion,
Async::Server#new_session for the 3.7 name check, and run_group and
the Async run and run_group in every record that
listed Server#run, since every caller-written command line passes the
same command guard. A reader of the registry, such as a check of which
tmux an example needs, saw those routes as ungated.

what:
- RUN_CHANNELS and CONTROL_CHANNELS name the methods that send a
  caller-written command line. Each capability and workaround that
  listed Server#run lists the run channels, and each that listed
  ControlConnection#exchange lists both control channels.
- control-mode adds Async::Server#open_control and
  ControlConnection.new, buffer-delete-named adds
  Async::Server#delete_buffer, and name-separators-rejected adds
  Async::Server#new_session. capabilities.json is regenerated.
- Unit tests pin control mode's routes and require a record that names
  one channel to name its twins. An integration test runs every route
  the registry names for named buffer deletion: each is refused below
  tmux 3.4 and works on newer tmux.
why: The docs site writes one intro for every API example, "tmux 3.3a
or newer", because the manifest could not say that a program needs a
newer tmux. examples/api/control.rb and async_control.rb open a control
client, which the library refuses below tmux 3.7, so the docs site held
both pages back (#92). A release written by hand in the manifest would
repeat what the capability registry knows, and a release derived from
the registry's apis alone is wrong: those lists mix methods refused on
every call with command channels refused only for some commands, so
Server#run would make an unrelated example need tmux 3.8.

what:
- Manifest version 2 lets an API example list capability ids in
  api.capabilities; the two control programs list control-mode. A
  version 1 manifest, as in releases before this, is read as before,
  so a docs rebuild of an earlier release still exports, with no
  release stated, since that manifest cannot say which program needs
  a newer tmux.
- scripts/examples resolves each id against the library's registry. A
  documented symbol the library refuses below a capability's release
  on every call makes that capability required; the command channels
  and select_layout, which pass the caller's own command or layout on,
  do not. An unknown or missing capability fails the check. A program
  may list a capability its documented symbols do not reach, such as a
  second control example; the packaging run expects it to be refused
  on a tmux without it.
- A docs rebuild of an earlier release runs the checker with that
  release's library loaded, which may have no registry at all, as in
  v0.1.0.alpha.2. The checker loads the registry only to check a
  version 2 manifest and writes the channel list out, and a test checks
  a version 1 manifest in a process with no registry.
- The docs export adds tmux_releases: for each API program, the highest
  release of its capabilities or the port's floor, ranked with the
  library's own release order, so the docs site reads a release instead
  of ranking capabilities itself.
- CONTRIBUTING describes the field.
why: The installed-example run decided which programs an older tmux
refuses by matching symbols that end in #open_control and comparing the
daemon with a literal 3.7. A program that needs another capability
would have failed on the CI cells below it, and a change to the control
release would have gone unnoticed here.

what:
- A program's listed api.capabilities that the daemon lacks, by the
  library's own available? check, are the ones it must be refused for:
  it must exit with LibTmux::UnsupportedFeatureError. The message is not
  matched, since some refusals name the daemon's release instead of the
  capability's.
- needs_control? and control_daemon? are removed.
why: The workspace and control examples now run as the docs site shows
them, and the registry lists more of the routes to each refusal.

what:
- Three 0.1.2 entries: workspace_apply.rb runs saved alone, API
  examples declare the capabilities they need in manifest version 2,
  and capabilities.json lists the Async, run_group and
  ControlConnection.new routes.
@tony
tony force-pushed the examples-standalone-92 branch from 4d16965 to fbe8550 Compare November 5, 2026 02:33
@tony
tony merged commit 0bf7834 into master Nov 5, 2026
14 checks passed
@tony
tony deployed to docs-preview-cleanup November 5, 2026 02:38 — with GitHub Actions Active

This branch was successfully deployed

1 active and 1 inactive deployments
docs-preview-cleanup — fbe8550e Deployed Nov 5, 2026 by tony via cleanup #66
docs-preview — fbe8550e Deployed Nov 5, 2026 by tony via publish (pr-93, pr, false, docs-preview, true) / publish #328
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Three API examples are held off the docs site's Ruby pages

1 participant