agentvibes 2.14.16 → 2.14.17
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.
- package/README.md +7 -6
- package/RELEASE_NOTES.md +98 -0
- package/bin/agent-vibes +4 -2
- package/package.json +1 -1
- package/src/commands/install-mcp.js +11 -2
- package/src/installer.js +37 -13
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
[](https://github.com/paulpreibisch/AgentVibes/actions/workflows/publish.yml)
|
|
12
12
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
13
13
|
|
|
14
|
-
**Author**: Paul Preibisch ([@997Fire](https://x.com/997Fire)) | **Version**: v2.14.
|
|
14
|
+
**Author**: Paul Preibisch ([@997Fire](https://x.com/997Fire)) | **Version**: v2.14.17
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
@@ -94,14 +94,15 @@ Whether you're coding in Claude Code, chatting in Claude Desktop, or using Warp
|
|
|
94
94
|
|
|
95
95
|
## 📰 Latest Release
|
|
96
96
|
|
|
97
|
-
**[v2.14.
|
|
97
|
+
**[v2.14.17 - CodeQL Code Quality Improvements](https://github.com/paulpreibisch/AgentVibes/releases/tag/v2.14.17)** 🎉
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
Hi everyone! I enabled CodeQL on this repository to ensure the highest quality code for AgentVibes. It found 5 issues which we fixed in this release! All Node.js improvements, macOS safe.
|
|
100
100
|
|
|
101
101
|
**Key Highlights:**
|
|
102
|
-
-
|
|
103
|
-
-
|
|
104
|
-
-
|
|
102
|
+
- ✨ **Atomic File Writes** - Config files now use temp+rename pattern for reliability
|
|
103
|
+
- ✨ **Array-Based Commands** - Switched to `execFileSync` with array args (cleaner code)
|
|
104
|
+
- ✨ **Input Validation** - Added validation for shell paths and config locations
|
|
105
|
+
- ✅ **macOS Safe** - All changes are Node.js only, no bash modifications
|
|
105
106
|
|
|
106
107
|
💡 **Tip:** If `npx agentvibes` shows an older version or missing commands, clear your npm cache: `npm cache clean --force && npx agentvibes@latest --help`
|
|
107
108
|
|
package/RELEASE_NOTES.md
CHANGED
|
@@ -1,3 +1,101 @@
|
|
|
1
|
+
# Release v2.14.17 - CodeQL Code Quality Improvements
|
|
2
|
+
|
|
3
|
+
**Release Date:** 2025-12-02
|
|
4
|
+
**Type:** Patch Release (Code Quality)
|
|
5
|
+
|
|
6
|
+
## AI Summary
|
|
7
|
+
|
|
8
|
+
Hi everyone! I enabled CodeQL on this repository to ensure the highest quality code for AgentVibes. It found 5 issues which we fixed in this release!
|
|
9
|
+
|
|
10
|
+
AgentVibes v2.14.17 addresses all 5 CodeQL suggestions by upgrading to more robust Node.js APIs. These are proactive improvements to follow best practices - using atomic file writes and array-based command execution. No bash code was touched, so macOS Bash 3.2 compatibility is fully preserved.
|
|
11
|
+
|
|
12
|
+
**Key Highlights:**
|
|
13
|
+
- ✨ **Atomic File Writes** - Config files now use temp+rename pattern for reliability
|
|
14
|
+
- ✨ **Array-Based Commands** - Switched to `execFileSync` with array args (cleaner code)
|
|
15
|
+
- ✨ **Input Validation** - Added validation for shell paths and config locations
|
|
16
|
+
- ✅ **macOS Safe** - All changes are Node.js only, no bash modifications
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Code Quality Improvements
|
|
21
|
+
|
|
22
|
+
### Atomic File Writes (CodeQL #5)
|
|
23
|
+
**File:** `src/commands/install-mcp.js:151`
|
|
24
|
+
|
|
25
|
+
Upgraded config file writing to use the atomic temp+rename pattern for better reliability.
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
// Before: Direct write
|
|
29
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
30
|
+
|
|
31
|
+
// After: Atomic write pattern
|
|
32
|
+
const tempPath = `${configPath}.tmp.${process.pid}`;
|
|
33
|
+
fs.writeFileSync(tempPath, JSON.stringify(config, null, 2), { mode: 0o600 });
|
|
34
|
+
fs.renameSync(tempPath, configPath);
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Array-Based Command Execution (CodeQL #2, #4)
|
|
38
|
+
**Files:** `bin/agent-vibes:33`, `src/installer.js:1305`
|
|
39
|
+
|
|
40
|
+
Switched from string-based to array-based command execution for cleaner, more robust code.
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
// Before: String concatenation
|
|
44
|
+
execSync(`node "${installerPath}" ${arguments_.join(' ')}`);
|
|
45
|
+
|
|
46
|
+
// After: Array arguments (cleaner!)
|
|
47
|
+
execFileSync('node', [installerPath, ...arguments_]);
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Input Validation (CodeQL #1, #3)
|
|
51
|
+
**File:** `src/installer.js:215-217`
|
|
52
|
+
|
|
53
|
+
Added validation for shell paths and config file locations.
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
// Validate shell is a known shell binary
|
|
57
|
+
const validShells = ['/bin/bash', '/bin/zsh', '/bin/sh', ...];
|
|
58
|
+
if (!validShells.includes(shell)) {
|
|
59
|
+
throw new Error('Shell path not recognized');
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## macOS Compatibility Note
|
|
66
|
+
|
|
67
|
+
These improvements only modify JavaScript/Node.js code. No bash scripts were changed. The "array-based arguments" are **JavaScript arrays** (Node.js API), not bash arrays. Full macOS Bash 3.2 compatibility is preserved!
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Files Modified
|
|
72
|
+
|
|
73
|
+
| File | Changes |
|
|
74
|
+
|------|---------|
|
|
75
|
+
| `bin/agent-vibes` | execSync → execFileSync with array args |
|
|
76
|
+
| `src/commands/install-mcp.js` | Atomic file write with temp+rename |
|
|
77
|
+
| `src/installer.js` | exec → execFile, added shell/config validation |
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Testing
|
|
82
|
+
|
|
83
|
+
- ✅ All 132 BATS tests pass
|
|
84
|
+
- ✅ All 12 Node.js tests pass
|
|
85
|
+
- ✅ No bash code modified
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Upgrade
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npx agentvibes update
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
1
99
|
# Release v2.14.16 - Security Hardening & Dependency Updates
|
|
2
100
|
|
|
3
101
|
**Release Date:** 2025-12-02
|
package/bin/agent-vibes
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* This file ensures proper execution when run via npx
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { execFileSync } from 'node:child_process';
|
|
9
9
|
import path from 'node:path';
|
|
10
10
|
import fs from 'node:fs';
|
|
11
11
|
import { fileURLToPath } from 'node:url';
|
|
@@ -30,7 +30,9 @@ if (isNpxExecution) {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
try {
|
|
33
|
-
|
|
33
|
+
// Security: Use execFileSync with array args to prevent command injection
|
|
34
|
+
// Arguments are passed as array elements, not string interpolation
|
|
35
|
+
execFileSync('node', [installerPath, ...arguments_], {
|
|
34
36
|
stdio: 'inherit',
|
|
35
37
|
cwd: path.dirname(__dirname),
|
|
36
38
|
});
|
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": "2.14.
|
|
4
|
+
"version": "2.14.17",
|
|
5
5
|
"description": "Now your AI Agents can finally talk back! Professional TTS voice for Claude Code and Claude Desktop (via MCP) with multi-provider support.",
|
|
6
6
|
"homepage": "https://agentvibes.org",
|
|
7
7
|
"keywords": [
|
|
@@ -147,8 +147,17 @@ function updateClaudeConfig(agentVibesPath, provider, apiKey = null) {
|
|
|
147
147
|
config.mcpServers.agentvibes.env.ELEVENLABS_API_KEY = apiKey;
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
// Write config
|
|
151
|
-
|
|
150
|
+
// Write config atomically to prevent race conditions (TOCTOU)
|
|
151
|
+
// Write to temp file first, then rename atomically
|
|
152
|
+
const tempPath = `${configPath}.tmp.${process.pid}`;
|
|
153
|
+
try {
|
|
154
|
+
fs.writeFileSync(tempPath, JSON.stringify(config, null, 2), { mode: 0o600 });
|
|
155
|
+
fs.renameSync(tempPath, configPath);
|
|
156
|
+
} catch (error) {
|
|
157
|
+
// Clean up temp file if rename fails
|
|
158
|
+
try { fs.unlinkSync(tempPath); } catch { /* ignore cleanup errors */ }
|
|
159
|
+
throw error;
|
|
160
|
+
}
|
|
152
161
|
|
|
153
162
|
return configPath;
|
|
154
163
|
}
|
package/src/installer.js
CHANGED
|
@@ -128,16 +128,17 @@ function showReleaseInfo() {
|
|
|
128
128
|
console.log(
|
|
129
129
|
boxen(
|
|
130
130
|
chalk.white.bold('═══════════════════════════════════════════════════════════════\n') +
|
|
131
|
-
chalk.cyan.bold(' 📦 AgentVibes v2.14.
|
|
131
|
+
chalk.cyan.bold(' 📦 AgentVibes v2.14.17 - CodeQL Code Quality Improvements\n') +
|
|
132
132
|
chalk.white.bold('═══════════════════════════════════════════════════════════════\n\n') +
|
|
133
133
|
chalk.green.bold('🎙️ WHAT\'S NEW:\n\n') +
|
|
134
|
-
chalk.cyan('
|
|
135
|
-
chalk.cyan('
|
|
136
|
-
chalk.cyan('
|
|
134
|
+
chalk.cyan('Hi everyone! I enabled CodeQL on this repository to ensure the\n') +
|
|
135
|
+
chalk.cyan('highest quality code for AgentVibes. It found 5 issues which we\n') +
|
|
136
|
+
chalk.cyan('fixed in this release! All Node.js improvements, macOS safe.\n\n') +
|
|
137
137
|
chalk.green.bold('✨ KEY HIGHLIGHTS:\n\n') +
|
|
138
|
-
chalk.gray('
|
|
139
|
-
chalk.gray('
|
|
140
|
-
chalk.gray('
|
|
138
|
+
chalk.gray(' ✨ Atomic File Writes - Config uses temp+rename for reliability\n') +
|
|
139
|
+
chalk.gray(' ✨ Array-Based Commands - Cleaner execFileSync with array args\n') +
|
|
140
|
+
chalk.gray(' ✨ Input Validation - Shell path and config validation added\n') +
|
|
141
|
+
chalk.gray(' ✅ macOS Safe - All Node.js changes, no bash modifications\n\n') +
|
|
141
142
|
chalk.white.bold('═══════════════════════════════════════════════════════════════\n\n') +
|
|
142
143
|
chalk.gray('📖 Full Release Notes: RELEASE_NOTES.md\n') +
|
|
143
144
|
chalk.gray('🌐 Website: https://agentvibes.org\n') +
|
|
@@ -196,17 +197,40 @@ function execScript(scriptPath, options = {}) {
|
|
|
196
197
|
const args = parts.slice(1);
|
|
197
198
|
|
|
198
199
|
// Validate that the script file doesn't contain shell metacharacters
|
|
199
|
-
if (scriptFile.match(/[;&|`$(){}[\]<>]/)) {
|
|
200
|
+
if (scriptFile.match(/[;&|`$(){}[\]<>'"\\]/)) {
|
|
200
201
|
throw new Error('Invalid characters in script path');
|
|
201
202
|
}
|
|
202
203
|
|
|
203
204
|
// Validate path is within expected directory (defense in depth)
|
|
204
205
|
const resolvedPath = path.resolve(scriptFile);
|
|
205
206
|
const allowedDir = path.resolve(__dirname, '..', '.claude', 'hooks');
|
|
206
|
-
if (!resolvedPath.startsWith(allowedDir)) {
|
|
207
|
+
if (!resolvedPath.startsWith(allowedDir + path.sep) && resolvedPath !== allowedDir) {
|
|
207
208
|
throw new Error('Script path outside allowed directory');
|
|
208
209
|
}
|
|
209
210
|
|
|
211
|
+
// Security: Validate shell and shellConfig don't contain dangerous characters
|
|
212
|
+
// These come from environment variables which could be attacker-controlled
|
|
213
|
+
if (shell.match(/[;&|`$(){}[\]<>'"\\]/)) {
|
|
214
|
+
throw new Error('Invalid characters in shell path');
|
|
215
|
+
}
|
|
216
|
+
if (shellConfig.match(/[;&|`$(){}[\]<>'"\\]/)) {
|
|
217
|
+
throw new Error('Invalid characters in shell config path');
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Validate shell is an absolute path to a known shell
|
|
221
|
+
const validShells = ['/bin/bash', '/bin/zsh', '/bin/sh', '/usr/bin/bash', '/usr/bin/zsh', '/usr/bin/sh'];
|
|
222
|
+
if (!validShells.includes(shell) && !shell.match(/^\/(?:usr\/)?(?:local\/)?bin\/(?:ba)?sh$/)) {
|
|
223
|
+
throw new Error('Shell path not recognized as a valid shell');
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Validate shellConfig is under home directory
|
|
227
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || '';
|
|
228
|
+
const resolvedConfig = path.resolve(shellConfig);
|
|
229
|
+
const resolvedHome = path.resolve(homeDir);
|
|
230
|
+
if (!resolvedConfig.startsWith(resolvedHome + path.sep)) {
|
|
231
|
+
throw new Error('Shell config must be under home directory');
|
|
232
|
+
}
|
|
233
|
+
|
|
210
234
|
// Security: Use execFileSync with -c flag to prevent command injection
|
|
211
235
|
// The shell sources its config and executes the script with arguments passed as array
|
|
212
236
|
// This avoids string interpolation vulnerabilities
|
|
@@ -1297,12 +1321,12 @@ async function detectAndMigrateOldConfig(targetDir, spinner) {
|
|
|
1297
1321
|
try {
|
|
1298
1322
|
await fs.access(migrationScript);
|
|
1299
1323
|
|
|
1300
|
-
// Execute migration script
|
|
1301
|
-
const {
|
|
1324
|
+
// Execute migration script using execFile to prevent command injection
|
|
1325
|
+
const { execFile } = require('child_process');
|
|
1302
1326
|
const { promisify } = require('util');
|
|
1303
|
-
const
|
|
1327
|
+
const execFilePromise = promisify(execFile);
|
|
1304
1328
|
|
|
1305
|
-
await
|
|
1329
|
+
await execFilePromise('bash', [migrationScript], { cwd: targetDir });
|
|
1306
1330
|
|
|
1307
1331
|
spinner.succeed(chalk.green('✓ Configuration migrated to .agentvibes/'));
|
|
1308
1332
|
console.log(chalk.gray(' Old locations: .claude/config/, .claude/plugins/'));
|