Claude Code, Skill
NPCTalk
Make any NPC in any game talk back with Fish Audio: skills, a self-hosted voice server and tools that let an AI agent wire up speech-to-text, an LLM in character, cloned Fish Audio voices (Drama 3, S2 Pro) and actions, with a full GTA V example.
Compatibility: Not stated.
Grade B
Minor issues only, no Medium or High. Worth a quick look at the findings below before installing.
Not a guarantee. A hygiene check of the source at the commit shown, not a security audit.
PERMISSION_DELETE_FILES NETWORK_NO_FIXED_HOST SECRETS_PATH_DOTENV SECRETS_ENV_READ
Why this grade
- PERMISSION_DELETE_FILES Low
Contains a call that can delete files.
examples/gta-v/tools/edit.ts, line 31
const r = await new Deno.Command(cmd, { args: a, stdout: "piped", stderr: "piped" }).output(); - NETWORK_NO_FIXED_HOST Low
Makes a network call whose host is not written as a fixed address.
npctalk/server.py, line 59
with urllib.request.urlopen(url, timeout=900) as r: # a cold start answers once the model is up - SECRETS_PATH_DOTENV Low
Mentions a .env file.
npctalk/check.py, line 13
written out, .env files - SECRETS_ENV_READ Note
Reads an environment variable whose name contains KEY, SECRET, TOKEN, PASSWORD or CREDENTIAL.
npctalk/server.py, line 97
token = os.environ.get("NPCVOICE_TOKEN", "")
Any High, or two or more Medium findings, give D. One Medium gives C. Low findings or a security Note give B. Each code names a finding behind the letter.
Grades are a hygiene check of the source at the commit shown, on the date checked, not a security audit or a guarantee. The free directory grades are automated. Before release, a PlugVet engineer reviews every paid report and any grade we hold back, including all F grades, against the source code and the evidence we quote.
What was checked
Plain notes from the hygiene checks.
Permissions
Concern
can delete files.
PERMISSION_DELETE_FILES
examples/gta-v/tools/edit.ts, line 31
const r = await new Deno.Command(cmd, { args: a, stdout: "piped", stderr: "piped" }).output();
npctalk/check.py, line 54
out = subprocess.run(["git", "-C", str(root), "ls-files", "-co", "--exclude-standard", "-z"],
npctalk/voice.py, line 97
out = subprocess.run(["ffmpeg", "-v", "error", "-i", str(path), "-ac", "1", "-ar", str(rate), "-f", "s16le", "-"],
Show more
npctalk/voice.py, line 182
subprocess.run(["ffmpeg", "-v", "error", "-y", *inputs, "-filter_complex", graph, "-map", "[out]",
npctalk/voice.py, line 190
subprocess.run(["ffmpeg", "-v", "error", "-y", *inputs, "-filter_complex", graph, "-map", "[out]",
npctalk/voice.py, line 278
subprocess.run(cmd, check=True)
server/drama3.py, line 128
self.server = subprocess.Popen(
server/s2pro.py, line 115
self.servers.append(subprocess.Popen(
server/finetune/prepare_dataset.py, line 123
shutil.rmtree(d, ignore_errors=True)
server/finetune/train.py, line 281
shutil.rmtree(out, ignore_errors=True)
Install and update
Pass
No install-time script found, and dependencies are pinned or absent.
Network
Concern
can reach a host that is not written as a fixed address.
NETWORK_NO_FIXED_HOST
npctalk/server.py, line 59
with urllib.request.urlopen(url, timeout=900) as r: # a cold start answers once the model is up
npctalk/server.py, line 75
with urllib.request.urlopen(req, timeout=timeout) as r:
npctalk/voice.py, line 202
with urllib.request.urlopen(req, timeout=120) as r:
Show more
server/drama3.py, line 178
httpx.post(f"http://127.0.0.1:{PORT}/v1/audio/speech", timeout=600,
server/drama3.py, line 323
if httpx.get(f"http://127.0.0.1:{PORT}{path}", timeout=2).status_code == 200:
server/drama3.py, line 336
httpx.post(f"http://127.0.0.1:{PORT}/v1/audio/speech", timeout=600,
server/keepwarm.py, line 30
r = httpx.get(health, timeout=900, follow_redirects=True)
server/s2pro.py, line 158
httpx.post(f"http://127.0.0.1:{self.port_for(name)}/v1/audio/speech", timeout=600, json={
server/s2pro.py, line 182
if httpx.get(f"http://127.0.0.1:{port}{path}", timeout=2).status_code == 200:
server/s2pro.py, line 194
httpx.post(f"http://127.0.0.1:{port}/v1/audio/speech", timeout=300, json={
server/fal/fal_app.py, line 42
curl git ffmpeg libsndfile1 build-essential \\
server/fal/fal_app.py, line 109
httpx.post(f"http://127.0.0.1:{PORT}/v1/audio/speech", timeout=300, json={
server/fal/fal_app.py, line 125
if httpx.get(f"http://127.0.0.1:{PORT}{path}", timeout=2).status_code == 200:
.agents/skills/make-npcs-talk/references/architecture.md, line 37
| `fal/fal_app.py` | S2 Pro on fal with a realtime WebSocket (alternative host) |
.claude/skills/make-npcs-talk/references/architecture.md, line 37
| `fal/fal_app.py` | S2 Pro on fal with a realtime WebSocket (alternative host) |
docs/how-it-was-made.md, line 44
with a realtime WebSocket (`server/fal/fal_app.py`), and on Modal through SGLang-Omni with a plain streaming HTTP
Secrets
Concern
reads a credential or environment file.
SECRETS_ENV_READ SECRETS_PATH_DOTENV
npctalk/check.py, line 13
written out, .env files
npctalk/check.py, line 27
".cmd", ".bat", ".cfg", ".csproj", ".xml", ".env", ""}
npctalk/server.py, line 97
token = os.environ.get("NPCVOICE_TOKEN", "")
Show more
npctalk/check.py, line 76
if path.name == ".env" or path.name.startswith(".env."):
npctalk/check.py, line 77
found.append((rel, ".env file"))
npctalk/voice.py, line 213
key = os.environ.get("FAL_KEY", "")
server/drama3.py, line 71
.env({"DEBIAN_FRONTEND": "noninteractive", "CUDA_HOME": "/usr/local/cuda", "HF_HUB_ENABLE_HF_TRANSFER": "1"})
server/s2pro.py, line 56
.env({"DEBIAN_FRONTEND": "noninteractive", "CUDA_HOME": "/usr/local/cuda"})
server/fal/fal_app.py, line 88
snapshot_download("fishaudio/s2-pro", local_dir=CKPT, token=os.environ.get("HF_TOKEN"))
.gitignore, line 5
.pytest_cache/
.gitignore, line 6
.env
Agent instructions
Pass
No instruction to ignore earlier instructions or to hide a step.
Obfuscation
Pass
No encoded or minified payload found.
Licence
Pass
A licence file is present (LICENSE).
Maintainer activity
Pass
The latest commit is within the last 365 days.
Note
Hygiene check of commit 59635ceb8ee0. can delete files. can reach a host that is not written as a fixed address. reads a credential or environment file.
Date and source
Date checked:
github.com
Commit graded: 59635ceb8ee010599c3caf9d9d1ee1aa114af91d
This link goes to the original host. PlugVet does not host or check what you download from there, and installing it is your own decision and risk.