|
1 | 1 | import { Api } from "coder/site/src/api/api"
|
2 |
| -import { Workspace, WorkspaceAgent, WorkspaceAgentTask } from "coder/site/src/api/typesGenerated" |
| 2 | +import { Workspace, WorkspaceAgent } from "coder/site/src/api/typesGenerated" |
3 | 3 | import { EventSource } from "eventsource"
|
4 | 4 | import * as path from "path"
|
5 | 5 | import * as vscode from "vscode"
|
@@ -155,14 +155,26 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
|
155 | 155 | showMetadata,
|
156 | 156 | )
|
157 | 157 |
|
158 |
| - // Fetch AI tasks for the workspace |
| 158 | + // Get app status from the workspace agents |
159 | 159 | try {
|
160 |
| - // Create a dummy emitter for logs |
161 |
| - const _emitter = new vscode.EventEmitter<string>() |
| 160 | + const agents = extractAgents(workspace) |
| 161 | + agents.forEach((agent) => { |
| 162 | + // Check if agent has apps property with status reporting |
| 163 | + if (agent.apps && Array.isArray(agent.apps)) { |
| 164 | + workspaceTreeItem.appStatus = agent.apps.map((app) => ({ |
| 165 | + name: app.display_name || app.name || "App", |
| 166 | + status: app.status || "Running", |
| 167 | + icon: app.icon || "$(pulse)", |
| 168 | + url: app.url, |
| 169 | + agent_id: agent.id, |
| 170 | + agent_name: agent.name, |
| 171 | + })) |
| 172 | + } |
| 173 | + }) |
162 | 174 | } catch (error) {
|
163 |
| - // Log the error but continue - we don't want to fail the whole tree if AI tasks fail |
| 175 | + // Log the error but continue - we don't want to fail the whole tree if app status fails |
164 | 176 | this.storage.writeToCoderOutputChannel(
|
165 |
| - `Failed to fetch AI tasks for workspace ${workspace.name}: ${errToStr(error, "unknown error")}`, |
| 177 | + `Failed to get app status for workspace ${workspace.name}: ${errToStr(error, "unknown error")}`, |
166 | 178 | )
|
167 | 179 | }
|
168 | 180 |
|
@@ -239,13 +251,24 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
|
239 | 251 |
|
240 | 252 | const items: vscode.TreeItem[] = []
|
241 | 253 |
|
242 |
| - // Add AI tasks section with collapsible header |
243 |
| - if (element.agent.tasks.length > 0) { |
244 |
| - const aiTasksSection = new SectionTreeItem( |
245 |
| - "AI Tasks", |
246 |
| - element.agent.tasks.map((task) => new AITaskTreeItem(task)), |
| 254 | + // Add app status section with collapsible header |
| 255 | + if (element.agent.apps && element.agent.apps.length > 0) { |
| 256 | + let needsAttention = [] |
| 257 | + for (const app of element.agent.apps) { |
| 258 | + if (app.statuses && app.statuses.length > 0) { |
| 259 | + for (const status of app.statuses) { |
| 260 | + if (status.needs_user_attention) { |
| 261 | + needsAttention.push(new AppStatusTreeItem(status)) |
| 262 | + } |
| 263 | + } |
| 264 | + } |
| 265 | + } |
| 266 | + |
| 267 | + const appStatusSection = new SectionTreeItem( |
| 268 | + "Applications in need of attention", |
| 269 | + needsAttention, |
247 | 270 | )
|
248 |
| - items.push(aiTasksSection) |
| 271 | + items.push(appStatusSection) |
249 | 272 | }
|
250 | 273 |
|
251 | 274 | const savedMetadata = watcher?.metadata || []
|
@@ -346,18 +369,27 @@ class AgentMetadataTreeItem extends vscode.TreeItem {
|
346 | 369 | }
|
347 | 370 | }
|
348 | 371 |
|
349 |
| -class AITaskTreeItem extends vscode.TreeItem { |
350 |
| - constructor(public readonly task: WorkspaceAgentTask) { |
351 |
| - // Add a hand raise emoji (✋) to indicate tasks awaiting user input |
352 |
| - super(task.icon, vscode.TreeItemCollapsibleState.None) |
353 |
| - this.description = task.summary |
354 |
| - this.contextValue = "coderAITask" |
| 372 | +class AppStatusTreeItem extends vscode.TreeItem { |
| 373 | + constructor( |
| 374 | + public readonly app: { |
| 375 | + name?: string |
| 376 | + display_name?: string |
| 377 | + status?: string |
| 378 | + icon?: string |
| 379 | + url?: string |
| 380 | + agent_id?: string |
| 381 | + agent_name?: string |
| 382 | + }, |
| 383 | + ) { |
| 384 | + super(app.icon || "$(pulse)", vscode.TreeItemCollapsibleState.None) |
| 385 | + this.description = app.status || "Running" |
| 386 | + this.contextValue = "coderAppStatus" |
355 | 387 |
|
356 |
| - // Add command to handle clicking on the task |
| 388 | + // Add command to handle clicking on the app |
357 | 389 | this.command = {
|
358 |
| - command: "coder.openAITask", |
359 |
| - title: "Open AI Task", |
360 |
| - arguments: [task], |
| 390 | + command: "coder.openAppStatus", |
| 391 | + title: "Open App Status", |
| 392 | + arguments: [app], |
361 | 393 | }
|
362 | 394 | }
|
363 | 395 | }
|
@@ -409,14 +441,15 @@ class AgentTreeItem extends OpenableTreeItem {
|
409 | 441 | "coderAgent",
|
410 | 442 | )
|
411 | 443 |
|
412 |
| - if (agent.task_waiting_for_user_input) { |
413 |
| - this.label = "🙋 " + this.label |
| 444 | + if (agent.apps && agent.apps.length > 0) { |
| 445 | + // Add an icon to indicate this agent has running apps |
| 446 | + this.label = "🖐️ " + this.label |
414 | 447 | }
|
415 | 448 | }
|
416 | 449 | }
|
417 | 450 |
|
418 | 451 | export class WorkspaceTreeItem extends OpenableTreeItem {
|
419 |
| - public aiTasks: { waiting: boolean; tasks: WorkspaceAgentTask[] }[] = [] |
| 452 | + public appStatus: { name: string; status: string; icon?: string }[] = [] |
420 | 453 |
|
421 | 454 | constructor(
|
422 | 455 | public readonly workspace: Workspace,
|
|
0 commit comments