diff --git a/packages/cli-workflow/src/commands/serve/routes-live.ts b/packages/cli-workflow/src/commands/serve/routes-live.ts index 47bb134..4fbc5b5 100644 --- a/packages/cli-workflow/src/commands/serve/routes-live.ts +++ b/packages/cli-workflow/src/commands/serve/routes-live.ts @@ -1,4 +1,4 @@ -import { statSync, watch } from "node:fs"; +import { existsSync, statSync, watch } from "node:fs"; import { join } from "node:path"; import { createCasStore, getContentMerklePayload } from "@uncaged/workflow-cas"; import { @@ -307,6 +307,12 @@ export function createLiveRoutes(storageRoot: string): Hono { return; } + // If thread is not actively running, emit all records and close — don't keep SSE open + const runningPath = join(storageRoot, "logs", threadTarget.bundleHash, `${threadId}.running`); + if (!existsSync(runningPath)) { + return; + } + const controller = new AbortController(); let completed = false; diff --git a/packages/workflow-dashboard/src/components/thread-detail.tsx b/packages/workflow-dashboard/src/components/thread-detail.tsx index cb3f516..4127759 100644 --- a/packages/workflow-dashboard/src/components/thread-detail.tsx +++ b/packages/workflow-dashboard/src/components/thread-detail.tsx @@ -80,7 +80,7 @@ export function ThreadDetail({ agent, threadId, onBack }: Props) {

{threadId} - {sse.connected && ( + {sse.connected && !sse.completed && (