恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
MastraCode Factory UI 开发指南:Mastra 工厂的 React 前端、Needs attention 行动中心与测试体系
首页
资讯中心
/
MastraCode Factory UI 开发指南:Mastra 工厂的 React 前端、Needs attention 行动中心与测试体系
MastraCode Factory UI 开发指南:Mastra 工厂的 React 前端、Needs attention 行动中心与测试体系
发布时间:2026/9/13 23:52:47
MastraCode Factory UI 开发指南Mastra 工厂的 React 前端、Needs attention 行动中心与测试体系【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastrainternal/factory-ui是 MastraCodeMastra 的软件工厂的浏览器端 React 单页应用SPA负责页面路由、客户端状态、API 访问与 UI 测试最终产物会被打包进 Mastra CLI。本文以 mastracode/factory-ui/README.md 为主线结合 web 宿主 与mastra/factory核心库源码完整讲解 Factory UI 的开发启动流程、看板活动Board activity机制、Needs attention 行动中心的实现细节以及单测/MSW 测试的落地方式帮助你快速上手这个多页面、多 Board、带实时事件流的复杂 React 应用。Factory UI 在整个 MastraCode 中的位置Factory UI 不是独立运行的站点而是 MastraCode 三件套中的前端层包职责关键说明internal/factory-ui本包React SPA、客户端数据层、Vite 配置、UI 测试构建产物打包进 Mastra CLImastra/factorymastracode/factory/README.md策略policy、校验、持久化等全部领域逻辑不得把业务逻辑写进 Reactmastracode/webmastracode/web/README.md环境相关的存储、认证、集成、事件总线、沙箱装配拥有 Docker 与.envREADME 中的约束非常明确Keep policy, validation, and persistence inmastra/factory, not in React.策略、校验与持久化保持在mastra/factory不要放进 React。从 package.json 可以看到Factory UI 只负责把它消费进来dependencies: { mastra/client-js: workspace:*, mastra/code-sdk: workspace:*, mastra/core: workspace:*, mastra/factory: workspace:*, mastra/playground-ui: workspace:*, mastra/react: workspace:*, tanstack/react-query: ^5.90.21, xyflow/react: ^12.10.1, d3-force: ^3.0.0, react-router: ^8.0.0, shiki: ^1.29.2 }架构上的依赖方向是单向的factory-ui → factory领域层→ web装配层。UI 通过mastra/client-js、mastra/react和 React Query 与宿主 API 通信而决策如批准、重试、驳回最终都会落到mastra/factory的 canonical decision state 上。开发环境启动一条命令跑起 Docker、API 与 Vite前置条件按 README开发前需要先完成两步准备仓库级安装参照 仓库根目录 README 的 Setup 部分完成pnpm install。GitHub App 配置参照 mastracode/web/README.md#configure-local-onboarding 完成本地 onboarding 的 GitHub App 配置Homepage/Callback/Setup URL、Contents/Issues/Pull requests 读写权限、.env中的GITHUB_APP_*等。一体化启动命令pnpm --dir mastracode/web dev:ui这条命令做三件事细节见 mastracode/factory-ui/AGENTS.md启动 Docker 服务LibSQL 与本地沙箱构建本包依赖的 workspace 包mastra/factory、mastra/playground-ui等启动宿主 API:4111与 Vite dev server:5173。启动后打开http://localhost:5173即可使用 Split UI 模式。分别重启任意一侧如果只想重启前端或后端、而不想丢掉另一侧状态README 给出了拆分方案# 终端 1只启动 Docker 服务 pnpm --dir mastracode/web db:up # 终端 2只启动宿主 API:4111 pnpm --dir mastracode/web api # 终端 3只启动 Vite dev server:5173 pnpm --filter ./mastracode/factory-ui dev注意mastracode/web是 workspace 之外的独立 pnpm 项目拥有自己的 lockfile通过link:依赖 monorepo 包所以dev:api实际上是pnpm --dir ../web api的 shim——Turbo 只能编排 workspace 内的包这个 shim 让两侧可以独立重启。集成模式后端开发、类生产检查则使用pnpm --dir mastracode/web dev访问http://localhost:5873。从 package.json 可以看到 dev 脚本的完整定义scripts: { dev: MASTRACODE_ENV_DIR../web vite --config src/vite.config.ts, dev:api: pnpm --dir ../web api, build: vite --config src/vite.config.ts build, typecheck: tsc --noEmit -p src/ui/tsconfig.json, test: vitest run, test:unit: vitest run --project unit:factory-ui, test:msw: vitest run --project msw:factory-ui }MASTRACODE_ENV_DIR../web表明 Vite 会从mastracode/web读取环境变量运行时配置由 src/ui/runtime-config.ts 装配。SPA 路由结构URL 是当前 Factory 的唯一事实来源src/ui/router.tsx 使用 React Router v7 的 data mode 定义整个 SPA 的路由表。核心设计原则写在文件注释里The URL is the single source of truth for the active factory: everything factory-scoped lives under/factories/:factoryId/**.认证守卫不在 loader 中做而是在 React layout 层RequireAuth通过useFactoryAuth读取/auth/me未认证会话重定向到/signinSignInGate则把已登录或认证关闭的访问者送回/。关键路由一览位于factories/:factoryId之下路由页面说明/factories/:factoryIdFactoryHomeRedirect落到活动 factory 的 Board 或草稿编辑器/factories/:factoryId/workWorkBoardPageWork 看板/factories/:factoryId/reviewReviewBoardPageReview 看板/factories/:factoryId/boards/:boardIdCustomBoardPage自定义看板/factories/:factoryId/attentionAttentionPageNeeds attention 行动中心/factories/:factoryId/activityActivityPage活动时间线/factories/:factoryId/overviewOverviewPage总览/metrics会 301 式重定向到这里/factories/:factoryId/rulesRulesPage规则页/factories/:factoryId/auditAuditPage审计历史/factories/:factoryId/knowledgeKnowledgePage知识图谱需 server feature 开启/factories/:factoryId/settings/:sectionSettingsPage设置此外还有两类工厂无关的深链接/threads/:threadId与/settings/connections。它们由服务端构建的链接使用如 Slack 的 View Session 卡片SPA 侧先保证访问者已认证再转发到第一个 factory 的对应页面。Board activity审计历史驱动的看板活动视图README 对看板活动的描述是Work 与 Review 看板上的卡片会显示工作项审计历史中最后操作的那个人。把鼠标悬停在姓名或头像上会打开该卡片的近期事件时间线。这条能力的实现链路是Factory 在写入审计事件时会把actor 名称与头像存进事件 metadata对于没有该 metadata 的旧事件Factory 通过配置的认证 provider 解析 actor 画像profile解析失败时回退显示存储的 actor ID 与一个首字母缩写。也就是说UI 层如 AuditPage.tsx、ActivityPage.tsx只负责展示而如何解析 actor完全由mastra/factory的 audit 存储层负责——这正是策略在 factory 不在 React的体现。前端对应的数据获取逻辑集中在src/hooksuseAuditEvents、useWorkItems、useFactoryData等自定义 hook 通过mastra/client-js拉取审计历史与看板数据并用 React Query 统一管理缓存与失效。相关的 MSW 测试如BoardPageWorkItemActivity.msw.test.tsx、AuditPage.msw.test.tsx保证了这条链路的页面行为可回归。Needs attention项目成员的行动中心定位与入口README 明确将其定义为project-member action center项目成员行动中心。它有三个层次的入口侧边栏 footerSidebarAttention.tsx常驻的 Needs attention 按钮带未读徽标与预览弹层Popover弹层内三个 TabNeeds you / Approvals / Activity右上角 View all 跳转完整收件箱完整页面路由/factories/:factoryId/attention即 AttentionPage.tsx。弹层预览的两个关键设计预览与徽标分离查询徽标与提示音挂在始终挂载的useFactoryAttention(factoryId, open, 25, attention)查询上Tab 内容读各自分组的查询。两者共用同一个ATTENTION_PREVIEW_LIMIT 25常量见 useFactoryAttention.ts因此侧边栏与 Overview 共享同一份缓存。按需展示弹层只显示最新的 25 条预览当groupOpenCount 0时显示 Open the inbox to continue through older items.引导用户进入完整页面。完整页面的三视图与三分组AttentionPage 提供三种视图?view查询参数控制默认openconst VIEWS [ { value: open, label: Open, icon: Inbox }, { value: unread, label: Unread, icon: Mail }, { value: archived, label: Archived, icon: Archive }, ];页面内部把 attention 项划分为三个分组见 attention.ts 的ATTENTION_GROUP_OF_KIND分组含义包含的 kindattention需要打断你的事情automation-failed、supervisor-finding、agent-waiting、mentionqueue等你批准/放行的运行automation-proposedactivity你参与的讨论有进展activity页面头部是interruptingattention分组时间线下方依次是 Waiting for approvalqueue与 Activityactivity两个带未读计数的小节——注释原话是What needs a person leads the page; what waits on their say-so and what they merely follow sit under it.需要你处理的事置顶等你拍板的事与你可选跟进的事排在下面。页面还提供按日分组的时间线groupByDayDayHeading与 Activity 页共用同一套 rail 组件和全文搜索useDeferredValue防抖通过search参数传给 API。六种 attention 项类型attention.ts 定义了六种 discriminated union 成员每个都有独立的图标、徽标色与目标跳转kind含义目标target徽标mention评论中提到你评论所在 work-item/threadgreenactivity你参与的讨论有新进展work-item commentneutralautomation-failed终端自动化失败匹配的角色会话或 Board 卡片redautomation-proposed等待批准的建议运行该 decision 的批准队列orangesupervisor-findingSupervisor 健康发现/rules页面blueagent-waitingagent 正等待计划/问题答复work-item session/threadorange每种项的key、occurrence、occurredAt、read、archived等字段共同构成收件箱数据模型attentionItemSourceId()把不同 kind 映射到各自的源 IDcommentId / workItemId / decisionId / findingKey / sessionId这是后续收据receipt与决策 API 的寻址基础。每行可执行的动作AttentionItemRow.tsx 定义了行的动作区hover 时在行右侧浮现不影响布局动作由 useAttentionItemActions.ts 统一装配侧边栏弹层与页面共用同一份Ask supervisor把该项的上下文拼成 prompt跳到 supervisor 提问页Retry仅automation-failed且canRetry为 true 时出现触发 decision 的retry动作Run it / Dismiss仅automation-proposed触发 decision 的approve/dismiss动作Mark as read未读时Archive / Restore收据操作。这些动作分成两类语义README 特别强调Read and archive are per-user. Retry, reconciliation, approval, and dismissal update canonical decision state for every member.读/归档/恢复写入 attention receipt是按用户的调用updateFactoryAttentionReceiptURL 形如/web/factory/projects/:id/attention/:kind/:sourceId/:occurrence/:action重试/批准/驳回修改mastra/factory的 canonical decision state影响所有成员。页面顶部的 Mark all open as read 按钮走markAllFactoryAttentionRead注意它带游标分页只要hasMore就带着nextCursor继续 POST/attention/read-all直到全部读完见 useFactoryAttention.ts。失败项的一致性协调与 occurrence 机制README 这一段是整个模块最核心的语义Failures are reconciled against canonical Factory state before they become queryable: an accepted transition issucceeded, obsolete work issuperseded, and only unresolvedfaileddecisions remain.也就是说失败这个状态不是事件一发生就直接展示的。在它变得可查询queryable之前系统会拿它与 canonical Factory state 做对账reconcile已接受的迁移transition→ 标记为succeeded成功已过时的工作 → 标记为superseded被取代只有真正未解决的failed决策才保留为失败。这保证了 Needs attention 页面展示的失败都是仍然成立的失败而不是历史噪音。Go to 导航打开失败决策对应的角色会话role session若该角色没有会话则打开正确的 Work/Review 看板并高亮对应卡片。Retry 可见性只对策略允许重试的类型化失败typed failures显示 Retry 按钮。occurrence发生次数机制A later terminal failure increments the decisions occurrence and reappears unread without allowing a delayed receipt from the previous occurrence to hide it.同一条 decision 的后续终端失败会使occurrence递增、以未读重新出现并且前一次 occurrence 的延迟收据不会把新的失败藏起来。前端在渲染与收据 API 中都携带occurrence如/attention/:kind/:sourceId/:occurrence/read从而保证旧回执只作用于旧 occurrence。成功/失败提示音静默基线 跨标签页锁成功运行的完成继续使用侧边栏会话行的Ready 指示灯 完成音而失败音效的设计是Failure sounds establish a silent initial baseline and use a cross-tab lock so one occurrence plays once.实现位于 attentionSound.ts静默初始基线首次挂载时不响铃!previous || previous.scope ! scope直接返回只有新 key 且 occurredAt 比基线更新才触发playDoneSound()跨标签页锁优先用 Web Locks APInavigator.locks.request(mastracode-attention-sound, ...)保证一次 occurrence 只播放一次不支持锁的环境回退到localStorage去重keymastracode.attentionNotified.v2再退到内存Map上限 50 个 scope。实时性事件流优先轮询兜底useFactoryAttention.ts 的注释揭示了刷新策略The stream announces every attention change; the poll only bridges the window where no stream is up.侧边栏徽标查询固定refetchInterval: 5_000ATTENTION_POLL_MS作为常驻安全网历史列表使用useInfiniteQuery当useFeedEventsConnected()显示事件流已连接时关闭轮询由 SSE 流FeedEventsProvider推送变更流断开时才回到 5 秒轮询staleTime: 2_000控制缓存新鲜度getNextPageParam: lastPage.nextCursor支撑无限滚动分页。测试策略单测隔离逻辑MSW 覆盖页面README 给出测试分层原则Use unit tests for isolated code and MSW tests for pages, routes, hooks, mutations, and React Query behavior.对应的四条命令pnpm --filter ./mastracode/factory-ui test:unit pnpm --filter ./mastracode/factory-ui test:msw pnpm --filter ./mastracode/factory-ui typecheck pnpm --filter ./mastracode/factory-ui build测试拓扑源自 AGENTS.md 与仓库目录层配置/入口覆盖对象约定单元测试根 vitest.config.ts 的unit:factory-uiproject纯函数、格式化如 date、无 UI 依赖的逻辑隔离运行不碰网络MSW 测试e2e/ui/vitest.config.ts 的msw:factory-uiproject配套 msw-server.ts 与 render.tsx页面、路由、hooks、mutations、React Query 行为用真实mastra/client-js MSW 拦截网络边界类型检查tsc --noEmit -p src/ui/tsconfig.json全量类型src/ui/tsconfig.json含 Playground UI 声明的类型解析 workaround构建Vite buildSPA 产物产物由 Mastra CLI 打包不在 web host 运行时使用关键约定AGENTS.md 原文只 mock 网络边界绝不 mock 自己的 hooks、services 或 auth gatingquery 链等待用waitForMutationsIdle。仓库中的 MSW 测试非常详尽与本文主题直接相关的有useFactoryAttention.msw.test.tsxattention 数据获取与失效useFactoryDecisions.msw.test.tsxuseFactoryDecisionActionretry/approve/dismiss 动作BoardPageIntakeFeedFailure.msw.test.tsx失败项在 Board 上的呈现BoardPageProposedRun.msw.test.tsx等待批准的建议运行BoardPageReReviewDonePr.msw.test.tsxReview 看板上的复查流AuditPage.msw.test.tsx审计时间线。e2e/ui/attention.ts 中还提供了构造attentionKindSummaries的测试工具函数按 kind 统计 open/unread/latest说明测试侧对 attention 数据模型有完整复刻。开发与协作约定目录布局保持src/src/ui的双层结构——它避免了 200 个互相引用reciprocal imports之间的变更抖动churn见 AGENTS.md领域边界策略、校验、持久化永远在mastra/factoryReact 层只做编排与展示构建产物归属本包的 build 产物被Mastra CLI 打包Produces the Factory SPA bundled by the Mastra CLI而不是 web host 在运行时使用环境要求engines.node 22.19.0见 package.json。小结MastraCode Factory UI 是一个边界清晰的 React SPA路由以/factories/:factoryId/**为骨架Needs attention 行动中心围绕canonical decision state 按用户收据的双层模型构建六种 attention 项、三视图、三分组、occurrence 递增与跨标签页提示音构成了完整的产品闭环测试侧则以单测隔离逻辑、MSW 覆盖交互、只 mock 网络边界为原则。掌握 README 中的启动命令与拆分重启方式、理解 attention 的对账与收据语义是深入这个前端代码库的两把钥匙。进一步探索可读 factory-ui/AGENTS.md 的测试规范、src/ui/router.tsx 的完整路由表以及 mastracode/factory/README.md 中mastra/factory的领域实现。【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考