v0.6.3

anomalyco/opentuiv0.6.3Oct 13, 2026by github-actions[bot]

Upgrading?

AI Summary

This release introduces the Program Status Protocol (OSC 7501) to allow coding agents like opencode to report their state (e.g., blocked, working, done) to the terminal in real-time. It adds new APIs for status reporting, native support for the protocol, and capability detection to ensure compatibility with terminals that support the feature.

Key Highlights

  • New `renderer.setProgramStatus()` API for sending program state updates via OSC 7501.
  • Native support for program status reporting via `ot_session_control()` and `OT_CONTROL_PROGRAM_STATUS`.
  • Capability detection with `TerminalCapabilities.program_status` to verify terminal support.
  • Improved handling of agent states in background tabs to prevent silent waiting.

Breaking Changes

  • Native error codes changed: `ot_session_control()` now returns `OT_INVALID_ARGUMENT` for invalid payloads instead of `OT_INVALID_PHASE`.
  • Record management behavior: Reports now replace records, and omitted fields are removed from the record.

New Features

  • Program status reporting via OSC 7501 protocol.
  • New `renderer.setProgramStatus()` and `NativeSession.setProgramStatus()` APIs.
  • Native `ot_session_control()` support for `OT_CONTROL_PROGRAM_STATUS`.
  • Capability query for `TerminalCapabilities.program_status`.
  • Native constant `OT_CAP_PROGRAM_STATUS`.

Full Release Notes

A coding agent such as opencode can wait for minutes at a permission prompt in a
background tab. Before this release, the terminal could not tell the user about it.
In 0.6.3, the agent can report its state to the terminal:

```typescript
renderer.setProgramStatus({ state: "blocked", kind: "permission", app: "opencode", message: "Allow bash?" })
```

This call writes one report in the
[Program Status Protocol](https://www.superlogical.com/rex/docs/build/program-status),
OSC 7501. The terminal decides how to show the report. It can use a tab
indicator, an inbox entry, or a desktop notification. A terminal that does not
implement the protocol ignores the sequence, so `setProgramStatus()` does not
wait for capability detection. `capabilities.program_status` only tells you that
a reply arrived. A `false` value can also mean that the reply has not arrived
yet.

Each report replaces one record, and a field that a report omits is gone from
the record. Send `app` and `title` with every report that needs them. A program
that runs several tasks can give each task its own record with an `id`. It can
then remove that record with `clear`:

```typescript
renderer.setProgramStatus({ state: "working", id: "subagent-1", title: "Explore", progress: 40 })
renderer.setProgramStatus({ state: "clear", id: "subagent-1" })
```

Records belong to the terminal, not to the renderer. OpenTUI does not clear them
when the renderer is destroyed or suspended. When the process exits, the
terminal drops `working` and `blocked` records. It keeps `done` and `error`
records for the user to find. If the user should see the result, report `done` or
`error` before the program exits. OpenTUI also does not wrap reports in tmux or
GNU Screen passthrough. The outer terminal cannot tell panes apart or see the
program exit, so a `working` record from a pane would never clear.

C hosts send the same report with `ot_session_control()` and
`OT_CONTROL_PROGRAM_STATUS`. The payload is an `ot_session_program_status` struct,
followed by the id, app, title, and message bytes. Native code checks every
report on both paths before it writes anything. A report that a terminal would
discard or only partly read fails at the call.

## Added

- **core:** `renderer.setProgramStatus(status)` and
  `NativeSession.setProgramStatus(status)` send one OSC 7501 program status
  report. They return `false` when OpenTUI does not queue the report, and they
  throw for an invalid report. See
  [Program status](https://opentui.com/docs/application-apis/program-status).
  ([#1657](https://github.com/anomalyco/opentui/pull/1657))
- **core:** `TerminalCapabilities.program_status` is `true` when the terminal
  replies to the `OSC 7501 ; ?` query. The renderer sends this query at startup
  with the other capability queries, but not to foot. See
  [Terminal capabilities](https://opentui.com/docs/reference/terminal-capabilities).
  ([#1657](https://github.com/anomalyco/opentui/pull/1657))
- **native:** `ot_session_control()` with `OT_CONTROL_PROGRAM_STATUS` and an
  `ot_session_program_status` payload sends a program status report.
  `OT_CAP_PROGRAM_STATUS` is set when the terminal replies to the query. See
  [Program status](https://opentui.com/docs/application-apis/program-status).
  ([#1657](https://github.com/anomalyco/opentui/pull/1657))

## Changed

- **native:** `ot_session_control()` now checks the payload before the terminal
  phase. While the terminal is not active, an invalid payload returns
  `OT_INVALID_ARGUMENT` instead of `OT_INVALID_PHASE`. A title with control
  characters is one example. See [Frames and output](https://opentui.com/docs/native/frames).
  ([#1657](https://github.com/anomalyco/opentui/pull/1657))

API changes and documentation: https://opentui.com/docs/releases/0.6.3


## What's Changed
* core: report program status with OSC 7501 by @simonklee in https://github.com/anomalyco/opentui/pull/1657


**Full Changelog**: https://github.com/anomalyco/opentui/compare/v0.6.2...v0.6.3

Related Repositories