Skip to content

Stream startup logs (workspace build and agent startup scripts) in task detail view #793

@EhabY

Description

@EhabY

Summary

When a task's workspace is building or its agent is initializing, the task detail view shows "Logs not available in current task state." Similar to the Coder dashboard UI, we should stream the build and agent startup logs and display them in-place.

Current Behavior

In src/webviews/tasks/tasksPanel.ts, handleGetTaskDetails fetches task logs via getTaskLogs. When the workspace is in a building/initializing state, the server returns empty logs ({ logs: [] }).

Desired Behavior

When a task is in pending or initializing status, instead of showing "Logs not available", the extension should:

  1. Stream workspace build logs — using the existing watchBuildLogsByBuildId WebSocket API (/api/v2/workspacebuilds/{buildId}/logs?follow=true) during the provisioning phase.
  2. Stream agent startup script logs — using the existing watchWorkspaceAgentLogs WebSocket API (/api/v2/workspaceagents/{agentId}/logs?follow=true) once the agent is connecting/starting.
  3. Push logs to the webview in real-time via the already-defined (but unused) TasksApi.logsAppend notification.

Reference Implementation (Coder Dashboard)

The Coder web UI (site/src/pages/TaskPage/TaskPage.tsx) handles this with two components:

  • BuildingWorkspace — shown when workspace.latest_build.status is starting or pending. Uses the useWorkspaceBuildLogs(workspace.latest_build.id) hook to stream provisioner job logs via WebSocket, rendering them in a <WorkspaceBuildLogs> component with auto-scroll.
  • TaskStartingAgent — shown when the agent lifecycle_state is created or starting. Uses useAgentLogs({ agentId: agent.id }) to stream agent startup script logs, rendered via <AgentLogs> with auto-scroll.

Both show a progress indicator and auto-scroll as new log lines arrive.

Implementation Plan

1. Backend: TasksPanel log streaming (src/webviews/tasks/tasksPanel.ts)

The TasksPanel class needs to:

  • Track active WebSocket connections for build/agent log streaming (similar to how WorkspaceStateMachine manages buildLogSocket and agentLogSocket).
  • When handleGetTaskDetails detects a task in pending/initializing status:
    • Look up the workspace via the task's workspace_id to get latest_build.id and agent info.
    • Open a WebSocket to watchBuildLogsByBuildId (build logs) or watchWorkspaceAgentLogs (agent logs) as appropriate.
    • Forward incoming log messages to the webview via the existing TasksApi.logsAppend notification.
  • Clean up WebSocket connections when the task transitions to a stable state (active, paused, error) or when a different task is selected.

Key consideration: The CoderApi class already has watchBuildLogsByBuildId and watchWorkspaceAgentLogs methods that return UnidirectionalStream objects, so no new API methods are needed.

2. Determine task phase for log type

The task status alone doesn't tell us whether we're in the build phase or agent startup phase. We need to inspect the workspace status:

Workspace Status Agent Status Log Source
pending, starting N/A Build logs (watchBuildLogsByBuildId)
running created, connecting, starting Agent logs (watchWorkspaceAgentLogs)
running connected (lifecycle: ready) Task app logs (existing behavior)

This means handleGetTaskDetails needs access to the workspace object. Currently it only fetches the task — it will need to also fetch the workspace when the task status is pending or initializing.

3. Webview: Render streamed logs (packages/tasks/)

The webview needs:

  • A new state for "building/initializing" that shows streamed logs instead of the static "not available" message.
  • Subscribe to TasksApi.logsAppend notifications and append incoming log entries to a growing list.
  • Auto-scroll to the latest log entry as new lines arrive. (Similar to AgentChatHistory
  • Reuse the same CSS styles already used for the AgentChatHistory log display.
  • Optionally, show a progress indicator (the existing VscodeProgressRing works) with contextual text like "Building workspace..." or "Running startup scripts...".

4. Lifecycle management

  • Only one streaming connection should be active at a time per task.
  • When the user switches to a different task's details, close the previous stream.
  • When the task transitions from initializingactive, close the stream and switch to the normal task logs view.
  • On TasksPanel.dispose(), clean up any active streaming connections.

5. Tests (test/unit/webviews/tasks/tasksPanel.test.ts)

  • Mock watchBuildLogsByBuildId and watchWorkspaceAgentLogs to emit simulated log entries.
  • Verify that logsAppend notifications are sent to the webview during building/initializing states.
  • Verify cleanup when task transitions to active.
  • The TasksPanelClient mock type will need getWorkspace, watchBuildLogsByBuildId, and watchWorkspaceAgentLogs added.

Files to Modify

File Change
src/webviews/tasks/tasksPanel.ts Add streaming logic, WebSocket lifecycle management
packages/shared/src/tasks/types.ts Possibly extend LogsStatus with "streaming" or add a startup phase type
packages/shared/src/tasks/api.ts Possibly add a new notification for startup phase
packages/tasks/src/App.tsx or new component Render streamed startup logs in the webview
packages/tasks/src/components/ New component(s) for build/agent log display
packages/tasks/src/hooks/useTasksApi.ts Hook up logsAppend listener
test/unit/webviews/tasks/tasksPanel.test.ts New test cases for streaming behavior

Created on behalf of @EhabY

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions