feat: explain task phase in android progress cards

This commit is contained in:
AI Bot
2026-06-06 19:05:07 +08:00
parent 7973c441e4
commit 755e30612c
2 changed files with 80 additions and 0 deletions

View File

@@ -1339,6 +1339,19 @@ public final class BossUi {
titleRow.addView(pin);
card.addView(titleRow);
String phase = progress == null ? "" : progress.optString("phase", "").trim();
if (!TextUtils.isEmpty(phase)) {
TextView phaseView = secondaryText(context, "当前状态:" + executionPhaseLabel(phase));
phaseView.setPadding(0, dp(context, 8), 0, 0);
card.addView(phaseView);
}
String lastProgressAt = progress == null ? "" : progress.optString("lastProgressAt", "").trim();
if (!TextUtils.isEmpty(lastProgressAt)) {
TextView lastProgressView = secondaryText(context, "最后更新:" + lastProgressAt);
lastProgressView.setPadding(0, dp(context, 4), 0, 0);
card.addView(lastProgressView);
}
JSONArray steps = progress == null ? null : progress.optJSONArray("steps");
if (steps == null || steps.length() == 0) {
card.addView(progressLine(context, "等待执行进度回写", "running"));
@@ -1931,6 +1944,37 @@ public final class BossUi {
return card;
}
private static String executionPhaseLabel(String phase) {
switch (phase) {
case "queued":
return "等待设备接收";
case "claimed":
return "设备已接收";
case "executor_starting":
return "正在启动执行器";
case "turn_started":
return "已写入目标线程";
case "awaiting_reply":
return "等待线程回复";
case "completing":
return "正在回写结果";
case "completed":
return "已完成";
case "recoverable_failed":
return "可恢复失败";
case "terminal_failed":
return "执行失败";
case "timed_out":
return "执行超时";
case "canceled":
return "已取消";
case "needs_user_action":
return "需要用户处理";
default:
return phase;
}
}
private static View progressLine(Context context, String text, String status) {
LinearLayout row = new LinearLayout(context);
row.setOrientation(LinearLayout.HORIZONTAL);

View File

@@ -948,6 +948,42 @@ public class ProjectDetailActivityUiTest {
assertTrue(viewTreeContainsText(messageView, "Mendelexplorer"));
}
@Test
public void executionProgressMessageRendersPhaseExplanation() throws Exception {
Intent intent = new Intent()
.putExtra(ProjectDetailActivity.EXTRA_PROJECT_ID, "thread-phase")
.putExtra(ProjectDetailActivity.EXTRA_PROJECT_NAME, "Boss开发主线程");
TestProjectDetailActivity activity = Robolectric
.buildActivity(TestProjectDetailActivity.class, intent)
.setup()
.get();
JSONObject message = new JSONObject()
.put("id", "progress-phase-1")
.put("sender", "master")
.put("senderLabel", "主 Agent")
.put("body", "执行进度")
.put("kind", "execution_progress")
.put("sentAt", "2026-06-06T10:16:00+08:00")
.put("executionProgress", new JSONObject()
.put("status", "running")
.put("phase", "awaiting_reply")
.put("lastProgressAt", "2026-06-06T10:15:30+08:00")
.put("steps", new JSONArray()
.put(new JSONObject()
.put("text", "等待目标线程回复")
.put("status", "running"))));
View messageView = ReflectionHelpers.callInstanceMethod(
activity,
"buildMessageView",
ReflectionHelpers.ClassParameter.from(JSONObject.class, message)
);
assertTrue(viewTreeContainsText(messageView, "当前状态:等待线程回复"));
assertTrue(viewTreeContainsText(messageView, "最后更新2026-06-06T10:15:30+08:00"));
}
@Test
public void executionProgressMessageRendersCodexApprovalAndFileChangeSections() throws Exception {
Intent intent = new Intent()