Files
boss/docs/superpowers/plans/2026-04-04-master-agent-thread-status-sync.md

26 KiB
Raw Blame History

主 Agent 线程状态文档与增量同步 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: 让主 Agent 用“线程状态文档 + 最近进展事件 + 关键时刻深拉”的方式理解活跃线程,减少常态 token 消耗,同时保持关键时刻的接手能力与实时性。

Architecture: 在现有 projectUnderstandingSnapshot 自动同步链路上新增线程级 ThreadStatusDocumentThreadProgressEvent,让 heartbeat / thread reply 先走轻量事件同步,再在关键场景触发全量理解刷新。主 Agent prompt 组装从“读项目理解快照”升级为“读线程状态文档 + 最近事件 + 项目记忆”,前台增加只读 线程状态 入口。

Tech Stack: Next.js App Router、TypeScript、文件型状态存储 data/boss-state.json、Android 原生客户端、Node test runner、Gradle unit tests


文件结构

新增/扩展数据模型与状态归一化

  • Modify: /Users/kris/code/boss/src/lib/boss-data.ts
  • Test: /Users/kris/code/boss/tests/thread-status-sync.test.ts
  • Test: /Users/kris/code/boss/tests/device-import-draft.test.ts

职责:

  • BossState 里新增线程状态文档和进展事件
  • 补 normalization / pruning / slicing
  • 增加全量同步与轻量同步任务排队逻辑

主 Agent prompt 组装与读取逻辑

  • Modify: /Users/kris/code/boss/src/lib/boss-master-agent.ts
  • Test: /Users/kris/code/boss/tests/master-agent-thread-status-prompt.test.ts

职责:

  • 让主 Agent 默认读取线程状态文档和最近进展事件
  • 保留关键时刻深拉线程的兜底路径

线程状态 API 与会话信息展示

  • Create: /Users/kris/code/boss/src/app/api/v1/projects/[projectId]/thread-status/route.ts
  • Modify: /Users/kris/code/boss/src/components/app-ui.tsx
  • Modify: /Users/kris/code/boss/android/app/src/main/java/com/hyzq/boss/BossApiClient.java
  • Modify: /Users/kris/code/boss/android/app/src/main/java/com/hyzq/boss/ConversationInfoActivity.java
  • Create: /Users/kris/code/boss/android/app/src/main/java/com/hyzq/boss/ThreadStatusActivity.java
  • Test: /Users/kris/code/boss/tests/thread-status-route.test.ts
  • Test: /Users/kris/code/boss/android/app/src/test/java/com/hyzq/boss/ConversationInfoActivityTest.java
  • Test: /Users/kris/code/boss/android/app/src/test/java/com/hyzq/boss/ThreadStatusActivityTest.java

职责:

  • 提供线程状态只读接口
  • 在线程会话信息页增加 线程状态 入口
  • Android 前台可查看线程状态

文档与回归

  • Modify: /Users/kris/code/boss/README.md
  • Modify: /Users/kris/code/boss/docs/architecture/current_runtime_and_deploy_status_cn.md
  • Modify: /Users/kris/code/boss/docs/architecture/api_and_service_inventory_cn.md

职责:

  • 记录线程状态文档和进展事件的运行方式
  • 记录 API 与同步策略

Task 1: 新增线程状态文档与进展事件模型

Files:

  • Modify: /Users/kris/code/boss/src/lib/boss-data.ts

  • Test: /Users/kris/code/boss/tests/thread-status-sync.test.ts

  • Step 1: 写失败测试,锁住状态模型归一化与裁剪行为

import test from "node:test";
import assert from "node:assert/strict";

let readState: (typeof import("../src/lib/boss-data"))["readState"];
let writeState: (typeof import("../src/lib/boss-data"))["writeState"];

