[FEATURE]: Native StatusLine Hook for Plugins (Context-Free Display) #6083

Open
opened 2026-02-16 18:00:16 -05:00 by yindo · 0 comments
Owner

Originally created by @keybrdist on GitHub (Jan 15, 2026).

Originally assigned to: @thdxr on GitHub.

Feature Request: Native StatusLine Hook for Plugins

Problem

Plugins that want to display persistent contextual information (timestamps, git status, session metrics) must inject text into message parts. This causes all injected content to become part of the conversation context sent to the LLM.

For a statusline that displays on every message:

  • ~30 tokens consumed per message
  • 100-message session = ~3,000 tokens wasted on display-only content
  • Reduces effective context window

Attempted Workarounds

We tried using the ignored: true flag on text parts:

Approach Result
ignored: true without IDs Validation error (missing id, sessionID, messageID)
ignored: true with proper IDs Part displays, but user's message text disappears

The ignored flag hides content from both UI and context. There's no "display-only" option.

Proposed Solution

Add a statusLine hook for plugins, similar to Claude Code's implementation:

// Plugin hook
"tui.statusLine"?: (input: StatusLineInput) => Promise<{ text: string }>;

Or a config-based approach:

{
  "statusLine": {
    "type": "command",
    "command": "~/.config/opencode/statusline.sh"
  }
}

Input Data

Provide rich session context:

{
  "session_id": "abc123",
  "model": { "id": "claude-sonnet-4-20250514", "display_name": "Sonnet" },
  "workspace": { "current_dir": "/path/to/project" },
  "cost": { "total_cost_usd": 0.0234 },
  "context_window": {
    "context_window_size": 200000,
    "current_usage": { "input_tokens": 8500, "output_tokens": 1200 }
  }
}

UI Placement

Persistent bar in the TUI (not part of conversation):

┌─────────────────────────────────────────────────┐
│  [conversation content]                         │
│  > prompt input                                 │
├─────────────────────────────────────────────────┤
│  🕐 23:28 │ ⎇ main │ Sonnet │ 45% │ $0.02      │
└─────────────────────────────────────────────────┘

Benefits

  1. Zero context cost - Display-only content doesn't consume tokens
  2. Rich session data - Plugins can show cost, context %, model info
  3. Parity with Claude Code - statusLine docs

Related Issues

  • #7927 - Display Project Name and Git Status in TUI (similar UI, but built-in not plugin-driven)
  • #5971 - Plugin API for custom sidebar panels (related plugin API)

Reference

Originally created by @keybrdist on GitHub (Jan 15, 2026). Originally assigned to: @thdxr on GitHub. ## Feature Request: Native StatusLine Hook for Plugins ### Problem Plugins that want to display persistent contextual information (timestamps, git status, session metrics) must inject text into message parts. This causes **all injected content to become part of the conversation context sent to the LLM**. For a statusline that displays on every message: - ~30 tokens consumed per message - 100-message session = ~3,000 tokens wasted on display-only content - Reduces effective context window ### Attempted Workarounds We tried using the `ignored: true` flag on text parts: | Approach | Result | |----------|--------| | `ignored: true` without IDs | Validation error (missing id, sessionID, messageID) | | `ignored: true` with proper IDs | Part displays, but user's message text disappears | The `ignored` flag hides content from both UI and context. There's no "display-only" option. ### Proposed Solution Add a `statusLine` hook for plugins, similar to Claude Code's implementation: ```typescript // Plugin hook "tui.statusLine"?: (input: StatusLineInput) => Promise<{ text: string }>; ``` Or a config-based approach: ```json { "statusLine": { "type": "command", "command": "~/.config/opencode/statusline.sh" } } ``` ### Input Data Provide rich session context: ```json { "session_id": "abc123", "model": { "id": "claude-sonnet-4-20250514", "display_name": "Sonnet" }, "workspace": { "current_dir": "/path/to/project" }, "cost": { "total_cost_usd": 0.0234 }, "context_window": { "context_window_size": 200000, "current_usage": { "input_tokens": 8500, "output_tokens": 1200 } } } ``` ### UI Placement Persistent bar in the TUI (not part of conversation): ``` ┌─────────────────────────────────────────────────┐ │ [conversation content] │ │ > prompt input │ ├─────────────────────────────────────────────────┤ │ 🕐 23:28 │ ⎇ main │ Sonnet │ 45% │ $0.02 │ └─────────────────────────────────────────────────┘ ``` ### Benefits 1. **Zero context cost** - Display-only content doesn't consume tokens 2. **Rich session data** - Plugins can show cost, context %, model info 3. **Parity with Claude Code** - [statusLine docs](https://docs.anthropic.com/en/docs/claude-code/statusline) ### Related Issues - #7927 - Display Project Name and Git Status in TUI (similar UI, but built-in not plugin-driven) - #5971 - Plugin API for custom sidebar panels (related plugin API) ### Reference - Plugin demonstrating the limitation: [opencode-breadcrumb](https://github.com/keybrdist/opencode-breadcrumb) - Claude Code statusLine: https://docs.anthropic.com/en/docs/claude-code/statusline
yindo added the opentui label 2026-02-16 18:00:16 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#6083