Skip to content

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.

assync

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:

assync config set ui.splash false

Or for a single run:

ASSYNC_NO_SPLASH=1 assync
# or
assync --no-splash

Reduced motion (shows the completed state immediately, no animated fill):

ASSYNC_REDUCED_MOTION=1 assync
# or persistently:
assync config set ui.reduced_motion true

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
16 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=1 renders 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=1 forces 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 assync process itself (via the standard library, not a new dependency) — not overall system load.