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

Commit77e3f0d

Browse files
authored
Bcpeinhardt/ai agent session in vscode (#488)
1 parent7dae71d commit77e3f0d

File tree

6 files changed

+191
-6
lines changed

6 files changed

+191
-6
lines changed

‎CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
##Unreleased
44

5+
###Added
6+
7+
- Coder extension sidebar now displays available app statuses, and let's
8+
the user click them to drop into a session with a running AI Agent.
9+
510
##[v1.7.1](https://github.com/coder/vscode-coder/releases/tag/v1.7.1) (2025-04-14)
611

712
###Fixed

‎package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,12 @@
204204
"title":"Coder: View Logs",
205205
"icon":"$(list-unordered)",
206206
"when":"coder.authenticated"
207+
},
208+
{
209+
"command":"coder.openAppStatus",
210+
"title":"Coder: Open App Status",
211+
"icon":"$(robot)",
212+
"when":"coder.authenticated"
207213
}
208214
],
209215
"menus": {

‎src/commands.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import{Api}from"coder/site/src/api/api"
22
import{getErrorMessage}from"coder/site/src/api/errors"
33
import{User,Workspace,WorkspaceAgent}from"coder/site/src/api/typesGenerated"
4+
importpathfrom"node:path"
45
import*asvscodefrom"vscode"
56
import{makeCoderSdk,needToken}from"./api"
67
import{extractAgents}from"./api-helper"
@@ -407,6 +408,63 @@ export class Commands {
407408
}
408409
}
409410

