Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Bcpeinhardt/ai agent session in vscode#488

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
bcpeinhardt merged 30 commits intomainfrombcpeinhardt/ai-agent-session-in-vscode
Apr 22, 2025
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
30 commits
Select commitHold shift + click to select a range
bfa33eb
update deps to kyles branch and make helper for getting agent informa…
bcpeinhardtMar 18, 2025
92c3bfd
agents in sidebar
bcpeinhardtMar 18, 2025
c5f6dcb
janky working demo for meeting
bcpeinhardtMar 18, 2025
b2f6bb8
clean up some horrible claude code
bcpeinhardtMar 18, 2025
c7001d5
separate metadata and tasks
bcpeinhardtMar 18, 2025
f39f458
tweaks to terminal sizing
bcpeinhardtMar 19, 2025
c31cb7c
put coder dep back on main post merge of ai work
bcpeinhardtMar 31, 2025
063b27e
statuses updates
bcpeinhardtApr 1, 2025
be1e137
coder ssh strategy finally working
bcpeinhardtApr 1, 2025
08c93ae
show apps in need of attention only when there are some to show
bcpeinhardtApr 1, 2025
99f3b1d
working with goose and claude
bcpeinhardtApr 1, 2025
cd7c68c
switch up labels
bcpeinhardtApr 1, 2025
26f740d
remove hand raise emojis
bcpeinhardtApr 1, 2025
ac8d5fd
app not application
bcpeinhardtApr 1, 2025
d0386d0
resolve conflict
bcpeinhardtApr 1, 2025
69f9b97
remove unused commands
bcpeinhardtApr 1, 2025
68c2e04
terminal names
bcpeinhardtApr 1, 2025
b1e281c
use built in coder cli
bcpeinhardtApr 2, 2025
5c66430
Merge branch 'main' into bcpeinhardt/ai-agent-session-in-vscode
bcpeinhardtApr 14, 2025
83fafb0
Merge branch 'main' into bcpeinhardt/ai-agent-session-in-vscode
bcpeinhardtApr 15, 2025
22246b9
reset back to working state pre tmux and reverse app statuses so most…
bcpeinhardtApr 21, 2025
80f74f9
only show terminal after ssh command and app commands run
bcpeinhardtApr 21, 2025
0f7dd65
loading indicator
bcpeinhardtApr 21, 2025
8f996dd
update loading msg
bcpeinhardtApr 21, 2025
c24b675
don't mess with terminal size
bcpeinhardtApr 21, 2025
6f83606
workspace name isn't optional
bcpeinhardtApr 21, 2025
579ad4e
changelog and format
bcpeinhardtApr 21, 2025
9340b7d
remove unused icon code
bcpeinhardtApr 21, 2025
8dac372
cleanup
bcpeinhardtApr 21, 2025
866956a
remove unnecessary label assignment (I think there used to be an icon…
bcpeinhardtApr 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletionsCHANGELOG.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,6 +2,11 @@

## Unreleased

### Added

- Coder extension sidebar now displays available app statuses, and let's
the user click them to drop into a session with a running AI Agent.

## [v1.7.1](https://github.com/coder/vscode-coder/releases/tag/v1.7.1) (2025-04-14)

### Fixed
Expand Down
6 changes: 6 additions & 0 deletionspackage.json
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -204,6 +204,12 @@
"title": "Coder: View Logs",
"icon": "$(list-unordered)",
"when": "coder.authenticated"
},
{
"command": "coder.openAppStatus",
"title": "Coder: Open App Status",
"icon": "$(robot)",
"when": "coder.authenticated"
}
],
"menus": {
Expand Down
58 changes: 58 additions & 0 deletionssrc/commands.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
import { Api } from "coder/site/src/api/api"
import { getErrorMessage } from "coder/site/src/api/errors"
import { User, Workspace, WorkspaceAgent } from "coder/site/src/api/typesGenerated"
import path from "node:path"
import * as vscode from "vscode"
import { makeCoderSdk, needToken } from "./api"
import { extractAgents } from "./api-helper"
Expand DownExpand Up@@ -407,6 +408,63 @@ export class Commands {
}
}

