Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 21 additions & 13 deletions UnrealClaude/Source/UnrealClaude/Private/ClaudeCodeRunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1437,21 +1437,29 @@ void FClaudeCodeRunner::ExecuteProcess()
// Cache the stdin payload for the silence watchdog diagnostic.
LastStdinPayload = StdinPayload;

if (!StdinPayload.IsEmpty())
// Write on a background thread
void* WriteHandle = StdInWritePipe;
void* ReadHandleForChild = StdInReadPipe;
StdInWritePipe = nullptr;
StdInReadPipe = nullptr;

Async(EAsyncExecution::Thread, [WriteHandle, ReadHandleForChild, StdinPayload, ImageCount = CurrentConfig.AttachedImagePaths.Num()]()
{
FTCHARToUTF8 Utf8Payload(*StdinPayload);
int32 BytesWritten = 0;
bool bWritten = FPlatformProcess::WritePipe(StdInWritePipe, (const uint8*)Utf8Payload.Get(), Utf8Payload.Length(), &BytesWritten);
UE_LOG(LogUnrealClaude, Log, TEXT("Wrote to Claude stdin (stream-json, success=%d, %d/%d bytes, images: %d, system: %d chars, user: %d chars)"),
bWritten, BytesWritten, Utf8Payload.Length(), CurrentConfig.AttachedImagePaths.Num(),
CurrentConfig.SystemPrompt.Len(), CurrentConfig.Prompt.Len());
}
if (!StdinPayload.IsEmpty())
{
FTCHARToUTF8 Utf8Payload(*StdinPayload);
int32 BytesWritten = 0;
bool bWritten = FPlatformProcess::WritePipe(WriteHandle, (const uint8*)Utf8Payload.Get(), Utf8Payload.Length(), &BytesWritten);
UE_LOG(LogUnrealClaude, Log, TEXT("Wrote to Claude stdin (stream-json, success=%d, %d/%d bytes, images: %d)"),
bWritten, BytesWritten, Utf8Payload.Length(), ImageCount);
}

// Close stdin write pipe to signal EOF to Claude
// We close the entire stdin pipe pair since child has the read end
FPlatformProcess::ClosePipe(StdInReadPipe, StdInWritePipe);
StdInReadPipe = nullptr;
StdInWritePipe = nullptr;
// Close stdin write pipe to signal EOF to Claude
// We close the entire stdin pipe pair since child has the read end
void* ReadCopy = ReadHandleForChild;
void* WriteCopy = WriteHandle;
FPlatformProcess::ClosePipe(ReadCopy, WriteCopy);
});
}

SystemPromptFilePath.Empty();
Expand Down
29 changes: 23 additions & 6 deletions UnrealClaude/Source/UnrealClaude/Private/ClaudeEditorWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "Widgets/Input/SButton.h"
#include "Widgets/Input/SCheckBox.h"
#include "Widgets/SBoxPanel.h"
#include "Widgets/Layout/SWidgetSwitcher.h"
#include "Styling/AppStyle.h"
#include "Styling/CoreStyle.h"
#include "Framework/Application/SlateApplication.h"
Expand Down Expand Up @@ -152,11 +153,27 @@ void SChatMessage::Construct(const FArguments& InArgs)
}
else
{
ContentWidget = SNew(STextBlock)
.Text(FText::FromString(Message))
.TextStyle(FAppStyle::Get(), "NormalText")
.ColorAndOpacity(FSlateColor(TextColor))
.AutoWrapText(true);
// Allow selecting user messages in Plain Text mode
ContentWidget = SNew(SWidgetSwitcher)
.WidgetIndex_Lambda([this]() { return bSelectionModeAttr.Get() ? 1 : 0; })

+ SWidgetSwitcher::Slot()
[
SNew(STextBlock)
.Text(FText::FromString(Message))
.TextStyle(FAppStyle::Get(), "NormalText")
.ColorAndOpacity(FSlateColor(TextColor))
.AutoWrapText(true)
]

+ SWidgetSwitcher::Slot()
[
SNew(SMultiLineEditableText)
.Text(FText::FromString(Message))
.TextStyle(FAppStyle::Get(), "NormalText")
.AutoWrapText(true)
.IsReadOnly(true)
];
}

ChildSlot
Expand Down Expand Up @@ -481,7 +498,7 @@ void SClaudeEditorWidget::AddMessage(const FString& Message, bool bIsUser)
.Message(Message)
.IsUser(bIsUser)
.bRenderMarkdown(!bIsUser) // Enable Markdown rendering for Claude messages
.bSelectionMode_Lambda([this, bIsUser]() { return bSelectionMode && !bIsUser; }) // Dynamic: only for Claude messages
.bSelectionMode_Lambda([this]() { return bSelectionMode; }) // Dynamic: applies to both user and Claude messages
];

// Only scroll to bottom if we were already there
Expand Down