feat: board-first orchestration with Gateway Bridge, live-update, and flow-board
- GatewayBridgeController: MCP-artiger Kommando-Adapter für Agent-zu-Backend - TaskBridgeService + LiveUpdateService: SSE Live-Sync + Bridge-Kommandos - FlowBoard.vue: Board-first orchestration dashboard panel - live-sync.ts store + live.ts service: SSE-basierte Live-Updates - Nullability-Warnung in HealthController.cs gefixt - nginx.conf: SSE-Proxy + CORS für Bridge-Endpunkte - .gitignore: pnpm/corepack local caches ausgeschlossen - docs: architecture-board-first-orchestration.md hinzugefügt - README: Backend Bridge API dokumentiert
This commit is contained in:
@@ -12,11 +12,13 @@
|
||||
*
|
||||
* Polling startet bei Mount, stoppt bei Unmount.
|
||||
*/
|
||||
import { onMounted, onUnmounted } from 'vue'
|
||||
import { computed, onMounted, onUnmounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useAgentStore } from '../../stores/agents'
|
||||
import { useChatStore } from '../../stores/chat'
|
||||
import { useDashboardStore } from '../../stores/dashboard'
|
||||
import { useTaskStore } from '../../stores/tasks'
|
||||
import { useLiveSyncStore } from '../../stores/live-sync'
|
||||
import AlertBar from '../../components/dashboard/v2/AlertBar.vue'
|
||||
import FlowCanvas from '../../components/dashboard/v2/FlowCanvas.vue'
|
||||
import IrisChat from '../../components/dashboard/v2/IrisChat.vue'
|
||||
@@ -29,6 +31,8 @@ const agentStore = useAgentStore()
|
||||
const chatStore = useChatStore()
|
||||
const dashboardStore = useDashboardStore()
|
||||
const taskStore = useTaskStore()
|
||||
const liveSyncStore = useLiveSyncStore()
|
||||
const router = useRouter()
|
||||
|
||||
const {
|
||||
addAgent,
|
||||
@@ -42,18 +46,21 @@ const {
|
||||
updatePositions,
|
||||
} = useFlowBoardState(agentStore, chatStore)
|
||||
|
||||
const blockedTasks = computed(() => taskStore.taskList.filter(task => task.status === 'blocked'))
|
||||
|
||||
function handleBlockerClick() {
|
||||
console.log('[FlowBoard] blocker clicked')
|
||||
if (!blockedTasks.value.length) return
|
||||
router.push('/tasks')
|
||||
}
|
||||
|
||||
function blockerLabel() {
|
||||
const blockedTask = taskStore.taskList.find(task => task.status === 'blocked')
|
||||
const blockedTask = blockedTasks.value[0]
|
||||
if (!blockedTask) return undefined
|
||||
return `${taskStore.taskList.filter(task => task.status === 'blocked').length} Blocker — ${blockedTask.title}`
|
||||
return `${blockedTasks.value.length} Blocker — ${blockedTask.title}`
|
||||
}
|
||||
|
||||
function blockerCount() {
|
||||
return taskStore.taskList.filter(task => task.status === 'blocked').length
|
||||
return blockedTasks.value.length
|
||||
}
|
||||
|
||||
/* ── Lifecycle ────────────────────────────────────── */
|
||||
@@ -62,6 +69,8 @@ onMounted(() => {
|
||||
chatStore.startPolling()
|
||||
dashboardStore.startPolling()
|
||||
taskStore.startPolling()
|
||||
taskStore.startBoardPolling()
|
||||
liveSyncStore.connect()
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
@@ -69,6 +78,8 @@ onUnmounted(() => {
|
||||
chatStore.stopPolling()
|
||||
dashboardStore.stopPolling()
|
||||
taskStore.stopPolling()
|
||||
taskStore.stopBoardPolling()
|
||||
liveSyncStore.disconnect()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user