From 6ee343244eae96a8d7af93e07eb5702903caebd2 Mon Sep 17 00:00:00 2001 From: humansinstitute Date: Mon, 20 Oct 2025 17:21:51 +0800 Subject: [PATCH 1/2] Adding Tmux based running for testing with Wingman Deep Dive --- .env | 1 + chat/src/components/message-input.tsx | 115 ++++++-- cmd/server/server.go | 109 +++++++- lib/httpapi/setup.go | 13 - lib/screentracker/conversation.go | 4 + lib/termexec/termexec.go | 361 +++++++++++++++++--------- 6 files changed, 442 insertions(+), 161 deletions(-) create mode 100644 .env diff --git a/.env b/.env new file mode 100644 index 0000000..95d0ab1 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +AGENTAPI_ALLOWED_HOSTS="dev.otherstuff.studio dev.otherstuff.ai localhost" diff --git a/chat/src/components/message-input.tsx b/chat/src/components/message-input.tsx index 0748dee..edd9705 100644 --- a/chat/src/components/message-input.tsx +++ b/chat/src/components/message-input.tsx @@ -7,6 +7,7 @@ import { ArrowLeftIcon, ArrowRightIcon, ArrowUpIcon, + Command as CommandIcon, CornerDownLeftIcon, DeleteIcon, SendIcon, @@ -14,6 +15,12 @@ import { Square, } from "lucide-react"; import {Tabs, TabsList, TabsTrigger} from "./ui/tabs"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "./ui/dropdown-menu"; import type {ServerStatus} from "./chat-provider"; import TextareaAutosize from "react-textarea-autosize"; import {useChat} from "./chat-provider"; @@ -50,6 +57,32 @@ const specialKeys: Record = { Backspace: "\b", // Backspace key }; +const SHIFT_TAB_SEQUENCE = "\x1b[Z"; +const CLEAR_SCREEN_SEQUENCE = "\x0C"; + +interface ControlAction { + id: string; + label: string; + display: string; + sequence: string; +} + +const CONTROL_ACTIONS: ControlAction[] = [ + {id: "escape", label: "Esc", display: "Esc", sequence: specialKeys.Escape}, + {id: "enter", label: "Enter", display: "⏎", sequence: "\r"}, + {id: "tab", label: "Tab", display: "Tab", sequence: specialKeys.Tab}, + {id: "shift-tab", label: "Shift+Tab", display: "Shift+Tab", sequence: SHIFT_TAB_SEQUENCE}, + {id: "one-enter", label: "1 + Enter", display: "1⏎", sequence: "1\r"}, + {id: "two-enter", label: "2 + Enter", display: "2⏎", sequence: "2\r"}, + {id: "three-enter", label: "3 + Enter", display: "3⏎", sequence: "3\r"}, + {id: "ctrl-c", label: "Ctrl+C", display: "Ctrl+C", sequence: "\x03"}, + {id: "arrow-up", label: "Up", display: "ArrowUp", sequence: specialKeys.ArrowUp}, + {id: "arrow-down", label: "Down", display: "ArrowDown", sequence: specialKeys.ArrowDown}, + {id: "arrow-left", label: "Left", display: "ArrowLeft", sequence: specialKeys.ArrowLeft}, + {id: "arrow-right", label: "Right", display: "ArrowRight", sequence: specialKeys.ArrowRight}, + {id: "clear", label: "Clear", display: "Clear", sequence: CLEAR_SCREEN_SEQUENCE}, +]; + export default function MessageInput({ onSendMessage, disabled = false, @@ -121,9 +154,25 @@ export default function MessageInput({ setSentChars((prev) => [...prev, newChar]); }; + const handleControlAction = (action: ControlAction) => { + if (disabled || inputMode !== "control") { + return; + } + addSentChar(action.display); + onSendMessage(action.sequence, "raw"); + textareaRef.current?.focus(); + }; + const handleKeyDown = (e: KeyboardEvent) => { // In control mode, send special keys as raw messages if (inputMode === "control" && !disabled) { + if (e.key === "Tab" && e.shiftKey) { + e.preventDefault(); + addSentChar("Shift+Tab"); + onSendMessage(SHIFT_TAB_SEQUENCE, "raw"); + return; + } + // Check if the pressed key is in our special keys map if (specialKeys[e.key]) { e.preventDefault(); @@ -241,26 +290,54 @@ export default function MessageInput({
- - { - textareaRef.current?.focus(); - }} - > - Text - - { - textareaRef.current?.focus(); - }} - > - Control - - +
+ + { + textareaRef.current?.focus(); + }} + > + Text + + { + textareaRef.current?.focus(); + }} + > + Control + + + + {inputMode === "control" && !disabled && ( + + + + + + {CONTROL_ACTIONS.map((action) => ( + handleControlAction(action)} + > + {action.label} + + ))} + + + )} +
-
+