@xenosystem/agent-interface-ui 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/agentHostPlatformBridge.d.ts.map +1 -1
- package/dist/adapters/agentHostPlatformBridge.js +131 -36
- package/dist/adapters/agentHostPlatformBridge.js.map +1 -1
- package/dist/components/agent/AgentInterface.d.ts.map +1 -1
- package/dist/components/agent/AgentInterface.js +322 -32
- package/dist/components/agent/AgentInterface.js.map +1 -1
- package/dist/components/agent/AgentView.d.ts +1 -0
- package/dist/components/agent/AgentView.d.ts.map +1 -1
- package/dist/components/agent/AgentView.js +144 -12
- package/dist/components/agent/AgentView.js.map +1 -1
- package/dist/platformApiTypes.d.ts +49 -0
- package/dist/platformApiTypes.d.ts.map +1 -1
- package/dist/stores/agentChatStore.d.ts +22 -5
- package/dist/stores/agentChatStore.d.ts.map +1 -1
- package/dist/stores/agentChatStore.js +187 -50
- package/dist/stores/agentChatStore.js.map +1 -1
- package/package.json +5 -5
|
@@ -18,8 +18,9 @@ import { isWideWorkbenchTab } from './AgentWorkbenchPanel.js';
|
|
|
18
18
|
import { PermissionDialog } from './PermissionDialog.js';
|
|
19
19
|
import { runtimeEventSummary } from './runtimeEventSummary.js';
|
|
20
20
|
import { latestContextPressure } from './timelineContextPressure.js';
|
|
21
|
+
import { createConversationRuntimeBinding, runtimeSelectionForSdk } from '../../utils/conversationRuntime.js';
|
|
21
22
|
import { usePermissionStore } from '../../stores/permissionStore.js';
|
|
22
|
-
import { useAgentChatStore, loadLocalAgentConversations, projectConversationRuntimeEvents, } from '../../stores/agentChatStore.js';
|
|
23
|
+
import { useAgentChatStore, loadLocalAgentConversations, projectConversationRuntimeEvents, resetAcpContinuationForWorkspaceChange, } from '../../stores/agentChatStore.js';
|
|
23
24
|
import { useAgentIdeStore } from '../../stores/agentIdeStore.js';
|
|
24
25
|
import { useAgentSearchStore } from '../../stores/agentSearchStore.js';
|
|
25
26
|
import { useWorkspaceStore, } from '../../stores/workspaceStore.js';
|
|
@@ -1553,10 +1554,13 @@ function loadCachedRightPanelTerminals() {
|
|
|
1553
1554
|
.map((tab) => ({
|
|
1554
1555
|
id: tab.id,
|
|
1555
1556
|
label: tab.label,
|
|
1557
|
+
kind: tab.kind === 'provider-session' ? 'provider-session' : 'shell',
|
|
1556
1558
|
conversationId: tab.conversationId,
|
|
1557
1559
|
terminalId: tab.terminalId,
|
|
1558
1560
|
cwd: tab.cwd,
|
|
1559
1561
|
allowedKey: tab.allowedKey,
|
|
1562
|
+
...(typeof tab.laneId === 'string' ? { laneId: tab.laneId } : {}),
|
|
1563
|
+
...(typeof tab.expectedLaneRevision === 'number' ? { expectedLaneRevision: tab.expectedLaneRevision } : {}),
|
|
1560
1564
|
output: '',
|
|
1561
1565
|
starting: false,
|
|
1562
1566
|
exited: false,
|
|
@@ -1575,10 +1579,13 @@ function persistCachedRightPanelTerminals(tabs) {
|
|
|
1575
1579
|
.map((tab) => ({
|
|
1576
1580
|
id: tab.id,
|
|
1577
1581
|
label: tab.label,
|
|
1582
|
+
kind: tab.kind,
|
|
1578
1583
|
conversationId: tab.conversationId,
|
|
1579
1584
|
terminalId: tab.terminalId,
|
|
1580
1585
|
cwd: tab.cwd,
|
|
1581
1586
|
allowedKey: tab.allowedKey,
|
|
1587
|
+
...(tab.laneId ? { laneId: tab.laneId } : {}),
|
|
1588
|
+
...(typeof tab.expectedLaneRevision === 'number' ? { expectedLaneRevision: tab.expectedLaneRevision } : {}),
|
|
1582
1589
|
}));
|
|
1583
1590
|
window.sessionStorage.setItem(RIGHT_PANEL_TERMINALS_STORAGE_KEY, JSON.stringify(serializable));
|
|
1584
1591
|
}
|
|
@@ -1592,7 +1599,7 @@ function clampRightPanelWidth(width) {
|
|
|
1592
1599
|
: Math.max(RIGHT_PANEL_MIN_WIDTH, Math.min(RIGHT_PANEL_MAX_WIDTH, window.innerWidth - 360));
|
|
1593
1600
|
return Math.min(viewportAwareMax, Math.max(RIGHT_PANEL_MIN_WIDTH, Math.round(width)));
|
|
1594
1601
|
}
|
|
1595
|
-
function FolderSidebar({ conversationId, rootDirectory, allowedDirectories, onOpenFolder, onClose, onOpenFile, activeFilePath, terminalCapabilityEnabled, terminalReady, resolvedTerminalCwd, terminalTabs, onPtyInput, onPtyResize, onCreateTerminal, onCloseTerminal, onClearTerminal, onRestartTerminal, width, onResizeStart, }) {
|
|
1602
|
+
function FolderSidebar({ conversationId, rootDirectory, allowedDirectories, onOpenFolder, onClose, onOpenFile, activeFilePath, terminalCapabilityEnabled, terminalReady, providerSessionTuiReady, resolvedTerminalCwd, terminalTabs, onPtyInput, onPtyResize, onCreateTerminal, onCreateProviderTui, onCloseTerminal, onClearTerminal, onRestartTerminal, width, onResizeStart, }) {
|
|
1596
1603
|
const [rightPanelTab, setRightPanelTab] = useState('files');
|
|
1597
1604
|
const [browserTabs, setBrowserTabs] = useState(() => loadCachedRightPanelBrowserTabs());
|
|
1598
1605
|
const activeBrowserTabId = rightPanelTab.startsWith('browser:') ? rightPanelTab.slice('browser:'.length) : null;
|
|
@@ -1818,7 +1825,12 @@ function FolderSidebar({ conversationId, rootDirectory, allowedDirectories, onOp
|
|
|
1818
1825
|
if (id)
|
|
1819
1826
|
setRightPanelTab(`terminal:${id}`);
|
|
1820
1827
|
setNewTabMenuOpen(false);
|
|
1821
|
-
}, disabled: !terminalCapabilityEnabled || !terminalReady, className: "w-full flex items-center gap-2.5 px-3 py-2 text-left text-[12px] text-white/64 hover:bg-white/[0.06] hover:text-white transition-colors disabled:cursor-not-allowed disabled:opacity-35 disabled:hover:bg-transparent disabled:hover:text-white/64", children: [_jsx(Terminal, { className: "h-3.5 w-3.5 text-white/42", strokeWidth: 1.8 }), _jsx("span", { children: "PowerShell" })] })
|
|
1828
|
+
}, disabled: !terminalCapabilityEnabled || !terminalReady, className: "w-full flex items-center gap-2.5 px-3 py-2 text-left text-[12px] text-white/64 hover:bg-white/[0.06] hover:text-white transition-colors disabled:cursor-not-allowed disabled:opacity-35 disabled:hover:bg-transparent disabled:hover:text-white/64", children: [_jsx(Terminal, { className: "h-3.5 w-3.5 text-white/42", strokeWidth: 1.8 }), _jsx("span", { children: "PowerShell" })] }), _jsxs("button", { type: "button", role: "menuitem", onClick: () => {
|
|
1829
|
+
const id = onCreateProviderTui();
|
|
1830
|
+
if (id)
|
|
1831
|
+
setRightPanelTab(`terminal:${id}`);
|
|
1832
|
+
setNewTabMenuOpen(false);
|
|
1833
|
+
}, disabled: !providerSessionTuiReady, className: "w-full flex items-center gap-2.5 px-3 py-2 text-left text-[12px] text-white/64 hover:bg-white/[0.06] hover:text-white transition-colors disabled:cursor-not-allowed disabled:opacity-35 disabled:hover:bg-transparent disabled:hover:text-white/64", children: [_jsx(Terminal, { className: "h-3.5 w-3.5 text-white/42", strokeWidth: 1.8 }), _jsx("span", { children: "Provider TUI" })] })] }))] }), _jsxs("div", { ref: panelMenuRef, className: "relative", children: [_jsx("button", { type: "button", onClick: () => setPanelMenuOpen((open) => !open), className: `h-7 w-7 inline-flex items-center justify-center rounded-[5px] transition-colors ${panelMenuOpen
|
|
1822
1834
|
? 'text-white/72 bg-white/[0.07]'
|
|
1823
1835
|
: 'text-white/30 hover:text-white/65 hover:bg-white/[0.055]'}`, title: "Panel options", "aria-haspopup": "menu", "aria-expanded": panelMenuOpen, children: _jsx(MoreHorizontal, { className: "w-3.5 h-3.5", strokeWidth: 1.8 }) }), panelMenuOpen && (_jsxs("div", { role: "menu", className: "absolute right-0 top-[32px] z-50 w-52 overflow-hidden rounded-[7px] border border-white/[0.08] bg-[#111114] py-1 shadow-[0_16px_40px_rgba(0,0,0,0.45)]", children: [activeTerminal ? (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", role: "menuitem", onClick: () => {
|
|
1824
1836
|
onClearTerminal(activeTerminal.id);
|
|
@@ -1826,7 +1838,9 @@ function FolderSidebar({ conversationId, rootDirectory, allowedDirectories, onOp
|
|
|
1826
1838
|
}, className: "w-full px-3 py-2 text-left text-[12px] text-white/64 hover:bg-white/[0.06] hover:text-white transition-colors", children: "Clear terminal" }), _jsx("button", { type: "button", role: "menuitem", onClick: () => {
|
|
1827
1839
|
onRestartTerminal(activeTerminal.id);
|
|
1828
1840
|
setPanelMenuOpen(false);
|
|
1829
|
-
}, className: "w-full px-3 py-2 text-left text-[12px] text-white/64 hover:bg-white/[0.06] hover:text-white transition-colors", children:
|
|
1841
|
+
}, className: "w-full px-3 py-2 text-left text-[12px] text-white/64 hover:bg-white/[0.06] hover:text-white transition-colors", children: activeTerminal.kind === 'provider-session' && activeTerminal.exited
|
|
1842
|
+
? 'Reconcile and return to chat'
|
|
1843
|
+
: `Restart ${activeTerminal.kind === 'provider-session' ? (activeTerminal.label || 'Provider TUI') : 'PowerShell'}` }), _jsx("button", { type: "button", role: "menuitem", onClick: () => {
|
|
1830
1844
|
onCloseTerminal(activeTerminal.id);
|
|
1831
1845
|
setPanelMenuOpen(false);
|
|
1832
1846
|
}, className: "w-full px-3 py-2 text-left text-[12px] text-red-200/70 hover:bg-red-500/[0.09] hover:text-red-100 transition-colors", children: "Close terminal tab" }), _jsx("div", { className: "my-1 h-px bg-white/[0.06]" })] })) : activeBrowser ? (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", role: "menuitem", onClick: () => {
|
|
@@ -1850,6 +1864,11 @@ function FolderSidebar({ conversationId, rootDirectory, allowedDirectories, onOp
|
|
|
1850
1864
|
setRightPanelTab(`terminal:${id}`);
|
|
1851
1865
|
setPanelMenuOpen(false);
|
|
1852
1866
|
}, disabled: !terminalCapabilityEnabled || !terminalReady, className: "w-full px-3 py-2 text-left text-[12px] text-white/64 hover:bg-white/[0.06] hover:text-white transition-colors disabled:cursor-not-allowed disabled:opacity-35 disabled:hover:bg-transparent", children: "New PowerShell tab" }), _jsx("button", { type: "button", role: "menuitem", onClick: () => {
|
|
1867
|
+
const id = onCreateProviderTui();
|
|
1868
|
+
if (id)
|
|
1869
|
+
setRightPanelTab(`terminal:${id}`);
|
|
1870
|
+
setPanelMenuOpen(false);
|
|
1871
|
+
}, disabled: !providerSessionTuiReady, className: "w-full px-3 py-2 text-left text-[12px] text-white/64 hover:bg-white/[0.06] hover:text-white transition-colors disabled:cursor-not-allowed disabled:opacity-35 disabled:hover:bg-transparent", children: "Open Provider TUI" }), _jsx("button", { type: "button", role: "menuitem", onClick: () => {
|
|
1853
1872
|
terminalTabs.forEach((tab) => onCloseTerminal(tab.id));
|
|
1854
1873
|
setRightPanelTab('files');
|
|
1855
1874
|
setPanelMenuOpen(false);
|
|
@@ -1861,7 +1880,7 @@ function FolderSidebar({ conversationId, rootDirectory, allowedDirectories, onOp
|
|
|
1861
1880
|
return (_jsx("div", { className: visible
|
|
1862
1881
|
? 'absolute inset-0'
|
|
1863
1882
|
: 'absolute inset-0 invisible pointer-events-none opacity-0', "aria-hidden": !visible, children: _jsx(React.Suspense, { fallback: _jsx("div", { className: "h-full bg-[#08080a] px-3 py-2 text-[12px] text-white/40", children: "Loading browser..." }), children: _jsx(AgentWorkspaceBrowserPanel, { browserId: tab.id, browserLabel: tab.label, rootDirectory: effectiveRoot || rootDirectory, allowedDirectories: effectiveAllowedDirectories, onOpenFolder: onOpenFolder }) }) }, tab.id));
|
|
1864
|
-
}), rightPanelTab === 'files' && effectiveRoot && (_jsxs("div", { children: [_jsxs("button", { type: "button", onClick: () => handleToggleDirectory(effectiveRoot), className: "w-full flex items-center gap-1.5 px-2 py-1.5 text-white/68 hover:text-white hover:bg-white/[0.04] rounded-md transition-colors text-left", children: [_jsx(ChevronDownIcon, { className: `w-3 h-3 flex-shrink-0 transition-transform ${expandedPaths.has(effectiveRoot) ? '' : '-rotate-90'}` }), expandedPaths.has(effectiveRoot) ? (_jsx(FolderOpen, { className: "w-3.5 h-3.5 flex-shrink-0 text-white/55", strokeWidth: 1.8 })) : (_jsx(Folder, { className: "w-3.5 h-3.5 flex-shrink-0 text-white/45", strokeWidth: 1.8 })), _jsx("span", { className: "min-w-0 truncate text-[12px]", children: directoryLeafName(effectiveRoot) })] }), expandedPaths.has(effectiveRoot) && (_jsxs("div", { className: "mt-0.5", children: [isRootLoading && (_jsx(FolderTreeLoadingSkeleton, { depth: 1, rows: 5 })), !isRootLoading && loadErrors[effectiveRoot] && (_jsx("div", { className: "pl-7 py-1 text-[11px] text-red-300/45", children: loadErrors[effectiveRoot] })), !isRootLoading && !loadErrors[effectiveRoot] && (entriesByPath[effectiveRoot] || []).map((entry) => (_jsx(FolderTreeNode, { entry: entry, depth: 1, expandedPaths: expandedPaths, loadingPaths: loadingPaths, loadErrors: loadErrors, entriesByPath: entriesByPath, onToggleDirectory: handleToggleDirectory, onOpenFile: onOpenFile, activeFilePath: activeFilePath }, entry.path)))] }))] })), rightPanelTab === 'files' && !effectiveRoot && (_jsxs("div", { className: "mt-2 rounded-md border border-white/[0.06] bg-white/[0.02] p-3", children: [_jsx("p", { className: "text-[11px] uppercase tracking-[0.18em] text-white/28", children: "Folder Explorer" }), _jsx("p", { className: "mt-2 text-[12px] leading-relaxed text-white/42", children: "Open a folder for this conversation to browse files here and send them into the editor." }), _jsxs("div", { className: "mt-3 space-y-2", children: [_jsx(SkeletonBlock, { className: "h-3 w-[78%]" }), _jsx(SkeletonBlock, { className: "h-3 w-[66%]" }), _jsx(SkeletonBlock, { className: "h-3 w-[72%]" })] })] })), activeTerminalTabId && (_jsx(React.Suspense, { fallback: _jsx("div", { className: "h-full bg-[#050506] px-3 py-2 font-mono text-[12px] text-white/40", children: "Loading terminal..." }), children: _jsx(AgentPtyTerminalPanel, { terminalKey: activeTerminal?.id || null, terminalId: activeTerminal?.terminalId || null, output: activeTerminal?.output || '', terminalCapabilityEnabled: terminalCapabilityEnabled, terminalReady: terminalReady, onInput: (data) => activeTerminal && onPtyInput(activeTerminal.id, data), onResize: (cols, rows) => activeTerminal && onPtyResize(activeTerminal.id, cols, rows) }) }))] })] }));
|
|
1883
|
+
}), rightPanelTab === 'files' && effectiveRoot && (_jsxs("div", { children: [_jsxs("button", { type: "button", onClick: () => handleToggleDirectory(effectiveRoot), className: "w-full flex items-center gap-1.5 px-2 py-1.5 text-white/68 hover:text-white hover:bg-white/[0.04] rounded-md transition-colors text-left", children: [_jsx(ChevronDownIcon, { className: `w-3 h-3 flex-shrink-0 transition-transform ${expandedPaths.has(effectiveRoot) ? '' : '-rotate-90'}` }), expandedPaths.has(effectiveRoot) ? (_jsx(FolderOpen, { className: "w-3.5 h-3.5 flex-shrink-0 text-white/55", strokeWidth: 1.8 })) : (_jsx(Folder, { className: "w-3.5 h-3.5 flex-shrink-0 text-white/45", strokeWidth: 1.8 })), _jsx("span", { className: "min-w-0 truncate text-[12px]", children: directoryLeafName(effectiveRoot) })] }), expandedPaths.has(effectiveRoot) && (_jsxs("div", { className: "mt-0.5", children: [isRootLoading && (_jsx(FolderTreeLoadingSkeleton, { depth: 1, rows: 5 })), !isRootLoading && loadErrors[effectiveRoot] && (_jsx("div", { className: "pl-7 py-1 text-[11px] text-red-300/45", children: loadErrors[effectiveRoot] })), !isRootLoading && !loadErrors[effectiveRoot] && (entriesByPath[effectiveRoot] || []).map((entry) => (_jsx(FolderTreeNode, { entry: entry, depth: 1, expandedPaths: expandedPaths, loadingPaths: loadingPaths, loadErrors: loadErrors, entriesByPath: entriesByPath, onToggleDirectory: handleToggleDirectory, onOpenFile: onOpenFile, activeFilePath: activeFilePath }, entry.path)))] }))] })), rightPanelTab === 'files' && !effectiveRoot && (_jsxs("div", { className: "mt-2 rounded-md border border-white/[0.06] bg-white/[0.02] p-3", children: [_jsx("p", { className: "text-[11px] uppercase tracking-[0.18em] text-white/28", children: "Folder Explorer" }), _jsx("p", { className: "mt-2 text-[12px] leading-relaxed text-white/42", children: "Open a folder for this conversation to browse files here and send them into the editor." }), _jsxs("div", { className: "mt-3 space-y-2", children: [_jsx(SkeletonBlock, { className: "h-3 w-[78%]" }), _jsx(SkeletonBlock, { className: "h-3 w-[66%]" }), _jsx(SkeletonBlock, { className: "h-3 w-[72%]" })] })] })), activeTerminalTabId && (_jsx(React.Suspense, { fallback: _jsx("div", { className: "h-full bg-[#050506] px-3 py-2 font-mono text-[12px] text-white/40", children: "Loading terminal..." }), children: _jsx(AgentPtyTerminalPanel, { terminalKey: activeTerminal?.id || null, terminalId: activeTerminal?.terminalId || null, output: activeTerminal?.output || '', terminalCapabilityEnabled: activeTerminal?.kind === 'provider-session' ? true : terminalCapabilityEnabled, terminalReady: activeTerminal?.kind === 'provider-session' ? providerSessionTuiReady : terminalReady, onInput: (data) => activeTerminal && onPtyInput(activeTerminal.id, data), onResize: (cols, rows) => activeTerminal && onPtyResize(activeTerminal.id, cols, rows) }) }))] })] }));
|
|
1865
1884
|
}
|
|
1866
1885
|
function RightSidebarControls({ folderPanelOpen, onOpenFolderPanel, }) {
|
|
1867
1886
|
return (_jsxs("div", { className: "absolute top-2 right-3 z-20 flex items-center gap-1.5", children: [_jsx("button", { className: "h-[34px] w-[34px] inline-flex items-center justify-center text-white/35 hover:text-white/60 transition-colors", title: "Sidebar options", "aria-label": "Sidebar options", type: "button", children: _jsx(MoreHorizontal, { className: "w-4 h-4", strokeWidth: 1.8 }) }), !folderPanelOpen && (_jsx("button", { onClick: onOpenFolderPanel, className: "h-[34px] w-[34px] inline-flex items-center justify-center transition-colors text-white/45 hover:text-white/75", title: "Open right sidebar", "aria-label": "Open right sidebar", type: "button", children: _jsx(PanelRightOpen, { className: "w-4 h-4", strokeWidth: 1.8 }) }))] }));
|
|
@@ -3249,6 +3268,15 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
3249
3268
|
const conversationId = existing?.id || createConversation(MAIN_ASSISTANT_ID);
|
|
3250
3269
|
setViewMode('inbox');
|
|
3251
3270
|
setSelectedInboxConversationId(conversationId);
|
|
3271
|
+
updateConversation(conversationId, {
|
|
3272
|
+
model: MAIN_ASSISTANT_MODEL,
|
|
3273
|
+
runtime: createConversationRuntimeBinding({
|
|
3274
|
+
selection: runtimeSelectionForSdk('user'),
|
|
3275
|
+
model: MAIN_ASSISTANT_MODEL,
|
|
3276
|
+
reasoningModel: MAIN_ASSISTANT_MODEL,
|
|
3277
|
+
inferenceMode: 'cloud',
|
|
3278
|
+
}),
|
|
3279
|
+
});
|
|
3252
3280
|
const attach = getAgentPlatformBridge()?.agent?.attachSdkSession;
|
|
3253
3281
|
if (!attach) {
|
|
3254
3282
|
appendMessage(conversationId, {
|
|
@@ -3375,6 +3403,8 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
3375
3403
|
const activeConversationAllowedDirectories = useMemo(() => {
|
|
3376
3404
|
if (!activeConversation)
|
|
3377
3405
|
return [];
|
|
3406
|
+
if (activeConversation.workspaceMode === 'chat-only')
|
|
3407
|
+
return [];
|
|
3378
3408
|
const granted = (activeConversation.grantedDirectories || [])
|
|
3379
3409
|
.map((dir) => normalizeDirectoryPath(dir))
|
|
3380
3410
|
.filter(Boolean);
|
|
@@ -3398,6 +3428,44 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
3398
3428
|
},
|
|
3399
3429
|
});
|
|
3400
3430
|
}, [activeConversationId, updateConversation]);
|
|
3431
|
+
useEffect(() => {
|
|
3432
|
+
if (!activeConversationId)
|
|
3433
|
+
return;
|
|
3434
|
+
const workspace = getAgentPlatformBridge().workspace;
|
|
3435
|
+
if (!workspace.conversationResume || !workspace.providerLanesList)
|
|
3436
|
+
return;
|
|
3437
|
+
let cancelled = false;
|
|
3438
|
+
void workspace.conversationResume({ conversationId: activeConversationId }).then(async (resumed) => {
|
|
3439
|
+
if (cancelled || !resumed.success || !resumed.hostStorageIdentity)
|
|
3440
|
+
return;
|
|
3441
|
+
const listed = await workspace.providerLanesList({
|
|
3442
|
+
conversationId: activeConversationId,
|
|
3443
|
+
includeHistorical: true,
|
|
3444
|
+
});
|
|
3445
|
+
if (cancelled || !listed.success)
|
|
3446
|
+
return;
|
|
3447
|
+
const conversation = useAgentChatStore.getState().getConversation(activeConversationId);
|
|
3448
|
+
if (!conversation)
|
|
3449
|
+
return;
|
|
3450
|
+
const lanes = listed.lanes || resumed.lanes || [];
|
|
3451
|
+
const activeLane = lanes.find((lane) => lane.laneId === listed.activeLaneId) || resumed.activeLane;
|
|
3452
|
+
updateConversation(activeConversationId, {
|
|
3453
|
+
sessionUi: {
|
|
3454
|
+
...(conversation.sessionUi || {}),
|
|
3455
|
+
hostBinding: {
|
|
3456
|
+
schemaVersion: 1,
|
|
3457
|
+
conversationId: activeConversationId,
|
|
3458
|
+
hostStorageIdentity: resumed.hostStorageIdentity,
|
|
3459
|
+
},
|
|
3460
|
+
...(activeLane ? { activeLane } : {}),
|
|
3461
|
+
lanes,
|
|
3462
|
+
},
|
|
3463
|
+
});
|
|
3464
|
+
});
|
|
3465
|
+
return () => {
|
|
3466
|
+
cancelled = true;
|
|
3467
|
+
};
|
|
3468
|
+
}, [activeConversationId, updateConversation]);
|
|
3401
3469
|
const workbenchPanelTab = activeSessionUi.panelTab || 'trace';
|
|
3402
3470
|
const selectedTraceMessageId = activeSessionUi.selectedTraceMessageId || null;
|
|
3403
3471
|
const terminalHistory = activeSessionUi.terminalHistory || [];
|
|
@@ -3444,7 +3512,14 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
3444
3512
|
return DEFAULT_AGENT_CAPABILITIES;
|
|
3445
3513
|
}, [selectedAgentId, viewMode, workspaces]);
|
|
3446
3514
|
const terminalCapabilityEnabled = !!activeAgentCapabilities.terminal;
|
|
3447
|
-
const terminalReady = terminalCapabilityEnabled &&
|
|
3515
|
+
const terminalReady = terminalCapabilityEnabled && Boolean(resolvedTerminalCwd || activeConversationId);
|
|
3516
|
+
const activeLane = activeSessionUi.activeLane;
|
|
3517
|
+
const guiOwnsActiveProviderSession = Boolean(activeRuntimeRequestId && activeRuntimeConversationId === activeConversationId);
|
|
3518
|
+
const providerSessionTuiReady = Boolean(activeConversationId
|
|
3519
|
+
&& activeLane?.laneId
|
|
3520
|
+
&& !guiOwnsActiveProviderSession
|
|
3521
|
+
&& getAgentPlatformBridge().workspace.providerNativeAttach
|
|
3522
|
+
&& (activeLane.status === 'new' || activeLane.status === 'clean'));
|
|
3448
3523
|
const rightPanelPtyAllowedKey = useMemo(() => activeConversationAllowedDirectories.map(normalizeDirectoryPath).join('|'), [activeConversationAllowedDirectories]);
|
|
3449
3524
|
useEffect(() => {
|
|
3450
3525
|
rightPanelTerminalsRef.current = rightPanelTerminals;
|
|
@@ -3464,7 +3539,7 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
3464
3539
|
terminalId: null,
|
|
3465
3540
|
starting: false,
|
|
3466
3541
|
exited: true,
|
|
3467
|
-
output: entry.output || '
|
|
3542
|
+
output: entry.output || `[${entry.kind === 'provider-session' ? (entry.label || 'Provider TUI') : 'PowerShell'} session is no longer available.]\r\n`,
|
|
3468
3543
|
};
|
|
3469
3544
|
}
|
|
3470
3545
|
return {
|
|
@@ -3485,6 +3560,24 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
3485
3560
|
: tab)));
|
|
3486
3561
|
});
|
|
3487
3562
|
getAgentPlatformBridge().workspace.onPtyExit((payload) => {
|
|
3563
|
+
const exitedTab = rightPanelTerminalsRef.current.find((tab) => tab.terminalId === payload.terminalId);
|
|
3564
|
+
if (exitedTab?.kind === 'provider-session' && exitedTab.laneId) {
|
|
3565
|
+
const conversation = useAgentChatStore.getState().getConversation(exitedTab.conversationId);
|
|
3566
|
+
const lane = conversation?.sessionUi?.activeLane;
|
|
3567
|
+
if (lane?.laneId === exitedTab.laneId) {
|
|
3568
|
+
useAgentChatStore.getState().updateConversation(exitedTab.conversationId, {
|
|
3569
|
+
sessionUi: {
|
|
3570
|
+
...(conversation?.sessionUi || {}),
|
|
3571
|
+
activeLane: {
|
|
3572
|
+
...lane,
|
|
3573
|
+
status: 'externally_advanced',
|
|
3574
|
+
revision: (exitedTab.expectedLaneRevision ?? lane.revision) + 1,
|
|
3575
|
+
invalidationReason: 'Native provider TUI exited; reconcile before continuing in chat.',
|
|
3576
|
+
},
|
|
3577
|
+
},
|
|
3578
|
+
});
|
|
3579
|
+
}
|
|
3580
|
+
}
|
|
3488
3581
|
setRightPanelTerminals((current) => current.map((tab) => (tab.terminalId === payload.terminalId
|
|
3489
3582
|
? {
|
|
3490
3583
|
...tab,
|
|
@@ -3497,14 +3590,14 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
3497
3590
|
});
|
|
3498
3591
|
return () => {
|
|
3499
3592
|
// Do not stop PTYs here. AgentInterface can unmount when switching app tabs;
|
|
3500
|
-
// each
|
|
3593
|
+
// each terminal tab owns its process until the tab is explicitly closed.
|
|
3501
3594
|
getAgentPlatformBridge().workspace.offPtyData();
|
|
3502
3595
|
getAgentPlatformBridge().workspace.offPtyExit();
|
|
3503
3596
|
};
|
|
3504
3597
|
}, []);
|
|
3505
|
-
const startRightPanelTerminal = useCallback((tabId, conversationId, cwd, allowedDirs) => {
|
|
3598
|
+
const startRightPanelTerminal = useCallback((tabId, conversationId, cwd, allowedDirs, profile) => {
|
|
3506
3599
|
const allowedDirsForStart = allowedDirs.length > 0 ? allowedDirs : [cwd].filter(Boolean);
|
|
3507
|
-
if (!cwd
|
|
3600
|
+
if (!profile && !cwd && allowedDirsForStart.length === 0 && !conversationId) {
|
|
3508
3601
|
setRightPanelTerminals((current) => current.map((tab) => (tab.id === tabId
|
|
3509
3602
|
? {
|
|
3510
3603
|
...tab,
|
|
@@ -3515,16 +3608,43 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
3515
3608
|
: tab)));
|
|
3516
3609
|
return;
|
|
3517
3610
|
}
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3611
|
+
const nativeAttach = getAgentPlatformBridge().workspace.providerNativeAttach;
|
|
3612
|
+
const start = profile
|
|
3613
|
+
? nativeAttach
|
|
3614
|
+
? nativeAttach({
|
|
3615
|
+
conversationId,
|
|
3616
|
+
laneId: profile.laneId,
|
|
3617
|
+
expectedLaneRevision: profile.expectedLaneRevision,
|
|
3618
|
+
cols: 80,
|
|
3619
|
+
rows: 24,
|
|
3620
|
+
})
|
|
3621
|
+
: Promise.resolve({
|
|
3622
|
+
success: false,
|
|
3623
|
+
code: 'NATIVE_TUI_UNSUPPORTED',
|
|
3624
|
+
error: 'Native provider TUI handoff is unavailable on this host.',
|
|
3625
|
+
terminalId: undefined,
|
|
3626
|
+
})
|
|
3627
|
+
: getAgentPlatformBridge().workspace.ptyStart({
|
|
3628
|
+
conversationId,
|
|
3629
|
+
cwd: cwd || undefined,
|
|
3630
|
+
allowedDirs: allowedDirsForStart,
|
|
3631
|
+
cols: 80,
|
|
3632
|
+
rows: 24,
|
|
3633
|
+
});
|
|
3634
|
+
void start.then((result) => {
|
|
3524
3635
|
const tabStillExists = rightPanelTerminalsRef.current.some((tab) => tab.id === tabId);
|
|
3525
3636
|
if (!tabStillExists) {
|
|
3526
|
-
if (result?.terminalId)
|
|
3637
|
+
if (result?.terminalId && profile) {
|
|
3638
|
+
void getAgentPlatformBridge().workspace.providerNativeStop?.({
|
|
3639
|
+
conversationId,
|
|
3640
|
+
laneId: profile.laneId,
|
|
3641
|
+
terminalId: result.terminalId,
|
|
3642
|
+
reason: 'The requesting terminal tab was closed during launch.',
|
|
3643
|
+
});
|
|
3644
|
+
}
|
|
3645
|
+
else if (result?.terminalId) {
|
|
3527
3646
|
void getAgentPlatformBridge().workspace.ptyStop({ terminalId: result.terminalId });
|
|
3647
|
+
}
|
|
3528
3648
|
return;
|
|
3529
3649
|
}
|
|
3530
3650
|
if (!result?.success || !result.terminalId) {
|
|
@@ -3533,7 +3653,7 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
3533
3653
|
...tab,
|
|
3534
3654
|
starting: false,
|
|
3535
3655
|
exited: true,
|
|
3536
|
-
output: tab.output + `${result?.error ||
|
|
3656
|
+
output: tab.output + `${result?.error || `Failed to start ${profile ? 'native provider TUI' : 'PowerShell'}.`}\r\n`,
|
|
3537
3657
|
}
|
|
3538
3658
|
: tab)));
|
|
3539
3659
|
return;
|
|
@@ -3542,11 +3662,26 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
3542
3662
|
? {
|
|
3543
3663
|
...tab,
|
|
3544
3664
|
terminalId: result.terminalId,
|
|
3545
|
-
cwd: result.cwd || cwd,
|
|
3665
|
+
cwd: ('cwd' in result && result.cwd) || cwd,
|
|
3666
|
+
...(profile && 'laneRevision' in result && typeof result.laneRevision === 'number'
|
|
3667
|
+
? { expectedLaneRevision: result.laneRevision }
|
|
3668
|
+
: {}),
|
|
3546
3669
|
starting: false,
|
|
3547
3670
|
exited: false,
|
|
3548
3671
|
}
|
|
3549
3672
|
: tab)));
|
|
3673
|
+
if (profile && 'laneRevision' in result && typeof result.laneRevision === 'number') {
|
|
3674
|
+
const conversation = useAgentChatStore.getState().getConversation(conversationId);
|
|
3675
|
+
const lane = conversation?.sessionUi?.activeLane;
|
|
3676
|
+
if (lane?.laneId === profile.laneId) {
|
|
3677
|
+
useAgentChatStore.getState().updateConversation(conversationId, {
|
|
3678
|
+
sessionUi: {
|
|
3679
|
+
...(conversation?.sessionUi || {}),
|
|
3680
|
+
activeLane: { ...lane, status: 'active_native', revision: result.laneRevision },
|
|
3681
|
+
},
|
|
3682
|
+
});
|
|
3683
|
+
}
|
|
3684
|
+
}
|
|
3550
3685
|
});
|
|
3551
3686
|
}, []);
|
|
3552
3687
|
const handleCreateRightPanelTerminal = useCallback(() => {
|
|
@@ -3559,6 +3694,7 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
3559
3694
|
const tab = {
|
|
3560
3695
|
id: tabId,
|
|
3561
3696
|
label: existingCount === 0 ? 'PowerShell' : `PowerShell ${existingCount + 1}`,
|
|
3697
|
+
kind: 'shell',
|
|
3562
3698
|
conversationId: activeConversationId,
|
|
3563
3699
|
terminalId: null,
|
|
3564
3700
|
cwd,
|
|
@@ -3579,22 +3715,66 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
3579
3715
|
terminalCapabilityEnabled,
|
|
3580
3716
|
terminalReady,
|
|
3581
3717
|
]);
|
|
3718
|
+
const handleCreateProviderSessionTui = useCallback(() => {
|
|
3719
|
+
const lane = activeSessionUi.activeLane;
|
|
3720
|
+
if (!activeConversationId || !lane?.laneId || guiOwnsActiveProviderSession)
|
|
3721
|
+
return null;
|
|
3722
|
+
const existing = rightPanelTerminalsRef.current.find((tab) => (tab.conversationId === activeConversationId
|
|
3723
|
+
&& tab.kind === 'provider-session'
|
|
3724
|
+
&& tab.laneId === lane.laneId));
|
|
3725
|
+
if (existing) {
|
|
3726
|
+
if (existing.exited && !existing.starting) {
|
|
3727
|
+
const cwd = existing.cwd || resolvedTerminalCwd || activeConversationAllowedDirectories[0] || '';
|
|
3728
|
+
setRightPanelTerminals((current) => current.map((tab) => (tab.id === existing.id
|
|
3729
|
+
? { ...tab, starting: true, exited: false, output: '' }
|
|
3730
|
+
: tab)));
|
|
3731
|
+
startRightPanelTerminal(existing.id, activeConversationId, cwd, activeConversationAllowedDirectories, { kind: 'provider-session', laneId: lane.laneId, expectedLaneRevision: lane.revision });
|
|
3732
|
+
}
|
|
3733
|
+
return existing.id;
|
|
3734
|
+
}
|
|
3735
|
+
const cwd = resolvedTerminalCwd || activeConversationAllowedDirectories[0] || '';
|
|
3736
|
+
const tabId = `provider-tui-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
3737
|
+
const tab = {
|
|
3738
|
+
id: tabId,
|
|
3739
|
+
label: lane.providerDisplayName ? `${lane.providerDisplayName} TUI` : 'Provider TUI',
|
|
3740
|
+
kind: 'provider-session',
|
|
3741
|
+
conversationId: activeConversationId,
|
|
3742
|
+
terminalId: null,
|
|
3743
|
+
cwd,
|
|
3744
|
+
allowedKey: `provider-session:${lane.laneId}`,
|
|
3745
|
+
laneId: lane.laneId,
|
|
3746
|
+
expectedLaneRevision: lane.revision,
|
|
3747
|
+
output: '',
|
|
3748
|
+
starting: true,
|
|
3749
|
+
exited: false,
|
|
3750
|
+
};
|
|
3751
|
+
setRightPanelTerminals((current) => [...current, tab]);
|
|
3752
|
+
startRightPanelTerminal(tabId, activeConversationId, cwd, activeConversationAllowedDirectories, { kind: 'provider-session', laneId: lane.laneId, expectedLaneRevision: lane.revision });
|
|
3753
|
+
return tabId;
|
|
3754
|
+
}, [
|
|
3755
|
+
activeConversationAllowedDirectories,
|
|
3756
|
+
activeConversationId,
|
|
3757
|
+
activeSessionUi.activeLane,
|
|
3758
|
+
guiOwnsActiveProviderSession,
|
|
3759
|
+
resolvedTerminalCwd,
|
|
3760
|
+
startRightPanelTerminal,
|
|
3761
|
+
]);
|
|
3582
3762
|
useEffect(() => {
|
|
3583
3763
|
if (!activeConversationId)
|
|
3584
3764
|
return;
|
|
3585
3765
|
if (!terminalCapabilityEnabled || !terminalReady) {
|
|
3586
|
-
const tabsForConversation = rightPanelTerminalsRef.current.filter((tab) => tab.conversationId === activeConversationId);
|
|
3766
|
+
const tabsForConversation = rightPanelTerminalsRef.current.filter((tab) => (tab.conversationId === activeConversationId && tab.kind === 'shell'));
|
|
3587
3767
|
for (const tab of tabsForConversation) {
|
|
3588
3768
|
if (tab.terminalId)
|
|
3589
3769
|
void getAgentPlatformBridge().workspace.ptyStop({ terminalId: tab.terminalId });
|
|
3590
3770
|
}
|
|
3591
3771
|
if (tabsForConversation.length > 0) {
|
|
3592
|
-
setRightPanelTerminals((current) => current.filter((tab) => tab.conversationId !== activeConversationId));
|
|
3772
|
+
setRightPanelTerminals((current) => current.filter((tab) => (tab.conversationId !== activeConversationId || tab.kind !== 'shell')));
|
|
3593
3773
|
}
|
|
3594
3774
|
return;
|
|
3595
3775
|
}
|
|
3596
3776
|
const current = rightPanelTerminalsRef.current;
|
|
3597
|
-
const conversationTabs = current.filter((tab) => tab.conversationId === activeConversationId);
|
|
3777
|
+
const conversationTabs = current.filter((tab) => (tab.conversationId === activeConversationId && tab.kind === 'shell'));
|
|
3598
3778
|
const validTabs = conversationTabs.filter((tab) => tab.allowedKey === rightPanelPtyAllowedKey);
|
|
3599
3779
|
const staleTabs = conversationTabs.filter((tab) => tab.allowedKey !== rightPanelPtyAllowedKey);
|
|
3600
3780
|
for (const tab of staleTabs) {
|
|
@@ -3603,11 +3783,13 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
3603
3783
|
}
|
|
3604
3784
|
if (staleTabs.length > 0) {
|
|
3605
3785
|
setRightPanelTerminals((latest) => latest.filter((tab) => (tab.conversationId !== activeConversationId ||
|
|
3786
|
+
tab.kind !== 'shell' ||
|
|
3606
3787
|
tab.allowedKey === rightPanelPtyAllowedKey)));
|
|
3607
3788
|
}
|
|
3608
3789
|
if (validTabs.length === 0) {
|
|
3609
3790
|
queueMicrotask(() => {
|
|
3610
3791
|
const stillMissing = !rightPanelTerminalsRef.current.some((tab) => (tab.conversationId === activeConversationId &&
|
|
3792
|
+
tab.kind === 'shell' &&
|
|
3611
3793
|
tab.allowedKey === rightPanelPtyAllowedKey));
|
|
3612
3794
|
if (stillMissing)
|
|
3613
3795
|
handleCreateRightPanelTerminal();
|
|
@@ -3620,6 +3802,29 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
3620
3802
|
terminalCapabilityEnabled,
|
|
3621
3803
|
terminalReady,
|
|
3622
3804
|
]);
|
|
3805
|
+
useEffect(() => {
|
|
3806
|
+
if (!activeConversationId)
|
|
3807
|
+
return;
|
|
3808
|
+
const activeLaneId = activeSessionUi.activeLane?.laneId;
|
|
3809
|
+
const staleProviderTabs = rightPanelTerminalsRef.current.filter((tab) => (tab.conversationId === activeConversationId
|
|
3810
|
+
&& tab.kind === 'provider-session'
|
|
3811
|
+
&& (!activeLaneId || tab.laneId !== activeLaneId)));
|
|
3812
|
+
for (const tab of staleProviderTabs) {
|
|
3813
|
+
if (tab.terminalId && tab.laneId) {
|
|
3814
|
+
void getAgentPlatformBridge().workspace.providerNativeStop?.({
|
|
3815
|
+
conversationId: tab.conversationId,
|
|
3816
|
+
laneId: tab.laneId,
|
|
3817
|
+
terminalId: tab.terminalId,
|
|
3818
|
+
reason: 'The active provider lane changed.',
|
|
3819
|
+
});
|
|
3820
|
+
}
|
|
3821
|
+
}
|
|
3822
|
+
if (staleProviderTabs.length > 0) {
|
|
3823
|
+
setRightPanelTerminals((current) => current.filter((tab) => (tab.conversationId !== activeConversationId
|
|
3824
|
+
|| tab.kind !== 'provider-session'
|
|
3825
|
+
|| (!!activeLaneId && tab.laneId === activeLaneId))));
|
|
3826
|
+
}
|
|
3827
|
+
}, [activeConversationId, activeSessionUi.activeLane?.laneId]);
|
|
3623
3828
|
const handleRightPanelPtyInput = useCallback((tabId, data) => {
|
|
3624
3829
|
const terminalId = rightPanelTerminalsRef.current.find((tab) => tab.id === tabId)?.terminalId;
|
|
3625
3830
|
if (!terminalId)
|
|
@@ -3634,8 +3839,17 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
3634
3839
|
}, []);
|
|
3635
3840
|
const handleCloseRightPanelTerminal = useCallback((tabId) => {
|
|
3636
3841
|
const tab = rightPanelTerminalsRef.current.find((entry) => entry.id === tabId);
|
|
3637
|
-
if (tab?.terminalId)
|
|
3842
|
+
if (tab?.terminalId && tab.kind === 'provider-session' && tab.laneId) {
|
|
3843
|
+
void getAgentPlatformBridge().workspace.providerNativeStop?.({
|
|
3844
|
+
conversationId: tab.conversationId,
|
|
3845
|
+
laneId: tab.laneId,
|
|
3846
|
+
terminalId: tab.terminalId,
|
|
3847
|
+
reason: 'The provider TUI tab was closed.',
|
|
3848
|
+
});
|
|
3849
|
+
}
|
|
3850
|
+
else if (tab?.terminalId) {
|
|
3638
3851
|
void getAgentPlatformBridge().workspace.ptyStop({ terminalId: tab.terminalId });
|
|
3852
|
+
}
|
|
3639
3853
|
setRightPanelTerminals((current) => current.filter((entry) => entry.id !== tabId));
|
|
3640
3854
|
}, []);
|
|
3641
3855
|
const handleClearRightPanelTerminal = useCallback((tabId) => {
|
|
@@ -3648,17 +3862,82 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
3648
3862
|
const tab = rightPanelTerminalsRef.current.find((entry) => entry.id === tabId);
|
|
3649
3863
|
if (!tab || tab.conversationId !== activeConversationId)
|
|
3650
3864
|
return;
|
|
3865
|
+
const activeLane = activeSessionUi.activeLane;
|
|
3866
|
+
if (tab.kind === 'provider-session' && (!activeLane?.laneId || tab.laneId !== activeLane.laneId)) {
|
|
3867
|
+
handleCloseRightPanelTerminal(tabId);
|
|
3868
|
+
return;
|
|
3869
|
+
}
|
|
3651
3870
|
const oldTerminalId = tab.terminalId;
|
|
3652
3871
|
const cwd = tab.cwd || resolvedTerminalCwd || activeConversationAllowedDirectories[0] || '';
|
|
3872
|
+
if (tab.kind === 'provider-session' && tab.laneId) {
|
|
3873
|
+
if (oldTerminalId) {
|
|
3874
|
+
void getAgentPlatformBridge().workspace.providerNativeStop?.({
|
|
3875
|
+
conversationId: tab.conversationId,
|
|
3876
|
+
laneId: tab.laneId,
|
|
3877
|
+
terminalId: oldTerminalId,
|
|
3878
|
+
reason: 'The user requested a native provider TUI restart.',
|
|
3879
|
+
});
|
|
3880
|
+
return;
|
|
3881
|
+
}
|
|
3882
|
+
const reconcile = getAgentPlatformBridge().workspace.providerReconcile;
|
|
3883
|
+
if (!reconcile || !activeLane)
|
|
3884
|
+
return;
|
|
3885
|
+
setRightPanelTerminals((current) => current.map((entry) => (entry.id === tabId
|
|
3886
|
+
? { ...entry, starting: true, output: `${entry.output}\r\n[reconciling native provider session]\r\n` }
|
|
3887
|
+
: entry)));
|
|
3888
|
+
void reconcile({
|
|
3889
|
+
conversationId: tab.conversationId,
|
|
3890
|
+
laneId: tab.laneId,
|
|
3891
|
+
expectedLaneRevision: activeLane.revision,
|
|
3892
|
+
acknowledgePartialContext: true,
|
|
3893
|
+
}).then((result) => {
|
|
3894
|
+
if (!result.success || !result.lane) {
|
|
3895
|
+
setRightPanelTerminals((current) => current.map((entry) => (entry.id === tabId
|
|
3896
|
+
? { ...entry, starting: false, exited: true, output: `${entry.output}[${result.error || 'Provider reconciliation failed.'}]\r\n` }
|
|
3897
|
+
: entry)));
|
|
3898
|
+
return;
|
|
3899
|
+
}
|
|
3900
|
+
const conversation = useAgentChatStore.getState().getConversation(tab.conversationId);
|
|
3901
|
+
useAgentChatStore.getState().updateConversation(tab.conversationId, {
|
|
3902
|
+
sessionUi: {
|
|
3903
|
+
...(conversation?.sessionUi || {}),
|
|
3904
|
+
activeLane: result.lane,
|
|
3905
|
+
lanes: [
|
|
3906
|
+
...((conversation?.sessionUi?.lanes || []).filter((lane) => lane.laneId !== result.lane.laneId)),
|
|
3907
|
+
result.lane,
|
|
3908
|
+
],
|
|
3909
|
+
},
|
|
3910
|
+
});
|
|
3911
|
+
setRightPanelTerminals((current) => current.map((entry) => (entry.id === tabId
|
|
3912
|
+
? {
|
|
3913
|
+
...entry,
|
|
3914
|
+
expectedLaneRevision: result.lane.revision,
|
|
3915
|
+
starting: false,
|
|
3916
|
+
exited: true,
|
|
3917
|
+
output: `${entry.output}[reconciled; chat may resume]\r\n`,
|
|
3918
|
+
}
|
|
3919
|
+
: entry)));
|
|
3920
|
+
});
|
|
3921
|
+
return;
|
|
3922
|
+
}
|
|
3653
3923
|
setRightPanelTerminals((current) => current.map((entry) => (entry.id === tabId
|
|
3654
3924
|
? { ...entry, terminalId: null, cwd, output: '', starting: true, exited: false }
|
|
3655
3925
|
: entry)));
|
|
3656
|
-
if (oldTerminalId)
|
|
3926
|
+
if (oldTerminalId) {
|
|
3657
3927
|
void getAgentPlatformBridge().workspace.ptyStop({ terminalId: oldTerminalId });
|
|
3658
|
-
|
|
3659
|
-
|
|
3928
|
+
}
|
|
3929
|
+
startRightPanelTerminal(tabId, tab.conversationId, cwd, activeConversationAllowedDirectories, undefined);
|
|
3930
|
+
}, [activeConversationAllowedDirectories, activeConversationId, activeSessionUi.activeLane, handleCloseRightPanelTerminal, resolvedTerminalCwd, startRightPanelTerminal]);
|
|
3660
3931
|
const rightPanelTerminalsForConversation = useMemo(() => (rightPanelTerminals.filter((tab) => (tab.conversationId === activeConversationId &&
|
|
3661
|
-
tab.
|
|
3932
|
+
(tab.kind === 'provider-session'
|
|
3933
|
+
? (activeLane?.laneId ? tab.laneId === activeLane.laneId : false)
|
|
3934
|
+
: tab.allowedKey === rightPanelPtyAllowedKey)))), [activeConversationId, activeLane?.laneId, rightPanelPtyAllowedKey, rightPanelTerminals]);
|
|
3935
|
+
const providerSessionTuiOwnsActiveSession = rightPanelTerminalsForConversation.some((tab) => (tab.kind === 'provider-session' && !tab.exited && (tab.starting || !!tab.terminalId)));
|
|
3936
|
+
const providerSessionTuiInputLockReason = providerSessionTuiOwnsActiveSession
|
|
3937
|
+
? 'Native provider TUI owns this session. Exit or close the TUI before sending from chat.'
|
|
3938
|
+
: activeLane?.status === 'externally_advanced' || activeLane?.status === 'needs_reconciliation'
|
|
3939
|
+
? 'The native provider session advanced outside chat. Use “Reconcile and return to chat” before continuing.'
|
|
3940
|
+
: undefined;
|
|
3662
3941
|
const patchActiveConversationSessionUi = useCallback((patch) => {
|
|
3663
3942
|
if (!activeConversationId)
|
|
3664
3943
|
return;
|
|
@@ -5614,7 +5893,7 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
5614
5893
|
}
|
|
5615
5894
|
}, [handleSubagentRefresh, policyCaller, refreshSubagentAvailability, setTransientEditorStatus]);
|
|
5616
5895
|
const handleOpenFolderForConversation = useCallback(async () => {
|
|
5617
|
-
if (!activeConversationId)
|
|
5896
|
+
if (!activeConversationId || providerSessionTuiInputLockReason || activeRuntimeRequestId)
|
|
5618
5897
|
return;
|
|
5619
5898
|
const result = await getAgentPlatformBridge()?.workspace?.pickDirectory?.();
|
|
5620
5899
|
if (!result?.success || !result.path)
|
|
@@ -5628,10 +5907,21 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
5628
5907
|
viewMode,
|
|
5629
5908
|
});
|
|
5630
5909
|
updateConversation(activeConversationId, {
|
|
5910
|
+
schemaVersion: 3,
|
|
5911
|
+
workspaceMode: 'workspace',
|
|
5631
5912
|
rootDirectory: normalizedDirectory,
|
|
5632
5913
|
grantedDirectories: prioritizeDirectory(activeConversation?.grantedDirectories, normalizedDirectory),
|
|
5914
|
+
sessionUi: resetAcpContinuationForWorkspaceChange(activeConversation?.sessionUi),
|
|
5633
5915
|
});
|
|
5634
|
-
}, [
|
|
5916
|
+
}, [
|
|
5917
|
+
activeConversation?.grantedDirectories,
|
|
5918
|
+
activeConversation?.sessionUi,
|
|
5919
|
+
activeConversationId,
|
|
5920
|
+
activeRuntimeRequestId,
|
|
5921
|
+
providerSessionTuiInputLockReason,
|
|
5922
|
+
updateConversation,
|
|
5923
|
+
viewMode,
|
|
5924
|
+
]);
|
|
5635
5925
|
const handleEditorContentChange = useCallback((path, content) => {
|
|
5636
5926
|
setOpenEditorTabs((prev) => prev.map((tab) => (tab.type === 'file' && tab.file.path === path
|
|
5637
5927
|
? { ...tab, file: { ...tab.file, content, isDirty: content !== tab.file.savedContent } }
|
|
@@ -7578,7 +7868,7 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
7578
7868
|
}, teamId: settingsPanel.teamId, teamName: teamForSettings?.name || settingsPanel.teamName, onClose: handleCloseSettings, onDelete: handleDeleteFromSettings }));
|
|
7579
7869
|
}
|
|
7580
7870
|
if (viewMode === 'inbox') {
|
|
7581
|
-
return (_jsx(React.Suspense, { fallback: _jsx("div", { className: "flex h-full items-center justify-center text-[12px] text-white/35", children: "Loading chat..." }), children: _jsx(AgentView, { agentId: MAIN_ASSISTANT_ID, conversationId: selectedInboxConversationId, isMainAssistant: true, agentName: MAIN_ASSISTANT_NAME, model: MAIN_ASSISTANT_MODEL, templateName: "Main Assistant", workspaceName: "All Workspaces", teamName: "Global", systemPrompt: enrichedMainSystemPromptWithCodeContext, capabilities: { terminal: true, fileRead: true, fileWrite: true, appLaunch: true }, permissionProfile: "standard", allowedDirectories: [], approvalRules: [], allowedApps: [], teamAgents: [], onCreateWorkspace: handleMainCreateWorkspace, onCreateTeam: handleMainCreateTeam, onCreateTeamAgent: handleMainCreateTeamAgent, onGetInboxWorkspaceOptions: handleGetInboxWorkspaceOptions, onBindInboxConversationToWorkspace: handleBindInboxConversationToWorkspace, onOpenReassignedConversation: handleOpenReassignedConversation, onOpenEditorPath: handleOpenEditorPath, onOpenEditorDiff: handleOpenEditorDiff, onPeekEditorPath: handlePeekEditorPath, onPeekEditorDiff: handlePeekEditorDiff, renderWorkbenchPanel: false, onOpenConversationSettings: handleSelectSidebarSettings, onConversationCreated: activateSessionConversation }) }));
|
|
7871
|
+
return (_jsx(React.Suspense, { fallback: _jsx("div", { className: "flex h-full items-center justify-center text-[12px] text-white/35", children: "Loading chat..." }), children: _jsx(AgentView, { agentId: MAIN_ASSISTANT_ID, conversationId: selectedInboxConversationId, isMainAssistant: true, agentName: MAIN_ASSISTANT_NAME, model: MAIN_ASSISTANT_MODEL, templateName: "Main Assistant", workspaceName: "All Workspaces", teamName: "Global", systemPrompt: enrichedMainSystemPromptWithCodeContext, capabilities: { terminal: true, fileRead: true, fileWrite: true, appLaunch: true }, permissionProfile: "standard", allowedDirectories: [], approvalRules: [], allowedApps: [], teamAgents: [], onCreateWorkspace: handleMainCreateWorkspace, onCreateTeam: handleMainCreateTeam, onCreateTeamAgent: handleMainCreateTeamAgent, onGetInboxWorkspaceOptions: handleGetInboxWorkspaceOptions, onBindInboxConversationToWorkspace: handleBindInboxConversationToWorkspace, onOpenReassignedConversation: handleOpenReassignedConversation, onOpenEditorPath: handleOpenEditorPath, onOpenEditorDiff: handleOpenEditorDiff, onPeekEditorPath: handlePeekEditorPath, onPeekEditorDiff: handlePeekEditorDiff, renderWorkbenchPanel: false, onOpenConversationSettings: handleSelectSidebarSettings, externalInputLockReason: providerSessionTuiInputLockReason, onConversationCreated: activateSessionConversation }) }));
|
|
7582
7872
|
}
|
|
7583
7873
|
// If an agent is selected, show the chat view.
|
|
7584
7874
|
// Conversation is created lazily on first message send.
|
|
@@ -7607,7 +7897,7 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
7607
7897
|
sp += `\n\nInstalled XENO apps: ${runtimeContext.installedApps.join(', ')}`;
|
|
7608
7898
|
}
|
|
7609
7899
|
return sp || undefined;
|
|
7610
|
-
})()), templateName: selectedAgent.templateName, workspaceName: selectedAgent.workspaceName, teamName: selectedAgent.teamName, capabilities: selectedAgent.capabilities, permissionProfile: selectedAgent.permissionProfile || 'standard', runtimeSelection: selectedAgent.runtimeSelection, allowedDirectories: selectedAgent.allowedDirectories, approvalRules: selectedAgent.approvalRules || [], onAddApprovalRule: (rule) => {
|
|
7900
|
+
})()), templateName: selectedAgent.templateName, workspaceName: selectedAgent.workspaceName, teamName: selectedAgent.teamName, capabilities: selectedAgent.capabilities, permissionProfile: selectedAgent.permissionProfile || 'standard', runtimeSelection: selectedAgent.runtimeSelection, externalInputLockReason: providerSessionTuiInputLockReason, allowedDirectories: selectedAgent.allowedDirectories, approvalRules: selectedAgent.approvalRules || [], onAddApprovalRule: (rule) => {
|
|
7611
7901
|
addAgentApprovalRule(selectedAgentHierarchy.workspace.id, selectedAgentHierarchy.team.id, selectedAgent.id, rule);
|
|
7612
7902
|
}, allowedApps: resolvedAllowedApps, teamAgents: teamAgents, onCreateAgent: handleCreateAgentFromAgent, onAskAgent: handleAskAgentFromAgent, onEnableFileWrite: enableSelectedAgentFileWrite, onOpenEditorPath: handleOpenEditorPath, onOpenEditorDiff: handleOpenEditorDiff, onPeekEditorPath: handlePeekEditorPath, onPeekEditorDiff: handlePeekEditorDiff, onOpenRuntimeSettings: () => {
|
|
7613
7903
|
handleOpenSettings({
|
|
@@ -7673,7 +7963,7 @@ export default function AgentInterface({ surface = 'embedded', initialSdkSession
|
|
|
7673
7963
|
`subagentRunId ?? conversationId`, so the conversation id
|
|
7674
7964
|
IS the run id here. Passing anything else would ask the
|
|
7675
7965
|
host about a run it has never heard of. */
|
|
7676
|
-
reviewRunId: activeConversationId, traceMessages: traceMessages, selectedTraceMessage: selectedTraceMessage, outputEntries: outputEntries, problemEntries: problemEntries, onSelectTab: handleSelectWorkbenchTab, onClose: handleCloseWorkbenchPanel, onSelectTraceMessage: handleSelectWorkbenchTraceMessage, onOpenChatSettings: handleOpenActiveConversationSettings, onOpenChatAcpAgents: handleOpenActiveConversationAcpAgents, onOpenChatPlugins: handleOpenPluginManager, onOpenChatKnowledge: handleOpenActiveConversationKnowledge, onOpenEditorPath: handleOpenEditorPath, onOpenEditorDiff: handleOpenEditorDiff, terminalCapabilityEnabled: terminalCapabilityEnabled, terminalReady: terminalReady, resolvedTerminalCwd: resolvedTerminalCwd, terminalDraftCwd: terminalDraftCwd, terminalDraftInput: terminalDraftInput, onChangeTerminalCwd: setTerminalDraftCwd, onChangeTerminalInput: setTerminalDraftInput, onResetTerminalCwd: handleResetWorkbenchTerminalCwd, onClearTerminalHistory: handleClearWorkbenchTerminalHistory, onRunTerminalCommand: () => { void handleRunWorkbenchTerminalCommand(); }, terminalHistory: terminalHistory, liveTerminalRuns: liveTerminalRunsForConversation, onReuseTerminalEntry: handleReuseWorkbenchTerminalEntry, onStopTerminalRun: (terminalId) => { void handleStopWorkbenchTerminalRun(terminalId); }, codeWorkbench: codeWorkbenchState, onCodeQueryChange: setCodeWorkbenchQuery, onCodeModeChange: handleCodeModeChange, onCodeIndex: handleCodeIndex, onCodeSearch: handleCodeSearch, onCodeOpenPath: handleCodeOpenPath, onCodeToggleFile: handleCodeToggleFile, onCodeToggleSymbol: handleCodeToggleSymbol, onCodeCreateContextPack: () => { void handleCodeCreateContextPack(); }, onCodeMaterializeContextPack: (packId) => { void handleCodeMaterializeContextPack(packId); }, onCodeAttachContextPack: (packId) => { void handleCodeAttachContextPack(packId); }, onCodeRefreshContextPacks: () => { void handleCodeRefreshContextPacks(); }, onCodeRefreshChanges: () => { void handleCodeRefreshChanges(); }, onCodeRefreshActions: () => { void handleCodeRefreshActions(); }, onCodeApplyAction: (action) => { void handleCodeApplyAction(action); }, onCodeOrganizeImports: () => { void handleCodeOrganizeImports(); }, onCodeRenameSymbol: () => { void handleCodeRenameSymbol(); }, onCodeRefreshLanguageServices: () => { void handleCodeRefreshLanguageServices(); }, onCodeControlLanguageService: (serviceId, action) => { void handleCodeControlLanguageService(serviceId, action); }, onCodeRepairIndex: () => { void handleCodeRepairIndex(); }, engineeringWorkbench: engineeringWorkbenchState, onEngineeringRefresh: () => { void handleEngineeringRefresh(); }, onEngineeringTogglePath: handleEngineeringTogglePath, onEngineeringOpenPath: handleEngineeringOpenPath, onEngineeringPreviewDiff: (paths) => { void handleEngineeringPreviewDiff(paths); }, onEngineeringStage: (paths) => { void handleEngineeringStage(paths); }, onEngineeringUnstage: (paths) => { void handleEngineeringUnstage(paths); }, onEngineeringRunCheck: (checkId) => { void handleEngineeringRunCheck(checkId); }, onEngineeringStartBackgroundCheck: (checkId) => { void handleEngineeringStartBackgroundCheck(checkId); }, onEngineeringStopBackgroundRun: (runId) => { void handleEngineeringStopBackgroundRun(runId); }, onEngineeringReadBackgroundRunOutput: (runId) => { void handleEngineeringReadBackgroundRunOutput(runId); }, onEngineeringCommitMessageChange: setEngineeringCommitMessage, onEngineeringCommit: () => { void handleEngineeringCommit(); }, onEngineeringQueuePatchReview: () => { void handleEngineeringQueuePatchReview(); }, onEngineeringUpdatePatchReview: (id, status) => { void handleEngineeringUpdatePatchReview(id, status); }, onEngineeringReviewPatchSelection: (request) => { void handleEngineeringReviewPatchSelection(request); }, onEngineeringCompareCheckpoints: (fromCheckpointId, toCheckpointId) => { void handleEngineeringCompareCheckpoints(fromCheckpointId, toCheckpointId); }, onEngineeringRestoreCheckpoint: (checkpointId) => { void handleEngineeringRestoreCheckpoint(checkpointId); }, cliControlPlane: cliControlPlaneState, cliControlPlaneCaller: policyCaller, cliControlPlaneConversationId: activeConversationId, cliControlPlaneRemoteBackendId: selectedAgent?.runtimeSelection?.remoteBackendId || '', onCliControlPlaneInspect: () => { void handleCliControlPlaneInspect(); }, onCliControlPlaneInspectOperation: (operation) => { void handleCliControlPlaneInspectOperation(operation); }, onCliControlPlaneRemoteRunOperation: (action, runId) => { void handleCliControlPlaneRemoteRunOperation(action, runId); }, subagentWorkbench: subagentWorkbenchState, subagentDelegationTargets: subagentDelegationTargets, subagentDelegationSourceName: selectedAgent?.name, subagentDelegationDisabledReason: subagentDelegationDisabledReason, onSubagentRefresh: () => { void handleSubagentRefresh(); }, onSubagentRecoverRuns: () => { void handleSubagentRecoverRuns(); }, onSubagentSelectRun: handleSubagentSelectRun, onSubagentOpenConversation: handleSubagentOpenConversation, onSubagentCancelRun: (run) => { void handleSubagentCancelRun(run); }, onCreateSubagentDelegation: handleWorkbenchSubagentDelegation, policyWorkbench: policyWorkbenchState, onPolicyRefresh: () => { void handlePolicyRefresh(); } }) }) }) }))] })] }), folderPanelOpen && (_jsx(FolderSidebar, { conversationId: activeConversationId, rootDirectory: activeConversation?.rootDirectory || null, allowedDirectories: activeConversationAllowedDirectories, onOpenFolder: handleOpenFolderForConversation, onClose: () => setFolderPanelOpen(false), onOpenFile: handleOpenEditorFile, activeFilePath: activeEditorFilePath, terminalCapabilityEnabled: terminalCapabilityEnabled, terminalReady: terminalReady, resolvedTerminalCwd: resolvedTerminalCwd, terminalTabs: rightPanelTerminalsForConversation, onPtyInput: handleRightPanelPtyInput, onPtyResize: handleRightPanelPtyResize, onCreateTerminal: handleCreateRightPanelTerminal, onCloseTerminal: handleCloseRightPanelTerminal, onClearTerminal: handleClearRightPanelTerminal, onRestartTerminal: handleRestartRightPanelTerminal, width: rightPanelWidth, onResizeStart: handleRightPanelResizeStart })), rightPanelResizing && (_jsx("div", { className: "fixed inset-0 z-[9999] cursor-col-resize bg-transparent", "aria-hidden": "true" })), pendingPermission && (_jsx(PermissionDialog, { request: pendingPermission, onDecision: resolvePermission }))] }));
|
|
7966
|
+
reviewRunId: activeConversationId, traceMessages: traceMessages, selectedTraceMessage: selectedTraceMessage, outputEntries: outputEntries, problemEntries: problemEntries, onSelectTab: handleSelectWorkbenchTab, onClose: handleCloseWorkbenchPanel, onSelectTraceMessage: handleSelectWorkbenchTraceMessage, onOpenChatSettings: handleOpenActiveConversationSettings, onOpenChatAcpAgents: handleOpenActiveConversationAcpAgents, onOpenChatPlugins: handleOpenPluginManager, onOpenChatKnowledge: handleOpenActiveConversationKnowledge, onOpenEditorPath: handleOpenEditorPath, onOpenEditorDiff: handleOpenEditorDiff, terminalCapabilityEnabled: terminalCapabilityEnabled, terminalReady: terminalReady, resolvedTerminalCwd: resolvedTerminalCwd, terminalDraftCwd: terminalDraftCwd, terminalDraftInput: terminalDraftInput, onChangeTerminalCwd: setTerminalDraftCwd, onChangeTerminalInput: setTerminalDraftInput, onResetTerminalCwd: handleResetWorkbenchTerminalCwd, onClearTerminalHistory: handleClearWorkbenchTerminalHistory, onRunTerminalCommand: () => { void handleRunWorkbenchTerminalCommand(); }, terminalHistory: terminalHistory, liveTerminalRuns: liveTerminalRunsForConversation, onReuseTerminalEntry: handleReuseWorkbenchTerminalEntry, onStopTerminalRun: (terminalId) => { void handleStopWorkbenchTerminalRun(terminalId); }, codeWorkbench: codeWorkbenchState, onCodeQueryChange: setCodeWorkbenchQuery, onCodeModeChange: handleCodeModeChange, onCodeIndex: handleCodeIndex, onCodeSearch: handleCodeSearch, onCodeOpenPath: handleCodeOpenPath, onCodeToggleFile: handleCodeToggleFile, onCodeToggleSymbol: handleCodeToggleSymbol, onCodeCreateContextPack: () => { void handleCodeCreateContextPack(); }, onCodeMaterializeContextPack: (packId) => { void handleCodeMaterializeContextPack(packId); }, onCodeAttachContextPack: (packId) => { void handleCodeAttachContextPack(packId); }, onCodeRefreshContextPacks: () => { void handleCodeRefreshContextPacks(); }, onCodeRefreshChanges: () => { void handleCodeRefreshChanges(); }, onCodeRefreshActions: () => { void handleCodeRefreshActions(); }, onCodeApplyAction: (action) => { void handleCodeApplyAction(action); }, onCodeOrganizeImports: () => { void handleCodeOrganizeImports(); }, onCodeRenameSymbol: () => { void handleCodeRenameSymbol(); }, onCodeRefreshLanguageServices: () => { void handleCodeRefreshLanguageServices(); }, onCodeControlLanguageService: (serviceId, action) => { void handleCodeControlLanguageService(serviceId, action); }, onCodeRepairIndex: () => { void handleCodeRepairIndex(); }, engineeringWorkbench: engineeringWorkbenchState, onEngineeringRefresh: () => { void handleEngineeringRefresh(); }, onEngineeringTogglePath: handleEngineeringTogglePath, onEngineeringOpenPath: handleEngineeringOpenPath, onEngineeringPreviewDiff: (paths) => { void handleEngineeringPreviewDiff(paths); }, onEngineeringStage: (paths) => { void handleEngineeringStage(paths); }, onEngineeringUnstage: (paths) => { void handleEngineeringUnstage(paths); }, onEngineeringRunCheck: (checkId) => { void handleEngineeringRunCheck(checkId); }, onEngineeringStartBackgroundCheck: (checkId) => { void handleEngineeringStartBackgroundCheck(checkId); }, onEngineeringStopBackgroundRun: (runId) => { void handleEngineeringStopBackgroundRun(runId); }, onEngineeringReadBackgroundRunOutput: (runId) => { void handleEngineeringReadBackgroundRunOutput(runId); }, onEngineeringCommitMessageChange: setEngineeringCommitMessage, onEngineeringCommit: () => { void handleEngineeringCommit(); }, onEngineeringQueuePatchReview: () => { void handleEngineeringQueuePatchReview(); }, onEngineeringUpdatePatchReview: (id, status) => { void handleEngineeringUpdatePatchReview(id, status); }, onEngineeringReviewPatchSelection: (request) => { void handleEngineeringReviewPatchSelection(request); }, onEngineeringCompareCheckpoints: (fromCheckpointId, toCheckpointId) => { void handleEngineeringCompareCheckpoints(fromCheckpointId, toCheckpointId); }, onEngineeringRestoreCheckpoint: (checkpointId) => { void handleEngineeringRestoreCheckpoint(checkpointId); }, cliControlPlane: cliControlPlaneState, cliControlPlaneCaller: policyCaller, cliControlPlaneConversationId: activeConversationId, cliControlPlaneRemoteBackendId: selectedAgent?.runtimeSelection?.remoteBackendId || '', onCliControlPlaneInspect: () => { void handleCliControlPlaneInspect(); }, onCliControlPlaneInspectOperation: (operation) => { void handleCliControlPlaneInspectOperation(operation); }, onCliControlPlaneRemoteRunOperation: (action, runId) => { void handleCliControlPlaneRemoteRunOperation(action, runId); }, subagentWorkbench: subagentWorkbenchState, subagentDelegationTargets: subagentDelegationTargets, subagentDelegationSourceName: selectedAgent?.name, subagentDelegationDisabledReason: subagentDelegationDisabledReason, onSubagentRefresh: () => { void handleSubagentRefresh(); }, onSubagentRecoverRuns: () => { void handleSubagentRecoverRuns(); }, onSubagentSelectRun: handleSubagentSelectRun, onSubagentOpenConversation: handleSubagentOpenConversation, onSubagentCancelRun: (run) => { void handleSubagentCancelRun(run); }, onCreateSubagentDelegation: handleWorkbenchSubagentDelegation, policyWorkbench: policyWorkbenchState, onPolicyRefresh: () => { void handlePolicyRefresh(); } }) }) }) }))] })] }), folderPanelOpen && (_jsx(FolderSidebar, { conversationId: activeConversationId, rootDirectory: activeConversation?.rootDirectory || null, allowedDirectories: activeConversationAllowedDirectories, onOpenFolder: handleOpenFolderForConversation, onClose: () => setFolderPanelOpen(false), onOpenFile: handleOpenEditorFile, activeFilePath: activeEditorFilePath, terminalCapabilityEnabled: terminalCapabilityEnabled, terminalReady: terminalReady, providerSessionTuiReady: providerSessionTuiReady, resolvedTerminalCwd: resolvedTerminalCwd, terminalTabs: rightPanelTerminalsForConversation, onPtyInput: handleRightPanelPtyInput, onPtyResize: handleRightPanelPtyResize, onCreateTerminal: handleCreateRightPanelTerminal, onCreateProviderTui: handleCreateProviderSessionTui, onCloseTerminal: handleCloseRightPanelTerminal, onClearTerminal: handleClearRightPanelTerminal, onRestartTerminal: handleRestartRightPanelTerminal, width: rightPanelWidth, onResizeStart: handleRightPanelResizeStart })), rightPanelResizing && (_jsx("div", { className: "fixed inset-0 z-[9999] cursor-col-resize bg-transparent", "aria-hidden": "true" })), pendingPermission && (_jsx(PermissionDialog, { request: pendingPermission, onDecision: resolvePermission }))] }));
|
|
7677
7967
|
if (surface !== 'standalone-desktop') {
|
|
7678
7968
|
return (_jsxs("div", { className: "flex h-full w-full flex-col overflow-hidden", "data-xeno-agent-embedded-shell": "true", children: [_jsx("header", { className: "xeno-chrome-shell xeno-border-subtle h-10 flex-shrink-0 border-b", "data-xeno-agent-session-header": "embedded", "data-xeno-hub-header-style": "true", children: sessionTabsNode }), _jsx("div", { className: "min-h-0 min-w-0 flex-1", children: agentWorkspace })] }));
|
|
7679
7969
|
}
|