test("thread status documents and progress events normalize and trim correctly", async () => {
  const state = await readState();
  state.threadStatusDocuments = [
    {
      documentId: "doc-1",
      projectId: "thread-a",
      threadId: "thread-a-id",
      threadDisplayName: "线程 A",
      folderName: "Talking",
      deviceId: "mac-studio",
      projectGoal: "完成树莓派二代查询链路",
      currentPhase: "功能实现",
      currentProgress: "已打通查询接口,正在补手机端展示",
      technicalArchitecture: "Next.js API + Android 原生客户端",
      currentBlockers: "",
      recommendedNextStep: "补会话页展示与排序",
      keyFiles: ["src/lib/boss-data.ts"],
      keyCommands: ["npm run build"],
      updatedAt: "2026-04-04T18:00:00+08:00",
      sourceTaskId: "task-1",
      sourceKind: "full_sync",
    },
  ];
  state.threadProgressEvents = Array.from({ length: 30 }, (_, index) => ({
    eventId: `event-${index}`,
    projectId: "thread-a",
    threadId: "thread-a-id",
    threadDisplayName: "线程 A",
    deviceId: "mac-studio",
    eventType: "progress_updated",
    summary: `进展 ${index}`,
    phase: "功能实现",
    blockerDelta: "",
    nextStepDelta: "",
    createdAt: `2026-04-04T18:${String(index).padStart(2, "0")}:00+08:00`,
    sourceTaskId: `task-${index}`,
  }));

  await writeState(state);
  const normalized = await readState();

  assert.equal(normalized.threadStatusDocuments.length, 1);
  assert.equal(normalized.threadStatusDocuments[0]?.projectGoal, "完成树莓派二代查询链路");
  assert.equal(normalized.threadProgressEvents.length, 20);
  assert.equal(normalized.threadProgressEvents[0]?.eventId, "event-29");
});
  • Step 2: 跑测试,确认它先失败

Run:

npx --yes tsx --test /Users/kris/code/boss/tests/thread-status-sync.test.ts

Expected:

  • FAIL提示 threadStatusDocumentsthreadProgressEvents 不存在,或者长度/排序不符合预期

  • Step 3: 在 BossState 里新增模型与归一化逻辑

/Users/kris/code/boss/src/lib/boss-data.ts 增加接口与默认值:

export interface ThreadStatusDocument {
  documentId: string;
  projectId: string;
  threadId: string;
  threadDisplayName: string;
  folderName: string;
  deviceId: string;
  projectGoal: string;
  currentPhase: string;
  currentProgress: string;
  technicalArchitecture: string;
  currentBlockers: string;
  recommendedNextStep: string;
  keyFiles: string[];
  keyCommands: string[];
  updatedAt: string;
  sourceTaskId: string;
  sourceKind: "device_import" | "full_sync" | "incremental_sync";
}

export interface ThreadProgressEvent {
  eventId: string;
  projectId: string;
  threadId: string;
  threadDisplayName: string;
  deviceId: string;
  eventType:
    | "phase_changed"
    | "progress_updated"
    | "blocker_added"
    | "blocker_resolved"
    | "next_step_changed"
    | "architecture_updated"
    | "handoff_ready";
  summary: string;
  phase?: string;
  blockerDelta?: string;
  nextStepDelta?: string;
  createdAt: string;
  sourceTaskId: string;
  sourceMessageId?: string;
}

并把状态接入:

threadStatusDocuments: ensureArray(raw.threadStatusDocuments, []).map((item) => ({
  ...item,
  keyFiles: ensureArray(item.keyFiles, []),
  keyCommands: ensureArray(item.keyCommands, []),
})),
threadProgressEvents: ensureArray(raw.threadProgressEvents, [])
  .map((item) => ({ ...item }))
  .sort((a, b) => b.createdAt.localeCompare(a.createdAt))
  .slice(0, 400),

syncDerivedState 里裁剪每线程最近事件:

const eventBuckets = new Map<string, ThreadProgressEvent[]>();
for (const event of state.threadProgressEvents) {
  const key = `${event.projectId}:${event.threadId}`;
  const bucket = eventBuckets.get(key) ?? [];
  if (bucket.length < 20) bucket.push(event);
  eventBuckets.set(key, bucket);
}
state.threadProgressEvents = [...eventBuckets.values()].flat();
  • Step 4: 重新跑测试,确认通过

Run:

