Commit Graph
11 Commits
Author SHA1 Message Date
02a0aa6733 fix(cursor): surface agent errors with warning styling in web UI (#871)
* test: reproduce issue #864

Assert Cursor error paths emit agent error payloads and web UI renders
them as warning-styled events instead of neutral session messages.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(cursor): surface agent errors with warning styling in web UI (closes #864)

Route Cursor stderr, init, prompt, and legacy exit failures through
sendAgentMessage({ type: 'error' }) and teach the web chat layer to
render error events with a warning icon instead of neutral info text.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-18 10:17:57 +08:00
andGitHub 9e35067aa9 feat(web): show timestamps on chat messages (#664) 2026-05-22 13:14:26 +08:00
weishu 089ddad476 feat: support Codex goal slash command 2026-05-15 22:15:17 +08:00
CoColateandGitHub e76738aa5a fix(codex): improve web rendering for Codex events (#544)
* test(codex): add web event rendering harness

* fix(codex): surface plan updates in web

* fix(codex): render MCP tool calls in web

* fix(codex): improve terminal and context display

* fix(codex): format token usage events

* fix(codex): show status context in web

* fix(codex): preserve tool result errors
2026-04-29 17:22:45 +08:00
Junmo KimandGitHub 00ba610ab0 feat: display rate limit warnings instead of raw JSON (#388)
* refactor(web): extract normalizeTimestamp helper in presentation

Extract the shared seconds-vs-milliseconds normalization logic into
a private `normalizeTimestamp()` helper. No behavior change —
`formatUnixTimestamp()` produces identical output.

* refactor(web): return AgentEvent from parseClaudeUsageLimit

Change return type from `number | null` to `AgentEvent | null` so
the caller doesn't need to construct the event object. No behavior
change — the same `limit-reached` event is produced.

* feat(cli): convert rate_limit_event to standardized text format

Parse undocumented Claude `rate_limit_event` JSON in the CLI adapter
layer (AcpMessageHandler) before it reaches the web.

Converted text format (pipe-delimited):
  - "Claude AI usage limit warning|{ts}|{pct}|{rateLimitType}"
  - "Claude AI usage limit reached|{ts}|{rateLimitType}"

Status handling:
  - `allowed_warning` → warning text with utilization and limit type
  - `rejected` → reached text with limit type
  - `allowed` → silently suppressed (noise)
  - unknown statuses → passed through as-is (forward-compatible)

* feat(web): display rate limit warnings with limit type

Parse standardized pipe-delimited text from the CLI adapter into
`limit-warning` and `limit-reached` events, displaying the rate
limit type (5-hour, 7-day) when available.

- `limit-warning`: "⚠️ Usage limit 90% (5-hour) · resets 2:00 PM"
- `limit-reached`: " Usage limit reached (5-hour) until 4/2/2026"
- Backward compatible: `limit-reached` without limitType still works

The `reached` regex uses `(?:\|([^|]*))?$` to optionally match the
limitType field, maintaining compatibility with the existing format.

* refactor(cli): move rate limit parsing out of flushText

Remove rate limit detection from flushText() back to plain buffer
flush. The next commit will re-add parsing at the chunk level
(handleUpdate) where it can intercept before buffer merging.

Includes failing tests that demonstrate the mixed-chunk bug:
when a rate_limit_event chunk arrives in the same turn as normal
text, the JSON leaks into the merged buffer.

* fix(cli): intercept rate_limit_event at chunk level, not flush

Move rate limit detection from flushText() to the agentMessageChunk
handler so it fires before the chunk enters the shared text buffer.

Previously, a rate_limit_event chunk arriving in the same turn as
normal text would merge into bufferedText and leak as raw JSON.
Now the chunk is intercepted individually, the existing buffer is
flushed first (preserving prior text), and the converted message
is emitted separately.

* fix(cli): skip flush when suppressing allowed rate_limit_event

Only flush the text buffer when the parsed event will actually be
displayed. Suppressed events (e.g. status: 'allowed') now return
immediately without flushing, preventing a text → allowed → text
sequence from splitting one answer into two agent-text blocks.

* fix(web): include limitType in limit-reached reconcile key

Without this, reprocessing a message from the old format (no
limitType) to the new typed format reuses the stale block and
the (5-hour)/(7-day) suffix never appears.
2026-04-03 08:25:22 +08:00
weishu 7a8f1c3e87 feat: add compact_boundary event support in web UI
https://github.com/tiann/hapi/issues/108#issuecomment-3799439152
2026-01-27 10:04:01 +08:00
weishu 8137ce4f23 feat: add microcompact_boundary event handling in web UI
Adds support for Claude Code's microcompact_boundary system message type to display context microcompaction events with token savings information in the chat UI. Shows a package icon with formatted token count (e.g., "Context compacted (saved 32K tokens)"). close #108
2026-01-26 10:30:27 +08:00
weishu 940d7b8233 feat(web): add turn-duration event display 2026-01-17 15:00:04 +08:00
weishu f7d161e6cf feat: add api-error event support with folding for retry messages
Introduces support for displaying API error system messages in the web UI with
automatic folding of consecutive retry messages to show only the latest state.
2026-01-05 13:00:25 +08:00
weishu 35d959dba4 feat: improve event presentation with separate icons and add aria labels to buttons 2025-12-18 08:56:52 +08:00
weishu 7f07bdc796 refactor: extract presentation utilities and status indicator component 2025-12-18 08:47:13 +08:00