Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
32792ab
docs(ci[deploy]): Publish to libtmux.org under this port's prefix
tony Sep 6, 2026
ad2d4fe
docs(ci[deploy]) Pin the deploy workflow to v1
tony Sep 6, 2026
de5437c
docs(ci[deploy]): Publish to libtmux.org alongside git-pull.com
tony Sep 6, 2026
77a3066
docs(ci[deploy]): Pin the deploy workflow to a commit
tony Sep 6, 2026
4935a3d
docs(ci[deploy]) Move the deploy pin to v0.1.0-alpha.1
tony Sep 6, 2026
164a5bc
DO NOT MERGE: publish from docs-site-deploy, and repin
Sep 6, 2026
a767b6f
fix(ci) Publish the shell tree to libtmux.org, not the Sphinx site
Sep 6, 2026
523251d
docs(CHANGES) A second docs publish, to libtmux.org
tony Sep 6, 2026
1c4d7f1
docs(query_list): Document the two exceptions QueryList raises
tony Sep 6, 2026
9031d2f
docs(constants): Say what the default-scope sentinel means
tony Sep 6, 2026
5c55192
Docs(ci[deploy]): Pin the current docs shell
tony Sep 20, 2026
0526d65
Docs(ci[deploy]): Pin the refreshed docs shell
tony Sep 20, 2026
612b7c5
Docs(ci): Publish selected source revisions
tony Sep 27, 2026
2816683
Docs(ci): Preserve the selected dependency lock
tony Sep 27, 2026
e5e0182
Docs(ci): Pin the merged documentation layout
tony Sep 28, 2026
e3902fe
docs(ci[publish]): Verify publication provenance
tony Sep 29, 2026
68fbf05
Docs(ci): Build from source MCP catalogs
tony Sep 30, 2026
0c40137
Docs(ci): Publish the current documentation UI
tony Oct 5, 2026
a2cc07f
Docs(fix[ci]): use the repaired site publisher
tony Oct 5, 2026
ec7fd64
Docs(ci): Use shared header publication
tony Oct 8, 2026
13f310a
Docs(fix): Initialize navigation before analytics
tony Oct 5, 2026
0eb528e
Docs(ci): Pin verified shared navigation
tony Oct 8, 2026
e099110
Docs(ci): Refresh shared navigation
tony Oct 6, 2026
6669fd1
ci(docs) Handle legacy Python documentation assets
tony Oct 8, 2026
bf3c53b
Use shared header in documentation builds (#762)
tony Oct 8, 2026
37b931b
Docs(ci): Publish reviewed navigation fixes
tony Oct 9, 2026
af6da21
Publish native Python stable assets (#763)
tony Oct 8, 2026
ced0b2c
Docs(ci): Publish native Contents layout
tony Oct 9, 2026
64ede49
Publish reviewed documentation navigation fixes (#765)
tony Oct 9, 2026
2314ca9
Docs(ci): Publish query and transport docs
tony Oct 9, 2026
60406c4
Publish native Contents drawer layout (#766)
tony Oct 9, 2026
d65dbdc
Docs(ci): Publish MCP guides and Copy fix
tony Oct 9, 2026
967bebb
Publish reviewed query and transport docs (#767)
tony Oct 9, 2026
502bcf6
Docs(ci): Publish Copy readiness and port prose
tony Oct 10, 2026
852c5af
Publish MCP guides and console Copy fix (#768)
tony Oct 9, 2026
6e7ab15
Docs(ci): Publish shared navigation fixes
tony Oct 10, 2026
0f5c7bb
Publish Copy readiness and port-specific prose (#770)
tony Oct 10, 2026
212d19b
Publish shared breadcrumb and navigation fixes (#772)
tony Oct 10, 2026
5562520
Docs(ci): Pin reviewed reference UI publisher
tony Oct 12, 2026
88a2abc
Docs(chore): Use the updated reference renderer
tony Oct 16, 2026
efe51ce
Docs(ci): Adopt reviewed site publisher (#773)
tony Oct 12, 2026
3c5c1e2
ci(docs) publish reviewed checkpoint (#776)
tony Oct 16, 2026
1b1c55e
Docs(ci): Add glossary contents and tab shortcuts (#781)
tony Oct 17, 2026
e55eedf
Docs(ci): Fix reference spacing and drawer focus (#782)
tony Oct 17, 2026
cc85513
ci(docs) Update shared publisher (#784)
tony Oct 17, 2026
2833835
ci(docs) Adopt header menus and reference fixes (#786)
tony Oct 18, 2026
d975914
ci(docs) Adopt kind badges and the tmux catalog (#788)
tony Oct 19, 2026
d4a25b4
ci(docs) Read final release tags as stable (#790)
tony Oct 22, 2026
035344f
ci(docs) Add repo and package links to the header (#791)
tony Oct 24, 2026
958fd05
ci(docs) Add sidebar layouts and exact API links (#792)
tony Oct 25, 2026
115e6ca
ci(docs) Add inventories and 0.1.0 release docs (#796)
tony Oct 28, 2026
3a22e29
ci(docs) Lead symbol links with their kind badge (#798)
tony Oct 29, 2026
5334bf4
ci(docs) Tint links by kind, indent the API tree (#799)
tony Oct 31, 2026
4bae2d7
ci(docs) Write symbols each language's way (#806)
tony Nov 1, 2026
5e375b1
ci(docs) Add examples to port landing pages (#811)
tony Nov 1, 2026
ce57dd2
ci(docs) Revise the Workspace and MCP pages (#814)
tony Nov 1, 2026
6dd128d
ci(docs) Rework the port home and add Core home (#817)
tony Nov 3, 2026
1e5415f
ci(docs) Show the MCP replay on port builds (#818)
tony Nov 3, 2026
d44d0be
ci(docs) Refresh Ruby, TypeScript and Rust docs (#819)
tony Nov 4, 2026
81ed870
ci(docs) Draw the MCP example from tmux's state (#820)
tony Nov 5, 2026
19720f6
ci(docs) Play Core examples, swap pages in place (#836)
tony Nov 7, 2026
c385c6b
ci(docs) Draw the Core player's tmux like a client (#847)
tony Nov 7, 2026
9604e15
ci(docs) Refine the example players and overviews (#848)
tony Nov 8, 2026
dd95e47
ci(docs) Refine the pages and list the new ports (#850)
tony Nov 9, 2026
7240413
ci(docs) Update the docs pages and builds (#851)
tony Nov 10, 2026
528d2e6
ci(docs) Update the docs pages and builds (#853)
tony Nov 12, 2026
d8e4d2d
ci(docs) Update the docs pages and builds (#854)
tony Nov 12, 2026
8dc6cdb
ci(docs) Pin the docs workflows to libtmux/docs 15786d72e
tony Nov 14, 2026
deaec07
ci(docs) Pin the docs workflows to libtmux/docs 15786d72e (#855)
tony Nov 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
groups:
actions:
patterns: ['*']
152 changes: 100 additions & 52 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -1,70 +1,133 @@
name: docs

on:
pull_request:
paths: &docs-paths
- CHANGES
- README.*
- 'docs/**'
- 'examples/**'
- 'src/libtmux/**'
- uv.lock
- pyproject.toml
- '.github/workflows/docs.yml'
push:
branches:
- master
branches: [master]
tags: ['v*']
paths: *docs-paths
workflow_dispatch:
inputs:
source-ref:
description: Exact source ref to build
required: true
default: master
version:
description: URL version slug
required: true
default: latest
version-kind:
description: Version policy
required: true
type: choice
options: [trunk, tag, alias]
default: trunk
is-default:
description: Make this version canonical
required: true
type: boolean
default: false
resolves-to:
description: Immutable target for an alias
required: false
default: ''
publish:
description: Publish the selected revision to libtmux.org
required: true
type: boolean
default: false

permissions:
contents: read
id-token: write

jobs:
build:
build-libtmux-org:
uses: libtmux/docs/.github/workflows/port-docs.yml@15786d72eefca1ad802fdd398ee4773e944334c2
with:
port: py
source-ref: ${{ inputs.source-ref }}
version: ${{ inputs.version }}
version-kind: ${{ inputs.version-kind }}
is-default: ${{ inputs.is-default == true }}
resolves-to: ${{ inputs.resolves-to }}
publish: ${{ inputs.publish == true }}

# Both reusable workflows must move together to the same reviewed commit.
# Pull requests build only; dispatch publication is an explicit input.
publish-libtmux-org:
needs: build-libtmux-org
if: needs.build-libtmux-org.outputs.should-publish == 'true'
concurrency:
group: docs-deploy-${{ github.repository }}-py
queue: max
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.build-libtmux-org.outputs.matrix) }}
permissions:
contents: read
id-token: write
uses: libtmux/docs/.github/workflows/reusable-deploy.yml@15786d72eefca1ad802fdd398ee4773e944334c2
with:
path-prefix: py/${{ matrix.version }}
artifact: docs-py-${{ matrix.version }}
version-kind: ${{ matrix.kind }}
port: py
version: ${{ matrix.version }}
label: ${{ matrix.version }}
is-default: ${{ matrix.isDefault }}
resolves-to: ${{ matrix.resolvesTo }}
environment: docs
secrets:
role-arn: ${{ secrets.LIBTMUX_ORG_ROLE_ARN }}
bucket: ${{ secrets.LIBTMUX_ORG_BUCKET }}
distribution: ${{ secrets.LIBTMUX_ORG_DISTRIBUTION }}

# The standalone site keeps its root Sphinx build and follows local symlinks.
# Only a default-branch push publishes it; branch dispatches target libtmux.org.
publish-git-pull-com:
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
environment: docs
strategy:
matrix:
python-version: ['3.14']
env:
UV_FROZEN: 'true'
permissions:
contents: read
id-token: write
concurrency:
group: docs-git-pull-com-${{ github.repository }}
queue: max
steps:
- uses: actions/checkout@v7

- name: Filter changed file paths to outputs
uses: dorny/paths-filter@v4
id: changes
with:
filters: |
root_docs:
- CHANGES
- README.*
docs:
- 'docs/**'
- 'examples/**'
python_files:
- 'src/libtmux/**'
- uv.lock
- pyproject.toml

- name: Should publish
if: steps.changes.outputs.docs == 'true' || steps.changes.outputs.root_docs == 'true' || steps.changes.outputs.python_files == 'true'
run: echo "PUBLISH=$(echo true)" >> $GITHUB_ENV

- name: Install uv
if: env.PUBLISH == 'true'
uses: astral-sh/setup-uv@v10.2.0
with:
enable-cache: true

- name: Set up Python ${{ matrix.python-version }}
if: env.PUBLISH == 'true'
run: uv python install ${{ matrix.python-version }}
- name: Set up Python
run: uv python install 3.14

- name: Install dependencies [w/ docs]
if: env.PUBLISH == 'true'
run: uv sync --all-extras --dev
run: uv sync --frozen --all-extras --dev

- name: Install just
if: env.PUBLISH == 'true'
uses: extractions/setup-just@v4

- name: Print python versions
if: env.PUBLISH == 'true'
run: |
python -V
uv run python -V

- name: Cache sphinx fonts
if: env.PUBLISH == 'true'
uses: actions/cache@v6
with:
path: ~/.cache/sphinx-fonts
Expand All @@ -73,44 +136,29 @@ jobs:
sphinx-fonts-

- name: Build documentation
if: env.PUBLISH == 'true'
env:
# This tree is published to the bucket root, not nested under
# libtmux.org's shell, so the shell's chrome and site-wide search
# are not reachable from here. Keep Furo's own search page and load
# no chrome. See the note in docs/conf.py.
#
# Delete this when the sync below moves under libtmux.org, to a
# per-port prefix. Left behind, the build publishes nested and
# still unskinned — no chrome, and Furo's search where the site's
# own belongs — which reads as the shell having failed rather than
# as a stale flag. tests/test_docs_conf.py covers both shapes.
LIBTMUX_DOCS_STANDALONE: '1'
run: |
cd docs && just html

- name: Configure AWS Credentials
if: env.PUBLISH == 'true'
- name: Configure AWS credentials for libtmux.git-pull.com
uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: ${{ secrets.LIBTMUX_DOCS_ROLE_ARN }}
aws-region: us-east-1

- name: Push documentation to S3
if: env.PUBLISH == 'true'
run: |
aws s3 sync docs/_build/html "s3://${{ secrets.LIBTMUX_DOCS_BUCKET }}" \
--delete --follow-symlinks

- name: Invalidate CloudFront
if: env.PUBLISH == 'true'
run: |
aws cloudfront create-invalidation \
--distribution-id "${{ secrets.LIBTMUX_DOCS_DISTRIBUTION }}" \
--paths "/index.html" "/objects.inv" "/searchindex.js"

- name: Purge cache on Cloudflare
if: env.PUBLISH == 'true'
uses: jakejarvis/cloudflare-purge-action@v0.3.0
env:
CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }}
Expand Down
8 changes: 8 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ it.

### Development

#### Docs publish to libtmux.org (#756)

The docs build publishes to `libtmux.org` under `en/py/latest/` through the
shared deploy workflow every libtmux port calls, and keeps publishing to
libtmux.git-pull.com unchanged. Each destination takes its own build:
libtmux.org gets the site's shared shell with this port's reference nested
at `api/`, libtmux.git-pull.com the Sphinx site at a root.

#### Ruff 0.17.3 for development (#755)

Minimum `ruff>=0.17.3` (was `>=0.17.1`) for development and CI lint checks.
Expand Down
13 changes: 13 additions & 0 deletions src/libtmux/_internal/query_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,11 +315,24 @@ def lookup_iregex(


class PKRequiredException(Exception):
"""Raised when :meth:`QueryList.items` is called without a primary key.

``items()`` pairs each entry with a key, and the list has no opinion about
which field that should be. Set ``pk_key`` on the list before calling it.
"""

def __init__(self, *args: object) -> None:
super().__init__("items() require a pk_key exists")


class OpNotFound(ValueError):
"""Raised when a filter names a lookup that does not exist.

The lookup is the part after the last ``__`` in a keyword, so a mistyped
one — or a field name that happens to end in ``__`` — reaches here rather
than silently matching nothing.
"""

def __init__(self, op: str, *args: object) -> None:
super().__init__(f"{op} not in LOOKUP_NAME_MAP")

Expand Down
9 changes: 7 additions & 2 deletions src/libtmux/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,13 @@ class PaneDirection(enum.Enum):


class _DefaultOptionScope:
# Sentinel value for default scope
...
"""Sentinel meaning "whichever scope tmux would use".

Distinct from passing no scope at all: this is the default value of the
``scope`` parameter, and a call carrying it sends no scope flag. tmux then
resolves the option itself, which for a pane option means falling back to
the window's and then to the global window options.
"""


DEFAULT_OPTION_SCOPE: _DefaultOptionScope = _DefaultOptionScope()
Expand Down
Loading