abeam 0.0.1__py3-none-win_amd64.whl
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.
|
Binary file
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: abeam
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Classifier: Development Status :: 3 - Alpha
|
|
5
|
+
Classifier: Environment :: Console
|
|
6
|
+
Classifier: Intended Audience :: Developers
|
|
7
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
8
|
+
Classifier: Programming Language :: Rust
|
|
9
|
+
Classifier: Topic :: Software Development
|
|
10
|
+
Classifier: Topic :: Terminals :: Terminal Emulators/X Terminals
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Summary: One window for a Claude Code session: Claude hosted in a pty pane, with git, a file viewer and a shell beside it.
|
|
13
|
+
Keywords: claude,claude-code,terminal,tui,multiplexer,conpty
|
|
14
|
+
License-Expression: MIT
|
|
15
|
+
Requires-Python: >=3.9
|
|
16
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
17
|
+
Project-URL: Homepage, https://github.com/OpenAfterHours/abeam
|
|
18
|
+
Project-URL: Issues, https://github.com/OpenAfterHours/abeam/issues
|
|
19
|
+
Project-URL: Repository, https://github.com/OpenAfterHours/abeam
|
|
20
|
+
|
|
21
|
+
# abeam
|
|
22
|
+
|
|
23
|
+
One window for a Claude Code session.
|
|
24
|
+
|
|
25
|
+
Claude runs in the left pane — hosted in a pty, parsed, and drawn by abeam, not
|
|
26
|
+
passed through to your terminal. The right pane shows the state of the git
|
|
27
|
+
worktree, the document Claude just wrote, or a shell to run things in. A file
|
|
28
|
+
watcher drives the first two, so neither has to be asked.
|
|
29
|
+
|
|
30
|
+
It replaces a three-window setup: Claude in one terminal, git in another, and an
|
|
31
|
+
editor open purely to read the markdown Claude produced.
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
┌ claude ──────────────────────────────┐┌ git · main ↑2 · 12 changed ──────┐
|
|
35
|
+
│ ││ Staged (1) +40 -6 │
|
|
36
|
+
│ > implement the parser ││ M crates/abeam/src/app.rs +40-6│
|
|
37
|
+
│ ││ Changed (1) +7 -0 │
|
|
38
|
+
│ ● Writing crates/abeam/src/parse.rs ││ M docs/design.md +7-0 │
|
|
39
|
+
│ ││ Untracked (1) │
|
|
40
|
+
│ ││ ? notes/ │
|
|
41
|
+
│ ││ Recent │
|
|
42
|
+
│ ││ a1b2c3d 2m parser skeleton │
|
|
43
|
+
└──────────────────────────────────────┘└──────────────────────────────────┘
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Why this rather than wezterm + lazygit + glow
|
|
47
|
+
|
|
48
|
+
Because the right pane knows what the agent just did. A watcher on the
|
|
49
|
+
repository root feeds both views: markdown Claude writes becomes the document on
|
|
50
|
+
screen, and any file it touches refreshes git within one debounce interval. That
|
|
51
|
+
is the only thing here you cannot assemble out of existing tools, and it is the
|
|
52
|
+
reason abeam exists.
|
|
53
|
+
|
|
54
|
+
Everything else is a consequence of that. The panes are read-only, they never
|
|
55
|
+
take focus from Claude, and they never switch themselves — a pane that yanks
|
|
56
|
+
itself into view while you are reading is delightful twice and infuriating
|
|
57
|
+
thereafter.
|
|
58
|
+
|
|
59
|
+
## Installing
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
uvx abeam # run it without installing anything
|
|
63
|
+
uv tool install abeam # or keep it on PATH
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
There is no Python in abeam. PyPI is the delivery van: the wheel's whole payload
|
|
67
|
+
is a compiled Windows binary, so `uvx` fetches a few hundred kilobytes and runs
|
|
68
|
+
it — no Rust toolchain, no build step, and nothing to compile on your machine.
|
|
69
|
+
|
|
70
|
+
## Requirements
|
|
71
|
+
|
|
72
|
+
- **Windows, x86-64.** Everything works because of specific ConPTY behaviour,
|
|
73
|
+
and the pty test suites are `#![cfg(windows)]`. The code is not portable
|
|
74
|
+
today, and on another platform the tests pass by saying nothing. Only x86-64
|
|
75
|
+
wheels are published: ARM Windows would cross-compile in one line and would be
|
|
76
|
+
a binary nobody has ever run, so `uvx` reporting no matching wheel is the more
|
|
77
|
+
honest answer until someone can test it.
|
|
78
|
+
- `git` on `PATH`, for the git pane. Its absence is reported in the pane, not
|
|
79
|
+
fatal.
|
|
80
|
+
- Rust 1.95+ and the MSVC toolchain — **only to build from source**. Plain
|
|
81
|
+
`cargo build`, no vcvars wrapper.
|
|
82
|
+
|
|
83
|
+
## Running it
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
abeam # hosts `claude` in the current directory
|
|
87
|
+
abeam pwsh # hosts something else
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The first argument is the program; everything after it is passed through. The
|
|
91
|
+
current directory is both the child's working directory and the root that the
|
|
92
|
+
git pane and the watcher use.
|
|
93
|
+
|
|
94
|
+
From a checkout, `cargo run -p abeam` and `cargo run -p abeam -- pwsh` do the
|
|
95
|
+
same.
|
|
96
|
+
|
|
97
|
+
## Keys
|
|
98
|
+
|
|
99
|
+
Everything abeam binds lives under `Alt` and the F-keys. **Nothing abeam claims
|
|
100
|
+
is a key Claude can act on** — the audit behind that is `docs/keymap.md`, and
|
|
101
|
+
`crates/abeam/src/keys.rs` has tests pinning it. Everything else you type goes
|
|
102
|
+
to Claude untouched.
|
|
103
|
+
|
|
104
|
+
| Key | |
|
|
105
|
+
| --- | --- |
|
|
106
|
+
| `Alt+G` | right pane → git |
|
|
107
|
+
| `Alt+E` | right pane → files / markdown (again for the file list) |
|
|
108
|
+
| `Alt+S` | right pane → a shell, **and focus it** (again to hand focus back) |
|
|
109
|
+
| `F2` | right pane → pty diagnostics, and back to what it displaced |
|
|
110
|
+
| `Alt+Left` / `Alt+Right` | move focus |
|
|
111
|
+
| `Alt+J` / `Alt+K` | scroll the right pane a line — **without focusing it** |
|
|
112
|
+
| `Alt+PgDn` / `Alt+PgUp` | scroll the right pane a page — without focusing it |
|
|
113
|
+
| `Alt+Z` | zoom: hide / show the right pane |
|
|
114
|
+
| `Alt+Q` | quit (twice while a child is live) |
|
|
115
|
+
| `F1` | key help overlay |
|
|
116
|
+
| `Ctrl+\` or `F12` | send the *next* key to Claude verbatim |
|
|
117
|
+
|
|
118
|
+
Reading the right pane costs nothing: switching views and scrolling both work
|
|
119
|
+
while Claude still has focus. You only need focus to drive a selection — or to
|
|
120
|
+
type, which is what `Alt+S` is for and the only reason a view key moves focus.
|
|
121
|
+
|
|
122
|
+
Once the right pane *is* focused, plain keys work, deliberately the same
|
|
123
|
+
vocabulary as Claude's own transcript view: `j`/`k` and arrows for a line,
|
|
124
|
+
`space`/`b` and PgDn/PgUp for a page, `Ctrl+D`/`Ctrl+U` for a half page, `g`/`G`
|
|
125
|
+
and Home/End for the ends, `Tab`/`Shift+Tab` for the selection, `Enter` to open,
|
|
126
|
+
`r` to refresh. `t` swaps rendered markdown for its source; in the file list,
|
|
127
|
+
`/` finds a file anywhere under the root and `Backspace` goes up a directory.
|
|
128
|
+
`Esc` or `q` hands focus back to Claude.
|
|
129
|
+
|
|
130
|
+
The shell view is the exception, and it has to be: `Esc` and `q` belong to
|
|
131
|
+
whatever is running in it. `Alt+S` or `Alt+←` is the way out, and its border
|
|
132
|
+
says so rather than leaving you to find out.
|
|
133
|
+
|
|
134
|
+
`Ctrl+\` exists so abeam can never permanently shadow a Claude binding. If a
|
|
135
|
+
future Claude release binds `Alt+G`, `Ctrl+\` then `Alt+G` still reaches it.
|
|
136
|
+
|
|
137
|
+
## The panes
|
|
138
|
+
|
|
139
|
+
**git** — read-only. Branch, ahead/behind, staged / unstaged / untracked files
|
|
140
|
+
with per-file line counts, and recent commits. Every `git` call is a read: it
|
|
141
|
+
stages nothing and commits nothing, which matters because it refreshes itself
|
|
142
|
+
unasked. Refreshes when the watcher sees a write, and on a two-second safety
|
|
143
|
+
timer for changes the watcher cannot see (`.git` is deliberately not watched, so
|
|
144
|
+
a commit made in another terminal arrives on the timer). `Enter` opens the
|
|
145
|
+
selected file in the viewer, when the row names one to open: git collapses an
|
|
146
|
+
untracked tree to a single `dir/` entry and there is no directory view to open
|
|
147
|
+
one in, and a deletion is a path git has just finished saying is gone. Enter
|
|
148
|
+
does nothing on those, rather than trading the view you are reading for a
|
|
149
|
+
viewer saying "no such file".
|
|
150
|
+
|
|
151
|
+
**files** — read-only markdown and source, and a way to reach any of it.
|
|
152
|
+
Markdown is rendered, not shown as source: headings, lists, tables, quotes, GFM
|
|
153
|
+
alerts, footnotes, and syntax-highlighted fenced code. `t` swaps that for the
|
|
154
|
+
source it was rendered from, highlighted and numbered like any other file, and
|
|
155
|
+
back. Source files get highlighting and a line-number gutter. Everything is
|
|
156
|
+
pre-wrapped to the pane's exact width and scrolled by physical row, so
|
|
157
|
+
jump-to-end lands where you asked. On startup it opens the newest markdown under
|
|
158
|
+
the root; after that it follows what gets written. If something arrives while
|
|
159
|
+
another view is showing it waits, and the border says `◆ Alt+E` rather than
|
|
160
|
+
switching under you.
|
|
161
|
+
|
|
162
|
+
A second `Alt+E` opens the **file list**: a gitignore-aware directory browser
|
|
163
|
+
starting wherever the open file lives. `Enter` descends or opens, `Backspace`
|
|
164
|
+
climbs — and lands on the directory you just left, so walking back up is a place
|
|
165
|
+
rather than a reset. `/` finds a file by name anywhere under the root, matched
|
|
166
|
+
as a subsequence over its path and ranked so a hit in the file name beats one in
|
|
167
|
+
a directory name; `Esc` cancels the find and stays put, because being thrown out
|
|
168
|
+
of the pane by the key that means "never mind" is the worst thing a filter box
|
|
169
|
+
can do. The list is the second half of the never-switch-under-you rule: a
|
|
170
|
+
document arriving from the watcher waits while you are walking a tree, exactly
|
|
171
|
+
as it waits behind the git view.
|
|
172
|
+
|
|
173
|
+
**shell** — `Alt+S`, and the reason it is here rather than in another window:
|
|
174
|
+
`git branch`, `uv run ruff format`, `cargo test`, run in the directory abeam was
|
|
175
|
+
pointed at, next to the session that is about to be told what they printed. It
|
|
176
|
+
is a real pty — `pwsh`, falling back to `powershell` then `cmd`, or whatever
|
|
177
|
+
`ABEAM_SHELL` names — started the first time the view is drawn and never before,
|
|
178
|
+
so a session that never asks for one never pays for it. `Alt+J`/`Alt+K` scroll
|
|
179
|
+
its history without focusing it, which is why they are not the arrow keys the
|
|
180
|
+
shell would read as history. A child that exits leaves its last screen up with
|
|
181
|
+
`Enter` to start another, and while it is dead `Esc` means what it means
|
|
182
|
+
everywhere else.
|
|
183
|
+
|
|
184
|
+
Nor will abeam close out from under it: Claude exiting holds the door rather
|
|
185
|
+
than killing whatever is running, and says `shell open · Alt+Q to quit` in the
|
|
186
|
+
left title. That is "open", not "busy" — ConPTY cannot be asked whether a
|
|
187
|
+
command is running, so a shell sitting at a prompt holds the door exactly as a
|
|
188
|
+
build does. Type `exit` in it, or `Alt+Q` twice.
|
|
189
|
+
|
|
190
|
+
**pty diagnostics** (`F2`) — what the emulation layer is doing: alt-screen,
|
|
191
|
+
application cursor, bracketed paste, mouse mode, byte counts, resize count, and
|
|
192
|
+
the pty and parser sizes side by side, to be compared with the pane you can see
|
|
193
|
+
rather than with each other. **DSR answered** is the one that matters:
|
|
194
|
+
ConPTY blocks until its opening cursor query is answered, so a red zero there
|
|
195
|
+
means the session is hung rather than slow. `docs/conpty-findings.md` explains
|
|
196
|
+
each field and why it is on screen.
|
|
197
|
+
|
|
198
|
+
## Layout
|
|
199
|
+
|
|
200
|
+
60/40 split, and below 60 columns the right pane collapses entirely rather than
|
|
201
|
+
squeezing Claude into 36. The pty is sized from exactly the rect that was drawn,
|
|
202
|
+
once per frame, which is also what coalesces a window drag into a single ConPTY
|
|
203
|
+
resize.
|
|
204
|
+
|
|
205
|
+
## Repository
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
crates/abeam-pty/ the pty host layer: ConPTY session, input encoding, DSR
|
|
209
|
+
crates/abeam/ the binary: shell, layout, focus, panes
|
|
210
|
+
crates/abeam/tests/end_to_end.rs abeam itself, hosted in a pty and typed at
|
|
211
|
+
docs/conpty-findings.md what the spike learned. Read before touching the pty.
|
|
212
|
+
docs/keymap.md the keybinding collision audit
|
|
213
|
+
pyproject.toml maturin's instructions for wrapping the binary
|
|
214
|
+
.github/workflows/ ci on every push; release on a v* tag
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## Releasing
|
|
218
|
+
|
|
219
|
+
Tag it and push the tag:
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
git tag v0.0.1 && git push origin v0.0.1
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
`release.yml` builds the wheel on Windows and uploads it to PyPI through
|
|
226
|
+
**trusted publishing** — an OIDC exchange between GitHub and PyPI, so there is
|
|
227
|
+
no API token in this repository to leak or rotate. PyPI is configured to trust
|
|
228
|
+
one repository, one workflow file and one environment (`pypi`); renaming any of
|
|
229
|
+
the three breaks the publish, deliberately.
|
|
230
|
+
|
|
231
|
+
The version lives in `[workspace.package]` in `Cargo.toml` and nowhere else. The
|
|
232
|
+
workflow refuses to run if the tag disagrees with it, because a release where
|
|
233
|
+
those two differ is discovered by whoever installs the wrong thing.
|
|
234
|
+
|
|
235
|
+
`cargo run -p abeam-pty --example host` is a complete pty host in one file, kept
|
|
236
|
+
as the manual regression harness and as proof that `PtySession` is sufficient
|
|
237
|
+
without abeam. The one thing that reproduces the ConPTY stall itself is the
|
|
238
|
+
ignore-DSR arm of `conpty_stalls_until_the_dsr_query_is_answered` in
|
|
239
|
+
`crates/abeam-pty/tests/conpty.rs`, which pins it in both directions.
|
|
240
|
+
|
|
241
|
+
Build and test with `--all-targets`, or the examples bit-rot:
|
|
242
|
+
|
|
243
|
+
```
|
|
244
|
+
cargo build --workspace --all-targets
|
|
245
|
+
cargo test --workspace
|
|
246
|
+
cargo clippy --workspace --all-targets
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Status
|
|
250
|
+
|
|
251
|
+
Working, and used. Not finished.
|
|
252
|
+
|
|
253
|
+
**Done.** The pty host layer, proven by a spike that ran a real Claude session
|
|
254
|
+
against it on 2026-08-01. All three right-hand views, the file list and the find
|
|
255
|
+
under it, the rendered/source toggle, and the watcher driving what it should.
|
|
256
|
+
Focus, zoom, help, the diagnostics view, and the literal-next escape hatch.
|
|
257
|
+
248 tests, `clippy --all-targets` clean.
|
|
258
|
+
|
|
259
|
+
**Verified how.** The whole path — pty → parser → pane, git worker → real `git`
|
|
260
|
+
→ rendered rows, watcher → both panes, Enter in git → open in files — is
|
|
261
|
+
covered by tests that spawn a real ConPTY child and draw real frames.
|
|
262
|
+
|
|
263
|
+
On top of that, `crates/abeam/tests/end_to_end.rs` does to abeam what abeam does
|
|
264
|
+
to Claude: it spawns **the built binary** in a ConPTY, types at it as bytes, and
|
|
265
|
+
reads the screen that comes back. That is what proves the parts no in-process
|
|
266
|
+
test can reach — that abeam starts at all, that raw mode and the alternate
|
|
267
|
+
screen survive being someone else's child, that `Alt+S` written as `ESC s`
|
|
268
|
+
becomes the binding it should, and that a command typed into the shell view runs
|
|
269
|
+
in the right directory and puts its answer on screen. Three paths are pinned that
|
|
270
|
+
way today: type a command in the shell and read its output; reach a file nothing
|
|
271
|
+
pointed the pane at, by `Alt+E` `Alt+E` `/`; and a copy of a real shell planted
|
|
272
|
+
in the repository under the name abeam is about to look for, which abeam must
|
|
273
|
+
refuse to run. That last one is a test about an attack rather than a feature —
|
|
274
|
+
Windows resolves a bare program name against the *calling* process's directory
|
|
275
|
+
before it consults `PATH`, so a `pwsh.exe` committed to a cloned repo was one
|
|
276
|
+
keystroke from executing. For the whole session abeam now stands in
|
|
277
|
+
`%SystemRoot%` and hands its pty absolute paths only.
|
|
278
|
+
|
|
279
|
+
What none of it covers is a human at a terminal. The six pass criteria in
|
|
280
|
+
`docs/conpty-findings.md` (rendering, one character per keystroke, editing keys,
|
|
281
|
+
live resize, paste, `/exit`) were confirmed against the spike's host and have
|
|
282
|
+
not been re-run against `abeam` itself since the panes landed. Do that before
|
|
283
|
+
trusting it with real work.
|
|
284
|
+
|
|
285
|
+
**Not done, and known.**
|
|
286
|
+
|
|
287
|
+
- **The shell view has never been driven by a human.** A test types `set /a
|
|
288
|
+
123*456` into the real binary and reads `56088` back off the screen, which is
|
|
289
|
+
more than a smoke test and still less than use: the six pass criteria above
|
|
290
|
+
were confirmed against Claude in the *left* pane, and a shell in a
|
|
291
|
+
46-column right pane is not the same thing. Expect the first real `cargo test`
|
|
292
|
+
run in there to find something about width, wrapping or the scrollback that no
|
|
293
|
+
test thought to ask about.
|
|
294
|
+
- **`Alt+J` is on borrowed time.** Claude has a live `app:toggleTerminal` action
|
|
295
|
+
with no default key, and its footer already prints `meta + j` as a fallback —
|
|
296
|
+
so Claude's own UI advertises a key abeam has claimed. Nothing is bound today
|
|
297
|
+
and the invariant holds; the day it is bound, abeam has to move.
|
|
298
|
+
`docs/keymap.md` carries the details.
|
|
299
|
+
- **An npm-installed `claude` cannot be hosted.** `npm i -g` puts three files in
|
|
300
|
+
`%APPDATA%\npm`: `claude` (a POSIX shell script, no extension), `claude.cmd`
|
|
301
|
+
and `claude.ps1`. Windows starts only `.exe` and `.com` directly, so plain
|
|
302
|
+
`abeam` fails at startup for those users — and the two obvious fixes are both
|
|
303
|
+
wrong: preferring the `.cmd` does not help, because `CreateProcessW` cannot
|
|
304
|
+
run that either, and going through `cmd.exe /c` hands abeam's own argv to a
|
|
305
|
+
command-line re-parser that treats `&`, `|` and `^` as syntax. The native
|
|
306
|
+
installer (`claude.exe`) is unaffected. Fixing it properly is a decision about
|
|
307
|
+
how abeam launches its main program, not a patch.
|
|
308
|
+
- **Windows only.** Not a portability bug so much as an absence of work: nothing
|
|
309
|
+
outside `abeam-pty` is platform-specific, but nothing has been tried.
|
|
310
|
+
- **No configuration.** Keybindings, the split ratio and the refresh interval are
|
|
311
|
+
all constants. Claude's own bindings are user-configurable, so abeam's should
|
|
312
|
+
be too before anyone else uses it.
|
|
313
|
+
- **No diff view.** The git pane shows *which* files changed and by how many
|
|
314
|
+
lines, not what changed in them.
|
|
315
|
+
- **The first source file with code in it costs a visible hitch** of 100–200 ms,
|
|
316
|
+
while syntect deserialises its syntax and theme dumps. A session that only
|
|
317
|
+
reads prose never pays it.
|
|
318
|
+
- **Laying a document out happens on the frame path**, and stalling a frame
|
|
319
|
+
stalls Claude's keystrokes. Reading is the cheap half; parsing, highlighting
|
|
320
|
+
and wrapping is the expensive one, and it runs again at every new width, so
|
|
321
|
+
dragging the window border with a large document open pays it per frame. The
|
|
322
|
+
only bound on it is the 512 KiB read cap — about 210 ms of layout in a release
|
|
323
|
+
build, measured — and going over that is visible: the pane says where it
|
|
324
|
+
stopped. Highlighting gives up above 64 KiB and shows plain text. A slow
|
|
325
|
+
network share can still stall the frame that opens a file.
|
|
326
|
+
- **Source highlighting assumes a dark terminal** (base16-ocean.dark). A TUI
|
|
327
|
+
cannot ask the terminal for its palette. Backgrounds are discarded so that a
|
|
328
|
+
light theme is washed out rather than unreadable.
|
|
329
|
+
- **UTF-16 files are reported as binary.** The sniff is a NUL byte in the first
|
|
330
|
+
8 KiB, which is what git does.
|
|
331
|
+
- **Two Claude features are unreachable inside abeam**, and both will be reported
|
|
332
|
+
as abeam bugs: `Ctrl+Shift+B` and `Ctrl+Shift+C` are indistinguishable from
|
|
333
|
+
`Ctrl+B` / `Ctrl+C` in legacy terminal encoding, and hold-to-talk voice needs
|
|
334
|
+
key *release* events, which abeam drops for a load-bearing reason
|
|
335
|
+
(`docs/conpty-findings.md`, constraint 3).
|
|
336
|
+
- **`EnableMouseCapture` disables your terminal's native text selection.**
|
|
337
|
+
Copying out of abeam needs Shift+drag, and which terminals honour that varies.
|
|
338
|
+
- **The `Alt` namespace is free against one audited Claude build** (2026-07-25).
|
|
339
|
+
It is not guaranteed free forever; `Ctrl+\` is the mitigation.
|
|
340
|
+
|
|
341
|
+
## A warning for anyone changing the pty layer
|
|
342
|
+
|
|
343
|
+
`docs/conpty-findings.md` lists five constraints that look like things to tidy
|
|
344
|
+
up and are not. The shortest version: ConPTY hangs forever if you do not answer
|
|
345
|
+
its opening `ESC [ 6 n`, `wait()` never returns so only `try_wait()` is safe,
|
|
346
|
+
Windows sends a Release event for every key and forwarding it double-types
|
|
347
|
+
everything, mouse reports must be gated on what the hosted app enabled, and
|
|
348
|
+
`Screen::contents()` tells you nothing about layout.
|
|
349
|
+
|
|
350
|
+
There are tests pinning all five. Read the document first.
|
|
351
|
+
|
|
352
|
+
## License
|
|
353
|
+
|
|
354
|
+
MIT. See [LICENSE](LICENSE).
|
|
355
|
+
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
abeam-0.0.1.data/scripts/abeam.exe,sha256=MegVq8AWOs31xbJIdnOCa2h-7R_EsnLXFszqfH6dMYE,4658688
|
|
2
|
+
abeam-0.0.1.dist-info/METADATA,sha256=n9lAlt3T7qSPYdBLbpcTpD9ZIUfwkvGbLcud3DK9qnM,19293
|
|
3
|
+
abeam-0.0.1.dist-info/WHEEL,sha256=2zDlIYIdD4m4N3p5DVEG3iJhGLdhsBQgdH-FqVkAur8,94
|
|
4
|
+
abeam-0.0.1.dist-info/licenses/LICENSE,sha256=WjN_Zhc7AK0DglJTwdUcgqkGSnV7EoTqdttW5GcWHAE,1091
|
|
5
|
+
abeam-0.0.1.dist-info/sboms/abeam.cyclonedx.json,sha256=Ly_Et7ZxkwpsSDUahZgLw3hV_xUluNt3oGgN22tlbzY,237127
|
|
6
|
+
abeam-0.0.1.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Phil Harrison
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|