agentvibes 5.1.2 → 5.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,6 +16,17 @@ param(
16
16
  [string]$llm = ""
17
17
  )
18
18
 
19
+ # Security: Validate LLM provider name (alphanumeric, hyphens, underscores
20
+ # only) — mirrors play-tts.sh line 92. This prevents weird values from
21
+ # poisoning the audio-effects.cfg lookup or the AGENTVIBES_LLM_KEY env var
22
+ # we export to child scripts. An invalid value is treated as unset rather
23
+ # than aborting, so the script falls back to the default config and the
24
+ # rest of TTS still works.
25
+ if ($llm -and $llm -notmatch '^[a-zA-Z0-9_-]+$') {
26
+ Write-Error "Invalid LLM provider name: '$llm' — must match ^[a-zA-Z0-9_-]+$. Falling back to default config."
27
+ $llm = ""
28
+ }
29
+
19
30
  # Configuration paths
20
31
  # Priority: CLAUDE_PROJECT_DIR env var → script's parent project → user profile
21
32
  # Local project settings ALWAYS override global (~/.claude)
package/README.md CHANGED
@@ -11,7 +11,7 @@
11
11
  [![Publish](https://github.com/paulpreibisch/AgentVibes/actions/workflows/publish.yml/badge.svg)](https://github.com/paulpreibisch/AgentVibes/actions/workflows/publish.yml)
12
12
  [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
13
13
 
14
- **Author**: Paul Preibisch ([@997Fire](https://x.com/997Fire)) | **Version**: v5.1.2
14
+ **Author**: Paul Preibisch ([@997Fire](https://x.com/997Fire)) | **Version**: v5.1.3
15
15
 
16
16
  ---
17
17
 
@@ -43,6 +43,14 @@ Whether you're using Claude Code, GitHub Copilot, OpenAI Codex, Claude Desktop,
43
43
 
44
44
  ---
45
45
 
46
+ ## 🛡️ v5.1.3 — Hardening Pass (Adversarial Review Followup)
47
+
48
+ - **Existing `.mcp.json` is now auto-migrated** — v5.1.2's installer detected an existing `.mcp.json` and printed instructions instead of fixing it, leaving v5.1.0/v5.1.1 users still broken after upgrade. v5.1.3 merges the `AGENTVIBES_LLM` env var into existing configs in-place.
49
+ - **`AGENTVIBES_LLM` is now validated** in both `mcp-server/server.py` (Python regex) and `play-tts.ps1` (PowerShell regex), matching `play-tts.sh`'s `^[a-zA-Z0-9_-]+$` check. Cross-platform contract is now symmetric.
50
+ - **`npm pack` content guard hardened**: hard-fails (not silent-passes) when `npm pack` errors; uses `git status --porcelain` to catch UNTRACKED publishable files (the v5.1.0 disaster also could've happened with a stray new file); has explicit 60s timeout to prevent CI hangs.
51
+
52
+ ---
53
+
46
54
  ## 🔀 v5.1.2 — MCP Per-LLM Routing Hotfix
47
55
 
48
56
  - **MCP server now reads `AGENTVIBES_LLM` env var** instead of hardcoding `copilot` — Codex / Copilot / Claude Code each get routed to their own per-LLM voice / pretext / music / effects config from `audio-effects.cfg`.
package/RELEASE_NOTES.md CHANGED
@@ -1,5 +1,40 @@
1
1
  # AgentVibes Release Notes
2
2
 
3
+ ## 🛡️ v5.1.3 — Hardening Pass (Adversarial Review Followup)
4
+
5
+ **Release Date:** April 2026
6
+
7
+ This release addresses HIGH/MEDIUM findings from a parallel adversarial review (Blind Hunter + Edge Case Hunter) of the v5.1.2 hotfix.
8
+
9
+ ### Bug Fixes
10
+
11
+ - **Existing `.mcp.json` is now auto-migrated** — v5.1.2's installer detected an existing `.mcp.json` and printed instructions to fix it manually. Result: anyone upgrading from v5.1.0/v5.1.1 was still broken after `npm i -g agentvibes@5.1.2`. v5.1.3 detects an existing config, merges the `AGENTVIBES_LLM` env var (and the rest of the agentvibes server entry) in-place, and shows a green "✅ MCP Configuration Updated" message. Existing user `env` keys are preserved.
12
+
13
+ - **`AGENTVIBES_LLM` is now validated** before being forwarded to the child shell. The bash version of `play-tts.sh` already validated `^[a-zA-Z0-9_-]+$` and rejected weird values; the Python `mcp-server/server.py` and the Windows `play-tts.ps1` did not. Now all three do, with the same regex. Invalid values are logged to stderr and treated as "unset" so TTS still works (falls back to default config).
14
+
15
+ ### Testing & Hardening
16
+
17
+ - **`npm pack` content guard now hard-fails on `packError`** instead of silently returning early. The previous v5.1.2 implementation had `if (packError) return;` in 6 of 8 tests, which meant a real `npm pack` failure surfaced as one failed test and SIX false-greens — defeating the entire purpose of the publish guard.
18
+
19
+ - **Dirty-tree check now uses `git status --porcelain`** instead of `git diff HEAD`. The previous implementation only caught modified-but-uncommitted tracked files; it missed brand-new untracked files in publishable directories (e.g. a `play-tts.ps1.new` someone forgot to delete). The v5.1.0 disaster could just as easily have shipped via an untracked stray file.
20
+
21
+ - **`npm pack` exec timeout** — added explicit 60-second timeout with `SIGKILL` so the publish guard can't hang CI on a stuck registry call.
22
+
23
+ - **`git status` failures hard-fail** instead of silently skipping. A missing git binary in CI was previously treated as "no findings" — that's exactly the opposite of what a security guard should do. Now it fails loudly with a message explaining the guard requires git.
24
+
25
+ - **3 new regression tests** for the new validations and migration logic.
26
+
27
+ ### How to Update
28
+
29
+ ```
30
+ npm cache clean --force
31
+ npx --yes agentvibes@5.1.3
32
+ ```
33
+
34
+ If you upgraded from v5.1.0 or v5.1.1, **re-run the AgentVibes installer once** so the new in-place migration touches your existing `.mcp.json` / `.codex/config.toml` / `.vscode/mcp.json`.
35
+
36
+ ---
37
+
3
38
  ## 🔀 v5.1.2 — MCP Per-LLM Routing Hotfix
4
39
 
5
40
  **Release Date:** April 2026
@@ -203,10 +203,22 @@ class AgentVibesServer:
203
203
  # this env var (e.g. .codex/config.toml [mcp_servers.agentvibes]
204
204
  # env = { AGENTVIBES_LLM = "codex" }).
205
205
  #
206
- # If unset, no -llm flag is passed and play-tts falls back to
207
- # the project / global default config — which is the correct
208
- # behavior for ad-hoc / unconfigured callers.
206
+ # If unset OR invalid, no -llm flag is passed and play-tts falls
207
+ # back to the project / global default config. Validation
208
+ # mirrors play-tts.sh line 92 — alphanumeric / hyphen /
209
+ # underscore only. This prevents weird values from poisoning
210
+ # the audio-effects.cfg lookup or being forwarded as ambiguous
211
+ # arguments to the child shell.
212
+ import re as _re
209
213
  llm_key = os.environ.get("AGENTVIBES_LLM", "").strip()
214
+ if llm_key and not _re.match(r"^[a-zA-Z0-9_-]+$", llm_key):
215
+ # Invalid value — log to stderr and treat as unset
216
+ print(
217
+ f"[AgentVibes] WARN: Ignoring invalid AGENTVIBES_LLM='{llm_key}' "
218
+ "(must match ^[a-zA-Z0-9_-]+$); falling back to default config",
219
+ file=__import__('sys').stderr,
220
+ )
221
+ llm_key = ""
210
222
  tts_script = "play-tts.ps1" if self.is_windows else "play-tts.sh"
211
223
  play_tts = self.hooks_dir / tts_script
212
224
  if self.is_windows:
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "agentvibes",
4
- "version": "5.1.2",
4
+ "version": "5.1.3",
5
5
  "description": "Now your AI Agents can finally talk back! Professional TTS voice for Claude Code, Claude Desktop (via MCP), and Clawdbot with multi-provider support.",
6
6
  "homepage": "https://agentvibes.org",
7
7
  "keywords": [
package/src/installer.js CHANGED
@@ -4320,18 +4320,75 @@ async function handleMcpConfiguration(targetDir, options) {
4320
4320
  }
4321
4321
 
4322
4322
  if (mcpExists) {
4323
- // Scenario 3: Config already exists - show manual instructions
4323
+ // Existing config: try to migrate it in-place so users upgrading from
4324
+ // v5.1.x get the AGENTVIBES_LLM env var added without manual editing.
4325
+ // This is the v5.1.2 follow-up fix — the prior version returned here
4326
+ // and only printed instructions, leaving existing users broken.
4327
+ let migrated = false;
4328
+ let migrationError = null;
4329
+ try {
4330
+ const existingRaw = await fs.readFile(mcpConfigPath, 'utf8');
4331
+ const existingCfg = JSON.parse(existingRaw);
4332
+ if (existingCfg && typeof existingCfg === 'object') {
4333
+ if (!existingCfg.mcpServers || typeof existingCfg.mcpServers !== 'object') {
4334
+ existingCfg.mcpServers = {};
4335
+ }
4336
+ const current = existingCfg.mcpServers.agentvibes;
4337
+ const wantEnv = { AGENTVIBES_LLM: 'claude-code' };
4338
+ // Decide whether we need to write — only if the agentvibes entry
4339
+ // is missing OR its env doesn't include the AGENTVIBES_LLM key.
4340
+ const needsWrite =
4341
+ !current ||
4342
+ !current.env ||
4343
+ current.env.AGENTVIBES_LLM !== 'claude-code';
4344
+ if (needsWrite) {
4345
+ existingCfg.mcpServers.agentvibes = {
4346
+ command: 'npx',
4347
+ args: ['-y', '--package=agentvibes', 'agentvibes-mcp-server'],
4348
+ // Preserve any other env keys the user added manually.
4349
+ env: { ...(current?.env ?? {}), ...wantEnv },
4350
+ };
4351
+ await fs.writeFile(mcpConfigPath, JSON.stringify(existingCfg, null, 2) + '\n');
4352
+ migrated = true;
4353
+ }
4354
+ }
4355
+ } catch (err) {
4356
+ migrationError = err;
4357
+ }
4358
+
4359
+ if (migrated) {
4360
+ console.log(
4361
+ boxen(
4362
+ chalk.green.bold('✅ MCP Configuration Updated\n\n') +
4363
+ chalk.white('Your existing ') + chalk.cyan('.mcp.json') + chalk.white(' has been updated\n') +
4364
+ chalk.white('with the AgentVibes MCP server entry, including the\n') +
4365
+ chalk.cyan('AGENTVIBES_LLM=claude-code') + chalk.white(' env var for per-LLM routing.'),
4366
+ {
4367
+ padding: 1,
4368
+ margin: { top: 1, bottom: 1, left: 0, right: 0 },
4369
+ borderStyle: 'double',
4370
+ borderColor: 'green',
4371
+ }
4372
+ )
4373
+ );
4374
+ return;
4375
+ }
4376
+
4377
+ // Migration was not needed (already correct) or failed — fall through
4378
+ // to the manual-instructions box.
4324
4379
  console.log(
4325
4380
  boxen(
4326
4381
  chalk.yellow.bold('ℹ️ MCP Configuration Already Exists\n\n') +
4327
4382
  chalk.white('An ') + chalk.cyan('.mcp.json') + chalk.white(' file already exists in this project.\n\n') +
4328
- chalk.white('To add AgentVibes MCP server manually, add this\n') +
4329
- chalk.white('to your ') + chalk.cyan('mcpServers') + chalk.white(' section:'),
4383
+ (migrationError
4384
+ ? chalk.red('Could not auto-update it: ' + migrationError.message + '\n\n')
4385
+ : chalk.gray('It already has the correct AgentVibes entry.\n\n')) +
4386
+ chalk.white('To add or fix the AgentVibes MCP server manually, use:'),
4330
4387
  {
4331
4388
  padding: 1,
4332
4389
  margin: { top: 1, bottom: 1, left: 0, right: 0 },
4333
4390
  borderStyle: 'round',
4334
- borderColor: 'yellow',
4391
+ borderColor: migrationError ? 'red' : 'yellow',
4335
4392
  }
4336
4393
  )
4337
4394
  );