npx --yes tsx --test /Users/kris/code/boss/tests/thread-status-sync.test.ts

Expected:

  • PASS

  • Step 5: 提交这一小步

git add /Users/kris/code/boss/src/lib/boss-data.ts /Users/kris/code/boss/tests/thread-status-sync.test.ts
git commit -m "feat: add thread status document models"

Task 2: 用线程状态文档替代常态全量理解

Files:

  • Modify: /Users/kris/code/boss/src/lib/boss-data.ts

  • Test: /Users/kris/code/boss/tests/device-import-draft.test.ts

  • Test: /Users/kris/code/boss/tests/thread-status-sync.test.ts

  • Step 1: 写失败测试锁住“heartbeat 优先记增量,不总是排全量理解”

test("active thread updates create lightweight progress events before full re-sync", async () => {
  const state = await readState();
  const project = state.projects.find((item) => item.id !== "master-agent" && item.threadMeta.codexThreadRef);
  assert.ok(project);

  project!.projectUnderstanding = {
    projectGoal: "目标 A",
    currentProgress: "旧进度",
    technicalArchitecture: "旧架构",
    currentBlockers: "",
    recommendedNextStep: "旧下一步",
    sourceTaskId: "task-old",
    updatedAt: "2026-04-04T10:00:00+08:00",
    sourceKind: "thread_sync",
  };
  state.threadStatusDocuments = [
    {
      documentId: "doc-old",
      projectId: project!.id,
      threadId: project!.threadMeta.threadId,
      threadDisplayName: project!.threadMeta.threadDisplayName,
      folderName: project!.threadMeta.folderName,
      deviceId: project!.deviceIds[0]!,
      projectGoal: "目标 A",
      currentPhase: "功能实现",
      currentProgress: "旧进度",
      technicalArchitecture: "旧架构",
      currentBlockers: "",
      recommendedNextStep: "旧下一步",
      keyFiles: [],
      keyCommands: [],
      updatedAt: "2026-04-04T10:00:00+08:00",
      sourceTaskId: "task-old",
      sourceKind: "full_sync",
    },
  ];

  // 用已有 heartbeat 处理函数或相关 helper 驱动活跃更新
  const result = await upsertThreadProgressEventInStateForTest(state, {
    projectId: project!.id,
    threadId: project!.threadMeta.threadId,
    threadDisplayName: project!.threadMeta.threadDisplayName,
    deviceId: project!.deviceIds[0]!,
    eventType: "progress_updated",
    summary: "已完成手机端排序修复",
    phase: "功能实现",
    createdAt: "2026-04-04T12:00:00+08:00",
    sourceTaskId: "task-new",
  });

  assert.equal(result.threadProgressEvents[0]?.summary, "已完成手机端排序修复");
  assert.equal(
    result.masterAgentTasks.some((task) => task.projectUnderstandingTargetProjectId === project!.id),
    false,
  );
});
  • Step 2: 跑测试,确认先失败

Run:

npx --yes tsx --test /Users/kris/code/boss/tests/thread-status-sync.test.ts /Users/kris/code/boss/tests/device-import-draft.test.ts

Expected:

  • FAIL提示没有轻量事件 helper 或仍然直接走完整理解任务

  • Step 3: 在状态层新增轻量事件写入与全量理解判定

/Users/kris/code/boss/src/lib/boss-data.ts 增加:

function upsertThreadStatusDocumentInState(
  state: BossState,
  input: {
    projectId: string;
    threadId: string;
    threadDisplayName: string;
    folderName: string;
    deviceId: string;
    projectGoal: string;
    currentPhase: string;
    currentProgress: string;
    technicalArchitecture: string;
    currentBlockers: string;
    recommendedNextStep: string;
    keyFiles: string[];
    keyCommands: string[];
    updatedAt: string;
    sourceTaskId: string;
    sourceKind: ThreadStatusDocument["sourceKind"];
  },
) {
  const existing = state.threadStatusDocuments.find(
    (item) => item.projectId === input.projectId && item.threadId === input.threadId,
  );
  if (existing) {
    Object.assign(existing, input);
    return existing;
  }
  const document: ThreadStatusDocument = {
    documentId: randomToken("thread-status"),
    ...input,
  };
  state.threadStatusDocuments.unshift(document);
  return document;
}

function appendThreadProgressEventInState(
  state: BossState,
  input: Omit<ThreadProgressEvent, "eventId">,
) {
  state.threadProgressEvents.unshift({
    eventId: randomToken("thread-event"),
    ...input,
  });
}

并把 heartbeat / thread reply 的同步策略改成:

if (shouldQueueProjectUnderstandingSync(project, observedActivityAt, state)) {
  // 仍保留关键时刻全量理解
} else {
  appendThreadProgressEventInState(state, {
    projectId: project.id,
    threadId: project.threadMeta.threadId,
    threadDisplayName: project.threadMeta.threadDisplayName,
    deviceId: project.deviceIds[0] ?? "mac-studio",
    eventType: "progress_updated",
    summary: "检测到线程有新活动",
    phase: project.projectUnderstanding ? "功能实现" : undefined,
    createdAt: observedActivityAt,
    sourceTaskId: "heartbeat-auto",
  });
}
  • Step 4: 重新跑测试,确认通过

Run:

npx --yes tsx --test /Users/kris/code/boss/tests/thread-status-sync.test.ts /Users/kris/code/boss/tests/device-import-draft.test.ts

Expected:

  • PASS

  • Step 5: 提交这一小步

git add /Users/kris/code/boss/src/lib/boss-data.ts /Users/kris/code/boss/tests/thread-status-sync.test.ts /Users/kris/code/boss/tests/device-import-draft.test.ts
git commit -m "feat: add lightweight thread progress events"

Task 3: 主 Agent 默认读取线程状态文档与最近事件

Files:

  • Modify: /Users/kris/code/boss/src/lib/boss-master-agent.ts

  • Test: /Users/kris/code/boss/tests/master-agent-thread-status-prompt.test.ts

  • Step 1: 写失败测试,锁住主 Agent prompt 读取顺序

import test from "node:test";
import assert from "node:assert/strict";
import { readState } from "../src/lib/boss-data.ts";
import { buildMasterAgentExecutionPromptForTest } from "../src/lib/boss-master-agent.ts";

test("master agent prompt prefers thread status documents and recent events", async () => {
  const state = await readState();
  state.threadStatusDocuments = [
    {
      documentId: "doc-1",
      projectId: "demo-thread",
      threadId: "thread-1",
      threadDisplayName: "树莓派二代查询",
      folderName: "Talking",
      deviceId: "mac-studio",
      projectGoal: "完成树莓派二代问答",
      currentPhase: "功能实现",
      currentProgress: "已经打通线程排序与会话时间刷新",
      technicalArchitecture: "Boss Web + Android + local-agent",
      currentBlockers: "群聊回流文案还需要收口",
      recommendedNextStep: "继续修群聊回流提示",
      keyFiles: ["src/lib/boss-data.ts"],
      keyCommands: ["npm run build"],
      updatedAt: "2026-04-04T19:00:00+08:00",
      sourceTaskId: "task-doc",
      sourceKind: "full_sync",
    },
  ];
  state.threadProgressEvents = [
    {
      eventId: "event-1",
      projectId: "demo-thread",
      threadId: "thread-1",
      threadDisplayName: "树莓派二代查询",
      deviceId: "mac-studio",
      eventType: "progress_updated",
      summary: "已完成会话排序修复",
      phase: "功能实现",
      createdAt: "2026-04-04T19:10:00+08:00",
      sourceTaskId: "task-event",
    },
  ];

  const prompt = buildMasterAgentExecutionPromptForTest(state, "请接手这个项目继续推进");

  assert.match(prompt, /线程状态文档/);
  assert.match(prompt, /完成树莓派二代问答/);
  assert.match(prompt, /已完成会话排序修复/);
});
  • Step 2: 跑测试,确认先失败

Run:

npx --yes tsx --test /Users/kris/code/boss/tests/master-agent-thread-status-prompt.test.ts

Expected:

  • FAIL提示当前 prompt 里没有线程状态文档和进展事件

  • Step 3: 修改主 Agent prompt 组装

/Users/kris/code/boss/src/lib/boss-master-agent.ts 增加线程状态摘要:

const activeThreadStatusDocs = state.threadStatusDocuments
  .sort((a, b) => b.updatedAt.localeCompare(a.updatedAt))
  .slice(0, 3)
  .map((doc) =>
    [
      `线程状态文档:${doc.threadDisplayName}`,
      doc.projectGoal ? `目标=${doc.projectGoal}` : undefined,
      doc.currentPhase ? `阶段=${doc.currentPhase}` : undefined,
      doc.currentProgress ? `进度=${doc.currentProgress}` : undefined,
      doc.technicalArchitecture ? `架构=${doc.technicalArchitecture}` : undefined,
      doc.currentBlockers ? `阻塞=${doc.currentBlockers}` : undefined,
      doc.recommendedNextStep ? `下一步=${doc.recommendedNextStep}` : undefined,
    ]
      .filter(Boolean)
      .join(" / "),
  )
  .join("\\n");

const recentThreadProgressEvents = state.threadProgressEvents
  .sort((a, b) => b.createdAt.localeCompare(a.createdAt))
  .slice(0, 5)
  .map((event) => `${event.threadDisplayName}${event.summary}`)
  .join("\\n");

并把返回 prompt 的内容改成:

"线程状态文档:",
activeThreadStatusDocs || "无",
"",
"最近线程进展:",
recentThreadProgressEvents || "无",
  • Step 4: 重新跑测试,确认通过

Run:

npx --yes tsx --test /Users/kris/code/boss/tests/master-agent-thread-status-prompt.test.ts

Expected:

  • PASS

  • Step 5: 提交这一小步

git add /Users/kris/code/boss/src/lib/boss-master-agent.ts /Users/kris/code/boss/tests/master-agent-thread-status-prompt.test.ts
git commit -m "feat: read thread status documents in master agent prompts"

Task 4: 新增线程状态只读 API

Files:

  • Create: /Users/kris/code/boss/src/app/api/v1/projects/[projectId]/thread-status/route.ts

  • Modify: /Users/kris/code/boss/src/lib/boss-data.ts

  • Test: /Users/kris/code/boss/tests/thread-status-route.test.ts

  • Step 1: 写失败测试,锁住路由返回格式

import test from "node:test";
import assert from "node:assert/strict";
import { GET } from "../src/app/api/v1/projects/[projectId]/thread-status/route.ts";

test("GET thread-status returns current document and recent events", async () => {
  const response = await GET(
    new Request("http://localhost/api/v1/projects/demo-thread/thread-status"),
    { params: Promise.resolve({ projectId: "demo-thread" }) },
  );

  assert.equal(response.status, 200);
  const body = await response.json();
  assert.ok(body.threadStatusDocument);
  assert.ok(Array.isArray(body.recentProgressEvents));
});
  • Step 2: 跑测试,确认先失败

Run:

npx --yes tsx --test /Users/kris/code/boss/tests/thread-status-route.test.ts

Expected:

  • FAIL提示 route 不存在或返回格式不对

  • Step 3: 实现只读 route

创建 /Users/kris/code/boss/src/app/api/v1/projects/[projectId]/thread-status/route.ts

import { NextResponse } from "next/server";
import { readState } from "@/src/lib/boss-data";

export async function GET(
  _request: Request,
  { params }: { params: Promise<{ projectId: string }> },
) {
  const { projectId } = await params;
  const state = await readState();
  const project = state.projects.find((item) => item.id === projectId);
  if (!project) {
    return NextResponse.json({ error: "PROJECT_NOT_FOUND" }, { status: 404 });
  }
  const threadStatusDocument =
    state.threadStatusDocuments.find((item) => item.projectId === projectId) ?? null;
  const recentProgressEvents = state.threadProgressEvents
    .filter((item) => item.projectId === projectId)
    .sort((a, b) => b.createdAt.localeCompare(a.createdAt))
    .slice(0, 5);
  return NextResponse.json({
    projectId,
    threadStatusDocument,
    recentProgressEvents,
  });
}
  • Step 4: 重新跑测试,确认通过

Run:

npx --yes tsx --test /Users/kris/code/boss/tests/thread-status-route.test.ts

Expected:

  • PASS

  • Step 5: 提交这一小步

git add /Users/kris/code/boss/src/app/api/v1/projects/[projectId]/thread-status/route.ts /Users/kris/code/boss/tests/thread-status-route.test.ts
git commit -m "feat: add thread status read api"

Task 5: 在线程会话信息页接入线程状态入口

Files:

  • Modify: /Users/kris/code/boss/android/app/src/main/java/com/hyzq/boss/BossApiClient.java

  • Modify: /Users/kris/code/boss/android/app/src/main/java/com/hyzq/boss/ConversationInfoActivity.java

  • Create: /Users/kris/code/boss/android/app/src/main/java/com/hyzq/boss/ThreadStatusActivity.java

  • Test: /Users/kris/code/boss/android/app/src/test/java/com/hyzq/boss/ConversationInfoActivityTest.java

  • Test: /Users/kris/code/boss/android/app/src/test/java/com/hyzq/boss/ThreadStatusActivityTest.java

  • Step 1: 写失败测试,锁住入口和渲染

@Test
public void conversationInfoShowsThreadStatusEntryForThreadConversation() {
    BossUi.ViewNode root = renderConversationInfoForThread();
    assertTrue(viewTreeContainsText(root, "线程状态"));
}

@Test
public void threadStatusActivityRendersCurrentGoalProgressAndNextStep() {
    BossUi.ViewNode root = renderThreadStatusActivityWithFixture();
    assertTrue(viewTreeContainsText(root, "当前目标"));
    assertTrue(viewTreeContainsText(root, "当前进度"));
    assertTrue(viewTreeContainsText(root, "建议下一步"));
}
  • Step 2: 跑测试,确认先失败

Run:

cd /Users/kris/code/boss/android && ./gradlew testDebugUnitTest --tests com.hyzq.boss.ConversationInfoActivityTest --tests com.hyzq.boss.ThreadStatusActivityTest --no-daemon

Expected:

  • FAIL提示没有 线程状态 入口或 Activity 不存在

  • Step 3: 实现 Android 入口与只读页

/Users/kris/code/boss/android/app/src/main/java/com/hyzq/boss/BossApiClient.java 增加:

public JSONObject getThreadStatus(String projectId) throws IOException, ApiException {
    return getJson("/api/v1/projects/" + Uri.encode(projectId) + "/thread-status");
}

/Users/kris/code/boss/android/app/src/main/java/com/hyzq/boss/ConversationInfoActivity.java 中,当当前会话是线程会话时增加:

addMenuRow(container, "线程状态", v -> {
    Intent intent = new Intent(this, ThreadStatusActivity.class);
    intent.putExtra("projectId", projectId);
    startActivity(intent);
});

创建 /Users/kris/code/boss/android/app/src/main/java/com/hyzq/boss/ThreadStatusActivity.java,读取接口并展示:

renderSection("当前目标", document.optString("projectGoal"));
renderSection("当前阶段", document.optString("currentPhase"));
renderSection("当前进度", document.optString("currentProgress"));
renderSection("技术架构", document.optString("technicalArchitecture"));
renderSection("当前阻塞", document.optString("currentBlockers"));
renderSection("建议下一步", document.optString("recommendedNextStep"));
renderEvents(recentProgressEvents);
  • Step 4: 重新跑测试,确认通过

Run:

cd /Users/kris/code/boss/android && ./gradlew testDebugUnitTest --tests com.hyzq.boss.ConversationInfoActivityTest --tests com.hyzq.boss.ThreadStatusActivityTest --no-daemon

Expected:

  • PASS

  • Step 5: 提交这一小步

