<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="rss.xsl"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Sendra Blog</title>
        <link>https://sendra.oyibe.dev/blog/</link>
        <description>Sendra Blog</description>
        <lastBuildDate>Tue, 15 Sep 2026 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Sendra 0.1.0: the first tagged release]]></title>
            <link>https://sendra.oyibe.dev/blog/sendra-0-1-0/</link>
            <guid>https://sendra.oyibe.dev/blog/sendra-0-1-0/</guid>
            <pubDate>Tue, 15 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Sendra 0.1.0 is the first tagged release: prebuilt binaries, checksums, and install options via shell, npm, Homebrew, and Cargo, plus what's in the box.]]></description>
            <content:encoded><![CDATA[
<p>Sendra 0.1.0 is out — the first tagged release, and the first time you can
install it instead of building it from source.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_HxVq" id="what-010-means-here">What "0.1.0" means here<a href="https://sendra.oyibe.dev/blog/sendra-0-1-0/#what-010-means-here" class="hash-link" aria-label="Direct link to What &quot;0.1.0&quot; means here" title="Direct link to What &quot;0.1.0&quot; means here" translate="no">​</a></h2>
<p>Nothing in this release is new relative to what's been in the repo — it's
the same request/collection model, CLI, and TUI <a class="" href="https://sendra.oyibe.dev/blog/introducing-sendra/">introduced</a>
and <a class="" href="https://sendra.oyibe.dev/blog/one-binary-two-interfaces/">described in depth</a> in the last two
posts. What changes is that it's now built, checksummed, and published
under a version number, with prebuilt binaries and package-manager entries
instead of a <code>git clone</code> + <code>cargo build</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_HxVq" id="whats-in-the-box">What's in the box<a href="https://sendra.oyibe.dev/blog/sendra-0-1-0/#whats-in-the-box" class="hash-link" aria-label="Direct link to What's in the box" title="Direct link to What's in the box" translate="no">​</a></h2>
<ul>
<li class=""><strong>Requests and collections as plain YAML</strong> — method, URL, headers, and a
body as <code>body</code>, <code>json</code>, <code>body_file</code>, <code>form</code>, or <code>multipart</code>, with
<code>auth: bearer</code>/<code>basic</code>/<code>api_key</code>.</li>
<li class=""><strong><code>sendra run</code></strong> and <strong><code>sendra test</code></strong> — send a request or collection from
the shell, or run it against <code>assertions:</code> and fail the build on a miss.
<code>test</code> supports <code>--junit</code> for CI report output.</li>
<li class=""><strong>Assertions</strong> on status, headers, and body, including JSON-path checks
and an operator sub-language (<code>greater_than</code>, <code>matches</code>, <code>not:</code>, and
more).</li>
<li class=""><strong>Capture and chaining</strong> — pull a value out of one response (JSON path,
header, or status code) and substitute it into a later request in the
same run.</li>
<li class=""><strong>Environments and variables</strong> — <code>.sendra/environments/*.yaml</code> resolved
via <code>--env</code>, with <code>{{variable}}</code> and <code>${OS_VAR}</code> substitution.</li>
<li class=""><strong>Config, layered</strong> — <code>.sendra/config.yaml</code> for default headers, timeout,
redirects, TLS, proxy, and cookie-jar settings, resolved project-over-global,
overridable per-invocation with flags like <code>-H</code>, <code>--var</code>, <code>--insecure</code>,
<code>--proxy</code>.</li>
<li class=""><strong>Scripting</strong> — <code>pre_request</code>/<code>post_request</code> hooks in an embedded
scripting language (Rhai), with no external runtime to install.</li>
<li class=""><strong>OAuth</strong> — an <code>authorization_code</code> login flow for requests that need a
browser-based token first.</li>
<li class=""><strong><code>sendra import curl</code></strong>, <strong><code>sendra init</code></strong>, and <strong><code>sendra schema</code></strong> — convert
a curl command into a request file, scaffold a new <code>.sendra/</code> project, and
emit JSON Schemas for editor tooling.</li>
<li class=""><strong>The TUI</strong> (<code>sendra tui</code>, or a bare <code>sendra</code>) — the full-screen terminal
app covered in <a class="" href="https://sendra.oyibe.dev/blog/one-binary-two-interfaces/">the last post</a>, built on
the same core as the CLI.</li>
<li class=""><strong>One binary.</strong> <code>sendra-cli</code> and <code>sendra-tui</code> build into a single <code>sendra</code>
binary — installing it gets you both.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_HxVq" id="install-it">Install it<a href="https://sendra.oyibe.dev/blog/sendra-0-1-0/#install-it" class="hash-link" aria-label="Direct link to Install it" title="Direct link to Install it" translate="no">​</a></h2>
<p>Shell:</p>
<div class="language-sh codeBlockContainer_hA7d theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Vm_w"><pre tabindex="0" class="prism-code language-sh codeBlock_qD1D thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_Lj6x"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">curl</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">--proto</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'=https'</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">--tlsv1.2</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-LsSf</span><span class="token plain"> https://github.com/sendra-lab/Sendra/releases/latest/download/sendra-cli-installer.sh </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sh</span><br></div></code></pre></div></div>
<p>PowerShell:</p>
<div class="language-powershell codeBlockContainer_hA7d theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Vm_w"><pre tabindex="0" class="prism-code language-powershell codeBlock_qD1D thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_Lj6x"><div class="token-line" style="color:#393A34"><span class="token plain">powershell -ExecutionPolicy Bypass -c "irm https://github.com/sendra-lab/Sendra/releases/latest/download/sendra-cli-installer.ps1 | iex"</span><br></div></code></pre></div></div>
<p>npm:</p>
<div class="language-sh codeBlockContainer_hA7d theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Vm_w"><pre tabindex="0" class="prism-code language-sh codeBlock_qD1D thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_Lj6x"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">npm</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> @sendra-lab/sendra</span><br></div></code></pre></div></div>
<p>pnpm:</p>
<div class="language-sh codeBlockContainer_hA7d theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Vm_w"><pre tabindex="0" class="prism-code language-sh codeBlock_qD1D thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_Lj6x"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">pnpm</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">add</span><span class="token plain"> @sendra-lab/sendra</span><br></div></code></pre></div></div>
<p>Bun:</p>
<div class="language-sh codeBlockContainer_hA7d theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Vm_w"><pre tabindex="0" class="prism-code language-sh codeBlock_qD1D thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_Lj6x"><div class="token-line" style="color:#393A34"><span class="token plain">bun </span><span class="token function" style="color:#d73a49">add</span><span class="token plain"> @sendra-lab/sendra</span><br></div></code></pre></div></div>
<p>Homebrew:</p>
<div class="language-sh codeBlockContainer_hA7d theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Vm_w"><pre tabindex="0" class="prism-code language-sh codeBlock_qD1D thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_Lj6x"><div class="token-line" style="color:#393A34"><span class="token plain">brew </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> sendra-lab/tap/sendra-cli</span><br></div></code></pre></div></div>
<p>Cargo:</p>
<div class="language-sh codeBlockContainer_hA7d theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Vm_w"><pre tabindex="0" class="prism-code language-sh codeBlock_qD1D thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_Lj6x"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">cargo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> sendra-cli</span><br></div></code></pre></div></div>
<p>Or download a prebuilt binary directly from the
<a href="https://github.com/sendra-lab/Sendra/releases/tag/v0.1.0" target="_blank" rel="noopener noreferrer" class="">v0.1.0 release page</a>,
which also has checksums for every artifact.</p>
<p>Once it's on your <code>PATH</code>:</p>
<div class="language-sh codeBlockContainer_hA7d theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Vm_w"><pre tabindex="0" class="prism-code language-sh codeBlock_qD1D thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_Lj6x"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">cat</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> get-request.yaml </span><span class="token operator" style="color:#393A34">&lt;&lt;</span><span class="token string" style="color:#e3116c">'EOF'</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">method: GET</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">url: https://httpbin.org/get</span><br></div><div class="token-line" style="color:#393A34"><span class="token string" style="color:#e3116c">EOF</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">sendra run get-request.yaml</span><br></div></code></pre></div></div>
<p>From there, <a class="" href="https://sendra.oyibe.dev/docs/intro/">the docs</a> cover the full request/collection
schema, every CLI flag, and the TUI's keybinding reference.</p>]]></content:encoded>
            <category>Changelog</category>
            <category>Announcement</category>
        </item>
        <item>
            <title><![CDATA[Introducing Sendra]]></title>
            <link>https://sendra.oyibe.dev/blog/introducing-sendra/</link>
            <guid>https://sendra.oyibe.dev/blog/introducing-sendra/</guid>
            <pubDate>Mon, 14 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Sendra is a terminal-native HTTP client where requests are YAML files in your repo. What ships today: run, test, and a full-screen TUI in a single binary.]]></description>
            <content:encoded><![CDATA[
<p>Sendra is a terminal-native HTTP client. Requests are plain YAML files that
live in your repo next to the code they exercise, and you send them from the
shell instead of a GUI.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_HxVq" id="why-sendra-exists">Why Sendra exists<a href="https://sendra.oyibe.dev/blog/introducing-sendra/#why-sendra-exists" class="hash-link" aria-label="Direct link to Why Sendra exists" title="Direct link to Why Sendra exists" translate="no">​</a></h2>
<p>Most HTTP client tools ask you to leave your editor and your repo behind: a
separate app, a proprietary export format, requests that live in someone's
cloud workspace instead of version control. Sendra starts from the opposite
assumption — a request is a file. It belongs in your repo, gets reviewed in a
pull request like any other change, and diffs over time the same way your
code does.</p>
<p>A request or collection file is checked against variables from an environment
file, so the same request can point at staging or production without
touching the file itself. It can also declare what the response <em>should</em>
look like — status, headers, body shape — which <code>sendra test</code> then passes or
fails your build on. No separate assertion library, no glue script: the
check lives in the same YAML as the request it's checking.</p>
<h2 class="anchor anchorTargetStickyNavbar_HxVq" id="whats-in-the-box-today">What's in the box today<a href="https://sendra.oyibe.dev/blog/introducing-sendra/#whats-in-the-box-today" class="hash-link" aria-label="Direct link to What's in the box today" title="Direct link to What's in the box today" translate="no">​</a></h2>
<p>Sendra ships as a single binary. There's no separate install step for a
scripting engine, a test runner, or a UI — building or installing <code>sendra</code>
gets you all of it:</p>
<ul>
<li class=""><strong><code>sendra run</code></strong> sends a request and prints the result.</li>
<li class=""><strong><code>sendra test</code></strong> runs one or a whole collection and fails your build on
unmet assertions.</li>
<li class=""><strong><code>sendra tui</code></strong> — or just <code>sendra</code> with nothing else on the command
line — opens a full-screen terminal UI for browsing and running requests
interactively, built directly on the same request model, YAML loading,
environment resolution, and HTTP execution the CLI commands use.</li>
</ul>
<p>The CLI side has been usable for a while: run and test requests, assert on
status/headers/body, capture a value out of one response and chain it into
the next request, layer config → environment → CLI overrides in a
predictable precedence order, and run <code>pre_request</code>/<code>post_request</code> scripts
in a sandbox with no filesystem or network access.</p>
<p>What's new is that the TUI has caught up past "browse and run" into a
genuinely complete editor. From inside the TUI you can now:</p>
<ul>
<li class=""><strong>Edit any part of a request in place</strong> — method, URL, headers, body,
auth, assertions, captures — with a form that refuses to save on an
invalid method or unparsable JSON body, and discards cleanly on <code>Esc</code>.</li>
<li class=""><strong>Work across multiple collections at once</strong>, each open in its own tab
with fully independent selection, run state, and edit session.</li>
<li class=""><strong>Log into OAuth <code>authorization_code</code> flows interactively</strong> — the TUI
opens your browser, runs a local callback listener, and caches the token
for the rest of the session, the same as <code>client_credentials</code>/<code>password</code>
tokens are.</li>
<li class=""><strong>Browse in-session run history</strong> per request, up to 20 runs deep, without
anything touching disk.</li>
</ul>
<p>None of this is a second product bolted onto the CLI. The TUI reuses
<code>sendra-core</code> directly — the same request model the CLI commands run on —
with one deliberate, documented gap: <code>pre_request</code>/<code>post_request</code> scripts
don't run from the TUI. Everything else behaves identically whether a
request is sent from a shell command or a keypress.</p>
<h2 class="anchor anchorTargetStickyNavbar_HxVq" id="try-it">Try it<a href="https://sendra.oyibe.dev/blog/introducing-sendra/#try-it" class="hash-link" aria-label="Direct link to Try it" title="Direct link to Try it" translate="no">​</a></h2>
<p>There's no packaged release yet, so building from source is the way in:</p>
<div class="language-sh codeBlockContainer_hA7d theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_Vm_w"><pre tabindex="0" class="prism-code language-sh codeBlock_qD1D thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_Lj6x"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">git</span><span class="token plain"> clone https://github.com/sendra-lab/Sendra.git</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin class-name">cd</span><span class="token plain"> Sendra</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">cargo</span><span class="token plain"> build </span><span class="token parameter variable" style="color:#36acaa">--workspace</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">--release</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">./target/release/sendra run examples/get-request.yaml</span><br></div></code></pre></div></div>
<p>From there, <a class="" href="https://sendra.oyibe.dev/docs/intro/">the docs</a> cover the full request/collection
schema, every CLI flag, the TUI's complete keybinding reference, and the
design rationale behind the harder calls — like why <code>sendra test</code> ignores an
unasserted status, or how the sandboxing guarantees around scripts work.</p>
<p>This is the first post on this blog, and we're planning to use it for
release-note-style updates too (tagged <a class="" href="https://sendra.oyibe.dev/blog/tags/changelog/"><code>changelog</code></a>)
rather than standing up a separate changelog page — see the tag description
for why.</p>]]></content:encoded>
            <category>Announcement</category>
            <category>Changelog</category>
        </item>
        <item>
            <title><![CDATA[One binary, two interfaces: how sendra run and sendra tui share a core]]></title>
            <link>https://sendra.oyibe.dev/blog/one-binary-two-interfaces/</link>
            <guid>https://sendra.oyibe.dev/blog/one-binary-two-interfaces/</guid>
            <pubDate>Sun, 13 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[sendra run and sendra tui are one binary on one request pipeline. Why the CLI and TUI share a core, and the one documented gap: scripts don't run in the TUI.]]></description>
            <content:encoded><![CDATA[
<p><code>sendra run</code> sends one request from your shell. <code>sendra tui</code> opens a
full-screen terminal app for browsing and running a whole collection. They
feel like different tools, but they're the same binary running the same
request pipeline — and that's a deliberate design choice worth explaining,
not an implementation accident.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_HxVq" id="why-one-binary-is-a-constraint-not-a-slogan">Why "one binary" is a constraint, not a slogan<a href="https://sendra.oyibe.dev/blog/one-binary-two-interfaces/#why-one-binary-is-a-constraint-not-a-slogan" class="hash-link" aria-label="Direct link to Why &quot;one binary&quot; is a constraint, not a slogan" title="Direct link to Why &quot;one binary&quot; is a constraint, not a slogan" translate="no">​</a></h2>
<p>It would have been easier, in some ways, to ship the TUI as a separate
crate with its own copy of request loading, environment resolution, and HTTP
execution. Instead, <code>sendra tui</code> reuses the same core the CLI commands run
on directly: the same request model, YAML loading, environment resolution,
capture logic, and HTTP execution that <code>run</code>/<code>test</code> use. There's no
translation layer between "what the CLI does" and "what the TUI does" —
there's one implementation, and two front ends that drive it.</p>
<p>That has a concrete payoff: a request behaves identically whether it's sent
with <code>sendra run request.yaml</code> or by pressing <code>Enter</code> on it in the TUI.
Environment substitution, config header merging, auth resolution, query and
body resolution, assertions, capture — all of it is the exact same code
path. If <code>sendra test</code> and the TUI ever disagreed about whether a request
passed its assertions, that would be a bug, not an edge case to document.</p>
<h2 class="anchor anchorTargetStickyNavbar_HxVq" id="the-one-honest-gap">The one honest gap<a href="https://sendra.oyibe.dev/blog/one-binary-two-interfaces/#the-one-honest-gap" class="hash-link" aria-label="Direct link to The one honest gap" title="Direct link to The one honest gap" translate="no">​</a></h2>
<p>There's exactly one place the two front ends diverge: <code>pre_request</code>/
<code>post_request</code> scripts don't run from the TUI. Everything else about a
request's send pipeline is shared, but scripts are the one part that isn't
— and it's called out as a deliberate, documented gap rather than something
that quietly doesn't work. If you're relying on a <code>pre_request</code> script to
set something up, <code>sendra run</code>/<code>sendra test</code> are still the way to send that
particular request.</p>
<p>The TUI's editing surface has a handful of gaps drawn the same way. Only
<code>json:</code> path assertions get a row editor — every other assertion kind
(<code>status</code>, <code>status_in</code>, <code>headers</code>, <code>body_contains</code>, <code>body_matches</code>,
<code>elapsed_ms_under</code>) is preserved exactly as loaded when you edit a request,
but has no in-app editor yet. A <code>body_file</code> body is shown read-only because
it names a file some other tool may have open; <code>form</code>/<code>multipart</code> bodies are
read-only because they're structured, list-of-parts bodies that would need
their own dedicated editor. In each case the choice is to be visibly
read-only rather than silently drop or mangle something the editor doesn't
fully understand.</p>
<h2 class="anchor anchorTargetStickyNavbar_HxVq" id="what-complete-ended-up-meaning-for-the-tui">What "complete" ended up meaning for the TUI<a href="https://sendra.oyibe.dev/blog/one-binary-two-interfaces/#what-complete-ended-up-meaning-for-the-tui" class="hash-link" aria-label="Direct link to What &quot;complete&quot; ended up meaning for the TUI" title="Direct link to What &quot;complete&quot; ended up meaning for the TUI" translate="no">​</a></h2>
<p>Early on, the TUI's job was narrower: load a collection, list its requests,
run whichever one you selected. Getting from there to something you could
actually work in all day meant three things landing together:</p>
<p><strong>In-place editing of a full request.</strong> <code>i</code> opens any selected request in an
edit form — method, URL, headers, body, auth, assertions, captures — that
mirrors the shape of the YAML itself. Auth editing is scoped deliberately:
the editor only edits an <code>auth</code> block that already exists on the request,
never introduces a new auth type where there was none. Saving is guarded —
an invalid method or a <code>json:</code> body that doesn't parse as JSON blocks the
save with the problem shown, rather than writing something broken back out.</p>
<p><strong>Multiple collections open at once.</strong> <code>o</code> opens another collection as a new
tab, and each tab is a fully independent session — its own selection, run
state, edit session, environment, and run history, none of it bleeding into
any other tab. This matters more than it sounds: without it, working across
a "staging" collection and a "webhooks" collection in the same sitting meant
either two terminal windows or closing one to open the other. Closing the
last remaining tab resets it to the welcome screen instead of leaving you
with zero tabs — there's always somewhere to land.</p>
<p><strong>Interactive OAuth for the one grant type that needs a browser.</strong>
<code>client_credentials</code> and <code>password</code> grants can fetch a token from fields
alone — client ID, secret, token URL, nothing else required. <code>authorization_code</code>
can't, because it needs a real human clicking "allow" in a real browser. For
that one case, <code>Ctrl+l</code> inside the auth editor opens your browser to the
configured authorization URL, runs a local callback listener bound to the
configured redirect URI, waits up to five minutes for the provider to
redirect back, and exchanges the resulting code for a token. That token is
cached in memory for the rest of the session, and every later run of a
request sharing that <code>oauth:</code> config reuses it automatically — including,
as a side effect, <code>client_credentials</code>/<code>password</code> tokens, which get the same
in-session caching even though they didn't need the browser step to get
there.</p>
<h2 class="anchor anchorTargetStickyNavbar_HxVq" id="the-bare-sendra-command">The bare <code>sendra</code> command<a href="https://sendra.oyibe.dev/blog/one-binary-two-interfaces/#the-bare-sendra-command" class="hash-link" aria-label="Direct link to the-bare-sendra-command" title="Direct link to the-bare-sendra-command" translate="no">​</a></h2>
<p>One small detail worth calling out: a bare <code>sendra</code>, with no subcommand at
all, launches the TUI with nothing preloaded — the same as <code>sendra tui</code>. This
was a deliberate choice, not a fallback for a missing argument. Typing just
<code>sendra</code> is meant to be a reasonable way to start, the same way you'd type
<code>git status</code> or <code>htop</code> without needing to remember a flag first. From there,
the welcome screen looks for <code>.yaml</code>/<code>.yml</code> files sitting directly in the
current directory and offers them as a picker, or gives you <code>o</code> to type a
path if nothing's nearby.</p>
<p>None of this — the shared core, the documented gaps, the bare-command
launch — reads as exciting on its own. Taken together, it's the difference
between a TUI that happens to exist next to the CLI, and one that's actually
the same tool wearing a different interface.</p>]]></content:encoded>
            <category>Deep dive</category>
        </item>
    </channel>
</rss>