Welcome to tx
tx is a thin, configurable launcher for AI code-assistant sessions. It gives you a fast terminal UI, reproducible pipelines, and integration points for your favourite providers so you can move between conversations without losing context. The latest rendered version of this guide lives at tx.bedecarroll.com.
Why tx?
- One keystroke launches the TUI, lets you select a session or profile, and runs or inserts the assembled command.
- Search recent work with a prompt-first filter or full-text indexing, then resume a session exactly where it left off.
- Compose providers, pre snippets, post processors, and wrappers with TOML configuration—no bespoke scripting required.
- Keep logs, cache, and configuration under XDG-friendly directories for predictable automation.
- Integrations such as prompt-assembler and the built-in self-update command extend tx without complicating the core workflow.
This book walks through the features from first install to advanced automation so you can make tx part of your daily development loop.
Getting Started
Start here if you are new to tx. The chapters in this section cover installation paths, the minimum configuration required to launch the TUI, and the filesystem layout tx relies on for state. Once you finish, you will have a working setup that can start and resume sessions.
Install
tx publishes as a standard Rust binary. Install from the GitHub releases if you want a ready-to-run build, or compile from source when you need to hack locally.
Install from a release
curl --proto '=https' --tlsv1.2 -LsSf \
https://github.com/bedecarroll/tool-executor/releases/latest/download/tx-installer.sh \
| sh
Windows users can run:
powershell -ExecutionPolicy Bypass -c "irm https://github.com/bedecarroll/tool-executor/releases/latest/download/tx-installer.ps1 | iex"
The scripts install tx into your Cargo binary directory and verify checksums. Manual downloads are available on the release page—look for the tx-<target>.tar.gz (Unix) or tx-<target>.zip (Windows) assets if you prefer to unpack them yourself.
Build from source
# from a cloned repository
cargo install --path .
# once crates.io publishing begins
cargo install tool-executor
The build expects Rust 1.90 (edition 2024). If you use rustup, pin the toolchain by running rustup override set 1.90.0 inside the repository. Tooling such as cargo-nextest, cargo-insta, and cargo-llvm-cov are managed through mise; run mise trust followed by mise install if you plan to execute the provided quality checks locally.
When packaging for a team, prefer cargo dist tasks (mise run dist-*) so CI and local builds stay aligned.
Quick Start
Follow this checklist to boot a useful environment.
-
Create the storage directories tx expects:
mkdir -p ~/.config/tx/conf.d ~/.local/share/tx ~/.cache/tx -
Drop a minimal provider configuration in the first drop-in file:
# ~/.config/tx/conf.d/00-providers.toml [providers.codex] bin = "codex" flags = ["--search"] env = ["CODEX_TOKEN=${env:CODEX_TOKEN}"] stdin_mode = "pipe" -
Optionally register a profile that chains snippets or wrappers:
# ~/.config/tx/conf.d/10-profiles.toml [profiles.kickoff] provider = "codex" description = "Start a fresh Codex session" pre = [] post = [] wrap = "tmux_simple" [wrappers.tmux_simple] shell = true cmd = "tmux new -s tx-{{session.id}} '{{CMD}}'" -
Launch
txin the terminal. UseTabto insert the assembled command into your shell, pressEnterto execute it immediately,Ctrl+Yto print the selected session ID, orCtrl+Eto export the session transcript without leaving the UI.
At this point the TUI lists recent sessions on the left and configured profiles on the right. Select an item, review the preview pane, then run it.
Directory Layout
tx follows XDG conventions for configuration and caches. The default locations are:
| Purpose | Environment | Default Path |
|---|---|---|
| Configuration | TX_CONFIG_DIR or XDG_CONFIG_HOME | ~/.config/tx |
| Data (session log index, database) | XDG_DATA_HOME | ~/.local/share/tx |
| Cache (search index, transient state) | XDG_CACHE_HOME | ~/.cache/tx |
Configuration is layered. tx loads the base config.toml from the config directory and merges overrides from conf.d/*.toml in lexical order. Use small, well-scoped drop-in files (00-providers.toml, 10-profiles.toml, and so on) so teams can share or version-control only the pieces that change.
If you prefer a custom layout, pass --config-dir <path> or export TX_CONFIG_DIR. The override applies to both the main file and the conf.d/ directory.
Using the TUI
Launch tx with no arguments to open the terminal UI. The layout includes:
- Session list on the left with your most recent conversations.
- Profiles pane on the right listing saved configurations and virtual entries (such as prompt-assembler prompts).
- Preview area beneath the lists that shows the assembled pipeline, recent transcript highlights, or provider descriptions.
Keyboard highlights:
↑/↓orj/kmove through the active list.PgUp/PgDnjump roughly ten entries at a time.- Typing letters, numbers, or punctuation filters the list; use
Backspaceto edit the filter. Tabswitches focus between sessions and profiles and emits the assembled command to stdout.Ctrl+Tabperforms the same emit action for terminals that forward the modifier.Enterruns the selected entry immediately.Ctrl+Ftoggles between prompt search and full-text search.Ctrl+Pcycles the provider filter.Ctrl+Yprints the highlighted session ID to stdout and exits the TUI.Ctrl+Eexports the highlighted session transcript (matchingtx export) and exits the TUI.Escbacks out of filter overlays or closes the TUI entirely.
The footer displays diagnostics such as hidden providers or stale configuration. Increase verbosity with -v or -vv when launching tx if you want extra logging while you explore the UI.
Session Search
tx search surfaces the same data that powers the TUI, but in a script-friendly format. By default it lists recent sessions. Add arguments to narrow the results:
tx search assetperforms a prompt-only (first user message) search forasset.tx search context --full-textscans the entire transcript with the full-text index.tx search context --full-text --role assistantlimits hits to the assistant replies.
The JSON output includes the snippet that matched, the role (user or assistant), and last_active timestamps. Use it to feed dashboards, quick filters, or shell pipelines.
Session Lifecycle
tx keeps sessions lightweight so you can jump between experiments quickly.
- Start a new session by choosing a profile or provider from the TUI.
txrecords metadata immediately so the entry appears in recent sessions. - Resume a session by selecting it in the list or running
tx resume <session-id>. PressCtrl+Yin the TUI to print the highlighted session ID for copy/paste. The original provider, snippets, and wrappers are reused to avoid surprises. - Export transcripts with
tx export <session-id>, or pressCtrl+Ein the TUI to stream the same export to stdout without leaving the UI. The output is plain text so you can archive it or share context with collaborators. - Archive sessions by removing or moving the log files outside the tracked directories. They disappear from the default listing but remain searchable if the index still references them.
Each session stores its configuration snapshot. That means later configuration changes do not retroactively modify old runs; you stay reproducible even when options evolve.
Pipelines and Wrappers
Every tx launch assembles a pipeline:
stdin -> <pre snippets> -> provider -> <post snippets>
Snippets run as shell commands. Define them under [snippets.pre] or [snippets.post] in configuration and refer to them by name. Use pre snippets to stage prompts, template files, or environment setup; use post snippets to collect output, sync logs, or notify teammates.
Wrappers enclose the provider inside another process. Common patterns include running providers inside tmux sessions, Docker containers, or detached shells. A wrapper declares whether it should be invoked via /bin/sh -c (shell = true) and describes the command or argv array to execute. The placeholder {{CMD}} expands to the final provider command.
Combining snippets and wrappers lets you build repeatable, sharable workflows without shell scripts. Change the configuration once and the TUI, CLI, and exported commands follow suit.
Configuration Guide
tx reads declarative TOML. This section explains how configuration files are discovered, how individual sections work, and how to combine them into reusable profiles.
Command Syntax
Any field in this guide that asks for a command accepts either a single string or an explicit array. A string such as "glow -s dark" is parsed with shell-style quoting, while an array like ["glow", "-s", "dark"] keeps arguments exactly as written. Pick the form that keeps the intent clearest in your configuration files.
Schema Reference
Generate the complete JSON Schema with tx config schema --pretty whenever you need editor integration or automated validation. The published documentation bundles the latest schema at config-schema.json; download it directly or pipe the CLI output to a file to stay in sync.
Editor Integration
Many editors understand the #:schema directive at the top of a TOML file. Add the following line to any tx configuration file to enable inline validation, autocomplete, and hover docs:
#:schema https://tx.bedecarroll.com/assets/config-schema.json
After saving, supported editors will:
- Suggest configuration keys as you type.
- Flag invalid values with diagnostics.
- Surface field documentation on hover.
Configuration Files
tx loads configuration in this order:
$TX_CONFIG_DIR/config.toml(or$XDG_CONFIG_HOME/tx/config.tomlwhen the environment variable is unset).- All files under
$TX_CONFIG_DIR/conf.d/sorted lexicographically. - Command-line overrides such as
--config-dirrewrite the base path and restart the process above.
Each file is optional; tx tolerates partial definitions. The loader merges tables rather than replacing the entire structure, so you can keep shared defaults in config.toml and apply local overrides in numbered drop-ins.
Use small files with predictable numbers: 00-providers.toml for core provider declarations, 10-profiles.toml for team workflows, 20-local.toml for personal overrides. This keeps diffs targeted and makes it easy to sync only the pieces collaborators need.
Providers
Providers describe how tx should invoke an external AI assistant. Each provider entry lives under [providers.<name>] and requires at least a bin key.
[providers.codex]
bin = "codex"
flags = ["--search"]
env = ["CODEX_TOKEN=${env:CODEX_TOKEN}"]
stdin_mode = "pipe"
Key fields:
bin: executable name or absolute path.flags: default arguments passed to the provider.env: environment entries formatted asKEY=value. Use${env:VAR}to interpolate environment variables at runtime.stdin_mode: choose how stdin flows to the provider.pipe(default) streams data directly;capture_argcollects stdin and passes it as a positional argument.stdin_to: set whenstdin_mode = "capture_arg"to describe how the captured text should be substituted into the argument list. Include"{prompt}"to position the captured text.
Keep provider definitions small and descriptive. If a backend exposes many toggles, prefer encoding the common ones in flags and exposing the rest as profile-level options so users can switch between variants.
Snippets
Snippets are reusable shell commands that run before or after the provider. Declare them in two tables:
[snippets.pre]
refresh_context = "scripts/generate-context"
format_prompt = "prompt-tool --file prompt.md"
[snippets.post]
archive = "scripts/archive-session {{session.id}}"
Reference snippets by name in profiles. tx executes pre snippets in declaration order before the provider starts, piping stdin through each command. Post snippets run after the provider exits and receive the provider's stdout via stdin.
Snippets support the same templating tokens as wrappers, including {{session.id}}, {{var:KEY}}, and environment lookups. Use them to stitch together existing tooling without modifying tx itself.
Wrappers
Wrappers launch providers inside another process. They live under [wrappers.<name>] and must declare a cmd.
[wrappers.tmux]
shell = true
cmd = "tmux new -s tx-{{session.id}} '{{CMD}}'"
Options:
shell: whentrue, run the command via/bin/sh -c. Leave it unset (orfalse) to provide an argv array instead.cmd: shell string or array describing the wrapper invocation. The token{{CMD}}expands to the provider command after snippets are applied.
Use wrappers for tmux sessions, nohup/detached runs, or containerized backends. Wrappers stack with snippets, so you can prepare files, launch the wrapper, then process results without leaving the TOML layer.
Profiles
Profiles bundle providers, snippets, and wrappers into a menu entry. They appear under [profiles.<name>].
[profiles.kickoff]
provider = "codex"
description = "Start a new Codex session"
pre = ["refresh_context"]
post = ["archive"]
wrap = "tmux"
Fields:
provider(required): references a provider key.description: short label shown in the TUI preview.pre/post: arrays of snippet names.wrap: wrapper name.
Profiles can represent common workflows (bug triage, onboarding, runbooks) without duplicating configuration. Pair them with prompt-assembler integration to surface dynamic prompts alongside static entries.
Prompt Assembler Integration
Enable prompt-assembler support to expose reusable prompt recipes as virtual profiles.
Requirements
prompt-assembler(thepaCLI) must be onPATH.- tx v0.1.0 or newer.
- Configuration managed under the usual directories (
~/.config/txby default).
If pa returns an error or invalid JSON, tx hides the virtual profiles and prints a notice in the TUI footer.
Configuration
Create a drop-in file such as ~/.config/tx/conf.d/20-pa.toml:
[features.pa]
enabled = true
namespace = "pa"
namespacecontrols the prefix shown in the TUI (for examplepa/bootstrap).- Restart tx to refresh the list; the TUI re-runs
pa list --jsonwhen it launches.
Using Virtual Profiles
When the feature is active:
- Virtual entries appear in the profiles pane alongside regular profiles.
- The preview pane renders Markdown metadata (bold headings for provider, description, and tags) followed by a fenced code block labelled
markdownthat contains the assembled prompt frompa show --json <prompt-name>. Enterlaunches the pipeline immediately;Tabprints it for shell reuse.- When a previous session is highlighted you can press
Ctrl+Yto print its ID orCtrl+Eto export its transcript before switching back to the profile pane.
Behind the scenes tx inserts pa <prompt> as a pre snippet before your provider. Combine the feature with stdin_mode = "capture_arg" to pass assembled prompts as arguments:
[providers.codex]
bin = "codex"
flags = ["--search"]
stdin_mode = "capture_arg"
stdin_to = "codex:{prompt}"
With that configuration, selecting pa/hello captures the generator output and invokes the provider with codex --search "<prompt-text>".
Troubleshooting
- Run
tx doctorto confirmpais discoverable. - Increase logging with
RUST_LOG=tx=debug txif profiles disappear. - Restart tx after changing prompts in the
prompt-assemblerrepository.
Known limitation: additional metadata beyond tags and contents still requires future enhancements.
Advanced Topics
These chapters explore automation, logging, and other advanced capabilities. Use them when you want to script tx, integrate it with CI, or run the built-in self-update workflow.
Automation and Scripting
tx offers dedicated CLI commands for non-interactive workflows:
tx search+--full-textexposes JSON suitable for quick filters or dashboards.tx resume <session-id>relaunches an existing session with its original configuration.tx export <session-id>prints transcripts for archiving or sharing.tx config list|dump|where|lintinspects configuration state in batch jobs.
Combine them with shell tools to build automation. Examples:
# Resume the most recent session tagged "review"
tx search review --full-text --role user \
| jq -r 'sort_by(-.last_active)[0].session_id' \
| xargs tx resume
# Export the most recent assistant reply for quick sharing
tx search --full-text --role assistant \
| jq -r 'sort_by(-.last_active)[0].snippet' \
| tee /tmp/tx-latest.txt
When you need structured pipelines, rely on snippets and wrappers instead of bespoke scripts. Record the behaviour in configuration so other users receive the same automation by default.
Logging and Diagnostics
Increase verbosity with -v or -vv:
tx -v # info + debug summaries
tx -vv # full debug traces
Set RUST_LOG for granular control over subsystems:
RUST_LOG=tx=debug,rusqlite=warn tx
When troubleshooting configuration or prompt-assembler integration, run tx doctor. It verifies provider executables, checks for schema drift, and surfaces missing configuration keys. Combine it with verbose logging to track down path issues or environment variables.
Self-Update Feature
tx ships with a built-in self-update subcommand that pulls releases from GitHub. Install from source as usual—the command is available without extra feature flags:
cargo install --path .
Usage:
tx self-update # update to the latest GitHub release
tx self-update --version v0.3.0
The release archive formats are aligned with cargo dist defaults (.tar.gz on Unix, .zip on Windows). Keep them in sync if you customize the distribution pipeline.
Reference
Look up exact keys, commands, and repeatable processes here. The reference pages complement the narrative guides by listing the authoritative values.
Configuration Reference
This table lists every key tx reads from configuration files. Types refer to TOML types.
Defaults
| Key | Type | Default | Description |
|---|---|---|---|
provider | string | codex | Provider used when starting a new session without a profile. Must match a key under [providers]. |
profile | string | unset | Preferred profile when creating sessions. Must match a key under [profiles]. |
search_mode | string | first_prompt | Initial search mode in the TUI. Accepts first_prompt or full_text. |
Sessions the indexer marks as unactionable stay hidden from default listings but remain searchable.
Providers ([providers.<name>])
| Key | Type | Required | Description |
|---|---|---|---|
bin | string | ✅ | Executable or absolute path. |
flags | array<string> | Default arguments passed to the provider. | |
env | array<string> | Environment entries (KEY=value). Supports ${env:VAR} interpolation. | |
stdin_to | string | Template describing how to inject captured stdin into the argv list. Requires stdin_mode = "capture_arg". | |
stdin_mode | string | Delivery mode: pipe (default) streams stdin; capture_arg passes stdin as an argument. |
Snippet Commands ([snippets.pre], [snippets.post])
Values are shell commands executed before or after the provider. They can reference template tokens such as {{session.id}} or {{var:KEY}}.
Wrappers ([wrappers.<name>])
| Key | Type | Required | Description |
|---|---|---|---|
shell | bool | When true, invoke the wrapper via /bin/sh -c. Defaults to false. | |
cmd | string or array<string> | ✅ | Wrapper command. Use a string when shell = true; use an array for argv-style declarations. {{CMD}} expands to the provider command. |
Profiles ([profiles.<name>])
| Key | Type | Required | Description |
|---|---|---|---|
provider | string | ✅ | Provider key to run. |
description | string | Label shown in the TUI preview. | |
pre | array<string> | Ordered list of pre-snippet names. | |
post | array<string> | Ordered list of post-snippet names. | |
wrap | string | Wrapper name. |
Prompt Assembler ([features.pa])
| Key | Type | Default | Description |
|---|---|---|---|
enabled | bool | false | Enable the integration. |
namespace | string | pa | Prefix applied to virtual profile names. |
Derived Values
- Session log roots for the
codexprovider live under$CODEX_HOMEor fall back to~/.codex/session[s]. - Directory paths expand
~and environment variables usingshellexpandwith the same rules the runtime uses.
Keys not listed here are ignored. Keep configuration minimal and additive so drop-ins compose cleanly.
CLI Cheat Sheet
| Command | Description |
|---|---|
tx | Launch the TUI. |
tx search [query] | List sessions. Use --full-text to search every message and --role to filter by user or assistant. |
tx resume <session-id> | Resume a session with its original configuration. |
tx export <session-id> | Export a transcript as Markdown. |
tx config list | Enumerate currently active configuration files. |
tx config dump | Print the merged configuration. |
tx config where | Show the source location for a specific key. |
tx config lint | Run configuration validation checks. |
tx doctor | Diagnose common environment and dependency issues. |
tx self-update [--version] | Update the binary to the latest (or specified) GitHub release. |
Release Process
The cargo dist configuration lives under [workspace.metadata.dist] in Cargo.toml. Follow these steps when preparing a release:
-
Start from a clean working tree and an updated
CHANGELOG.md. Once familiar, prefer the wrapper tasksmise run dist-planandmise run dist-build. -
Install the tooling:
cargo install cargo-dist -
Initialize metadata the first time:
cargo dist initArchives default to
.tar.gzon Unix and.zipon Windows sotx self-updatecan consume them without extra configuration. -
Review the changes to
Cargo.tomland any suggested workflow files; commit them together. -
For each release candidate:
cargo dist plan cargo dist build cargo dist host cargo dist announce -
Tag the release and push to GitHub.
When cargo dist edits CI workflows, prefer running it locally and committing the diff instead of patching YAML by hand.
Workspace crates and versioning
The project ships two crates: the tool-executor library, which contains all runtime logic, and the tx CLI wrapper that cargo dist publishes. Keep their versions aligned at all times—bump version in both Cargo.toml files together and confirm the workspace metadata points packages = ["tx"] so archives continue to use the short tx prefix.
Troubleshooting
| Symptom | Fix |
|---|---|
| Providers missing from the TUI | Run tx config lint to confirm the configuration loaded, then check that provider names match the profiles referencing them. |
| Virtual profiles absent | Ensure prompt-assembler is installed and features.pa.enabled = true. Restart the TUI so it reloads virtual profiles. |
| Search returns no hits | Rebuild the index by clearing ~/.cache/tx and restarting. Verify the session logs still exist in the expected directories. |
| Pipelines fail with exit code 127 | The provider or snippet binary is not discoverable. Run tx doctor and update the PATH or absolute paths. |
| tmux wrappers exit immediately | Include quotes around {{CMD}} when using shell = true so tmux receives the full pipeline command. |
For verbose tracing, add -vv or set RUST_LOG=tx=debug. Capture logs when filing issues so maintainers can reproduce the environment.
Appendix
Supporting material for teams and contributors. Use it to align terminology and keep documentation workflows healthy.
Terminology
| Term | Meaning |
|---|---|
| Provider | External AI assistant executable that tx launches. |
| Profile | Named bundle of a provider, snippets, and optional wrapper. Appears in the TUI profiles pane. |
| Snippet | Shell command that runs before or after the provider to prepare or post-process context. |
| Wrapper | Process that surrounds the provider command (tmux, docker, etc.). |
| Session | A recorded conversation with metadata, visible in the TUI and via tx search. |
| Virtual profile | Profile generated dynamically from prompt-assembler. |
| Pipeline | The assembled flow of snippets, provider, and wrapper that tx executes. |
Documentation Workflow
The documentation lives in an mdBook located under docs/. Follow this loop to keep it healthy:
- Edit chapters under
docs/src/. UpdateSUMMARY.mdwhenever you add, remove, or move a page so the navigation stays accurate. - Run
mdbook build docsto generate the HTML output locally. The build directory defaults todocs/build/. - Validate code samples with
mdbook test docs. It compiles Rust snippets and catches copy-and-paste errors early. - Lint Markdown links and anchors with
mdbook-lintormdbook-linkcheck. Install them viacargo install mdbook-lint mdbook-linkcheckand wire into CI. - Commit both content and configuration (
docs/book.toml,docs/src/SUMMARY.md). Avoid committing the generatedbuild/output.
When writing pages:
- Prefer short headings and consistent hierarchy to keep the sidebar readable. Break long procedures into numbered lists.
- Use fenced code blocks (
```bash,```toml) so syntax highlighting works in the rendered book. - Hide boilerplate lines with mdBook's extension syntax (
#-prefixed hidden lines,// fn main() { # }, etc.) when the snippet needs to compile but should stay focused on the key lines. - Test external links periodically; mdBook's link checker helps catch outdated URLs during CI runs.
For automated environments, integrate the following into mise or CI job steps:
mdbook build docs
mdbook test docs
mdbook lint docs # provided by mdbook-lint
Running these alongside mise run fmt, mise run lint, and mise run test keeps code and docs aligned.