Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 6 additions & 1 deletion .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,12 @@ What a change is expected to carry:
decision the measurement forced belongs in
[`docs/decisions/`](../docs/decisions/) as a short ADR.
- **A changelog entry, when a caller can observe the change.** It goes under
`## Unreleased`. Nothing enforces this, which is why it is written down.
`## Unreleased` in the `CHANGELOG.md` of the module it changes, or in the root
file when it spans modules; [`WRITING.md`](WRITING.md#changelog) says which.
Nothing enforces that an entry exists, which is why it is written down. What
is enforced is the file: `python3 -m tools.ci.check` fails when a published
module loses its changelog or its `## Unreleased` section, and
`tools/verify-staged-release.sh` refuses a jar that does not carry it.
- **Nothing generated-looking.** Names that say what a thing is for, comments
that say why rather than what, no abstraction without a second caller.

Expand Down
13 changes: 13 additions & 0 deletions .github/WRITING.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,19 @@ observe.
Entries land under `## Unreleased`. The maintainer assigns the version when
cutting a release, so nothing written here predicts one.

Each published module keeps its own `CHANGELOG.md` beside its README, and an
entry goes in the file of the module it changes: `libtmux-mcp/CHANGELOG.md` for
the MCP server, `libtmux/CHANGELOG.md` for the core, and likewise for the other
eight. The root `CHANGELOG.md` holds what belongs to no single module: a change
that spans modules, and documentation, CI, tests, build and release tooling and
`libtmux-bom`, whichever module they concern. An entry lives in exactly one
file. The modules are released together, so a release heading appears in each
module's file from the release that first shipped the module, and a release with
nothing for it says ``No entries for `libtmux-mcp`.`` under that heading, and
the root file says `No entries that span modules.` under a release with none.
A link into the repository is relative to the file that holds it, so one in a
module's changelog starts with `../`.

Group under `Added`, `Changed`, `Fixed`, `Removed`, `Documented`, or `Security`,
newest release first, dated `YYYY-MM-DD`.

Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/tmux-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ jobs:

- name: The plan and the docs are sound
run: |
python3 -B -m unittest tools.ci.test_plan tools.ci.test_tmux_ref tools.ci.test_check
python3 -B -m unittest tools.ci.test_plan tools.ci.test_tmux_ref tools.ci.test_check \
tools.ci.test_staged_release
python3 -B -m tools.ci.check

- name: Plan the lanes
Expand Down
7 changes: 4 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ These hold for every change, whatever it touches:
This file routes; it does not restate. Read the policy that governs the change
being made:

- Documentation and user-facing prose — `README.md`, `CHANGELOG.md`, release
notes, commit messages, CLI and help text, API documentation, and source
comments: [`.github/WRITING.md`](.github/WRITING.md)
- Documentation and user-facing prose — `README.md`, `CHANGELOG.md` (the root
file and the one beside each module), release notes, commit messages, CLI and
help text, API documentation, and source comments:
[`.github/WRITING.md`](.github/WRITING.md)
- Contribution workflow, building, testing, and pull requests:
[`.github/CONTRIBUTING.md`](.github/CONTRIBUTING.md)
- Security-sensitive changes: [`SECURITY.md`](SECURITY.md)
Expand Down
1,041 changes: 37 additions & 1,004 deletions CHANGELOG.md

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion MIGRATION.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Migration notes

API changes that require updates to calling code are recorded here. See
[CHANGELOG.md](CHANGELOG.md) for the full change history.
[CHANGELOG.md](CHANGELOG.md), and the changelog beside each module, for the
full change history.

## Next release

Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -764,8 +764,9 @@ $ tmux-workspace load \
- **Tested against real tmux.** The real-tmux suite runs against every
supported release on every push.

Changes are recorded in [`CHANGELOG.md`](CHANGELOG.md); how a release is cut is
in [`RELEASING.md`](RELEASING.md).
Changes that span modules are recorded in [`CHANGELOG.md`](CHANGELOG.md), and
each module keeps a changelog of its own beside its README, linked from it; how
a release is cut is in [`RELEASING.md`](RELEASING.md).

## Documentation

Expand Down
10 changes: 10 additions & 0 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ questions.
So on the `0.1.N` line, while `0.1.2` is being prepared, `libtmuxVersion` is
`0.1.2-SNAPSHOT` and `libtmuxApiBaseline` is `0.1.1`.

### The changelogs

The root `CHANGELOG.md` and the `CHANGELOG.md` of each published module are
dated together. The `Tag v0.1.N` commit renames `## Unreleased` in every one of
them to the version heading and keeps an empty `## Unreleased` above it; a
module with nothing under the new heading says ``No entries for `<module>`.``
Each jar carries its module's file, and
[`tools/verify-staged-release.sh`](tools/verify-staged-release.sh) refuses a
staged jar without it.

## Gate 1 — own the namespace — **done**

`io.github.libtmux` is verified on the Central Portal, against the `libtmux`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,17 @@
// service that is gone.
plugins { id("com.vanniktech.maven.publish") }

// Ship each JVM package's artwork alongside its classes. The BOM has no JAR.
// Ship each JVM package's artwork and its changelog alongside its classes, so the jar a consumer
// holds says what changed in that module. The BOM has no JAR, and the staged-release check refuses a
// jar that lacks the changelog, which `from` would otherwise skip without a word.
plugins.withId("java") {
tasks.named<ProcessResources>("processResources") {
from(layout.projectDirectory.dir("assets")) {
into("META-INF/libtmux/${project.name}")
}
from(layout.projectDirectory.file("CHANGELOG.md")) {
into("META-INF/libtmux/${project.name}")
}
}
}

Expand Down
95 changes: 95 additions & 0 deletions libtmux-jackson/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Changelog

Notable changes to `libtmux-jackson`.

Releases are numbered `0.1.N`, and each release increments `N`. The API is not
settled: any release may change or remove exported identifiers, and the
changelog marks each break. Pin an exact version to avoid one. Only the newest
release is supported, and there are no backports.

The modules are released together at one version, so every release since this
module first shipped has a section here. Changes that span modules, such as
documentation, CI and release tooling, are in the [main
changelog](../CHANGELOG.md).

## Unreleased

## 0.1.1 — 2026-11-01

No entries for `libtmux-jackson`.

## 0.1.0 — 2026-10-25

No entries for `libtmux-jackson`.

## 0.0.1-alpha.19 — 2026-10-24

No entries for `libtmux-jackson`.

## 0.0.1-alpha.18 — 2026-10-19

No entries for `libtmux-jackson`.

## 0.0.1-alpha.17 — 2026-09-26

No entries for `libtmux-jackson`.

## 0.0.1-alpha.16 — 2026-09-26

No entries for `libtmux-jackson`.

## 0.0.1-alpha.15 — 2026-09-26

No entries for `libtmux-jackson`.

## 0.0.1-alpha.14 — 2026-09-20

No entries for `libtmux-jackson`.

## 0.0.1-alpha.13 — 2026-09-20

No entries for `libtmux-jackson`.

## 0.0.1-alpha.12 — 2026-09-19

No entries for `libtmux-jackson`.

## 0.0.1-alpha.11 — 2026-09-12

No entries for `libtmux-jackson`.

## 0.0.1-alpha.10 — 2026-09-06

No entries for `libtmux-jackson`.

## 0.0.1-alpha.9 — 2026-09-06

No entries for `libtmux-jackson`.

## 0.0.1-alpha.8 — 2026-08-30

No entries for `libtmux-jackson`.

## 0.0.1-alpha.7 — 2026-08-22

No entries for `libtmux-jackson`.

## 0.0.1-alpha.6 — 2026-08-16

No entries for `libtmux-jackson`.

## 0.0.1-alpha.5 — 2026-08-16

No entries for `libtmux-jackson`.

## 0.0.1-alpha.3 — 2026-08-16

No entries for `libtmux-jackson`.

## 0.0.1-alpha.2 — 2026-08-16

No entries for `libtmux-jackson`.

## 0.0.1-alpha.1 — 2026-08-16

No entries for `libtmux-jackson`.
1 change: 1 addition & 0 deletions libtmux-jackson/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ answers a different question, so writing it throws `SchemaException`.
- [Filtering guide](../docs/guide/filtering.md)
- [`libtmux-mcp`][mcp] — the separate MCP tool surface
- [Root README](../README.md)
- [Changelog](CHANGELOG.md) — what each release of this module changed

[filter-json]: https://libtmux.org/en/java/latest/reference/io-github-libtmux-jackson-filterjson-filterjson/
[filterexpr]: https://libtmux.org/en/java/latest/reference/io-github-libtmux-query-filterexpr-filterexpr/
Expand Down
138 changes: 138 additions & 0 deletions libtmux-junit5/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Changelog

Notable changes to `libtmux-junit5`.

Releases are numbered `0.1.N`, and each release increments `N`. The API is not
settled: any release may change or remove exported identifiers, and the
changelog marks each break. Pin an exact version to avoid one. Only the newest
release is supported, and there are no backports.

The modules are released together at one version, so every release since this
module first shipped has a section here. Changes that span modules, such as
documentation, CI and release tooling, are in the [main
changelog](../CHANGELOG.md).

## Unreleased

## 0.1.1 — 2026-11-01

No entries for `libtmux-junit5`.

## 0.1.0 — 2026-10-25

No entries for `libtmux-junit5`.

## 0.0.1-alpha.19 — 2026-10-24

No entries for `libtmux-junit5`.

## 0.0.1-alpha.18 — 2026-10-19

No entries for `libtmux-junit5`.

## 0.0.1-alpha.17 — 2026-09-26

No entries for `libtmux-junit5`.

## 0.0.1-alpha.16 — 2026-09-26

No entries for `libtmux-junit5`.

## 0.0.1-alpha.15 — 2026-09-26

### Added

- **`FakeTmux` answers control clients.** A test can attach a control client
to it and push output and notifications to that client, without tmux.
(#23)

### Fixed

- **`TmuxExtension` reaps a fixture whose pid was reused.** A killed run's
fixture is named by its JVM's start as well as its pid, so a live process
that later holds the pid no longer keeps it. (#23)

## 0.0.1-alpha.14 — 2026-09-20

No entries for `libtmux-junit5`.

## 0.0.1-alpha.13 — 2026-09-20

No entries for `libtmux-junit5`.

## 0.0.1-alpha.12 — 2026-09-19

### Added

- **`FakeTmux` tests library consumers without starting tmux.** It is available
in `libtmux-junit5`. (#17)

### Fixed

- **`NamedServerFixture` accepts platform temporary-directory symlinks.** (#17)

## 0.0.1-alpha.11 — 2026-09-12

No entries for `libtmux-junit5`.

## 0.0.1-alpha.10 — 2026-09-06

No entries for `libtmux-junit5`.

## 0.0.1-alpha.9 — 2026-09-06

### Added

- **`NamedServerFixture` safely owns explicitly named test servers.** It binds
teardown to the reported process, socket path, and inode, then fails closed if
any of that identity changes before cleanup.

## 0.0.1-alpha.8 — 2026-08-30

### Fixed

- **`TmuxExtension` proves abandoned servers exited before deleting their
directories.** Successful recovery also removes the abandoned directory.
(#6)

## 0.0.1-alpha.7 — 2026-08-22

No entries for `libtmux-junit5`.

## 0.0.1-alpha.6 — 2026-08-16

No entries for `libtmux-junit5`.

## 0.0.1-alpha.5 — 2026-08-16

No entries for `libtmux-junit5`.

## 0.0.1-alpha.3 — 2026-08-16

### Fixed

- **The fixture's sweep counted servers it had only asked to stop.**
`TmuxExtension` ended an abandoned server with `destroy`, which sends SIGTERM
and returns; tmux answers that by destroying every session and reaping each
pane's children first, so the process outlived the signal by up to 244ms under
load. The sweep now waits for each exit and counts what ended, which is what it
always claimed to return. The tmux matrix failed on that margin on its slowest
lane.

## 0.0.1-alpha.2 — 2026-08-16

No entries for `libtmux-junit5`.

## 0.0.1-alpha.1 — 2026-08-16

### Added

- **Teardown that outlives the process meant to do it.** A test JVM killed
outright left a tmux server running, and once the host's temporary-file
cleaner removed its directory the socket could not be reached to kill it —
nineteen such servers were found on this machine. `TmuxExtension` now names
the owning JVM in the socket path, ends its own servers from a shutdown hook,
and sweeps servers whose owner is gone before making its first one. A live
owner is never touched, so Gradle's per-module workers and the matrix's eight
lanes can share one root. Measurements, and the two rejected designs, in
[`docs/decisions/0006`](../docs/decisions/0006-real-tmux-junit5-fixture-lifecycle.md).
1 change: 1 addition & 0 deletions libtmux-junit5/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ try (Server server = tmux.server();
- [Testing with real tmux](../docs/guide/testing.md)
- [`libtmux`](../libtmux/README.md) — the library this gives you a server for
- [Root README](../README.md)
- [Changelog](CHANGELOG.md) — what each release of this module changed

[control-client]: https://libtmux.org/en/java/latest/reference/io-github-libtmux-control-controlclient-controlclient/
[fake-tmux]: https://libtmux.org/en/java/latest/reference/io-github-libtmux-junit5-faketmux-faketmux/
Expand Down
Loading
Loading