@xenosystem/agent-interface-ui 0.1.7 → 0.1.9

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.
@@ -138,6 +138,7 @@ interface AgentViewProps {
138
138
  onSelectAcpRuntime?: (acpAgentConfigId?: string, providerModel?: string) => void;
139
139
  onConversationCreated?: (conversationId: string) => void;
140
140
  renderWorkbenchPanel?: boolean;
141
+ externalInputLockReason?: string;
141
142
  }
142
143
  export declare function AgentView(props: AgentViewProps): React.JSX.Element;
143
144
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"AgentView.d.ts","sourceRoot":"","sources":["../../../src/components/agent/AgentView.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AgentView.d.ts","sourceRoot":"","sources":["../../../src/components/agent/AgentView.tsx"],"names":[],"mappings":"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"}
@@ -12,7 +12,7 @@ import { AppWindow, ArrowUp, Square, X, Check, Cloud, Monitor, ChevronDown, Chev
12
12
  import ReactMarkdown, { defaultUrlTransform } from 'react-markdown';
13
13
  import remarkGfm from 'remark-gfm';
14
14
  import CodeBlock from '../ui/CodeBlock.js';
15
- import { useAgentChatStore, setupAgentChatListeners, projectConversationRuntimeState } from '../../stores/agentChatStore.js';
15
+ import { useAgentChatStore, setupAgentChatListeners, projectConversationRuntimeState, resolveConversationWorkspaceBinding, resetAcpContinuationForWorkspaceChange } from '../../stores/agentChatStore.js';
16
16
  import { useAcpAgentStore } from '../../stores/acpAgentStore.js';
17
17
  import { useTabStore } from '../../stores/tabStore.js';
18
18
  import { useAuthStore } from '../../stores/authStore.js';
@@ -3191,6 +3191,7 @@ export function AgentView(props) {
3191
3191
  const conversation = conversationId ? conversations[conversationId] : undefined;
3192
3192
  const updateConversation = useAgentChatStore(s => s.updateConversation);
3193
3193
  const [input, setInput] = useState('');
3194
+ const [isSelectingConversationWorkspace, setIsSelectingConversationWorkspace] = useState(false);
3194
3195
  const [pendingAttachments, setPendingAttachments] = useState([]);
3195
3196
  const [editingMsgId, setEditingMsgId] = useState(null);
3196
3197
  const [isRunningCommand, setIsRunningCommand] = useState(false);
@@ -3849,11 +3850,37 @@ export function AgentView(props) {
3849
3850
  // Get messages from the conversation store
3850
3851
  const conversationHydrating = !!conversationId && !conversation;
3851
3852
  const conversationGrantedDirectories = conversation?.grantedDirectories || EMPTY_STRINGS;
3852
- const effectiveAllowedDirectories = useMemo(() => Array.from(new Set([
3853
- ...(allowedDirectories || EMPTY_STRINGS),
3854
- ...conversationGrantedDirectories,
3855
- ...(conversation?.rootDirectory ? [conversation.rootDirectory] : EMPTY_STRINGS),
3856
- ])), [allowedDirectories, conversation?.rootDirectory, conversationGrantedDirectories]);
3853
+ const workspaceBinding = useMemo(() => resolveConversationWorkspaceBinding({
3854
+ workspaceMode: conversation?.workspaceMode,
3855
+ rootDirectory: conversation?.rootDirectory,
3856
+ grantedDirectories: conversationGrantedDirectories,
3857
+ inheritedDirectories: allowedDirectories,
3858
+ hasMessages: (conversation?.messages.length || 0) > 0,
3859
+ }), [
3860
+ allowedDirectories,
3861
+ conversation?.messages.length,
3862
+ conversation?.rootDirectory,
3863
+ conversation?.workspaceMode,
3864
+ conversationGrantedDirectories,
3865
+ ]);
3866
+ const effectiveAllowedDirectories = workspaceBinding.allowedDirectories;
3867
+ useEffect(() => {
3868
+ if (!conversationId || !conversation || !workspaceBinding.legacyInferred)
3869
+ return;
3870
+ updateConversation(conversationId, {
3871
+ schemaVersion: 3,
3872
+ workspaceMode: workspaceBinding.mode,
3873
+ ...(workspaceBinding.mode === 'workspace'
3874
+ ? {
3875
+ rootDirectory: workspaceBinding.rootDirectory,
3876
+ grantedDirectories: workspaceBinding.allowedDirectories,
3877
+ }
3878
+ : {
3879
+ rootDirectory: undefined,
3880
+ grantedDirectories: [],
3881
+ }),
3882
+ });
3883
+ }, [conversation, conversationId, updateConversation, workspaceBinding]);
3857
3884
  const effectiveApprovalRules = props.approvalRules || EMPTY_APPROVAL_RULES;
3858
3885
  const systemPromptModel = runtimeProvider.kind === 'acp-provider'
3859
3886
  ? (acpProviderModel || selectedAcpAgentConfigId || actualModelId)
@@ -3917,7 +3944,9 @@ export function AgentView(props) {
3917
3944
  && !!selectedAcpAgentConfigId
3918
3945
  && !acpRuntimeAgentDetails[selectedAcpAgentConfigId]
3919
3946
  && !acpRuntimeAgentDetailErrors[selectedAcpAgentConfigId];
3920
- const inputLocked = isRunningCommand
3947
+ const inputLocked = workspaceBinding.mode === 'unselected'
3948
+ || !!props.externalInputLockReason
3949
+ || isRunningCommand
3921
3950
  || acpRuntimeReadinessPending
3922
3951
  || (runtimeProvider.kind !== 'acp-provider' && !isModelReady)
3923
3952
  || cloudModelUnavailable;
@@ -3998,7 +4027,7 @@ export function AgentView(props) {
3998
4027
  const resolvedTerminalCwd = (sessionUi?.terminalCwd || conversation?.rootDirectory || effectiveAllowedDirectories[0] || '').trim();
3999
4028
  const sdkSessionWorkingDirectory = (conversation?.rootDirectory || effectiveAllowedDirectories[0] || '').trim();
4000
4029
  const terminalCapabilityEnabled = !!props.capabilities?.terminal;
4001
- const terminalReady = terminalCapabilityEnabled && effectiveAllowedDirectories.length > 0;
4030
+ const terminalReady = terminalCapabilityEnabled && Boolean(resolvedTerminalCwd || conversation?.id);
4002
4031
  const localModelName = actualModelId.startsWith('local:') ? actualModelId.slice('local:'.length) : actualModelId;
4003
4032
  const localRuntimeAvailable = localRuntimeState?.available ?? null;
4004
4033
  const localRuntimeNeedsStart = selectedModel.startsWith('local:')
@@ -4490,10 +4519,20 @@ export function AgentView(props) {
4490
4519
  if (currentConversationId)
4491
4520
  return currentConversationId;
4492
4521
  const createdConversationId = createConversation(agentId);
4522
+ const inheritedWorkspaceRoot = workspaceBinding.mode === 'workspace'
4523
+ ? workspaceBinding.rootDirectory || workspaceBinding.allowedDirectories[0]
4524
+ : undefined;
4493
4525
  updateConversation(createdConversationId, {
4494
- schemaVersion: 2,
4526
+ schemaVersion: 3,
4495
4527
  model: selectedModel,
4496
4528
  runtime: currentRuntimeBinding,
4529
+ workspaceId: props.workspaceId,
4530
+ teamId: props.teamId,
4531
+ workspaceMode: workspaceBinding.mode,
4532
+ rootDirectory: inheritedWorkspaceRoot,
4533
+ grantedDirectories: workspaceBinding.mode === 'workspace'
4534
+ ? workspaceBinding.allowedDirectories
4535
+ : [],
4497
4536
  });
4498
4537
  onConversationCreated?.(createdConversationId);
4499
4538
  return createdConversationId;
@@ -4505,6 +4544,95 @@ export function AgentView(props) {
4505
4544
  onConversationCreated,
4506
4545
  selectedModel,
4507
4546
  updateConversation,
4547
+ workspaceBinding,
4548
+ props.teamId,
4549
+ props.workspaceId,
4550
+ ]);
4551
+ const chooseConversationWorkspace = useCallback(async () => {
4552
+ if (isBusy || props.externalInputLockReason || isSelectingConversationWorkspace)
4553
+ return;
4554
+ setIsSelectingConversationWorkspace(true);
4555
+ try {
4556
+ const result = await getAgentPlatformBridge()?.workspace?.pickDirectory?.();
4557
+ if (!result?.success || !result.path)
4558
+ return;
4559
+ const directory = result.path.trim();
4560
+ if (!directory)
4561
+ return;
4562
+ const targetConversationId = ensureConversationId(conversationId);
4563
+ const current = useAgentChatStore.getState().conversations[targetConversationId];
4564
+ updateConversation(targetConversationId, {
4565
+ schemaVersion: 3,
4566
+ workspaceMode: 'workspace',
4567
+ rootDirectory: directory,
4568
+ grantedDirectories: [
4569
+ directory,
4570
+ ...(current?.grantedDirectories || []).filter((entry) => entry !== directory),
4571
+ ],
4572
+ sessionUi: resetAcpContinuationForWorkspaceChange(current?.sessionUi),
4573
+ });
4574
+ }
4575
+ finally {
4576
+ setIsSelectingConversationWorkspace(false);
4577
+ }
4578
+ }, [
4579
+ conversationId,
4580
+ ensureConversationId,
4581
+ isBusy,
4582
+ isSelectingConversationWorkspace,
4583
+ props.externalInputLockReason,
4584
+ updateConversation,
4585
+ ]);
4586
+ const chooseConversationChatOnly = useCallback(() => {
4587
+ if (isBusy || props.externalInputLockReason || isSelectingConversationWorkspace)
4588
+ return;
4589
+ const targetConversationId = ensureConversationId(conversationId);
4590
+ const current = useAgentChatStore.getState().conversations[targetConversationId];
4591
+ updateConversation(targetConversationId, {
4592
+ schemaVersion: 3,
4593
+ workspaceMode: 'chat-only',
4594
+ rootDirectory: undefined,
4595
+ grantedDirectories: [],
4596
+ sessionUi: resetAcpContinuationForWorkspaceChange(current?.sessionUi),
4597
+ });
4598
+ }, [
4599
+ conversationId,
4600
+ ensureConversationId,
4601
+ isBusy,
4602
+ isSelectingConversationWorkspace,
4603
+ props.externalInputLockReason,
4604
+ updateConversation,
4605
+ ]);
4606
+ const handleSelectWorkspaceMode = useCallback(async (mode) => {
4607
+ if (isBusy || props.externalInputLockReason || isSelectingConversationWorkspace)
4608
+ return;
4609
+ if (mode === 'chat-only') {
4610
+ chooseConversationChatOnly();
4611
+ return;
4612
+ }
4613
+ const current = conversationId ? useAgentChatStore.getState().conversations[conversationId] : undefined;
4614
+ const explicitRoot = (current?.rootDirectory || current?.grantedDirectories?.[0] || '').trim();
4615
+ if (explicitRoot) {
4616
+ const targetConversationId = ensureConversationId(conversationId);
4617
+ updateConversation(targetConversationId, {
4618
+ schemaVersion: 3,
4619
+ workspaceMode: 'workspace',
4620
+ rootDirectory: explicitRoot,
4621
+ grantedDirectories: current?.grantedDirectories?.length ? current.grantedDirectories : [explicitRoot],
4622
+ sessionUi: resetAcpContinuationForWorkspaceChange(current?.sessionUi),
4623
+ });
4624
+ return;
4625
+ }
4626
+ await chooseConversationWorkspace();
4627
+ }, [
4628
+ chooseConversationChatOnly,
4629
+ chooseConversationWorkspace,
4630
+ conversationId,
4631
+ ensureConversationId,
4632
+ isBusy,
4633
+ isSelectingConversationWorkspace,
4634
+ props.externalInputLockReason,
4635
+ updateConversation,
4508
4636
  ]);
4509
4637
  const runtimeProviderBlockedMessage = useMemo(() => {
4510
4638
  return runtimeProvider.statusReason || `${runtimeProvider.displayName} is ${runtimeProvider.status.replace('_', ' ')}.`;
@@ -6004,7 +6132,7 @@ export function AgentView(props) {
6004
6132
  textareaRef.current.style.height = 'auto';
6005
6133
  return;
6006
6134
  }
6007
- if (effectiveAllowedDirectories.length === 0) {
6135
+ if (workspaceBinding.mode === 'workspace' && effectiveAllowedDirectories.length === 0) {
6008
6136
  appendMessage(targetConversationId, { role: 'assistant', content: 'No allowed directories configured. Open agent settings and add one.', error: 'No allowed directories configured.' });
6009
6137
  if (textareaRef.current)
6010
6138
  textareaRef.current.style.height = 'auto';
@@ -6019,8 +6147,9 @@ export function AgentView(props) {
6019
6147
  setIsRunningCommand(true);
6020
6148
  const result = await getAgentPlatformBridge().workspace.runCommand({
6021
6149
  command,
6022
- cwd: effectiveAllowedDirectories[0],
6023
- allowedDirs: effectiveAllowedDirectories
6150
+ cwd: effectiveAllowedDirectories[0] || '',
6151
+ allowedDirs: effectiveAllowedDirectories,
6152
+ conversationId: targetConversationId,
6024
6153
  });
6025
6154
  setIsRunningCommand(false);
6026
6155
  const blocks = [];
@@ -6829,7 +6958,7 @@ export function AgentView(props) {
6829
6958
  setToolStatus('Enter a command first.');
6830
6959
  return;
6831
6960
  }
6832
- if (!cwd) {
6961
+ if (!cwd && !conversation?.id) {
6833
6962
  setToolStatus('Open or choose a folder first to run terminal commands.');
6834
6963
  return;
6835
6964
  }
@@ -6846,6 +6975,7 @@ export function AgentView(props) {
6846
6975
  command,
6847
6976
  cwd,
6848
6977
  allowedDirs: effectiveAllowedDirectories,
6978
+ conversationId,
6849
6979
  timeoutMs: 30_000,
6850
6980
  });
6851
6981
  const endedAt = Date.now();
@@ -7087,8 +7217,8 @@ export function AgentView(props) {
7087
7217
  const selected = selectedTraceMessage?.id === message.id;
7088
7218
  return (_jsxs("button", { onClick: () => patchSessionUi({ panelOpen: true, panelTab: 'trace', selectedTraceMessageId: message.id }), className: `w-full text-left px-3 py-2 border-b border-white/[0.04] transition-colors ${selected ? 'bg-white/[0.06]' : 'hover:bg-white/[0.03]'}`, children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx("span", { className: "text-[11px] text-white/68 truncate", children: message.toolCalls?.[0]?.summary || message.content || 'Assistant turn' }), _jsx("span", { className: "text-[10px] text-white/18 tabular-nums", children: new Date(message.timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) })] }), _jsxs("div", { className: "flex items-center gap-2 mt-1", children: [_jsxs("span", { className: "text-[10px] text-white/24 tabular-nums", children: [toolCount, " tools"] }), message.error && _jsx("span", { className: "text-[10px] text-[#ff9a9a]", children: "error" })] })] }, message.id));
7089
7219
  })) }), _jsx("div", { className: "overflow-y-auto px-3 py-3", children: !selectedTraceMessage ? (_jsx("p", { className: "text-[11px] text-white/28", children: "Select a turn to inspect its tools and outputs." })) : (_jsx("div", { className: "space-y-2", children: (selectedTraceMessage.toolCalls || []).map((toolCall) => (_jsxs("div", { className: "rounded-[5px] border border-white/[0.06] bg-black/20 px-3 py-2", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-[11px] text-white/72 truncate", children: toolCall.summary || toolCall.toolName }), _jsxs("p", { className: "text-[10px] text-white/22 mt-1", children: [toolCall.toolName, typeof toolCall.durationMs === 'number' && toolCall.durationMs >= 1000 ? ` - ${Math.round(toolCall.durationMs)}ms` : ''] })] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [toolCall.diff && (props.onPeekEditorDiff || props.onOpenEditorDiff) && (_jsx("button", { onClick: () => (props.onPeekEditorDiff || props.onOpenEditorDiff)?.(toolCall.diff), className: "text-[10px] text-white/45 hover:text-white/78 transition-colors", children: "Open Diff" })), toolCall.artifacts?.find((artifact) => artifact.type === 'file' && artifact.openInEditor)?.value && (props.onPeekEditorPath || props.onOpenEditorPath) && (_jsx("button", { onClick: () => (props.onPeekEditorPath || props.onOpenEditorPath)?.(toolCall.artifacts.find((artifact) => artifact.type === 'file' && artifact.openInEditor).value), className: "text-[10px] text-white/30 hover:text-white/65 transition-colors", children: "Open File" }))] })] }), toolCall.result?.trim() && (_jsx("pre", { className: "mt-2 whitespace-pre-wrap break-words text-[11px] leading-relaxed text-white/52 font-mono", children: toolCall.result.trim() }))] }, toolCall.id))) })) })] })), sessionPanelTab === 'output' && (_jsx("div", { className: "h-full overflow-y-auto px-3 py-3", children: outputEntries.length === 0 ? (_jsx("p", { className: "text-[11px] text-white/28", children: "No output captured for the selected turn." })) : (_jsx("div", { className: "space-y-2", children: outputEntries.map((entry) => (_jsxs("div", { className: "rounded-[5px] border border-white/[0.06] bg-black/20 overflow-hidden", children: [_jsx("div", { className: "px-3 py-2 border-b border-white/[0.06] text-[10px] uppercase tracking-[0.12em] text-white/26", children: entry.label }), _jsx("pre", { className: `px-3 py-2 whitespace-pre-wrap break-words text-[11px] leading-relaxed font-mono ${entry.tone === 'error' ? 'text-[#ffaaaa]' : 'text-white/55'}`, children: entry.content })] }, entry.id))) })) })), sessionPanelTab === 'problems' && (_jsx("div", { className: "h-full overflow-y-auto px-3 py-3", children: problemEntries.length === 0 ? (_jsx("p", { className: "text-[11px] text-white/28", children: "No problems in this conversation." })) : (_jsx("div", { className: "space-y-2", children: problemEntries.map((problem) => (_jsxs("div", { className: "rounded-[5px] border border-[#4b1f24] bg-[#1a0f12] px-3 py-2", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx("p", { className: "text-[11px] text-[#ffb0b0] truncate", children: problem.label }), _jsx("span", { className: "text-[10px] text-white/20 tabular-nums", children: new Date(problem.timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) })] }), _jsx("p", { className: "mt-1 text-[11px] leading-relaxed text-[#f0b7b7]/80 whitespace-pre-wrap break-words", children: problem.detail })] }, problem.id))) })) })), sessionPanelTab === 'terminal' && (_jsxs("div", { className: "h-full flex flex-col", children: [_jsxs("div", { className: "px-3 py-2 border-b border-white/[0.06] flex items-center justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-[10px] uppercase tracking-[0.12em] text-white/26", children: "Workspace terminal" }), _jsx("p", { className: "text-[11px] text-white/34 truncate", children: terminalCapabilityEnabled
7090
- ? (resolvedTerminalCwd || 'Open a folder to start running commands.')
7091
- : 'Terminal access is disabled for this agent.' })] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [_jsx("button", { onClick: handleResetTerminalCwd, disabled: !terminalCapabilityEnabled || !effectiveAllowedDirectories.length, className: "text-[10px] text-white/32 hover:text-white/62 transition-colors disabled:opacity-30", children: "Reset cwd" }), _jsx("button", { onClick: handleClearTerminalHistory, disabled: terminalHistory.length === 0, className: "text-[10px] text-white/32 hover:text-white/62 transition-colors disabled:opacity-30", children: "Clear" })] })] }), _jsx("div", { className: "flex-1 min-h-0 overflow-y-auto px-3 py-3", children: !terminalCapabilityEnabled ? (_jsx("p", { className: "text-[11px] text-white/28", children: "Enable terminal capability for this agent to run commands from the dock." })) : !effectiveAllowedDirectories.length ? (_jsx("p", { className: "text-[11px] text-white/28", children: "Open or choose a folder first. Terminal commands run inside the conversation workspace." })) : terminalHistory.length === 0 && !activeTerminalCommand ? (_jsx("p", { className: "text-[11px] text-white/28", children: "No terminal commands yet. Run a command below and it will stay attached to this conversation." })) : (_jsxs("div", { className: "space-y-1.5", children: [activeTerminalCommand && (_jsxs("div", { className: "rounded border border-white/[0.04] bg-black/20 overflow-hidden", children: [_jsx("div", { className: `px-1.5 py-[5px] rounded transition-colors ${expandedActiveTerminalCard ? 'bg-white/[0.03]' : 'hover:bg-white/[0.02]'}`, children: _jsxs("div", { className: "flex items-start gap-1.5", children: [_jsxs("button", { type: "button", onClick: () => setExpandedActiveTerminalCard((value) => !value), className: "min-w-0 flex-1 inline-flex items-start gap-1.5 text-left", children: [_jsx("span", { className: "mt-[2px] inline-flex h-3 w-3 flex-shrink-0 items-center justify-center", children: _jsx("svg", { className: "w-3 h-3 text-white/25 animate-spin", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { d: "M12 2v4m0 12v4m-7.07-3.93l2.83-2.83m8.48-8.48l2.83-2.83M2 12h4m12 0h4M4.93 4.93l2.83 2.83m8.48 8.48l2.83 2.83", strokeWidth: 1.5, strokeLinecap: "square" }) }) }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block text-[10px] uppercase tracking-[0.14em] text-white/20", children: "Terminal" }), _jsx("span", { className: "block truncate text-[12px] leading-3 font-mono text-white/50", children: activeTerminalCommand.command })] })] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0 pt-[2px]", children: [_jsx("span", { className: "text-[10px] text-[#ffd38a]", children: "Running..." }), _jsx("button", { type: "button", onClick: () => setExpandedActiveTerminalCard((value) => !value), className: "flex-shrink-0", children: _jsx("svg", { className: `w-3 h-3 text-white/15 transition-transform ${expandedActiveTerminalCard ? 'rotate-90' : ''}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { d: "M9 6l6 6-6 6", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round" }) }) })] })] }) }), _jsx("div", { className: `grid transition-[grid-template-rows,opacity] duration-200 ease-out ${expandedActiveTerminalCard ? 'grid-rows-[1fr] opacity-100 mt-0.5' : 'grid-rows-[0fr] opacity-0 mt-0'}`, children: _jsx("div", { className: "min-h-0 overflow-hidden", children: _jsx("div", { className: "border-t border-white/[0.04] px-2.5 py-1.5 text-[10px] text-white/20 font-mono truncate", children: activeTerminalCommand.cwd }) }) })] })), terminalHistory.map((entry) => (_jsxs("div", { className: "rounded border border-white/[0.04] bg-black/20 overflow-hidden", children: [_jsx("div", { className: `px-1.5 py-[5px] rounded transition-colors ${expandedTerminalHistoryId === entry.id ? 'bg-white/[0.03]' : 'hover:bg-white/[0.02]'}`, children: _jsxs("div", { className: "flex items-start gap-1.5", children: [_jsxs("button", { type: "button", onClick: () => setExpandedTerminalHistoryId(expandedTerminalHistoryId === entry.id ? null : entry.id), className: "min-w-0 flex-1 inline-flex items-start gap-1.5 text-left", children: [_jsx("span", { className: "mt-[2px] inline-flex h-3 w-3 flex-shrink-0 items-center justify-center", children: entry.success ? (_jsx("span", { className: "block h-1.5 w-1.5 rounded-[2px] bg-[var(--xeno-marker-solid)]" })) : (_jsx(ErrorMarkerIcon, {})) }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block text-[10px] uppercase tracking-[0.14em] text-white/20", children: "Terminal" }), _jsx("span", { className: "block truncate text-[12px] leading-3 font-mono text-white/50", children: entry.command })] })] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0 pt-[2px]", children: [_jsx("span", { className: "text-[10px] text-white/20", children: new Date(entry.endedAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) }), _jsx("span", { className: "text-[10px] text-white/20 tabular-nums", children: entry.durationMs >= 1000 ? `${(entry.durationMs / 1000).toFixed(1)}s` : `${entry.durationMs}ms` }), _jsx("span", { className: `text-[10px] ${entry.success ? 'text-[#96e59d]' : 'text-[#ff9a9a]'}`, children: entry.success ? `exit ${entry.exitCode ?? 0}` : (entry.error ? 'failed' : `exit ${entry.exitCode ?? 'error'}`) }), _jsx("button", { onClick: () => handleReuseTerminalEntry(entry), className: "text-[10px] text-white/35 hover:text-white/65 transition-colors", children: "Reuse" }), _jsx("button", { type: "button", onClick: () => setExpandedTerminalHistoryId(expandedTerminalHistoryId === entry.id ? null : entry.id), className: "flex-shrink-0", children: _jsx("svg", { className: `w-3 h-3 text-white/15 transition-transform ${expandedTerminalHistoryId === entry.id ? 'rotate-90' : ''}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { d: "M9 6l6 6-6 6", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round" }) }) })] })] }) }), _jsx("div", { className: `grid transition-[grid-template-rows,opacity] duration-200 ease-out ${expandedTerminalHistoryId === entry.id ? 'grid-rows-[1fr] opacity-100 mt-0.5' : 'grid-rows-[0fr] opacity-0 mt-0'}`, children: _jsxs("div", { className: "min-h-0 overflow-hidden", children: [_jsx("div", { className: "border-t border-white/[0.04] px-2.5 py-1.5 text-[10px] text-white/20 font-mono truncate", children: entry.cwd }), entry.stdout.trim() && (_jsxs("div", { className: "border-t border-white/[0.04]", children: [_jsx("div", { className: "px-2.5 py-1 text-[10px] uppercase tracking-[0.12em] text-white/20", children: "Stdout" }), _jsx("pre", { className: "px-2.5 pb-2 whitespace-pre-wrap break-words text-[11px] leading-relaxed font-mono text-white/40", children: entry.stdout.trim() })] })), (entry.stderr.trim() || entry.error?.trim()) && (_jsxs("div", { className: "border-t border-red-500/10", children: [_jsx("div", { className: "px-2.5 py-1 text-[10px] uppercase tracking-[0.12em] text-[#ffb0b0]/70", children: "Error" }), _jsx("pre", { className: "px-2.5 pb-2 whitespace-pre-wrap break-words text-[11px] leading-relaxed font-mono text-[#f0b7b7]/80", children: [entry.error?.trim(), entry.stderr.trim()].filter(Boolean).join('\n\n') })] }))] }) })] }, entry.id)))] })) }), _jsx("div", { className: "border-t border-white/[0.06] px-3 py-2 bg-[#0b0b0d]", children: _jsxs("div", { className: "grid grid-cols-[minmax(0,220px)_minmax(0,1fr)_auto] gap-2", children: [_jsx("input", { value: terminalDraftCwd, onChange: (event) => setTerminalDraftCwd(event.target.value), placeholder: resolvedTerminalCwd || 'Working directory', className: "h-8 rounded-[4px] border border-white/[0.06] bg-black/20 px-2.5 text-[11px] text-white/70 placeholder:text-white/18 outline-none focus:border-white/[0.12]" }), _jsx("input", { value: terminalDraftInput, onChange: (event) => setTerminalDraftInput(event.target.value), onKeyDown: (event) => {
7220
+ ? (resolvedTerminalCwd || (terminalReady ? 'Conversation workspace (managed)' : 'Open a folder to start running commands.'))
7221
+ : 'Terminal access is disabled for this agent.' })] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [_jsx("button", { onClick: handleResetTerminalCwd, disabled: !terminalCapabilityEnabled || (!effectiveAllowedDirectories.length && !resolvedTerminalCwd), className: "text-[10px] text-white/32 hover:text-white/62 transition-colors disabled:opacity-30", children: "Reset cwd" }), _jsx("button", { onClick: handleClearTerminalHistory, disabled: terminalHistory.length === 0, className: "text-[10px] text-white/32 hover:text-white/62 transition-colors disabled:opacity-30", children: "Clear" })] })] }), _jsx("div", { className: "flex-1 min-h-0 overflow-y-auto px-3 py-3", children: !terminalCapabilityEnabled ? (_jsx("p", { className: "text-[11px] text-white/28", children: "Enable terminal capability for this agent to run commands from the dock." })) : !terminalReady ? (_jsx("p", { className: "text-[11px] text-white/28", children: "Open or choose a folder first. Terminal commands run inside the conversation workspace." })) : terminalHistory.length === 0 && !activeTerminalCommand ? (_jsx("p", { className: "text-[11px] text-white/28", children: "No terminal commands yet. Run a command below and it will stay attached to this conversation." })) : (_jsxs("div", { className: "space-y-1.5", children: [activeTerminalCommand && (_jsxs("div", { className: "rounded border border-white/[0.04] bg-black/20 overflow-hidden", children: [_jsx("div", { className: `px-1.5 py-[5px] rounded transition-colors ${expandedActiveTerminalCard ? 'bg-white/[0.03]' : 'hover:bg-white/[0.02]'}`, children: _jsxs("div", { className: "flex items-start gap-1.5", children: [_jsxs("button", { type: "button", onClick: () => setExpandedActiveTerminalCard((value) => !value), className: "min-w-0 flex-1 inline-flex items-start gap-1.5 text-left", children: [_jsx("span", { className: "mt-[2px] inline-flex h-3 w-3 flex-shrink-0 items-center justify-center", children: _jsx("svg", { className: "w-3 h-3 text-white/25 animate-spin", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { d: "M12 2v4m0 12v4m-7.07-3.93l2.83-2.83m8.48-8.48l2.83-2.83M2 12h4m12 0h4M4.93 4.93l2.83 2.83m8.48 8.48l2.83 2.83", strokeWidth: 1.5, strokeLinecap: "square" }) }) }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block text-[10px] uppercase tracking-[0.14em] text-white/20", children: "Terminal" }), _jsx("span", { className: "block truncate text-[12px] leading-3 font-mono text-white/50", children: activeTerminalCommand.command })] })] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0 pt-[2px]", children: [_jsx("span", { className: "text-[10px] text-[#ffd38a]", children: "Running..." }), _jsx("button", { type: "button", onClick: () => setExpandedActiveTerminalCard((value) => !value), className: "flex-shrink-0", children: _jsx("svg", { className: `w-3 h-3 text-white/15 transition-transform ${expandedActiveTerminalCard ? 'rotate-90' : ''}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { d: "M9 6l6 6-6 6", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round" }) }) })] })] }) }), _jsx("div", { className: `grid transition-[grid-template-rows,opacity] duration-200 ease-out ${expandedActiveTerminalCard ? 'grid-rows-[1fr] opacity-100 mt-0.5' : 'grid-rows-[0fr] opacity-0 mt-0'}`, children: _jsx("div", { className: "min-h-0 overflow-hidden", children: _jsx("div", { className: "border-t border-white/[0.04] px-2.5 py-1.5 text-[10px] text-white/20 font-mono truncate", children: activeTerminalCommand.cwd }) }) })] })), terminalHistory.map((entry) => (_jsxs("div", { className: "rounded border border-white/[0.04] bg-black/20 overflow-hidden", children: [_jsx("div", { className: `px-1.5 py-[5px] rounded transition-colors ${expandedTerminalHistoryId === entry.id ? 'bg-white/[0.03]' : 'hover:bg-white/[0.02]'}`, children: _jsxs("div", { className: "flex items-start gap-1.5", children: [_jsxs("button", { type: "button", onClick: () => setExpandedTerminalHistoryId(expandedTerminalHistoryId === entry.id ? null : entry.id), className: "min-w-0 flex-1 inline-flex items-start gap-1.5 text-left", children: [_jsx("span", { className: "mt-[2px] inline-flex h-3 w-3 flex-shrink-0 items-center justify-center", children: entry.success ? (_jsx("span", { className: "block h-1.5 w-1.5 rounded-[2px] bg-[var(--xeno-marker-solid)]" })) : (_jsx(ErrorMarkerIcon, {})) }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block text-[10px] uppercase tracking-[0.14em] text-white/20", children: "Terminal" }), _jsx("span", { className: "block truncate text-[12px] leading-3 font-mono text-white/50", children: entry.command })] })] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0 pt-[2px]", children: [_jsx("span", { className: "text-[10px] text-white/20", children: new Date(entry.endedAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) }), _jsx("span", { className: "text-[10px] text-white/20 tabular-nums", children: entry.durationMs >= 1000 ? `${(entry.durationMs / 1000).toFixed(1)}s` : `${entry.durationMs}ms` }), _jsx("span", { className: `text-[10px] ${entry.success ? 'text-[#96e59d]' : 'text-[#ff9a9a]'}`, children: entry.success ? `exit ${entry.exitCode ?? 0}` : (entry.error ? 'failed' : `exit ${entry.exitCode ?? 'error'}`) }), _jsx("button", { onClick: () => handleReuseTerminalEntry(entry), className: "text-[10px] text-white/35 hover:text-white/65 transition-colors", children: "Reuse" }), _jsx("button", { type: "button", onClick: () => setExpandedTerminalHistoryId(expandedTerminalHistoryId === entry.id ? null : entry.id), className: "flex-shrink-0", children: _jsx("svg", { className: `w-3 h-3 text-white/15 transition-transform ${expandedTerminalHistoryId === entry.id ? 'rotate-90' : ''}`, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { d: "M9 6l6 6-6 6", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round" }) }) })] })] }) }), _jsx("div", { className: `grid transition-[grid-template-rows,opacity] duration-200 ease-out ${expandedTerminalHistoryId === entry.id ? 'grid-rows-[1fr] opacity-100 mt-0.5' : 'grid-rows-[0fr] opacity-0 mt-0'}`, children: _jsxs("div", { className: "min-h-0 overflow-hidden", children: [_jsx("div", { className: "border-t border-white/[0.04] px-2.5 py-1.5 text-[10px] text-white/20 font-mono truncate", children: entry.cwd }), entry.stdout.trim() && (_jsxs("div", { className: "border-t border-white/[0.04]", children: [_jsx("div", { className: "px-2.5 py-1 text-[10px] uppercase tracking-[0.12em] text-white/20", children: "Stdout" }), _jsx("pre", { className: "px-2.5 pb-2 whitespace-pre-wrap break-words text-[11px] leading-relaxed font-mono text-white/40", children: entry.stdout.trim() })] })), (entry.stderr.trim() || entry.error?.trim()) && (_jsxs("div", { className: "border-t border-red-500/10", children: [_jsx("div", { className: "px-2.5 py-1 text-[10px] uppercase tracking-[0.12em] text-[#ffb0b0]/70", children: "Error" }), _jsx("pre", { className: "px-2.5 pb-2 whitespace-pre-wrap break-words text-[11px] leading-relaxed font-mono text-[#f0b7b7]/80", children: [entry.error?.trim(), entry.stderr.trim()].filter(Boolean).join('\n\n') })] }))] }) })] }, entry.id)))] })) }), _jsx("div", { className: "border-t border-white/[0.06] px-3 py-2 bg-[#0b0b0d]", children: _jsxs("div", { className: "grid grid-cols-[minmax(0,220px)_minmax(0,1fr)_auto] gap-2", children: [_jsx("input", { value: terminalDraftCwd, onChange: (event) => setTerminalDraftCwd(event.target.value), placeholder: resolvedTerminalCwd || 'Working directory', className: "h-8 rounded-[4px] border border-white/[0.06] bg-black/20 px-2.5 text-[11px] text-white/70 placeholder:text-white/18 outline-none focus:border-white/[0.12]" }), _jsx("input", { value: terminalDraftInput, onChange: (event) => setTerminalDraftInput(event.target.value), onKeyDown: (event) => {
7092
7222
  if (event.key === 'Enter' && !event.shiftKey) {
7093
7223
  event.preventDefault();
7094
7224
  void handleRunTerminalCommand();
@@ -7130,7 +7260,11 @@ export function AgentView(props) {
7130
7260
  })())) : (_jsx("div", { className: "px-3 py-3 text-[10px] text-white/25 text-center", children: "No matching models" }))) : (_jsx("div", { className: "px-3 py-3 text-[10px] text-white/25 text-center", children: "Loading models..." }))) : (_jsxs(_Fragment, { children: [localModels.length > 0 ? (filteredLocalModels.length > 0 ? filteredLocalModels.map(m => {
7131
7261
  const selected = m.id === (selectedLocalEffortFamily?.baseId || selectedModel);
7132
7262
  return (_jsxs("button", { onClick: () => { setInferenceMode('local'); setSelectedModel(m.id); setModelListOpen(false); setEffortListOpen(false); }, role: "option", "aria-selected": selected, className: `w-full flex items-center gap-2 px-3 py-1.5 text-left transition-colors cursor-pointer ${selected ? 'bg-white/[0.06]' : 'hover:bg-white/[0.04]'}`, children: [_jsx("span", { className: `text-[11px] truncate ${selected ? 'text-white/70' : 'text-white/40'}`, children: m.name }), m.parameterSize && _jsx("span", { className: "text-[8px] text-white/20 flex-shrink-0 ml-auto", children: m.parameterSize })] }, m.id));
7133
- }) : (_jsx("div", { className: "px-3 py-2.5 text-[10px] text-white/25 text-center", children: "No matching models" }))) : (_jsx("div", { className: "px-3 py-2.5 text-[10px] text-white/25 text-center", children: "No local models installed" })), _jsx("button", { onClick: () => { setModelListOpen(false); goToModelsMarketplace(); }, className: "w-full flex items-center justify-center gap-1.5 px-3 py-2 border-t border-white/[0.06] text-[10px] text-white/35 hover:text-white/60 hover:bg-white/[0.04] transition-colors cursor-pointer", children: "Browse models" })] })) })] })), _jsxs("div", { className: "space-y-0", children: [pendingTurns.length > 0 && (_jsxs("div", { className: "xeno-border-subtle rounded-t-md border border-b-0 bg-[#111111] overflow-hidden", children: [_jsxs("div", { className: "flex items-center justify-between gap-3 px-3 py-2 border-b xeno-border-subtle", children: [_jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [_jsx("span", { className: "text-[10px] uppercase tracking-[0.14em] xeno-text-faint whitespace-nowrap", children: "Queued Messages" }), _jsx("span", { className: "text-[10px] xeno-text-muted tabular-nums whitespace-nowrap", children: pendingTurns.length })] }), _jsx("button", { onClick: () => patchSessionUi({ panelOpen: true }), className: "text-[10px] xeno-text-faint hover:text-[color:var(--xeno-ink-secondary)] transition-colors whitespace-nowrap cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35", children: "Manage queue" })] }), _jsxs("div", { className: "divide-y xeno-border-subtle", children: [pendingTurns.slice(0, 3).map((turn) => (_jsxs("div", { className: "flex items-center gap-3 px-3 py-2", children: [_jsx("span", { className: "inline-flex h-5 min-w-5 items-center justify-center rounded-[4px] bg-white/[0.04] px-1.5 text-[10px] xeno-text-faint tabular-nums", children: new Date(turn.queuedAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) }), _jsx("span", { className: "min-w-0 flex-1 text-[12px] leading-4 xeno-text-secondary truncate", children: turn.content }), _jsx("button", { onClick: () => handleRemoveQueuedConversationTurn(turn.id), className: "text-[10px] xeno-text-faint hover:text-[color:var(--xeno-ink-secondary)] transition-colors whitespace-nowrap cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35", title: "Remove queued message", children: "Remove" })] }, turn.id))), pendingTurns.length > 3 && (_jsxs("div", { className: "px-3 py-2 text-[11px] xeno-text-faint", children: [pendingTurns.length - 3, " more queued"] }))] })] })), _jsxs("div", { className: `xeno-agent-composer-shell border border-white/[0.08] ${pendingTurns.length > 0 ? 'rounded-t-none rounded-b-md' : 'rounded-md'}`, children: [_jsx("input", { ref: fileInputRef, type: "file", accept: "image/*", multiple: true, onChange: (e) => { void handleAttachmentPick(e); }, className: "hidden" }), pendingAttachments.length > 0 && (_jsx("div", { className: "px-3 pt-3 pb-1", children: _jsx("div", { className: "grid grid-cols-4 gap-2", children: pendingAttachments.map(att => (_jsxs("div", { className: "xeno-app-shell xeno-border-subtle relative rounded overflow-hidden border", children: [_jsx("img", { src: att.dataUrl, alt: att.name, className: "w-full h-16 object-cover" }), _jsx("button", { onClick: () => removePendingAttachment(att.id), className: "absolute top-1 right-1 w-5 h-5 rounded-[4px] bg-black/60 text-white/70 hover:text-white flex items-center justify-center transition-colors cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35", "aria-label": `Remove attachment ${att.name}`, title: `Remove ${att.name}`, children: _jsx(X, { className: "w-3 h-3" }) })] }, att.id))) }) })), _jsx(GhostTextArea, { ref: textareaRef, rows: 2, value: input, onChange: handleInputChange, onKeyDown: handleKeyDown, disabled: !isModelReady, placeholder: effectiveGhostText
7263
+ }) : (_jsx("div", { className: "px-3 py-2.5 text-[10px] text-white/25 text-center", children: "No matching models" }))) : (_jsx("div", { className: "px-3 py-2.5 text-[10px] text-white/25 text-center", children: "No local models installed" })), _jsx("button", { onClick: () => { setModelListOpen(false); goToModelsMarketplace(); }, className: "w-full flex items-center justify-center gap-1.5 px-3 py-2 border-t border-white/[0.06] text-[10px] text-white/35 hover:text-white/60 hover:bg-white/[0.04] transition-colors cursor-pointer", children: "Browse models" })] })) })] })), _jsxs("div", { className: "space-y-0", children: [pendingTurns.length > 0 && (_jsxs("div", { className: "xeno-border-subtle rounded-t-md border border-b-0 bg-[#111111] overflow-hidden", children: [_jsxs("div", { className: "flex items-center justify-between gap-3 px-3 py-2 border-b xeno-border-subtle", children: [_jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [_jsx("span", { className: "text-[10px] uppercase tracking-[0.14em] xeno-text-faint whitespace-nowrap", children: "Queued Messages" }), _jsx("span", { className: "text-[10px] xeno-text-muted tabular-nums whitespace-nowrap", children: pendingTurns.length })] }), _jsx("button", { onClick: () => patchSessionUi({ panelOpen: true }), className: "text-[10px] xeno-text-faint hover:text-[color:var(--xeno-ink-secondary)] transition-colors whitespace-nowrap cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35", children: "Manage queue" })] }), _jsxs("div", { className: "divide-y xeno-border-subtle", children: [pendingTurns.slice(0, 3).map((turn) => (_jsxs("div", { className: "flex items-center gap-3 px-3 py-2", children: [_jsx("span", { className: "inline-flex h-5 min-w-5 items-center justify-center rounded-[4px] bg-white/[0.04] px-1.5 text-[10px] xeno-text-faint tabular-nums", children: new Date(turn.queuedAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) }), _jsx("span", { className: "min-w-0 flex-1 text-[12px] leading-4 xeno-text-secondary truncate", children: turn.content }), _jsx("button", { onClick: () => handleRemoveQueuedConversationTurn(turn.id), className: "text-[10px] xeno-text-faint hover:text-[color:var(--xeno-ink-secondary)] transition-colors whitespace-nowrap cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35", title: "Remove queued message", children: "Remove" })] }, turn.id))), pendingTurns.length > 3 && (_jsxs("div", { className: "px-3 py-2 text-[11px] xeno-text-faint", children: [pendingTurns.length - 3, " more queued"] }))] })] })), _jsxs("div", { className: "mb-2 flex items-center justify-between gap-2", "data-agent-workspace-binding": workspaceBinding.mode, children: [_jsxs("div", { className: "inline-flex items-center rounded-md border border-white/[0.08] bg-white/[0.025] p-0.5 text-[11px]", children: [_jsx("button", { type: "button", onClick: () => { void handleSelectWorkspaceMode('chat-only'); }, disabled: isBusy || !!props.externalInputLockReason || isSelectingConversationWorkspace, className: `rounded px-2.5 py-1 font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-40 ${workspaceBinding.mode !== 'workspace'
7264
+ ? 'bg-white/[0.12] text-white shadow-sm'
7265
+ : 'text-white/45 hover:bg-white/[0.04] hover:text-white/70'}`, "aria-pressed": workspaceBinding.mode !== 'workspace', children: "Chat" }), _jsx("button", { type: "button", onClick: () => { void handleSelectWorkspaceMode('workspace'); }, disabled: isBusy || !!props.externalInputLockReason || isSelectingConversationWorkspace, className: `rounded px-2.5 py-1 font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-40 ${workspaceBinding.mode === 'workspace'
7266
+ ? 'bg-white/[0.12] text-white shadow-sm'
7267
+ : 'text-white/45 hover:bg-white/[0.04] hover:text-white/70'}`, "aria-pressed": workspaceBinding.mode === 'workspace', children: isSelectingConversationWorkspace && workspaceBinding.mode !== 'workspace' ? 'Choosing…' : 'Agent' })] }), workspaceBinding.mode === 'workspace' ? (_jsxs("div", { className: "flex min-w-0 items-center gap-2 text-[10px]", children: [_jsx("span", { className: "min-w-0 truncate font-mono text-white/45", title: workspaceBinding.rootDirectory || workspaceBinding.allowedDirectories[0], children: workspaceBinding.rootDirectory || workspaceBinding.allowedDirectories[0] }), _jsx("button", { type: "button", onClick: () => { void chooseConversationWorkspace(); }, disabled: isSelectingConversationWorkspace || isBusy || !!props.externalInputLockReason, className: "shrink-0 text-white/35 transition-colors hover:text-white/70 disabled:cursor-not-allowed disabled:opacity-30", children: "Change folder" })] })) : (_jsx("span", { className: "min-w-0 truncate text-[10px] text-white/28", children: "Chat only \u00B7 no project file access" }))] }), props.externalInputLockReason && (_jsx("div", { className: "mb-2 rounded-md border border-amber-400/20 bg-amber-400/[0.06] px-3 py-2 text-[11px] text-amber-100/70", children: props.externalInputLockReason })), _jsxs("div", { className: `xeno-agent-composer-shell border border-white/[0.08] ${pendingTurns.length > 0 ? 'rounded-t-none rounded-b-md' : 'rounded-md'}`, children: [_jsx("input", { ref: fileInputRef, type: "file", accept: "image/*", multiple: true, onChange: (e) => { void handleAttachmentPick(e); }, className: "hidden" }), pendingAttachments.length > 0 && (_jsx("div", { className: "px-3 pt-3 pb-1", children: _jsx("div", { className: "grid grid-cols-4 gap-2", children: pendingAttachments.map(att => (_jsxs("div", { className: "xeno-app-shell xeno-border-subtle relative rounded overflow-hidden border", children: [_jsx("img", { src: att.dataUrl, alt: att.name, className: "w-full h-16 object-cover" }), _jsx("button", { onClick: () => removePendingAttachment(att.id), className: "absolute top-1 right-1 w-5 h-5 rounded-[4px] bg-black/60 text-white/70 hover:text-white flex items-center justify-center transition-colors cursor-pointer focus-visible:outline focus-visible:outline-1 focus-visible:outline-white/35", "aria-label": `Remove attachment ${att.name}`, title: `Remove ${att.name}`, children: _jsx(X, { className: "w-3 h-3" }) })] }, att.id))) }) })), _jsx(GhostTextArea, { ref: textareaRef, rows: 2, value: input, onChange: handleInputChange, onKeyDown: handleKeyDown, disabled: inputLocked, placeholder: effectiveGhostText
7134
7268
  ? ''
7135
7269
  : (isModelReady
7136
7270
  ? `Message ${agentName.replace(/\s*powered by .+$/i, '')}...`