Skip to content

Session Transcripts

Session transcripts capture what appears in your terminal during a session. Save what is already on screen after the fact, or record from a point in time onward, and export the result for audit logs, documentation or troubleshooting.

Open the session’s ⋮ menu in the session bar (the terminal’s right-click menu has the same actions):

  • Save transcript so far writes everything the terminal currently holds, scrollback included, whether or not you were recording. It is the one to reach for after the fact: the output is already there, so nothing had to be switched on beforehand.
  • Record transcript from now starts a recording. Every byte the session shows from this moment is kept in memory, timestamped relative to the start, until you stop.
  • Stop recording and save saves the recording and then stops it. If you cancel the save, the recording keeps running; nothing is thrown away.

While a recording runs, the session bar shows a recording indicator and Save transcript so far is still available.

Every save asks two things, in this order:

  1. Encrypt the file (a .zesttx file only ZestSSH can open) or save it as plain text (a .txt file any editor can read). Plain text carries a warning, because a transcript can contain passwords, keys or other sensitive output the session printed.
  2. Where: the OS Save As dialog, opened in ZestSSH/transcripts under your documents folder with a name made from the host label and the time.

Once it is written you get a toast with the path and a Show in folder button, and the path is kept in the notification bell in case the toast has gone.

The file starts with a header (which connection, when, and whether it is a recording or a snapshot of the terminal), the sensitive-data warning, and then the output.

Tap the record button in the terminal toolbar to start recording, and tap it again to stop. Stopping saves the recording into the app’s documents directory (ZestSSH/transcripts/, encrypted in release builds) and shows the path. The toolbar’s export action saves what is on screen, and the share action hands it to another app.

Encrypted transcript files carry a .zesttx extension. On desktop you choose encryption each time you save; on mobile, release builds encrypt automatically. When a file is encrypted:

  • Encryption: a non-AES construction. An HMAC-SHA256 keystream is used in a counter-mode-like way and XORed with the plaintext. A random 16-byte IV is generated for each file.
  • Integrity: a separate HMAC-SHA256 tag (encrypt-then-MAC, under an independent key) is appended to the file. On read, the HMAC is verified using constant-time comparison before any decryption occurs. If the tag does not match, decryption is refused.
  • Key management: a 256-bit key is generated on first use via Random.secure() and stored in FlutterSecureStorage (Keychain on iOS, EncryptedSharedPreferences on Android, OS credential store on desktop). Independent keystream and MAC subkeys are derived from it.
  • File format: [1-byte version] [16-byte IV] [ciphertext] [32-byte HMAC-SHA256], saved with a .zesttx extension (files written by older builds omit the leading version byte).

Saving as plain text (a desktop option, and the default in debug builds) writes a readable .txt file with no encryption, clearly flagged as “not encrypted” when it saves.

The transcript reader detects the file extension to determine the format:

  • .txt files are read as plain text.
  • .zesttx files are decrypted using the stored encryption key, with HMAC verification before decryption.

If the encryption key is lost (for example, app data cleared without a backup), encrypted transcripts cannot be recovered.

A recording buffers up to 50,000 entries or 16 MB, whichever comes first; when a limit is reached the oldest entries are dropped to make room. A Save transcript so far snapshot is bounded by the terminal’s scrollback setting instead.

  • Transcripts capture rendered terminal output, not raw SSH channel data.
  • A recording lives in memory until you stop and save it. If the app is killed before then, the recording is lost; a session log is written to disk as it happens and does not have this problem.
  • Transcript files are stored locally. They are not included in cloud sync.