chore(computer-use-mcp): added architecture docs outlining airi cli chafa (#1735)

This commit is contained in:
刘梓恒
2026-05-13 11:55:33 +08:00
committed by GitHub
parent 3b3c5f6aaf
commit cad10ca090
@@ -0,0 +1,293 @@
# AIRI Coding CLI + Chafa Architecture
## Purpose
Define a narrow architecture for a terminal-facing AIRI coding CLI that can
optionally render an animated avatar through `chafa`, without coupling terminal
presentation to the `computer-use-mcp` runtime.
This document is a boundary and contract proposal. It is not an implementation
plan for a full CLI in this PR.
## Current Status
As of 2026-04-26, the main branch does not expose a stable coding runner event
stream. A CLI that renders real progress needs a runner contract first. Starting
with terminal animation before that contract exists would produce presentation
without reliable runtime state.
The correct dependency order is:
1. Define a coding runner event contract.
2. Emit deterministic runner events from the coding runner.
3. Build a text-first CLI that consumes those events.
4. Add optional `chafa` avatar rendering as a display adapter.
## Confirmed Decisions
1. Future CLI package location: `packages/airi-cli`.
2. First integration channel: in-process runner callback.
3. JSONL over stdin/file remains a follow-up adapter for replay, fixtures, and
tooling interoperability.
4. `chafa` is optional presentation only.
## Hard Boundaries
1. No `chafa` dependency belongs in `services/computer-use-mcp` core runtime.
2. `computer-use-mcp` must remain headless-safe and CI-safe.
3. The CLI consumes runner events; it must not own planning, tool execution, or
runtime policy.
4. Missing `chafa` must degrade to plain text rendering.
5. Non-TTY output must support plain text or JSONL output.
6. CLI rendering changes must not be mixed with coding memory or runner runtime
refactors.
## Proposed Location Split
- Core runtime: `services/computer-use-mcp`.
- CLI package: `packages/airi-cli`.
- Event contract: initially colocated with the runner that emits it, then
exported for CLI consumption.
- Text renderer: `packages/airi-cli/src/renderers/text.ts`.
- Chafa adapter: `packages/airi-cli/src/renderers/chafa-avatar.ts`.
- JSONL adapter: `packages/airi-cli/src/adapters/jsonl.ts`.
## Runner Event Contract Draft
Use an append-only event envelope. The first transport should be an in-process
callback. JSONL is an adapter over the same envelope.
```ts
interface RunnerEventEnvelope<TKind extends string = string, TPayload = unknown> {
runId: string
seq: number
at: string
kind: TKind
payload: TPayload
}
```
Contract rules:
- `seq` is strictly increasing per `runId`.
- `at` is an ISO timestamp.
- events are append-only; later events must not rewrite earlier events.
- crash and timeout paths must emit deterministic terminal events.
## Minimum Event Kinds
- `run_started`
- `preflight_started`
- `preflight_completed`
- `step_started`
- `tool_call_started`
- `tool_call_completed`
- `assistant_message`
- `step_timeout`
- `report_status`
- `run_finished`
- `run_crashed`
## Minimum Payloads
`run_started`:
```ts
interface RunStartedPayload {
workspacePath: string
taskGoal: string
maxSteps: number
stepTimeoutMs: number
}
```
`step_started`:
```ts
interface StepStartedPayload {
stepIndex: number
maxSteps: number
}
```
`tool_call_started`:
```ts
interface ToolCallStartedPayload {
toolName: string
argsSummary: string
}
```
`tool_call_completed`:
```ts
interface ToolCallCompletedPayload {
toolName: string
ok: boolean
status?: string
summary: string
error?: string
}
```
`assistant_message`:
```ts
interface AssistantMessagePayload {
text: string
}
```
`report_status`:
```ts
interface ReportStatusPayload {
status: 'completed' | 'failed' | 'blocked'
summary?: string
}
```
`run_finished`:
```ts
interface RunFinishedPayload {
finalStatus: 'completed' | 'failed' | 'blocked' | 'timeout'
totalSteps: number
error?: string
}
```
## CLI Architecture
The CLI should have three separable layers.
### 1. Input Adapter
Input adapters convert transport-specific input into `RunnerEventEnvelope`
events.
Initial adapters:
- in-process runner callback
- stdin JSONL
- JSONL file replay
### 2. State Reducer
The reducer builds deterministic `CliViewState` from events.
Rules:
- no terminal I/O in the reducer
- no process spawning in the reducer
- no animation timing in the reducer
- reducer tests should use fixture event streams
### 3. Renderer Adapter
Renderer adapters consume `CliViewState`.
Initial renderers:
- text renderer, always available
- JSONL passthrough renderer for tooling
- optional `chafa` avatar renderer
## Chafa Adapter
The `chafa` adapter should:
- probe `chafa` binary availability at startup
- disable itself when stdout is not a TTY
- convert sprite or frame assets to ANSI frames
- pace animation independently from runner event rate
- fall back to text-only rendering on failure
Initial CLI flags:
- `--avatar=chafa|none`
- `--no-avatar`
- `--events=runner|stdin|jsonl-file`
- `--output=pretty|jsonl`
## Testing Strategy
1. Contract tests for event schema and monotonic `seq`.
2. Reducer tests from fixture JSONL streams.
3. Text renderer snapshot tests.
4. Chafa adapter tests with mocked binary probing and mocked child process
execution.
5. CI defaults to text mode and does not require `chafa`.
## Delivery Stages
### Stage 1: Contract
- define the runner event envelope
- add success, failure, and timeout fixture streams
- do not render terminal UI yet
### Stage 2: Text CLI
- scaffold `packages/airi-cli`
- consume runner events
- render run, step, tool, error, and final report state in plain text
### Stage 2.5: JSONL Adapter
- support stdin JSONL replay
- support JSONL file replay
- use fixtures for offline demos and tests
### Stage 3: Chafa Renderer
- add optional `chafa` renderer
- keep plain text as the default fallback
- keep CI and headless runs independent from `chafa`
## Acceptance Criteria
1. No `chafa` dependency is added under `services/computer-use-mcp`.
2. CLI works when `chafa` is not installed.
3. CI does not require `chafa`.
4. The reducer is testable from mocked event streams.
5. Terminal output degrades to plain text.
6. Runner behavior is not changed for animation-first UX.
## Review Checklist
Layering:
- no renderer code in `computer-use-mcp` runtime
- no `chafa` dependency in runtime packages
- CLI code stays under `packages/airi-cli`
Runtime:
- runner remains headless-safe
- runner emits events without depending on terminal state
- failures and timeouts produce deterministic events
Fallback:
- missing `chafa` does not fail CLI execution
- non-TTY mode uses text or JSONL output
Scope:
- do not mix CLI rendering with coding memory changes
- do not mix CLI rendering with desktop/browser runtime changes
## Out of Scope
- long-term memory promotion and governance
- desktop/browser runtime refactors
- terminal animation before a runner event contract exists
- changing coding runner completion semantics for display purposes
## Suggested Follow-up PRs
- `feat(cli): define coding runner event contract`
- `feat(cli): scaffold airi coding cli text renderer`
- `feat(cli): add optional terminal AIRI avatar renderer with chafa`