Refresh and brand VoiceStudio installable agent skills

This commit is contained in:
Palash Debnath
2026-09-17 01:10:37 +05:30
parent fd9a9aa3df
commit 2b0e43da05
7 changed files with 88 additions and 14 deletions
@@ -1,11 +1,6 @@
---
name: omnivoice
description: Legacy VoiceStudio skill alias for existing Claude installations. Generate local speech, discover saved voices, and transcribe audio through the running VoiceStudio backend.
---
# VoiceStudio compatibility entry
The current cross-agent package is [voicestudio](../../../skills/voicestudio/SKILL.md).
The current cross-agent package is [voicestudio](../../../../skills/voicestudio/SKILL.md).
For new installations use `npx skills add debpalash/VoiceStudio --skill voicestudio`.
Use the running backend at the user's configured address (default
@@ -27,3 +22,8 @@ never disable authentication to make an example work.
Source and current setup documentation:
https://github.com/debpalash/VoiceStudio
This archived entry is not an installable skill. Existing installations should
remove the old `omnivoice` / `oss-maintainer` entries and install `voicestudio` /
`voicestudio-maintainer` from the canonical repository. Legacy helpers remain
for existing users; the Electron supervisor is the preferred launcher.
+1 -1
View File
@@ -320,7 +320,7 @@ that — the agent recalls the architecture, conventions, and your past findings
instead of re-reading the tree each time. [**memxt**](https://github.com/debpalash/memxt)
(100% local, MCP-based, built by this project's maintainer) exists for exactly
this; any MCP memory server works. Pair it with the repo's agent skill —
`npx skills add debpalash/omnivoice-studio` — so your agent knows the project's
`npx skills add debpalash/VoiceStudio` — so your agent knows the project's
hard rules from the first prompt.
## Quality gates your PR must pass
+1 -1
View File
@@ -84,7 +84,7 @@ See [Electron setup](electron/README.md) for prerequisites and backend configura
| Integrations | [Local API](docs/speech-platform.md) · [MCP](docs/mcp.md) · [Examples](examples/README.md) |
| Development | [Contributing](.github/CONTRIBUTING.md) · [Electron](electron/README.md) · [Changelog](CHANGELOG.md) |
Agent skills: `npx skills add debpalash/VoiceStudio` — choose **voicestudio** for audio workflows or **oss-maintainer** for repository maintenance.
Agent skills: `npx skills add debpalash/VoiceStudio` — choose **voicestudio** for audio workflows or **voicestudio-maintainer** for repository maintenance.
## Sponsors
+1 -1
View File
@@ -103,7 +103,7 @@ VoiceStudio/
├── .agents/skills/ ⟵ canonical skill copies (vite, fastapi-python), pinned by
│ skills-lock.json — followed by path, never symlinked
├── skills/ ⟵ skills this repo publishes (omnivoice, oss-maintainer)
├── skills/ ⟵ skills this repo publishes (voicestudio, voicestudio-maintainer)
├── infra/ ⟵ edge/deploy workers (not the Docker deploy path)
│ └── install-redirect/ voicestudio.sh/install — UA-sniffing installer worker
@@ -1,9 +1,9 @@
---
name: oss-maintainer
description: Triage GitHub issues, review contributor pull requests, diagnose CI, and prepare explicitly requested releases using the target repository's rules. Use for repository maintenance work, not ordinary VoiceStudio audio generation.
name: voicestudio-maintainer
description: Triage GitHub issues, review contributor pull requests, diagnose CI, and prepare explicitly requested releases for VoiceStudio's Electron desktop app and Python backend. Use for repository maintenance work, not ordinary VoiceStudio audio generation.
---
# OSS maintenance
# VoiceStudio maintenance
Read the target repository's AGENTS.md, CLAUDE.md, contribution guide, and release documentation first. Their policies override this general workflow. Installing this skill does not authorize merges, releases, issue closures, or messages to contributors.
@@ -40,3 +40,37 @@ When maintaining debpalash/VoiceStudio, consult its current rules rather than ol
- Release channels and version ownership: `docs/RELEASING.md` and CLAUDE.md. Never infer a version bump from a fix request.
- Read CodeRabbit/Greptile findings and required CI before merging. Follow main's post-merge CI.
- Preserve local-first behavior, cross-platform behavior, model-install consent, synthetic-audio marking, and localization requirements.
## Current development commands
Run from the repository root:
```sh
bun install
bun run dev # Electron + supervised backend
bun run typecheck # Electron main, preload, and renderer
bun run test # Electron tests
bun run check:electron # types, tests, build, packaging contract
bun run dist # local installers; publishing disabled
```
`electron/src/main/` owns lifecycle, IPC, native helpers, and backend supervision;
`electron/src/preload/` exposes the renderer bridge; `electron/src/renderer/src/`
contains the React app. Keep privileged filesystem/process work out of the renderer.
`backend/` supplies the shared Python API; `native/desktop-bridge/` supplies native
capabilities. `frontend/` still serves the browser UI and legacy Tauri shell: do not
remove it or rename internal `omnivoice` packages, environment keys, or data paths
as a branding cleanup.
Electron is the default desktop. Tauri is retained for its final sunset update.
Use `electron-build.yml` for artifact-only four-platform packaging rehearsals;
inspect its results for Windows, Linux, macOS Intel, and macOS Apple Silicon.
Do not dispatch release/publishing workflows to test packaging. Signing, updater
migration, and successful installation are separate checks from a green build.
The app version still comes from `frontend/package.json`; do not move or bump it
without an explicit versioning task.
For backend tests, use the repo's CI dependencies and an empty temporary
`HF_HUB_CACHE` with `HF_HUB_OFFLINE=1`; installed developer models must not hide
missing fixtures. Run targeted tests while editing and the required full checks
before landing. Existing CI failures remain blockers, not implied waivers.
+26 -1
View File
@@ -13,7 +13,7 @@ The default backend is `http://localhost:3900`; honor the user's configured addr
1. Check `GET /health`.
2. Discover the running version's contracts with `GET /openapi.json`, and voices/engines with `GET /v1/audio/voices`. Do not invent profile IDs or infer installed models from a catalog listing.
3. If unavailable, launch the installed app. For an existing source checkout, follow its Electron README (`bun install`, then `cd electron && bun run dev`). Do not install a second backend or overwrite an existing checkout.
3. If unavailable, launch the installed app. For an existing source checkout, follow its Electron README (`bun install`, then `bun run dev` from the repository root). Do not install a second backend or overwrite an existing checkout.
4. Local configurations may permit unauthenticated calls; protected deployments require the configured credentials. Treat 401/403 as authentication failures, not permission to disable auth. Never print tokens or use a placeholder key as if it were a real credential.
## Generate speech
@@ -60,3 +60,28 @@ The running backend mounts an MCP endpoint at `http://localhost:3900/mcp`. Use t
For n8n, calling agents, containers, or other hosts, make the backend address reachable from that environment: container `localhost` refers to the container. Keep authentication and explicit remote-routing choices intact. An integration-directory listing does not mean the integration is connected.
On errors, read the response body, distinguish unavailable backend, missing model, unsupported capability, authentication, and busy hardware. Fix the reported condition; do not switch to a hosted provider or download a model without authorization.
## Desktop workflows and readiness
The Electron app includes voice cloning and design, saved profiles and gallery,
stories/audiobooks, dubbing projects, transcription, tools, and integrations.
Prefer its existing project and voice identifiers over creating duplicates.
For desktop automation, inspect the actual UI and current Settings shortcuts;
do not assume shortcut bindings or microphone permissions are the same on every host.
Before dictation, verify an installed speech-to-text model and a working input
device. Distinguish recording, paused recording, transcription processing, and
completed text. Copying a transcript and inserting it into another app are different
operations; confirm the intended target before typing and preserve clipboard content
where supported. Never report text delivered just because transcription completed.
For dubbing, inspect missing/failed segments and timing overflow before export.
Preserve music and non-speech audio when requested; do not silently replace the
whole soundtrack. Preserve the source and make the output a separate artifact.
Translation style prompts belong to the selected translation operation, and remote
agent translation requires the user's configured provider choice.
Use the integrations directory as discovery and setup guidance, not proof of a
working connector. Verify actual credentials, endpoint reachability, and supported
operations before describing a connection as ready. Container deployments need
persistent data volumes and a backend URL reachable by the calling client.
+16 -1
View File
@@ -13,7 +13,7 @@ def test_readme_installs_skills_from_the_canonical_repository() -> None:
def test_public_skill_surfaces_use_current_identity_and_license() -> None:
canonical = (ROOT / "skills/voicestudio/SKILL.md").read_text(encoding="utf-8")
claude = (ROOT / ".claude/skills/omnivoice/SKILL.md").read_text(encoding="utf-8")
claude = (ROOT / ".claude/skills/omnivoice/LEGACY.md").read_text(encoding="utf-8")
launcher = (
ROOT / ".claude/skills/omnivoice/scripts/start-backend.sh"
).read_text(encoding="utf-8")
@@ -24,3 +24,18 @@ def test_public_skill_surfaces_use_current_identity_and_license() -> None:
assert "${OMNIVOICE_HOME:-$HOME/VoiceStudio}" in launcher
assert "${OMNIVOICE_HOME:-$HOME/OmniVoice-Studio}" not in launcher
def test_published_skills_have_unique_branded_names() -> None:
import yaml
paths = list((ROOT / "skills").glob("*/SKILL.md"))
names = []
for path in paths:
metadata = yaml.safe_load(path.read_text(encoding="utf-8").split("---", 2)[1])
assert metadata["name"] == path.parent.name
assert metadata["description"]
names.append(metadata["name"])
assert set(names) == {"voicestudio", "voicestudio-maintainer"}
assert len(names) == len(set(names))
assert not (ROOT / ".claude/skills/omnivoice/SKILL.md").exists()