Receiving events
Everything the CLI says arrives as an AbstractEvent subclass.
import { AssistantEvent, ResultEvent, SystemEvent } from 'activecli';
command.subscribe((event) => { if (event instanceof AssistantEvent && event.hasText()) { process.stdout.write(event.text); }
if (event instanceof ResultEvent) { console.log('turn finished:', event.raw['subtype']); }});AssistantEvent.text
Section titled “AssistantEvent.text”AssistantEvent.text is the walk into message.content that every caller was otherwise writing by hand — the CLI nests its text there as an array of blocks, only some of which are text. It is empty when the assistant only called a tool, which is normal and not the same as the assistant having said nothing.
Two behaviours worth knowing up front
Section titled “Two behaviours worth knowing up front”- Unmodelled entries still arrive. An entry type the library has no class for becomes a
GenericEventrather than being dropped, so a CLI that gets ahead of this library does not silently lose events. - Non-protocol output is skipped, not treated as failure. CLIs write warnings to the same stream as their protocol. A line that is not JSON is passed over.
raw keeps the original entry
Section titled “raw keeps the original entry”Every event keeps the CLI’s original entry intact under raw, with no field removed or renamed:
command.subscribe((event) => { const unknown = event.raw['unknown_future_field']; // still there});That is what makes a GenericEvent useful rather than merely non-fatal: the entry the library did not model is still fully readable by a caller that does understand it.
Where to go next
Section titled “Where to go next”- Answering permission requests —
PermissionRequestEventhas its own channel. - Reference: events — every subclass and what it carries.
- Session lifecycle — what a
ResultEventof subtypeerror_during_executionactually means after an interrupt.