@t-req/app
v0.3.18
Published
API testing CLI for .http files - run requests, automate checks, and serve test workflows
Maintainers
Readme
@t-req/app (t-req CLI)
t-req is an API testing CLI and HTTP client for .http files. Run requests, automate checks, and inspect responses from the command line, interactive TUI, or web dashboard.
Developer Workflow
# 1. Scaffold a new project
treq init my-api
# 2. Open the TUI + server (starts everything)
cd my-api && treq open
# 3. Browse .http files, execute requests, run scripts -- all from the TUI
# Scripts automatically report HTTP requests back to the TUI (observer mode)
# 4. Or add --web to also open the browser dashboard
treq open --webInstallation
# Install via curl
curl -fsSL https://t-req.io/install | bash
# Or via package manager
npm install -g @t-req/app
bun add -g @t-req/appCommands
treq open - Open workspace (recommended)
Starts the server and TUI together. This is the primary way to use t-req interactively.
# Open current directory
treq open
# Open a specific workspace
treq open ./my-api
# Open with the web dashboard in your browser
treq open --web
# Custom port
treq open --port 8080Options
| Option | Description |
|--------|-------------|
| [workspace] | Workspace root directory (default: .) |
| --port, -p | Port to listen on (default: 4097) |
| --host, -H | Host to bind to (default: 127.0.0.1) |
| --web | Open the browser dashboard |
| --expose | Allow non-loopback binding (disables cookie auth) |
| --auto-update / --no-auto-update | Enable or disable startup auto-update checks (default: enabled) |
Security: a random token is generated on every launch. --web and --expose cannot be combined (SSRF protection).
treq init - Create a new project
treq init my-projectThis will prompt you to select:
- Runtime: bun (recommended) or node
- Package manager: bun, npm, pnpm, or yarn
Skip prompts with defaults:
treq init my-project --yesUses defaults: bun runtime, bun package manager, bun test runner.
Skip test file generation:
treq init my-project --yes --no-testsUse a specific test runner:
treq init my-project --yes --test-runner vitestOptions
| Option | Description |
|--------|-------------|
| [name] | Project name / directory |
| --yes, -y | Skip prompts, use defaults |
| --no-tests | Skip test file generation |
| --test-runner | Test runner to use (bun, vitest, jest) |
Generated project structure
my-project/
├── treq.jsonc # Project configuration
├── client.ts # Shared t-req client
├── run.ts # Example script (imports client)
├── tests/ # Test files (when tests enabled)
│ └── list.test.ts # Example test for users/list.http
├── collection/
│ ├── posts/
│ │ └── create.http # Example POST request
│ └── users/
│ ├── list.http # Example GET request (list)
│ └── get.http # Example GET request (single)
├── README.md
├── package.json
├── tsconfig.json
├── .treq/ # Local state (e.g. cookie jar)
└── .gitignoretreq run - Execute HTTP requests
Execute .http files directly from the command line:
# Execute the first request in a file
treq run collection/auth/login.http
# Use a config profile
treq run collection/auth/login.http --profile dev
# Execute a specific request by name
treq run collection/users.http --name "Get User"
# Execute a specific request by index
treq run collection/users.http --index 2
# Pass variables
treq run collection/auth/login.http --var [email protected] --var password=secret
# Legacy environment module (kept for compatibility)
# Loads environments/<env>.ts or environments/<env>.js from the workspace
treq run collection/auth/login.http --env dev
# Set timeout (in milliseconds)
treq run collection/auth/login.http --timeout 30000
# Verbose output (show headers)
treq run collection/auth/login.http --verboseOptions
| Option | Description |
|--------|-------------|
| --name, -n | Select request by @name directive |
| --index, -i | Select request by index (0-based) |
| --profile, -p | Config profile to use |
| --env, -e | Legacy environment module to load (environments/<env>.ts or environments/<env>.js) |
| --var | Set variable (can be used multiple times) |
| --timeout, -t | Request timeout in milliseconds |
| --workspace, -w | Workspace root directory |
| --verbose, -v | Show response headers |
treq ws - Test WebSocket sessions
Open an interactive or batch WebSocket session through a running t-req server.
# URL mode (interactive)
treq ws wss://echo.websocket.events
# File mode (select by name)
treq ws --file collection/chat.http --name connect --profile dev
# Batch mode with one-shot payload
treq ws wss://echo.websocket.events --execute '{"ping":true}' --wait 2
# NDJSON output for automation
echo '{"ping":true}' | treq ws wss://echo.websocket.events --jsonOptions
| Option | Description |
|--------|-------------|
| [url] | WebSocket URL (ws:// or wss://) |
| --file, -f | Path to .http file containing a WebSocket request |
| --name, -n | Select request by @name directive (file mode) |
| --index, -i | Select request by index (0-based, file mode) |
| --profile, -p | Config profile to use |
| --var, -v | Variables in key=value format (repeatable) |
| --server, -s | Server URL to connect to (default: http://127.0.0.1:4097) |
| --token, -t | Bearer token for authentication |
| --timeout | WebSocket connect timeout in milliseconds |
| --execute, -x | Send one message and switch to batch wait behavior |
| --wait, -w | Batch wait seconds before close (-1 waits indefinitely, default: 2) |
| --json | Emit live NDJSON events (meta.connected, ws.outbound, ws.inbound, ws.error, meta.closed, meta.summary) |
| --verbose | Show verbose output (~ frames and detailed error payloads) |
| --no-color | Disable ANSI colors in human-readable mode |
Use exactly one request source: URL positional argument or --file.
treq serve - Start HTTP server
Start an HTTP server that exposes the t-req API, enabling any programming language to execute .http files:
# Start server on default port (4097)
treq serve
# Custom port
treq serve --port 8080
# Bind to all interfaces (for remote access)
treq serve --host 0.0.0.0 --token your-secret-token
# Enable CORS for specific origins
treq serve --cors "http://localhost:3000,http://localhost:5173"
# stdio mode (JSON-RPC over stdin/stdout)
treq serve --stdioOptions
| Option | Description |
|--------|-------------|
| --port, -p | Port to listen on (default: 4097) |
| --host, -H | Host to bind to (default: 127.0.0.1) |
| --token | Bearer token for authentication |
| --cors | Allowed CORS origins (comma-separated) |
| --workspace, -w | Workspace root directory |
| --max-body-size | Max response body size in bytes (default: 10MB) |
| --max-sessions | Max concurrent sessions (default: 100) |
| --stdio | Use JSON-RPC over stdin/stdout instead of HTTP |
API Endpoints
| Method | Path | Description |
|--------|------|-------------|
| GET | /health | Server health and version info |
| GET | /config | Resolved config summary (supports ?profile= and ?path=) |
| POST | /parse | Parse .http file content |
| POST | /execute | Execute HTTP request |
| POST | /execute/sse | Execute SSE streaming request |
| POST | /execute/ws | Execute WebSocket request definition (server-owned session) |
| POST | /session | Create new session |
| GET | /session/:id | Get session state |
| PUT | /session/:id/variables | Update session variables |
| DELETE | /session/:id | Delete session |
| POST | /flows | Create a flow (Observer Mode grouping) |
| POST | /flows/:flowId/finish | Finish a flow (best-effort; server TTL will also clean up) |
| GET | /flows/:flowId/executions/:reqExecId | Fetch stored execution detail (Observer Mode) |
| GET | /workspace/files | List .http files in workspace |
| GET | /workspace/requests?path=... | List requests within a .http file |
| GET | /event?sessionId=... | SSE event stream filtered by session |
| GET | /event?flowId=... | SSE event stream filtered by flow |
| GET | /event/ws?sessionId=... | WebSocket event stream filtered by session |
| GET | /event/ws?flowId=... | WebSocket event stream filtered by flow |
| GET | /ws/session/:wsSessionId | Request session downstream control socket (WebSocket upgrade) |
| GET | /doc | OpenAPI documentation |
When
--tokenauth is enabled,/eventand/event/wsrequire eithersessionIdorflowIdto prevent cross-session leakage.
Example: Python Client
import requests
# Execute a request
response = requests.post("http://localhost:4097/execute", json={
"content": "GET https://api.example.com/users",
"variables": {"token": "abc123"}
})
print(response.json())Example: Go Client
resp, _ := http.Post("http://localhost:4097/execute", "application/json",
strings.NewReader(`{"content": "GET https://api.example.com/users"}`))Example: SSE Streaming (curl)
curl -N -X POST http://localhost:4097/execute/sse \
-H "Content-Type: application/json" \
-d '{"content": "# @sse\nGET https://sse.dev/test\n"}'Example: WebSocket Session Execute (curl)
curl -X POST http://localhost:4097/execute/ws \
-H "Content-Type: application/json" \
-d '{"content": "# @ws\nGET wss://echo.websocket.events\n"}'See examples/app/ for complete client examples in Python, Go, and TypeScript.
treq tui - Connect to existing server
Launch the TUI and connect to a server that is already running (started separately with treq serve).
# Connect to default server
treq tui
# Connect to a custom server
treq tui --server http://localhost:8080 --token my-tokenOptions
| Option | Description |
|--------|-------------|
| --server, -s | Server URL to connect to (default: http://localhost:4097) |
| --token, -t | Bearer token for authentication |
| --auto-update / --no-auto-update | Enable or disable startup auto-update checks (default: enabled) |
treq upgrade - Upgrade treq
Upgrade treq to the latest version (or a specific version). Auto-detects the installation method.
# Upgrade to latest
treq upgrade
# Upgrade to a specific version
treq upgrade 0.3.0Auto-update
Interactive commands (treq open, treq tui, treq web) perform startup update checks and attempt auto-upgrade for known install methods.
- Checks are cached for 24 hours in
~/.treq/auto-update.json - Failed auto-upgrade attempts are backed off for 24 hours for the same target version
- Successful installs apply on the next run (current process continues)
- Use
--no-auto-updateto disable per command - Use
TREQ_AUTO_UPDATE=0to disable via environment variable
Help
treq --help
treq init --help
treq run --help
treq ws --help
treq serve --help
treq open --helpTUI
The TUI provides an interactive terminal interface for browsing and executing your workspace.
Layout
- Left panel: Executions list
- Right panel: Execution details with tabs for body, headers, plugins, and output
Keyboard Shortcuts
| Key | Action |
|-----|--------|
| j / Down | Navigate down |
| k / Up | Navigate up |
| Enter | Execute selected file / toggle directory |
| Tab | Toggle between File Tree and Executions panel |
| Ctrl+H | Hide/show left panel |
| Ctrl+T | File/request picker |
| Ctrl+P | Command palette |
| Ctrl+E | Open in external editor |
| 1 / 2 / 3 / 4 | Switch detail tab (body / headers / plugins / output) |
| Escape | Cancel running script |
| Ctrl+C | Quit |
Script & Test Runner
The TUI can run scripts and tests directly. Supported runners:
Scripts: bun, node, npx tsx, npx ts-node, python
Test frameworks: bun test, vitest, jest, pytest
Runners are auto-detected from your project's lockfiles, config files, and package.json devDependencies.
Observer Mode
Observer mode lets your scripts report HTTP requests back to the TUI and web dashboard with zero code changes.
When you run a script from the TUI (or web dashboard), t-req injects these environment variables into the child process:
| Variable | Purpose |
|----------|---------|
| TREQ_SERVER | Server URL (e.g. http://localhost:4097) |
| TREQ_FLOW_ID | Flow ID grouping related requests |
| TREQ_SESSION_ID | Pre-created session ID |
| TREQ_TOKEN | Scoped, short-lived auth token |
@t-req/core's createClient() auto-detects TREQ_SERVER and routes requests through the server instead of executing them locally. Every request appears in the TUI/dashboard in real time via SSE.
The injected token is scoped to the specific flow and session, and is revoked when the script exits.
No code changes needed -- if your script already uses createClient(), observer mode works automatically.
Protocol Version
The server uses protocol version 1.1.
Migration note: 1.0 -> 1.1
1.1 is additive:
- Existing
/execute,/execute/sse, and/eventworkflows are unchanged. - New WebSocket capabilities are available via:
POST /execute/wsGET /ws/session/{wsSessionId}GET /event/ws
WebSocket scope in 1.1
.httpWebSocket blocks are connection definitions (messages are runtime-driven).- Binary WebSocket payloads are not supported in
1.1(binaryPayloads: false). - Replay is bounded in-memory only (no durable event history).
- Client-specific UI workflows are intentionally out of scope at the protocol layer.
/health is intentionally lean and only returns a basic status and server version:
{
"healthy": true,
"version": "0.1.0"
}Security
- Localhost by default: Server binds to
127.0.0.1unless--hostis specified - Token authentication: Use
--tokenflag for bearer auth (required for remote access) - Path scoping: All file paths are relative to workspace root; absolute paths and
..traversal are rejected - CORS disabled by default: Use
--corsto enable specific origins
