Skip to main content

multi-instance

Workflow for running multiple TD instances with Envoy, switching between them, and understanding the instance registry.

ソース情報

リポジトリ
dylanroscover/Embody
ソースの最終更新活動
2026年9月6日 07:13
検出された SKILL.md の言語
英語
スター
182
フォーク
11

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
multi-instance
description
Workflow for running multiple TD instances with Envoy, switching between them, and understanding the instance registry.
# Multi-Instance Workflow Envoy supports multiple TouchDesigner instances running simultaneously in the same git repo. Each instance gets its own port, and the bridge can switch between them on demand. ## Architecture ``` Claude Code <--> STDIO Bridge <--> Envoy (TD instance A, port 9870) | +---switch---> Envoy (TD instance B, port 9871) ``` - **One bridge process per SESSION** (spawned by each AI client's MCP client) - **Per-session pinning** - each bridge pins to an instance NAME and re-resolves its port from the registry every tick, so a pinned instance restarting on a new port still self-heals. The registry `active` field only seeds NEW bridges without a pin. - **Per-call addressing** - every Envoy tool accepts an optional `instance` argument; the bridge routes that one call to the named instance and leaves the pin alone (unknown or unreachable names fail only that call with `error_code` `envoy.instance.unknown` / `envoy.instance.unreachable`). Prefer it over switching when you only need one look at another instance. - **Switching is instant and session-local** - `switch_instance` re-pins THIS session's bridge in-memory; peers are untouched unless you pass `all_sessions=True` (writes the registry default and bumps `active_epoch`, which moves every session) - **Registration never re-routes running sessions** - a new instance takes the `active` default slot only when it is vacant or names a dead instance ## Instance Registry (`.embody/envoy.json`) Each Envoy instance registers itself in `.embody/envoy.json` at the git root on startup: ```json { "active": "Embody-5.257", "td_executable": "/Applications/TouchDesigner.app", "instances": { "Embody-5.257": { "toe_path": "dev/Embody-5.257.toe", "port": 9870, "td_pid": 12345 }, "MySecondProject": { "toe_path": "MySecondProject.toe", "port": 9871, "td_pid": 67890 } } } ``` | Field | Purpose | |-------|---------| | `active` | Default instance for NEWLY-spawned bridges (each bridge then pins per-session; only an `active_epoch` bump re-targets pinned bridges) | | `td_executable` | Path to TD app (used by `launch_td`) | | `instances.<name>.toe_path` | Relative path to the `.toe` file | | `instances.<name>.port` | Envoy HTTP port for this instance | | `instances.<name>.td_pid` | OS process ID of the TD process | Instances are added on Envoy startup and removed on graceful shutdown (`onDestroyTD`). ## Port Allocation Each instance picks a port from a 10-port range starting at the configured `Envoyport` parameter (default: `9870`): 1. Try the base port first 2. If occupied by **this** TD process's old server, force-close it and reclaim 3. If occupied by **another** process, scan `base+1` through `base+9` 4. First available port wins; if all 10 are taken, startup fails This means up to 10 simultaneous instances per base port. ## Workflow: Running Multiple Instances ### 1. Open the first `.toe` file Launch TD normally or via `launch_td`. Envoy starts on its configured port and registers in `.embody/envoy.json`. ### 2. Open additional `.toe` files Open them in separate TD instances (File > Open or double-click). Each Embody/Envoy auto-starts and claims the next available port. ### 3. List instances Call `switch_instance` with no parameters to see all registered instances and their status: ``` switch_instance() ``` Returns each instance's name, port, PID, reachability (PID alive + port responding), and whether it's the active target. ### 4. Switch to a different instance ``` switch_instance(instance="MySecondProject") ``` The bridge immediately redirects to the target instance's port. All subsequent MCP calls go to that TD process. ### 5. Switch back ``` switch_instance(instance="Embody-5.257") ``` ## Reachability Checks An instance is **reachable** only when: - Its registered PID is alive (`kill -0` / process table check) - Its registered port responds to a TCP connect Both conditions must be true. A dead PID with an open port means another instance reused that port - the entry is stale. `get_td_status` includes the full instance registry with reachability in its response. ## Stale Instance Cleanup Instances are deregistered on graceful TD shutdown. If TD crashes: - The PID becomes dead, so the instance shows as unreachable - The port may be freed, allowing a new instance to claim it - Stale entries remain in `.embody/envoy.json` but are filtered by reachability checks - Re-launching TD with the same `.toe` overwrites the stale entry ## Closing Instances **Preferred**: Close TD instances via Envoy by calling `execute_python` with `project.quit()`. This prompts the user to save unsaved changes, then triggers `onDestroyTD` for clean deregistration and port release. Works reliably across platforms. To close a specific instance, `switch_instance` to it first, then send the quit command: ```python switch_instance(instance="MySecondProject") # target the instance execute_python(code="project.quit()") # user gets save prompt in TD ``` **Never use `project.quit(force=True)`** unless the user has explicitly asked - it skips the save dialog and risks losing unsaved work. **Avoid**: `osascript -e 'quit app "TouchDesigner"'` and similar OS-level approaches are unreliable - they may not target the correct instance and don't guarantee clean Envoy shutdown. ## Common Scenarios | Scenario | Action | |----------|--------| | Test code in two `.toe` files side by side | Open both, `switch_instance` between them | | Test code in a secondary `.toe` | Open it, switch to it, perform work, switch back | | Check if a second TD is still running | `switch_instance()` (list mode) or `get_td_status` | | One instance crashed, want the other | `switch_instance` to the surviving instance | | Close a specific instance | `switch_instance` to it, then `execute_python` with `project.quit()` | ## Same-Project Instances When you open the same `.toe` file in multiple TD instances, Envoy auto-suffixes the registry key to avoid collisions. The first instance registers as `MyProject`, the second as `MyProject-2`, etc. Stale entries (dead PIDs) are automatically reclaimed. ## Limitations - The bridge connects to **one instance at a time** - no parallel MCP calls to multiple instances - Maximum **10 instances** per base port range - `.embody/envoy.json` is per git root - instances in different repos have separate registries - `launch_td` always launches the `.toe` configured in `.embody/envoy.json` top-level `toe_path` - use TD directly to open additional files - Opening the same `.toe` file in multiple instances auto-suffixes keys (`MyProject-2`, `-3`, etc.)
GitHubで見る