411+
publicasyncopenAppStatus(app:{
412+
name?:string
413+
url?:string
414+
agent_name?:string
415+
command?:string
416+
workspace_name:string
417+
}):Promise<void>{
418+
// Launch and run command in terminal if command is provided
419+
if(app.command){
420+
returnvscode.window.withProgress(
421+
{
422+
location:vscode.ProgressLocation.Notification,
423+
title:`Connecting to AI Agent...`,
424+
cancellable:false,
425+
},
426+
async()=>{
427+
constterminal=vscode.window.createTerminal(app.name)
428+
429+
// If workspace_name is provided, run coder ssh before the command
430+
431+
consturl=this.storage.getUrl()
432+
if(!url){
433+
thrownewError("No coder url found for sidebar")
434+
}
435+
constbinary=awaitthis.storage.fetchBinary(this.restClient,toSafeHost(url))
436+
constescape=(str:string):string=>`"${str.replace(/"/g,'\\"')}"`
437+
terminal.sendText(
438+
`${escape(binary)} ssh --global-config${escape(
439+
path.dirname(this.storage.getSessionTokenPath(toSafeHost(url))),
440+
)}${app.workspace_name}`,
441+
)
442+
awaitnewPromise((resolve)=>setTimeout(resolve,5000))
443+
terminal.sendText(app.command??"")
444+
terminal.show(false)
445+
},
446+
)
447+
}
448+
// Check if app has a URL to open
449+
if(app.url){
450+
returnvscode.window.withProgress(
451+
{
452+
location:vscode.ProgressLocation.Notification,
453+
title:`Opening${app.name||"application"} in browser...`,
454+
cancellable:false,
455+
},
456+
async()=>{
457+
awaitvscode.env.openExternal(vscode.Uri.parse(app.url!))
458+
},
459+
)
460+
}
461+
462+
// If no URL or command, show information about the app status
463+
vscode.window.showInformationMessage(`${app.name}`,{
464+
detail:`Agent:${app.agent_name||"Unknown"}`,
465+
})
466+
}
467+
410468
/**
411469
* Open a workspace belonging to the currently logged-in deployment.
412470
*

‎src/extension.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
181181
vscode.commands.registerCommand("coder.open",commands.open.bind(commands))
182182
vscode.commands.registerCommand("coder.openDevContainer",commands.openDevContainer.bind(commands))
183183
vscode.commands.registerCommand("coder.openFromSidebar",commands.openFromSidebar.bind(commands))
184+
vscode.commands.registerCommand("coder.openAppStatus",commands.openAppStatus.bind(commands))
184185
vscode.commands.registerCommand("coder.workspace.update",commands.updateWorkspace.bind(commands))
185186
vscode.commands.registerCommand("coder.createWorkspace",commands.createWorkspace.bind(commands))
186187
vscode.commands.registerCommand("coder.navigateToWorkspace",commands.navigateToWorkspace.bind(commands))

‎src/workspacesProvider.ts

Lines changed: 120 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import{Api}from"coder/site/src/api/api"
2-
import{Workspace,WorkspaceAgent}from"coder/site/src/api/typesGenerated"
2+
import{Workspace,WorkspaceAgent,WorkspaceApp}from"coder/site/src/api/typesGenerated"
33
import{EventSource}from"eventsource"
44
import*aspathfrom"path"
55
import*asvscodefrom"vscode"
@@ -146,9 +146,36 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
146146
}
147147
})
148148

149-
returnresp.workspaces.map((workspace)=>{
150-
returnnewWorkspaceTreeItem(workspace,this.getWorkspacesQuery===WorkspaceQuery.All,showMetadata)
151-
})
149+
// Create tree items for each workspace
150+
constworkspaceTreeItems=awaitPromise.all(
151+
resp.workspaces.map(async(workspace)=>{
152+
constworkspaceTreeItem=newWorkspaceTreeItem(
153+
workspace,
154+
this.getWorkspacesQuery===WorkspaceQuery.All,
155+
showMetadata,
156+
)
157+
158+
// Get app status from the workspace agents
159+
constagents=extractAgents(workspace)
160+
agents.forEach((agent)=>{
161+
// Check if agent has apps property with status reporting
162+
if(agent.apps&&Array.isArray(agent.apps)){
163+
workspaceTreeItem.appStatus=agent.apps.map((app:WorkspaceApp)=>({
164+
name:app.display_name,
165+
url:app.url,
166+
agent_id:agent.id,
167+
agent_name:agent.name,
168+
command:app.command,
169+
workspace_name:workspace.name,
170+
}))
171+
}
172+
})
173+
174+
returnworkspaceTreeItem
175+
}),
176+
)
177+
178+
returnworkspaceTreeItems
152179
}
153180

154181
/**
@@ -207,14 +234,58 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
207234
constagentTreeItems=agents.map(
208235
(agent)=>newAgentTreeItem(agent,element.workspaceOwner,element.workspaceName,element.watchMetadata),
209236
)
237+
210238
returnPromise.resolve(agentTreeItems)
211239
}elseif(elementinstanceofAgentTreeItem){
212240
constwatcher=this.agentWatchers[element.agent.id]
213241
if(watcher?.error){
214242
returnPromise.resolve([newErrorTreeItem(watcher.error)])
215243
}
244+
245+
constitems:vscode.TreeItem[]=[]
246+
247+
// Add app status section with collapsible header
248+
if(element.agent.apps&&element.agent.apps.length>0){
249+
constappStatuses=[]
250+
for(constappofelement.agent.apps){
251+
if(app.statuses&&app.statuses.length>0){
252+
for(conststatusofapp.statuses){
253+
// Show all statuses, not just ones needing attention.
254+
// We need to do this for now because the reporting isn't super accurate
255+
// yet.
256+
appStatuses.push(
257+
newAppStatusTreeItem({
258+
name:status.message,
259+
command:app.command,
260+
workspace_name:element.workspaceName,
261+
}),
262+
)
263+
}
264+
}
265+
}
266+
267+
// Show the section if it has any items
268+
if(appStatuses.length>0){
269+
constappStatusSection=newSectionTreeItem("App Statuses",appStatuses.reverse())
270+
items.push(appStatusSection)
271+
}
272+
}
273+
216274
constsavedMetadata=watcher?.metadata||[]
217-
returnPromise.resolve(savedMetadata.map((metadata)=>newAgentMetadataTreeItem(metadata)))
275+
276+
// Add agent metadata section with collapsible header
277+
if(savedMetadata.length>0){
278+
constmetadataSection=newSectionTreeItem(
279+
"Agent Metadata",
280+
savedMetadata.map((metadata)=>newAgentMetadataTreeItem(metadata)),
281+
)
282+
items.push(metadataSection)
283+
}
284+
285+
returnPromise.resolve(items)
286+
}elseif(elementinstanceofSectionTreeItem){
287+
// Return the children of the section
288+
returnPromise.resolve(element.children)
218289
}
219290

220291
returnPromise.resolve([])
@@ -265,6 +336,19 @@ function monitorMetadata(agentId: WorkspaceAgent["id"], restClient: Api): AgentW
265336
returnwatcher
266337
}
267338

339+
/**
340+
* A tree item that represents a collapsible section with child items
341+
*/
342+
classSectionTreeItemextendsvscode.TreeItem{
343+
constructor(
344+
label:string,
345+
publicreadonlychildren:vscode.TreeItem[],
346+
){
347+
super(label,vscode.TreeItemCollapsibleState.Collapsed)
348+
this.contextValue="coderSectionHeader"
349+
}
350+
}
351+
268352
classErrorTreeItemextendsvscode.TreeItem{
269353
constructor(error:unknown){
270354
super("Failed to query metadata: "+errToStr(error,"no error provided"),vscode.TreeItemCollapsibleState.None)
@@ -285,6 +369,28 @@ class AgentMetadataTreeItem extends vscode.TreeItem {
285369
}
286370
}
287371

372+
classAppStatusTreeItemextendsvscode.TreeItem{
373+
constructor(
374+
publicreadonlyapp:{
375+
name:string
376+
url?:string
377+
command?:string
378+
workspace_name?:string
379+
},
380+
){
381+
super("",vscode.TreeItemCollapsibleState.None)
382+
this.description=app.name
383+
this.contextValue="coderAppStatus"
384+
385+
// Add command to handle clicking on the app
386+
this.command={
387+
command:"coder.openAppStatus",
388+
title:"Open App Status",
389+
arguments:[app],
390+
}
391+
}
392+
}
393+
288394
typeCoderOpenableTreeItemType="coderWorkspaceSingleAgent"|"coderWorkspaceMultipleAgents"|"coderAgent"
289395

290396
exportclassOpenableTreeItemextendsvscode.TreeItem{
@@ -335,6 +441,15 @@ class AgentTreeItem extends OpenableTreeItem {
335441
}
336442

337443
exportclassWorkspaceTreeItemextendsOpenableTreeItem{
444+
publicappStatus:{
445+
name:string
446+
url?:string
447+
agent_id?:string
448+
agent_name?:string
449+
command?:string
450+
workspace_name?:string
451+
}[]=[]
452+
338453
constructor(
339454
publicreadonlyworkspace:Workspace,
340455
publicreadonlyshowOwner:boolean,

‎yarn.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1749,7 +1749,7 @@ co@3.1.0:
17491749

17501750
"coder@https://github.com/coder/coder#main":
17511751
version "0.0.0"
1752-
resolved "https://github.com/coder/coder#3ac844ad3d341d2910542b83d4f33df7bd0be85e"
1752+
resolved "https://github.com/coder/coder#2efb8088f4d923d1884fe8947dc338f9d179693b"
17531753

17541754
collapse-white-space@^1.0.2:
17551755
version "1.0.6"

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp