feat(mesh-plugin-task-runner): Agent Status UI with real-time monitoring#2371
feat(mesh-plugin-task-runner): Agent Status UI with real-time monitoring#2371
Conversation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace Claude-centric content with actual MCP Mesh project description, architecture diagram, tech stack, and quick start guide. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…itoring - Add Agent Status component with Current/History tabs - Show running agents with tool calls and assistant messages - Display session duration and status updates - Add stale session cleanup on agent spawn - Separate In Progress and Open task sections - Make tasks/skills container scrollable - Read sessions from .beads/sessions.json via local-fs MCP
🧪 BenchmarkShould we run the Virtual MCP strategy benchmark for this PR? React with 👍 to run the benchmark.
Benchmark will run on the next push after you react. |
Release OptionsShould a new version be published when this PR is merged? React with an emoji to vote on the release type:
Current version: Deployment
|
There was a problem hiding this comment.
3 issues found across 35 files
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="apps/mesh/src/web/components/chat/context.tsx">
<violation number="1" location="apps/mesh/src/web/components/chat/context.tsx:814">
P2: The event handler calls sendMessage immediately after setVirtualMcpId, so the message metadata still uses the previous selectedVirtualMcp. This means messages dispatched with virtualMcpId can be sent under the wrong agent. Consider deferring sendMessage until the selection state updates or passing the desired MCP id directly into sendMessage for this path.</violation>
</file>
<file name="apps/mesh/e2e/connections.spec.ts">
<violation number="1" location="apps/mesh/e2e/connections.spec.ts:70">
P2: `page.screenshot` will throw if the `e2e/.auth` folder doesn’t exist. Create the directory (e.g., `fs.mkdir(..., { recursive: true })`) or use Playwright’s `testInfo.outputPath()` to ensure the path exists before writing the screenshot.</violation>
</file>
<file name="apps/mesh/e2e/global.setup.ts">
<violation number="1" location="apps/mesh/e2e/global.setup.ts:92">
P2: Create the `.auth` directory before calling `storageState`, otherwise the setup can fail with ENOENT when the folder doesn’t exist.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| const { text, virtualMcpId } = event.detail; | ||
|
|
||
| // Optionally select the virtual MCP before sending | ||
| if (virtualMcpId) { |
There was a problem hiding this comment.
P2: The event handler calls sendMessage immediately after setVirtualMcpId, so the message metadata still uses the previous selectedVirtualMcp. This means messages dispatched with virtualMcpId can be sent under the wrong agent. Consider deferring sendMessage until the selection state updates or passing the desired MCP id directly into sendMessage for this path.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/mesh/src/web/components/chat/context.tsx, line 814:
<comment>The event handler calls sendMessage immediately after setVirtualMcpId, so the message metadata still uses the previous selectedVirtualMcp. This means messages dispatched with virtualMcpId can be sent under the wrong agent. Consider deferring sendMessage until the selection state updates or passing the desired MCP id directly into sendMessage for this path.</comment>
<file context>
@@ -747,7 +796,44 @@ export function ChatProvider({ children }: PropsWithChildren) {
+ const { text, virtualMcpId } = event.detail;
+
+ // Optionally select the virtual MCP before sending
+ if (virtualMcpId) {
+ setVirtualMcpId(virtualMcpId);
+ }
</file context>
| expect(page.url()).not.toContain("/login"); | ||
|
|
||
| // Take a screenshot for debugging | ||
| await page.screenshot({ path: "e2e/.auth/org-home.png" }); |
There was a problem hiding this comment.
P2: page.screenshot will throw if the e2e/.auth folder doesn’t exist. Create the directory (e.g., fs.mkdir(..., { recursive: true })) or use Playwright’s testInfo.outputPath() to ensure the path exists before writing the screenshot.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/mesh/e2e/connections.spec.ts, line 70:
<comment>`page.screenshot` will throw if the `e2e/.auth` folder doesn’t exist. Create the directory (e.g., `fs.mkdir(..., { recursive: true })`) or use Playwright’s `testInfo.outputPath()` to ensure the path exists before writing the screenshot.</comment>
<file context>
@@ -0,0 +1,76 @@
+ expect(page.url()).not.toContain("/login");
+
+ // Take a screenshot for debugging
+ await page.screenshot({ path: "e2e/.auth/org-home.png" });
+
+ // The home page should show something - could be dashboard, connections, etc.
</file context>
| ); | ||
|
|
||
| // Save the storage state (cookies + localStorage) | ||
| await page.context().storageState({ path: authFile }); |
There was a problem hiding this comment.
P2: Create the .auth directory before calling storageState, otherwise the setup can fail with ENOENT when the folder doesn’t exist.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/mesh/e2e/global.setup.ts, line 92:
<comment>Create the `.auth` directory before calling `storageState`, otherwise the setup can fail with ENOENT when the folder doesn’t exist.</comment>
<file context>
@@ -0,0 +1,95 @@
+ );
+
+ // Save the storage state (cookies + localStorage)
+ await page.context().storageState({ path: authFile });
+
+ console.log(`Auth state saved to ${authFile}`);
</file context>
…ved UX - Add AI-powered task planning via chat with Task Runner Agent - Add polling for task updates while planning is in progress - Auto-expand plan view when plan arrives with toast notification - Add "Approve & Execute" button for streamlined workflow - Refactor task hooks to use read_file/write_file directly - Remove dependency on removed BEADS_INIT, TASK_* tools from local-fs - Add quality gates detection and management
…1769960270044-98r02z)
…g and explanation of what is this project we are building
…1769975661621-2d4s0i)
- Add isSpawning state to prevent double-clicks on Execute buttons - Disable Execute and Approve & Execute when agent is already running - Show "Starting..." and loading spinner while spawning - Hide Execute button when agent already running for task - Reset spawning state when agent starts running
- Add "Stop" button on running agent session cards - Sends stop request via chat to Task Runner Agent - Shows confirmation dialog before stopping - Shows "Stopping..." state while request is pending
There was a problem hiding this comment.
1 issue found across 2 files (changes from recent commits).
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="packages/mesh-plugin-task-runner/components/task-board.tsx">
<violation number="1" location="packages/mesh-plugin-task-runner/components/task-board.tsx:292">
P2: `isStopping` is set to true when Stop is clicked, but it is never reset. If the agent doesn’t stop or the request fails, the button stays disabled and the UI is stuck on “Stopping…”. Consider resetting `isStopping` when the session leaves the running state or after a timeout.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| if (isStopping) return; | ||
| if (!confirm(`Stop agent working on "${session.taskTitle}"?`)) return; | ||
|
|
||
| setIsStopping(true); |
There was a problem hiding this comment.
P2: isStopping is set to true when Stop is clicked, but it is never reset. If the agent doesn’t stop or the request fails, the button stays disabled and the UI is stuck on “Stopping…”. Consider resetting isStopping when the session leaves the running state or after a timeout.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/mesh-plugin-task-runner/components/task-board.tsx, line 292:
<comment>`isStopping` is set to true when Stop is clicked, but it is never reset. If the agent doesn’t stop or the request fails, the button stays disabled and the UI is stuck on “Stopping…”. Consider resetting `isStopping` when the session leaves the running state or after a timeout.</comment>
<file context>
@@ -281,10 +280,22 @@ function formatRelativeTime(timestamp: string): string {
+ if (isStopping) return;
+ if (!confirm(`Stop agent working on "${session.taskTitle}"?`)) return;
+
+ setIsStopping(true);
+ // Send a message to the Task Runner Agent to stop the session
+ const stopMessage = `Please stop agent session ${sessionId} immediately. Call AGENT_STOP with sessionId="${sessionId}".`;
</file context>
- Rename QUERY_KEYS to KEYS in task-runner plugin - Add agentSessionsBase and loopStatusLegacy query keys - Use cn() utility for className concatenation - Add oxlint-disable comments for legitimate useEffect uses - Pin tanstack router versions
- STACK.md - Technologies and dependencies - ARCHITECTURE.md - System design and patterns - STRUCTURE.md - Directory layout - CONVENTIONS.md - Code style and patterns - TESTING.md - Test structure - INTEGRATIONS.md - External services - CONCERNS.md - Technical debt and issues
Site Builder plugin - AI-assisted site building with live preview for Mesh
Mode: yolo Depth: standard Parallelization: enabled Workflow agents: research=on, plan_check=on, verifier=on
4-phase plan for Site Builder plugin: - Phase 1: Plugin foundation with site-aware connection filtering - Phase 2: Dev server control and live preview iframe - Phase 3: Task integration and skill bundling - Phase 4: Polish with streaming progress and budget controls Skills to incorporate from ../context/skills/: - decocms-landing-pages - deco-sales-pitch-pages Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 01: Site Builder Plugin Foundation - Standard stack identified (React 19, TanStack Router v1, TanStack Query v5) - Architecture patterns documented (plugin definition, bindings, routing) - Pitfalls catalogued (connection filtering, tool availability, type safety)
Phase 01: plugin-foundation - 2 plan(s) in 2 wave(s) - Wave 1: Plugin scaffold with binding, router, query keys - Wave 2: UI components with stack detection hook - Ready for execution Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add package.json with mesh-plugin-site-builder name - Configure dependencies matching task-runner plugin - Add tsconfig.json extending root config
- Create SITE_BUILDER_BINDING extending OBJECT_STORAGE_BINDING - Add query key factory with site-builder prefix - Define keys for site detection, workspace, dev server, and pages
- Add siteBuilderRouter with / and /$connectionId routes - Export siteBuilderPlugin implementing Plugin interface - Register Sites sidebar item with Globe01 icon - Add placeholder components for compilation - TypeScript compiles without errors
Tasks completed: 3/3 - Task 1: Create plugin package scaffold - Task 2: Create binding definition and query keys - Task 3: Create router and plugin entry point SUMMARY: .planning/phases/01-plugin-foundation/01-01-SUMMARY.md STATE: .planning/STATE.md created
- Created useSiteDetection hook that reads deno.json - Detects Deco sites via deco/ imports in import map - Uses TanStack Query for caching with 30s stale time - Returns isDeco flag, deco imports list, and error handling
- plugin-header.tsx: Connection dropdown with Deco/Deno detection badges - SiteBadge component shows green "Deco" badge for detected sites - Shows yellow "Deno" badge for deno.json without deco imports - plugin-empty-state.tsx: Helpful instructions on connecting sites - Includes tip about deno.json detection mechanism
- Add PreviewFrame component with iframe, device mode toggle, and controls - Clicking a page now opens inline preview instead of new tab - Add Preview Site button when dev server is running - Fix scroll on pages list by adding overflow-y-auto to container Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
3 issues found across 30 files (changes from recent commits).
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="packages/mesh-plugin-site-builder/components/preview-frame.tsx">
<violation number="1" location="packages/mesh-plugin-site-builder/components/preview-frame.tsx:40">
P2: Opening a new tab without `noopener`/`noreferrer` exposes the app to tabnabbing via `window.opener`. Add the noopener/noreferrer feature flags when opening external URLs.</violation>
</file>
<file name=".planning/codebase/STRUCTURE.md">
<violation number="1" location=".planning/codebase/STRUCTURE.md:8">
P3: Avoid hard-coded developer-specific absolute paths in docs; use a generic or repo-relative root path so the structure applies to all environments.</violation>
</file>
<file name="packages/mesh-plugin-site-builder/components/site-list.tsx">
<violation number="1" location="packages/mesh-plugin-site-builder/components/site-list.tsx:202">
P2: Hardcoding "localhost:8000" will misreport the actual dev server URL when it runs on a different host or port. Render the dynamic serverUrl instead.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| }; | ||
|
|
||
| const handleOpenExternal = () => { | ||
| window.open(url, "_blank"); |
There was a problem hiding this comment.
P2: Opening a new tab without noopener/noreferrer exposes the app to tabnabbing via window.opener. Add the noopener/noreferrer feature flags when opening external URLs.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/mesh-plugin-site-builder/components/preview-frame.tsx, line 40:
<comment>Opening a new tab without `noopener`/`noreferrer` exposes the app to tabnabbing via `window.opener`. Add the noopener/noreferrer feature flags when opening external URLs.</comment>
<file context>
@@ -0,0 +1,148 @@
+ };
+
+ const handleOpenExternal = () => {
+ window.open(url, "_blank");
+ };
+
</file context>
| <div className="flex items-center gap-2"> | ||
| <div className="w-2 h-2 rounded-full bg-green-500 animate-pulse" /> | ||
| <span className="text-sm font-medium text-green-700 dark:text-green-400"> | ||
| Running on localhost:8000 |
There was a problem hiding this comment.
P2: Hardcoding "localhost:8000" will misreport the actual dev server URL when it runs on a different host or port. Render the dynamic serverUrl instead.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/mesh-plugin-site-builder/components/site-list.tsx, line 202:
<comment>Hardcoding "localhost:8000" will misreport the actual dev server URL when it runs on a different host or port. Render the dynamic serverUrl instead.</comment>
<file context>
@@ -0,0 +1,314 @@
+ <div className="flex items-center gap-2">
+ <div className="w-2 h-2 rounded-full bg-green-500 animate-pulse" />
+ <span className="text-sm font-medium text-green-700 dark:text-green-400">
+ Running on localhost:8000
+ </span>
+ </div>
</file context>
| ## Directory Layout | ||
|
|
||
| ``` | ||
| /Users/guilherme/Projects/mesh/ |
There was a problem hiding this comment.
P3: Avoid hard-coded developer-specific absolute paths in docs; use a generic or repo-relative root path so the structure applies to all environments.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .planning/codebase/STRUCTURE.md, line 8:
<comment>Avoid hard-coded developer-specific absolute paths in docs; use a generic or repo-relative root path so the structure applies to all environments.</comment>
<file context>
@@ -0,0 +1,239 @@
+## Directory Layout
+
+```
+/Users/guilherme/Projects/mesh/
+├── apps/ # Applications
+│ ├── api/ # REST API app (deprecated, functionality moved to mesh)
</file context>
When an MCP server restarts, cached connections become stale and return "Server not initialized" errors. This fix: - Add isStaleConnectionError() to detect server restart scenarios - Add invalidate() method to client pool for removing stale clients - Auto-detect stale connections in client.onerror handler - Retry connection once in passthrough-client when stale error detected - Invalidate cache on stale errors to allow fresh connection on next request This eliminates the need to restart the Mesh dev server when MCP servers are restarted. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add TaskPanel component that shows tasks and agent sessions - Import task-runner hooks (useTasks, useAgentSessions, useSkills) - Add mesh-plugin-task-runner as dependency - Export hooks from task-runner package - Show task panel alongside preview frame when viewing site Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously the task panel was only visible when a preview was open. Now it's always visible when viewing a valid Deco site, allowing users to manage tasks without needing to open a preview first. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy skill documentation from context repo: - decocms-landing-pages: patterns for building Deco landing pages - deco-sales-pitch-pages: workflow for personalized sales pitches These markdown skills provide agent context for site building tasks. Also fix biome config to ignore unknown file types (markdown). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When running a task from the site-builder TaskPanel, now includes site context in the AGENT_SPAWN command: - isDeco: true for Deco sites - serverUrl: dev server URL if running - pages: list of available page paths - decoImports: Deco imports from deno.json This enables agents to use Deco-specific patterns and reference the skills/decocms-landing-pages documentation. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add .claude/ to gitignore (local Claude Code settings) - Fix stale closure in chat event listener (use refs) - Fix import paths to include .ts extension - Use cn() for conditional className Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The TaskPanel was using deco:open-chat with a message, but that event only opens the panel. Now correctly uses: 1. deco:open-chat to open the panel 2. deco:send-chat-message (after delay) to send the AGENT_SPAWN command Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Extract TaskCard with full Plan/Approve/Execute workflow from task-board - Export component via package.json for cross-plugin usage - Update site-builder task-panel to reuse TaskCard from task-runner - Remove unused useEffect import from task-board Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add QualityGatesBaseline type to track verification state - Add useQualityGatesBaseline, useVerifyQualityGates, useAcknowledgeQualityGates hooks - Update QualityGatesTab to show verification UI with pass/fail results - Block task creation until baseline is verified or failures acknowledged - When failures are acknowledged, agents will NOT try to fix pre-existing issues Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add extractTextContent helper that handles:
- Direct string responses
- { content: string } format
- { content: [{ type: 'text', text: string }] } MCP format
- { text: string } format
Fixes "Failed to detect: [object Object] is not valid JSON" error
when auto-detecting quality gates.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Try package.json first, then fall back to deno.json - Handle deno.json tasks (uses "deno task" runner) - Handle error responses from read_file (e.g., "Error: ENOENT...") - Gracefully handle missing config files Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sites tab (site management only): - Remove TaskPanel from Sites tab - Add "Create Page" button → navigates to Tasks with skill - Add "Use as Template" button on pages → navigates to Tasks - Add "Edit" button on pages → navigates to Tasks Tasks tab (task execution): - Add search params support (skill, template, edit, site) - Auto-open Add Task form when navigating with context - Pre-select skill and pre-fill title based on params Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update ROADMAP with Phase 5 complete - Update STATE to reflect 100% milestone completion - Add Phase 5 plan and summary Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
TanStack Router's navigate() doesn't work well for cross-plugin navigation. Use window.location.href instead for navigating from Sites to Tasks with query params. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…avigation
Use /{org}/task-runner/{connectionId} pattern instead of /tasks/{connectionId}.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace text instruction with a clear "Verify Quality Gates" button in the warning banner. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The QUALITY_GATES_VERIFY tool is on task-runner MCP, not available via toolCaller which connects to local-fs MCP. Use EXEC tool to run gate commands directly. - Read project-config.json for gates list - Run each gate command using EXEC - Write baseline back to project-config.json - Same fix applied to acknowledge hook Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Check success property first, then exitCode - Increase timeout to 2 minutes for type checks - Include error message in output Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove duplicate "Verification Results" section. Instead, show pass/fail status and output directly on each gate card with: - Icon changes to checkmark or alert based on result - Pass/Fail badge on the right - Expandable error output when failed Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ates When a quality gate fails, show a "Create Fix Task" button that: - Pre-fills task title with gate name - Pre-fills description with error output and instructions - Opens task creation form ready for submission The task description includes the full error output in a code block and prompts to create subtasks for each issue. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…immediately Instead of pre-filling a form, the "Fix with Agent" button now: - Creates the task with gate errors in description - Sends prompt to chat to start planning immediately - Switches to Tasks tab after completion This provides a smoother UX for fixing quality gate failures. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="packages/mesh-plugin-task-runner/components/task-board.tsx">
<violation number="1" location="packages/mesh-plugin-task-runner/components/task-board.tsx:808">
P2: The new task description textarea is gated on `newTaskDescription` already being non-empty, so users creating a normal task have no way to enter a description. Render the textarea unconditionally (or provide an explicit control to show it) so the feature is usable.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| {/* Description textarea - shown when there's pre-filled content or user wants to add */} | ||
| {newTaskDescription && ( | ||
| <textarea | ||
| value={newTaskDescription} | ||
| onChange={(e) => setNewTaskDescription(e.target.value)} | ||
| placeholder="Task description (optional)..." | ||
| className="w-full px-3 py-2 text-sm border border-border rounded-md bg-background min-h-[100px] font-mono" | ||
| rows={6} | ||
| /> | ||
| )} |
There was a problem hiding this comment.
P2: The new task description textarea is gated on newTaskDescription already being non-empty, so users creating a normal task have no way to enter a description. Render the textarea unconditionally (or provide an explicit control to show it) so the feature is usable.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/mesh-plugin-task-runner/components/task-board.tsx, line 808:
<comment>The new task description textarea is gated on `newTaskDescription` already being non-empty, so users creating a normal task have no way to enter a description. Render the textarea unconditionally (or provide an explicit control to show it) so the feature is usable.</comment>
<file context>
@@ -777,6 +805,17 @@ function TasksTabContent({
autoFocus
/>
+ {/* Description textarea - shown when there's pre-filled content or user wants to add */}
+ {newTaskDescription && (
+ <textarea
</file context>
| {/* Description textarea - shown when there's pre-filled content or user wants to add */} | |
| {newTaskDescription && ( | |
| <textarea | |
| value={newTaskDescription} | |
| onChange={(e) => setNewTaskDescription(e.target.value)} | |
| placeholder="Task description (optional)..." | |
| className="w-full px-3 py-2 text-sm border border-border rounded-md bg-background min-h-[100px] font-mono" | |
| rows={6} | |
| /> | |
| )} | |
| {/* Description textarea */} | |
| <textarea | |
| value={newTaskDescription} | |
| onChange={(e) => setNewTaskDescription(e.target.value)} | |
| placeholder="Task description (optional)..." | |
| className="w-full px-3 py-2 text-sm border border-border rounded-md bg-background min-h-[100px] font-mono" | |
| rows={6} | |
| /> |
…perly The "Fix with Agent" button now uses buildTaskPrompt with AGENT_SPAWN format instead of sending a regular chat message. This ensures: - Agent session is properly tracked in sessions.json - Agent Status UI updates to show running agent - Task is linked to the spawned agent session Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…wning Changed "Fix with Agent" to behave like the "Plan" button on task cards: - Creates the task - Sends planning prompt asking agent to analyze and create a plan - Agent calls TASK_SET_PLAN when done - User can then review and start execution This gives the same flow as manually creating a task and clicking Plan. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ith Agent" Track pending planning task IDs in parent state and pass to TaskCard: - Added pendingPlanningTaskIds state in TaskBoard - TaskCard accepts initialPlanningRequested prop - QualityGatesTabContent passes taskId to onFixTaskCreated callback - TasksTabContent passes pending state to TaskCard Now when you click "Fix with Agent", the task card shows "Planning..." spinner just like when clicking the Plan button directly. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Call onPlanningStateChange(taskId, false) when a plan is received to remove the task from the pending planning set. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
1 issue found across 2 files (changes from recent commits).
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="packages/mesh-plugin-task-runner/components/task-board.tsx">
<violation number="1" location="packages/mesh-plugin-task-runner/components/task-board.tsx:882">
P2: onPlanningComplete is never called because TaskCard doesn’t invoke onPlanningStateChange. Pending planning task IDs added in this PR won’t clear, so tasks can stay stuck in the “planning” state (and repeatedly toggle planning state once the plan arrives).</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| refetchTasks={refetch} | ||
| sendChatMessage={sendChatMessage} | ||
| initialPlanningRequested={pendingPlanningTaskIds?.has(task.id)} | ||
| onPlanningStateChange={(taskId, isPending) => { |
There was a problem hiding this comment.
P2: onPlanningComplete is never called because TaskCard doesn’t invoke onPlanningStateChange. Pending planning task IDs added in this PR won’t clear, so tasks can stay stuck in the “planning” state (and repeatedly toggle planning state once the plan arrives).
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/mesh-plugin-task-runner/components/task-board.tsx, line 882:
<comment>onPlanningComplete is never called because TaskCard doesn’t invoke onPlanningStateChange. Pending planning task IDs added in this PR won’t clear, so tasks can stay stuck in the “planning” state (and repeatedly toggle planning state once the plan arrives).</comment>
<file context>
@@ -874,6 +878,10 @@ function TasksTabContent({
refetchTasks={refetch}
sendChatMessage={sendChatMessage}
+ initialPlanningRequested={pendingPlanningTaskIds?.has(task.id)}
+ onPlanningStateChange={(taskId, isPending) => {
+ if (!isPending) onPlanningComplete?.(taskId);
+ }}
</file context>
Summary
.beads/sessions.jsonvia local-fs MCPChanges
task-board.tsx: New AgentStatus, AgentSessionCard components with tabsuse-tasks.ts: New hooks for reading agent sessions from filesystemquery-keys.ts: Added agentSessions keyTest Plan
Summary by cubic
Adds the Task Runner plugin with an Agent Status UI and real-time monitoring, and introduces a Site Builder plugin for site detection, dev server control, pages, and inline live preview. Connects Sites to Tasks via routing and search params, adds chat-driven task planning, quality gate baseline verification, stop controls, and fixes stale MCP connections with automatic retry.
New Features
Dependencies
Written for commit 63815dd. Summary will update on new commits.