refactor: implement per-conversation tmux sessions and command-based MCP tools
This commit implements isolated tmux sessions for each conversation and refines the terminal MCP tools to use consistent command terminology. **Per-Conversation Tmux Sessions:** - Each Session now creates its own Terminal MCP client with conversation ID as tmux session name - Complete isolation: commands from different conversations don't interfere - Automatic cleanup: tmux session killed when conversation ends - Updated getAllTools() to accept custom terminal tools per session - Session.cleanup() now async to properly await tmux session termination **Command-Based MCP Tools:** - Removed old terminal-based tools (list_terminals, create_terminal, etc.) - Kept only command-based tools (execute_command, list_commands, etc.) - Updated kill_command to accept multiple command IDs for batch cleanup - Fixed bug where all commands showed same metadata (working directory, command) - Added window-specific option storage using set-window-option/show-window-options **Bug Fixes:** - Fixed listCommands() showing wrong working directory and command for dead commands - Stored command metadata as tmux window options for proper retrieval - Enhanced test to verify multiple commands retain unique metadata **Testing:** - Added comprehensive test suite with 26 passing tests - All tests verify command execution, capture, interaction, and cleanup - TypeScript: no errors - Backward compatibility maintained with global singleton fallback Generated with [Claude Code](https://claude.com/claude-code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
This commit is contained in:
co-authored by
Claude
Happy
parent
b267ca3958
commit
37a363da6d
@@ -152,8 +152,28 @@ const manualTools = {
|
||||
|
||||
/**
|
||||
* Get all tools (MCP + manual) for LLM
|
||||
* @param terminalTools - Optional custom terminal tools (per-session). If not provided, uses global singleton.
|
||||
*/
|
||||
export async function getAllTools(): Promise<Record<string, any>> {
|
||||
export async function getAllTools(terminalTools?: Record<string, any>): Promise<Record<string, any>> {
|
||||
if (terminalTools) {
|
||||
// Use provided terminal tools (per-session) and merge with Playwright
|
||||
const playwrightClient = await getPlaywrightMcpClient().catch((error) => {
|
||||
console.error("Failed to initialize Playwright MCP:", error);
|
||||
return null;
|
||||
});
|
||||
|
||||
const playwrightTools = playwrightClient
|
||||
? await playwrightClient.tools()
|
||||
: {};
|
||||
|
||||
return {
|
||||
...terminalTools,
|
||||
...playwrightTools,
|
||||
...manualTools,
|
||||
};
|
||||
}
|
||||
|
||||
// Fallback to global singleton tools
|
||||
const mcpTools = await getMcpTools();
|
||||
return {
|
||||
...mcpTools,
|
||||
|
||||
Reference in New Issue
Block a user