/ src / tools / spawn-chat.ts
spawn-chat.ts
 1  /**
 2   * Spawn Chat MCP Tool - Open Claude Code in another DreamNode
 3   * Enables holarchy traversal by spawning new sessions in subcontexts
 4   */
 5  
 6  import { exec } from 'child_process';
 7  import { promisify } from 'util';
 8  import { DreamNodeService } from '../services/standalone-adapter.js';
 9  
10  const execAsync = promisify(exec);
11  
12  /**
13   * Tool: spawn_chat
14   * Open Claude Code in a new terminal tab for a specific DreamNode
15   */
16  export async function spawnChat(args: {
17    identifier: string;
18    prompt?: string;
19  }): Promise<{
20    success: boolean;
21    dreamnode_path?: string;
22    dreamnode_title?: string;
23    error?: string;
24  }> {
25    try {
26      // Resolve DreamNode
27      const node = await DreamNodeService.getDreamNode(args.identifier);
28  
29      if (!node) {
30        return {
31          success: false,
32          error: `DreamNode not found: ${args.identifier}`
33        };
34      }
35  
36      // Build the claude command
37      let claudeCmd = 'claude';
38      if (args.prompt) {
39        // Escape the prompt for shell
40        const escapedPrompt = args.prompt.replace(/'/g, "'\\''");
41        claudeCmd = `claude '${escapedPrompt}'`;
42      }
43  
44      // macOS: Use osascript to open new Terminal tab and run command
45      const script = `
46        tell application "Terminal"
47          activate
48          tell application "System Events" to keystroke "t" using command down
49          delay 0.3
50          do script "cd '${node.path}' && ${claudeCmd}" in front window
51        end tell
52      `;
53  
54      await execAsync(`osascript -e '${script.replace(/'/g, "'\"'\"'")}'`);
55  
56      return {
57        success: true,
58        dreamnode_path: node.path,
59        dreamnode_title: node.title
60      };
61    } catch (error) {
62      return {
63        success: false,
64        error: error instanceof Error ? error.message : 'Unknown error'
65      };
66    }
67  }
68  
69  /**
70   * Export tool definitions for MCP registration
71   */
72  export const spawnChatTools = {
73    spawn_chat: {
74      name: 'spawn_chat',
75      description: 'Open Claude Code in a new terminal tab for a specific DreamNode. Enables holarchy traversal - spawn sessions in subcontexts to delegate work.',
76      inputSchema: {
77        type: 'object' as const,
78        properties: {
79          identifier: {
80            type: 'string',
81            description: 'UUID or title of the DreamNode to open Claude Code in'
82          },
83          prompt: {
84            type: 'string',
85            description: 'Optional initial prompt to send to Claude Code'
86          }
87        },
88        required: ['identifier']
89      },
90      handler: spawnChat
91    }
92  };