From eeb0a32b1c8973af0a53a3ea460e0c02a2f558ff Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sun, 5 Apr 2026 08:47:34 +0400 Subject: [PATCH 1/2] add windows smoke test workflow --- docs/install-notes-windows.md | 67 +++++++++ docs/poc-01-session-bootstrapper.md | 97 +++++++++++++ docs/smoke-test-runbook.md | 147 +++++++++++++++++++ scripts/poc/smoke_test_client.py | 158 +++++++++++++++++++++ scripts/windows/deploy_control_surface.ps1 | 33 +++++ scripts/windows/run_smoke_test.ps1 | 36 +++++ upstream-notes/imported-from-ziforge.md | 9 ++ 7 files changed, 547 insertions(+) create mode 100644 docs/install-notes-windows.md create mode 100644 docs/poc-01-session-bootstrapper.md create mode 100644 docs/smoke-test-runbook.md create mode 100644 scripts/poc/smoke_test_client.py create mode 100644 scripts/windows/deploy_control_surface.ps1 create mode 100644 scripts/windows/run_smoke_test.ps1 create mode 100644 upstream-notes/imported-from-ziforge.md diff --git a/docs/install-notes-windows.md b/docs/install-notes-windows.md new file mode 100644 index 0000000..01c1498 --- /dev/null +++ b/docs/install-notes-windows.md @@ -0,0 +1,67 @@ +# Windows Install Notes + +## Current Validated Behavior + +- Validated on the ASUS machine with Ableton Live `12.3.6`. +- `ClaudeMCP_Remote` did not become selectable when copied only into the user-level Ableton library path. +- On this machine, Ableton discovered the script only after it was copied into: + +```text +C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\ClaudeMCP_Remote +``` + +- After installation, the script still had to be selected manually in `Options > Preferences > Link, Tempo & MIDI`. +- The script then logged successful startup and exposed a TCP listener on `127.0.0.1:9004`. + +## Recommended Install Procedure + +1. Close Ableton Live. +2. Open PowerShell as Administrator if the `ProgramData` directory requires elevation. +3. From the repo root, run: + +```powershell +.\scripts\windows\deploy_control_surface.ps1 +``` + +4. Start Ableton Live. +5. Open `Options > Preferences > Link, Tempo & MIDI`. +6. Pick `ClaudeMCP_Remote` in an empty `Control Surface` slot. +7. Leave `Input` and `Output` unset unless another test explicitly requires them. + +## Verify Startup + +Check the Ableton log: + +```powershell +Get-Content "$env:APPDATA\Ableton\Live 12.3.6\Preferences\Log.txt" -Tail 200 +``` + +Expected startup lines include: + +- `Socket server started successfully on port 9004` +- `ClaudeMCP Remote Script initialized (Queue-based, Thread-Safe)` +- `Socket server listening on port 9004` + +## Verify Listener + +```powershell +Get-NetTCPConnection -LocalPort 9004 -ErrorAction SilentlyContinue | Format-Table -AutoSize LocalAddress,LocalPort,State,OwningProcess +``` + +Expected result: + +- `127.0.0.1 9004 Listen ` + +## Verify With Smoke Test + +```powershell +.\scripts\windows\run_smoke_test.ps1 +``` + +That wrapper runs the read-only smoke client and writes raw request/response output under `logs\`. + +## Operational Notes + +- On this machine, Windows-native runtime validation is more reliable than WSL for socket checks against Ableton. +- Treat WSL as the editing environment and Windows PowerShell as the runtime validation environment. +- Do not modify core Remote Script files for installation-only troubleshooting unless later evidence requires it. diff --git a/docs/poc-01-session-bootstrapper.md b/docs/poc-01-session-bootstrapper.md new file mode 100644 index 0000000..a781edd --- /dev/null +++ b/docs/poc-01-session-bootstrapper.md @@ -0,0 +1,97 @@ +# POC 01: Session Bootstrapper + +## Objective + +Establish a minimal, additive validation path that proves the `ClaudeMCP_Remote` Control Surface loads in Ableton Live, starts its localhost TCP server, and responds to at least one read-only request from an external client. + +## Scope + +- Install or verify the existing `ClaudeMCP_Remote` folder in Ableton's User Library Remote Scripts path on Windows. +- Select `ClaudeMCP_Remote` as an Ableton Control Surface. +- Confirm that Ableton listens on `127.0.0.1:9004`. +- Run `scripts/poc/smoke_test_client.py` using read-only actions only. +- Capture raw request and raw response output for review. + +## Non-goals + +- No bootstrapper logic beyond smoke validation. +- No live-performance workflow logic. +- No edits to `ClaudeMCP_Remote/__init__.py`. +- No edits to `ClaudeMCP_Remote/liveapi_tools.py`. +- No changes to the hard-coded action router. +- No attempt to validate all advertised tools. + +## Inputs + +- Local fork checkout on the ASUS machine. +- Ableton Live installed on Windows. +- Existing Remote Script source under `ClaudeMCP_Remote/`. +- Smoke client at `scripts/poc/smoke_test_client.py`. +- Ableton log file at `%APPDATA%\Ableton\Live x.x.x\Preferences\Log.txt`. + +## Outputs + +- Evidence that Ableton loaded the Control Surface without obvious startup errors. +- Evidence that `127.0.0.1:9004` is listening while Ableton is running. +- Raw request and raw response output from a read-only smoke test. +- A simple pass/fail result for this phase. + +## Proposed Command Sequence + +```powershell +cd C:\path\to\ableton-liveapi-tools-fork +python scripts\poc\smoke_test_client.py --host 127.0.0.1 --port 9004 --log-file logs\smoke-test-session.txt +``` + +Optional explicit single-action probe: + +```powershell +python scripts\poc\smoke_test_client.py --action ping --log-file logs\smoke-test-ping.txt +``` + +Optional listener check before the client run: + +```powershell +netstat -ano | findstr 9004 +``` + +## Verification Steps + +1. Confirm `ClaudeMCP_Remote` is present under the Ableton User Library Remote Scripts directory. +2. Launch Ableton Live and select `ClaudeMCP_Remote` in Preferences > Link, Tempo & MIDI > Control Surface. +3. Open the Ableton log and confirm there is no immediate `ClaudeMCP` startup exception. +4. Confirm a localhost listener exists on port `9004`. +5. Run the smoke client and verify that the first action is read-only. +6. Review the captured raw request and raw response output in the chosen log file. + +## Risks + +- Upstream install docs appear to overstate autoloading; manual Control Surface selection is likely required. +- The protocol is inferred from repo code and examples, not from a formal spec. +- Ableton can load the Control Surface but still fail to bind the socket if the port is already in use. +- `get_session_info` is read-only but still depends on the main-thread queue path being healthy. +- The Ableton log location varies by installed version string. + +## Pass/Fail Criteria + +Pass: + +- Ableton loads `ClaudeMCP_Remote` without obvious startup failure. +- Port `9004` is listening on `127.0.0.1`. +- The smoke client sends a read-only request first. +- The smoke client receives valid JSON with `"ok": true`. +- Raw request/response output is saved for review. + +Fail: + +- Ableton cannot load or select the Control Surface. +- No listener appears on port `9004`. +- The client cannot connect or times out. +- The response is empty, malformed, or returns `"ok": false`. + +## Rollback Approach + +- Deselect `ClaudeMCP_Remote` in Ableton Preferences and switch the Control Surface slot back to `None`. +- Remove or rename the installed `ClaudeMCP_Remote` directory from the Ableton User Library Remote Scripts path if needed. +- Delete only the smoke-test log files created under `logs/`. +- Leave core repo files unchanged, since this phase is additive only. diff --git a/docs/smoke-test-runbook.md b/docs/smoke-test-runbook.md new file mode 100644 index 0000000..599adfa --- /dev/null +++ b/docs/smoke-test-runbook.md @@ -0,0 +1,147 @@ +# Smoke Test Runbook + +## Purpose + +Run a minimal read-only validation of the existing `ClaudeMCP_Remote` Control Surface on Windows and capture raw TCP request/response output for review. + +## Validated Environment Notes + +- This ASUS runtime path was validated against Ableton Live `12.3.6` on Windows. +- On this machine, `ClaudeMCP_Remote` became selectable only after being copied into Ableton's built-in scripts directory under `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts`. +- WSL-side socket checks did not reliably see the Ableton listener even when the script was active. +- For this machine, treat Windows-native PowerShell or Command Prompt as the authoritative runtime validation environment. + +## Install And Select The Control Surface On Windows + +1. Close Ableton Live. +2. Copy the repo's `ClaudeMCP_Remote` folder into the built-in Ableton MIDI Remote Scripts directory: + +```powershell +Copy-Item -Recurse -Force .\ClaudeMCP_Remote "C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts\ClaudeMCP_Remote" +``` + +3. Start Ableton Live. +4. Open `Options > Preferences > Link, Tempo & MIDI`. +5. In an empty `Control Surface` slot, choose `ClaudeMCP_Remote`. +6. Leave the paired `Input` and `Output` fields unset unless a separate test requires them. + +Note: + +- Upstream docs suggest automatic loading after install, but current validated behavior on this machine still requires explicit Control Surface selection. +- The repo now includes [`scripts/windows/deploy_control_surface.ps1`](/home/jniplig/dev/AbletonAPI/ableton-liveapi-tools-fork/scripts/windows/deploy_control_surface.ps1) to make this copy step repeatable. + +## Confirm The TCP Server Is Running + +1. After selecting the Control Surface, wait a few seconds for Ableton to finish loading. +2. In PowerShell or Command Prompt, check for a listener on port `9004`: + +```powershell +Get-NetTCPConnection -LocalPort 9004 -ErrorAction SilentlyContinue | Format-Table -AutoSize LocalAddress,LocalPort,State,OwningProcess +``` + +Expected shape: + +- A line showing `127.0.0.1 9004 Listen `. + +3. If needed, inspect the Ableton log for `ClaudeMCP` startup messages or exceptions: + +```powershell +Get-Content "$env:APPDATA\Ableton\Live 12.3.6\Preferences\Log.txt" -Tail 200 +``` + +If the exact version directory differs, adjust the `Live 12.3.6` segment to match the installed version. + +## Run The Smoke Test + +From the repo root: + +```powershell +.\scripts\windows\run_smoke_test.ps1 +``` + +Equivalent direct invocation: + +```powershell +py -3 .\scripts\poc\smoke_test_client.py --host 127.0.0.1 --port 9004 --log-file .\logs\smoke-test-run.txt +``` + +Default action order: + +1. `ping` +2. `health_check` +3. `get_session_info` + +If a narrower first probe is preferred: + +```powershell +python scripts\poc\smoke_test_client.py --action ping --log-file logs\smoke-test-ping.txt +``` + +## Capture Logs + +Client-side capture: + +- Use `--log-file logs\smoke-test-run.txt` to append raw request and raw response lines. + +Ableton-side capture: + +```powershell +Get-Content "$env:APPDATA\Ableton\Live 12.3.6\Preferences\Log.txt" -Tail 200 +``` + +Optional transcript capture in PowerShell: + +```powershell +Start-Transcript -Path .\logs\powershell-session.txt +.\scripts\windows\run_smoke_test.ps1 +Stop-Transcript +``` + +## What Success Looks Like + +- Ableton remains running after the Control Surface is selected. +- `netstat` shows a listener on port `9004`. +- The smoke client prints the raw JSON request and raw JSON response for each action. +- The first action is read-only. +- At least one response is valid JSON and includes `"ok": true`. +- The log file under `logs\` contains the captured raw request/response output. + +## Common Failure Cases + +Control Surface does not appear in Ableton: + +- Confirm the installed folder name is exactly `ClaudeMCP_Remote`. +- Confirm the folder contains both `__init__.py` and `liveapi_tools.py`. +- Confirm the script was copied into the built-in `C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts` directory on this machine. +- Restart Ableton after copying the files. + +Connection refused: + +- Ableton is not running. +- `ClaudeMCP_Remote` is not selected as a Control Surface. +- The script failed during startup before opening the socket. + +Port `9004` is already in use: + +- Another process is already bound to the port. +- An earlier Ableton instance did not exit cleanly. + +Client times out: + +- Ableton loaded but the main-thread queue is blocked. +- The socket accepted the connection but the script did not produce a response within the timeout window. + +Malformed or unexpected response: + +- Protocol details are inferred from repo code and examples and may differ from external guidance. +- Review the raw response and the Ableton log before assuming the client is wrong. + +Ableton log path not found: + +- The installed Live version directory differs from the example path. +- Search under `%APPDATA%\Ableton\` for the active `Live x.x.x\Preferences\Log.txt`. + +WSL cannot see the listener: + +- On this machine, that is expected. +- Use Windows-native PowerShell or Command Prompt for runtime validation instead of WSL socket checks. diff --git a/scripts/poc/smoke_test_client.py b/scripts/poc/smoke_test_client.py new file mode 100644 index 0000000..3c2dcb7 --- /dev/null +++ b/scripts/poc/smoke_test_client.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python3 +""" +Minimal smoke test client for the ClaudeMCP Remote Script TCP server. + +Assumptions based on repo inspection: +- The Remote Script listens on 127.0.0.1:9004 by default. +- Requests are JSON objects terminated by a single newline. +- Responses are JSON objects terminated by a single newline. +- Safe read-only actions include: ping, health_check, get_session_info. +""" + +import argparse +import json +import socket +import sys +from datetime import datetime + + +DEFAULT_HOST = "127.0.0.1" +DEFAULT_PORT = 9004 +DEFAULT_TIMEOUT = 5.0 +DEFAULT_ACTIONS = ("ping", "health_check", "get_session_info") + + +def parse_args(): + parser = argparse.ArgumentParser( + description="Send a small read-only smoke test sequence to the Ableton Remote Script." + ) + parser.add_argument("--host", default=DEFAULT_HOST, help="TCP host to connect to") + parser.add_argument("--port", type=int, default=DEFAULT_PORT, help="TCP port to connect to") + parser.add_argument( + "--timeout", + type=float, + default=DEFAULT_TIMEOUT, + help="Socket timeout in seconds", + ) + parser.add_argument( + "--action", + action="append", + dest="actions", + help="Action to send. Repeat to override the default sequence.", + ) + parser.add_argument( + "--log-file", + help="Optional path to append raw request/response output for review.", + ) + return parser.parse_args() + + +def emit(text, log_file=None): + print(text) + if log_file: + with open(log_file, "a", encoding="utf-8") as handle: + handle.write(text + "\n") + + +def recv_line(sock): + chunks = [] + while True: + chunk = sock.recv(4096) + if not chunk: + break + chunks.append(chunk) + if b"\n" in chunk: + break + if not chunks: + return b"" + return b"".join(chunks) + + +def send_action(sock, action, log_file=None): + command = {"action": action} + raw_request = json.dumps(command) + "\n" + + emit("", log_file=log_file) + emit("----", log_file=log_file) + emit("timestamp: {0}".format(datetime.now().isoformat(timespec="seconds")), log_file=log_file) + emit("action: {0}".format(action), log_file=log_file) + emit("raw request: {0}".format(raw_request.rstrip("\n")), log_file=log_file) + + sock.sendall(raw_request.encode("utf-8")) + raw_response = recv_line(sock) + if not raw_response: + raise RuntimeError("No response received from server") + + decoded_response = raw_response.decode("utf-8", errors="replace").rstrip("\n") + emit("raw response: {0}".format(decoded_response), log_file=log_file) + + try: + parsed = json.loads(decoded_response) + except ValueError as exc: + raise RuntimeError("Response was not valid JSON: {0}".format(exc)) + + return parsed + + +def main(): + args = parse_args() + actions = tuple(args.actions) if args.actions else DEFAULT_ACTIONS + + if not actions: + print("error: no actions specified", file=sys.stderr) + return 2 + + try: + with socket.create_connection((args.host, args.port), timeout=args.timeout) as sock: + sock.settimeout(args.timeout) + emit( + "Connecting to {0}:{1} with timeout {2}s".format( + args.host, args.port, args.timeout + ), + log_file=args.log_file, + ) + + for index, action in enumerate(actions): + if index == 0 and action not in ("ping", "health_check", "get_session_info"): + raise RuntimeError( + "First action must be read-only for this smoke test: ping, health_check, or get_session_info" + ) + + response = send_action(sock, action, log_file=args.log_file) + if not response.get("ok"): + raise RuntimeError( + "Action '{0}' failed: {1}".format( + action, response.get("error", "unknown error") + ) + ) + + emit("", log_file=args.log_file) + emit("Smoke test passed", log_file=args.log_file) + return 0 + + except ConnectionRefusedError: + print( + "error: connection refused on {0}:{1}; confirm Ableton is running and the Control Surface is selected".format( + args.host, args.port + ), + file=sys.stderr, + ) + return 1 + except socket.timeout: + print( + "error: timed out talking to {0}:{1}; Ableton may be busy or the script may not be loaded".format( + args.host, args.port + ), + file=sys.stderr, + ) + return 1 + except OSError as exc: + print("error: socket failure: {0}".format(exc), file=sys.stderr) + return 1 + except RuntimeError as exc: + print("error: {0}".format(exc), file=sys.stderr) + return 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/windows/deploy_control_surface.ps1 b/scripts/windows/deploy_control_surface.ps1 new file mode 100644 index 0000000..da1f998 --- /dev/null +++ b/scripts/windows/deploy_control_surface.ps1 @@ -0,0 +1,33 @@ +param( + [string]$RepoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..\..")).Path, + [string]$AbletonScriptsRoot = "C:\ProgramData\Ableton\Live 12 Suite\Resources\MIDI Remote Scripts", + [switch]$BackupExisting +) + +$ErrorActionPreference = "Stop" + +$source = Join-Path $RepoRoot "ClaudeMCP_Remote" +$destination = Join-Path $AbletonScriptsRoot "ClaudeMCP_Remote" + +if (-not (Test-Path $source)) { + throw "Source control surface not found: $source" +} + +if (-not (Test-Path $AbletonScriptsRoot)) { + throw "Ableton MIDI Remote Scripts directory not found: $AbletonScriptsRoot" +} + +if ($BackupExisting -and (Test-Path $destination)) { + $timestamp = Get-Date -Format "yyyyMMdd_HHmmss" + $backupPath = "${destination}.backup.$timestamp" + Move-Item -Path $destination -Destination $backupPath + Write-Host "Backed up existing installation to $backupPath" +} +elseif (Test-Path $destination) { + Remove-Item -Recurse -Force $destination +} + +Copy-Item -Recurse -Force $source $destination + +Write-Host "Installed ClaudeMCP_Remote to $destination" +Write-Host "Next step: restart Ableton Live and select ClaudeMCP_Remote as a Control Surface." diff --git a/scripts/windows/run_smoke_test.ps1 b/scripts/windows/run_smoke_test.ps1 new file mode 100644 index 0000000..a705ffb --- /dev/null +++ b/scripts/windows/run_smoke_test.ps1 @@ -0,0 +1,36 @@ +param( + [string]$RepoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..\..")).Path, + [string]$Host = "127.0.0.1", + [int]$Port = 9004, + [string]$PythonLauncher = "py", + [string]$LogFile = "" +) + +$ErrorActionPreference = "Stop" + +$clientPath = Join-Path $RepoRoot "scripts\poc\smoke_test_client.py" +$logsDir = Join-Path $RepoRoot "logs" + +if (-not (Test-Path $clientPath)) { + throw "Smoke test client not found: $clientPath" +} + +if (-not (Test-Path $logsDir)) { + New-Item -ItemType Directory -Path $logsDir | Out-Null +} + +if (-not $LogFile) { + $timestamp = Get-Date -Format "yyyyMMdd_HHmmss" + $LogFile = Join-Path $logsDir "smoke-test-$timestamp.txt" +} + +Write-Host "Checking Windows listener state on port $Port..." +Get-NetTCPConnection -LocalPort $Port -ErrorAction SilentlyContinue | + Format-Table -AutoSize LocalAddress, LocalPort, State, OwningProcess + +Write-Host "" +Write-Host "Running smoke test client..." +& $PythonLauncher -3 $clientPath --host $Host --port $Port --log-file $LogFile + +Write-Host "" +Write-Host "Raw request/response capture saved to $LogFile" diff --git a/upstream-notes/imported-from-ziforge.md b/upstream-notes/imported-from-ziforge.md new file mode 100644 index 0000000..d7542f4 --- /dev/null +++ b/upstream-notes/imported-from-ziforge.md @@ -0,0 +1,9 @@ +Upstream repository: https://github.com/Ziforge/ableton-liveapi-tools + +Imported on: 2026-04-05 + +Imported commit: def40f7 + +Notes: +- Local fork scaffold directories under `docs/`, `scripts/`, `logs/`, and `upstream-notes/` were preserved. +- Upstream example scripts were placed under `examples/`. From 7c600b310d4d8343a259b7c209af27ab28b6d90d Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sun, 5 Apr 2026 11:04:23 +0400 Subject: [PATCH 2/2] add poc 02 status monitor plan --- docs/poc-02-status-monitor.md | 153 ++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 docs/poc-02-status-monitor.md diff --git a/docs/poc-02-status-monitor.md b/docs/poc-02-status-monitor.md new file mode 100644 index 0000000..ed17f5b --- /dev/null +++ b/docs/poc-02-status-monitor.md @@ -0,0 +1,153 @@ +# POC 02: Status Monitor + +## Objective + +Define a minimal, additive status-monitor layer that improves confidence in `ClaudeMCP_Remote` runtime health without modifying the core Remote Script, the 220-action router, or any live-performance behavior. + +## Scope + +- Build on the validated Windows smoke-test workflow from POC 01. +- Focus on read-only runtime signals already exposed by the repo and the host environment. +- Standardize how to confirm that the Control Surface loaded, the TCP server is listening, and basic session health can be queried safely. +- Capture evidence from both Ableton logs and TCP responses for later review. + +## Non-goals + +- No edits to `ClaudeMCP_Remote/__init__.py`. +- No edits to `ClaudeMCP_Remote/liveapi_tools.py`. +- No changes to the static action router. +- No event subscription or observer subsystem. +- No attempt to stream real-time session state. +- No live-performance automation, transport control, or write actions. + +## Current Known Signals + +From repo inspection and runtime validation, the following read-only signals already exist: + +- Ableton log messages emitted through `c_instance.log_message(...)`. +- Startup log lines including: + - `Socket server started successfully on port 9004` + - `ClaudeMCP Remote Script initialized (Queue-based, Thread-Safe)` + - `Socket server listening on port 9004` + - `Client connected from ...` +- TCP listener on `127.0.0.1:9004`. +- Read-only TCP actions: + - `ping` + - `health_check` + - `get_session_info` + +## Proposed Monitor Surface + +The status monitor for this phase should be a wrapper-level workflow, not a new core feature. + +### Layer 1: Process and startup evidence + +- Confirm Ableton Live is running. +- Confirm `ClaudeMCP_Remote` is selected as a Control Surface. +- Confirm recent Ableton log lines show successful script startup rather than an import or bind failure. + +### Layer 2: Listener evidence + +- Confirm Windows shows `127.0.0.1:9004` in `Listen` state. +- Record the owning process ID when available. + +### Layer 3: Read-only protocol evidence + +- Run `ping` to prove command/response flow works. +- Run `health_check` to capture: + - `ok` + - `message` + - `tool_count` + - `ableton_version` + - `queue_size` +- Run `get_session_info` to capture: + - playback state + - tempo + - time signature + - track count + - scene count + - loop values + +### Layer 4: Evidence capture + +- Save raw request and raw response payloads. +- Save a short Ableton log extract around startup and the client connection event. +- Keep outputs timestamped for side-by-side review across runs. + +## Proposed Artifacts + +This phase does not require core-code changes. The likely additive outputs are: + +- a small Windows-native wrapper script for repeated status checks +- a status log file under `logs/` +- a short runbook section or dedicated doc for interpreting the captured signals + +The current repo already includes most of the needed pieces: + +- `scripts/windows/run_smoke_test.ps1` +- `scripts/poc/smoke_test_client.py` +- `docs/smoke-test-runbook.md` + +## Proposed Command Sequence + +```powershell +.\scripts\windows\deploy_control_surface.ps1 +``` + +Restart Ableton Live, select `ClaudeMCP_Remote`, then run: + +```powershell +.\scripts\windows\run_smoke_test.ps1 +``` + +Optional direct checks: + +```powershell +Get-NetTCPConnection -LocalPort 9004 -ErrorAction SilentlyContinue | Format-Table -AutoSize LocalAddress,LocalPort,State,OwningProcess +Get-Content "$env:APPDATA\Ableton\Live 12.3.6\Preferences\Log.txt" -Tail 200 +``` + +## Verification Steps + +1. Confirm Ableton starts without obvious Control Surface load errors. +2. Confirm `127.0.0.1:9004` is in `Listen` state from Windows. +3. Run the smoke-test wrapper and confirm the first action remains read-only. +4. Confirm `ping`, `health_check`, and `get_session_info` all return valid JSON with `"ok": true`. +5. Review the raw request/response capture and the recent Ableton log tail together. +6. Confirm the captured `tool_count` and `ableton_version` remain plausible across repeated runs. + +## Risks + +- This repo still has no event-driven status feed, so the monitor is polling-based and coarse. +- `health_check` is useful but limited; it reports queue size and version, not full runtime internals. +- WSL-side socket visibility was unreliable on this machine, so status checks must be treated as Windows-native. +- The exact Ableton log path can vary by installed version. +- A successful listener check does not guarantee every action path is implemented correctly. + +## Pass/Fail Criteria + +Pass: + +- Ableton startup evidence is present in the log. +- Windows shows `127.0.0.1:9004` listening. +- Read-only status requests succeed consistently. +- Raw request/response and log evidence are captured together. +- No core Remote Script changes are required for the monitor workflow. + +Fail: + +- The script does not load or does not stay loaded. +- The port is not listening. +- Read-only requests fail, time out, or return malformed JSON. +- The monitoring workflow depends on WSL-only checks that do not reflect the real Windows runtime. + +## Rollback Approach + +- Deselect `ClaudeMCP_Remote` in Ableton Preferences if needed. +- Remove the deployed control surface copy from the Ableton scripts directory if this POC must be backed out. +- Delete only additive logs and wrapper outputs. +- Leave core repo code unchanged. + +## Recommendation + +Proceed with POC 02 as a documentation-and-wrapper phase first. Do not introduce a new monitoring subsystem in the Remote Script until repeated Windows-native runs show a stable need for more granular observability.