-
Notifications
You must be signed in to change notification settings - Fork 1.3k
feat(site): expose workspace apps in chat workspace pill #24295
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 18 commits
51d076f
057ac8d
dd3f0be
da60ae8
fd165c9
f366b30
ba6fda9
3441075
9689199
6610110
20de227
9c4be48
29ae400
0dcd9bd
5d6aa30
559e05b
1b186da
19ba116
a95bf52
831572d
6373d75
ef908e8
95d78c5
cff4e04
aedb81c
ed94b48
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,4 @@ | ||
| import { | ||
| ArchiveIcon, | ||
| MonitorDotIcon, | ||
| MonitorIcon, | ||
| MonitorPauseIcon, | ||
| MonitorXIcon, | ||
| } from "lucide-react"; | ||
| import { ArchiveIcon } from "lucide-react"; | ||
|
|
||
| import { | ||
| type FC, | ||
|
|
@@ -20,11 +14,7 @@ import type * as TypesGen from "#/api/typesGenerated"; | |
| import type { ChatDiffStatus, ChatMessagePart } from "#/api/typesGenerated"; | ||
| import { cn } from "#/utils/cn"; | ||
| import { pageTitle } from "#/utils/page"; | ||
| import { | ||
| type DisplayWorkspaceStatusType, | ||
| getDisplayWorkspaceStatus, | ||
| } from "#/utils/workspace"; | ||
|
|
||
| import { getDisplayWorkspaceStatus } from "#/utils/workspace"; | ||
| import { | ||
| AgentChatInput, | ||
| type ChatMessageInputRef, | ||
|
|
@@ -43,6 +33,7 @@ import { ChatTopBar } from "./components/ChatTopBar"; | |
| import { GitPanel } from "./components/GitPanel/GitPanel"; | ||
| import { RightPanel } from "./components/RightPanel/RightPanel"; | ||
| import { SidebarTabView } from "./components/Sidebar/SidebarTabView"; | ||
| import { StatusIcon } from "./components/StatusIcon"; | ||
| import { TerminalPanel } from "./components/TerminalPanel"; | ||
| import { ChatWorkspaceContext } from "./context/ChatWorkspaceContext"; | ||
| import { chatWidthClass, useChatFullWidth } from "./hooks/useChatFullWidth"; | ||
|
|
@@ -132,12 +123,7 @@ interface AgentChatPageViewProps { | |
| }; | ||
|
|
||
| // Workspace action handlers. | ||
| canOpenEditors: boolean; | ||
| canOpenWorkspace: boolean; | ||
| sshCommand: string | undefined; | ||
| handleOpenInEditor: (editor: "cursor" | "vscode") => void; | ||
| handleViewWorkspace: () => void; | ||
| handleOpenTerminal: () => void; | ||
| handleCommit: (repoRoot: string) => void; | ||
|
|
||
| // Chat action handlers. | ||
|
|
@@ -206,12 +192,7 @@ export const AgentChatPageView: FC<AgentChatPageViewProps> = ({ | |
| prNumber, | ||
| diffStatusData, | ||
| gitWatcher, | ||
| canOpenEditors, | ||
| canOpenWorkspace, | ||
| sshCommand, | ||
| handleOpenInEditor, | ||
| handleViewWorkspace, | ||
| handleOpenTerminal, | ||
| handleCommit, | ||
| handleInterrupt, | ||
| handleDeleteQueuedMessage, | ||
|
|
@@ -275,16 +256,25 @@ export const AgentChatPageView: FC<AgentChatPageViewProps> = ({ | |
|
|
||
| // Compute local diff stats from git watcher unified diffs. | ||
|
|
||
| // Prefer the git repository root over the agent's expanded directory | ||
| // for VS Code folder resolution (important for monorepos). | ||
| const preferredFolder = (() => { | ||
| const repoRoots = Array.from(gitWatcher?.repositories.keys() ?? []).sort(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems like it could have unexpected consequences if gitWatcher is tracking multiple repositories? Your diff view shows one repo and then the editor or what not opens up in another.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Definitely agree with you although that's the existing behavior. - // Prefer the active git repo root so VS Code opens to the
- // actual project directory, falling back to the agent's
- // configured directory.
- const repoRoots = Array.from(gitWatcher.repositories.keys()).sort();
- const folder = repoRoots[0] ?? workspaceAgent.expanded_directory;We should definitely noodle on a better approach here. |
||
| return repoRoots[0] || workspaceAgent?.expanded_directory; | ||
| })(); | ||
|
|
||
| const workspaceRoute = workspace | ||
| ? `/@${workspace.owner_name}/${workspace.name}` | ||
| : undefined; | ||
|
|
||
| const attachedWorkspace = (() => { | ||
| if (!workspace || !workspaceRoute) return undefined; | ||
|
|
||
| let { type, text } = getDisplayWorkspaceStatus( | ||
| workspace.latest_build.status, | ||
| workspace.latest_build.job, | ||
| ); | ||
|
|
||
| const agentPreparing = | ||
| workspace.latest_build.status === "running" && | ||
| (workspaceAgent?.lifecycle_state === "created" || | ||
|
|
@@ -300,23 +290,16 @@ export const AgentChatPageView: FC<AgentChatPageViewProps> = ({ | |
| type = "warning"; | ||
| text = "Startup failed"; | ||
| } | ||
|
|
||
| const effectiveType = workspace.health.healthy ? type : "warning"; | ||
| const statusLabel = workspace.health.healthy | ||
| ? `Workspace ${text.toLowerCase()}` | ||
| : `Workspace ${text.toLowerCase()} (unhealthy)`; | ||
| const iconCls = "size-3"; | ||
| const statusIconMap: Record<DisplayWorkspaceStatusType, React.ReactNode> = { | ||
| success: <MonitorIcon className={iconCls} />, | ||
| active: <MonitorDotIcon className={iconCls} />, | ||
| inactive: <MonitorPauseIcon className={iconCls} />, | ||
| error: <MonitorXIcon className={iconCls} />, | ||
| danger: <MonitorXIcon className={iconCls} />, | ||
| warning: <MonitorXIcon className={iconCls} />, | ||
| }; | ||
| const statusIcon = <StatusIcon type={effectiveType} />; | ||
| return { | ||
| name: workspace.name, | ||
| route: workspaceRoute, | ||
| statusIcon: statusIconMap[effectiveType], | ||
| statusIcon, | ||
| statusLabel, | ||
| }; | ||
| })(); | ||
|
|
@@ -357,14 +340,6 @@ export const AgentChatPageView: FC<AgentChatPageViewProps> = ({ | |
| showSidebarPanel, | ||
| onToggleSidebar: () => onSetShowSidebarPanel((prev) => !prev), | ||
| }} | ||
| workspace={{ | ||
| canOpenEditors, | ||
| canOpenWorkspace, | ||
| onOpenInEditor: handleOpenInEditor, | ||
| onViewWorkspace: handleViewWorkspace, | ||
| onOpenTerminal: handleOpenTerminal, | ||
| sshCommand, | ||
| }} | ||
| onArchiveAgent={handleArchiveAgentAction} | ||
| onUnarchiveAgent={handleUnarchiveAgentAction} | ||
| onArchiveAndDeleteWorkspace={ | ||
|
|
@@ -454,7 +429,12 @@ export const AgentChatPageView: FC<AgentChatPageViewProps> = ({ | |
| onMCPSelectionChange={onMCPSelectionChange} | ||
| onMCPAuthComplete={onMCPAuthComplete} | ||
| lastInjectedContext={lastInjectedContext} | ||
| workspace={workspace} | ||
| workspaceAgent={workspaceAgent} | ||
| chatId={agentId} | ||
| sshCommand={sshCommand} | ||
| attachedWorkspace={attachedWorkspace} | ||
| folder={preferredFolder} | ||
| /> | ||
| </div> | ||
| </div> | ||
|
|
@@ -568,14 +548,6 @@ export const AgentChatPageLoadingView: FC<AgentChatPageLoadingViewProps> = ({ | |
| showSidebarPanel: false, | ||
| onToggleSidebar: () => {}, | ||
| }} | ||
| workspace={{ | ||
| canOpenEditors: false, | ||
| canOpenWorkspace: false, | ||
| onOpenInEditor: () => {}, | ||
| onViewWorkspace: () => {}, | ||
| onOpenTerminal: () => {}, | ||
| sshCommand: undefined, | ||
| }} | ||
| onArchiveAgent={() => {}} | ||
| onUnarchiveAgent={() => {}} | ||
| onRegenerateTitle={() => {}} | ||
|
|
@@ -646,14 +618,6 @@ export const AgentChatPageNotFoundView: FC<AgentChatPageNotFoundViewProps> = ({ | |
| showSidebarPanel: false, | ||
| onToggleSidebar: () => {}, | ||
| }} | ||
| workspace={{ | ||
| canOpenEditors: false, | ||
| canOpenWorkspace: false, | ||
| onOpenInEditor: () => {}, | ||
| onViewWorkspace: () => {}, | ||
| onOpenTerminal: () => {}, | ||
| sshCommand: undefined, | ||
| }} | ||
| onArchiveAgent={() => {}} | ||
| onUnarchiveAgent={() => {}} | ||
| onRegenerateTitle={() => {}} | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.