Skip to content

Commit 0b8f5ea

Browse files
committed
feat: expose terminal stdin in threads for traceability
1 parent 36d516d commit 0b8f5ea

2 files changed

Lines changed: 37 additions & 0 deletions

File tree

src/features/app/hooks/useAppServerEvents.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ type AppServerEventHandlers = {
4141
onReasoningSummaryDelta?: (workspaceId: string, threadId: string, itemId: string, delta: string) => void;
4242
onReasoningTextDelta?: (workspaceId: string, threadId: string, itemId: string, delta: string) => void;
4343
onCommandOutputDelta?: (workspaceId: string, threadId: string, itemId: string, delta: string) => void;
44+
onTerminalInteraction?: (
45+
workspaceId: string,
46+
threadId: string,
47+
itemId: string,
48+
stdin: string,
49+
) => void;
4450
onFileChangeOutputDelta?: (workspaceId: string, threadId: string, itemId: string, delta: string) => void;
4551
onTurnDiffUpdated?: (workspaceId: string, threadId: string, diff: string) => void;
4652
onThreadTokenUsageUpdated?: (
@@ -246,6 +252,17 @@ export function useAppServerEvents(handlers: AppServerEventHandlers) {
246252
return;
247253
}
248254

255+
if (method === "item/commandExecution/terminalInteraction") {
256+
const params = message.params as Record<string, unknown>;
257+
const threadId = String(params.threadId ?? params.thread_id ?? "");
258+
const itemId = String(params.itemId ?? params.item_id ?? "");
259+
const stdin = String(params.stdin ?? "");
260+
if (threadId && itemId) {
261+
handlers.onTerminalInteraction?.(workspace_id, threadId, itemId, stdin);
262+
}
263+
return;
264+
}
265+
249266
if (method === "item/fileChange/outputDelta") {
250267
const params = message.params as Record<string, unknown>;
251268
const threadId = String(params.threadId ?? params.thread_id ?? "");

src/features/threads/hooks/useThreads.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,18 @@ export function useThreads({
752752
[markProcessing, safeMessageActivity],
753753
);
754754

755+
const handleTerminalInteraction = useCallback(
756+
(threadId: string, itemId: string, stdin: string) => {
757+
if (!stdin) {
758+
return;
759+
}
760+
const normalized = stdin.replace(/\r\n/g, "\n");
761+
const suffix = normalized.endsWith("\n") ? "" : "\n";
762+
handleToolOutputDelta(threadId, itemId, `\n[stdin]\n${normalized}${suffix}`);
763+
},
764+
[handleToolOutputDelta],
765+
);
766+
755767
const handleWorkspaceConnected = useCallback(
756768
(workspaceId: string) => {
757769
onWorkspaceConnected(workspaceId);
@@ -907,6 +919,14 @@ export function useThreads({
907919
) => {
908920
handleToolOutputDelta(threadId, itemId, delta);
909921
},
922+
onTerminalInteraction: (
923+
_workspaceId: string,
924+
threadId: string,
925+
itemId: string,
926+
stdin: string,
927+
) => {
928+
handleTerminalInteraction(threadId, itemId, stdin);
929+
},
910930
onFileChangeOutputDelta: (
911931
_workspaceId: string,
912932
threadId: string,

0 commit comments

Comments
 (0)