Repository navigation
Conversation
|
Brings the draft Clojure facade in line with the Java core and feature changes (core minimum change: #69, optional features: #72). The PR stays a draft; its history is kept and this is a fast-forward push to What changed
Verification (Linux/WSL, not the hosted matrix)
Not done: the diff against master still includes the unmerged core and feature commits until those PRs land. The hosted tmux 3.4/3.6/3.7x lanes and macOS are untested by me. |
|
Update: the core branch was rebased onto master and the version grammar now follows the canonical vectors (candidates and development builds rank below their release), so control qualifies on any daemon at or above 3.7 (3.8-rc2 and next-3.8 included, next-3.7 and 3.7-rc2 excluded). The facade's control gate asks the Java core; a third merge of the features branch (rewritten again) is pushed as a fast-forward. Re-verified: Clojure namespace load, namespace guard, unit tests, documentation checks, dependency metadata and spotless pass, and |
6988620 to
e57f5e0
Compare
e57f5e0 to
e295b16
Compare
dfea48c to
ea138df
Compare
f8faa9f to
e77e759
Compare
e77e759 to
80f1754
Compare
80f1754 to
f7a8e83
Compare
6d9297a to
d41e105
Compare
why: Text must follow the bytes this subscriber actually observed. Loss and partial-character eviction need visible outcomes, and every reader must see the same completed terminal map. what: - Apply byte bounds and incremental decoding after each reported gap - Report decoder resets, trailing text and the Java terminal cause - Fence stalled-consumer proofs after all subscriber offers - Run byte, Unicode, failure and competing-reader regressions
why: Explicit close must release a subscription's queued payload even when the control client ended first. Keeping that buffer prevents a stalled adapter from completing shutdown without consuming it. what: - Discard buffered events on close after an earlier remote end - Preserve the first terminal cause and existing loss counters - Verify release without replacing termination or counting new loss
why: Stopping an adapter blocked on a channel put replaced observed upstream loss with zero and discarded the decoder's incomplete tail. what: - Read the final owned outcome after closing its subscription - Preserve upstream loss, cause and trailing text separately - Check stop during pending puts, UTF-8 tails and remote termination - Make the live anchor follow the adapter's subscription
why: A rejected transactional close marked the adapter stopped before releasing its subscription, so a later ordinary stop skipped cleanup. what: - Reject I/O before changing events-channel or adapter state - Keep resource factory vars private and expose observe! for ownership - Reproduce the failed stop and verify subsequent resource release
why: Clojure callers need native arities, ownership contracts and source links; Java reference pages do not describe the facade's vars. what: - Generate each module's reference from public source metadata - Reject stale output in module checks without regenerating it - Document resource and creation options through ordinary docstrings - Keep raw task and runtime factories private - Link the native references from READMEs and guide navigation
why: Readers need complete programs with imports, entry points and an install recipe, rather than excerpts that depend on unseen fixtures. what: - Add eight Clojure programs and a Tools.deps consumer configuration - Reuse the private-server launcher and source-owned API manifest - Execute native entry points and check output, imports and targets - Validate consumer dependency versions against the current baseline - Hint open!'s return type for reflection-free with-open calls
why: Readers need complete programs for layout, movement, task cleanup and observation as well as the basic collection and creation calls. what: - Add workspace, bounded capture, command and observation programs - Execute control refusal examples on the oldest supported tmux - Keep core.async behind an explicit consumer dependency alias - Validate output and cleanup through installed artifacts - Bound demo JVM memory and report CLI verification durations
why: The shared JVM importer rejects unknown variants before selecting a language. Clojure entry points would break existing port imports. what: - Give native namespaces and Tools.deps their own source-owned catalog - Restore the shared JVM catalog and its inventory contract - Validate native setup files, language and source destinations
why: Empty documentation classifiers omit the native API, and the release verifier rejects archives containing only Clojure sources. what: - Generate native HTML with signatures and offline source links - Package references in each module's javadoc classifier - Accept Clojure sources while rejecting resource-only archives
why: Standalone failures otherwise send stream status and causes to uncollected temporary reports, preventing hosted failure diagnosis. what: - Send complete child Clojure exception reports to stderr
why: Related operations and ownership rules need navigable native references at the REPL and in both documentation formats. what: - Link public vars and namespaces with Clojure wikilinks - Resolve authored references and preserve inline code and punctuation - Bundle linked dependency documentation for offline navigation - Order documentation checks after explicit reference updates
why: The generated documentation index has an empty title and heading. what: - Link the optional adapter directly to the documented core.async namespace
why: A terminal line can arrive as more than eight events before a reader runs. what: - Remove undersized event bounds from the output and core.async examples - Preserve gap checks, byte bounds and deadlines
why: A fast process can survive the confirming read and make a race assertion fail. what: - Remove the newly created pane between its reply and the confirming snapshot - Decode its reported identity with the existing RowFormat helper - Preserve the TargetGoneException contract assertion
why: General CI also ran the Clojure live suite against distro tmux outside its endpoint policy. what: - Exclude the duplicate live suite from the general check command - Retain module checks and the ten dedicated Clojure compatibility jobs
why: Keep the deterministic lost-pane test aligned with Spotless. what: - Apply the configured Java formatter to the exception assertion
why: Cancellation must stop later tmux effects without preventing owned resources from closing. Final queued output and dispatch certainty must survive connection shutdown. what: - Fence managed continuations and allow local closure during cancellation - Drain terminated subscriptions before caching their final outcome - Preserve typed closure outcomes and command-group positions - Cover shutdown races and clarify the example's fixture socket input
why: Clojure companion READMEs lack the logos used by JVM siblings. what: - Add module-local Clojure SVG and PNG marks - Center their README titles and record artwork provenance
why: The Clojure module READMEs need the same recognizable artwork and centered introduction as the sibling JVM packages. what: - Add module-local SVG and PNG logos with source artwork provenance - Center the README titles and introductions while preserving examples - Include the supplied logos through the existing JAR resource convention
why: Readers need the shipped capabilities rather than the sequence of development fixes. what: - Describe native values, owned tasks and streams, and optional core.async - Record captured Java graphs, output limits, native docs, and Gradle CI - Link the consolidated Unreleased entries to PR #20
why: Cold JVM startup can exhaust the resource probe deadline before the namespace guard runs on a hosted runner. what: - Initialize JDK resource classes before arming each probe - Check every intercepted operation in the existing test JVM - Keep cold public namespace loading under its independent guard
why: Readers need the shipped capabilities rather than the sequence of development fixes. what: - Describe native values, owned tasks and streams, and optional core.async - Record captured Java graphs, output limits, native docs, and Gradle CI - Link the consolidated Unreleased entries to PR #20
Java tmux-support foundation
This PR targets
masterand builds on the core minimum change (tmux 3.3a floor and hook-free version checks) and the optional-feature change (control requires tmux 3.7, exact-3.7 name validation, and pinned control sockets).Summary
libtmux-clojurewith captured persistent maps and vectors, explicit Java refs for tmux effects, native collection processing, bounded tasks, and owned control streams. The artifact is pre-release.libtmux-clojure-core-asyncwithout adding core.async to the core module.Server.captureServerreturns metadata and entity handles from one capture. Reserved-capacity batches and chains preserve the transport's checked waiting path.The tested README quick start creates a session, acquires one graph, and traverses it locally. The documentation fixture supplies the explicit socket property:
The Clojure guide explains which calls perform I/O, how edited maps differ from actionable refs, and how to close runtimes, subscriptions, and channel adapters.
Contract
control/attach!goes throughServer.controland requires tmux 3.7 or newer before a client attaches. An older daemon raises:tmux/unsupported-feature, reported as not dispatched.subscribe!accepts:encoding(:bytesor:utf-8),:capacity,:max-bytes, and:decoder-capacity. Queued unescaped payload defaults to 16 MiB. Each text subscription decodes preserved bytes per pane and resets after its own gaps, escaping malformed bytes as\xHH.next!reports gaps before the retained suffix, cumulative byte/event loss, and decoder resets. The single terminal map includes trailing partial text and preserves the original:cause;:reasondistinguishes closure, completion, control exit, transport/protocol failure, and unknown EOF. A control exit does not prove daemon death.with-openreleases owned client/runtime resources. Closing the client does not kill the tmux daemon; optional adapters leave borrowed connections open. Acquisition and mutation end in!, while captured traversal stays local. Adapter events-channel closure rejects I/O insidedosyncbefore changing lifecycle state. Raw Clojure resource constructor vars are private; public constructors establish ownership.Verification (Linux/WSL)
Current Clojure module checks, namespace guards, test inventories, dependency metadata, and BOM coverage pass locally with Clojure 1.12.6 on JDK 25 and 27.
:integration-tests:clojureIntegrationTestpasses on tmux 3.3a and 3.7c, including the executable Clojure documentation. The floor checks control refusal; the upper endpoint exercises control and streaming.Repository documentation, Java Javadoc generation, the captured-server integration test, operation-reference freshness, Kotlin API validation, CI planner/check tests, and native-cache regressions pass locally. The split read-back test removes the reported pane before confirmation and checks the lost-target failure.
A copied Tools.deps consumer resolves locally installed library JARs and runs the complete API and capability programs through the copied launcher, including the optional core.async alias, with no library source directories or test classes on its classpath. Native documentation classifiers and the staged verifier have deliberate-break coverage for absent HTML, missing links, and Clojure-only sources.
Hosted workflows exercise JDK 25/27, the tmux endpoints, and macOS; the Checks tab records their current conclusions. Core and optional-adapter consumers pass through Tools.deps, Gradle, and Maven against the signed local stage on the supported runtime. Native binary, source, and documentation archives reproduce byte for byte. The native JARs include their module-local artwork and changelogs. No public registry installation or publication is claimed.
Indexed benchmarks compare Java/Clojure serial capture, bounded process workers, control, batches, and chains with the same output. Separate measurements cover acquisition, map conversion, local queries, fresh-JVM startup, observed output, cancellation, allocation and cleanup. Raw samples retain bounds and uncertainty; the results make no production-capacity claim.
Test plan