An open API service indexing awesome lists of open source software.

https://github.com/vasic-digital/tmux

Optimized + verified containerized tmux build — reproducible across hosts, jemalloc-aware, OOM-protected, 8-test verification gate. Reusable on any Linux system.
https://github.com/vasic-digital/tmux

containerized custom hardened memory-safe oom protected safety tmux tmx tmx-ci tmx-command

Last synced: 4 days ago
JSON representation

Optimized + verified containerized tmux build — reproducible across hosts, jemalloc-aware, OOM-protected, 8-test verification gate. Reusable on any Linux system.

Awesome Lists containing this project

README

          




README

/* Default styles provided by pandoc.
** See https://pandoc.org/MANUAL.html#variables-for-html for config info.
*/
html {
color: #1a1a1a;
background-color: #fdfdfd;
}
body {
margin: 0 auto;
max-width: 36em;
padding-left: 50px;
padding-right: 50px;
padding-top: 50px;
padding-bottom: 50px;
hyphens: auto;
overflow-wrap: break-word;
text-rendering: optimizeLegibility;
font-kerning: normal;
}
@media (max-width: 600px) {
body {
font-size: 0.9em;
padding: 12px;
}
h1 {
font-size: 1.8em;
}
}
@media print {
html {
background-color: white;
}
body {
background-color: transparent;
color: black;
font-size: 12pt;
}
p, h2, h3 {
orphans: 3;
widows: 3;
}
h2, h3, h4 {
page-break-after: avoid;
}
}
p {
margin: 1em 0;
}
a {
color: #1a1a1a;
}
a:visited {
color: #1a1a1a;
}
img {
max-width: 100%;
}
svg {
height: auto;
max-width: 100%;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 1.4em;
}
h5, h6 {
font-size: 1em;
font-style: italic;
}
h6 {
font-weight: normal;
}
ol, ul {
padding-left: 1.7em;
margin-top: 1em;
}
li > ol, li > ul {
margin-top: 0;
}
blockquote {
margin: 1em 0 1em 1.7em;
padding-left: 1em;
border-left: 2px solid #e6e6e6;
color: #606060;
}
code {
white-space: pre-wrap;
font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;
font-size: 85%;
margin: 0;
hyphens: manual;
}
pre {
margin: 1em 0;
overflow: auto;
}
pre code {
padding: 0;
overflow: visible;
overflow-wrap: normal;
}
.sourceCode {
background-color: transparent;
overflow: visible;
}
hr {
border: none;
border-top: 1px solid #1a1a1a;
height: 1px;
margin: 1em 0;
}
table {
margin: 1em 0;
border-collapse: collapse;
width: 100%;
overflow-x: auto;
display: block;
font-variant-numeric: lining-nums tabular-nums;
}
table caption {
margin-bottom: 0.75em;
}
tbody {
margin-top: 0.5em;
border-top: 1px solid #1a1a1a;
border-bottom: 1px solid #1a1a1a;
}
th {
border-top: 1px solid #1a1a1a;
padding: 0.25em 0.5em 0.25em 0.5em;
}
td {
padding: 0.125em 0.5em 0.25em 0.5em;
}
header {
margin-bottom: 4em;
text-align: center;
}
#TOC li {
list-style: none;
}
#TOC ul {
padding-left: 1.3em;
}
#TOC > ul {
padding-left: 0;
}
#TOC a:not(:hover) {
text-decoration: none;
}
span.smallcaps{font-variant: small-caps;}
div.columns{display: flex; gap: min(4vw, 1.5em);}
div.column{flex: auto; overflow-x: auto;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
/* The extra [class] is a hack that increases specificity enough to
override a similar rule in reveal.js */
ul.task-list[class]{list-style: none;}
ul.task-list li input[type="checkbox"] {
font-size: inherit;
width: 0.8em;
margin: 0 0.8em 0.2em -1.6em;
vertical-align: middle;
}
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
/* CSS for syntax highlighting */
html { -webkit-text-size-adjust: 100%; }
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
{ counter-reset: source-line 0; }
pre.numberSource code > span
{ position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
{ content: counter(source-line);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; display: inline-block;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
color: #aaaaaa;
}
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
div.sourceCode
{ background-color: #f8f8f8; }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ef2929; } /* Alert */
code span.an { color: #8f5902; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #204a87; } /* Attribute */
code span.bn { color: #0000cf; } /* BaseN */
code span.cf { color: #204a87; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4e9a06; } /* Char */
code span.cn { color: #8f5902; } /* Constant */
code span.co { color: #8f5902; font-style: italic; } /* Comment */
code span.cv { color: #8f5902; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #8f5902; font-weight: bold; font-style: italic; } /* Documentation */
code span.dt { color: #204a87; } /* DataType */
code span.dv { color: #0000cf; } /* DecVal */
code span.er { color: #a40000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #0000cf; } /* Float */
code span.fu { color: #204a87; font-weight: bold; } /* Function */
code span.im { } /* Import */
code span.in { color: #8f5902; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #204a87; font-weight: bold; } /* Keyword */
code span.op { color: #ce5c00; font-weight: bold; } /* Operator */
code span.ot { color: #8f5902; } /* Other */
code span.pp { color: #8f5902; font-style: italic; } /* Preprocessor */
code span.sc { color: #ce5c00; font-weight: bold; } /* SpecialChar */
code span.ss { color: #4e9a06; } /* SpecialString */
code span.st { color: #4e9a06; } /* String */
code span.va { color: #000000; } /* Variable */
code span.vs { color: #4e9a06; } /* VerbatimString */
code span.wa { color: #8f5902; font-weight: bold; font-style: italic; } /* Warning */

vasic-digital
tmux — optimized + verified containerized build


What's new in v1.0.15 /
v1.0.16 (2026-05-28)




  • Multi-line copy + paste-IN + Claude Code TUI
    support.
    New bind -n M-MouseDrag1Pane copy-mode -M
    (Alt-drag, macOS) and bind -n S-MouseDrag1Pane copy-mode -M
    (Shift-drag, Linux) force tmux selection even when Claude Code / vim /
    less / htop hold the alt-screen with mouse tracking. New
    @clip-read user option + prefix + P paste-IN
    binding pulls the OS clipboard INTO the current pane through
    tmux paste-buffer -p (bracketed paste). See docs/guides/clipboard.md
    for the operator recipe.


  • Workable-items SQLite SSoT
    (cmd/workable-items/).
    Project- local Go binary
    implementing the §11.4.93 SQLite single-source-of- truth for every
    workable item in Issues.md / Fixed.md. Pure-Go
    (no CGO) via modernc.org/sqlite. DB at
    docs/workable_items.db is TRACKED in git per
    §11.4.95
    . See docs/workable-items/README.md
    for the subcommand reference.


  • DOCX export on every Markdown sync.
    scripts/sync_all_markdown_exports.sh now produces
    .docx siblings alongside the existing .html +
    .pdf exports — verified across 44 candidate documents with
    pandoc-emitted "Microsoft Word 2007+" output.




A reproducible, hardened build of tmux with built-in
jemalloc support, OOM-protection helper, and a comprehensive
verification gate. Runs natively on any Linux host
(Ubuntu, ALT, Fedora, Arch, openSUSE, Alpine) where podman or docker is
available. macOS hosts (Apple Silicon + Intel) are
supported via a transparent bridge into the podman machine VM — the
operator gets a working tmx command on the macOS shell with
no manual SSH-juggling.


The 18 verification tests are why this matters: a
typical "build tmux from source" guide assumes the build worked. This
project ships a hard wall — bash scripts/setup.sh will
refuse to PATH-export the binary unless functional tests pass with
positive runtime evidence (cgroup interface readbacks,
/proc files, real session output), backed by a §11.4.4
layer-4 paired-mutation harness that proves the gates aren't themselves
bluffs. SKIPs document precondition gates (CAP_SYS_RESOURCE, libjemalloc
presence, destructive-test opt-in) explicitly. No PASS-bluffs.


Quick install (one command)


Linux host:


git clone --recurse-submodules git@github.com:vasic-digital/tmux.git ~/Projects/tmux

cd ~/Projects/tmux
sudo bash scripts/install_deps.sh # one-time host build deps
bash scripts/setup.sh # build + verify + install (no sudo)

macOS host (Apple Silicon or Intel):


brew install podman                   # one-time: container runtime

podman machine init && podman machine start
git clone --recurse-submodules git@github.com:vasic-digital/tmux.git ~/Projects/tmux
cd ~/Projects/tmux
bash scripts/setup.sh # build + VM-verify + install bridge

After setup.sh reports GREEN: open a new shell, or
source the rc for your shell (source ~/.bashrc or
source ~/.zshrc). Then tmx new|attach|ls|kill
invokes the verified vasic-digital build; the system tmux
command stays untouched and reachable side-by-side.


Architecture
(native dual-OS per-session isolation)


                    ┌────────────────────────────────────┐

│ OPERATOR SHELL │
│ $ tmx new -s mywork │
│ $ tmx new -s build ← own scope! │
└──────────────────┬─────────────────┘

│ scripts/tmx (host-native, OS-aware dispatch)

┌──────────────────────────┴──────────────────────────┐
│ │
Linux host macOS host (Darwin)
│ │
│ for each `tmx new -s NAME`: │ for each `tmx new -s NAME`:
│ systemd-run --user --scope │ tmux -L tmx-NAME new-session -d -s NAME \
│ --unit=tmx-NAME.scope │ "tmx-rlimit-wrapper.sh \
│ -p MemoryMax=<host-adaptive> │ <mem-kb> <cpu-sec> <nproc> \
│ -p CPUQuota=200% -p TasksMax=4096 │ $SHELL -l"
│ -p Delegate=yes │ set -g default-command "rlimit-wrapper …"
│ tmux -L tmx-NAME new -s NAME -d │
│ │
▼ ▼
┌─────────────────────────────────┐ ┌──────────────────────────────────────────┐
│ cgroup-v2 transient scope │ │ POSIX rlimit wrapper │
│ tmx-NAME.scope │ │ scripts/tmx-rlimit-wrapper.sh │
│ ├ MemoryMax = host-adaptive │ │ ├ ulimit -t ← RLIMIT_CPU (enforced) │
│ ├ CPUQuota = 200% │ │ ├ ulimit -u ← RLIMIT_NPROC (enforced) │
│ ├ TasksMax = 4096 │ │ └ ulimit -v ← RLIMIT_AS NOT enforced │
│ ├ Delegate = yes │ │ by XNU (documented gap) │
│ └ tmux 3.6a (Linux ELF) │ │ tmux 3.6a (Mach-O) │
│ status-bar = DJB2(host) │ │ status-bar = DJB2(host) │
│ oom_score_adj = -500 │ │ (oom_score_adj N/A on Darwin) │
└─────────────────────────────────┘ └──────────────────────────────────────────┘
Shell sees the operator's Shell sees the operator's macOS host:
Linux host: full FS, full PATH, full FS, full PATH (Homebrew, system tools,
all system binaries reachable. all Mach-O binaries), `id` = operator's user.

Native dual-OS per-session isolation (architecture
since 2026-05-13). Each tmx new -s NAME invocation creates
its own tmux server (socket tmx-NAME) with OS-native
isolation:




  • Linux — cgroup-v2 transient scope
    tmx-NAME.scope via systemd-run --user --scope.
    Kernel enforces MemoryMax, CPUQuota, TasksMax per-group. OOM in one
    session is contained to that scope — every other session AND
    user.slice survive (Constitution §1 invariant).


  • macOS (Darwin) — POSIX rlimit wrapper sets
    RLIMIT_CPU (CPU time) and RLIMIT_NPROC
    (per-user process count) before exec'ing the operator's
    $SHELL. The Darwin XNU kernel enforces these per-process.
    Children inherit. RLIMIT_AS (virtual memory) is NOT
    enforced
    by XNU for unprivileged processes — this is a
    documented gap; full memory containment on macOS requires launchd jobs
    with HardResourceLimits plist (root). See
    docs/guide/README.md §5.6 for the strength comparison.


Both OS paths deliver the same operator UX:
plain-vanilla tmux behaviour, the operator's shell with full host PATH
(Homebrew on macOS, /usr/local/bin on Linux, all system tools),
per-session resource ceilings applied transparently. No VM. No bridge.
No core@localhost. No bluff.


What you get

Component
Why

tmux 3.6a (latest stable)
Pinned to a known-good upstream tag

Hardened compile flags
-O2 -DNDEBUG -fstack-protector-strong -D_FORTIFY_SOURCE=2,
RELRO + immediate-binding link

Build-time -ljemalloc
jemalloc linked at the binary level (more aggressive RAM return than
glibc malloc)

Runtime LD_PRELOAD=libjemalloc.so
Wrapper preloads jemalloc even on hosts where the linker resolved a
different malloc

OOM-score protection
Optional setcap-enabled helper (tmx-oom-set) sets
oom_score_adj=-500 on the spawned server, making tmux
survive most OOM cascades

Bounded history-limit
Explicit 2000 (the default — explicit so future bumps
are intentional)

Per-session cwd memory (v1.0.13+)
tmx-shell-init.sh installs a
PROMPT_COMMAND / precmd hook inside every
pane; every command's cwd is recorded to ~/.tmx/state.json.
Reopen the same session name → wrapper passes
-c <last-pwd> to tmux new-session; the
pane materialises where you left off. End-to-end guarantee verified by
scripts/tests/43_e2e_cwd_persist_real_shell.sh.

Hermetic install
Built artifact lives in tmux/build/. PATH export points
there; system tmux untouched. Removable via
bash scripts/uninstall.sh (or
bash scripts/setup.sh --uninstall — both delegate to the
same single source of truth).

Verification gate


SUMMARY: PASS=41  FAIL=0  SKIP=3

GREEN: tmux binary verified — safe to PATH-export.

The 44 numbered tests cover (among others): smoke + binary version,
session lifecycle, jemalloc loaded, history-limit honored, clear-history
releases memory, 10 concurrent panes, sustained session no-leak,
OOM-score wrapper, crash isolation scope (cgroup-v2 transient),
hostname-derived status-bar colour (algorithm + integration), memory
pressure under cap, TasksMax stress, concurrent OOM independence,
per-session cgroup distinctness, window-name .exe strip,
scrollback + copy-mode scrolling (operator-path: 3000
lines generated, proven scrolled off-screen, reachable via copy-mode),
HelixConstitution inheritance (submodule + every governance doc's
pointer), CodeGraph index materialisation, cross-platform parity
branches (macOS ↔︎ Linux), tmx-shell-init non-TTY guard, tmx-state cwd
persistence end-to-end across exit + reopen, SSH dispatch to remote
nezha, dispatcher session-name validation, setup install/uninstall E2E,
and — new in v1.0.14clipboard copy-OUT
physically proven
end-to-end (test 44: marker round-trip
through y keystroke → @clip shell-pipe →
pbpaste / wl-paste / xclip /
termux-clipboard-get returns the marker).


Four honest SKIPs document precondition gates:




  • 03_jemalloc_loaded SKIPs if host doesn't have
    libjemalloc — sudo bash scripts/install_deps.sh provides
    it


  • 08_oom_score_adj SKIPs unless running as root OR the
    setcap helper is installed —
    sudo bash scripts/build_oom_set.sh --install enables
    it

  • Tests 12 / 13 / 14 (memory-pressure / TasksMax / concurrent-OOM)
    require TMX_TEST_DESTRUCTIVE=1 — run only on dedicated test
    hosts


A layer-4 paired-mutation harness (Constitution §103) lives at
scripts/tests/meta_test_false_positive_proof.sh: registered
mutations M1–M14 plus CM-CONSTITUTION-INHERITANCE each
break a feature, assert the matching test then FAILs, revert, and assert
it PASSes again. On macOS the harness reports 18 caught / 0
escaped / 6 skipped
(the 6 SKIPs are Linux-only isolation
mutations); the remainder run on Linux via
META=1 bash scripts/test_vm.sh. The gate is not considered
self-validating until every runnable mutation is caught.


Roadmap


See docs/plans/containerization.md
for the per-session containerization plan — each tmux
session running in its own cgroup-bounded container so that:



  • 2 CPU + reasonable RAM cap per session

  • Crash isolation: if one session OOMs/crashes, only that session
    dies; other sessions and their processes survive

  • One-command bootstrap: tmx new <session>
    transparently creates the container


Documentation map


Every project doc lives under a context-named subdirectory of
docs/ per constitution/Constitution.md's
file-layout rule. Every Markdown has a synced HTML + PDF sibling
generated by scripts/export_docs.sh per §11.4.65
universal-Markdown-export.

Area
Doc

Operator guide
docs/guide/README.md
— install, OS-by-OS notes, isolation comparison, troubleshooting

v1.0.14 / v1.0.15 clipboard
docs/guides/clipboard.md
— multi-line copy + paste-IN + Alt/Shift-drag inside Claude Code

v1.0.15 workable-items SSoT
docs/workable-items/README.md
cmd/workable-items/ Go binary, subcommand reference,
honest gaps

v1.0.9 shell-session resume
docs/manual/tmx-shell-integration.md
— end-user master manual with copy-paste worked examples

v1.0.9 shell integration
docs/guides/tmx-shell-integration.md
— operator install/uninstall guide for
tmx-shell-init.sh

v1.0.9 state daemon
docs/guides/tmx-state.md
— operator CLI reference + state-file schema for
tmx-state

v1.0.9 SSH dispatch
docs/guides/tmx-ssh-dispatch.md
ssh <host>-tmx <session> install, security,
troubleshooting

Scrolling (Claude Code TUI + mobile)
docs/scrolling/README.md

CodeGraph (§11.4.78)
docs/codegraph/README.md
— install, per-agent MCP wiring, anti-bluff verification

Architecture plans
docs/plans/native-dual-os.md
— current native-host design (no VM)

docs/plans/per-session-isolation.md
— per-session OOM containment

docs/plans/containerization.md
— original (now superseded) containerization plan

Cycle plans
docs/plans/v1.0.4.md
— this cycle's plan (CodeGraph + covenant propagation + AUDIT
fixes)

Research notes
docs/research/customization/colors.md
— hostname-derived status colour

Governance
Constitution.md — Project
Articles §101–§109 (extends constitution/); CLAUDE.md, AGENTS.md, QWEN.md — per-agent inheritance pointers
+ project-specific overlay

Universal governance
constitution/ submodule
(HelixDevelopment/HelixConstitution, pinned
7f738df)

Live state
CONTINUATION.md — read
first on a fresh conversation

Tracker
Issues.md (open) / Fixed.md (closed with closure SHA +
evidence)

Changelog
CHANGELOG.md — per-release
positive-evidence verification record

Repository conventions


This repo follows the vasic-digital anti-bluff
covenant
: every test that PASSes carries positive evidence of
the feature working; every SKIP documents its precondition; every gate
has a paired mutation in meta_test_*.sh proving the gate
isn't itself a bluff. The covenant is restated verbatim in
Constitution.md, CLAUDE.md,
AGENTS.md, and QWEN.md (per the 2026-05-21
operator mandate) so that any tool which doesn't expand
@imports still reads it. The upstream source lives in constitution/Constitution.md
§11.4.


CodeGraph (code-intelligence)


This project is wired with CodeGraph per
constitution/Constitution.md §11.4.78. The MCP server is
configured for Claude Code, OpenCode, Kimi CLI, Crush, and Qwen Code —
see docs/codegraph/README.md
for the install + per-agent wiring contract.


License


Apache 2.0 — see LICENSE.