Repository navigation
feat: rename to Toneshuttle as a general vocal and audio toolbox / 更名为声梭通用工具箱 - #4
Conversation
The product is moving from the Synthesizer V Toolbox name to Toneshuttle (声梭). Identifiers that existing installs depend on (userData folder, appId, NSIS GUID) are recorded separately so the rename cannot orphan user data. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tity - Pin userData to the legacy synthv-toolbox folder unless --user-data-dir is passed, so renaming the product can never orphan credentials, settings or plugins. - Load the SynthV bridge non-fatally; a broken component now leaves the app usable. - Add an auto/on/off SynthV integration preference: off skips every SynthV probe, hides SynthV components and drops the sv_* and Cover tools from agent sessions. - Isolate SynthV probe failures so they no longer reject the whole bootstrap. - Send a Toneshuttle system prompt naming the active integrations instead of Pi's coding-assistant default. - Refuse /agent and toolbox_agent outside AI mode, as the toolbox-mode copy promises. - Re-register launch at login when the renamed executable leaves a stale Run entry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Installers, release assets and the macOS app bundle now carry the Toneshuttle name. The appId, a pinned NSIS GUID derived from it, the GitHub update feed, the signing center project and the bundle id keep their original values so existing installs upgrade in place and keep receiving updates. Release drafting, macOS signing and publishing, and nightly validation look for the renamed assets; the macOS release tests import scripts through file URLs so they also run on Windows. The terms of use, README, changelog and guides describe Toneshuttle (声梭) as a general vocal and audio toolbox with Synthesizer V as an optional integration. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
activateProfile deleted the official Synthesizer V Studio 2 folder and copied the target slot over it without saving the folder back first, and import_current_sv2_profile only created an empty slot. Activating an imported slot therefore replaced the user's real SV2 data with an empty folder, and every launch discarded what SV2 had written since the last activation. Activation now saves the official folder into the active slot (or, when no slot is active, moves it into a timestamped backup under the vault that is never pruned) before swapping the target in. Re-activating the active slot only refreshes its saved copy. Every replacement copies into a temporary sibling and swaps by rename, so an interruption never leaves a half-written folder, and the active slot is cleared while the official folder is in flux so an interrupted switch is backed up rather than saved over the wrong slot. importCurrentProfile copies the official folder into a new slot that becomes active, and import_current_sv2_profile maps to it. Switching and importing are refused while the existing process scan reports Synthesizer V Studio 2 running. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
electron-builder names the Windows executable after productName, so the rename would have replaced "Synthesizer V Toolbox.exe" with "Toneshuttle.exe" inside the unchanged install directory. The launch at login entry, the shortcuts the installer keeps and renames on upgrade, taskbar pins and the installer's running-app check all name the old path, so they would have pointed at a deleted file. win.executableName pins the old file name for Windows only; the macOS bundle stays Toneshuttle.app and Task Manager still shows the product name from the file description. The continuity tests now check the package name that decides the userData folder and install directory, and the pinned executable name, instead of repeating the appId check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t settings
- Read the product name, tagline and logo from brand.ts; i18n strings link to
brand.name so the next rename touches one file.
- Settings > Integrations offers Auto/On/Off for Synthesizer V. When off, the
Bridge and SV2 account pages, SynthV-only tools, home shortcuts and Copilot
chips disappear; deep links land on a page that can turn it back on.
- Tool tabs and home quick-start share one visibility rule, which also stops
quick-start from offering pending tools.
- Connections generates copy-ready MCP configs for Claude Code, Codex, Cursor and
VS Code with the bearer token (masked until revealed), lists exposed tools and
can rotate the token.
- About shows the license, project, issue and terms links and the Dreamtonics
non-affiliation notice.
- Fix preview mocks: test/save MCP server no longer fall into the generic
endsWith("server") branch, the agent endpoint is /agent, ports start at 1024.
- Replace stale Tauri, Rust-backend and ~/.SynthVcopilot copy.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With the SynthV integration off the agent previously had no domain tools at all, so even the 'analyze this audio' starter prompt could not work. Sessions now get toolbox_audio_probe/loudness/features, toolbox_lyrics_rhymes/check and toolbox_history, routed through the existing command registry with arguments validated before they reach the host. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The audio-to-MIDI tool kept offering 'import into the current SynthV project' and could still submit a remembered true after the integration was turned off. Its title and description no longer name SynthV either. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saving the official Synthesizer V Studio 2 folder back into the active slot made three paths unsafe. Overlapping switches (the agent can call activateProfile beside the UI) both read the same active slot and the slower one saved another slot's data over it, so every operation that rewrites the store, a slot or the official folder now runs on one per-service promise chain. An isolated (Sandboxie) instance writes straight into its slot folder, which the next switch overwrites when that slot is active, so preparing or launching the active slot in isolation is refused. Selective sync into the active slot now writes the official folder (refused while SV2 runs) instead of the slot copy that the next switch discards. Re-activating the active slot replaces nothing, so a failed process scan counts as running there instead of blocking a normal launch. When the rollback rename of a failed swap also fails, the staged copy is removed before reporting where the previous content was kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
toolbox_internal/advanced and plugin host requests could still scan for SynthV or activate account slots after the user turned the integration off. They now get a client-safe error naming the setting instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ients
The loopback MCP and agent endpoints now require a per-install bearer token
(generated on first load, stored owner-only in runtime-settings.json, compared
in constant time, rotatable through rotate_http_api_token). Settings saves no
longer restart a server whose config is unchanged; a new token does.
Protocol fixes for Claude Code, Codex, Cursor, VS Code and the official SDK:
version negotiation over 2025-11-25/06-18/03-26 with MCP-Protocol-Version
checks, serverInfo title and instructions, -32700 parse errors, 202 for
notifications and responses, batch support, byte-counted body limits,
object-only structuredContent, validated content blocks, and tool execution
failures returned as isError results instead of JSON-RPC errors.
Tool definitions move to mcp-tools.ts: toolbox_internal/advanced list their
capability operations with titles and annotations, and toolbox_agent uses a
flat input schema because the Anthropic API rejects top-level oneOf/anyOf.
Agent task list results become {tasks}, and task persistence retries the
brief rename locks Windows takes while the file is being read.
test_mcp_server now launches the saved stdio server and performs a real
initialize + tools/list handshake (cmd shims quoted on Windows, process tree
stopped afterwards). Plugin uninstall/enable/grant reject ids that are not an
installed plugin's own directory, closing a path traversal.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Wires the typed toolbox_internal/advanced definitions, structured tool results and the server identity (with the real app version) into main.ts, and keeps a locked or damaged runtime-settings.json from being overwritten with defaults when a fresh token is generated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When the abort lands while the provider call is in flight, Pi can record the
turn with stopReason "error" ("This operation was aborted") instead of
"aborted". The status ladder checked round errors before cancellation, so a
user's Stop showed up as a model failure. agent-e2e hit this intermittently on
Windows; it now passes repeatedly, and a whitebox test pins the ordering.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Connections page saved stdio MCP servers, but no session ever saw their tools. McpStdioClient runs one server per process over newline-delimited JSON-RPC (MCP 2025-06-18): initialize with timeout, paginated tools/list, cancellable tools/call, ping and -32601 answers for server requests, stderr tail in every error, and process-tree teardown on close. On Windows commands resolve through PATH/PATHEXT; npm-style .cmd shims run through cmd.exe with double caret escaping, since their %* re-parse would otherwise expose unbalanced-quote arguments to command injection. ExternalMcpPool shares one client per enabled server across sessions, reconciles on config fingerprint, connects servers in parallel, isolates failures and respawns a dead server once per call. The Pi extension registers mcp__<server>__<tool> tools with provider-safe names and object schemas, runs read-only tools in any mode, refuses other tools outside Solo mode because external tools have no approval flow yet, and tells the model which servers failed and that tool output is data. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Drives the built app over CDP: branding, the SynthV integration switch and its persistence, the Connections page token and client configs, the official MCP SDK client against the authenticated endpoint (401 without or with a stale token, 409 for /agent in toolbox mode), and agent sessions against a mock model that must receive the Toneshuttle identity and only the active integration's tools. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
electron-autostart-tray asserted the old hard-coded tray labels; autostart-behavior and bridge-preview-session evaluate main.ts or api.ts in a VM and lacked the new synthvOn/renderIntegrationSettings helpers and BRAND. i18n-runtime was already failing on base because it never loaded i18nAbout; it now also loads i18nIntegrations and passes, so every literal t() key in main.ts is checked in both locales again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A server left running behind a dead cmd.exe or npx launcher was never killed: close() returned early once the direct child had exited, and the pool replaced dead clients without closing them. close() now always ends stdin and cleans up after the leader. POSIX signals the process group. Windows looks the orphans up by parent pid, because taskkill /T cannot walk the tree from a dead parent. An unexpected exit triggers this cleanup right away, and the pool keeps track of the clients it replaces so dispose() can wait for them. Servers that share a slug now get a hash of their id in the server segment. A server that fails to connect therefore no longer hands its tool names to a namesake. Schema sanitizing now resolves a top-level $ref, hoists definitions out of variants, keeps the requirements every accepted shape has, and merges conflicting variant properties into anyOf. Properties that reach a dangling $ref become unconstrained hints, so Pi no longer rejects every call. Tests now cover fragmented, coalesced and batched framing, including a UTF-8 character split across chunks. They also check the cancelled request id, and on Windows they check that orphans are reaped behind a dead cmd.exe launcher. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Wires the shared ExternalMcpPool into agent sessions (AI mode, enabled servers only), reconciles it after every settings change so removed or disabled servers stop at once, and disposes it on quit. The end-to-end test now adds a stdio server through the Connections form, runs the real probe, and checks that an agent session gets its tools, runs the read-only one in Edit mode and refuses the one that may change data. test:contracts also runs external-mcp-tools, toneshuttle-integrations and i18n-runtime. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It probed /etc/hosts, which on Windows resolves to a missing F:\etc\hosts, so the call failed on lstat before the containment check ran. It now uses a real file outside the data root. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- MCP clients and plugins can no longer drive SynthV through creative operations (score import, lyric write-back, retake, audio-to-project import) while the integration is off, nor start Cover in toolbox mode. - The agent prompt lists the enabled external MCP servers with a configuration digest, so adding or changing one recreates the session with its tools; it no longer names tools that Cover repair and tuning sessions do not have. - Agent tools reject UNC and relative paths, so a prompt-injected model cannot make the host open a network share. - Settings no longer claims the bridge failed to load when SynthV starts off. - A remembered tool that became hidden no longer leaves its group empty, and Home shows external MCP servers instead of a Bridge card when SynthV is off. - Autostart migration ignores Run entries whose path did not decode. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…shuttle The exe becomes Toneshuttle.exe, and the per-user install folder and the data folder move from synthv-toolbox to Toneshuttle. Existing installs upgrade in place: - electron/assets/installer.nsh moves $INSTDIR in customInit, leaving the registry to the old uninstaller so it still removes the old folder, and asks before closing a running old app on manual upgrades. - The data folder is renamed as a whole before setPath and the single-instance lock (user-data-migration.ts). The move runs under a cross-process lock, defers while an older instance holds the old folder, and rewrites the absolute paths stored in job, history, checkpoint and settings records. Settings shows the folder and any deferral. - The launch-at-login entry moves to the new exe through Electron's login-item API. Lookup paths are quoted: unquoted, Electron cuts them at the first space and matched another app's entry in testing. Also fixes launch-at-login always reporting failure on Windows (it read the entry back without its arguments), Settings overflowing at narrow widths, and a rotated MCP token being shown before the server enforced it, which let the old token work for a moment. The package name, appId and NSIS GUID stay unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
CI stops at the first failing contract test, so these only surfaced once earlier failures were fixed on this branch: - electron-http-mcp-server: cut method bodies at "\n }\n", which a CRLF checkout on Windows never contains, so the scan ran to the end of host-capabilities.ts. Normalize line ends before scanning. - media-importer: required a developer's venv at /private/tmp. yt_dlp is faked through PYTHONPATH, so fall back to the system Python. - component-workflow-e2e: Windows has no python3.11 command; use python. - cvrs export-lrc wrote CRLF on Windows through text mode. Write "\n" so LRC exports are identical on every platform. Verified locally on a simulated CRLF checkout: all 57 contract files pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c08ef6b3e9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…start - The client bounded each tools/list response but not their sum, so up to 100 pages near the message limit could pile gigabytes of definitions into the main process. A server may now contribute at most 1,000 tools and 8 MiB of definitions; the probe applies the same bounds. - The Cover retry gate looked up only params.id, while the cover service also accepts taskId, so a retry by taskId slipped past the AI-mode check. The gate now resolves the same alias. - Removing or reconfiguring an external MCP server did not wait for its old process, so turning AI mode off and on again could run two copies of the server at once. A replacement now waits for the retired process of the same server id. - A start that found another start migrating gave up after five seconds and quit silently, so a hidden at-login first instance never showed its window. It now waits up to two minutes for the move, then reaches the single-instance lock and hands the window over as any second launch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 881e2e8542
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…t SynthV - When a server's process died, the pool started its replacement while the old client was still reaping a server its launcher had left behind, so two copies could briefly hold the same ports, locks or files. The replacement now waits for that shutdown. The wait is registered per server id, so an entry that replaces this one because the server was edited meanwhile waits as well, and a server removed or a pool disposed during the wait starts nothing afterwards. - The wait can take seconds on Windows, so a cancelled tool call now stops waiting at once, and a session built while its server was being removed bumps the tools revision, so turning AI mode back on rebuilds it instead of reusing a session that lists the server as unavailable. - Turning SynthV off hid the whole Batch tool and refused every batch over MCP, although its render review recipe reads audio only. Batch now stays available: without SynthV it offers only audio recipes, with a matching placeholder, and the host gate refuses only the .svp project recipes. Any creative call that carries a project path, directly or in batch options, is refused with SynthV off, because the creative service snapshots and keeps backing up every project path it sees. - The render review recipe had no label: the dictionaries and the preview used render-quality-check, the backend render-review. A test now checks every backend recipe has a title in both locales. The placeholder paths also keep their backslashes; the template literal used to swallow them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- "auto" always enabled the integration, so it behaved exactly like On although Settings says it follows detection. It now enables SynthV when an installation is found, the user keeps SV2 account slots, or a Bridge script has connected; explicit On and Off still win. Whether the app's own bundled bridge component loaded is not evidence, since it ships with every install. - Detection is no longer a one-off at bootstrap. The main process probes again when a window gains focus and, while auto resolves to off, every ten seconds, then tells the renderer to refresh, so installing SynthV or starting its Bridge needs no restart and no visit to Settings. - A Bridge seen connected stays evidence for the rest of the run, so a heartbeat missed while SynthV is busy, or stopping the Bridge, cannot hide the integration in the middle of a Cover or an approved write. - The scripts folder the user installed the Bridge into from the Bridge page counts as an installation. It covers editions and locations the scanner does not know, such as Flat, for upgraded users. - With auto and nothing detected, Settings says to choose On for SynthV installed elsewhere or another edition, and onboarding no longer promises Bridge and project tools unconditionally. - The gate's refusal is now the bridge's own failure envelope with code SYNTHV_INTEGRATION_OFF, and its message names both causes. The Cover host and the creative bridge read failures before parsing them, so a refusal or a host error no longer surfaces as a JSON SyntaxError. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dfbed816a3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
… rollback - The main process reported a SynthV refresh only when the resolved switch flipped, so a Bridge connecting while the integration was already on never reached the renderer. A refresh now reports any change to what the renderer shows (switch, installations, account slots, Bridge), and window focus probes with the preference On too; only Off never probes. - The renderer dropped a change that arrived during a task, and the main process reports it once. It is now replayed when the task ends. - A session initialized after AI mode was turned off still asked for the configured external MCP servers and could start them again behind the settings callback's shutdown. The server list now rechecks AI mode. - History still read project backups and offered checkpoint restore with SynthV off, through the command path the renderer and the agent's toolbox tools use, which skipped the HostCapabilities gate. History hides those sections with the integration, and the command registry refuses the same .svp operations as HostCapabilities. - A token rotation whose settings file could not be written left the listener on a token nobody was shown. It now goes back to the old token and reports the failure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 764801ac0a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- The MCP client and probe bounded each stdout line by its string length, which counts UTF-16 units, so a line of three-byte characters could carry three times the 64 MiB limit. Both now split stdout through one StdoutLines helper that counts UTF-8 bytes per segment and keeps the unfinished line as parts, so a long line is not joined again on every chunk either. - Selective sync accepted the same slot as source and target; with the active slot that copied its saved folder over the live official one. It now needs two different slots, and the preview token is bound to its source, so a preview cannot be executed for another source. - The active slot is now also read from the official folder when it is the source, since its slot folder is only the copy saved when it was switched in; like writing into it, that needs SV2 closed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 58608bb261
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- The renderer's pasted-lyrics pronunciation form sends projectPath: null, and the SynthV gate counted any defined value as a project, so the command path refused lyrics-only checks with SynthV off. Only a non-empty string counts now, the test creative-service applies before it snapshots a project. - With SynthV off, every renderer refresh still listed SynthV processes, read the shortcut profile and asked for the Bridge session; it skips them now. The Lyrics page keeps its editor but drops the Bridge panel. - A tools/list_changed that arrived while a tools/list was in flight was overwritten by the stale answer, which then stayed cached. The pool now counts notifications, lists again when one overtook the request (a few times for a server that keeps changing), and never trusts an overtaken list as the cache. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 824dbe4bc9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…der, pooled MCP test - The Accounts and Bridge pages kept polling SynthV processes, account state and the Bridge after Auto turned the integration off while one of them stayed open; the poll now stops with the integration. - The per-server cap on tool definitions counted UTF-16 units, so definitions in non-ASCII text could exceed 8 MiB several times over; the client and the probe count UTF-8 bytes now. - The Accounts page and Open data folder pointed the active slot at its slot folder, a copy saved at switch-in that the next switch overwrites; they now report and reveal the official folder SV2 actually uses. - Testing an enabled server from the Connections page started a second copy beside the one the agent runs, which fails for servers that bind a port or hold a lock. The pool now answers the test through its running process when it runs that exact configuration; anything else is probed as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3636eef5f0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…ma depth - A conversation keeps its agent session while the prompt is unchanged and never lists tools again, so a server whose first load failed stayed missing from it even after recovering. Once a failure's backoff has passed, the next read of the pool revision, which is the next turn's prompt, bumps it once: that turn rebuilds the session and retries the server. Retries follow the user's turns, so nothing restarts a broken server in the background. - Tool schemas are walked recursively by the normalizer, Pi's validator and the provider, so a hostile nesting depth exhausted the stack and took the whole agent session down. A schema nested deeper than 64 levels, measured with an explicit stack, now makes that tool accept any object; the server still validates it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 727bf3af3d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…efresh, lock release - A settings change took effect before it was saved, so a full disk or a locked settings file switched SynthV, the mode or MCP servers behind a renderer that still showed the old values, without the change callback. Settings are now saved first and applied only after, one save at a time so each starts from what the previous one stored. - With SynthV saved as Off the app still loaded the bridge component at startup, which watches SynthV's status files for the whole run. It now reads the saved preference first and starts with a placeholder; the bridge is a SwitchableBridge that loads the component when the integration is turned on and closes it when it is turned off. The gated bridge reads tools on every use so it follows the swap. - A Test that re-listed a server's tools updated the cache without invalidating sessions, so a server that changed its tools silently kept stale tools in existing conversations. A Test that finds a different list now bumps the revision. - Removing the data-folder migration lock could throw (antivirus, an indexer) from module initialization and stop startup after the move had succeeded. Removal retries briefly and otherwise leaves the lock for the next start to find stale. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 80794b02a5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…esh, stale lock - A session registers each external tool, its schema and its read-only mark from the server configuration it listed. When the user edited the server during a run, the next call reached the replacement process under the old classification. Listed servers now carry their configuration fingerprint, calls pass it back, and a server reconfigured since is not called; the next message gets its current tools. - With SynthV saved as Off, turning it on loads the bridge component after the settings reply has gone out, so a load failure never reached Settings. Finishing a load or close now tells the renderer to refresh. - A stale migration lock that antivirus or an indexer still held made its removal throw from module initialization and stopped startup. The start now opens the old folder and leaves the move for a later start, without quitting as a second instance. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 45928d66fa
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…SynthV off - When a server's process died, the next call respawned it and invoked the tool straight away, although the session had registered that tool's schema and read-only mark from the old process. A call now carries the tool as the session registered it; after a restart or announced change the pool lists again and calls only a tool whose schema and read-only mark are unchanged, so Edit mode never runs a tool the new process no longer marks read-only. - Turning SynthV off left the creative service's backup timer copying tracked .svp projects every minute. The timer now checks the integration and skips backups while it is off, resuming when it is on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 04acdadf1e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…ion without a lock - A server that kept announcing tools/list_changed through all of the pool's list attempts left its last, overtaken answer cached and marked stale, but a call only re-listed an empty cache. A call now lists again whenever the cached list is behind the notifications, then compares the tool as before, so Edit mode never trusts a stale read-only mark. - When the migration lock could not be created for a reason other than another start holding it, the folder was moved without the lock, so two such starts could race the rename. The start now keeps the old folder and leaves the move to a later start. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7515401ed8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
A server that keeps announcing tools/list_changed during every list the pool retries leaves only an overtaken list, which no longer vouches for the tool a session registered. A call now re-lists such a cache and, if it is still behind the notifications afterwards, is refused instead of running under a read-only mark nothing confirms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e64e534533
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…login items - A SynthV refresh compared only installation and slot counts, so one edition replaced by another left Settings showing the old path and Bridge targets. It now compares the whole probe the renderer shows, including profiles and errors. - Stopping an agent run left the FFmpeg or audio-analysis process its toolbox tool had started running, and the workflow could still be recorded. The run's signal now travels from the tool through the command registry, the creative service and the component executor to the child process, which spawn ends on abort; a result that arrives after the stop is not recorded as history. - A Windows login entry disabled in Task Manager stays registered, so it read as enabled though Windows would not launch it. Launch at login now also needs executableWillLaunchAtLogin, and turning it on passes enabled so the disabled mark is cleared. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e555454f05
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…k, count raw definitions - toolbox_audio_probe's FFprobe kept running after Stop; probe_media now passes the run's signal to it like the loudness measurement. - A folder set aside for the data-folder move stayed aside when setup failed after it (a marker that could not be written) and the result did not mention it, so its only notice could be lost. When the move does not happen the folder goes back under its own name; only if that fails too does the decision report where it is. - The client counted tool definitions toward its 1,000-tool and 8 MiB caps only after validation and de-duplication, so a server repeating one large definition on every page stayed under the caps while costing hundreds of MiB. Every definition received now counts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
English
Renames the app from Synthesizer V Toolbox to Toneshuttle (声梭) and repositions it as a general vocal and audio creation toolbox, with Synthesizer V as an optional integration. Along the way it secures the local MCP server and makes it work with current MCP clients, gives the built-in agent a product identity and tools that do not need SynthV, and fixes the bugs found during the work.
What changed
electron/brand.ts,src/brand.ts), window, tray, About, installer and update artifact names, README, CHANGELOG and TERMS. TERMS now has a separate Synthesizer V section with a non-affiliation notice.Toneshuttle.exe.synthv-toolboxtoToneshuttlethroughelectron/assets/installer.nsh. OnlycustomInitis used, so the old uninstaller still removes the old folder. Manual upgrades ask before closing a running old app.synthv-toolboxtoToneshuttleon first start, before anything reads userData (electron/services/user-data-migration.ts). The move runs under a cross-process lock and waits while an older instance still holds the old folder. Absolute paths stored in job, history, checkpoint and settings records are rewritten.synthv-toolbox. It fixesapp.name, which names the login item, the macOS keychain item that protects SV2 web sessions, and the updater cache folder.SYNTHV_TOOLBOX_*environment variables.sv_*tools and one-click Cover are hidden.structuredContentandisError.toolbox_agentschema has no top-leveloneOf, which the Anthropic API rejects.Validation
Per-file test sweep: 64/67 files pass. The baseline before this branch was 53/61.
python3.11, and a macOS path.cover-service.mjsthat passes on rerun.Real Electron e2e over CDP (
test/toneshuttle-app-e2e.mjs,npm run test:toneshuttle-app). It covers:test/electron-app.mjspasses 16/16.Claude Code CLI connected using the
claude mcp addcommand generated by the app. A wrong token got 401.Local
electron-builder --win --publish never.installer.nshcompiles undermakensis -WXin both the installer and the uninstaller pass. The app ships asToneshuttle.exe, and the update feed and updater cache name are unchanged.Adversarial multi-agent reviews, with every confirmed finding fixed. For example, a read-only probe showed that unquoted login-item lookups matched another app's Run entry.
For reviewers
/Sinstall without--force-runmoves launch-at-login only after the first manual start.test_enroll/test_quitprobing with an intercepted token;src/main.ts. It should rebase onto this branch.中文
把应用从 Synthesizer V Toolbox 更名为 声梭 Toneshuttle,定位为通用的人声与音频创作工具箱,Synthesizer V 改为可选集成。同时加固本地 MCP 服务器并兼容当前的 MCP 客户端,让内置 Agent 以声梭身份工作,并提供不依赖 SynthV 的工具,顺带修复了过程中发现的问题。
主要改动
Toneshuttle.exe。synthv-toolbox改为Toneshuttle,由installer.nsh处理。它只用customInit,旧版卸载器仍会删除旧目录;手动升级时,如果旧版正在运行,会先询问再关闭。synthv-toolbox整体迁移到Toneshuttle。迁移在跨进程锁内进行;旧实例仍占用旧目录时推迟迁移;任务、历史、检查点和设置记录中的绝对路径会同步改写。synthv-toolbox。它决定app.name,而开机自启动项名称、macOS 上保护 SV2 网页会话的钥匙串条目和更新缓存目录都取决于app.name。SYNTHV_TOOLBOX_*环境变量。sv_*工具和一键 Cover 都会隐藏。structuredContent和isError。toolbox_agent的 schema 去掉了顶层oneOf,否则 Anthropic API 会拒绝。验证
全量逐文件测试:67 个文件中 64 个通过(本分支之前为 61 个中 53 个)。
python3.11,以及写死了 macOS 路径。cover-service.mjs早就存在的偶发 EPERM,重跑即可通过。真实 Electron 端到端测试(通过 CDP)。覆盖:
electron-app.mjs16/16 通过。Claude Code CLI 用应用生成的
claude mcp add命令连接成功;使用错误令牌时返回 401。本机
electron-builder --win --publish never。installer.nsh在makensis -WX下,安装器和卸载器两遍编译都通过;应用以Toneshuttle.exe打包,更新源和更新缓存目录名不变。多代理对抗审查,确认的问题已全部修复。例如,一次只读实验证实:不加引号的登录项查询会匹配到其他程序的自启动项。
审阅须知
/S静默安装、且不带--force-run时,开机自启动项要等用户手动启动一次新版后才会迁移。test_enroll/test_quit做探测;src/main.ts,建议基于本分支 rebase。🤖 Generated with Claude Code