Files
boss/docs/superpowers/plans/2026-04-14-android-chat-status-row-plan.md

113 lines
6.3 KiB
Markdown

# Android Chat Status Row Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Render `conversationTasks` and `executionWarnings` as a compact inline status row beneath each message on the Android chat page, dedupe grouped warnings per message, and keep realtime patches scoped to the affected message.
**Architecture:** Add a reusable status-row builder in `BossUi` and wire `ProjectDetailActivity.buildMessageView` to compute grouped tasks/warnings, append the status row under each bubble, and compare a fingerprint during realtime patches so only impacted views re-render.
**Tech Stack:** Android/Java UI (`ProjectDetailActivity.java`, `BossUi.java`) and Node-powered source-verification tests (`tests/android-chat-incremental-realtime-append.test.ts`, `tests/android-chat-local-realtime-patch.test.ts`).
---
### Task 1: Fail on missing inline status row in realtime append test
**Files:**
- Modify: `tests/android-chat-incremental-realtime-append.test.ts`
- Test: `npm test tests/android-chat-incremental-realtime-append.test.ts`
- [ ] **Step 1: Write the failing test**
```ts
assert.match(
source,
/wrapper\.addView\(BossUi\.buildMessageStatusRow\(/,
"expected every message bubble to append BossUi.buildMessageStatusRow",
);
assert.match(
source,
/List<JSONObject> messageWarnings = collectMessageWarnings\(projectMessagesPayload, messageId\);/,
"expected the new status row builder to source grouped warnings per message",
);
assert.match(
source,
/String statusFingerprint = buildStatusFingerprint\(messageId, projectMessagesPayload\);/,
"expected realtime patches to compute a fingerprint before replacing a message view",
);
```
- [ ] **Step 2: Run it to prove failure**
Run: `npm test tests/android-chat-incremental-realtime-append.test.ts`
Expected: FAIL because `BossUi.buildMessageStatusRow` and the new helper functions do not yet exist.
- [ ] **Step 3: Re-run after implementation to confirm success**
Run: `npm test tests/android-chat-incremental-realtime-append.test.ts`
Expected: PASS.
### Task 2: Fail on missing helper signatures in realtime patch test
**Files:**
- Modify: `tests/android-chat-local-realtime-patch.test.ts`
- Test: `npm test tests/android-chat-local-realtime-patch.test.ts`
- [ ] **Step 1: Write the failing test**
```ts
assert.match(
source,
/LinearLayout statusRow = buildMessageStatusRow\(this, message, conversationTask, messageWarnings\);/,
"expected buildMessageStatusRow to be invoked when each message is rendered",
);
assert.match(
source,
/List<JSONObject> buildMessageWarnings\(JSONObject payload, String messageId\);/,
"expected a helper that returns grouped warnings keyed by message id",
);
assert.match(
source,
/if \(!TextUtils\.equals\(currentFingerprint, nextFingerprint\)\) \{ replaceMessageViewById\(/,
"expected realtime patch to compare status fingerprint before rerendering",
);
```
- [ ] **Step 2: Run it to prove failure**
Run: `npm test tests/android-chat-local-realtime-patch.test.ts`
Expected: FAIL because helper signatures and fingerprint comparisons are missing.
- [ ] **Step 3: Re-run after implementation to confirm success**
Run: `npm test tests/android-chat-local-realtime-patch.test.ts`
Expected: PASS.
### Task 3: Add BossUi helper for compact status row
**Files:**
- Modify: `android/app/src/main/java/com/hyzq/boss/BossUi.java`
- Test: `npm test tests/android-chat-incremental-realtime-append.test.ts`
- Test: `npm test tests/android-chat-local-realtime-patch.test.ts`
- [ ] **Step 1: Implement `buildMessageStatusRow`**
Add a method that accepts `(Context context, String statusLabel, String detailText, boolean outgoing)` and returns a horizontal `LinearLayout` with spaced pills and body text, using rounded background colors and `TextView` ellipsizing. Keep it compact (max height) and re-usable for both warnings and conversation task summaries.
- [ ] **Step 2: Run targeted tests**
Run: `npm test tests/android-chat-incremental-realtime-append.test.ts tests/android-chat-local-realtime-patch.test.ts`
Expected: PASS after the helper is referenced by `ProjectDetailActivity`.
### Task 4: Wire ProjectDetailActivity to the new status row
**Files:**
- Modify: `android/app/src/main/java/com/hyzq/boss/ProjectDetailActivity.java`
- Test: `npm test tests/android-chat-incremental-realtime-append.test.ts`
- Test: `npm test tests/android-chat-local-realtime-patch.test.ts`
- [ ] **Step 1: Add helper methods for grouped warnings/tasks and fingerprinting**
Implement `List<JSONObject> collectMessageWarnings(JSONObject payload, String messageId)`, `@Nullable JSONObject findConversationTask(String messageId)`, and `private String buildStatusFingerprint(String messageId, JSONObject payload)` that concatenates task/w warning summaries so the realtime patch can detect status changes without re-rendering unchanged rows.
- [ ] **Step 2: Update `buildMessageView` to append a status row**
Inside `buildMessageView`, compute `List<JSONObject> messageWarnings` and `JSONObject messageTask`, then call `BossUi.buildMessageStatusRow(this, description, detail, outgoing)` and add it directly beneath the bubble instead of the previous warning card logic. Use the grouped data to deduplicate identical warnings (e.g., map by `warningId` or `title+summary`).
- [ ] **Step 3: Update realtime patch logic**
In `tryPatchRealtimeExecutionWarnings`, compute `String currentFingerprint = buildStatusFingerprint(messageId, currentRenderedProjectPayload)` and `String nextFingerprint = buildStatusFingerprint(messageId, projectMessagesPayload)`; only call `replaceMessageViewById` when they differ. Ensure `currentRenderedProjectPayload` is updated once per patch and that `renderNearBottom`/`setRefreshing` behavior stays the same.
- [ ] **Step 4: Run regression tests**
Run: `npm test tests/android-chat-incremental-realtime-append.test.ts tests/android-chat-local-realtime-patch.test.ts`
Expected: PASS.
### Task 5: Final verification
**Files:**
- Test: all above tests
- [ ] **Step 1: Run the two test files together**
Run: `npm test tests/android-chat-incremental-realtime-append.test.ts tests/android-chat-local-realtime-patch.test.ts`
Expected: PASS with no additional failures.