elsewindow 0.1.0__tar.gz → 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. elsewindow-0.2.1/.version +1 -0
  2. elsewindow-0.2.1/CHANGELOG.md +188 -0
  3. {elsewindow-0.1.0 → elsewindow-0.2.1}/MANIFEST.in +5 -0
  4. {elsewindow-0.1.0 → elsewindow-0.2.1}/PKG-INFO +49 -36
  5. {elsewindow-0.1.0 → elsewindow-0.2.1}/README.md +47 -15
  6. elsewindow-0.2.1/elsewindow/_persistent_agent.py +799 -0
  7. {elsewindow-0.1.0 → elsewindow-0.2.1}/elsewindow/cli.py +163 -14
  8. {elsewindow-0.1.0 → elsewindow-0.2.1}/elsewindow/config.py +50 -1
  9. elsewindow-0.2.1/elsewindow/desktop.py +480 -0
  10. elsewindow-0.2.1/elsewindow/journal.py +511 -0
  11. {elsewindow-0.1.0 → elsewindow-0.2.1}/elsewindow/live-cli.yml +31 -2
  12. {elsewindow-0.1.0 → elsewindow-0.2.1}/elsewindow/live_config.py +20 -3
  13. elsewindow-0.2.1/elsewindow/log_transport.py +358 -0
  14. elsewindow-0.2.1/elsewindow/machine.py +58 -0
  15. elsewindow-0.2.1/elsewindow/persistent.py +341 -0
  16. elsewindow-0.2.1/elsewindow/requirements-xpra-build.in +5 -0
  17. elsewindow-0.2.1/elsewindow/requirements-xpra-build.txt +121 -0
  18. elsewindow-0.2.1/elsewindow/requirements-xpra.in +4 -0
  19. elsewindow-0.2.1/elsewindow/requirements-xpra.txt +53 -0
  20. {elsewindow-0.1.0 → elsewindow-0.2.1}/elsewindow/session.py +393 -41
  21. elsewindow-0.2.1/elsewindow/session_bus.py +161 -0
  22. elsewindow-0.2.1/elsewindow/xpra_runtime.py +460 -0
  23. {elsewindow-0.1.0 → elsewindow-0.2.1}/elsewindow.egg-info/PKG-INFO +49 -36
  24. {elsewindow-0.1.0 → elsewindow-0.2.1}/elsewindow.egg-info/SOURCES.txt +13 -0
  25. elsewindow-0.2.1/elsewindow.egg-info/requires.txt +1 -0
  26. {elsewindow-0.1.0 → elsewindow-0.2.1}/pyproject.toml +6 -32
  27. elsewindow-0.2.1/requirements.in +2 -0
  28. elsewindow-0.1.0/.version +0 -1
  29. elsewindow-0.1.0/CHANGELOG.md +0 -18
  30. elsewindow-0.1.0/elsewindow.egg-info/requires.txt +0 -25
  31. {elsewindow-0.1.0 → elsewindow-0.2.1}/LICENSE +0 -0
  32. {elsewindow-0.1.0 → elsewindow-0.2.1}/elsewindow/__init__.py +0 -0
  33. {elsewindow-0.1.0 → elsewindow-0.2.1}/elsewindow/__main__.py +0 -0
  34. {elsewindow-0.1.0 → elsewindow-0.2.1}/elsewindow/profiles.yml +0 -0
  35. {elsewindow-0.1.0 → elsewindow-0.2.1}/elsewindow/py.typed +0 -0
  36. {elsewindow-0.1.0 → elsewindow-0.2.1}/elsewindow.egg-info/dependency_links.txt +0 -0
  37. {elsewindow-0.1.0 → elsewindow-0.2.1}/elsewindow.egg-info/entry_points.txt +0 -0
  38. {elsewindow-0.1.0 → elsewindow-0.2.1}/elsewindow.egg-info/top_level.txt +0 -0
  39. {elsewindow-0.1.0 → elsewindow-0.2.1}/setup.cfg +0 -0