public async openAppStatus(app: {
name?: string
url?: string
agent_name?: string
command?: string
workspace_name: string
}): Promise<void> {
// Launch and run command in terminal if command is provided
if (app.command) {
return vscode.window.withProgress(
{
location: vscode.ProgressLocation.Notification,
title: `Connecting to AI Agent...`,
cancellable: false,
},
async () => {
const terminal = vscode.window.createTerminal(app.name)

// If workspace_name is provided, run coder ssh before the command

const url = this.storage.getUrl()
if (!url) {
throw new Error("No coder url found for sidebar")
}
const binary = await this.storage.fetchBinary(this.restClient, toSafeHost(url))
const escape = (str: string): string => `"${str.replace(/"/g, '\\"')}"`
terminal.sendText(
`${escape(binary)} ssh --global-config ${escape(
path.dirname(this.storage.getSessionTokenPath(toSafeHost(url))),
)} ${app.workspace_name}`,
)
await new Promise((resolve) => setTimeout(resolve, 5000))
terminal.sendText(app.command ?? "")
terminal.show(false)
},
)
}
// Check if app has a URL to open
if (app.url) {
return vscode.window.withProgress(
{
location: vscode.ProgressLocation.Notification,
title: `Opening ${app.name || "application"} in browser...`,
cancellable: false,
},
async () => {
await vscode.env.openExternal(vscode.Uri.parse(app.url!))
},
)
}

// If no URL or command, show information about the app status
vscode.window.showInformationMessage(`${app.name}`, {
detail: `Agent: ${app.agent_name || "Unknown"}`,
})
}

/**
* Open a workspace belonging to the currently logged-in deployment.
*
Expand Down
1 change: 1 addition & 0 deletionssrc/extension.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -181,6 +181,7 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
vscode.commands.registerCommand("coder.open", commands.open.bind(commands))
vscode.commands.registerCommand("coder.openDevContainer", commands.openDevContainer.bind(commands))
vscode.commands.registerCommand("coder.openFromSidebar", commands.openFromSidebar.bind(commands))
vscode.commands.registerCommand("coder.openAppStatus", commands.openAppStatus.bind(commands))
vscode.commands.registerCommand("coder.workspace.update", commands.updateWorkspace.bind(commands))
vscode.commands.registerCommand("coder.createWorkspace", commands.createWorkspace.bind(commands))
vscode.commands.registerCommand("coder.navigateToWorkspace", commands.navigateToWorkspace.bind(commands))
Expand Down
125 changes: 120 additions & 5 deletionssrc/workspacesProvider.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
import { Api } from "coder/site/src/api/api"
import { Workspace, WorkspaceAgent } from "coder/site/src/api/typesGenerated"
import { Workspace, WorkspaceAgent, WorkspaceApp } from "coder/site/src/api/typesGenerated"
import { EventSource } from "eventsource"
import * as path from "path"
import * as vscode from "vscode"
Expand DownExpand Up@@ -146,9 +146,36 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
}
})

return resp.workspaces.map((workspace) => {
return new WorkspaceTreeItem(workspace, this.getWorkspacesQuery === WorkspaceQuery.All, showMetadata)
})
// Create tree items for each workspace
const workspaceTreeItems = await Promise.all(
resp.workspaces.map(async (workspace) => {
const workspaceTreeItem = new WorkspaceTreeItem(
workspace,
this.getWorkspacesQuery === WorkspaceQuery.All,
showMetadata,
)

// Get app status from the workspace agents
const agents = extractAgents(workspace)
agents.forEach((agent) => {
// Check if agent has apps property with status reporting
if (agent.apps && Array.isArray(agent.apps)) {
workspaceTreeItem.appStatus = agent.apps.map((app: WorkspaceApp) => ({
name: app.display_name,
url: app.url,
agent_id: agent.id,
agent_name: agent.name,
command: app.command,
workspace_name: workspace.name,
}))
}
})

return workspaceTreeItem
}),
)

return workspaceTreeItems
}

/**
Expand DownExpand Up@@ -207,14 +234,58 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
const agentTreeItems = agents.map(
(agent) => new AgentTreeItem(agent, element.workspaceOwner, element.workspaceName, element.watchMetadata),
)

return Promise.resolve(agentTreeItems)
} else if (element instanceof AgentTreeItem) {
const watcher = this.agentWatchers[element.agent.id]
if (watcher?.error) {
return Promise.resolve([new ErrorTreeItem(watcher.error)])
}

const items: vscode.TreeItem[] = []

// Add app status section with collapsible header
if (element.agent.apps && element.agent.apps.length > 0) {
const appStatuses = []
for (const app of element.agent.apps) {
if (app.statuses && app.statuses.length > 0) {
for (const status of app.statuses) {
// Show all statuses, not just ones needing attention.
// We need to do this for now because the reporting isn't super accurate
// yet.
appStatuses.push(
new AppStatusTreeItem({
name: status.message,
command: app.command,
workspace_name: element.workspaceName,
}),
)
}
}
}

// Show the section if it has any items
if (appStatuses.length > 0) {
const appStatusSection = new SectionTreeItem("App Statuses", appStatuses.reverse())
items.push(appStatusSection)
}
}

const savedMetadata = watcher?.metadata || []
return Promise.resolve(savedMetadata.map((metadata) => new AgentMetadataTreeItem(metadata)))

// Add agent metadata section with collapsible header
if (savedMetadata.length > 0) {
const metadataSection = new SectionTreeItem(
"Agent Metadata",
savedMetadata.map((metadata) => new AgentMetadataTreeItem(metadata)),
)
items.push(metadataSection)
}

return Promise.resolve(items)
} else if (element instanceof SectionTreeItem) {
// Return the children of the section
return Promise.resolve(element.children)
}

return Promise.resolve([])
Expand DownExpand Up@@ -265,6 +336,19 @@ function monitorMetadata(agentId: WorkspaceAgent["id"], restClient: Api): AgentW
return watcher
}

/**
* A tree item that represents a collapsible section with child items
*/
class SectionTreeItem extends vscode.TreeItem {
constructor(
label: string,
public readonly children: vscode.TreeItem[],
) {
super(label, vscode.TreeItemCollapsibleState.Collapsed)
this.contextValue = "coderSectionHeader"
}
}

