Workboard 插件
Workboard 插件为 Control UI 添加一个可选的看板风格工作板:智能体级别的工作卡片、分配给智能体,以及返回卡片任务、运行和 Control UI 会话的链接。
Workboard 刻意保持轻量:它只跟踪一个 OpenClaw Gateway 的本地操作工作。它不是 GitHub Issues、Linear、Jira 或其他团队项目管理系统的替代品。
启用它¶
Workboard 已内置,但默认禁用:
- 在 Control UI 中打开 插件,或使用相对于已配置 Control UI 基础路径的
/plugins。例如,基础路径为/openclaw时使用/openclaw/plugins。 - 打开 Workboard 插件,选择 生命周期,并打开启用开关。由于 Workboard 随 OpenClaw 一起提供,因此不需要 安装 操作。
- 等待生命周期操作完成,然后打开 Workboard 选项卡。
插件运行时加载后,Workboard 选项卡会出现在 Control UI 导航中。禁用期间,该选项卡会从导航中隐藏。在插件被禁用或被 plugins.allow/plugins.deny 阻止时直接打开 /workboard 路由,会显示插件不可用状态,而不是卡片数据。
等效的 CLI 工作流如下:
启用会自动应用于正在运行的 Gateway。如果 Gateway 离线,请先启动它,再打开 dashboard。参见 应用更改并检查。
配置¶
Workboard 没有插件专属配置。使用标准插件条目启用/禁用它:
看板外观¶
使用 编辑看板 更改看板的名称、图标和颜色。保存时,重置为默认 会清除图标和颜色;取消则保持已保存的看板不变。
对于 workboard.boards.upsert,省略 icon 或 color、传入 null 或传入空字符串都会保留现有值,包括旧客户端。若要显式清除外观,请发送 clearAppearance: ["icon", "color"],或仅列出要清除的字段。即使请求同时为这些字段提供了替换值,列出的字段也会被清除。其他字段保持普通更新行为。clearAppearance 必须是仅包含 "icon" 和 "color" 的数组;空数组不会更改任何内容。使用此参数的客户端需要支持显式清除外观的 Gateway 版本;旧 Gateway 未实现此重置。
卡片字段¶
| 字段 | 值 |
|---|---|
status |
triage, backlog, todo, scheduled, ready, running, review, blocked, done |
priority |
low, normal, high, urgent |
labels |
自由格式字符串 |
agentId |
可选的已分配智能体 |
| 关联引用 | 可选任务、运行、会话或源 URL |
execution |
可选元数据,用于从卡片启动的 Codex/Claude 运行(引擎、模式、模型、会话、运行 ID、状态) |
卡片还携带紧凑元数据:
| 元数据 | 值 |
|---|---|
| 卡片状态 | 尝试次数、评论、链接、证明、产物、自动化设置、附件、工作进程日志、工作进程协议状态、认领、诊断、通知、模板 ID、归档状态、过期会话检测 |
| 最近事件 | created, edited, moved, linked, specified, decomposed, claimed, heartbeat, execution_updated, attempt_started, attempt_updated, comment_added, link_added, proof_added, artifact_added, attachment_added, diagnostic, notification, dispatch, orchestration, protocol_violation, archived, unarchived, stale |
此元数据可让操作员在不打开关联会话的情况下查看卡片在看板中的流转过程。它是本地操作上下文,不是会话记录或 GitHub issue 历史的替代品。
插件和 Control UI 使用同一个 Workboard 卡片契约。因此,Control UI 刷新会保留工作区来源和权限、认领状态、诊断操作以及通知序列号,而不是投影一个更小的仅用于 UI 的卡片副本。在两个界面都支持之前,未知的诊断类型、诊断严重级别和通知类型会被忽略。它们永远不会被重写为另一种有效状态。
打开的 Workboard 选项卡会根据 plugin.workboard.changed 失效事件更新。每个事件只包含存储纪元和修订号。随后,UI 会通过正常的 operator.read RPC 重新读取规范卡片。多个修订会合并为一次后续读取。当卡片正在被拖动、编辑或写入时,Workboard 会延迟该读取,并在本地交互结束后恢复。重新连接时始终执行规范重新加载。没有例行的全卡片轮询,刷新仍可作为手动恢复手段。
当存在多个看板时,工具栏会包含一个 看板 筛选器,它基于持久化的看板元数据,而不仅仅是当前可见的卡片。因此,空看板和已归档看板仍然可以选择。没有显式看板 id 的卡片属于规范的 default 看板。每个看板都有一个规范的 /workboard/<boardId> 页面,可以加入书签、共享或固定在侧边栏中。之前发布的 /workboard?board=<boardId> 形式仍保留为兼容性别名,并重定向到该页面,同时保留其他查询参数。选择 所有看板 会返回 /workboard。
看板可以存储一个 automationJobId 引用,指向拥有其 AI 分类提示词、模型、计划和运行历史的自动化作业。当该引用存在时,看板页面会显示一个 自动化 链接。匹配的会话事件会通过当前活动 Workboard 服务的调度器权限来触发所附自动化,包括在 worker 的工具权限关闭之后,同一看板的事件会在 60 秒内合并。自动化的计划仍然是兜底机制。已禁用和自动禁用的自动化永远不会被触发。删除看板不会删除或以其他方式修改由操作员拥有的自动化作业。
卡片存储在插件自身的 Gateway 状态中,并随该 Gateway 的其余 OpenClaw 状态一起迁移(参见 存储)。
从卡片开始工作¶
未链接且没有活动或未解决任务关联的卡片可以直接开始工作:
- 运行 Claude / 运行 OpenAI 会以显式引擎启动一个任务跟踪的代理运行,发送卡片提示词,并将卡片标记为
running。Claude 运行使用anthropic/claude-sonnet-4-6。OpenAI 运行使用openai/gpt-6-astra。 - 打开 Claude / 打开 OpenAI 会创建一个已链接的 Control UI 会话,但不发送卡片提示词,用于保持附着在看板上的手动工作。打开它会清除任何计划,并将
scheduled卡片移动到todo。其他卡片保持其状态。
自主启动使用 Gateway 的任务跟踪代理运行路径(除非显式选择 Claude/OpenAI,否则使用默认代理和模型)。Workboard 随后会将生成的运行 id 和会话密钥链接回卡片。每个已链接的执行还会记录一次尝试摘要(引擎、模式、模型、运行 id、时间戳、状态、滚动失败计数),以便重复失败保持可见。
Control UI 从卡片的已链接会话读取生命周期。卡片状态更改由 Gateway 侧 Workboard 插件使用已链接的运行和会话生命周期进行持久化(参见 会话生命周期同步)。
代理工具¶
| 工具 | 用途 |
|---|---|
workboard_list |
列出带有认领/诊断状态的紧凑卡片;可选看板筛选。 |
workboard_read |
返回一张卡片以及受限的 worker 上下文(笔记、尝试、评论、链接、证明、工件、父级结果、最近负责人工作、活动诊断)。 |
workboard_create |
创建一张卡片,可选父级、租户、技能、看板、工作区元数据、幂等键、运行时限制、重试预算。 |
workboard_link |
将父级链接到子卡片。子卡片保持 todo,直到所有父级达到 done,然后分派提升将它们移动到 ready。 |
workboard_claim |
为调用代理认领一张卡片;将 backlog/todo/ready 移动到 running。 |
workboard_heartbeat |
在较长运行期间刷新认领心跳。 |
workboard_release |
在完成、暂停或交接后释放认领;可以将卡片移动到下一个状态。 |
workboard_complete / workboard_block |
用于最终摘要、证明、工件和已创建卡片清单(必须引用链接回已完成卡片的卡片)或阻塞原因的结构性生命周期工具。 |
workboard_attachment_add / workboard_attachment_read / workboard_attachment_delete |
在插件 SQLite 状态中存储小型卡片附件,在卡片上建立索引,并在 worker 上下文中暴露。 |
| 工具 | 用途 |
|---|---|
workboard_worker_log / workboard_protocol_violation |
记录工作者日志行,并在自动工作者停止而未调用 workboard_complete/workboard_block 时阻止卡片。 |
workboard_board_create / workboard_board_archive / workboard_board_delete |
管理持久化的看板元数据(显示名称、描述、归档状态、默认工作区)。 |
workboard_runs |
返回卡片的持久化运行尝试历史。 |
workboard_specify |
将粗略的分诊/待办卡片转换为澄清后的 todo 卡片;在卡片上记录规格摘要。 |
workboard_decompose |
将父级编排卡片展开为关联的子卡片,继承看板/租户元数据;可使用已创建卡片清单完成父卡片。 |
workboard_notify_subscribe / workboard_notify_list / workboard_notify_events / workboard_notify_advance / workboard_notify_unsubscribe |
管理通知订阅。事件读取支持安全重放;advance 移动持久游标,使调用方能够恢复,而不会丢失或重复读取已完成/失败/过期的卡片事件。 |
workboard_boards / workboard_stats |
检查看板命名空间和队列统计。 |
workboard_promote / workboard_reassign / workboard_reclaim |
恢复或交接卡住的工作。 |
workboard_comment / workboard_proof |
添加交接备注或附加证明/工件引用。 |
workboard_unblock |
将受阻工作移回 todo。 |
workboard_move |
将卡片移动到另一个状态;已认领卡片要求调用方具有 agent 认领范围。 |
workboard_dispatch |
在不启动工作者的情况下推动依赖提升或过期认领清理;工作者启动使用 Gateway 或斜杠命令调度。 |
证明状态是工作者报告的结果,而非独立验证。passed
条目表示工作者报告其命令或检查成功。需要独立质量门禁的消费者应检查所附命令、URL 或工件,并运行自己的验证器。workboard_proof 返回新记录的 proofId。当
workboard_complete 报告同一证明的终态状态时,传入 proofId,以便待定记录就地解决,而不会丢失其标识或时间戳。已经具有相同终态状态的证明会被原样复用。没有
proofId 的完成证明保持仅追加,因此稍后的重试不会仅因为其命令或备注相同就重写较旧的历史。
已认领卡片会拒绝来自其他 agent 的 agent 工具变更,除非调用方持有 workboard_claim 返回的认领令牌。每个由 agent 工具或 Gateway RPC 调用返回的卡片都会将 metadata.claim.token 脱敏为 [redacted](令牌本身仅从 workboard_claim 以顶层形式返回一次),因此 Control UI 操作员和其他 agent 可以检查认领状态,而无需看到可用令牌。恢复通过 workboard_promote/workboard_reassign/workboard_reclaim 进行,这些操作不需要令牌。
调度¶
调度是 Gateway 本地的:它不会生成任意 OS 进程。正常的 OpenClaw 子 agent 会话仍拥有执行权。一次调度遍历:
- 提升依赖就绪的卡片。
- 阻止过期声明或超时运行。
- 将看板配置的分诊卡片标记为编排候选。
- 认领一小批就绪卡片,并通过 Gateway 子代理运行时启动工作器运行。
空闲扫描不会改变就绪卡片的历史记录。现有的调度计数器和时间戳仍作为历史值保留;新启动会使用卡片的启动、尝试和执行历史。
工作器会获得有界的卡片上下文,以及通过 Workboard 工具对卡片进行心跳、完成或阻塞所需的声明令牌。
工作区路径遵循调用者现有的文件系统权限:
- 具有
operator.write的 Gateway 客户端可以使用已配置的代理工作区。 operator.admin客户端可以使用其他主机检出。- 沙箱化代理工具使用其沙箱工作区访问权限。
- 非沙箱的仅工作区工具使用其配置的工作区根目录。
Workboard 在分配工作区时记录该权限,并在调度时再次与当前调用者的权限求交集,因此已持久化的卡片无法扩大后续调用者的访问范围。对于具有显式主机工作区但未记录权限的旧卡片,必须在完整主机调度之前重新保存该工作区。没有主机路径的卡片在首次调度时采用当前调用者的权限。
工作区绑定调度仅接受目录或 Git 检出,且其仓库根目录必须与目标代理工作区完全匹配。worktree 请求会被缩小到该目录,并作为目录工作区持久化,因此主机不会物化检出或执行仓库设置代码。目标工作器必须针对该确切工作区使用可写的、非共享的 Docker 沙箱,且没有提升的执行权限、持久化的 host/node exec 覆盖或未分类的插件和 MCP 工具。Workboard 会枚举其已注册的工具,而不是信任 workboard_* 前缀,并且调度会拒绝实时挂载/配置哈希过期的热 Docker 容器。调度会报告不兼容的目标策略,而不是启动限制更少的工作器。完整主机调度可以指向其他本地检出,并保留正常的受管 worktree 设置。
工作区权限不会创建第二套卡片生命周期权限模型。可以变更 Workboard 卡片的调用者可以在所有界面上手动将它们移动到相同的状态。只读工作区访问仅阻止需要写入的工作器调度。
工作器选择¶
每轮默认最多启动 3 个工作器。就绪卡片按优先级、然后位置、然后创建时间排序。每轮每个所有者/代理只启动一张卡片,并跳过在看板上已有运行中或审查中工作的所有者。已归档卡片、具有活动声明的卡片以及状态不是 ready 的卡片永远不会被选择用于启动工作器(它们仍可能受调度数据侧影响:过期声明清理、依赖提升、超时清理)。
会话键按看板/卡片确定,因此重复调度会路由回同一工作器通道,而不是创建无关会话:
- 已分配卡片:
agent:<agentId>:subagent:workboard-<boardId>-<cardId> - 未分配卡片:
subagent:workboard-<boardId>-<cardId>(Gateway 解析已配置的默认代理)
如果卡片被认领后无法启动工作器,Workboard 会阻塞该卡片、清除声明、记录运行启动失败,并追加一行工作器日志——可在控制 UI、CLI JSON、代理工具和卡片诊断中看到。
入口点¶
- 控制 UI 调度操作
openclaw workboard dispatch- 在支持命令的通道上执行
/workboard dispatch
当 Gateway 可用时,三者都使用 Gateway 子代理运行时。CLI 有一个操作员回退机制:如果 Gateway 调用因连接/不可用错误失败(或旧 Gateway 出现 unknown method 错误),并且没有显式的 --url/--token 目标,也没有配置远程 Gateway(OPENCLAW_GATEWAY_URL 或 gateway.mode: remote),则 CLI 针对本地 SQLite 状态运行仅数据调度——它可以提升依赖、清理过期声明并阻塞超时运行,但不能启动工作器。来自可访问 Gateway 的身份验证、权限和验证失败不会被视为不可用。它们会显示为命令错误;当提供了显式 --url/--token 目标时,任何 Gateway 失败也会显示为命令错误。
看板元数据可以设置 autoDecompose、autoDecomposePerDispatch、defaultAssignee 和 orchestratorProfile。OpenClaw 会记录此意图,并将其暴露在工作器上下文中。实际的规格/分解仍通过常规 Workboard 工具运行。
CLI 和斜杠命令¶
openclaw workboard list [--board <id>] [--status <status>] [--include-archived] [--json]
openclaw workboard create "Fix stale card lifecycle" --priority high --labels bug,workboard
openclaw workboard show <card-id> [--json]
openclaw workboard move <card-id> --status <status> [--json]
openclaw workboard dispatch [--board <id>] [--json]
list 文本输出默认隐藏已归档卡片(--include-archived 可覆盖)。--json 始终包含已归档卡片,与现有脚本使用的完整卡片契约一致。show 和 move 接受无歧义的 id 前缀。list、create、show 和 move 始终直接读取/写入本地插件状态。只有 dispatch 会调用正在运行的 Gateway,并带有上述回退机制。
有关完整标志、JSON 输出、Gateway 回退行为、id 前缀处理、调度选择规则和故障排除,请参阅 Workboard CLI。
/workboard list、/workboard show <card-id>、/workboard create <title>、/workboard move <card-id> --status <status> 和 /workboard dispatch 与 CLI 对应。列表和显示是任何已授权命令发送者的读取操作。创建、移动和调度在聊天界面上需要所有者状态,或具有 operator.write/operator.admin 的 Gateway 客户端。手动操作员移动使用与控制 UI 拖放相同的声明覆盖行为。它们的 worktree 访问仍遵循上述相同的工作区边界。
会话生命周期同步¶
卡片可以链接到现有的 Control UI 会话,或者在你从卡片开始工作时创建的会话。已链接的卡片会内联显示会话生命周期:运行中、过期、已链接空闲、完成或失败。你还可以通过其页眉或 Sessions 标签页中的 添加到 Workboard 捕获现有会话。该卡片会链接到该会话,使用会话标签或最近的用户提示作为标题,并在可用时从最近的用户提示以及最新的助手响应中填充笔记。
捕获操作在开始时保持目标看板处于选中状态。在复用卡片之前,它会重新加载非活动看板的卡片,恢复已归档的精确匹配项,并且从不根据临时链接推断会话所有权。
已捕获的会话会显示 打开 Workboard 卡片 和一个已链接卡片标签。两者使用相同的卡片状态,包括浏览器重新加载后。在当前代理筛选之外打开卡片时,看板会切换到 所有代理,但不会更改所选的聊天代理。
打开卡片时,会独立于侧边栏的代理筛选和分页加载其链接会话详情。在详情加载或不可用时,卡片会保留其链接并显示 会话状态未知 或 会话不可用。不明确的临时链接会显示 会话链接不明确。编辑卡片以选择精确会话。使用 刷新 重试。若要继续现有会话,请在 编辑卡片 中选择其精确链接,然后选择 打开会话。若要重新开始,请在 编辑卡片 中清除链接。清除链接会保留其任务关联,因此当该任务处于活动或未解决状态时,开始 仍不可用。更改卡片的负责人不会更改其现有会话的所有者。
裸 global 和 unknown 链接无法标识会话所有者。打开时,它们会显示 会话链接不明确。使用 编辑卡片 选择显式会话。Workboard 不会为新的捕获或链接提供这些裸链接。
如果活动的已链接会话停止报告最近活动,Workboard 会将卡片标记为 stale,并将其作为元数据存储,直到生命周期清除它。
生命周期写入由 Gateway 端的 Workboard 插件负责,因此不依赖于打开的浏览器标签页。代理和子代理完成钩子会立即持久化最终结果。有界的会话扫描每分钟运行一次,以协调活动、空闲、缺失和过期会话状态。每次存储变更都会发出常规的 plugin.workboard.changed 失效通知,因此打开的 Workboard 标签页会重新加载规范卡片,而不是写入自己的生命周期投影。
当卡片处于活动工作状态时,Workboard 会跟随已链接的会话:
| 已链接会话状态 | 卡片状态 |
|---|---|
| 活动 | running |
| 已完成 | review |
| 失败、被终止、超时或中止 | blocked |
手动审查状态优先。 将卡片移动到 review、blocked 或 done 会停止该卡片的自动同步,直到你将其移回 todo 或 running。
启动卡片使用常规 Gateway 会话。Workboard 仅存储卡片元数据和链接。对话记录、模型选择和运行生命周期仍由常规会话系统负责。在活动的已链接卡片上使用 停止 可中止当前运行 - Workboard 会将该卡片标记为 blocked,以便其保持可见以供后续处理。
新卡片可以从 Workboard 模板(bugfix、docs、release、pr_review、plugin)开始。模板会预填标题、笔记、标签和优先级。模板 id 会作为卡片元数据存储。
控制 UI 工作流¶
- 在 Control UI 中打开 Workboard 标签页。
- 创建一张卡片,包含标题、笔记、优先级、标签、可选代理和可选链接会话 - 或打开 Sessions 并选择 添加到 Workboard 以处理现有会话。
- 在列之间拖动卡片,或聚焦其紧凑状态控件并使用菜单或 ArrowLeft/ArrowRight。拖动期间,源卡片会变暗,可用的放置列会获得轮廓。
- 当未链接卡片没有活动或未解决的任务关联时,启动该卡片。
- 在代理工作时,从卡片打开已链接的会话。
- 让生命周期同步将运行中的工作移动到
review/blocked,然后在接受后手动将卡片移动到done。
会话看板组件¶
Workboard 为会话仪表板提供三个原生组件(参见 仪表板)。代理使用其 dashboard 工具,通过 content: { kind: "plugin", pluginKind, props } 固定它们,它们作为第一方 UI 渲染并带有实时数据 — 无需沙箱框架或能力授权:
workboard:card配合props: { cardId }显示一张卡片,包含其状态控件、优先级和已分配代理。workboard:board配合可选的props: { boardId }显示完整的看板,包含可拖动卡片和状态控件。没有boardId时显示所有看板。有boardId时仅显示该看板。workboard:mini配合可选的props: { boardId, limit }显示按状态统计的数量,以及顶部就绪/运行中卡片,并链接到完整看板页面。没有boardId时聚合所有看板。有boardId时限定到该看板(未显式指定看板 id 创建的卡片位于default)。
诊断¶
诊断基于本地卡片元数据计算。内置检查会标记:
| 类型 | 条件 |
|---|---|
stranded_ready |
已分配的 todo/backlog/ready 卡片超过 1 小时未更新。 |
running_without_heartbeat |
running 卡片超过 20 分钟没有认领心跳或执行更新。 |
blocked_too_long |
blocked 卡片超过 24 小时未更新。 |
repeated_failures |
卡片跟踪的失败次数达到 2 次或更多。 |
| 类型 | 条件 |
|---|---|
missing_proof |
没有证明、产物或附件的 done 卡片。 |
orphaned_session |
有 sessionKey 但没有 execution 元数据的 running 卡片。 |
archived_but_active |
已归档卡片仍处于任何非 done 生命周期状态。 |
权限¶
网关 RPC 方法位于 workboard.* 下:
| 范围 | 方法 |
|---|---|
operator.read |
cards.list, cards.export, cards.diagnostics, attachment list/get, notification event reads, boards.list, cards.stats, cards.runs |
operator.write |
cards.diagnostics.refresh, create/captureSession/update/move/delete/comment/link/linkDependency/proof/artifact, attachment add/delete, worker log, protocol violation, claim/heartbeat/release/promote/reassign/reclaim/complete/block/unblock/start, cards.dispatch, cards.bulk, archive, boards.upsert/archive/delete, cards.specify/decompose, notification subscribe/delete/advance |
workboard.cards.update、workboard.cards.move、workboard.cards.archive 和
workboard.cards.delete 接受可选的 expectedUpdatedAt 请求字段。
传入从所读卡片获取的有限数值 updatedAt,以保护写入操作。
如果卡片已发生变化,请求将以 workboard_conflict 失败,并在
error.details.card 中返回其最新卡片(error.details.type 为
workboard_card_conflict)。重试前请检查该卡片。省略该字段
将保留该方法现有的无保护请求行为。
Control UI 批量操作使用每张卡片观察到的修订版本,并在发生冲突时停止。 剩余卡片保持选中状态以供检查和重试;该批次不会静默地 针对较新的修订版本重试,也不会覆盖其他客户端的更改。
没有任何 RPC 方法需要 operator.admin。以只读
operator 访问权限连接的浏览器可以查看看板,但不能修改卡片。admin 范围
会扩大接受的 Workboard 主机路径。它不会改变可用方法。
存储¶
Workboard 将持久数据存储在 OpenClaw 状态目录下的插件拥有的关系型 SQLite 数据库中:看板、卡片、标签、生命周期事件、 运行尝试、评论、依赖链接、证明、产物引用、 附件元数据和 blob、诊断、通知、worker 日志、 协议状态以及订阅均位于 Workboard 表中(而不是 插件键值条目)。卡片导出会保留看板叙述, 而不会内联附件 blob 内容。
SQLite 的打开、查询和事务在后台数据库 worker 中运行。 禁用或重新加载插件时,会在关闭 其连接之前排空已接受的存储工作。
在 .28 版本中使用过 Workboard 的安装可以运行
openclaw doctor --fix,将随附的旧版插件状态命名空间
(workboard.cards、workboard.boards、workboard.notify,以及如果存在,
workboard.attachments)迁移到关系型数据库。
故障排查¶
选项卡显示 Workboard 不可用
如果配置了 plugins.allow,请将 workboard 添加到其中。如果 plugins.deny
包含 workboard,请在启用插件之前将其移除。
卡片无法保存
确认浏览器连接具有 operator.write 访问权限。只读 operator
会话可以列出卡片,但不能创建、编辑、移动或删除它们。
启动卡片未打开预期会话
检查卡片的 agent id 和关联会话,然后打开 Sessions 或 Chat 以 检查实际运行状态。
分发未启动 worker
确认至少有一张没有活动认领的 ready 卡片:
如果 CLI 报告仅数据分发,请启动或重启 Gateway 并 重试 - 仅数据分发只会更新本地看板状态,但无法启动 subagent worker 运行。当同一 owner 或 agent 的另一张卡片 已在运行或等待审核时,卡片也可能被跳过。请先完成、 阻止或释放该活动工作,再为同一 owner 分发更多任务。
相关¶
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw