+ {terminalContextDrafts.map((draft) => (
+
+
+
+ {t('chat.chatInput.terminalContext', { terminal: draft.fileLabel, start: draft.startLine, end: draft.endLine })}
+
+
+
+ ))}
{reviewCount > 0 ? (
= ({ part, messageId, agentMention }) => {
const partWithText = part as PartWithText;
const rawText = partWithText.text;
- const textContent = typeof rawText === 'string' ? rawText : partWithText.content || partWithText.value || '';
+ const serializedText = typeof rawText === 'string' ? rawText : partWithText.content || partWithText.value || '';
+ const terminalContextState = React.useMemo(() => extractTerminalContexts(serializedText), [serializedText]);
+ const textContent = terminalContextState.visibleText;
const [isExpanded, setIsExpanded] = React.useState(false);
const [isTruncated, setIsTruncated] = React.useState(false);
@@ -190,7 +193,7 @@ const UserTextPart: React.FC = ({ part, messageId, agentMenti
});
}, [agentMention, openSkill, skillByName, textContent]);
- if (!textContent || textContent.trim().length === 0) {
+ if ((!textContent || textContent.trim().length === 0) && terminalContextState.contexts.length === 0) {
return null;
}
@@ -243,6 +246,18 @@ const UserTextPart: React.FC = ({ part, messageId, agentMenti
plainTextContent
)}
+ {terminalContextState.contexts.length > 0 ? (
+
+ {terminalContextState.contexts.map((context, index) => (
+
+
+ {t('chat.message.terminalContext', { terminal: context.terminalLabel, start: context.startLine, end: context.endLine })}
+
+ {context.text}
+
+ ))}
+
+ ) : null}
);
};
diff --git a/packages/ui/src/components/layout/ContextPanel.tsx b/packages/ui/src/components/layout/ContextPanel.tsx
index 23086158..e195ba37 100644
--- a/packages/ui/src/components/layout/ContextPanel.tsx
+++ b/packages/ui/src/components/layout/ContextPanel.tsx
@@ -25,6 +25,7 @@ import { runtimeFetch } from '@/lib/runtime-fetch';
import { refreshRuntimeUrlAuthToken } from '@/lib/runtime-auth';
import { getRuntimeUrlResolver } from '@/lib/runtime-url';
import { getRuntimeApiBaseUrl } from '@/lib/runtime-switch';
+import { getPreviewTargetRecoveryAction } from '@/lib/preview/proxy-response';
import { Icon } from "@/components/icon/Icon";
import { OpenChamberLogo } from "@/components/ui/OpenChamberLogo";
import { invokeDesktopCommand } from '@/lib/desktopNative';
@@ -951,27 +952,37 @@ const PreviewPane: React.FC