class ErrorTreeItem extends vscode.TreeItem {
constructor(error: unknown) {
super("Failed to query metadata: " + errToStr(error, "no error provided"), vscode.TreeItemCollapsibleState.None)
Expand All@@ -285,6 +369,28 @@ class AgentMetadataTreeItem extends vscode.TreeItem {
}
}

class AppStatusTreeItem extends vscode.TreeItem {
constructor(
public readonly app: {
name: string
url?: string
command?: string
workspace_name?: string
},
) {
super("", vscode.TreeItemCollapsibleState.None)
this.description = app.name
this.contextValue = "coderAppStatus"

// Add command to handle clicking on the app
this.command = {
command: "coder.openAppStatus",
title: "Open App Status",
arguments: [app],
}
}
}

type CoderOpenableTreeItemType = "coderWorkspaceSingleAgent" | "coderWorkspaceMultipleAgents" | "coderAgent"

export class OpenableTreeItem extends vscode.TreeItem {
Expand DownExpand Up@@ -335,6 +441,15 @@ class AgentTreeItem extends OpenableTreeItem {
}

export class WorkspaceTreeItem extends OpenableTreeItem {
public appStatus: {
name: string
url?: string
agent_id?: string
agent_name?: string
command?: string
workspace_name?: string
}[] = []

constructor(
public readonly workspace: Workspace,
public readonly showOwner: boolean,
Expand Down
2 changes: 1 addition & 1 deletionyarn.lock
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1714,7 +1714,7 @@ co@3.1.0:

"coder@https://github.com/coder/coder#main":
version "0.0.0"
resolved "https://github.com/coder/coder#3ac844ad3d341d2910542b83d4f33df7bd0be85e"
resolved "https://github.com/coder/coder#2efb8088f4d923d1884fe8947dc338f9d179693b"

collapse-white-space@^1.0.2:
version "1.0.6"
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp