chore(plan): file T-461 (red error border on API-error cards)

Flag API-error conversation cards with a red statusError border (the card
already has an error status + bordered variant; just needs wiring). UI
tracker T-276.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-17 09:42:54 +02:00
co-authored by Claude Opus 4.8
parent f5fab2f4c2
commit 50d10c792a
3 changed files with 34 additions and 0 deletions
+16
View File
@@ -5877,3 +5877,19 @@ INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, chang
**Files:** `pubspec.yaml` (fonts:), `assets/fonts/inter/`, `assets/licenses.yaml`, `lib/widgets/src/typography.dart`, `lib/src/shell/root_shell.dart` (DefaultTextStyle), mono consumers (editor / terminal / markdown / code-block), the Appearance settings category (T-452) + schema registration.
**Related:** T-444 (epic), T-452 (Appearance category where these render), T-448 (field renderer), T-449 (scope), ui-design `theme.md` (typography section: clideUiFamily / clideMonoFamily / clideFont* sizes), D-42 (bundled-dep documentation), D-44 (theming).', NULL, '2026-06-17 07:39:55', '2026-06-17 07:39:55.628', '2026-06-17 07:39:55.628', NULL, '316143b93910994fac553f6f515f6645', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD91RWDWZPHFPJ72FHHHWS08', 'description', NULL, 'User report 2026-06-16 (screenshot ~/.cache/clide/pasted/paste-1781681999949.png). An API error renders as a plain conversation card with no error styling:
clide
API Error: Server is temporarily limiting requests (not your usage limit) · Rate limited
It should be visually flagged with a **red error border** on the card so it stands out from normal turns.
**Already supported just needs wiring.** `lib/builtin/claude/src/conversation_card.dart`:
- `ConversationCardStatus.error` exists (line ~302 `tokens.statusError`) but today only tints the header status tick, not the border.
- The `bordered` variant draws `Border.all(color: widget.borderColor ?? tokens.panelBorder)` (lines ~61 / ~224) so the border defaults to the neutral `panelBorder`.
**Fix:** render the API-error card as `variant: bordered, status: error, borderColor: tokens.statusError` (or, cleaner, have the card derive the border from `status == error tokens.statusError` so any error card gets the red border without each caller passing it). Wire the producer the error / system message that carries the "API Error …" text (in `conversation_view.dart` / `transcript_reader.dart`, e.g. the stream error / `SessionEnd.reason` path) to mark the card as an error.
**Acceptance:** an API error (rate-limit, server error, etc.) renders a card with a red `statusError` border; normal cards unchanged; a widget test asserts the error card''s border colour.
**Files:** lib/builtin/claude/src/conversation_card.dart (border from error status), the error/system-message rendering in lib/builtin/claude/src/conversation_view.dart / transcript_reader.dart.', NULL, '2026-06-17 07:41:47', '2026-06-17 07:41:47.267', '2026-06-17 07:41:47.267', NULL, 'aa0330e9165b9b9fc3f1c516abc3a07c', 2) ON CONFLICT(hash) DO NOTHING;
+1
View File
@@ -286,3 +286,4 @@ INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD1HK7YKJTEK1WV4VHK0RT8R', 'T-458', '2026-06-16 14:12:04.212', '2026-06-16 14:12:04.212', NULL, '070f1def635ee013df639cb9fe81e357', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash);
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD1JBRABJHX804CPMZJDC444', 'T-459', '2026-06-16 14:15:25.011', '2026-06-16 14:15:25.011', NULL, '44d5db70ef13ead00c4dcc437c387cec', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash);
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD91A7VEW3VCY7QX1END2Z3G', 'T-460', '2026-06-17 07:39:25.019', '2026-06-17 07:39:25.019', NULL, 'e7e749d35dc413a560d3347be5f4a9ee', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash);
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD91RWDWZPHFPJ72FHHHWS08', 'T-461', '2026-06-17 07:41:24.975', '2026-06-17 07:41:24.975', NULL, '4e3fba7aaad762b7b7cd854459cf664a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash);
+17
View File
@@ -7080,3 +7080,20 @@ INSERT INTO tickets (record_id, type, parent_record_id, title, description, stat
**Files:** `pubspec.yaml` (fonts:), `assets/fonts/inter/`, `assets/licenses.yaml`, `lib/widgets/src/typography.dart`, `lib/src/shell/root_shell.dart` (DefaultTextStyle), mono consumers (editor / terminal / markdown / code-block), the Appearance settings category (T-452) + schema registration.
**Related:** T-444 (epic), T-452 (Appearance category where these render), T-448 (field renderer), T-449 (scope), ui-design `theme.md` (typography section: clideUiFamily / clideMonoFamily / clideFont* sizes), D-42 (bundled-dep documentation), D-44 (theming).', 'backlog', 'medium', NULL, NULL, NULL, '2026-06-17 07:39:25.019', '2026-06-17 07:39:55.628', NULL, '0bd5fdb6f8d924a23eb45be2c48bedaf', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD91RWDWZPHFPJ72FHHHWS08', 'bug', '06FB0TNQM5TWC00GW0P3X02HZW', 'API-error cards: flag with a red error border (statusError)', NULL, 'backlog', 'medium', NULL, NULL, NULL, '2026-06-17 07:41:24.975', '2026-06-17 07:41:24.975', NULL, '38eac435cdb43c08db84de486c65a527', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD91RWDWZPHFPJ72FHHHWS08', 'bug', '06FB0TNQM5TWC00GW0P3X02HZW', 'API-error cards: flag with a red error border (statusError)', 'User report 2026-06-16 (screenshot ~/.cache/clide/pasted/paste-1781681999949.png). An API error renders as a plain conversation card with no error styling:
clide
API Error: Server is temporarily limiting requests (not your usage limit) · Rate limited
It should be visually flagged with a **red error border** on the card so it stands out from normal turns.
**Already supported just needs wiring.** `lib/builtin/claude/src/conversation_card.dart`:
- `ConversationCardStatus.error` exists (line ~302 `tokens.statusError`) but today only tints the header status tick, not the border.
- The `bordered` variant draws `Border.all(color: widget.borderColor ?? tokens.panelBorder)` (lines ~61 / ~224) so the border defaults to the neutral `panelBorder`.
**Fix:** render the API-error card as `variant: bordered, status: error, borderColor: tokens.statusError` (or, cleaner, have the card derive the border from `status == error tokens.statusError` so any error card gets the red border without each caller passing it). Wire the producer the error / system message that carries the "API Error …" text (in `conversation_view.dart` / `transcript_reader.dart`, e.g. the stream error / `SessionEnd.reason` path) to mark the card as an error.
**Acceptance:** an API error (rate-limit, server error, etc.) renders a card with a red `statusError` border; normal cards unchanged; a widget test asserts the error card''s border colour.
**Files:** lib/builtin/claude/src/conversation_card.dart (border from error status), the error/system-message rendering in lib/builtin/claude/src/conversation_view.dart / transcript_reader.dart.', 'backlog', 'medium', NULL, NULL, NULL, '2026-06-17 07:41:24.975', '2026-06-17 07:41:47.266', NULL, 'e4c3db66fb4ba42ba08896b97ef3ad89', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);