git add /Users/kris/code/boss/android/app/src/main/java/com/hyzq/boss/BossApiClient.java /Users/kris/code/boss/android/app/src/main/java/com/hyzq/boss/ConversationInfoActivity.java /Users/kris/code/boss/android/app/src/main/java/com/hyzq/boss/ThreadStatusActivity.java /Users/kris/code/boss/android/app/src/test/java/com/hyzq/boss/ConversationInfoActivityTest.java /Users/kris/code/boss/android/app/src/test/java/com/hyzq/boss/ThreadStatusActivityTest.java
git commit -m "feat: add thread status view in android"

Task 6: 完整回归、文档同步与发版

Files:

  • Modify: /Users/kris/code/boss/README.md

  • Modify: /Users/kris/code/boss/docs/architecture/current_runtime_and_deploy_status_cn.md

  • Modify: /Users/kris/code/boss/docs/architecture/api_and_service_inventory_cn.md

  • Step 1: 同步文档

在文档里明确新增:

- 主 Agent 当前会优先读取线程状态文档和最近进展事件,而不是常态反复重跑完整理解
- 已导入设备与新导入设备都走统一的线程状态同步链
- 线程会话信息页新增只读 `线程状态`
  • Step 2: 跑完整关键回归

Run:

npx --yes tsx --test /Users/kris/code/boss/tests/thread-status-sync.test.ts /Users/kris/code/boss/tests/device-import-draft.test.ts /Users/kris/code/boss/tests/master-agent-thread-status-prompt.test.ts /Users/kris/code/boss/tests/thread-status-route.test.ts
npm run lint
npm run build
cd /Users/kris/code/boss/android && ./gradlew testDebugUnitTest --tests com.hyzq.boss.ConversationInfoActivityTest --tests com.hyzq.boss.ThreadStatusActivityTest --no-daemon
cd /Users/kris/code/boss/android && ./gradlew assembleRelease --no-daemon

Expected:

  • 全部 PASS

  • build 成功

  • Android release 包成功生成

  • Step 3: 部署服务器

Run:

sshpass -p 'Asd123456.' ssh -o StrictHostKeyChecking=no ubuntu@106.53.170.158 "sudo rm -rf /opt/boss/.next && sudo mkdir -p /opt/boss/.next && sudo chown -R ubuntu:ubuntu /opt/boss /opt/boss/.next"
sshpass -p 'Asd123456.' rsync -az --delete -e "ssh -o StrictHostKeyChecking=no" --exclude '.git/' --exclude 'node_modules/' --exclude 'data/' --exclude '.superpowers/' --exclude 'public/downloads/' /Users/kris/code/boss/ ubuntu@106.53.170.158:/opt/boss/
sshpass -p 'Asd123456.' ssh -o StrictHostKeyChecking=no ubuntu@106.53.170.158 "cd /opt/boss && sudo systemctl restart boss-web && sudo systemctl restart caddy && curl -fsS http://127.0.0.1:3000/api/health"
curl -fsS https://boss.hyzq.net/api/health

Expected:

  • 远端本机健康检查返回 ok:true

  • 公网健康检查返回 ok:true

  • Step 4: 最终提交

git add /Users/kris/code/boss/README.md /Users/kris/code/boss/docs/architecture/current_runtime_and_deploy_status_cn.md /Users/kris/code/boss/docs/architecture/api_and_service_inventory_cn.md
git commit -m "feat: add thread status sync pipeline"
git push gitea codex/wechat-native-ui-rollback

自检

Spec 覆盖

  • 线程状态文档Task 1
  • 线程进展事件Task 1 / Task 2
  • 主 Agent 读取“文档 + 最近事件”Task 3
  • 关键时刻深拉保留Task 2 / Task 3
  • APP 只读查看线程状态Task 4 / Task 5
  • 不写入项目仓库:通过 Task 1-5 全部走 Boss 内部状态层实现

Placeholder 扫描

  • 没有 TBD / TODO / implement later
  • 每个任务都给了文件、代码、命令和预期结果

类型一致性

  • 线程状态文档统一命名为 ThreadStatusDocument
  • 增量事件统一命名为 ThreadProgressEvent
  • API 字段统一用 threadStatusDocument / recentProgressEvents