@@ -0,0 +1 @@
1
+ 0.2.1
@@ -0,0 +1,188 @@
1
+ <!-- Copyright (c) 2026 kogeler. SPDX-License-Identifier: MIT. -->
2
+
3
+ # Changelog
4
+
5
+ All notable changes to Elsewindow are documented here.
6
+
7
+ ## Unreleased
8
+
9
+ ### Fixed
10
+
11
+ - Submit the two Xpra environment locks together with the other six to the
12
+ GitHub dependency graph. Since 0.2.0 the push-only submission job rejected the
13
+ generated snapshot; a unit test now keeps its accepted manifest list equal to
14
+ the generator's output.
15
+
16
+ ## [0.2.1] - 2026-09-08
17
+
18
+ ### Added
19
+
20
+ - Include the standard desktop portal and GTK backend in explicit system-package
21
+ preparation and the release-backed disposable images. Startup never installs
22
+ system packages.
23
+ - Own a private foreground desktop portal, GTK backend and transient permission
24
+ store for remote file dialogs and portal notifications. OpenURI and unrelated
25
+ desktop portal methods remain disabled.
26
+ - Prevent repeated child-start requests from launching a second application or
27
+ competing portal helpers within the same owned session.
28
+ - Add repeatable `--env NAME=VALUE` and `--env NAME` application overrides for
29
+ ordinary and persistent sessions. Preserve literal and empty values, isolate
30
+ overrides from session helpers, and require matching values on persistent
31
+ reconnects.
32
+ - Document that Zed's default `notify_when_agent_waiting` opens no agent
33
+ notification window in any Wayland session, including Elsewindow's, and that
34
+ `all_screens` delivers them as forwarded windows.
35
+ - Cover application-drawn agent notification windows in the live test with a
36
+ lightweight probe of Zed's Wayland flow, the operator's persistent H.264
37
+ `gigabit_lan` command line, and a real xfwm4 desktop across a persistent
38
+ reconnect.
39
+ - Resume the ordered live matrix at a fixed failure with
40
+ `make live-test LIVE_FROM=CASE`, and run selected tests without the coverage
41
+ gate with `make test-focused TESTS=...`. Only a complete live run validates a
42
+ change.
43
+
44
+ ### Changed
45
+
46
+ - Update the published SSH runtime dependency through its single requirements
47
+ input. Derive environment, lock, clean-install, standalone and live identity
48
+ checks from that input instead of maintaining duplicate version constants.
49
+ - Missing journald no longer prevents ordinary or persistent application startup;
50
+ warn with setup guidance and retain terminal output and the remote log relay.
51
+ - Check optional notification and GPU prerequisites on both hosts. Missing
52
+ support disables delivery or selects RGB for this connection with explicit
53
+ package guidance; absent portal services never prevent application startup.
54
+ - Unavailable persistence or declined linger falls back to an ordinary session
55
+ only when no persistent state is recorded, with a warning about disconnect
56
+ cleanup. Never replace or duplicate an existing persistent application.
57
+ - Synchronized the maintained fork's client wheel default and pointer diagnostics
58
+ without duplicating the mirrored wheel option in the session policy.
59
+
60
+ ### Fixed
61
+
62
+ - Prevent an open but unread SSH output pipe from blocking ordinary remote
63
+ shutdown. Bound raw-output queues, retain native journal processing, and report
64
+ dropped bytes without postponing owned application cleanup.
65
+ - Wait for the remote dialog's actual focus before sending its dismissal key
66
+ in the live GUI test. Repeat abrupt master loss and retain bounded process,
67
+ owned-path and shutdown-journal evidence on cleanup failure.
68
+ - Allow local Xpra environment preparation, reuse, and startup on shared
69
+ filesystems with mapped ownership or broader Unix permissions.
70
+ - Use the same resolved Xpra executable for preparation, diagnosis, and session
71
+ startup when PATH contains symbolic links. Allow longer installed-file checks
72
+ on shared storage and report timeouts without treating them as stale
73
+ environments or reinstalling dependencies.
74
+ - Read installed file inventories directly with bounded concurrent reads during
75
+ Xpra validation to avoid repeated filesystem metadata scans and detect missing
76
+ package files.
77
+ - Consume the canonical Xpra client modal-window default from the mirrored YAML
78
+ instead of duplicating it in Python.
79
+ - Mask the current packaged Xpra socket and service in the disposable target so
80
+ its only TCP listener is SSH.
81
+
82
+ ## [0.2.0] - 2026-09-05
83
+
84
+ ### Added
85
+
86
+ - Enabled remote application notifications by default, with a private owned
87
+ foreground D-Bus session per application session and no Xpra D-Bus control.
88
+ - Added a separate system-Python Xpra environment with hash-locked matching
89
+ PyOpenGL and accelerator additions. `make runtime-venv` prepares both local
90
+ environments; installed and standalone commands provide `--prepare-xpra`.
91
+ All local Xpra commands use the prepared interpreter, while ordinary startup
92
+ validates current inputs and installed bytes without installing anything.
93
+ - Bundled Xpra setup resources in all artifacts and shared clean setup,
94
+ stale-environment rejection, and repair smoke across wheel, sdist, and
95
+ standalone routes. Extended the existing live topology to exercise the
96
+ prepared client and its public zero-copy capability.
97
+ - Support accelerator source builds when a wheel is unavailable, including
98
+ Linux arm64, using a hash-verified archive and separately locked temporary
99
+ build tools. Exercise offline native compilation in every artifact smoke.
100
+ - Added synchronized `--log-level` control for Elsewindow and Xpra logs on both
101
+ hosts, with `warning` by default, host-local journald records in ordinary and
102
+ persistent sessions, and matching local stdout/stderr output.
103
+ - Added targeted diagnostics with `--log-level=debug-clipboard` and general
104
+ diagnostics with `--log-level=debug`. Both modes warn that system journals
105
+ may contain sensitive data.
106
+ - Preserved local Xpra probe diagnostics in the journal, including failures
107
+ before SSH authentication, and added side/session/source-process metadata.
108
+ - Extended the existing live topology to verify real journals on both hosts,
109
+ identical local terminal output, and unchanged ordinary/persistent cleanup.
110
+ - Aggregate four clearly labeled local/remote Elsewindow and Xpra sources in
111
+ the local terminal and journal. Forward new remote records through owned
112
+ SSH mux channels in both lifecycle modes; keep the remote journal limited
113
+ to remote sources, without granting journal-reading privileges or reconnecting.
114
+ - Include one shared session ID in every log message and native journal record
115
+ on both hosts. Keep ordinary invocations distinct and persistent IDs stable
116
+ across reconnects, namespaced by remote machine and account; isolate concurrent
117
+ log subscribers without changing application identity or ownership.
118
+ - Added `--persistent` sessions backed by owned transient user systemd
119
+ services. Repeating the same remote executable invocation path and exact
120
+ arguments resumes the application after client or SSH loss; exiting the
121
+ foreground application with any status ends the session. Ordinary
122
+ heartbeat-supervised sessions remain the default.
123
+ - Added per-invocation linger checks and interactive consent to enable it for
124
+ the remote account, using the same owned SSH connection for any required
125
+ sudo prompt. Persistent sessions never reconnect or restart automatically.
126
+ - Extended the existing release-backed live topology with real systemd,
127
+ linger refusal/consent, detach and client/SSH-loss recovery, cancellation,
128
+ repeated manual reconnects, and cleanup after successful or failed
129
+ application exit.
130
+
131
+ ### Changed
132
+
133
+ - Isolated all checkout Python environments by an application-specific hash of
134
+ the OS machine ID and local UID, shared by Make and the repository launcher.
135
+ Installed and standalone Xpra defaults use the same host isolation for shared
136
+ data directories. Leave legacy environments and other machines' venvs untouched.
137
+ - Persistent resumption requires the original logging policy.
138
+ - Consolidated all public CLI options, defaults, profiles, and restrictions
139
+ into one linked reference, with parser-backed documentation checks.
140
+ - Synchronized the maintained-fork clipboard YAML blocks and assembled the
141
+ same reviewed policy for both peers without duplicating option values or
142
+ applying the fork's clipboard-test-only X11 overrides.
143
+ - Included the persistent-session helper in wheel, source, and standalone
144
+ distributions, verified its packaged bytes, and exposed its source digest
145
+ through `--diagnose`.
146
+
147
+ ### Fixed
148
+
149
+ - Restored ordinary GUI behavior suppressed by the minimal Xpra base: custom
150
+ cursors, mouse-wheel forwarding, keyboard-state synchronization, modal windows,
151
+ detected DPI, and client scaling initially at 1:1, without new CLI switches.
152
+ - Routed `SIGHUP` through normal session cancellation and terminated owned
153
+ local SSH probe processes when their requests are cancelled.
154
+
155
+ ## [0.1.1] - 2026-09-04
156
+
157
+ ### Changed
158
+
159
+ - Enabled bidirectional Xpra clipboard synchronization by default, with
160
+ explicit `off`, `to-server`, and `both` policies applied to both peers.
161
+ - Synchronized the mirrored Xpra keyboard diagnostics with the current
162
+ maintained-fork configuration.
163
+ - Moved all exact direct Python versions to six native
164
+ `requirements*.in`/`requirements*.txt` pip-compile pairs so Dependabot can
165
+ update each complete graph instead of treating `pyproject.toml` as a plain
166
+ requirements manifest.
167
+ - Aligned both local lock resolver stages with Dependabot's pip and pip-tools
168
+ pair, and made published runtime metadata derive from `requirements.in`
169
+ without a second version authority.
170
+ - Made an exact existing release suppress the reusable release CI and both
171
+ publication jobs, while ordinary CI accepts maintenance at an already
172
+ published version and authenticates installer acceptance API requests.
173
+ - Added trusted-base PR metadata automation that mirrors a populated
174
+ `Unreleased` section without requiring a version change, preserving manual
175
+ PR text while release-worthy changes accumulate across merges.
176
+
177
+ ## [0.1.0] - 2026-08-30
178
+
179
+ ### Added
180
+
181
+ - Established Elsewindow as an independent Linux project with one public
182
+ distribution, import package, command, and repository identity.
183
+ - Preserved the one-authentication OpenSSH lifecycle, mux-only Xpra channels,
184
+ heartbeat-supervised remote process group, and selective cleanup behavior.
185
+ - Shipped reviewed Xpra command and network profiles as package data and kept
186
+ release-backed package installation and container acceptance tooling.
187
+ - Added CPython 3.13 and 3.14 governance, deterministic Python distributions,
188
+ Linux standalone artifacts, and fail-closed publication policy.
@@ -4,7 +4,12 @@ include LICENSE
4
4
  include MANIFEST.in
