I want to create support for being able to invoke an agent from a script via a thread() function.

This function should take 3 parameters:

- the prompt
- a schema documenting the desired yield type
- an optional options param documenting the type of model we want to invoke, settings on that model, available tools, cwd, and other things (we will extend this later)

The underlying mechanism is that this script will run inside a magenta / neovim session. When the thread function is triggered, it will create a thread - visible in magenta and interactive in the same way as any other thread. The thread will run with the prompt. The thread will be spawened with a yield_to_parent tool that matches the schema provided in the yield type. So when the agent is done, it will yield back to the script.

I think there should be 2 interfaces for the script:

1. lua, through the magenta plugin command api. lua hands control over to the plugin via a function call. The function call is received on the node side. The function runs, then yields the result back to the lua side. We can use this to leverage magenta threads to customzie neovim behavior, like hooking up thread-driven actions to key bindings, etc...

2. typescript. the magenta node process spawns a subprocess that runs a typescript script. The script has a small shell magenta sdk library that assumes it's running as a subprocess and uses ipc to invoke the agent command. The magenta node process monitors the ipc sockets and is able to receive the thread parameters, and send the results back. This means we need to write a small typescript lib that users can use to create these scripts (which are intended to run as subprocesses).

I think beyond the agent() function we'll create a more rich communication mechanism so the script can drive the magenta ui better:

From the lua side, these scripts are triggered by the user via the neovim surface, and run immediately.

On the magenta side, these scripts are placed in a `.magenta/scripts` directory and discovered. The sdk provides a registerScript function:

```
function registerScript('name', 'description', parameterSchema, async runner(parameters, thread, log) => Promse<void>): void
```

This exposes the script by name/description/parameterSchema to agents running in magenta, so they can trigger them. Once triggered, they live outside of the lifecycle of the thread that triggered them.

When a script is invoked, it establishes a communication with magenta, and gives the inner runner access to the parameters, thread & report functions. When executed, on the magenta side, this makes the script show up in the thread overview, under a new scripts section. Threads and logs spawned by the script end up showing up in that section.

log just allows the script to report on its progress, as threads run. This shows up within the script section.
