The Interactive Console¶
Running assync with no arguments, in an interactive terminal, opens a
full-screen console for operating missions: a compact status header, the
roles for the current mission, activity, findings, and pending human
decisions — without leaving the terminal or repeatedly re-running assync
status.
This is purely a different way to look at the same runtime the CLI
commands already operate on (.assync-runtime/, via
Runtime Storage) — approving a decision in the
console calls the exact same resolve_decision() service function as
assync decision approve, with the same authorization and audit-logging
behavior. There is no separate state to drift out of sync.
It never appears where you don't want it¶
The console only launches when both stdin and stdout are a real, interactive terminal. Any of the following stay exactly as before — plain text, no animation, no full-screen takeover:
assync status --json # a real TTY, but an explicit subcommand
assync status | jq # piped — not a TTY
assync --no-tui # explicit opt-out
ASSYNC_NO_SPLASH=1 assync # still launches, skips the animation
Every existing subcommand (init, status, validate, mission,
decision, run, …) is completely unaffected — only the bare assync
invocation's behavior changed. To force the console from a script or a
TTY-uncertain context, use assync tui explicitly; it exits with an
error rather than hanging if the terminal isn't interactive.
Startup¶
In an interactive terminal, assync shows a short (~3 second) startup
screen — the Assync wordmark and two "sync bars" — before handing off to
the console proper. Press any key to skip it immediately. It never
reappears once the console is running; the large wordmark and the brand
line ("Now the ass knows what the head is thinking.") live only here —
the running console uses a one-line compact header instead, to leave the
screen for mission content.
Disable it permanently:
Or for a single run:
Reduced motion (shows the completed state immediately, no animated fill):
Layout¶
● ASSYNC v0.1.0 │ my-project │ 1 role │ 05:11
AGENTS ✓ Security Engineer 00:00
! DECISION One or more blocking findings remain open — accept, ...
[Y] Approve [N] Reject [E] Explain [D] Details
MISSION Improve the installation experience
STATUS WAITING_FOR_AUTHORIZATION · 1/1 roles complete · risk=low
OUTPUT 1 findings (1 blocking) · 1 decision(s) pending
✓ Security Engineer
0 active │ 1 findings │ 1 decision(s) │ Needs approval
❯ Type a command or /help…
The header abbreviates itself to fit the terminal width, dropping the least-essential pieces first, and the whole layout stays usable at 80×24. On very small terminals, the header may show only the version, role count, and elapsed time.
The agent bar, honestly¶
This runtime executes mission roles sequentially, one at a time —
see orchestrator/service.py::start_mission. The agent bar reflects
that truthfully: at most one role is ever shown as "running" at once,
never several in parallel. Each role shows:
| Symbol | Meaning |
|---|---|
○ |
pending — not started yet |
● |
running — the current mission is ACTIVE and this is the next unstarted role in execution order |
✓ |
done — has a completed AgentRun |
× |
failed |
Keyboard shortcuts vs. the command input¶
The command input holds focus by default, for typing. Textual's Input
widget unconditionally consumes plain character keys for text entry —
there's no way for a single-key shortcut like 1 or y to coexist with
an always-focused text box and still let you type a mission title
containing a digit. So:
- Press escape to move focus to the main view — single-key shortcuts
(
1-6,y/n/e/d,?) are active there. - Press enter or / to jump back to the command input.
| Key (main view has focus) | Action |
|---|---|
1–6 |
Switch view: Mission / Activity / Agents / Findings / Security / Decisions |
? |
Help |
y / n |
Approve / reject the top pending decision |
e / d |
Explain / see full details of the top pending decision |
ctrl+r |
Refresh now (the console also polls the runtime every 2 seconds) |
Slash commands¶
Typed into the command input, from anywhere:
/help /status /agents /findings /security /decisions
/approve <decision_id> /reject <decision_id>
/mission list
/mission show <mission_id>
/mission new --project-id X --title T --objective O [--required-role R]...
/mission start <mission_id> --run-config <path>
/clear /quit
/pause, /resume, and /stop are recognized but explicitly reported
as not supported — there's no in-flight execution to pause or resume
in a synchronous, sequential orchestrator; claiming otherwise would be a
lie the interface tells you. /mission start genuinely runs the real
orchestrator (on a background thread, so the console stays responsive)
and the activity view fills in with real audit-log events as each role
actually completes.
Plain text without a leading / is not sent to an AI agent — this
MVP has no natural-language-to-mission backend. It's accepted as a
shorthand for approve/reject/explain/details when a decision is
pending; otherwise the console tells you so and points at /mission new
or the assync mission CLI.
Accessibility and terminal compatibility¶
NO_COLOR=1renders the whole console monochrome (handled by Textual itself).- State is never conveyed by color alone — every status has its own
symbol (
✓/×/●/○/!) and label text. TERM=dumb(or any non-interactive stdin/stdout) never attempts to launch the console at all — a dumb terminal can't do the cursor positioning or alternate-screen buffer a full-screen app needs, regardless of color settings.ASSYNC_ASCII=1forces ASCII-safe separators/glyphs (-,*,>,v,x) instead of Unicode box-drawing and block characters, for terminals/fonts that render Unicode inconsistently.
Known limitations¶
- Execution is sequential and synchronous — no live concurrent multi-agent progress, because the orchestrator doesn't have that concurrency to report.
- No natural-language mission dispatch — no LLM/agent backend is wired into this MVP for free-text requests.
- CPU/RAM in the status bar describe the
assyncprocess itself (via the standard library, not a new dependency) — not overall system load.