mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-16 23:41:35 +00:00
* feat(ui): add plugin catalog management * feat(gateway): add plugins.uninstall and richer plugin catalog metadata Adds a plugins.uninstall gateway method (operator.admin, control-plane write) backed by a lock-guarded uninstallManagedPlugin that mirrors the CLI flow: config cleanup, install-record removal, managed file deletion, and registry refresh. Bundled plugins stay disable-only. Catalog entries now carry a manifest-derived category and a removable flag; ClawHub search results expose download counts and verification tiers. * feat(ui): redesign plugins page with inventory, store shelves, and cover art Rebuilds /settings/plugins around three tabs: Installed (category-grouped inventory with overview stats, state filters, uninstall for external plugins, and inline MCP server management through the shared config seam), Discover (featured/official shelves plus one-click MCP connectors and curated ClawHub searches), and ClawHub (search with download counts and verification badges). Every catalog entry renders bundled cover art or a deterministic gradient monogram tile - no more empty boxes. Artwork generated with Codex CLI, shipped as 512px WebP under ui/public/plugin-art. * chore(ui): regenerate locale bundles for plugins manager strings * docs: describe plugins manager tabs, uninstall, and MCP connectors * fix(plugins): human catalog labels and un-pinned hosted fallback ids listManagedPlugins now prefers manifest names over registry package-name backfill, falls back to channel catalog labels and blurbs, and stops pinning expectedPluginId when a hosted feed entry only exposes its package name (which rejected every legitimate install of that package). Found via live gateway testing against ClawHub. * fix(ui): send minimal RFC 7396 merge patches for MCP server edits config.patch merges rather than replaces, so key removal needs an explicit null; sending the full config back made MCP server removal a no-op. Found via live gateway testing. * fix(ui): write explicit MCP transports for URL servers The MCP runtime defaults URL-only servers to SSE, so streamable HTTP endpoints saved by the add form or connector templates would fail at connect time. Connector templates now declare their transport and the add form infers streamable-http unless the URL follows the /sse convention. Flagged by autoreview against the transport resolver. * test(ui): wait for deferred plugin requests before resolving in e2e * feat(ui): plugins detail view, action menus, and unified ClawHub search Reworks the plugins page from PR #103176 feedback: merges the ClawHub tab into Discover (typing searches ClawHub inline and appends a quiet From ClawHub section, with Browse ClawHub demoted to a header text link), makes every row and store card open a plugin detail overlay (hero art, primary enable/install action, metadata table), and replaces enable/disable switches with a state chip plus an overflow menu (Enable/Disable, Remove for external plugins, View details) matching the ChatGPT-store install+menu pattern. MCP rows use the same menu; refresh is now icon-only. * chore(ui): regenerate locale bundles for plugins UI iteration * feat(ui): vetted, grouped connector catalog for the plugins store Expands Connect your world to 28 connectors organized into use-case shelves (Work & productivity, Coding & infrastructure, Home & media, Everyday life). Every entry passed a three-stage subagent review: official-docs verification plus live endpoint probes for MCP servers, ClawHub result-quality and malware/typosquat screening for curated searches, and an adversarial pass that dynamically registered OAuth clients to prove one-click viability. That review removed Figma (registration allowlisted, 403) and Atlassian (OAuth issuer-mismatch bug upstream), downgraded GitHub to PAT-based setup (no dynamic client registration upstream), fixed Linear (/sse retired) and Home Assistant (/api/mcp, streamable HTTP) endpoints, retargeted poisoned or dead searches (youtube, finance, hue dropped; calendar -> google calendar; stocks replaces finance), and added Todoist, Airtable, Canva, Stripe, Context7, DeepWiki, Hugging Face one-click MCP servers plus Jira, PDF, transcription, Kubernetes, Reddit, maps, translation, and notes searches. Keyless servers get a ready-to-use success message; new cover art included. * chore(ui): regenerate locale bundles for connector groups * fix(plugins): suppress hosted catalog rows once their package is installed Hosted feed entries without a declared runtime id fall back to their package name as catalog id, which never matches the installed runtime id, so the Discover shelf kept offering an already-installed package. Installed package names now also suppress official rows. Flagged by autoreview. * fix(plugins): pin declared runtime ids and surface connector errors in place The runtime-id pin now keys off explicitly declared catalog ids (plugin, channel, or provider) instead of string-comparing against the package name, so declared ids that equal their package name stay enforced while entry-id fallbacks stay unpinned. Connector add failures on Discover now render on the triggering card instead of the Installed tab's MCP section. Both flagged by autoreview; regression tests included. * feat(ui): full inventory artwork, pulse header, and two-column plugin list Every bundled plugin now ships distinctive cover art (113 new Codex CLI illustrations; 172 total, ~2.1MB WebP), so inventory rows and detail views never fall back to monogram tiles. The four stat cards give way to a compact inventory pulse: a segmented enabled/disabled/issues meter whose legend and counts live inside the filter chips. Inventory, MCP, and search rows flow into two columns when the panel is wide enough. * chore(ui): regenerate locale bundles for pulse header * fix(ui): omit stdio args from the MCP server row target Stdio MCP args routinely carry tokens, and the inventory is visible to read-only operators; mirror the config page and show only the command. Flagged by autoreview; regression test included. * fix(merge): point crestodian setup at relocated plugin commit/refresh modules * fix(merge): add bootstrapToken to plugins page test gateway harness * fix(plugins): name catalog install-action branches so Swift emits the union * fix(ui): satisfy strict lint on plugins page form parsing and mocks * chore(build): regen docs map, raise plugin-sdk declaration budget for new protocol surface * fix(ui): type the plugins page patch mock with its real call signature
365 lines
24 KiB
Markdown
365 lines
24 KiB
Markdown
---
|
|
summary: "Optional dashboard workboard for agent-owned cards and session handoff"
|
|
read_when:
|
|
- You want a Kanban-style workboard in the Control UI
|
|
- You are enabling or disabling the bundled Workboard plugin
|
|
- You want to track planned agent work without an external project manager
|
|
title: "Workboard plugin"
|
|
---
|
|
|
|
The Workboard plugin adds an optional Kanban-style board to the
|
|
[Control UI](/web/control-ui): agent-sized work cards, assignment to agents,
|
|
and a link back to the card's task, run, and dashboard session.
|
|
|
|
Workboard is intentionally small: it tracks local operating work for one
|
|
OpenClaw Gateway. It is not a replacement for GitHub Issues, Linear, Jira, or
|
|
other team project management systems.
|
|
|
|
## Enable it
|
|
|
|
Workboard is bundled but disabled by default:
|
|
|
|
1. Open **Plugins** in the Control UI, or use `/settings/plugins` relative to
|
|
the configured Control UI base path. For example, a base path of `/openclaw`
|
|
uses `/openclaw/settings/plugins`.
|
|
2. Find **Workboard** and choose **Enable**. Because Workboard is included with
|
|
OpenClaw, it does not need an **Install** action.
|
|
3. If the UI reports that a restart is required, restart the Gateway.
|
|
|
|
The Workboard tab appears in the dashboard nav after the plugin runtime loads.
|
|
While it is disabled, the tab stays hidden from navigation. Opening the
|
|
`/workboard` route directly while the plugin is disabled or blocked by
|
|
`plugins.allow`/`plugins.deny` shows a plugin-unavailable state instead of card
|
|
data.
|
|
|
|
The equivalent CLI workflow is:
|
|
|
|
```bash
|
|
openclaw plugins enable workboard
|
|
openclaw gateway restart
|
|
openclaw dashboard
|
|
```
|
|
|
|
## Configuration
|
|
|
|
Workboard has no plugin-specific config. Enable/disable it with the standard
|
|
plugin entry:
|
|
|
|
```json5
|
|
{
|
|
plugins: {
|
|
entries: {
|
|
workboard: {
|
|
enabled: true,
|
|
config: {},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
```bash
|
|
openclaw plugins disable workboard
|
|
openclaw gateway restart
|
|
```
|
|
|
|
## Card fields
|
|
|
|
| Field | Values |
|
|
| ----------- | ------------------------------------------------------------------------------------------------------------- |
|
|
| `status` | `triage`, `backlog`, `todo`, `scheduled`, `ready`, `running`, `review`, `blocked`, `done` |
|
|
| `priority` | `low`, `normal`, `high`, `urgent` |
|
|
| `labels` | free-form strings |
|
|
| `agentId` | optional assigned agent |
|
|
| linked refs | optional task, run, session, or source URL |
|
|
| `execution` | optional metadata for a Codex/Claude run started from the card (engine, mode, model, session, run id, status) |
|
|
|
|
Cards also carry compact metadata for attempts, comments, links, proof,
|
|
artifacts, automation settings, attachments, worker logs, worker protocol
|
|
state, claims, diagnostics, notifications, template id, archive state, and
|
|
stale-session detection, plus a recent-events list (`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`). This metadata lets an
|
|
operator see how a card moved through the board without opening the linked
|
|
session; it is local operating context, not a replacement for session
|
|
transcripts or GitHub issue history.
|
|
|
|
Cards are stored in the plugin's own Gateway state and move with the rest of
|
|
that Gateway's OpenClaw state (see [Storage](#storage)).
|
|
|
|
## Starting work from a card
|
|
|
|
Unlinked cards can start work directly:
|
|
|
|
- **Run Codex** / **Run Claude** starts a task-tracked agent run with an
|
|
explicit engine, sends the card prompt, and marks the card `running`. Codex
|
|
runs use `openai/gpt-5.5`; Claude runs use `anthropic/claude-sonnet-4-6`.
|
|
- **Open Codex** / **Open Claude** creates a linked dashboard session without
|
|
sending the card prompt or moving the card, for manual work that stays
|
|
attached to the board.
|
|
|
|
Autonomous starts use the Gateway's task-tracked agent run path (default agent
|
|
and model unless Codex/Claude is chosen explicitly); Workboard then links the
|
|
resulting task, run id, and session key back onto the card. Each linked
|
|
execution also records an attempt summary (engine, mode, model, run id,
|
|
timestamps, status, rolling failure count) so repeated failures stay visible.
|
|
|
|
The dashboard refreshes task status from the Gateway task ledger, matching
|
|
tasks to cards by task id, run id, or linked session key. A queued/running
|
|
task keeps the card's lifecycle active; a finished, failed, timed-out, or
|
|
cancelled task moves the card toward `review` or `blocked` using the same sync
|
|
rule as linked sessions (see [Session lifecycle sync](#session-lifecycle-sync)).
|
|
|
|
## Agent tools
|
|
|
|
| Tool | Purpose |
|
|
| ------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| `workboard_list` | List compact cards with claim/diagnostic state; optional board filter. |
|
|
| `workboard_read` | Return one card plus bounded worker context (notes, attempts, comments, links, proof, artifacts, parent results, recent assignee work, active diagnostics). |
|
|
| `workboard_create` | Create a card with optional parents, tenant, skills, board, workspace metadata, idempotency key, runtime limit, retry budget. |
|
|
| `workboard_link` | Link a parent to a child card. Children stay `todo` until every parent reaches `done`, then dispatch promotion moves them to `ready`. |
|
|
| `workboard_claim` | Claim a card for the calling agent; moves `backlog`/`todo`/`ready` into `running`. |
|
|
| `workboard_heartbeat` | Refresh the claim heartbeat during a longer run. |
|
|
| `workboard_release` | Release the claim after completion, pause, or handoff; can move the card to a next status. |
|
|
| `workboard_complete` / `workboard_block` | Structured lifecycle tools for final summaries, proof, artifacts, and created-card manifests (must reference cards linked back to the completed card) or blocker reasons. |
|
|
| `workboard_attachment_add` / `workboard_attachment_read` / `workboard_attachment_delete` | Store small card attachments in plugin SQLite state, index on the card, expose in worker context. |
|
|
| `workboard_worker_log` / `workboard_protocol_violation` | Record worker log lines and block a card when an automated worker stops without calling `workboard_complete`/`workboard_block`. |
|
|
| `workboard_board_create` / `workboard_board_archive` / `workboard_board_delete` | Manage persisted board metadata (display name, description, archive state, default workspace). |
|
|
| `workboard_runs` | Return the persisted run-attempt history for a card. |
|
|
| `workboard_specify` | Turn a rough triage/backlog card into a clarified `todo` card; records the spec summary on the card. |
|
|
| `workboard_decompose` | Fan a parent orchestration card into linked children, inheriting board/tenant metadata; can complete the parent with a created-card manifest. |
|
|
| `workboard_notify_subscribe` / `workboard_notify_list` / `workboard_notify_events` / `workboard_notify_advance` / `workboard_notify_unsubscribe` | Manage notification subscriptions. Event reads are replay-safe; `advance` moves the durable cursor so callers resume without losing or double-reading completed/failed/stale card events. |
|
|
| `workboard_boards` / `workboard_stats` | Inspect board namespaces and queue stats. |
|
|
| `workboard_promote` / `workboard_reassign` / `workboard_reclaim` | Recover or hand off stuck work. |
|
|
| `workboard_comment` / `workboard_proof` | Add handoff notes or attach proof/artifact references. |
|
|
| `workboard_unblock` | Move blocked work back to `todo`. |
|
|
| `workboard_dispatch` | Nudge dependency promotion or stale-claim cleanup. |
|
|
|
|
Claimed cards reject agent-tool mutations from other agents unless the caller
|
|
holds the claim token returned by `workboard_claim`. Every card returned by an
|
|
agent tool or Gateway RPC call redacts `metadata.claim.token` to `[redacted]`
|
|
(the token itself is returned once, top-level, only from `workboard_claim`),
|
|
so dashboard operators and other agents can inspect claim state without ever
|
|
seeing a usable token. Recovery goes through
|
|
`workboard_promote`/`workboard_reassign`/`workboard_reclaim`, which do not
|
|
require the token.
|
|
|
|
## Dispatch
|
|
|
|
Dispatch is Gateway-local: it does not spawn arbitrary OS processes. Normal
|
|
OpenClaw subagent sessions still own execution. One dispatch pass:
|
|
|
|
1. Promotes dependency-ready cards.
|
|
2. Records dispatch metadata on ready cards.
|
|
3. Blocks expired claims or timed-out runs.
|
|
4. Marks board-configured triage cards as orchestration candidates.
|
|
5. Claims a small batch of ready cards and starts worker runs through the
|
|
Gateway subagent runtime.
|
|
|
|
Workers get bounded card context plus the claim token needed to heartbeat,
|
|
complete, or block the card through the Workboard tools.
|
|
|
|
### Worker selection
|
|
|
|
Each pass starts **at most 3 workers by default**. Ready cards are ordered by
|
|
priority, then position, then creation time. A pass starts only one card per
|
|
owner/agent and skips owners that already have running or review work on the
|
|
board. Archived cards, cards with an active claim, and cards not in `ready`
|
|
status are never selected for worker starts (they can still be affected by the
|
|
data side of dispatch: stale-claim cleanup, dependency promotion, timeout
|
|
cleanup).
|
|
|
|
Session keys are deterministic per board/card, so repeated dispatches route
|
|
back to the same worker lane instead of creating unrelated sessions:
|
|
|
|
- Assigned cards: `agent:<agentId>:subagent:workboard-<boardId>-<cardId>`
|
|
- Unassigned cards: `subagent:workboard-<boardId>-<cardId>` (Gateway resolves
|
|
the configured default agent)
|
|
|
|
If a worker cannot be started after a card is claimed, Workboard blocks the
|
|
card, clears the claim, records the run-start failure, and appends a worker
|
|
log line - visible in the dashboard, CLI JSON, agent tools, and card
|
|
diagnostics.
|
|
|
|
### Entry points
|
|
|
|
- Dashboard dispatch action
|
|
- `openclaw workboard dispatch`
|
|
- `/workboard dispatch` on a command-capable channel
|
|
|
|
All three use the Gateway subagent runtime when the Gateway is available. The
|
|
CLI has one operator fallback: if the Gateway call fails with a
|
|
connection/unavailable error (or an `unknown method` error for older
|
|
Gateways), and no explicit `--url`/`--token` target and no configured remote
|
|
Gateway (`OPENCLAW_GATEWAY_URL` or `gateway.mode: remote`) apply, the CLI runs
|
|
data-only dispatch against local SQLite state - it can promote dependencies,
|
|
clean stale claims, and block timed-out runs, but cannot start workers. Auth,
|
|
permission, and validation failures from a reachable Gateway are not treated
|
|
as unavailable; they surface as command errors, and so does any Gateway
|
|
failure when an explicit `--url`/`--token` target was given.
|
|
|
|
Board metadata can set `autoDecompose`, `autoDecomposePerDispatch`,
|
|
`defaultAssignee`, and `orchestratorProfile`. OpenClaw records this intent and
|
|
exposes it in worker context; actual specification/decomposition still runs
|
|
through the normal Workboard tools.
|
|
|
|
## CLI and slash command
|
|
|
|
```bash
|
|
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 dispatch [--board <id>] [--json]
|
|
```
|
|
|
|
`list` text output hides archived cards by default (`--include-archived`
|
|
overrides); `--json` always includes archived cards, matching the full-card
|
|
contract used by existing scripts. `show` accepts an unambiguous id prefix.
|
|
`list`, `create`, and `show` always read/write local plugin state directly.
|
|
Only `dispatch` calls the running Gateway, with the fallback described above.
|
|
|
|
See [Workboard CLI](/cli/workboard) for full flags, JSON output, Gateway
|
|
fallback behavior, id-prefix handling, dispatch selection rules, and
|
|
troubleshooting.
|
|
|
|
`/workboard list`, `/workboard show <card-id>`, `/workboard create <title>`,
|
|
and `/workboard dispatch` mirror the CLI. List and show are read operations
|
|
for any authorized command sender. Create and dispatch require owner status on
|
|
chat surfaces, or a Gateway client with `operator.write`/`operator.admin`.
|
|
|
|
## Session lifecycle sync
|
|
|
|
Cards can link to an existing dashboard session, or one created when you
|
|
start work from the card. Linked cards show the session lifecycle inline:
|
|
running, stale, linked idle, done, failed, or missing. You can also capture an
|
|
existing session from the Sessions tab with **Add to Workboard**; the card
|
|
links to that session, uses the session label or recent user prompt as title,
|
|
and seeds notes from the recent user prompt plus the latest assistant response
|
|
when available.
|
|
|
|
If the linked session goes missing, the card stays linked for context and
|
|
still offers start controls to restart into a fresh session. If an active
|
|
linked session stops reporting recent activity, Workboard marks the card
|
|
`stale` and stores that as metadata until the lifecycle clears it.
|
|
|
|
While a card is in an active work state, Workboard follows the linked session:
|
|
|
|
| Linked session state | Card status |
|
|
| ------------------------------------- | ----------- |
|
|
| active | `running` |
|
|
| completed | `review` |
|
|
| failed, killed, timed out, or aborted | `blocked` |
|
|
|
|
**Manual review states win.** Moving a card to `review`, `blocked`, or `done`
|
|
stops auto-sync for that card until you move it back to `todo` or `running`.
|
|
|
|
Starting a card uses normal Gateway sessions; Workboard only stores card
|
|
metadata and links. Conversation transcript, model selection, and run
|
|
lifecycle stay owned by the regular session system. Use **Stop** on a live
|
|
linked card to abort the active run - Workboard marks that card `blocked` so
|
|
it stays visible for follow-up.
|
|
|
|
New cards can start from Workboard templates (`bugfix`, `docs`, `release`,
|
|
`pr_review`, `plugin`). Templates prefill title, notes, labels, and priority;
|
|
the template id is stored as card metadata.
|
|
|
|
## Dashboard workflow
|
|
|
|
1. Open the Workboard tab in the Control UI.
|
|
2. Create a card with a title, notes, priority, labels, optional agent, and
|
|
optional linked session - or open Sessions and choose **Add to Workboard**
|
|
for an existing session.
|
|
3. Drag the card between columns, or focus its compact status control and use
|
|
the menu or ArrowLeft/ArrowRight.
|
|
4. Start work from the card to create or reuse a dashboard session.
|
|
5. Open the linked session from the card while the agent works.
|
|
6. Let lifecycle sync move running work into `review`/`blocked`, then manually
|
|
move the card to `done` when accepted.
|
|
|
|
## Diagnostics
|
|
|
|
Diagnostics are computed from local card metadata. Built-in checks flag:
|
|
|
|
| Kind | Condition |
|
|
| --------------------------- | ------------------------------------------------------------------------------ |
|
|
| `stranded_ready` | Assigned `todo`/`backlog`/`ready` card not updated in over 1 hour. |
|
|
| `running_without_heartbeat` | `running` card with no claim heartbeat or execution update in over 20 minutes. |
|
|
| `blocked_too_long` | `blocked` card not updated in over 24 hours. |
|
|
| `repeated_failures` | Card's tracked failure count reaches 2 or more. |
|
|
| `missing_proof` | `done` card with no proof, artifacts, or attachments. |
|
|
| `orphaned_session` | `running` card with a `sessionKey` but no `execution` metadata. |
|
|
|
|
## Permissions
|
|
|
|
Gateway RPC methods live under `workboard.*`:
|
|
|
|
| Scope | Methods |
|
|
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| `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/update/move/delete/comment/link/linkDependency/proof/artifact, attachment add/delete, worker log, protocol violation, claim/heartbeat/release/promote/reassign/reclaim/complete/block/unblock, `cards.dispatch`, `cards.bulk`, archive, `boards.upsert`/`archive`/`delete`, `cards.specify`/`decompose`, notification subscribe/delete/advance |
|
|
|
|
No RPC method requires `operator.admin`. Browsers connected with read-only
|
|
operator access can inspect the board but cannot mutate cards.
|
|
|
|
## Storage
|
|
|
|
Workboard stores durable data in a plugin-owned relational SQLite database
|
|
under the OpenClaw state directory: boards, cards, labels, lifecycle events,
|
|
run attempts, comments, dependency links, proof, artifact references,
|
|
attachment metadata and blobs, diagnostics, notifications, worker logs,
|
|
protocol state, and subscriptions all live in Workboard tables (not
|
|
plugin key-value entries). A card export preserves the board narrative
|
|
without inlining attachment blob contents.
|
|
|
|
Installations that used Workboard in the `.28` release can run
|
|
`openclaw doctor --fix` to migrate the shipped legacy plugin-state namespaces
|
|
(`workboard.cards`, `workboard.boards`, `workboard.notify`, and, if present,
|
|
`workboard.attachments`) into the relational database.
|
|
|
|
## Troubleshooting
|
|
|
|
**The tab says Workboard is unavailable**
|
|
|
|
```bash
|
|
openclaw plugins inspect workboard --runtime --json
|
|
```
|
|
|
|
If `plugins.allow` is configured, add `workboard` to it. If `plugins.deny`
|
|
contains `workboard`, remove it before enabling the plugin.
|
|
|
|
**Cards do not save**
|
|
|
|
Confirm the browser connection has `operator.write` access. Read-only operator
|
|
sessions can list cards but cannot create, edit, move, or delete them.
|
|
|
|
**Starting a card does not open the expected session**
|
|
|
|
Check the card's agent id and linked session, then open Sessions or Chat to
|
|
inspect the actual run state.
|
|
|
|
**Dispatch does not start a worker**
|
|
|
|
Confirm there is at least one `ready` card without an active claim:
|
|
|
|
```bash
|
|
openclaw workboard list --status ready
|
|
```
|
|
|
|
If the CLI reports data-only dispatch, start or restart the Gateway and
|
|
retry - data-only dispatch updates local board state but cannot start
|
|
subagent worker runs. Cards can also be skipped when another card for the
|
|
same owner or agent is already running or waiting for review; complete,
|
|
block, or release that active work before dispatching more for the same
|
|
owner.
|
|
|
|
## Related
|
|
|
|
- [Control UI](/web/control-ui)
|
|
- [Workboard CLI](/cli/workboard)
|
|
- [Plugins](/tools/plugin)
|
|
- [Manage plugins](/plugins/manage-plugins)
|
|
- [Sessions](/concepts/session)
|