5
5
  include README.md
6
6
  include pyproject.toml
7
+ include requirements.in
7
8
  recursive-include elsewindow *.py *.yml py.typed
9
+ include elsewindow/requirements-xpra.in
10
+ include elsewindow/requirements-xpra.txt
11
+ include elsewindow/requirements-xpra-build.in
12
+ include elsewindow/requirements-xpra-build.txt
8
13
  prune .github
9
14
  prune bin
10
15
  prune containers
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: elsewindow
3
- Version: 0.1.0
3
+ Version: 0.2.1
4
4
  Summary: Run one remote Linux GUI application through Xpra over one owned OpenSSH master
5
5
  Author: kogeler
6
6
  Maintainer: kogeler
@@ -25,26 +25,7 @@ Classifier: Typing :: Typed
25
25
  Requires-Python: <3.15,>=3.13
26
26
  Description-Content-Type: text/markdown
27
27
  License-File: LICENSE
28
- Requires-Dist: ssh-wrapper==0.1.0
29
- Provides-Extra: quality
30
- Requires-Dist: bandit[toml]==1.9.4; extra == "quality"
31
- Requires-Dist: mypy==2.3.1; extra == "quality"
32
- Requires-Dist: pip-audit==2.10.1; extra == "quality"
33
- Requires-Dist: pip-licenses==5.5.5; extra == "quality"
34
- Requires-Dist: ruff==0.16.5; extra == "quality"
35
- Provides-Extra: test
36
- Requires-Dist: pytest==9.1.1; extra == "test"
37
- Requires-Dist: pytest-asyncio==1.4.0; extra == "test"
38
- Requires-Dist: pytest-cov==7.1.0; extra == "test"
39
- Requires-Dist: pytest-xdist==3.8.0; extra == "test"
40
- Provides-Extra: package
41
- Requires-Dist: build==1.6.0; extra == "package"
42
- Requires-Dist: setuptools==84.0.0; extra == "package"
43
- Requires-Dist: wheel==0.48.0; extra == "package"
44
- Provides-Extra: standalone
45
- Requires-Dist: pyinstaller==6.22.2; extra == "standalone"
46
- Provides-Extra: docs
47
- Requires-Dist: mkdocs-material==9.7.7; extra == "docs"
28
+ Requires-Dist: ssh-wrapper==0.1.1
48
29
  Dynamic: license-file
49
30
 
50
31
  # Elsewindow
@@ -56,20 +37,26 @@ cleans only the server, application process group, sockets, and runtime state
56
37
  created by that invocation.
57
38
 
58
39
  The application renders through the remote Wayland compositor and remote GPU.
59
- Only Xpra picture, input, and control traffic crosses SSH.
40
+ Only Xpra picture, input, clipboard, notification, and control traffic crosses SSH.
60
41
 
61
42
  ## Install And Run
62
43
 
63
44
  The Python distribution requires Linux, CPython 3.13 or 3.14, OpenSSH,
64
45
  `false`, a local graphical session, and compatible Xpra packages on both
65
- systems. Install with pip or pipx after the first release:
46
+ systems. [Optional desktop features](doc/cli.md#optional-desktop-features)
47
+ have separate system prerequisites: missing support produces a warning and
48
+ disables only that feature for the session. Startup never installs packages.
49
+ Install the latest published release with pip or pipx:
66
50
 
67
51
  ```bash
68
- python3.14 -m pip install "elsewindow==0.1.0"
69
- # or: pipx install "elsewindow==0.1.0"
52
+ python3.14 -m pip install elsewindow
53
+ # or: pipx install elsewindow
54
+ elsewindow --prepare-xpra
70
55
  elsewindow --ssh-alias agents-a -- xterm
71
56
  ```
72
57
 
58
+ The version prepared by this source tree is recorded only in [`.version`](.version).
59
+
73
60
  Check packaged versions, profile digests, Linux support, and local commands
74
61
  without opening a connection:
75
62
 
@@ -78,7 +65,8 @@ elsewindow --diagnose
78
65
  ```
79
66
 
80
67
  The published distribution resolves the exact reviewed
81
- [`ssh-wrapper==0.1.0`](https://pypi.org/project/ssh-wrapper/0.1.0/) dependency.
68
+ [`ssh-wrapper`](https://pypi.org/project/ssh-wrapper/) release pinned only in
69
+ [`requirements.in`](requirements.in).
82
70
  For a source checkout, prepare the hash-locked runtime and use the repository
83
71
  launcher from any working directory:
84
72
 
@@ -87,6 +75,15 @@ make runtime-venv
87
75
  ./bin/elsewindow --help
88
76
  ```
89
77
 
78
+ This one make target prepares the isolated Elsewindow runtime and a separate
79
+ system-Python venv for local Xpra. The latter keeps GTK and native Xpra modules
80
+ in their system packages while installing a hash-locked matching PyOpenGL and
81
+ accelerator pair. Session startup never invokes pip or changes system packages.
82
+ Both environments are selected automatically beneath `.venvs/<machine-user-key>/`,
83
+ so each machine prepares its own Python and native additions in a shared checkout.
84
+ See [checkout setup](doc/getting-started.md#prepare-a-source-checkout) for migration
85
+ and system-command behavior.
86
+
90
87
  Use a direct authority when an OpenSSH alias is not appropriate:
91
88
 
92
89
  ```bash
@@ -97,10 +94,14 @@ elsewindow \
97
94
  -- /opt/application/bin/application
98
95
  ```
99
96
 
100
- The default encoding and network profiles are `rgb` and `gigabit_lan`.
101
- Production arguments come exclusively from the reviewed YAML mirrors shipped
102
- inside the Python package. See [the Xpra guide](doc/xpra.md) for profile,
103
- hardware, application, and lifecycle details.
97
+ See the [CLI reference](doc/cli.md) for every option, default, and allowed
98
+ value, including encoding/network profiles, clipboard policy, logging, and
99
+ persistence. Repeat [`--env`](doc/cli.md#application-environment) to set remote
100
+ application variables or copy explicitly named local values. Reviewed profile
101
+ arguments come from the packaged YAML mirrors.
102
+ The [Xpra guide](doc/xpra.md) covers hardware, application, and lifecycle
103
+ behavior; the [security model](doc/security.md) explains clipboard and logging
104
+ trust boundaries.
104
105
 
105
106
  ## Installing The Maintained Xpra Build
106
107
 
@@ -138,17 +139,22 @@ APT transaction.
138
139
  After the first release, GitHub Releases provide `elsewindow-linux-amd64` and
139
140
  `elsewindow-linux-arm64`. These native one-file ELF executables bundle
140
141
  Elsewindow, CPython, `ssh-wrapper`, version metadata, and the reviewed YAML
141
- profiles. They do not bundle OpenSSH, Xpra, Podman, GPU drivers, VA-API, or
142
+ profiles, and the local Xpra setup code and dependency lock. They do not bundle
143
+ OpenSSH, Xpra, Podman, GPU drivers, VA-API, or
142
144
  distribution packages. Verify the release's `SHA256SUMS.txt`, make the selected
143
- file executable, and run `./elsewindow-linux-amd64 --diagnose` (or the arm64
144
- equivalent) before starting a session.
145
+ file executable, run `./elsewindow-linux-amd64 --prepare-xpra`, then
146
+ `./elsewindow-linux-amd64 --diagnose` (or the arm64 equivalents) before starting
147
+ a session. Preparation uses the system Xpra Python, not the bundled interpreter,
148
+ and needs neither a checkout nor GNU Make. See the
149
+ [setup reference](doc/cli.md#prepare-xpra) for prerequisites and storage.
145
150
 
146
151
  ## Documentation
147
152
 
148
153
  - [Rendered documentation site](https://kogeler.github.io/elsewindow/)
149
154
  (published by the first reviewed direct `main` push)
150
155
  - [Getting started](doc/getting-started.md)
151
- - [Complete Xpra behavior and options](doc/xpra.md)
156
+ - [Complete CLI reference](doc/cli.md)
157
+ - [Xpra behavior and lifecycle](doc/xpra.md)
152
158
  - [Security model](doc/security.md)
153
159
  - [Architecture](doc/architecture.md)
154
160
  - [Development and validation](doc/development.md)
@@ -164,13 +170,20 @@ file, and advertised `llms.txt` route without network access.
164
170
  ## Automatic Live Validation
165
171
 
166
172
  `make live-test` resolves the newest fork release, builds checksum-bound Ubuntu
167
- target and Debian client images, and runs detach and abrupt-master-loss cases
173
+ target and Debian client images, and runs ordinary and persistent lifecycle cases
168
174
  on a private rootless Podman network. The payload excludes `elsewindow/` source
169
175
  and clean-installs the already verified wheel. The harness generates a fresh
170
- Ed25519 key, performs exactly one authentication per case, verifies a visible
176
+ Ed25519 key, performs exactly one authentication per invocation, verifies a visible
171
177
  window and picture updates through the production profile assembler, preserves
172
178
  an unrelated session, and removes only its labelled containers and network.
173
179
  All wheel, test, and key material enters through validated tar streams; the
174
180
  test uses no host bind, data volume, or copy channel.
175
181
 
182
+ Persistent cases exercise real systemd user services, linger consent, resumption
183
+ after client/SSH loss, stable application identity and cleanup on application
184
+ exit. The same matrix checks all four local/remote log sources in the local
185
+ journal and terminal, and only remote sources in the server journal, at the
186
+ selected log level. Enable this opt-in mode with
187
+ `--persistent`; see the [CLI reference](doc/cli.md#persistent).
188
+
176
189
  Released under the [MIT License](LICENSE).
@@ -7,20 +7,26 @@ cleans only the server, application process group, sockets, and runtime state
7
7
  created by that invocation.
8
8
 
9
9
  The application renders through the remote Wayland compositor and remote GPU.
10
- Only Xpra picture, input, and control traffic crosses SSH.
10
+ Only Xpra picture, input, clipboard, notification, and control traffic crosses SSH.
11
11
 
12
12
  ## Install And Run
13
13
 
14
14
  The Python distribution requires Linux, CPython 3.13 or 3.14, OpenSSH,
15
15
  `false`, a local graphical session, and compatible Xpra packages on both
16
- systems. Install with pip or pipx after the first release:
16
+ systems. [Optional desktop features](doc/cli.md#optional-desktop-features)
17
+ have separate system prerequisites: missing support produces a warning and
18
+ disables only that feature for the session. Startup never installs packages.
19
+ Install the latest published release with pip or pipx:
17
20
 
18
21
  ```bash
19
- python3.14 -m pip install "elsewindow==0.1.0"
20
- # or: pipx install "elsewindow==0.1.0"
22
+ python3.14 -m pip install elsewindow
23
+ # or: pipx install elsewindow
24
+ elsewindow --prepare-xpra
21
25
  elsewindow --ssh-alias agents-a -- xterm
22
26
  ```
23
27
 
28
+ The version prepared by this source tree is recorded only in [`.version`](.version).
29
+
24
30
  Check packaged versions, profile digests, Linux support, and local commands
25
31
  without opening a connection:
26
32
 
@@ -29,7 +35,8 @@ elsewindow --diagnose
29
35
  ```
30
36
 
31
37
  The published distribution resolves the exact reviewed
32
- [`ssh-wrapper==0.1.0`](https://pypi.org/project/ssh-wrapper/0.1.0/) dependency.
38
+ [`ssh-wrapper`](https://pypi.org/project/ssh-wrapper/) release pinned only in
39
+ [`requirements.in`](requirements.in).
33
40
  For a source checkout, prepare the hash-locked runtime and use the repository
34
41
  launcher from any working directory:
35
42
 
@@ -38,6 +45,15 @@ make runtime-venv
38
45
  ./bin/elsewindow --help
39
46
  ```
40
47
 
48
+ This one make target prepares the isolated Elsewindow runtime and a separate
49
+ system-Python venv for local Xpra. The latter keeps GTK and native Xpra modules
50
+ in their system packages while installing a hash-locked matching PyOpenGL and
51
+ accelerator pair. Session startup never invokes pip or changes system packages.
52
+ Both environments are selected automatically beneath `.venvs/<machine-user-key>/`,
53
+ so each machine prepares its own Python and native additions in a shared checkout.
54
+ See [checkout setup](doc/getting-started.md#prepare-a-source-checkout) for migration
55
+ and system-command behavior.
56
+
41
57
  Use a direct authority when an OpenSSH alias is not appropriate:
42
58
 
43
59
  ```bash
@@ -48,10 +64,14 @@ elsewindow \
48
64
  -- /opt/application/bin/application
49
65
  ```
50
66
 
51
- The default encoding and network profiles are `rgb` and `gigabit_lan`.
52
- Production arguments come exclusively from the reviewed YAML mirrors shipped
53
- inside the Python package. See [the Xpra guide](doc/xpra.md) for profile,
54
- hardware, application, and lifecycle details.
67
+ See the [CLI reference](doc/cli.md) for every option, default, and allowed
68
+ value, including encoding/network profiles, clipboard policy, logging, and
69
+ persistence. Repeat [`--env`](doc/cli.md#application-environment) to set remote
70
+ application variables or copy explicitly named local values. Reviewed profile
71
+ arguments come from the packaged YAML mirrors.
72
+ The [Xpra guide](doc/xpra.md) covers hardware, application, and lifecycle
73
+ behavior; the [security model](doc/security.md) explains clipboard and logging
74
+ trust boundaries.
55
75
 
56
76
  ## Installing The Maintained Xpra Build
57
77
 
@@ -89,17 +109,22 @@ APT transaction.
89
109
  After the first release, GitHub Releases provide `elsewindow-linux-amd64` and
90
110
  `elsewindow-linux-arm64`. These native one-file ELF executables bundle
91
111
  Elsewindow, CPython, `ssh-wrapper`, version metadata, and the reviewed YAML
92
- profiles. They do not bundle OpenSSH, Xpra, Podman, GPU drivers, VA-API, or
112
+ profiles, and the local Xpra setup code and dependency lock. They do not bundle
113
+ OpenSSH, Xpra, Podman, GPU drivers, VA-API, or
93
114
  distribution packages. Verify the release's `SHA256SUMS.txt`, make the selected
94
- file executable, and run `./elsewindow-linux-amd64 --diagnose` (or the arm64
95
- equivalent) before starting a session.
115
+ file executable, run `./elsewindow-linux-amd64 --prepare-xpra`, then
116
+ `./elsewindow-linux-amd64 --diagnose` (or the arm64 equivalents) before starting
117
+ a session. Preparation uses the system Xpra Python, not the bundled interpreter,
118
+ and needs neither a checkout nor GNU Make. See the
119
+ [setup reference](doc/cli.md#prepare-xpra) for prerequisites and storage.
96
120
 
97
121
  ## Documentation
98
122
 
99
123
  - [Rendered documentation site](https://kogeler.github.io/elsewindow/)
100
124
  (published by the first reviewed direct `main` push)
101
125
  - [Getting started](doc/getting-started.md)
102
- - [Complete Xpra behavior and options](doc/xpra.md)
126
+ - [Complete CLI reference](doc/cli.md)
127
+ - [Xpra behavior and lifecycle](doc/xpra.md)
103
128
  - [Security model](doc/security.md)
104
129
  - [Architecture](doc/architecture.md)
105
130
  - [Development and validation](doc/development.md)
@@ -115,13 +140,20 @@ file, and advertised `llms.txt` route without network access.
115
140
  ## Automatic Live Validation
116
141
 
117
142
  `make live-test` resolves the newest fork release, builds checksum-bound Ubuntu
118
- target and Debian client images, and runs detach and abrupt-master-loss cases
143
+ target and Debian client images, and runs ordinary and persistent lifecycle cases
119
144
  on a private rootless Podman network. The payload excludes `elsewindow/` source
120
145
  and clean-installs the already verified wheel. The harness generates a fresh
121
- Ed25519 key, performs exactly one authentication per case, verifies a visible
146
+ Ed25519 key, performs exactly one authentication per invocation, verifies a visible
122
147
  window and picture updates through the production profile assembler, preserves
123
148
  an unrelated session, and removes only its labelled containers and network.
124
149
  All wheel, test, and key material enters through validated tar streams; the
125
150
  test uses no host bind, data volume, or copy channel.
126
151
 
152
+ Persistent cases exercise real systemd user services, linger consent, resumption
153
+ after client/SSH loss, stable application identity and cleanup on application
154
+ exit. The same matrix checks all four local/remote log sources in the local
155
+ journal and terminal, and only remote sources in the server journal, at the
156
+ selected log level. Enable this opt-in mode with
157
+ `--persistent`; see the [CLI reference](doc/cli.md#persistent).
158
+
127
159
  Released under the [MIT License](LICENSE).