Fix: child tasks only from spec/breakdown agents; live review badge

Two fixes from real usage:
- Child-task creation is now gated to story-producing skills (spec-writing,
  story-breakdown). A code/design/test agent's output is the artifact — a numbered list
  in it (e.g. file names from an engineer) is no longer mistaken for child stories.
- The review-inbox badge now updates without a refresh: it polls more often (6s),
  refetches on window focus, and reacts to a REVIEWS_CHANGED event the board fires after
  Run (with a couple of delayed pulses to catch the ~5s completion) and the review page
  fires after approve / send back.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-16 22:22:57 +03:30
parent 9993ebb2b4
commit 1f562fd633
4 changed files with 35 additions and 7 deletions
+8 -3
View File
@@ -10,7 +10,7 @@ import {
} from '@dnd-kit/core'
import { Bot, Plus, Trash2 } from 'lucide-react'
import { toast } from 'sonner'
import { AppShell } from '@/components/AppShell'
import { AppShell, REVIEWS_CHANGED } from '@/components/AppShell'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import {
@@ -514,8 +514,13 @@ function TaskDrawer({
onClick={() =>
act(
() => api.post('/api/assembler/runs', { seatId, workItemId: task.id }),
'Dispatched — the proposal will land in the review inbox.',
)
'Dispatched — it will appear in the review inbox shortly.',
).then(() => {
// The proposal lands ~a few seconds later; nudge the review badge to refetch.
window.dispatchEvent(new Event(REVIEWS_CHANGED))
setTimeout(() => window.dispatchEvent(new Event(REVIEWS_CHANGED)), 4000)
setTimeout(() => window.dispatchEvent(new Event(REVIEWS_CHANGED)), 9000)
})
}
>
<Bot data-icon="inline-start" />
+2
View File
@@ -8,6 +8,7 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Label } from '@/components/ui/label'
import { Skeleton } from '@/components/ui/skeleton'
import { Textarea } from '@/components/ui/textarea'
import { REVIEWS_CHANGED } from '@/components/AppShell'
import { AgentFace } from '@/components/AgentFace'
import { MarkdownEditor } from '@/components/MarkdownEditor'
import { api } from '@/lib/api'
@@ -169,6 +170,7 @@ function ReviewCard({ item, onDecided }: { item: ReviewItem; onDecided: (id: str
toast.info('Sent back to the agent')
}
onDecided(item.id)
window.dispatchEvent(new Event(REVIEWS_CHANGED))
} catch (err) {
toast.error((err as Error).message)
} finally {