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
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# Changelog

## 0.1.5

- Add `--record-stdin` so `twatch` can record terminal output from stdin without spawning a child PTY
- Add `--size WIDTH,HEIGHT` for fixed-size stdin recording and document the tmux-oriented JSONL recording flow
- Store `--record-stdin` traces as checkpoints plus deltas instead of writing a full snapshot on every frame
- Compact in-memory cell symbols, compress delta history when `-C` is enabled, and raise the default checkpoint interval to reduce long-running memory pressure
- Add transparent `.jsonl.gz` log read/write support and make the tmux plugin default to `archive` compression so active pane replay stays faster
- Compress large snapshot and delta payloads inside JSONL records so plain `.jsonl` traces also shrink without hiding frame metadata
- Open replay after preloading the first 256 frames and continue loading the rest in the background to reduce large-log startup delay
- Spill older active `--record-stdin` frames into a compact sidecar during long-running sessions so live `.jsonl` logs grow more slowly
- Add tunable `--record-stdin-spill-every` and `--record-stdin-spill-retain` controls, and store deltas in a more compact run/style-table form to shrink active tmux logs further
- Treat `-L 0` as unlimited history retention so tmux replay can avoid trimming large recordings on startup
- Write active JSONL records in a more compact array-based format while keeping backward-compatible readers for older object-based logs

This release is focused on tmux-oriented recording and replay scalability.
It adds the first backend-oriented building block for `tmux pipe-pane` style integrations by letting `twatch` ingest terminal output from stdin and store it as replayable traces.

Notes:

- `--record-stdin` requires `--logfile` and cannot be combined with `--batch`, `--replay`, or a child command
- Replay readers remain backward-compatible with older object-based JSONL logs

## 0.1.4

- Add customizable `twatch` keymaps with `-K/--keymap KEY=ACTION`, including pane-specific navigation, snapshot actions, pause control, and app-input mode switching
Expand Down
23 changes: 22 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "twatch"
version = "0.1.4"
version = "0.1.5"
edition = "2024"
description = "twatch - record, rewind, and diff terminal UI screens."
license = "MIT"
Expand All @@ -12,12 +12,14 @@ homepage = "https://github.com/blacknon/twatch"

[dependencies]
anyhow = "1.0"
base64 = "0.22"
clap = { version = "4.5", features = ["derive"] }
crossterm = "0.28"
flate2 = "1.1"
portable-pty = "0.9"
ratatui = "0.30"
regex = "1.12"
rmp-serde = "1.3"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
shell-words = "1.1"
Expand Down
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ Options:

--replay <REPLAY>
Replay a saved JSONL trace in read-only mode
--record-stdin
Record terminal output from stdin without spawning a child PTY
--size <WIDTH,HEIGHT>
Use a fixed terminal size for stdin recording
--screenshot-dir <SCREENSHOT_DIR>
[default: /tmp]
--screenshot-format <SCREENSHOT_FORMAT>
Expand All @@ -116,7 +120,7 @@ Options:
-L, --limit <LIMIT>
[default: 500]
--checkpoint-interval <CHECKPOINT_INTERVAL>
[default: 12]
[default: 120]
--debug
Show debug diagnostics in the interactive UI
-h, --help
Expand Down Expand Up @@ -313,6 +317,15 @@ This is useful for debugging long-running screens outside the live UI.
twatch --logfile ./twatch.jsonl htop
```

### Stdin recorder

Record terminal output from stdin into a JSONL trace without launching a child PTY.
This is the backend intended for tmux `pipe-pane` style integrations.

```bash
tmux pipe-pane -o "twatch --record-stdin --size '#{pane_width},#{pane_height}' --logfile '$HOME/.local/state/twatch/tmux/pane-12.jsonl'"
```

### Replay mode

Open a saved JSONL trace without launching a child PTY.
Expand Down
4 changes: 3 additions & 1 deletion src/app/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub(super) struct AppConfig {
pub aftercommand_runtime: Option<AfterCommandRuntime>,
pub command_display: String,
pub debug: bool,
pub hide_header: bool,
pub keymap: Vec<KeyBinding>,
pub child_bindings: Vec<ChildBinding>,
}
Expand Down Expand Up @@ -59,7 +60,7 @@ impl AppConfig {
Ok(Self {
child_pause_supported,
diff_mode: cli.differences.into(),
history_limit: cli.limit.max(1),
history_limit: cli.limit,
checkpoint_interval: cli.checkpoint_interval.max(1),
compress: cli.compress,
logfile: cli.replay.clone().or(cli.logfile.clone()),
Expand All @@ -84,6 +85,7 @@ impl AppConfig {
}),
command_display,
debug: cli.debug,
hide_header: cli.hide_header,
keymap,
child_bindings,
})
Expand Down
2 changes: 1 addition & 1 deletion src/app/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl App {
}
}

fn current_snapshot_matches_filter(&self) -> bool {
pub(super) fn current_snapshot_matches_filter(&self) -> bool {
let Some(snapshot) = &self.current_snapshot else {
return false;
};
Expand Down
Loading
Loading