| 203 | argsSchema = TypeArgs; |
| 204 | |
| 205 | async execute(args: z.infer<typeof TypeArgs>, _ctx: ToolContext): Promise<ToolResult> { |
| 206 | if (!isMacos()) return macosOnly(this.name); |
| 207 | try { |
| 208 | const cliclickPath = await which('cliclick'); |
| 209 | if (cliclickPath) { |
| 210 | // cliclick t:<text> types literal text. Special chars need escaping. |
| 211 | await runCmd(cliclickPath, ['t:' + args.text], { timeoutMs: 15_000 }); |
| 212 | return { content: `Typed ${args.text.length} char(s).` }; |
| 213 | } |
| 214 | // Fallback: AppleScript keystroke |
| 215 | const escaped = args.text.replace(/\\/g, '\\\\').replace(/"/g, '\\"'); |
| 216 | const script = `tell application "System Events" to keystroke "${escaped}"`; |
| 217 | await runCmd('osascript', ['-e', script], { timeoutMs: 15_000 }); |
| 218 | return { content: `Typed ${args.text.length} char(s) via AppleScript.` }; |
| 219 | } catch (e: any) { |
| 220 | return { content: `[COMPUTER_USE_ERROR] type failed: ${e?.message ?? e}`, isError: true }; |
| 221 | } |
| 222 | } |
| 223 | } |
| 224 | |
| 225 | // ───────────────────────────────────────────────────────────────────────────── |